Metalang99
1.13.3
Full-blown preprocessor metaprogramming
Loading...
Searching...
No Matches
nat.h
Go to the documentation of this file.
1
9
#ifndef ML99_NAT_H
10
#define ML99_NAT_H
11
12
#include <metalang99/priv/bool.h>
13
14
#include <metalang99/nat/dec.h>
15
#include <metalang99/nat/div.h>
16
#include <metalang99/nat/eq.h>
17
#include <metalang99/nat/inc.h>
18
19
#include <
metalang99/lang.h
>
20
35
#define ML99_inc(x) ML99_call(ML99_inc, x)
36
51
#define ML99_dec(x) ML99_call(ML99_dec, x)
52
74
#define ML99_natMatch(x, matcher) ML99_call(ML99_natMatch, x, matcher)
75
94
#define ML99_natMatchWithArgs(x, matcher, ...) \
95
ML99_call(ML99_natMatchWithArgs, x, matcher, __VA_ARGS__)
96
112
#define ML99_natEq(x, y) ML99_call(ML99_natEq, x, y)
113
129
#define ML99_natNeq(x, y) ML99_call(ML99_natNeq, x, y)
130
146
#define ML99_greater(x, y) ML99_call(ML99_greater, x, y)
147
163
#define ML99_greaterEq(x, y) ML99_call(ML99_greaterEq, x, y)
164
180
#define ML99_lesser(x, y) ML99_call(ML99_lesser, x, y)
181
197
#define ML99_lesserEq(x, y) ML99_call(ML99_lesserEq, x, y)
198
211
#define ML99_add(x, y) ML99_call(ML99_add, x, y)
212
225
#define ML99_sub(x, y) ML99_call(ML99_sub, x, y)
226
239
#define ML99_mul(x, y) ML99_call(ML99_mul, x, y)
240
255
#define ML99_div(x, y) ML99_call(ML99_div, x, y)
256
276
#define ML99_divChecked(x, y) ML99_call(ML99_divChecked, x, y)
277
292
#define ML99_mod(x, y) ML99_call(ML99_mod, x, y)
293
306
#define ML99_add3(x, y, z) ML99_call(ML99_add3, x, y, z)
307
320
#define ML99_sub3(x, y, z) ML99_call(ML99_sub3, x, y, z)
321
334
#define ML99_mul3(x, y, z) ML99_call(ML99_mul3, x, y, z)
335
350
#define ML99_div3(x, y, z) ML99_call(ML99_div3, x, y, z)
351
364
#define ML99_min(x, y) ML99_call(ML99_min, x, y)
365
378
#define ML99_max(x, y) ML99_call(ML99_max, x, y)
379
397
#define ML99_assertIsNat(x) ML99_call(ML99_assertIsNat, x)
398
399
#define ML99_INC(x) ML99_PRIV_INC(x)
400
#define ML99_DEC(x) ML99_PRIV_DEC(x)
401
#define ML99_NAT_EQ(x, y) ML99_PRIV_NAT_EQ(x, y)
402
#define ML99_NAT_NEQ(x, y) ML99_PRIV_NOT(ML99_NAT_EQ(x, y))
403
#define ML99_DIV_CHECKED(x, y) ML99_PRIV_DIV_CHECKED(x, y)
404
408
#define ML99_NAT_MAX 255
409
410
#ifndef DOXYGEN_IGNORE
411
412
// Pattern matching {
413
414
#define ML99_natMatch_IMPL(x, matcher) \
415
ML99_PRIV_IF( \
416
ML99_NAT_EQ(x, 0), \
417
ML99_callUneval(matcher##Z, ), \
418
ML99_callUneval(matcher##S, ML99_DEC(x)))
419
420
#define ML99_natMatchWithArgs_IMPL(x, matcher, ...) \
421
ML99_PRIV_IF( \
422
ML99_NAT_EQ(x, 0), \
423
ML99_callUneval(matcher##Z, __VA_ARGS__), \
424
ML99_callUneval(matcher##S, ML99_DEC(x), __VA_ARGS__))
425
// } (Pattern matching)
426
427
// Comparison operators {
428
429
#define ML99_natEq_IMPL(x, y) v(ML99_NAT_EQ(x, y))
430
#define ML99_natNeq_IMPL(x, y) v(ML99_NAT_NEQ(x, y))
431
432
#define ML99_lesser_IMPL(x, y) \
433
ML99_PRIV_IF( \
434
ML99_NAT_EQ(y, 0), \
435
v(ML99_PRIV_FALSE()), \
436
ML99_PRIV_IF( \
437
ML99_NAT_EQ(x, ML99_DEC(y)), \
438
v(ML99_PRIV_TRUE()), \
439
ML99_callUneval(ML99_lesser, x, ML99_DEC(y))))
440
441
#define ML99_lesserEq_IMPL(x, y) ML99_greaterEq_IMPL(y, x)
442
443
#define ML99_greater_IMPL(x, y) ML99_lesser_IMPL(y, x)
444
#define ML99_greaterEq_IMPL(x, y) \
445
ML99_PRIV_IF(ML99_NAT_EQ(x, y), v(ML99_PRIV_TRUE()), ML99_greater_IMPL(x, y))
446
// } (Comparison operators)
447
448
// Arithmetical operators {
449
450
#define ML99_inc_IMPL(x) v(ML99_INC(x))
451
#define ML99_dec_IMPL(x) v(ML99_DEC(x))
452
453
#define ML99_add_IMPL(x, y) \
454
ML99_PRIV_IF(ML99_NAT_EQ(y, 0), v(x), ML99_callUneval(ML99_add, ML99_INC(x), ML99_DEC(y)))
455
#define ML99_sub_IMPL(x, y) \
456
ML99_PRIV_IF(ML99_NAT_EQ(y, 0), v(x), ML99_callUneval(ML99_sub, ML99_DEC(x), ML99_DEC(y)))
457
#define ML99_mul_IMPL(x, y) \
458
ML99_PRIV_IF(ML99_NAT_EQ(y, 0), v(0), ML99_add(v(x), ML99_callUneval(ML99_mul, x, ML99_DEC(y))))
459
460
#define ML99_add3_IMPL(x, y, z) ML99_add(ML99_add_IMPL(x, y), v(z))
461
#define ML99_sub3_IMPL(x, y, z) ML99_sub(ML99_sub_IMPL(x, y), v(z))
462
#define ML99_mul3_IMPL(x, y, z) ML99_mul(ML99_mul_IMPL(x, y), v(z))
463
#define ML99_div3_IMPL(x, y, z) ML99_div(ML99_div_IMPL(x, y), v(z))
464
465
#define ML99_min_IMPL(x, y) ML99_call(ML99_if, ML99_lesser_IMPL(x, y), v(x, y))
466
#define ML99_max_IMPL(x, y) ML99_call(ML99_if, ML99_lesser_IMPL(x, y), v(y, x))
467
468
#define ML99_divChecked_IMPL(x, y) v(ML99_DIV_CHECKED(x, y))
469
470
// ML99_mod_IMPL {
471
472
#define ML99_mod_IMPL(x, y) \
473
ML99_PRIV_IF( \
474
ML99_NAT_EQ(y, 0), \
475
ML99_fatal(ML99_mod, modulo by 0), \
476
ML99_PRIV_modAux_IMPL(x, y, 0))
477
478
#define ML99_PRIV_modAux_IMPL(x, y, acc) \
479
ML99_PRIV_IF( \
480
ML99_PRIV_OR(ML99_NAT_EQ(x, 0), ML99_IS_JUST(ML99_DIV_CHECKED(x, y))), \
481
v(acc), \
482
ML99_callUneval(ML99_PRIV_modAux, ML99_DEC(x), y, ML99_INC(acc)))
483
// } (ML99_mod_IMPL)
484
485
// } (Arithmetical operators)
486
487
#define ML99_assertIsNat_IMPL(x) \
488
ML99_PRIV_IF( \
489
ML99_PRIV_NAT_EQ(x, x), \
490
v(ML99_PRIV_EMPTY()), \
491
ML99_PRIV_ASSERT_IS_NAT_FATAL(x, ML99_NAT_MAX))
492
493
// clang-format off
494
#define ML99_PRIV_ASSERT_IS_NAT_FATAL(x, max) ML99_fatal(ML99_assertIsNat, x must be within [0; max])
495
// clang-format on
496
497
// Arity specifiers {
498
499
#define ML99_inc_ARITY 1
500
#define ML99_dec_ARITY 1
501
#define ML99_natMatch_ARITY 2
502
#define ML99_natMatchWithArgs_ARITY 3
503
#define ML99_natEq_ARITY 2
504
#define ML99_natNeq_ARITY 2
505
#define ML99_greater_ARITY 2
506
#define ML99_greaterEq_ARITY 2
507
#define ML99_lesser_ARITY 2
508
#define ML99_lesserEq_ARITY 2
509
#define ML99_add_ARITY 2
510
#define ML99_sub_ARITY 2
511
#define ML99_mul_ARITY 2
512
#define ML99_div_ARITY 2
513
#define ML99_divChecked_ARITY 2
514
#define ML99_mod_ARITY 2
515
#define ML99_add3_ARITY 3
516
#define ML99_sub3_ARITY 3
517
#define ML99_mul3_ARITY 3
518
#define ML99_div3_ARITY 3
519
#define ML99_min_ARITY 2
520
#define ML99_max_ARITY 2
521
#define ML99_assertIsNat_ARITY 1
522
// } (Arity specifiers)
523
524
#endif
// DOXYGEN_IGNORE
525
526
#endif
// ML99_NAT_H
lang.h
The core metalanguage.
include
metalang99
nat.h
Generated by
1.9.8