From a19a010d1e5a0d9bf474d2f432c977d30b25117e Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Wed, 21 Apr 2021 00:04:45 +0200 Subject: [PATCH] Add WIP version for a M_LET recursive --- m-core.h | 26 ++++++++++++++++---------- tests/test-mcore.c | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/m-core.h b/m-core.h index e9e114ef..8b6977db 100644 --- a/m-core.h +++ b/m-core.h @@ -2879,9 +2879,13 @@ static inline size_t m_core_cstr_hash(const char str[]) /* API transformation support: transform the call to the method into the supported API by the method. - Example of usage in oplist: ( INIT_WITH(API_1(method)) ) */ + Example of usage in oplist: ( INIT_WITH(API_1(method)) ) + NOTE: It uses M_RET_ARG3 instead of M_RET_ARG2 since M_GET_METHOD + uses M_RET_ARG2: to be able to use M_GET_METHOD within a M_APPLY_API + we need another macro to avoid being marked. +*/ #define M_APPLY_API(method, oplist, ...) \ - M_RET_ARG2(M_C(M_OPLAPI_INDIRECT_, method)(M_C(M_OPLAPI_EXTRACT_,method),oplist,__VA_ARGS__), method(__VA_ARGS__),) + M_RET_ARG3( , M_C(M_OPLAPI_INDIRECT_, method)(M_C(M_OPLAPI_EXTRACT_,method),oplist,__VA_ARGS__), M_DELAY2(method)(__VA_ARGS__),) /* API Transformation : 0: Method has been disable. It shall not be called. Raised an error. @@ -2889,16 +2893,18 @@ static inline size_t m_core_cstr_hash(const char str[]) API_2: by addr for first argument, API_3: oplist given, API_4 :by affectation for first argument, 5: API_by affectation + oplist API_6 :by addr for two arguments, 5: API_by address for both + oplist + + NOTE: It starts by a comma, to ack the success of the transformation. */ #define M_OPLAPI_ERROR(method, oplist, ...) , M_STATIC_FAILURE(M_LIB_DISABLED_METHOD, "The method has been explictly disabled for the requested operator, yet it has been called by the container") -#define M_OPLAPI_0(method, oplist, ...) , method(__VA_ARGS__) -#define M_OPLAPI_1(method, oplist, ...) , method(oplist, __VA_ARGS__) -#define M_OPLAPI_2(method, oplist, ...) , method(& __VA_ARGS__) -#define M_OPLAPI_3(method, oplist, ...) , method(oplist, &__VA_ARGS__) -#define M_OPLAPI_4(method, oplist, x, ...) , x = method(__VA_ARGS__) -#define M_OPLAPI_5(method, oplist, x, ...) , x = method(oplist, __VA_ARGS__) -#define M_OPLAPI_6(method, oplist, x, ...) , method(&x, &__VA_ARGS__) -#define M_OPLAPI_7(method, oplist, x, ...) , method(oplist, &x, &__VA_ARGS__) +#define M_OPLAPI_0(method, oplist, ...) , M_DELAY3(method)(__VA_ARGS__) +#define M_OPLAPI_1(method, oplist, ...) , M_DELAY3(method)(oplist, __VA_ARGS__) +#define M_OPLAPI_2(method, oplist, ...) , M_DELAY3(method)(& __VA_ARGS__) +#define M_OPLAPI_3(method, oplist, ...) , M_DELAY(method)(oplist, &__VA_ARGS__) +#define M_OPLAPI_4(method, oplist, x, ...) , x = M_DELAY3(method)(__VA_ARGS__) +#define M_OPLAPI_5(method, oplist, x, ...) , x = M_DELAY3(method)(oplist, __VA_ARGS__) +#define M_OPLAPI_6(method, oplist, x, ...) , M_DELAY3(method)(&x, &__VA_ARGS__) +#define M_OPLAPI_7(method, oplist, x, ...) , M_DELAY3(method)(oplist, &x, &__VA_ARGS__) /* API transformation support for indirection */ #define M_OPLAPI_INDIRECT_0 M_OPLAPI_ERROR #define M_OPLAPI_INDIRECT_API_0(...) M_OPLAPI_0 diff --git a/tests/test-mcore.c b/tests/test-mcore.c index efda592d..53a1111e 100644 --- a/tests/test-mcore.c +++ b/tests/test-mcore.c @@ -263,6 +263,30 @@ static void test_let(void) } assert(b); + // Test of recursive INIT_WITH within M_LET + // We need to use M_APPLY_APIA / M_APPLY_APIB for this. +#define OPL1 (TYPE(int), INIT_WITH(OPL1_F)) +#define OPL1_F(d, x) ((d) = (x)) +#define OPL2 (TYPE(int), INIT_WITH(API_1(OPL2_F)), OPLIST(OPL1) ) +#define OPL2_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) +#define OPL3 (TYPE(int), INIT_WITH(API_1(OPL3_F)), OPLIST(OPL2) ) +#define OPL3_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) +#define OPL4 (TYPE(int), INIT_WITH(API_1(OPL4_F)), OPLIST(OPL3) ) +#define OPL4_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) +#define OPL5 (TYPE(int), INIT_WITH(API_1(OPL5_F)), OPLIST(OPL4) ) +#define OPL5_F(opl, d, x) M_APPLY_API(M_GET_INIT_WITH M_GET_OPLIST opl, M_GET_OPLIST opl, d, x) + + M_LET( (x, 4585) , OPL1) + assert (x == 4585); + M_LET( (x, 4586) , OPL2) + assert (x == 4586); + M_LET( (x, 4587) , OPL3) + assert (x == 4587); + M_LET( (x, 4588) , OPL4) + assert (x == 4588); + M_LET( (x, 4589) , OPL5) + assert (x == 4589); + int c = 0; M_LET_IF( assert(c++ == 0), (assert(c++ == 1), true), assert(c++ == 3)) { assert(c++ == 2);