/* * File: macro_logic.h * Author: root * * Created on December 22, 2018, 4:49 AM * * To test: * gcc -DAJK_TEST_MACRO_LOGIC -E macro_logic.h */ #ifndef MACRO_LOGIC_H #define MACRO_LOGIC_H #define AJK_CAT(a, ...) AJK_PRIMITIVE_CAT(a, __VA_ARGS__) #define AJK_PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ #define AJK_COMPL(b) AJK_PRIMITIVE_CAT(AJK_COMPL_, b) #define AJK_COMPL_0 1 #define AJK_COMPL_1 0 #define AJK_BITAND(x) AJK_PRIMITIVE_CAT(AJK_BITAND_, x) #define AJK_BITAND_0(y) 0 #define AJK_BITAND_1(y) y #define AJK_INC(x) AJK_PRIMITIVE_CAT(AJK_INC_, x) #define AJK_INC_0 1 #define AJK_INC_1 2 #define AJK_INC_2 3 #define AJK_INC_3 4 #define AJK_INC_4 5 #define AJK_INC_5 6 #define AJK_INC_6 7 #define AJK_INC_7 8 #define AJK_INC_8 9 #define AJK_INC_9 10 #define AJK_INC_10 10 #define AJK_DEC(x) AJK_PRIMITIVE_CAT(AJK_DEC_, x) #define AJK_DEC_0 0 #define AJK_DEC_1 0 #define AJK_DEC_2 1 #define AJK_DEC_3 2 #define AJK_DEC_4 3 #define AJK_DEC_5 4 #define AJK_DEC_6 5 #define AJK_DEC_7 6 #define AJK_DEC_8 7 #define AJK_DEC_9 8 #define AJK_DEC_10 9 #define AJK_CHECK_N(x, n, ...) n #define AJK_CHECK(...) AJK_CHECK_N(__VA_ARGS__, 0,) #define AJK_PROBE(x) x, 1, #define AJK_IS_PAREN(x) AJK_CHECK(AJK_IS_PAREN_PROBE x) #define AJK_IS_PAREN_PROBE(...) AJK_PROBE(~) #define AJK_NOT(x) AJK_CHECK(AJK_PRIMITIVE_CAT(AJK_NOT_, x)) #define AJK_NOT_0 AJK_PROBE(~) #define AJK_COMPL(b) AJK_PRIMITIVE_CAT(AJK_COMPL_, b) #define AJK_COMPL_0 1 #define AJK_COMPL_1 0 #define AJK_BOOL(x) AJK_COMPL(AJK_NOT(x)) #define AJK_IIF(c) AJK_PRIMITIVE_CAT(AJK_IIF_, c) #define AJK_IIF_0(t, ...) __VA_ARGS__ #define AJK_IIF_1(t, ...) t #define AJK_IF(c) AJK_IIF(AJK_BOOL(c)) #define AJK_EAT(...) #define AJK_EXPAND(...) __VA_ARGS__ #define AJK_WHEN(c) AJK_IF(c)(AJK_EXPAND, AJK_EAT) #define AJK_EMPTY() #define AJK_DEFER(id) id AJK_EMPTY() #define AJK_OBSTRUCT(id) id AJK_DEFER(AJK_EMPTY)() #define AJK_EVAL(...) AJK_EVAL1(AJK_EVAL1(AJK_EVAL1(__VA_ARGS__))) #define AJK_EVAL1(...) AJK_EVAL2(AJK_EVAL2(AJK_EVAL2(__VA_ARGS__))) #define AJK_EVAL2(...) AJK_EVAL3(AJK_EVAL3(AJK_EVAL3(__VA_ARGS__))) #define AJK_EVAL3(...) AJK_EVAL4(AJK_EVAL4(AJK_EVAL4(__VA_ARGS__))) #define AJK_EVAL4(...) AJK_EVAL5(AJK_EVAL5(AJK_EVAL5(__VA_ARGS__))) #define AJK_EVAL5(...) __VA_ARGS__ #define AJK_REPEAT(AJK_count, AJK_macro, ...) \ AJK_WHEN(AJK_count) \ ( \ AJK_OBSTRUCT(AJK_REPEAT_INDIRECT) () \ ( \ AJK_DEC(AJK_count), AJK_macro, __VA_ARGS__ \ ) \ AJK_OBSTRUCT(AJK_macro) \ ( \ AJK_DEC(AJK_count), __VA_ARGS__ \ ) \ ) #define AJK_REPEAT_INDIRECT() AJK_REPEAT #define AJK_WHILE(AJK_pred, AJK_op, ...) \ IF(AJK_pred(__VA_ARGS__)) \ ( \ AJK_OBSTRUCT(AJK_WHILE_INDIRECT) () \ ( \ AJK_pred, AJK_op, AJK_op(__VA_ARGS__) \ ), \ __VA_ARGS__ \ ) #define AJK_WHILE_INDIRECT() AJK_WHILE #define AJK_PRIMITIVE_COMPARE(x, y) AJK_IS_PAREN \ ( \ AJK_COMPARE_ ## x ( AJK_COMPARE_ ## y) (()) \ ) #define AJK_IS_COMPARABLE(x) AJK_IS_PAREN( AJK_CAT(AJK_COMPARE_, x) (()) ) #define AJK_NOT_EQUAL(x, y) \ AJK_IIF(AJK_BITAND(AJK_IS_COMPARABLE(x))(AJK_IS_COMPARABLE(y)) ) \ ( \ AJK_PRIMITIVE_COMPARE, \ 1 AJK_EAT \ )(x, y) #define AJK_EQUAL(x, y) AJK_COMPL(AJK_NOT_EQUAL(x, y)) #define AJK_COMMA() , #define AJK_COMMA_IF(n) AJK_IF(n)(AJK_COMMA, AJK_EAT)() #define AJK_COMMA_VAR(AJK_count, AJK_v) AJK_COMMA_IF(AJK_count) AJK_v ## AJK_count #define AJK_MAKE_LIST(AJK_v, AJK_count) AJK_EVAL(AJK_REPEAT(AJK_count, AJK_COMMA_VAR, AJK_v)) #define AJK_FUN(AJK_count, AJK_v, AJK_args, AJK_body) AJK_v ## AJK_count (AJK_args) { AJK_body(AJK_count) } #define AJK_MAKE_FUNS(AJK_v, AJK_args, AJK_count, AJK_body) AJK_EVAL(AJK_REPEAT(AJK_count, AJK_FUN, AJK_v, AJK_args, AJK_body)) #ifdef AJK_TEST_MACRO_LOGIC #define BODY(AJKindex) some(C, statement); contaning(a, test[AJKindex]); #define ZERO_TIMES_TEST 0 #define THREE_TIMES_TEST 3 blank > AJK_MAKE_LIST(VARIABLE_, ZERO_TIMES_TEST) < because zero repeats Make 3 comma separated indexed variables : AJK_MAKE_LIST(VARIABLE_, THREE_TIMES_TEST) Make 3 bogus function bodies AJK_MAKE_FUNS(unsigned Cfunc,(arg1, arg2),3,BODY) #endif #endif /* MACRO_LOGIC_H */