- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
// https://github.com/AlexCeleste/C99-Lambda
// # C99-Lambda: nested functions, lambdas, and closures, in ISO C99
// https://github.com/AlexCeleste/C99-Lambda/blob/57583080392d5f3f626034bbb3292eb0070ba304/c_lambda.h#L110
// Internal lambda builder functions
#define FN_8CL_ARG_TYPE(T) , T
#define FN_8FEXP(call, p, f, R) { FN_8GETTYPE_8fn f = fn f; call(M_ID p M_IF(M_2ORMORE R, (_fun, M_REST_ R), (_fun))); }
#define FN_8CLEXP(call, p, c, R) { void * _fun = cl c; call(M_ID p M_IF(M_2ORMORE R, (_fun, M_REST_ R), (_fun))); }
#define FN_8EMIT_NS(N, H, B, Q) FN_8EMIT_NS_((FN_8GET_NL(N, B)), H, (M_ZIP_W2(FN_8EMIT_ELEM, B, M_ILIST)), Q)
#define FN_8EMIT_NS_(NL, H, BL, Q) (8ZIPNE,(NL, BL, Q), FN_8EMIT_BODY(NL, H, BL))
#define FN_8GET_NL(N, B) M_ZIP_W2(FN_8GET_NL_1, M_ENLIST(_8anon_##N##_, M_NARGS B), M_ILIST)
#define FN_8GET_NL_1(A, B) , M_CONC_(A, B)
#define FN_8EMIT_BODY(NL, H, BL) M_ID H M_ZIP_WITH(FN_8EMIT_BLOCK, BL, NL)
#define FN_8EMIT_ELEM(E, _) ,M_CONC_(FN_8EMIT_, E)
#define FN_8EMIT_8blk(...) (1, 0, __VA_ARGS__)
#define FN_8EMIT_8fn(...) (0, 0, __VA_ARGS__)
#define FN_8EMIT_8cl(...) (0, 1, __VA_ARGS__)
#define FN_8EMIT_BLOCK(P, N) M_IF(M_FIRST P, (M_REST2 P), (FN_8EMIT_NAME((M_REST P, r, a, o), N)))
#define FN_8EMIT_NAME(P, N) M_IF(M_FIRST P, (FN_8EMIT_CL(N, M_ID P)), (N))
#define FN_8EMIT_CL(...) FN_8EMIT_CL_(__VA_ARGS__)
#define FN_8EMIT_CL_(n, _, r, a, o, ...) (void*)&(struct n##_env_t){ \
n,sizeof(struct n##_env_t) M_FOR_EACH(FN_8CL_SND, M_ID o) }
#define FN_8CL_SND(P) , M_REST_ P
#define FN_8EMIT_ENV(E, Q) (8DO_Q, (Q), FN_8EMIT_ENV_(E))
#define FN_8EMIT_ENV_(n, rt, a, o) struct n##_env_t { \
FN_8CTYPE(rt, n, a, _fun); size_t _size; M_FOR_EACH(FN_8FLDS, M_ID o) };
#define FN_8FLDS(F) M_FIRST_ F M_REST_ F;
#define FN_8CL_DEC(rt, n, a) static rt n(void * _envV, M_ID a) { struct n##_env_t * _env = _envV;
#define FN_8FTYPE(rt, C, a, pn) rt(* C pn)a
#define FN_8CTYPE(rt, n, a, pn) rt(* pn)(void *, M_ID a)
#define FN_8FN_TYPE(F) M_CONC(FN_8GETTYPE_, M_FIRST(M_REST((F))))
#define FN_8GETTYPE_8fn(rt, a, ...) rt(* _fun)a
#define FN_8CLSZ(T, N) T M_CONC(_, N);
#define FN_8ZIPNE(NL, BL, Q) (8FLTNE, ((M_ZIP_W2(FN_8ZIPNE_, NL, BL)), Q))
#define FN_8ZIPNE_(N, B) ,(M_FIRST_ B, N, M_REST_ B)
#define FN_8FLTNE(EL, Q) (8POPEM, ((0 M_FOR_EACH(FN_8FLTNE_, M_ID EL)), Q))
#define FN_8FLTNE_(E) M_IF(M_FIRST_ E, (), (,(M_REST_ E)))
#define FN_8POPEM(FL, Q) M_IF(M_2ORMORE(M_ID FL), ((8F2NS, ((M_REST_ FL), Q))), ((8DO_Q, (Q))))
#define FN_8F2NS(FL, Q) (8DO_Q, ((M_FOR_E2(FN_8F2NS_1, M_ID FL), M_ID Q)))
#define FN_8F2NS_1(F) ,FN_8F2NS_2 F
#define FN_8F2NS_2(n, isC, rt, a, ...) M_IF(isC, \
((8EMIT_NS_NX, (n, (FN_8CL_DEC(rt, n, a)), M_REST(__VA_ARGS__))), (8EMIT_ENV,(n, rt, a, M_FIRST(__VA_ARGS__)))), \
((8EMIT_NS_NX, (n, (static rt n a), __VA_ARGS__))))
#define FN_8DO_Q(Q) (M_ID(M_FIRST_ M_FIRST_ Q),(M_ID M_REST_ M_FIRST_ Q, (M_REST_ Q)))
#define FN_8EMIT_NS_NX(...) (8EMIT_NS, (__VA_ARGS__))