Loading...
Searching...
No Matches
nat.h
Go to the documentation of this file.
#ifndef ML99_NAT_H
#define ML99_NAT_H
#include <metalang99/priv/bool.h>
#include <metalang99/nat/dec.h>
#include <metalang99/nat/div.h>
#include <metalang99/nat/eq.h>
#include <metalang99/nat/inc.h>
#include <metalang99/lang.h>
#define ML99_inc(x) ML99_call(ML99_inc, x)
#define ML99_dec(x) ML99_call(ML99_dec, x)
#define ML99_natMatch(x, matcher) ML99_call(ML99_natMatch, x, matcher)
#define ML99_natMatchWithArgs(x, matcher, ...) \
ML99_call(ML99_natMatchWithArgs, x, matcher, __VA_ARGS__)
#define ML99_natEq(x, y) ML99_call(ML99_natEq, x, y)
#define ML99_natNeq(x, y) ML99_call(ML99_natNeq, x, y)
#define ML99_greater(x, y) ML99_call(ML99_greater, x, y)
#define ML99_greaterEq(x, y) ML99_call(ML99_greaterEq, x, y)
#define ML99_lesser(x, y) ML99_call(ML99_lesser, x, y)
#define ML99_lesserEq(x, y) ML99_call(ML99_lesserEq, x, y)
#define ML99_add(x, y) ML99_call(ML99_add, x, y)
#define ML99_sub(x, y) ML99_call(ML99_sub, x, y)
#define ML99_mul(x, y) ML99_call(ML99_mul, x, y)
#define ML99_div(x, y) ML99_call(ML99_div, x, y)
#define ML99_divChecked(x, y) ML99_call(ML99_divChecked, x, y)
#define ML99_mod(x, y) ML99_call(ML99_mod, x, y)
#define ML99_add3(x, y, z) ML99_call(ML99_add3, x, y, z)
#define ML99_sub3(x, y, z) ML99_call(ML99_sub3, x, y, z)
#define ML99_mul3(x, y, z) ML99_call(ML99_mul3, x, y, z)
#define ML99_div3(x, y, z) ML99_call(ML99_div3, x, y, z)
#define ML99_min(x, y) ML99_call(ML99_min, x, y)
#define ML99_max(x, y) ML99_call(ML99_max, x, y)
#define ML99_assertIsNat(x) ML99_call(ML99_assertIsNat, x)
#define ML99_INC(x) ML99_PRIV_INC(x)
#define ML99_DEC(x) ML99_PRIV_DEC(x)
#define ML99_NAT_EQ(x, y) ML99_PRIV_NAT_EQ(x, y)
#define ML99_NAT_NEQ(x, y) ML99_PRIV_NOT(ML99_NAT_EQ(x, y))
#define ML99_DIV_CHECKED(x, y) ML99_PRIV_DIV_CHECKED(x, y)
#define ML99_NAT_MAX 255
#ifndef DOXYGEN_IGNORE
// Pattern matching {
#define ML99_natMatch_IMPL(x, matcher) \
ML99_PRIV_IF( \
ML99_NAT_EQ(x, 0), \
ML99_callUneval(matcher##Z, ), \
ML99_callUneval(matcher##S, ML99_DEC(x)))
#define ML99_natMatchWithArgs_IMPL(x, matcher, ...) \
ML99_PRIV_IF( \
ML99_NAT_EQ(x, 0), \
ML99_callUneval(matcher##Z, __VA_ARGS__), \
ML99_callUneval(matcher##S, ML99_DEC(x), __VA_ARGS__))
// } (Pattern matching)
// Comparison operators {
#define ML99_natEq_IMPL(x, y) v(ML99_NAT_EQ(x, y))
#define ML99_natNeq_IMPL(x, y) v(ML99_NAT_NEQ(x, y))
#define ML99_lesser_IMPL(x, y) \
ML99_PRIV_IF( \
ML99_NAT_EQ(y, 0), \
v(ML99_PRIV_FALSE()), \
ML99_PRIV_IF( \
ML99_NAT_EQ(x, ML99_DEC(y)), \
v(ML99_PRIV_TRUE()), \
ML99_callUneval(ML99_lesser, x, ML99_DEC(y))))
#define ML99_lesserEq_IMPL(x, y) ML99_greaterEq_IMPL(y, x)
#define ML99_greater_IMPL(x, y) ML99_lesser_IMPL(y, x)
#define ML99_greaterEq_IMPL(x, y) \
ML99_PRIV_IF(ML99_NAT_EQ(x, y), v(ML99_PRIV_TRUE()), ML99_greater_IMPL(x, y))
// } (Comparison operators)
// Arithmetical operators {
#define ML99_inc_IMPL(x) v(ML99_INC(x))
#define ML99_dec_IMPL(x) v(ML99_DEC(x))
#define ML99_add_IMPL(x, y) \
ML99_PRIV_IF(ML99_NAT_EQ(y, 0), v(x), ML99_callUneval(ML99_add, ML99_INC(x), ML99_DEC(y)))
#define ML99_sub_IMPL(x, y) \
ML99_PRIV_IF(ML99_NAT_EQ(y, 0), v(x), ML99_callUneval(ML99_sub, ML99_DEC(x), ML99_DEC(y)))
#define ML99_mul_IMPL(x, y) \
ML99_PRIV_IF(ML99_NAT_EQ(y, 0), v(0), ML99_add(v(x), ML99_callUneval(ML99_mul, x, ML99_DEC(y))))
#define ML99_add3_IMPL(x, y, z) ML99_add(ML99_add_IMPL(x, y), v(z))
#define ML99_sub3_IMPL(x, y, z) ML99_sub(ML99_sub_IMPL(x, y), v(z))
#define ML99_mul3_IMPL(x, y, z) ML99_mul(ML99_mul_IMPL(x, y), v(z))
#define ML99_div3_IMPL(x, y, z) ML99_div(ML99_div_IMPL(x, y), v(z))
#define ML99_min_IMPL(x, y) ML99_call(ML99_if, ML99_lesser_IMPL(x, y), v(x, y))
#define ML99_max_IMPL(x, y) ML99_call(ML99_if, ML99_lesser_IMPL(x, y), v(y, x))
#define ML99_divChecked_IMPL(x, y) v(ML99_DIV_CHECKED(x, y))
// ML99_mod_IMPL {
#define ML99_mod_IMPL(x, y) \
ML99_PRIV_IF( \
ML99_NAT_EQ(y, 0), \
ML99_fatal(ML99_mod, modulo by 0), \
ML99_PRIV_modAux_IMPL(x, y, 0))
#define ML99_PRIV_modAux_IMPL(x, y, acc) \
ML99_PRIV_IF( \
ML99_PRIV_OR(ML99_NAT_EQ(x, 0), ML99_IS_JUST(ML99_DIV_CHECKED(x, y))), \
v(acc), \
ML99_callUneval(ML99_PRIV_modAux, ML99_DEC(x), y, ML99_INC(acc)))
// } (ML99_mod_IMPL)
// } (Arithmetical operators)
#define ML99_assertIsNat_IMPL(x) \
ML99_PRIV_IF( \
ML99_PRIV_NAT_EQ(x, x), \
v(ML99_PRIV_EMPTY()), \
ML99_PRIV_ASSERT_IS_NAT_FATAL(x, ML99_NAT_MAX))
// clang-format off
#define ML99_PRIV_ASSERT_IS_NAT_FATAL(x, max) ML99_fatal(ML99_assertIsNat, x must be within [0; max])
// clang-format on
// Arity specifiers {
#define ML99_inc_ARITY 1
#define ML99_dec_ARITY 1
#define ML99_natMatch_ARITY 2
#define ML99_natMatchWithArgs_ARITY 3
#define ML99_natEq_ARITY 2
#define ML99_natNeq_ARITY 2
#define ML99_greater_ARITY 2
#define ML99_greaterEq_ARITY 2
#define ML99_lesser_ARITY 2
#define ML99_lesserEq_ARITY 2
#define ML99_add_ARITY 2
#define ML99_sub_ARITY 2
#define ML99_mul_ARITY 2
#define ML99_div_ARITY 2
#define ML99_divChecked_ARITY 2
#define ML99_mod_ARITY 2
#define ML99_add3_ARITY 3
#define ML99_sub3_ARITY 3
#define ML99_mul3_ARITY 3
#define ML99_div3_ARITY 3
#define ML99_min_ARITY 2
#define ML99_max_ARITY 2
#define ML99_assertIsNat_ARITY 1
// } (Arity specifiers)
#endif // DOXYGEN_IGNORE
#endif // ML99_NAT_H
lang.h
The core metalanguage.