.
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Fri, 6 Jun 2025 03:46:53 +0000 (03:46 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Fri, 6 Jun 2025 03:46:53 +0000 (03:46 +0000)
README.md

index caf657e..d1450e6 100644 (file)
--- a/README.md
+++ b/README.md
@@ -39,19 +39,85 @@ A multiline, ISO-style function macro with literal token bodies and a strict par
 
 ### `#assign`
 
-A declarative form of macro definition that allows both the macro name and body to be defined via either literal or expanded token expressions. Unlike `#define`, `#assign` enables delayed evaluation through bracketed forms.
+Similar behavior to a non-function, declarative, form of `#define`.  It has both a directive and macro form. In macro form it expands to nothing. When brackets are used instead of parenthesis, the clauses are expanded before the named macro is defined.
 
 ```c
 #assign (FOO) (42)        // literal
-#assign [BAR] [BAZ]       // expanded name and body
+_ASSIGN [BAR] [BAZ]       // expanded name and body
 ```
 
-Both directives support structured token handling and follow evaluation rules that prevent recursion via standard CPP coloring.
+Hence in this second case, `BAR` will be expanded and must result in an identifier name, if it is not macro, then it is taken literally.  Also `BAZ` will be expanded if it is a macro, and the result will be the body of the `[BAZ]` macro.
 
-A built-in macro `_ASSIGN` mirrors the `#assign` directive and can be used within macro logic.
+## Built-in Macros
+
+RT introduces functional built-in macros to extend CPP’s token manipulation capabilities. All built-ins are prefixed with `_` and operate without side effects, except `_ASSIGN`.
+
+### _ASSIGN
+
+A macro form of `#assign`. Takes two *clauses* — either parenthesized for literal input, or bracketed for expanded input.
+
+  _ASSIGN (FOO) (42)           // literal name and body
+  _ASSIGN [BAR] [BAZ]          // both name and body expanded
+
+- ( ... ) ⇒ literal clause (no expansion)
+- [ ... ] ⇒ expanded clause (macros are recursively expanded)
+
+This expands to nothing but defines (or overwrites) a macro binding. New macros created via _ASSIGN are *colored* (i.e., inert within the macro that created them).
+
+---
+
+### List Conversions
+
+These help translate between CPP’s two list types: space-separated `token_list` and comma-separated `argument_list`.
+
+  _TO_ARG_LIST(tokens...)        // a b c → a,b,c
+  _TO_TOKEN_LIST(a,b,c)          // a,b,c → a b c
+
+---
+
+### Token List Operators
+
+  _FIRST(tokens...)              // first token
+  _REST(tokens...)               // all but first
+  _MAP(f, tokens...)             // f(a) f(b) f(c)
+  _AL_MAP(f, a1, a2, ...)        // f(a1) f(a2) f(a3)
+
+- _MAP operates on a space-separated token list.
+- _AL_MAP operates on a comma-separated argument list.
 
 ---
 
+### Logic Primitives
+
+These treat token presence as boolean truth.
+
+  _IF(p, a, b)                   // if p is non-empty → a else → b
+  _NOT(p)                        // if p is empty → TRUE else →
+  _AND(a1, a2, ...)              // all must be non-empty
+  _OR(a1, a2, ...)               // returns first non-empty
+
+Notes:
+- _AND() expands to nothing if any argument is empty.
+- _OR() short-circuits to the first non-empty argument.
+
+---
+
+### Token-Level Predicate
+
+  _IS_IDENTIFIER(x)             // if x is a valid identifier → x else →
+
+---
+
+### Token Construction
+
+  _PASTE(a, b, c)               // pastes into single token
+
+All tokens are concatenated into one; result must be a valid CPP token (e.g., identifier). Invalid pastes result in a compiler error.
+
+---
+
+These primitives enable set manipulation, conditional macros, structural mapping, and functional programming patterns — within standard C preprocessor constraints.
+
 ## Feature Highlights
 
 * Structural support for: