From 605ce9b9381e29c22cf391a38b0f639134b2219e Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Sat, 14 Dec 2019 11:12:59 +0100 Subject: [PATCH] * Update version * Update comments * Improve robustness --- m-core.h | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/m-core.h b/m-core.h index 3d7d31a1..3b8c6ddf 100644 --- a/m-core.h +++ b/m-core.h @@ -51,8 +51,8 @@ /* Define M*LIB version */ #define M_CORE_VERSION_MAJOR 0 -#define M_CORE_VERSION_MINOR 2 -#define M_CORE_VERSION_PATCHLEVEL 3 +#define M_CORE_VERSION_MINOR 3 +#define M_CORE_VERSION_PATCHLEVEL 0 /* M_ASSUME is equivalent to assert, but gives hints to compiler about how to optimize the code if NDEBUG is defined. @@ -110,6 +110,7 @@ extern void m_no_default_function(void) __attribute__((error("The requested op #define M_NO_DEFAULT(...) m_no_default_function() #endif + /***************************************************************/ /****************** Preprocessing Times Macro ******************/ /***************************************************************/ @@ -187,14 +188,14 @@ extern void m_no_default_function(void) __attribute__((error("The requested op #define M_INC_50 51 #define M_INC_51 52 #define M_INC_52 53 -#define M_INC_53 OVERFLOW +#define M_INC_53 M_INC_overflow_detected /* Decrement the number given in argument (from [0..52[) Generated by: for i in $(seq 1 52) ; do printf "#define M_DEC_%d %d\n" $i $(($i - 1)) ; done */ #define M_DEC(x) M_C(M_DEC_, x) -#define M_DEC_0 overflow +#define M_DEC_0 M_DEC_underflow_detected #define M_DEC_1 0 #define M_DEC_2 1 #define M_DEC_3 2 @@ -251,8 +252,8 @@ extern void m_no_default_function(void) __attribute__((error("The requested op /* Add two integers. Generated by: for i in $(seq 0 52) ; do printf "#define M_ADDI_%d(n) " $i ; for j in $(seq 1 $i) ; do printf "M_INC(";done ; printf "n" ; for j in $(seq 1 $i) ; do printf ")" ;done ; printf "\n" ; done */ -#define M_ADDI(f, n) f(n) -#define M_ADD(x,y) M_ADDI(M_C(M_ADDI_, y), x) +#define M_ADD(x,y) M_ADDI(M_C(M_ADDI_, y), x) +#define M_ADDI(f,n) f(n) #define M_ADDI_0(n) n #define M_ADDI_1(n) M_INC(n) #define M_ADDI_2(n) M_INC(M_INC(n)) @@ -310,8 +311,8 @@ extern void m_no_default_function(void) __attribute__((error("The requested op /* Substract two integers. Generated by: for i in $(seq 0 52) ; do printf "#define M_SUBI_%d(n) " $i ; for j in $(seq 1 $i) ; do printf "M_DEC(";done ; printf "n" ; for j in $(seq 1 $i) ; do printf ")" ;done ; printf "\n" ; done */ -#define M_SUBI(f, n) f(n) -#define M_SUB(x,y) M_SUBI(M_C(M_SUBI_, y), x) +#define M_SUB(x,y) M_SUBI(M_C(M_SUBI_, y), x) +#define M_SUBI(f,n) f(n) #define M_SUBI_0(n) n #define M_SUBI_1(n) M_DEC(n) #define M_SUBI_2(n) M_DEC(M_DEC(n)) @@ -366,7 +367,7 @@ extern void m_no_default_function(void) __attribute__((error("The requested op #define M_SUBI_51(n) M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(n))))))))))))))))))))))))))))))))))))))))))))))))))) #define M_SUBI_52(n) M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(M_DEC(n)))))))))))))))))))))))))))))))))))))))))))))))))))) -/* Return the nth argument. +/* Return the nth argument (either variable or static). Generated by: for i in $(seq 1 53 ) ; do printf "#define M_RETI_ARG%d(" $i; for j in $(seq 1 $i) ; do printf "_%d, " $j ; done ; printf "...) _%d\n#define M_RET_ARG%d(...) M_RETI_ARG%d(__VA_ARGS__)\n\n" $i $i $i ; done */ @@ -752,22 +753,23 @@ extern void m_no_default_function(void) __attribute__((error("The requested op #define M_INVI_1 0 #define M_INV(x) M_C(M_INVI_, x) -/* Perform a AND between the inputs */ +/* Perform a AND between the boolean inputs */ #define M_ANDI_00 0 #define M_ANDI_01 0 #define M_ANDI_10 0 #define M_ANDI_11 1 #define M_AND(x,y) M_C3(M_ANDI_, x, y) -/* Perform a OR between the inputs */ +/* Perform a OR between the boolean inputs */ #define M_ORI_00 0 #define M_ORI_01 1 #define M_ORI_10 1 #define M_ORI_11 1 #define M_OR(x,y) M_C3(M_ORI_, x, y) + /* M_IF Macro : - M_IF(condition)(Execute if true, execute if false) + M_IF(condition)(Block if true, Block if false) Example: M_IF(0)(true_action, false_action) --> false_action */ #define M_IFI_0(true_macro, ...) __VA_ARGS__ #define M_IFI_1(true_macro, ...) true_macro @@ -775,13 +777,13 @@ extern void m_no_default_function(void) __attribute__((error("The requested op /* Return 1 if there is a comma inside the argument list, 0 otherwise. */ -#define M_COMMA_P(...) M_RET_ARG53(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, useless) +#define M_COMMA_P(...) M_RET_ARG76(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, useless) /* Return the string representation of the evaluated x. NOTE: Need to be used with M_APPLY to defer the evaluation */ #define M_AS_STR(x) #x -/* Return 1 if the argument is 'empty', 0 otherwise. +/* Return 1 if the argument is empty (aka ''), 0 otherwise. Handle: EMPTY_P(), EMPTY_P(x), EMPTY_P(()) and EMPTY_P(,) and EMPTY_P(f) with #define f() 2,3 */ #define M_EMPTYI_DETECT(...) 0, 1, #define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ () ) @@ -899,8 +901,8 @@ extern void m_no_default_function(void) __attribute__((error("The requested op #define M_MAP2(f, d, ...) M_MAP2I(M_C(M_MAP2B_, M_NARGS(__VA_ARGS__)), f, d, __VA_ARGS__) #define M_MAP2I(F,...) F (__VA_ARGS__) -/* Duplicate for GET_METHOD as it may be called in context where a M_MAP2 is in progress. - NOTE: Increase number of arguments to 52 due to the number of available methods. +/* Duplicate for GET_METHOD as it may be called in context where a M_MAP2 is in progress (for oplist). + NOTE: Increase number of arguments to 76 due to the number of available methods. NOTE: Rewrite with another approach much more verbose but also much faster for the compiler. This kind of approach seems ugly, but is in fact the fast one. NOTE: Do not call recursively the macro (example: M_MAP2B_10 expands f(d,e) then call M_MAP2B_9 on what remains to break as soon as possible the macro "chain". @@ -1252,7 +1254,7 @@ extern void m_no_default_function(void) __attribute__((error("The requested op #define M_DEFAULT_ARGS_EVAL(...) __VA_ARGS__ #define M_DEFAULT_ARGS( ...) M_DEFAULT_ARGS_EVAL(M_DEFAULT_ARGS2(__VA_ARGS__)) -/* NOTEQUAL(val1,val2) with val from [0 to 30[ +/* NOTEQUAL(val1,val2) with val from [0 to 52[ Return 1 or 0 if val1=val2 */ #define M_NOTEQUAL_0_0 0 @@ -1310,7 +1312,7 @@ extern void m_no_default_function(void) __attribute__((error("The requested op #define M_NOTEQUAL_52_52 0 #define M_NOTEQUAL(x,y) M_BOOL(M_C4(M_NOTEQUAL_, x, _, y)) -/* EQUAL(val1,val2) with valN from [0 to 30[ +/* EQUAL(val1,val2) Return 1 if val1=val2 or 0 Example: M_EQUAL(1,2) --> 0 */