#ifndef CPP_EXT_0
#define CPP_EXT_0
+/*===========================================================================
+DEBUG
+===========================================================================*/
+
+#include <stdio.h>
+#define DEBUG_CPP
+#define STR(x) #x
+
+// print the macro and the evaluation of the macro
+#define SHOW(expr) printf("%s -> %s\n", #expr, STR(expr))
/*===========================================================================
Constants
===========================================================================*/
#define _CAT2(a ,b) a ## b
-#define CAT2(a ,b) _CAT(a ,b)
+#define CAT2(a ,b) _CAT2(a ,b)
#define _CAT3(a ,b ,c) a ## b ## c
-#define CAT3(a ,b ,c) _CAT(a ,b ,c)
+#define CAT3(a ,b ,c) _CAT3(a ,b ,c)
+
+#define _CAT4(a ,b ,c ,d) a ## b ## c ## d
+#define CAT4(a ,b ,c ,d) _CAT4(a ,b ,c ,d)
+
/*===========================================================================
Logic
Logic Connectors
===========================================================================*/
- #define _NOT_1(x_item) MATCH_RWR( _RWR_NOT__##x_item )
- #define _NOT(x_item) _NOT_1(x_item)
+ #define _NOT(x_item) \
+ MATCH_RWR( CAT2(_RWR_NOT__ ,x_item) )
- #define _AND_1(x_item ,y_item) MATCH_RWR( _RWR_AND__##x_item##__oo__##y_item )
- #define _AND(x_item ,y_item) _AND_1(x_item ,y_item)
+ #define _AND(x_item ,y_item) \
+ MATCH_RWR( CAT4(_RWR_AND__ ,x_item ,__oo__ ,y_item) )
- #define _OR_1(x_item ,y_item) NOT_MATCH_RWR( _RWR_OR__##x_item##__oo__##y_item )
- #define _OR(x_item ,y_item) _OR_1(x_item ,y_item)
+ #define _OR(x_item ,y_item) \
+ NOT_MATCH_RWR( CAT4(_RWR_OR__ ,x_item ,__oo__ ,y_item) )
- #define _BOOL_2(x_item) \
- _AND(\
- EXISTS_ITEM( _FIRST(x_item) ) \
- ,NOT_MATCH_RWR( _RWR_EQ__0__oo__##x_item) \
+ #define _BOOL(x_item) \
+ _AND( \
+ EXISTS_ITEM( x_item ) \
+ ,NOT_MATCH_RWR( CAT2(_RWR_EQ__0__oo__ ,x_item) ) \
)
- #define _BOOL_1(x_item) _BOOL_2(x_item)
- #define BOOL(x_item) _BOOL_1(_FIRST(x_item))
-
- #define NOT(x_item) _NOT(BOOL(x_item))
+ #define BOOL(x_item) _BOOL(_FIRST(x_item))
+
+ #define NOT(x_item) _NOT(BOOL(x_item))
#define AND(x_item ,y_item) _AND(BOOL(x_item) ,BOOL(y_item))
- #define OR(x_item ,y_item) _OR(BOOL(x_item) ,BOOL(y_item))
+ #define OR(x_item ,y_item) _OR(BOOL(x_item) ,BOOL(y_item))
/*===========================================================================
Equality
===========================================================================*/
- #define _EQ(x_item ,y_item) MATCH_RWR( _RWR_EQ__##x_item##__oo__##y_item )
- #define EQ(x_item ,y_item) _EQ(x_item ,y_item)
+ #define EQ(x_item ,y_item) \
+ MATCH_RWR( CAT4(_RWR_EQ__ ,x_item ,__oo__ ,y_item) )
+
+ #define NOT_EQ(x_item ,y_item) \
+ NOT_MATCH_RWR( CAT4(_RWR_EQ__ ,x_item ,__oo__ ,y_item) )
+
+#if 0
+
- #define _NOT_EQ(x_item ,y_item) EXISTS(_RWR_EQ__##x_item##__oo__##y_item)
- #define NOT_EQ(x_item ,y_item) _NOT_EQ(x_item ,y_item)
/*===========================================================================
IF-ELSE construct.
A most amazing little macro. It has no dependencies on the other macros
in this file, though many will be useful for setting (condition)
- The seemingly extra layer prevents BOOL_(condition) from being pasted
- with a ## which, if done, would prevent it from being evaluated. Recall,
- the first step in evaluation is a literal copy in of the arguments.
-===========================================================================*/
+ The seemingly extra layer prevents BOOL_(condition) from being pasted with a ## which, if done, would prevent it from being evaluated. Recall, the first step in evaluation is a literal copy in of the arguments. ===symbol ========================================================================*/
- #define IF_ELSE(condition) _IF_ELSE(BOOL(condition))
- #define _IF_ELSE(condition) __IF_ELSE(condition)
- #define __IF_ELSE(condition) _IF_##condition
+ #define _IF_ELSE(condition) CAT2(_IF_ ,BOOL(condition))
#define _IF_1(...) __VA_ARGS__ _IF_1_ELSE
#define _IF_0(...) _IF_0_ELSE
#define _IF_1_ELSE(...)
#define _IF_0_ELSE(...) __VA_ARGS__
+
/*===========================================================================
Access
see below the recursion section for Nth .. when it is written ;-)
(pad) \
( _THIRD(__VA_ARGS__ ,pad, pad) )
-
+#endif
#endif
-#include <stdio.h>
-#define STR(x) #x
-// no evaluation, and one pass of evaluation
-#define SHOW(expr) printf("%s --> %s\n", #expr, STR(expr))
-
#include "cpp_ext_0.c"
-// Patch for CAT to succeed
-#define FOOBAR 12345
+#define F 1
+#define O1 2
+#define O2 3
+#define B 4
+#define A 5
+#define R 6
+#define D 7
+
// Patch for _EXISTS to succeed on 0
#define _REWRITE_TWION_0 _REWRITE_TWION
int main(void){
+ printf("try_1_exists\n\n");
// Constant macros
int x COMMA y = 1; // Tests that COMMA = ,
+ printf("y? %d\n", y);
+ printf("\n");
// Token paste test
- int _cat_result = FOOBAR; // _CAT(FOO ,BAR) → FOOBAR → 12345
- printf("_CAT(FOO ,BAR) → %d\n", _cat_result);
+ int _cat_result = CAT2(CAT3(F ,O1 ,O2) ,CAT4(B ,A ,R ,D));
+ printf("FOOBARD %d\n" ,_cat_result);
printf("\n");
// Selector macros
-#include <stdio.h>
-#define STR(x) #x
-// no evaluation, and one pass of evaluation
-#define SHOW(expr) printf("%s --> %s\n", #expr, STR(expr))
-
#include "cpp_ext_0.c"
int main(void){
SHOW( NOT_MATCH(x0) );
printf("\n");
-
//--------------------------------------------------------------------------
// Primitive Connectors
//--------------------------------------------------------------------------
SHOW( _OR(1 ,1) ); // rule missing → NOT_MATCH → 1
printf("\n");
- //--------------------------------------------------------------------------
- // Equality
- //--------------------------------------------------------------------------
-
- SHOW( _EQ(0 ,0) ); // rule defined → MATCH → 1
- SHOW( _EQ(1 ,1) ); // rule defined → MATCH → 1
- SHOW( _EQ(0 ,1) ); // no rule → MATCH fails → 0
- SHOW( _EQ(x ,x) ); // no rule → MATCH fails → 0
- printf("\n");
-
- SHOW( _NOT_EQ(0 ,1) ); // rule missing → EXISTS → 1
- SHOW( _NOT_EQ(0 ,0) ); // rule exists → EXISTS → 0
- printf("\n");
-
//--------------------------------------------------------------------------
// Logical Connectors (BOOL + AND/OR/NOT)
//--------------------------------------------------------------------------
- SHOW( _BOOL_2(0) ); // 0
- SHOW( _BOOL_2(1) ); // 1
- SHOW( _BOOL_2(2) ); // 1 because it exists
- SHOW( _BOOL_2(x0) ); // 0 because it does not exit (see the #define at the top)
+ printf("x0 is a macro with an empty definition");
+
+ SHOW( _BOOL(0) ); // 0
+ SHOW( _BOOL(1) ); // 1
+ SHOW( _BOOL(2) ); // 1 because it exists
+ SHOW( _BOOL(x0) ); // 0 because it does not exit (see the #define at the top)
printf("\n");
SHOW( BOOL(0) ); // _FIRST = 0, EXISTS_ITEM(_FIRST) = 0 → _AND(0 ,1) → 0
--- /dev/null
+#include "cpp_ext_0.c"
+
+int main(void){
+
+ //---------------------------------------------------------------------------
+ // EQ Tests — identity and mismatch
+ //---------------------------------------------------------------------------
+
+ SHOW(EQ(0 ,0)); // Expected → 1
+ SHOW(EQ(1 ,1)); // Expected → 1
+ SHOW(EQ(0 ,1)); // Expected → 0
+ SHOW(EQ(1 ,0)); // Expected → 0
+
+ SHOW(EQ(x ,x)); // Expected → 0 (no _RWREQ__x__oo__x defined)
+ SHOW(EQ(x ,y)); // Expected → 0
+
+ //---------------------------------------------------------------------------
+ // NOTEQ Tests — inverse behavior
+ //---------------------------------------------------------------------------
+
+ SHOW(NOT_EQ(0 ,0)); // Expected → 0 (because EQ → 1, so EXISTS → 0)
+ SHOW(NOT_EQ(1 ,1)); // Expected → 0
+ SHOW(NOT_EQ(0 ,1)); // Expected → 1
+ SHOW(NOT_EQ(1 ,0)); // Expected → 1
+
+ SHOW(NOT_EQ(x ,x)); // Expected → 1 (EQ not defined → NOTEQ = 1)
+ SHOW(NOT_EQ(x ,y)); // Expected → 1
+
+ //---------------------------------------------------------------------------
+ // Mixed cases with macros
+ //---------------------------------------------------------------------------
+
+ #define XSYM 0
+ #define YSYM 1
+
+ SHOW(EQ(XSYM ,XSYM)); // Expected → 1 (0,0)
+ SHOW(EQ(XSYM ,YSYM)); // Expected → 0 (0,1)
+ SHOW(NOT_EQ(XSYM ,YSYM)); // Expected → 1
+
+ SHOW(EQ(XSYM ,0)); // Expected → 1
+ SHOW(EQ(XSYM ,1)); // Expected → 0
+
+ SHOW(NOT_EQ(YSYM ,0)); // Expected → 1
+ SHOW(NOT_EQ(YSYM ,1)); // Expected → 0
+
+ //---------------------------------------------------------------------------
+ // Edge case: undefined symbol
+ //---------------------------------------------------------------------------
+
+ SHOW(EQ(z ,z)); // Expected → 0
+ SHOW(NOT_EQ(z ,z)); // Expected → 1
+
+ printf("\n");
+ return 0;
+}
+++ /dev/null
-#include <stdio.h>
-#define STR(x) #x
-// no evaluation, and one pass of evaluation
-#define SHOW(expr) printf("%s --> %s\n", #expr, STR(expr))
-
-#include "cpp_ext_0.c"
-
-int main(void){
-
- //---------------------------------------------------------------------------
- // Basic boolean cases
- //---------------------------------------------------------------------------
-
- SHOW(IF_ELSE(1)(yes)(no));
-#if 0
- SHOW(IF_ELSE(0)(yes)(no)); // → no
-
- //---------------------------------------------------------------------------
- // Symbolic identifiers
- //---------------------------------------------------------------------------
- SHOW(IF_ELSE(TRUE)(ok)(fail)); // → ok
- SHOW(IF_ELSE(FALSE)(ok)(fail)); // → fail
- SHOW(IF_ELSE(foo)(alpha)(omega)); // → omega (foo is undefined)
-
- //---------------------------------------------------------------------------
- // Logic expressions
- //---------------------------------------------------------------------------
- SHOW(IF_ELSE(AND(1 ,1))(pass)(fail)); // → pass
- SHOW(IF_ELSE(OR(0 ,0))(yes)(no)); // → no
- SHOW(IF_ELSE(NOT(0))(on)(off)); // → on
-
- //---------------------------------------------------------------------------
- // Code-like output
- //---------------------------------------------------------------------------
- SHOW(IF_ELSE(1)(int x = 1;)(int x = 2;)); // → int x = 1;
- SHOW(IF_ELSE(0)(int x = 1;)(int x = 2;)); // → int x = 2;
-
- //---------------------------------------------------------------------------
- // Comma usage in true/false branches
- //---------------------------------------------------------------------------
- SHOW(IF_ELSE(1)(a ,b ,c)(x ,y ,z)); // → a ,b ,c
- SHOW(IF_ELSE(0)(a ,b ,c)(x ,y ,z)); // → x ,y ,z
-
- //---------------------------------------------------------------------------
- // Empty condition
- //---------------------------------------------------------------------------
- SHOW(IF_ELSE()(true)(false)); // → false (BOOL() = 0)
-
- //---------------------------------------------------------------------------
- // Nested IF_ELSE
- //---------------------------------------------------------------------------
- SHOW(
- IF_ELSE(AND(1 ,1))(
- IF_ELSE(0)(inner_true)(inner_false)
- )(
- outer_false
- )
- ); // → inner_false
-
-#endif
- return 0;
-}
--- /dev/null
+#include "cpp_ext_0.c"
+
+int main(void){
+
+ //---------------------------------------------------------------------------
+ // Basic boolean cases
+ //---------------------------------------------------------------------------
+
+ SHOW(IF_ELSE(1)(yes)(no));
+#if 0
+ SHOW(IF_ELSE(0)(yes)(no)); // → no
+
+ //---------------------------------------------------------------------------
+ // Symbolic identifiers
+ //---------------------------------------------------------------------------
+ SHOW(IF_ELSE(TRUE)(ok)(fail)); // → ok
+ SHOW(IF_ELSE(FALSE)(ok)(fail)); // → fail
+ SHOW(IF_ELSE(foo)(alpha)(omega)); // → omega (foo is undefined)
+
+ //---------------------------------------------------------------------------
+ // Logic expressions
+ //---------------------------------------------------------------------------
+ SHOW(IF_ELSE(AND(1 ,1))(pass)(fail)); // → pass
+ SHOW(IF_ELSE(OR(0 ,0))(yes)(no)); // → no
+ SHOW(IF_ELSE(NOT(0))(on)(off)); // → on
+
+ //---------------------------------------------------------------------------
+ // Code-like output
+ //---------------------------------------------------------------------------
+ SHOW(IF_ELSE(1)(int x = 1;)(int x = 2;)); // → int x = 1;
+ SHOW(IF_ELSE(0)(int x = 1;)(int x = 2;)); // → int x = 2;
+
+ //---------------------------------------------------------------------------
+ // Comma usage in true/false branches
+ //---------------------------------------------------------------------------
+ SHOW(IF_ELSE(1)(a ,b ,c)(x ,y ,z)); // → a ,b ,c
+ SHOW(IF_ELSE(0)(a ,b ,c)(x ,y ,z)); // → x ,y ,z
+
+ //---------------------------------------------------------------------------
+ // Empty condition
+ //---------------------------------------------------------------------------
+ SHOW(IF_ELSE()(true)(false)); // → false (BOOL() = 0)
+
+ //---------------------------------------------------------------------------
+ // Nested IF_ELSE
+ //---------------------------------------------------------------------------
+ SHOW(
+ IF_ELSE(AND(1 ,1))(
+ IF_ELSE(0)(inner_true)(inner_false)
+ )(
+ outer_false
+ )
+ ); // → inner_false
+
+#endif
+ return 0;
+}