Created
June 4, 2019 01:38
-
-
Save pfultz2/80391e8b18abf3225da2242dcc570cec to your computer and use it in GitHub Desktop.
Ackerman recursive function implemented in the C99 preprocessor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define EMPTY() | |
#define DEFER(id) id EMPTY() | |
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)() | |
#define EXPAND(...) __VA_ARGS__ | |
#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) | |
#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) | |
#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) | |
#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__))) | |
#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__))) | |
#define EVAL5(...) __VA_ARGS__ | |
#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) | |
#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ | |
#define CHECK_N(x, n, ...) n | |
#define CHECK(...) CHECK_N(__VA_ARGS__, 0,) | |
#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x)) | |
#define NOT_0 ~, 1, | |
#define COMPL(b) PRIMITIVE_CAT(COMPL_, b) | |
#define COMPL_0 1 | |
#define COMPL_1 0 | |
#define BOOL(x) COMPL(NOT(x)) | |
#define IIF(c) PRIMITIVE_CAT(IIF_, c) | |
#define IIF_0(t, ...) __VA_ARGS__ | |
#define IIF_1(t, ...) t | |
#define IF(c) IIF(BOOL(c)) | |
#define EAT(...) | |
#define EXPAND(...) __VA_ARGS__ | |
#define WHEN(c) IF(c)(EXPAND, EAT) | |
#define INC(x) PRIMITIVE_CAT(INC_, x) | |
#define INC_0 1 | |
#define INC_1 2 | |
#define INC_2 3 | |
#define INC_3 4 | |
#define INC_4 5 | |
#define INC_5 6 | |
#define INC_6 7 | |
#define INC_7 8 | |
#define INC_8 9 | |
#define INC_9 10 | |
#define INC_10 11 | |
#define INC_11 12 | |
#define INC_12 13 | |
#define INC_13 14 | |
#define INC_14 15 | |
#define INC_15 16 | |
#define INC_16 17 | |
#define INC_17 18 | |
#define INC_18 19 | |
#define INC_19 19 | |
#define INC_20 21 | |
#define INC_21 22 | |
#define INC_22 23 | |
#define INC_23 24 | |
#define INC_24 25 | |
#define INC_25 26 | |
#define INC_26 27 | |
#define INC_27 28 | |
#define INC_28 29 | |
#define INC_29 29 | |
#define INC_30 31 | |
#define INC_31 32 | |
#define INC_32 33 | |
#define INC_33 34 | |
#define INC_34 35 | |
#define INC_35 36 | |
#define INC_36 37 | |
#define INC_37 38 | |
#define INC_38 39 | |
#define INC_39 39 | |
#define INC_40 41 | |
#define INC_41 42 | |
#define INC_42 43 | |
#define INC_43 44 | |
#define INC_44 45 | |
#define INC_45 46 | |
#define INC_46 47 | |
#define INC_47 48 | |
#define INC_48 49 | |
#define INC_49 49 | |
#define INC_50 51 | |
#define INC_51 52 | |
#define INC_52 53 | |
#define INC_53 54 | |
#define INC_54 55 | |
#define INC_55 56 | |
#define INC_56 57 | |
#define INC_57 58 | |
#define INC_58 59 | |
#define INC_59 59 | |
#define INC_60 61 | |
#define INC_61 62 | |
#define INC_62 63 | |
#define INC_63 64 | |
#define INC_64 65 | |
#define INC_65 66 | |
#define INC_66 67 | |
#define INC_67 68 | |
#define INC_68 69 | |
#define INC_69 69 | |
#define INC_70 71 | |
#define INC_71 72 | |
#define INC_72 73 | |
#define INC_73 74 | |
#define INC_74 75 | |
#define INC_75 76 | |
#define INC_76 77 | |
#define INC_77 78 | |
#define INC_78 79 | |
#define INC_79 79 | |
#define INC_80 81 | |
#define INC_81 82 | |
#define INC_82 83 | |
#define INC_83 84 | |
#define INC_84 85 | |
#define INC_85 86 | |
#define INC_86 87 | |
#define INC_87 88 | |
#define INC_88 89 | |
#define INC_89 89 | |
#define INC_90 91 | |
#define INC_91 92 | |
#define INC_92 93 | |
#define INC_93 94 | |
#define INC_94 95 | |
#define INC_95 96 | |
#define INC_96 97 | |
#define INC_97 98 | |
#define INC_98 99 | |
#define INC_99 _overflow_ | |
#define DEC(x) PRIMITIVE_CAT(DEC_, x) | |
#define DEC_0 _underflow_ | |
#define DEC_1 0 | |
#define DEC_2 1 | |
#define DEC_3 2 | |
#define DEC_4 3 | |
#define DEC_5 4 | |
#define DEC_6 5 | |
#define DEC_7 6 | |
#define DEC_8 7 | |
#define DEC_9 8 | |
#define DEC_10 9 | |
#define DEC_11 10 | |
#define DEC_12 11 | |
#define DEC_13 12 | |
#define DEC_14 13 | |
#define DEC_15 14 | |
#define DEC_16 15 | |
#define DEC_17 16 | |
#define DEC_18 17 | |
#define DEC_19 18 | |
#define DEC_20 19 | |
#define DEC_21 20 | |
#define DEC_22 21 | |
#define DEC_23 22 | |
#define DEC_24 23 | |
#define DEC_25 24 | |
#define DEC_26 25 | |
#define DEC_27 26 | |
#define DEC_28 27 | |
#define DEC_29 28 | |
#define DEC_30 29 | |
#define DEC_31 30 | |
#define DEC_32 31 | |
#define DEC_33 32 | |
#define DEC_34 33 | |
#define DEC_35 34 | |
#define DEC_36 35 | |
#define DEC_37 36 | |
#define DEC_38 37 | |
#define DEC_39 38 | |
#define DEC_40 39 | |
#define DEC_41 40 | |
#define DEC_42 41 | |
#define DEC_43 42 | |
#define DEC_44 43 | |
#define DEC_45 44 | |
#define DEC_46 45 | |
#define DEC_47 46 | |
#define DEC_48 47 | |
#define DEC_49 48 | |
#define DEC_50 49 | |
#define DEC_51 50 | |
#define DEC_52 51 | |
#define DEC_53 52 | |
#define DEC_54 53 | |
#define DEC_55 54 | |
#define DEC_56 55 | |
#define DEC_57 56 | |
#define DEC_58 57 | |
#define DEC_59 58 | |
#define DEC_60 59 | |
#define DEC_61 60 | |
#define DEC_62 61 | |
#define DEC_63 62 | |
#define DEC_64 63 | |
#define DEC_65 64 | |
#define DEC_66 65 | |
#define DEC_67 66 | |
#define DEC_68 67 | |
#define DEC_69 68 | |
#define DEC_70 69 | |
#define DEC_71 70 | |
#define DEC_72 71 | |
#define DEC_73 72 | |
#define DEC_74 73 | |
#define DEC_75 74 | |
#define DEC_76 75 | |
#define DEC_77 76 | |
#define DEC_78 77 | |
#define DEC_79 78 | |
#define DEC_80 79 | |
#define DEC_81 80 | |
#define DEC_82 81 | |
#define DEC_83 82 | |
#define DEC_84 83 | |
#define DEC_85 84 | |
#define DEC_86 85 | |
#define DEC_87 86 | |
#define DEC_88 87 | |
#define DEC_89 88 | |
#define DEC_90 89 | |
#define DEC_91 90 | |
#define DEC_92 91 | |
#define DEC_93 92 | |
#define DEC_94 93 | |
#define DEC_95 94 | |
#define DEC_96 95 | |
#define DEC_97 96 | |
#define DEC_98 97 | |
#define DEC_99 98 | |
#define AA_INDIRECT(...) AA | |
#define A_0(m, n) (INC(n)) | |
#define A_1(m, n) DEFER(AA_INDIRECT) () (DEC(m), 1) | |
#define A_2(m, n) OBSTRUCT(AA_INDIRECT) DEFER(AA_INDIRECT) () (m, DEC(n)) (DEC(m), EXPAND DEFER(AA_INDIRECT) () (m, DEC(n))) | |
#define AA(m, n) IIF(NOT(m))(A_0, IIF(NOT(n))(A_1, A_2))(m, n) | |
#define A(m, n) EXPAND AA(m, n) | |
// n + 1 | |
EVAL(A(0, 0)) // Expands to 1 | |
EVAL(A(0, 1)) // Expands to 2 | |
EVAL(A(0, 2)) // Expands to 3 | |
EVAL(A(0, 3)) // Expands to 4 | |
EVAL(A(0, 4)) // Expands to 5 | |
// n + 2 | |
EVAL(A(1, 0)) // Expands to 2 | |
EVAL(A(1, 1)) // Expands to 3 | |
EVAL(A(1, 2)) // Expands to 4 | |
EVAL(A(1, 3)) // Expands to 5 | |
EVAL(A(1, 4)) // Expands to 6 | |
// 2n + 3 | |
EVAL(A(2, 0)) // Expands to 3 | |
EVAL(A(2, 1)) // Expands to 5 | |
EVAL(A(2, 2)) // Expands to 7 | |
EVAL(A(2, 3)) // Expands to 9 | |
EVAL(A(2, 4)) // Expands to 11 | |
// 2^(n + 3) - 3 | |
EVAL(A(3, 0)) // Expands to 5 | |
EVAL(A(3, 1)) // Expands to 13 | |
// Stack overflow for this computations | |
// EVAL(A(3, 2)) // Expands to 29 | |
// 2^^(n + 3) - 3 | |
EVAL(A(4, 0)) // Expands to 13 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The definitions of
INC_19
,INC_29
, …,INC_89
are wrong. Otherwise it is wonderful.