Skip to content

Instantly share code, notes, and snippets.

@camel-cdr
Last active March 6, 2022 22:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save camel-cdr/e3b9436e0e7b95519f25c14551a767eb to your computer and use it in GitHub Desktop.
Save camel-cdr/e3b9436e0e7b95519f25c14551a767eb to your computer and use it in GitHub Desktop.
C preprocessor continuation machine with some helper macros
#define XXX_CM_UP_0(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_1 (XXX_CM_PASS_DN_0 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_1(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_2 (XXX_CM_PASS_DN_1 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_2(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_3 (XXX_CM_PASS_DN_2 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_3(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_4 (XXX_CM_PASS_DN_3 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_4(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_5 (XXX_CM_PASS_DN_4 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_5(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_6 (XXX_CM_PASS_DN_5 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_6(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_7 (XXX_CM_PASS_DN_6 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_7(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_8 (XXX_CM_PASS_DN_7 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_8(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_9 (XXX_CM_PASS_DN_8 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_9(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_10(XXX_CM_PASS_DN_9 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_10(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_11(XXX_CM_PASS_DN_10(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_11(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_12(XXX_CM_PASS_DN_11(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_12(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_13(XXX_CM_PASS_DN_12(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_13(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_14(XXX_CM_PASS_DN_13(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_14(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_15(XXX_CM_PASS_DN_14(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_15(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_16(XXX_CM_PASS_DN_15(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_16(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_17(XXX_CM_PASS_DN_16(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_17(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_18(XXX_CM_PASS_DN_17(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_18(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_19(XXX_CM_PASS_DN_18(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_19(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_20(XXX_CM_PASS_DN_19(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_20(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_21(XXX_CM_PASS_DN_20(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_21(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_22(XXX_CM_PASS_DN_21(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_22(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_23(XXX_CM_PASS_DN_22(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_23(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_24(XXX_CM_PASS_DN_23(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_24(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_25(XXX_CM_PASS_DN_24(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_25(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_26(XXX_CM_PASS_DN_25(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_26(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_27(XXX_CM_PASS_DN_26(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_27(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_28(XXX_CM_PASS_DN_27(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_28(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_29(XXX_CM_PASS_DN_28(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_29(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_30(XXX_CM_PASS_DN_29(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_30(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_31(XXX_CM_PASS_DN_30(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_UP_31(P,a,b,c,d,e,f,...) XXX_CM_PASS_UP_32(XXX_CM_PASS_DN_31(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_0(P,a,b,c,d,e,f,...) XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__ )
#define XXX_CM_DN_1(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_0 (XXX_CM_PASS_DN_0 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_2(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_1 (XXX_CM_PASS_DN_1 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_3(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_2 (XXX_CM_PASS_DN_2 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_4(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_3 (XXX_CM_PASS_DN_3 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_5(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_4 (XXX_CM_PASS_DN_4 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_6(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_5 (XXX_CM_PASS_DN_5 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_7(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_6 (XXX_CM_PASS_DN_6 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_8(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_7 (XXX_CM_PASS_DN_7 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_9(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_8 (XXX_CM_PASS_DN_8 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_10(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_9 (XXX_CM_PASS_DN_9 (XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_11(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_10(XXX_CM_PASS_DN_10(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_12(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_11(XXX_CM_PASS_DN_11(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_13(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_12(XXX_CM_PASS_DN_12(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_14(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_13(XXX_CM_PASS_DN_13(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_15(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_14(XXX_CM_PASS_DN_14(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_16(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_15(XXX_CM_PASS_DN_15(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_17(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_16(XXX_CM_PASS_DN_16(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_18(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_17(XXX_CM_PASS_DN_17(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_19(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_18(XXX_CM_PASS_DN_18(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_20(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_19(XXX_CM_PASS_DN_19(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_21(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_20(XXX_CM_PASS_DN_20(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_22(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_21(XXX_CM_PASS_DN_21(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_23(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_22(XXX_CM_PASS_DN_22(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_24(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_23(XXX_CM_PASS_DN_23(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_25(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_24(XXX_CM_PASS_DN_24(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_26(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_25(XXX_CM_PASS_DN_25(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_27(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_26(XXX_CM_PASS_DN_26(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_28(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_27(XXX_CM_PASS_DN_27(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_29(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_28(XXX_CM_PASS_DN_28(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_30(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_29(XXX_CM_PASS_DN_29(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_DN_31(P,a,b,c,d,e,f,...) XXX_CM_PASS_DN_30(XXX_CM_PASS_DN_30(XXX__##f(,P##a,P##b,P##c,P##d,P##e,P##__VA_ARGS__)))
#define XXX_CM_PASS_UP_1(x) XXX_CM_UP_1 x
#define XXX_CM_PASS_UP_2(x) XXX_CM_UP_2 x
#define XXX_CM_PASS_UP_3(x) XXX_CM_UP_3 x
#define XXX_CM_PASS_UP_4(x) XXX_CM_UP_4 x
#define XXX_CM_PASS_UP_5(x) XXX_CM_UP_5 x
#define XXX_CM_PASS_UP_6(x) XXX_CM_UP_6 x
#define XXX_CM_PASS_UP_7(x) XXX_CM_UP_7 x
#define XXX_CM_PASS_UP_8(x) XXX_CM_UP_8 x
#define XXX_CM_PASS_UP_9(x) XXX_CM_UP_9 x
#define XXX_CM_PASS_UP_10(x) XXX_CM_UP_10 x
#define XXX_CM_PASS_UP_11(x) XXX_CM_UP_11 x
#define XXX_CM_PASS_UP_12(x) XXX_CM_UP_12 x
#define XXX_CM_PASS_UP_13(x) XXX_CM_UP_13 x
#define XXX_CM_PASS_UP_14(x) XXX_CM_UP_14 x
#define XXX_CM_PASS_UP_15(x) XXX_CM_UP_15 x
#define XXX_CM_PASS_UP_16(x) XXX_CM_UP_16 x
#define XXX_CM_PASS_UP_17(x) XXX_CM_UP_17 x
#define XXX_CM_PASS_UP_18(x) XXX_CM_UP_18 x
#define XXX_CM_PASS_UP_19(x) XXX_CM_UP_19 x
#define XXX_CM_PASS_UP_20(x) XXX_CM_UP_20 x
#define XXX_CM_PASS_UP_21(x) XXX_CM_UP_21 x
#define XXX_CM_PASS_UP_22(x) XXX_CM_UP_22 x
#define XXX_CM_PASS_UP_23(x) XXX_CM_UP_23 x
#define XXX_CM_PASS_UP_24(x) XXX_CM_UP_24 x
#define XXX_CM_PASS_UP_25(x) XXX_CM_UP_25 x
#define XXX_CM_PASS_UP_26(x) XXX_CM_UP_26 x
#define XXX_CM_PASS_UP_27(x) XXX_CM_UP_27 x
#define XXX_CM_PASS_UP_28(x) XXX_CM_UP_28 x
#define XXX_CM_PASS_UP_29(x) XXX_CM_UP_29 x
#define XXX_CM_PASS_UP_30(x) XXX_CM_UP_30 x
#define XXX_CM_PASS_UP_31(x) XXX_CM_UP_31 x
#define XXX_CM_PASS_UP_32(x) XXX_CM_ERROR_NO_MORE_MACHINE_STATE x
#define XXX_CM_PASS_DN_0(x) XXX_CM_DN_0 x
#define XXX_CM_PASS_DN_1(x) XXX_CM_DN_1 x
#define XXX_CM_PASS_DN_2(x) XXX_CM_DN_2 x
#define XXX_CM_PASS_DN_3(x) XXX_CM_DN_3 x
#define XXX_CM_PASS_DN_4(x) XXX_CM_DN_4 x
#define XXX_CM_PASS_DN_5(x) XXX_CM_DN_5 x
#define XXX_CM_PASS_DN_6(x) XXX_CM_DN_6 x
#define XXX_CM_PASS_DN_7(x) XXX_CM_DN_7 x
#define XXX_CM_PASS_DN_8(x) XXX_CM_DN_8 x
#define XXX_CM_PASS_DN_9(x) XXX_CM_DN_9 x
#define XXX_CM_PASS_DN_10(x) XXX_CM_DN_10 x
#define XXX_CM_PASS_DN_11(x) XXX_CM_DN_11 x
#define XXX_CM_PASS_DN_12(x) XXX_CM_DN_12 x
#define XXX_CM_PASS_DN_13(x) XXX_CM_DN_13 x
#define XXX_CM_PASS_DN_14(x) XXX_CM_DN_14 x
#define XXX_CM_PASS_DN_15(x) XXX_CM_DN_15 x
#define XXX_CM_PASS_DN_16(x) XXX_CM_DN_16 x
#define XXX_CM_PASS_DN_17(x) XXX_CM_DN_17 x
#define XXX_CM_PASS_DN_18(x) XXX_CM_DN_18 x
#define XXX_CM_PASS_DN_19(x) XXX_CM_DN_19 x
#define XXX_CM_PASS_DN_20(x) XXX_CM_DN_20 x
#define XXX_CM_PASS_DN_21(x) XXX_CM_DN_21 x
#define XXX_CM_PASS_DN_22(x) XXX_CM_DN_22 x
#define XXX_CM_PASS_DN_23(x) XXX_CM_DN_23 x
#define XXX_CM_PASS_DN_24(x) XXX_CM_DN_24 x
#define XXX_CM_PASS_DN_25(x) XXX_CM_DN_25 x
#define XXX_CM_PASS_DN_26(x) XXX_CM_DN_26 x
#define XXX_CM_PASS_DN_27(x) XXX_CM_DN_27 x
#define XXX_CM_PASS_DN_28(x) XXX_CM_DN_28 x
#define XXX_CM_PASS_DN_29(x) XXX_CM_DN_29 x
#define XXX_CM_PASS_DN_30(x) XXX_CM_DN_30 x
#define XXX_CM_PASS_DN_31(x) XXX_CM_DN_31 x
#define XXX_CM_ERROR_NO_MORE_MACHINE_STATE()
#define XXX_CM(...) XXX_SCAN(XXX_SEQ_EAT XXX_LPAREN XXX_CM_UP_0(__VA_ARGS__))
#define XXX_CAT(a,b) a##b
#define XXX_PCAT(a,b) XXX_CAT(a,b)
#define XXX_STR(a) #a
#define XXX_PSTR(a) XXX_STR(a)
#define XXX_FX(f,...) f(__VA_ARGS__)
#define XXX_FX(f,...) f(__VA_ARGS__)
#define XXX_SCAN(...) __VA_ARGS__
#define XXX_NOSCAN(P,...) P##__VA_ARGS__
#define XXX_LPAREN (
#define XXX_TUPLE_AT_1(a,...) a
#define XXX_TUPLE_AT_2(a,b,...) b
#define XXX_SEQ_EAT(...)
#define XXX_SEQ_SPLAT(...) __VA_ARGS__,
#define XXX_SEQ_AT_1(P,x) XXX_SEQ_AT_1a(XXX_SEQ_SPLAT P##x)
#define XXX_SEQ_AT_1a(x) XXX_TUPLE_AT_1(x)
// Returns 1 if the identifiers x and y are equal and otherwise 0.
// For this to work a XXX_EQUAL_X_X must be defined to ",1", where X is the
// identifier that shall be compared.
#define XXX_EQUAL(x,y) XXX_CHECK(XXX_EQUAL_##x##_##y)
#define XXX_CHECK(...) XXX_TUPLE_AT_2(__VA_ARGS__,0,)
#define XXX_IS_0(x) XXX_CHECK(XXX_EQUAL_0_##x)
#define XXX_EQUAL_0_0 ,1
// Returns 1 if a is empty and otherwise 0.
#define XXX_IS_EMPTY(...) XXX_FX(XXX_TUPLE_AT_2,XXX_IS_EMPTY_EXPAND __VA_ARGS__ (),0,)
#define XXX_IS_EMPTY_EXPAND() ,1
// Returns 1 if a is empty and otherwise 0.
#define XXX_IS_EMPTY(...) XXX_FX(XXX_TUPLE_AT_2,XXX_IS_EMPTY_EXPAND __VA_ARGS__ (),0,)
#define XXX_IS_EMPTY_EXPAND() ,1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment