working cpp_ext_0 and cpp_ext_1
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Tue, 1 Apr 2025 05:09:09 +0000 (05:09 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Tue, 1 Apr 2025 05:09:09 +0000 (05:09 +0000)
developer/cc🖉/Binding.lib.c
developer/cc🖉/TM.lib.c
developer/cc🖉/cpp_ext.c
developer/cc🖉/cpp_ext_0.c
developer/cc🖉/cpp_ext_1.c
developer/document🖉/cpp_CAT_and_comma.org [new file with mode: 0644]
developer/document🖉/cpp_gothyas.txt
developer/example_cpp/try_ext_1.c

index cdf6bb5..4296c2e 100644 (file)
@@ -25,7 +25,7 @@ Template parameters:
 
 // once per Binding·TYPE value
 #ifdef Binding·TYPE
-#if NOT( FIND_ITEM(Binding·TYPE ,Binding·TYPE_LIST) )
+#if NOT_CONTAINS(Binding·TYPE ,Binding·TYPE_LIST) )
 #pragma message( STR_VAL(Binding·TYPE) )
 
   //this is what it takes to append to a list in cpp ...
index 75d54af..3300f37 100644 (file)
@@ -59,7 +59,7 @@
 
 // once per TM·CVT value
 #ifdef TM·CVT
-#if ! FIND_ITEM( TM·CVT ,TM·TYPE_LIST )
+#if NOT_CONTAINS( TM·CVT ,TM·TYPE_LIST )
 #define TM·TYPE_LIST APPEND(TM·TYPE_LIST ,TM·TYPE)
 
   // declare 'TM' as a type
index 680bbf5..b1bb1d1 100644 (file)
@@ -6,9 +6,8 @@
  #include "cpp_ext_1.c"
 
   /*
-    Types must be registered with predicates.
+    CONTAINS requires registration of pattern, as examples:
 
-    // all legal FG·Type are registered here
     #define EQ__int__oo__int
     #define EQ__float__oo__float
     #define EQ__char__oo__char
 
   */
  
-  #define FIRST_SEEN(type ,list) \
-    NOT(FIND_ITEM(type ,list)) )
-
- // CAT(SEP, ...) will soon be added to cpp_ext_1, then this will be:
- // #define Ξ(...)  CAT(· ,__VA_ARGS__)
-
-  // Individual macros for specific argument counts
-  #define _Ξ0() 
-  #define Ξ0() _Ξ0()
-
-  #define _Ξ1(a) a
-  #define Ξ1(a) _Ξ1(a)
-
-  #define _Ξ2(a ,b) a##·##b
-  #define Ξ2(a ,b) _Ξ2(a ,b)
-
-  #define _Ξ3(a ,b ,c) a##·##b##·##c
-  #define Ξ3(a ,b ,c) _Ξ3(a ,b ,c)
-
-  #define _Ξ4(a ,b ,c ,d) a##·##b##·##c##·##d
-  #define Ξ4(a ,b ,c ,d) _Ξ4(a ,b ,c ,d)
-
-  #define _Ξ5(a ,b ,c ,d ,e) a##·##b##·##c##·##d##·##e
-  #define Ξ5(a ,b ,c ,d ,e) _Ξ5(a ,b ,c ,d ,e)
-
-  #define _Ξ6(a ,b ,c ,d ,e ,f) a##·##b##·##c##·##d##·##e##·##f
-  #define Ξ6(a ,b ,c ,d ,e ,f) _Ξ6(a ,b ,c ,d ,e ,f)
-
-  #define _Ξ7(a ,b ,c ,d ,e ,f ,g) a##·##b##·##c##·##d##·##e##·##f##·##g
-  #define Ξ7(a ,b ,c ,d ,e ,f ,g) _Ξ7(a ,b ,c ,d ,e ,f ,g)
-
-  #define _Ξ8(a ,b ,c ,d ,e ,f ,g ,h) a##·##b##·##c##·##d##·##e##·##f##·##g##·##h
-  #define Ξ8(a ,b ,c ,d ,e ,f ,g ,h) _Ξ8(a ,b ,c ,d ,e ,f ,g ,h)
-
-  #define _Ξ9(a ,b ,c ,d ,e ,f ,g ,h ,i) a##·##b##·##c##·##d##·##e##·##f##·##g##·##h##·##i
-  #define Ξ9(a ,b ,c ,d ,e ,f ,g ,h ,i) _Ξ9(a ,b ,c ,d ,e ,f ,g ,h ,i)
-
-  #define _Ξ10(a ,b ,c ,d ,e ,f ,g ,h ,i ,j) a##·##b##·##c##·##d##·##e##·##f##·##g##·##h##·##i##·##j
-  #define Ξ10(a ,b ,c ,d ,e ,f ,g ,h ,i ,j) _Ξ10(a ,b ,c ,d ,e ,f ,g ,h ,i ,j)
-
-  // Argument counting mechanism
-  #define _ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N
-  #define COUNT_ARGS(...) _ARG_N(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
-
-  // Macro name concatenation
-  #define _CONCAT(a, b) a##b
-  #define CONCAT(a, b) _CONCAT(a, b)
-
-  // Selector that chooses the right macro based on argument count
-  #define Ξ_EXPAND(count, ...) CONCAT(Ξ, count)(__VA_ARGS__)
-  #define Ξ(...) Ξ_EXPAND(COUNT_ARGS(__VA_ARGS__), __VA_ARGS__)
+  #define NOT_CONTAINS(item ,list) BOOL( NOT(CONTAINS(item ,list)) )
 
+  #define Ξ(...)  CAT(· ,__VA_ARGS__)
 
 #endif 
index e196e92..635bab9 100644 (file)
@@ -34,7 +34,7 @@ DEBUG
 #define STR_VAL(...) #__VA_ARGS__ " -> " VAL(__VA_ARGS__)
 
 // print the macro and the evaluation of the macro at run time:
-#define SHOW(expr) printf("%s -> %s\n", #expr, STR(expr))
+#define SHOW(expr) printf("%s -> %s\n", #expr, STR(expr));
 
 /*===========================================================================
 Constants
index 5f8a5b4..63d63f7 100644 (file)
@@ -56,12 +56,12 @@ DROPE_EMPTY_RIGHT
     m RETURN_NOTHING RETURN_NOTHING RETURN_NOTHING RETURN_NOTHING RETURN_NOTHING()()()()()
 
 /*===========================================================================
-  Find an item in a list
+  List operations
 
-  number of EVALs required depends upon length of not found list prefix
+  number of EVALs required depends upon length list that is processed
 
-  REST will return nothing on one of two conditions, that the list has
-  been exhausted, or that the list is about to exhausted, it has nothing
+  REST will return nothing on one of two conditions: that the list has
+  been exhausted, or that the list is about to be exhausted and it has nothing
   after the last comma. To assure that a tailing item always gets sent
   to the predicate, even when empty, we append an empty item.
 
@@ -95,17 +95,17 @@ DROPE_EMPTY_RIGHT
   #define WHILE(predicate ,...) EVAL( _WHILE(predicate ,__VA_ARGS__ ,) )
 
   // returns true or false
-  #define _HAS_ITEM(item ,...) \
+  #define _CONTAINS(item ,...) \
     IF \
       (__VA_ARGS__) \
       (IF \
         ( EQ(item ,_FIRST(__VA_ARGS__)) ) \
         ( 1 ) \
-        ( DEFER3(_HAS_ITEM_CONFEDERATE)()(item ,REST(__VA_ARGS__)) ) \
+        ( DEFER3(_CONTAINS_CONFEDERATE)()(item ,REST(__VA_ARGS__)) ) \
         ) \
       () 
-  #define _HAS_ITEM_CONFEDERATE() _HAS_ITEM
-  #define HAS_ITEM(predicate ,...) EVAL( _HAS_ITEM(predicate ,__VA_ARGS__ ,) )
+  #define _CONTAINS_CONFEDERATE() _CONTAINS
+  #define CONTAINS(predicate ,...) EVAL( _CONTAINS(predicate ,__VA_ARGS__ ,) )
 
   // if no list, returns EOL(), else returns last item in the list
   #define _LAST(...) \
@@ -121,26 +121,25 @@ DROPE_EMPTY_RIGHT
   #define _LAST_s_CONFEDERATE() _LAST_s
   #define LAST(...) EVAL( _LAST(__VA_ARGS__ ,) )
 
-  // join tokens with a separator in between, separator can have nothing as a value
-
-
-#define _CAT(sep ,...) \
-  IF \
-    (__VA_ARGS__) \
-    (_CAT_s(sep ,__VA_ARGS__)) \
-    ()
-
-#define _CAT_s(sep ,a ,...) \
-  IF \
-    (__VA_ARGS__) \
-    ( CAT3( a ,sep ,DEFER5(_CAT_s_CONFEDERATE())(sep ,__VA_ARGS__)) )  \
-    (a)
-
-#define _CAT_s_CONFEDERATE() _CAT_s
+  #define CAT(sep ,...) \
+    IF \
+      (__VA_ARGS__) \
+      (_CAT_s(sep ,__VA_ARGS__))   \
+      ()
 
-#define CAT(...) EVAL( _CAT(__VA_ARGS__ ,) )
+  #define _CAT_s(sep ,a ,...)\
+    IF \
+      (__VA_ARGS__) \
+      ( EVAL(_CAT_ss(sep ,a ,__VA_ARGS__)) )  \
+      (a)
 
+  #define _CAT_ss(sep ,accumulator ,a ,...) \
+    IF \
+      (__VA_ARGS__) \
+      ( DEFER2(_CAT_ss_CONFEDERATE)()(sep ,accumulator##sep##a ,__VA_ARGS__) ) \
+      (accumulator##sep##a)
 
+  #define _CAT_ss_CONFEDERATE() _CAT_ss
 
 /*===========================================================================
   Quantifiers
@@ -150,7 +149,7 @@ DROPE_EMPTY_RIGHT
   #define AND(...) WHILE(EXISTS ,__VA_ARGS__)
 
   // AKA existence quantification, returns true or false
-  #define OR(...)  NOT(WHILE(NOT ,__VA_ARGS__)
+  #define OR(...)  NOT( WHILE(NOT ,__VA_ARGS__) )
 
 /*===========================================================================
   Access
diff --git a/developer/document🖉/cpp_CAT_and_comma.org b/developer/document🖉/cpp_CAT_and_comma.org
new file mode 100644 (file)
index 0000000..1507b5c
--- /dev/null
@@ -0,0 +1,44 @@
+* CATSEP Separator Expansion Notes
+:PROPERTIES:
+:CREATED:  [2025-04-01]
+:END:
+
+** Problem
+
+When using `CATSEP` (or `CAT`) to join tokens with a separator, we encountered an issue where passing a macro-defined separator (e.g. `COMMA`) leads to incorrect behavior:
+
+- The macro expands too early.
+- The result is malformed token pasting like `,A` instead of proper separation.
+- This happens because `##` prevents further expansion, so any `sep` macro used in a `##` must already be fully resolved.
+
+** Attempts
+
+We tried multiple versions:
+- Using `DEFER`, `DEFER2`, `DEFER3` to hide expansion.
+- Wrapping the separator in a macro (e.g. `DEFER_SEP()`).
+- Recursive accumulation models with delayed evaluation.
+
+** Findings
+
+- The separator **must not be a macro** when passed as an argument to a `##` operation.
+- Macro arguments are always expanded before `##` is applied, unless blocked (e.g., by an extra layer of indirection).
+- `##` prevents further expansion, so once the macro has been expanded into a literal comma (`,`) or semicolon (`;`), it can no longer be deferred.
+
+** Recommendation
+
+Use raw characters or tokens as separators, not macros. For example:
+
+#+begin_src c
+CAT(, A ,B ,C)    // OK makes a token ABC
+CAT(;, A ,B ,C)    // OK - [I don't think this works either]
+CAT(__oo__, A ,B ,C)  // OK A__oo__B__oo__C
+CAT(COMMA, A ,B ,C)   // ❌ COMMA expands too early
+#+end_src
+
+If you must use a macro-defined separator, redesign may be required. For now:
+
+** Conclusion
+
+⛔ **Do not use macro-defined separators in `CAT` or `CATSEP`.**
+
+Leave this as a known limitation and revisit if/when it becomes essential. Better to avoid the rabbit hole for now.
index c2cd602..62d78c8 100644 (file)
@@ -15,7 +15,7 @@ When defining a macro:
 When calling a macro.
   Can have space between a macro function name and the argument list.
 
-2.
+3.
 
 Macros can be called with empty arguments.
 
@@ -24,10 +24,8 @@ Macros can be called with empty arguments.
     int a_macro (a,,b)  // -> a + + c
   #+END_SRC
 
-  3. The access macros,  FIRST, SECOND ... have a padding character as a first argument.
-  The padding character is returned if the list is not long enough for the access.
-  It can be left empty.
+4.
 
-  FIRST(,)  will return the empty_token.
+The COMMA macro, though defined, can't be used in any two level or more deep macro calls, because it will expand to a comma on the first level. It perhaps could be wrapped in a function that is given a deferred call, and then have eval expand it, dunno.
 
 
index 8e87532..b0b5eaa 100644 (file)
@@ -32,7 +32,7 @@ int main(void){
   printf("\n");
 
   //--------------------------------------------------------------------------
-  // HAS_ITEM: returns 1 if item found
+  // CONTAINS: returns 1 if item found
   //    HAS requires the EQ templates to be set for each case.
   //--------------------------------------------------------------------------
 
@@ -40,8 +40,8 @@ int main(void){
   SHOW( EQ(B ,B) );
   printf("\n");
 
-  SHOW( HAS_ITEM(C ,A ,B ,C ,D) );   // → 1
-  SHOW( HAS_ITEM(Z ,A ,B ,C ,D) );   // → ε
+  SHOW( CONTAINS(C ,A ,B ,C ,D) );   // → 1
+  SHOW( CONTAINS(Z ,A ,B ,C ,D) );   // → ε
   printf("\n");
 
 
@@ -79,9 +79,9 @@ int main(void){
   // CAT: join items with a separator
   //--------------------------------------------------------------------------
 
-  //  SHOW( CAT( ;, A ,B ,C ,D ,Z) );  // → Z
+  //  SHOW( CAT( SEMICOLON, A ,B ,C ,D ,Z) );  // → Z
+  SHOW( CAT(__oo__,A ,B ,C) );  // → 
   SHOW( CAT(,A ,B ,C) );  // → 
-  SHOW( CAT( COMMA, A ,B ,C ,D ,Z) );  // → Z
   SHOW( CAT(,A ,B ,) );  // → 
   SHOW( CAT(,1) );  
   SHOW( CAT(,) );              // → ε
@@ -90,7 +90,6 @@ int main(void){
   //--------------------------------------------------------------------------
   // AND: true if all items are true (non-empty)
   //--------------------------------------------------------------------------
-#if 0
   SHOW( AND(1 ,X ,0) );        // → 1
   SHOW( AND(1 ,X ,) );       // → ε
   printf("\n");
@@ -102,5 +101,52 @@ int main(void){
   SHOW( OR( , , ,X) );         // → 1
   SHOW( OR( , , ,) );          // → ε
   printf("\n");
-#endif
+
 }
+/*
+  2025-04-01T04:44:40Z[developer]
+  Thomas-developer@Stanley§/home/Thomas-masu/developer/N/developer/example_cpp§
+  > gcc try_ext_1.c 
+
+  2025-04-01T04:44:44Z[developer]
+  Thomas-developer@Stanley§/home/Thomas-masu/developer/N/developer/example_cpp§
+  > ./a.out
+  EVAL(EXAMPLE_CHAIN(3)) -> 3 + 1 + 1
+
+  FIND(IS_X ,A ,B ,X ,Y ,Z) -> X
+  FIND(IS_X ,A ,B ,C ,D) -> EOL()
+
+  EQ(A ,B) -> 
+  EQ(B ,B) -> 1
+
+  CONTAINS(C ,A ,B ,C ,D) -> 1
+  CONTAINS(Z ,A ,B ,C ,D) -> 
+
+  WHILE(NON_Z ,A ,B ,C ,Z ,D ,E) -> 
+  WHILE(NON_Z ,A ,B ,C) -> 1
+
+  EXISTS() -> 
+  EXISTS(0) -> 1
+  EXISTS(1) -> 1
+  EXISTS(X) -> 1
+  WHILE(EXISTS ,1 ,X , ) -> 
+  WHILE(EXISTS ,1 , ,X ,0) -> 
+  WHILE(EXISTS ,1 ,X ,0) -> 1
+
+  LAST(A ,B ,C ,D ,Z) -> Z
+  LAST(A ,B ,) -> 
+  LAST() -> 
+
+  CAT(__oo__,A ,B ,C) -> A__oo__B__oo__C
+  CAT(,A ,B ,C) -> ABC
+  CAT(,A ,B ,) -> AB
+  CAT(,1) -> 1
+  CAT(,) -> 
+
+  AND(1 ,X ,0) -> 1
+  AND(1 ,X ,) -> 
+
+  OR( , , ,X) -> 1
+  OR( , , ,) -> 
+
+*/