From: Thomas Walker Lynch Date: Sat, 5 Apr 2025 16:09:46 +0000 (+0000) Subject: tape machine iterator try files working X-Git-Url: https://git.reasoningtechnology.com/usr/lib/python2.7/inspect.py?a=commitdiff_plain;h=1706dee0f01266b288fff2983091af0a610fb833;p=N tape machine iterator try files working --- diff --git a/README.md b/README.md new file mode 100644 index 0000000..80f1869 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# N: Experimental Multi-Precision Library and Language + +This project is an experimental system for building a high-performance multi-precision arithmetic library in C, with no headers, using a powerful template and namespacing mechanism based on the C preprocessor. + +## Highlights + +### 🧠 Headerless Development in C +All modules follow a two-part structure: interface and implementation, guarded by `#ifndef Module·FACE` and `#ifdef Module·IMPLEMENTATION`. This allows all code to be included in any order without needing `.h` files. + +### 🧰 Advanced CPP Extensions +The `cpp_ext` system introduces macro-based logic (e.g., `IF`, `FIND`, `CAT`, `EVAL`, `WHILE`), enabling token-based templating, membership testing, and extensible list manipulation—all within standard C. + +### 🧬 Parametric Polymorphism via Templates +Modules such as the `TM` (tape machine / iterator) library are implemented generically via macro substitution (`_TM·CVT_`). This enables instantiations like `TM·AU`, `TM·Str`, and more, while preserving type safety and zero runtime overhead. + +### 🌀 Namespaces in C +All public symbols use the `·` (U+00B7 MIDDLE DOT) to simulate hierarchical namespacing (e.g., `TM·AU·Array·init_pe`). This avoids naming collisions and allows clean introspection and tooling. + +### 🧪 Iterator Framework Demonstrated +The `TM` system defines abstract iterators ("tape machines") over bounded or unbounded data. Implementations include: +- `Array` (classic memory-backed segment) +- `ZeroLength` (null iterator) +- `SingletonSegment` (one-value, writable) +- `SingletonCircle` (one-value, looped) +These implementations verify polymorphic dispatch, step/read/write behavior, and status handling across modes. + +### ❌ No Python Filter Required +Previous builds used a Python script for C preprocessing. This has been replaced by the native `cpp_ext.c` layer, making the system fully self-contained in C. + +--- + +## 🚧 Still in Progress + +- The core multi-precision arithmetic (`MP` types and operations) is under active development. +- Template-based `map`, `copy`, and reduction operators will be added next, leveraging the iterator interface. +- Future work includes algebraic dispatch, symbolic manipulation, and seamless CLI test generators. + diff --git "a/developer/cc\360\237\226\211/Binding.lib.c" "b/developer/cc\360\237\226\211/Binding.lib.c" index 6d6b707..d36f1aa 100644 --- "a/developer/cc\360\237\226\211/Binding.lib.c" +++ "b/developer/cc\360\237\226\211/Binding.lib.c" @@ -38,11 +38,17 @@ fields in an instance. note the use of the comma operator to return the result from the b.fg->fn call */ - #define Binding·call(b, fn, ...) \ - ( \ - Binding·wellformed_binding(b) , \ - b.fg->fn(b __VA_OPT__(,) __VA_ARGS__) \ + #ifdef Binding·DEBUG + #include + #define Binding·call(b ,fn ,...) ( \ + assert((b).fg != NULL) \ + ,assert((b).tableau != NULL) \ + ,(b).fg->fn(b __VA_OPT__(,) __VA_ARGS__) \ ) + #else + #define Binding·call(b ,fn ,...) \ + (b).fg->fn(b __VA_OPT__(,) __VA_ARGS__) + #endif #endif @@ -65,15 +71,6 @@ fields in an instance. ·(_BINDING_ ,FG) *fg; } _BINDING_; - static void Binding·wellformed_binding(_BINDING_ b){ - #ifdef Binding·DEBUG - Core·Guard·init_count(chk); - Core·Guard·fg.check(&chk, 1, b.fg, "NULL fg table"); - Core·Guard·fg.check(&chk, 1, b.tableau, "NULL tableau"); - Core·Guard·assert(chk); - #endif - } - #endif #endif diff --git "a/developer/cc\360\237\226\211/TM.lib.c" "b/developer/cc\360\237\226\211/TM.lib.c" index 57e7cbb..6f5f1a9 100644 --- "a/developer/cc\360\237\226\211/TM.lib.c" +++ "b/developer/cc\360\237\226\211/TM.lib.c" @@ -33,7 +33,7 @@ typedef enum{ TM·Topo·mu = 0 - ,TM·Topo·empty = 1 + ,TM·Topo·zero_length = 1 ,TM·Topo·singleton = 1 << 1 ,TM·Topo·segment = 1 << 2 ,TM·Topo·circle = 1 << 3 @@ -79,7 +79,7 @@ typedef struct ·(TM,_TM·CVT_,FG){ - TM·Topo (*topo) ( ·(TM,_TM·CVT_) tm ); + TM·Topo (*topo) ( ·(TM,_TM·CVT_) tm ); bool (*bounded) ( ·(TM,_TM·CVT_) tm ); ·(extent_t,_TM·CVT_) (*extent) ( ·(TM,_TM·CVT_) tm ); @@ -103,35 +103,72 @@ } ·(TM,_TM·CVT_,FG); + //---------------------------------------- + // ZeroLength tape interface + + typedef struct{ + bool hd; + } ·(TM,_TM·CVT_,ZeroLength,Tableau); + + ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,ZeroLength,init)( + ·(TM,_TM·CVT_,ZeroLength,Tableau) *t + ); + + //---------------------------------------- + // SingletonSegment tape interface + + typedef struct{ + bool hd; + _TM·CVT_ value; + } ·(TM,_TM·CVT_,SingletonSegment,Tableau); + + ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,SingletonSegment,init)( + ·(TM,_TM·CVT_,SingletonSegment,Tableau) *t + ,_TM·CVT_ initial_value + ); + + //---------------------------------------- + // SingletonCircle tape interface + + typedef struct{ + bool hd; + _TM·CVT_ value; + } ·(TM,_TM·CVT_,SingletonCircle,Tableau); + + ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,SingletonCircle,init)( + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t + ,_TM·CVT_ initial_value + ); + //---------------------------------------- // Array interface - // Not exposing the implementation would be better, but the user needs to allocate these before calling init. - typedef struct{ - _TM·CVT_ *hd; - _TM·CVT_ *position; - ·(extent_t,_TM·CVT_) extent; - } ·(TM,_TM·CVT_,Array,Tableau); - - /* - We assume that the binding produced by init is valid. Thus: it does not have null pointers to the tableau or the fg table; it points to an initialized tableau; it points to a valid array fg table; and, that the fg table and tableau go together. - - Calling init is the only time the user/programmer will need to know the implementation name. - - The resulting binding object returned is what the user will call an instance of the - type. - */ - ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,Array,init_pe)( - ·(TM,_TM·CVT_,Array,Tableau) *t - ,_TM·CVT_ position[] - ,·(extent_t,_TM·CVT_) extent - ); - - ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,Array,init_pp)( - ·(TM,_TM·CVT_,Array,Tableau) *t - ,_TM·CVT_ *position_left - ,_TM·CVT_ *position_right - ); + // Not exposing the implementation would be better, but the user needs to allocate these before calling init. + typedef struct{ + _TM·CVT_ *hd; + _TM·CVT_ *position; + ·(extent_t,_TM·CVT_) extent; + } ·(TM,_TM·CVT_,Array,Tableau); + + /* + We assume that the binding produced by init is valid. Thus: it does not have null pointers to the tableau or the fg table; it points to an initialized tableau; it points to a valid array fg table; and, that the fg table and tableau go together. + + Calling init is the only time the user/programmer will need to know the implementation name. + + The resulting binding object returned is what the user will call an instance of the + type. + */ + ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,Array,init_pe)( + ·(TM,_TM·CVT_,Array,Tableau) *t + ,_TM·CVT_ position[] + ,·(extent_t,_TM·CVT_) extent + ); + + ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,Array,init_pp)( + ·(TM,_TM·CVT_,Array,Tableau) *t + ,_TM·CVT_ *position_left + ,_TM·CVT_ *position_right + ); #endif // #if BOOLEAN( NOT_IN(Binding ,TM) ) #endif // #ifdef _TM·CVT_ @@ -163,6 +200,329 @@ #pragma message( "Including LOCAL code for:" STR_VAL(_TM·CVT_) ) #endif + /*------------------------------------------------------------------------ + ZeroLength tape implementation + */ + + Local TM·Topo ·(TM,_TM·CVT_,ZeroLength,topo)( ·(TM,_TM·CVT_) tm ){ + return TM·Topo·zero_length; + } + + Local bool ·(TM,_TM·CVT_,ZeroLength,bounded)( ·(TM,_TM·CVT_) tm ){ + return true; + } + + Local ·(extent_t,_TM·CVT_) ·(TM,_TM·CVT_,ZeroLength,extent)( ·(TM,_TM·CVT_) tm ){ + assert(0); + } + + Local TM·Status ·(TM,_TM·CVT_,ZeroLength,status)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,ZeroLength,Tableau) *t = (·(TM,_TM·CVT_,ZeroLength,Tableau) *) tm.tableau; + if( !t->hd ) return TM·Status·dismounted; + return TM·Status·out_of_area; + } + + Local bool ·(TM,_TM·CVT_,ZeroLength,dismounted)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,ZeroLength,Tableau) *t = (·(TM,_TM·CVT_,ZeroLength,Tableau) *) tm.tableau; + return !t->hd; + } + + Local bool ·(TM,_TM·CVT_,ZeroLength,on_tape)( ·(TM,_TM·CVT_) tm ){ + return false; + } + + Local bool ·(TM,_TM·CVT_,ZeroLength,on_leftmost)( ·(TM,_TM·CVT_) tm ){ + return false; + } + + Local bool ·(TM,_TM·CVT_,ZeroLength,on_rightmost)( ·(TM,_TM·CVT_) tm ){ + return false; + } + + // does nothing if tape is already mounted + Local void ·(TM,_TM·CVT_,ZeroLength,mount)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,ZeroLength,Tableau) *t = (·(TM,_TM·CVT_,ZeroLength,Tableau) *) tm.tableau; + if( !t->hd ) t->hd = true; + } + + Local void ·(TM,_TM·CVT_,ZeroLength,dismount)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,ZeroLength,Tableau) *t = (·(TM,_TM·CVT_,ZeroLength,Tableau) *) tm.tableau; + t->hd = false; + } + + Local void ·(TM,_TM·CVT_,ZeroLength,step)( ·(TM,_TM·CVT_) tm ){ + assert(0); + } + + Local void ·(TM,_TM·CVT_,ZeroLength,step_left)( ·(TM,_TM·CVT_) tm ){ + assert(0); + } + + // rewind does nothing if the tape is dismounted + Local void ·(TM,_TM·CVT_,ZeroLength,rewind)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,ZeroLength,Tableau) *t = (·(TM,_TM·CVT_,ZeroLength,Tableau) *) tm.tableau; + if( ·(TM,_TM·CVT_,ZeroLength,dismounted)( tm ) ) return; + assert(0); + } + + Local _TM·CVT_ ·(TM,_TM·CVT_,ZeroLength,read)( ·(TM,_TM·CVT_) tm ){ + assert(0); + } + + Local void ·(TM,_TM·CVT_,ZeroLength,write)( ·(TM,_TM·CVT_) tm ,_TM·CVT_ *remote_pt ){ + assert(0); + } + + Local ·(TM,_TM·CVT_,FG) ·(TM,_TM·CVT_,ZeroLength,fg) = { + + .topo = ·(TM,_TM·CVT_,ZeroLength,topo) + ,.bounded = ·(TM,_TM·CVT_,ZeroLength,bounded) + ,.extent = ·(TM,_TM·CVT_,ZeroLength,extent) + + ,.status = ·(TM,_TM·CVT_,ZeroLength,status) + ,.dismounted = ·(TM,_TM·CVT_,ZeroLength,dismounted) + ,.on_tape = ·(TM,_TM·CVT_,ZeroLength,on_tape) + ,.on_leftmost = ·(TM,_TM·CVT_,ZeroLength,on_leftmost) + ,.on_rightmost = ·(TM,_TM·CVT_,ZeroLength,on_rightmost) + + ,.mount = ·(TM,_TM·CVT_,ZeroLength,mount) + ,.dismount = ·(TM,_TM·CVT_,ZeroLength,dismount) + + ,.step = ·(TM,_TM·CVT_,ZeroLength,step) + ,.step_right = ·(TM,_TM·CVT_,ZeroLength,step) + ,.step_left = ·(TM,_TM·CVT_,ZeroLength,step_left) + ,.rewind = ·(TM,_TM·CVT_,ZeroLength,rewind) + + ,.read = ·(TM,_TM·CVT_,ZeroLength,read) + ,.write = ·(TM,_TM·CVT_,ZeroLength,write) + + }; + + ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,ZeroLength,init)( + ·(TM,_TM·CVT_,ZeroLength,Tableau) *t + ){ + t->hd = true; + ·(TM,_TM·CVT_) tm = { + .tableau = (·(TM,_TM·CVT_,Tableau) *)t + ,.fg = &·(TM,_TM·CVT_,ZeroLength,fg) + }; + return tm; + } + + /*------------------------------------------------------------------------ + SingletonSegment tape + */ + + Local TM·Topo ·(TM,_TM·CVT_,SingletonSegment,topo)( ·(TM,_TM·CVT_) tm ){ + return TM·Topo·singleton; + } + Local bool ·(TM,_TM·CVT_,SingletonSegment,bounded)( ·(TM,_TM·CVT_) tm ){ + return true; + } + Local ·(extent_t,_TM·CVT_) ·(TM,_TM·CVT_,SingletonSegment,extent)( ·(TM,_TM·CVT_) tm ){ + return 0; + } + Local TM·Status ·(TM,_TM·CVT_,SingletonSegment,status)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonSegment,Tableau) *t = (·(TM,_TM·CVT_,SingletonSegment,Tableau) *) tm.tableau; + if( !t->hd ) return TM·Status·dismounted; + return TM·Status·leftmost | TM·Status·rightmost; + } + Local bool ·(TM,_TM·CVT_,SingletonSegment,dismounted)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonSegment,Tableau) *t = (·(TM,_TM·CVT_,SingletonSegment,Tableau) *) tm.tableau; + return !t->hd; + } + + // these could be pulled from the tm.fg table, and defined once + Local bool ·(TM,_TM·CVT_,SingletonSegment,on_tape)( ·(TM,_TM·CVT_) tm ){ + return ·(TM,_TM·CVT_,SingletonSegment,status)( tm ) & TM·Status·on_tape; + } + Local bool ·(TM,_TM·CVT_,SingletonSegment,on_leftmost)( ·(TM,_TM·CVT_) tm ){ + return ·(TM,_TM·CVT_,SingletonSegment,status)( tm ) & TM·Status·leftmost; + } + Local bool ·(TM,_TM·CVT_,SingletonSegment,on_rightmost)( ·(TM,_TM·CVT_) tm ){ + return ·(TM,_TM·CVT_,SingletonSegment,status)( tm ) & TM·Status·rightmost; + } + + // does nothing if tape is already mounted + Local void ·(TM,_TM·CVT_,SingletonSegment,mount)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonSegment,Tableau) *t = (·(TM,_TM·CVT_,SingletonSegment,Tableau) *) tm.tableau; + t->hd = true; + } + Local void ·(TM,_TM·CVT_,SingletonSegment,dismount)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonSegment,Tableau) *t = (·(TM,_TM·CVT_,SingletonSegment,Tableau) *) tm.tableau; + t->hd = false; + } + + Local void ·(TM,_TM·CVT_,SingletonSegment,step)( ·(TM,_TM·CVT_) tm ){ + assert(0); + } + Local void ·(TM,_TM·CVT_,SingletonSegment,step_left)( ·(TM,_TM·CVT_) tm ){ + assert(0); + } + Local void ·(TM,_TM·CVT_,SingletonSegment,rewind)( ·(TM,_TM·CVT_) tm ){ + return; + } + + Local _TM·CVT_ ·(TM,_TM·CVT_,SingletonSegment,read)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonSegment,Tableau) *t = (·(TM,_TM·CVT_,SingletonSegment,Tableau) *) tm.tableau; + return t->value; + } + Local void ·(TM,_TM·CVT_,SingletonSegment,write)( ·(TM,_TM·CVT_) tm ,_TM·CVT_ *remote_pt ){ + ·(TM,_TM·CVT_,SingletonSegment,Tableau) *t = (·(TM,_TM·CVT_,SingletonSegment,Tableau) *) tm.tableau; + t->value = *remote_pt; + } + + Local ·(TM,_TM·CVT_,FG) ·(TM,_TM·CVT_,SingletonSegment,fg) = { + + .topo = ·(TM,_TM·CVT_,SingletonSegment,topo) + ,.bounded = ·(TM,_TM·CVT_,SingletonSegment,bounded) + ,.extent = ·(TM,_TM·CVT_,SingletonSegment,extent) + + ,.status = ·(TM,_TM·CVT_,SingletonSegment,status) + ,.dismounted = ·(TM,_TM·CVT_,SingletonSegment,dismounted) + ,.on_tape = ·(TM,_TM·CVT_,SingletonSegment,on_tape) + ,.on_leftmost = ·(TM,_TM·CVT_,SingletonSegment,on_leftmost) + ,.on_rightmost = ·(TM,_TM·CVT_,SingletonSegment,on_rightmost) + + ,.mount = ·(TM,_TM·CVT_,SingletonSegment,mount) + ,.dismount = ·(TM,_TM·CVT_,SingletonSegment,dismount) + + ,.step = ·(TM,_TM·CVT_,SingletonSegment,step) + ,.step_right = ·(TM,_TM·CVT_,SingletonSegment,step) + ,.step_left = ·(TM,_TM·CVT_,SingletonSegment,step_left) + ,.rewind = ·(TM,_TM·CVT_,SingletonSegment,rewind) + + ,.read = ·(TM,_TM·CVT_,SingletonSegment,read) + ,.write = ·(TM,_TM·CVT_,SingletonSegment,write) + + }; + + /* + tm is up casted from being array specific, to being generic. Later it is downcasted within the array code before being used. This can be seen at the top of each of the array specific function. This is the only loss of static type safety, and it is embedded in the library code. + */ + ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,SingletonSegment,init)( + ·(TM,_TM·CVT_,SingletonSegment,Tableau) *t + ,_TM·CVT_ initial_value + ){ + t->hd = true; + t->value = initial_value; + + ·(TM,_TM·CVT_) tm = { + .tableau = (·(TM,_TM·CVT_,Tableau) *)t + ,.fg = &·(TM,_TM·CVT_,SingletonSegment,fg) + }; + + return tm; + } + + + /*------------------------------------------------------------------------ + SingletonCircle tape + */ + + Local TM·Topo ·(TM,_TM·CVT_,SingletonCircle,topo)( ·(TM,_TM·CVT_) tm ){ + return TM·Topo·circle; + } + Local bool ·(TM,_TM·CVT_,SingletonCircle,bounded)( ·(TM,_TM·CVT_) tm ){ + return false; + } + Local ·(extent_t,_TM·CVT_) ·(TM,_TM·CVT_,SingletonCircle,extent)( ·(TM,_TM·CVT_) tm ){ + return 0; + } + Local TM·Status ·(TM,_TM·CVT_,SingletonCircle,status)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t = (·(TM,_TM·CVT_,SingletonCircle,Tableau) *) tm.tableau; + if( !t->hd ) return TM·Status·dismounted; + return TM·Status·interim; + } + Local bool ·(TM,_TM·CVT_,SingletonCircle,dismounted)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t = (·(TM,_TM·CVT_,SingletonCircle,Tableau) *) tm.tableau; + return !t->hd; + } + + // these could be pulled from the tm.fg table, and defined once + Local bool ·(TM,_TM·CVT_,SingletonCircle,on_tape)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t = (·(TM,_TM·CVT_,SingletonCircle,Tableau) *) tm.tableau; + return t->hd; + } + Local bool ·(TM,_TM·CVT_,SingletonCircle,on_leftmost)( ·(TM,_TM·CVT_) tm ){ + return false; + } + Local bool ·(TM,_TM·CVT_,SingletonCircle,on_rightmost)( ·(TM,_TM·CVT_) tm ){ + return false; + } + + // does nothing if tape is already mounted + Local void ·(TM,_TM·CVT_,SingletonCircle,mount)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t = (·(TM,_TM·CVT_,SingletonCircle,Tableau) *) tm.tableau; + t->hd = true; + } + Local void ·(TM,_TM·CVT_,SingletonCircle,dismount)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t = (·(TM,_TM·CVT_,SingletonCircle,Tableau) *) tm.tableau; + t->hd = false; + } + + Local void ·(TM,_TM·CVT_,SingletonCircle,step)( ·(TM,_TM·CVT_) tm ){ + return; + } + Local void ·(TM,_TM·CVT_,SingletonCircle,step_left)( ·(TM,_TM·CVT_) tm ){ + return; + } + Local void ·(TM,_TM·CVT_,SingletonCircle,rewind)( ·(TM,_TM·CVT_) tm ){ + return; + } + + Local _TM·CVT_ ·(TM,_TM·CVT_,SingletonCircle,read)( ·(TM,_TM·CVT_) tm ){ + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t = (·(TM,_TM·CVT_,SingletonCircle,Tableau) *) tm.tableau; + return t->value; + } + Local void ·(TM,_TM·CVT_,SingletonCircle,write)( ·(TM,_TM·CVT_) tm ,_TM·CVT_ *remote_pt ){ + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t = (·(TM,_TM·CVT_,SingletonCircle,Tableau) *) tm.tableau; + t->value = *remote_pt; + } + + Local ·(TM,_TM·CVT_,FG) ·(TM,_TM·CVT_,SingletonCircle,fg) = { + + .topo = ·(TM,_TM·CVT_,SingletonCircle,topo) + ,.bounded = ·(TM,_TM·CVT_,SingletonCircle,bounded) + ,.extent = ·(TM,_TM·CVT_,SingletonCircle,extent) + + ,.status = ·(TM,_TM·CVT_,SingletonCircle,status) + ,.dismounted = ·(TM,_TM·CVT_,SingletonCircle,dismounted) + ,.on_tape = ·(TM,_TM·CVT_,SingletonCircle,on_tape) + ,.on_leftmost = ·(TM,_TM·CVT_,SingletonCircle,on_leftmost) + ,.on_rightmost = ·(TM,_TM·CVT_,SingletonCircle,on_rightmost) + + ,.mount = ·(TM,_TM·CVT_,SingletonCircle,mount) + ,.dismount = ·(TM,_TM·CVT_,SingletonCircle,dismount) + + ,.step = ·(TM,_TM·CVT_,SingletonCircle,step) + ,.step_right = ·(TM,_TM·CVT_,SingletonCircle,step) + ,.step_left = ·(TM,_TM·CVT_,SingletonCircle,step_left) + ,.rewind = ·(TM,_TM·CVT_,SingletonCircle,rewind) + + ,.read = ·(TM,_TM·CVT_,SingletonCircle,read) + ,.write = ·(TM,_TM·CVT_,SingletonCircle,write) + + }; + + /* + tm is up casted from being array specific, to being generic. Later it is downcasted within the array code before being used. This can be seen at the top of each of the array specific function. This is the only loss of static type safety, and it is embedded in the library code. + */ + ·(TM,_TM·CVT_) ·(TM,_TM·CVT_,SingletonCircle,init)( + ·(TM,_TM·CVT_,SingletonCircle,Tableau) *t + ,_TM·CVT_ initial_value + ){ + t->hd = true; + t->value = initial_value; + + ·(TM,_TM·CVT_) tm = { + .tableau = (·(TM,_TM·CVT_,Tableau) *)t + ,.fg = &·(TM,_TM·CVT_,SingletonCircle,fg) + }; + + return tm; + } + /*------------------------------------------------------------------------ Array implementation with a segment tape @@ -199,26 +559,22 @@ } Local bool ·(TM,_TM·CVT_,Array,dismounted)( ·(TM,_TM·CVT_) tm ){ - ·(TM,_TM·CVT_,Array,Tableau) *t = (·(TM,_TM·CVT_,Array,Tableau) *) tm.tableau; return ·(TM,_TM·CVT_,Array,status)( tm ) & TM·Status·dismounted; } Local bool ·(TM,_TM·CVT_,Array,on_tape)( ·(TM,_TM·CVT_) tm ){ - ·(TM,_TM·CVT_,Array,Tableau) *t = (·(TM,_TM·CVT_,Array,Tableau) *) tm.tableau; return ·(TM,_TM·CVT_,Array,status)( tm ) & TM·Status·on_tape; } Local bool ·(TM,_TM·CVT_,Array,on_leftmost)( ·(TM,_TM·CVT_) tm ){ - ·(TM,_TM·CVT_,Array,Tableau) *t = (·(TM,_TM·CVT_,Array,Tableau) *) tm.tableau; return ·(TM,_TM·CVT_,Array,status)( tm ) & TM·Status·leftmost; } Local bool ·(TM,_TM·CVT_,Array,on_rightmost)( ·(TM,_TM·CVT_) tm ){ - ·(TM,_TM·CVT_,Array,Tableau) *t = (·(TM,_TM·CVT_,Array,Tableau) *) tm.tableau; return ·(TM,_TM·CVT_,Array,status)( tm ) & TM·Status·rightmost; } - // does nothing if the hd is already mounted + // does nothing if tape is already mounted Local void ·(TM,_TM·CVT_,Array,mount)( ·(TM,_TM·CVT_) tm ){ ·(TM,_TM·CVT_,Array,Tableau) *t = (·(TM,_TM·CVT_,Array,Tableau) *) tm.tableau; if( !t->hd ) t->hd = t->position; @@ -229,7 +585,6 @@ t->hd = NULL; } - // does nothing if the hd is not mounted Local void ·(TM,_TM·CVT_,Array,step)( ·(TM,_TM·CVT_) tm ){ ·(TM,_TM·CVT_,Array,Tableau) *t = (·(TM,_TM·CVT_,Array,Tableau) *) tm.tableau; t->hd++; @@ -240,6 +595,7 @@ t->hd--; } + // rewind does nothing if the tape is dismounted Local void ·(TM,_TM·CVT_,Array,rewind)( ·(TM,_TM·CVT_) tm ){ ·(TM,_TM·CVT_,Array,Tableau) *t = (·(TM,_TM·CVT_,Array,Tableau) *) tm.tableau; if( ·(TM,_TM·CVT_,Array,dismounted)( tm ) ) return; @@ -253,7 +609,7 @@ Local void ·(TM,_TM·CVT_,Array,write)( ·(TM,_TM·CVT_) tm ,_TM·CVT_ *remote_pt ){ ·(TM,_TM·CVT_,Array,Tableau) *t = (·(TM,_TM·CVT_,Array,Tableau) *) tm.tableau; - *remote_pt = *t->hd; + *t->hd = *remote_pt; } Local ·(TM,_TM·CVT_,FG) ·(TM,_TM·CVT_,Array,fg) = { diff --git a/developer/example/try_TM_1.cli.c b/developer/example/try_TM_1.cli.c index 8a6b8c5..a43e852 100644 --- a/developer/example/try_TM_1.cli.c +++ b/developer/example/try_TM_1.cli.c @@ -1,5 +1,5 @@ /* - try_TM.cli.c - Example use of TM·AU type with array backend. + try_TM_1.cli.c - Example use of TM·AU type with array backend. */ #include diff --git a/developer/example/try_TM_1.out b/developer/example/try_TM_1.out new file mode 100644 index 0000000..09d8c8e --- /dev/null +++ b/developer/example/try_TM_1.out @@ -0,0 +1,2 @@ +running try_TM_1.cli.c on Apr 5 2025 at 15:51:22 +01 02 03 04 05 diff --git a/developer/example/try_TM_2.cli.c b/developer/example/try_TM_2.cli.c new file mode 100644 index 0000000..b315402 --- /dev/null +++ b/developer/example/try_TM_2.cli.c @@ -0,0 +1,70 @@ +/* + try_TM_2.cli.c - Demonstrates two coexisting TM types: TM·AU and TM·str. +*/ + +#include +#include "cpp_ext.c" +#include "TM.lib.c" + +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__Binding__TM·AU + +typedef char* Str; +#define _TM·CVT_ Str +#include "TM.lib.c" +#define SET__Binding__TM·Str + +int main(){ + printf("running try_TM_2.cli.c on %s at %s\n", __DATE__, __TIME__); + + // TM·AU example + AU tape1[] = {0xAA ,0x55 ,0xC2}; + extent_t·AU extent1 = sizeof(tape1) / sizeof(AU) - 1; + + TM·AU·Array·Tableau t1; + TM·AU tm1 = TM·AU·Array·init_pe(&t1 ,tape1 ,extent1); + + if( Binding·call(tm1 ,on_tape) ){ + printf("TM·AU tape: "); + do{ + printf("%02x", (unsigned int) Binding·call(tm1 ,read)); + if( Binding·call(tm1 ,on_rightmost) ) break; + putchar(' '); + Binding·call(tm1 ,step); + }while(1); + printf("\n"); + } + + // TM·Str example + Str tape2[] = {"hello", "world", "Calderis"}; + extent_t·Str extent2 = sizeof(tape2) / sizeof(Str) - 1; + + TM·Str·Array·Tableau t2; + TM·Str tm2 = TM·Str·Array·init_pe(&t2 ,tape2 ,extent2); + + if( Binding·call(tm2 ,on_tape) ){ + printf("TM·Str tape: "); + do{ + printf("\"%s\"", Binding·call(tm2 ,read)); + if( Binding·call(tm2 ,on_rightmost) ) break; + putchar(' '); + Binding·call(tm2 ,step); + }while(1); + printf("\n"); + } + + return 0; +} + +// Bring in local implementations +#define LOCAL + +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__TM·LOCAL__TM·AU + +#define _TM·CVT_ Str +#include "TM.lib.c" +#define SET__TM·LOCAL__TM·Str + diff --git a/developer/example/try_TM_2.out b/developer/example/try_TM_2.out new file mode 100644 index 0000000..58227da --- /dev/null +++ b/developer/example/try_TM_2.out @@ -0,0 +1,3 @@ +running try_TM_2.cli.c on Apr 5 2025 at 15:51:22 +TM·AU tape: aa 55 c2 +TM·Str tape: "hello" "world" "Calderis" diff --git a/developer/example/try_TM_3.cli.c b/developer/example/try_TM_3.cli.c new file mode 100644 index 0000000..496f6d5 --- /dev/null +++ b/developer/example/try_TM_3.cli.c @@ -0,0 +1,79 @@ +/* + try_TM_3.cli.c - Tests repeat includes, and more TM functions +*/ + +#include +#include "cpp_ext.c" +#include "TM.lib.c" + +// Include the same type twice (should be gate-guarded) +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__Binding__TM·AU + +#define _TM·CVT_ Str +typedef char* Str; +#include "TM.lib.c" +#define SET__Binding__TM·Str + +// Include LOCAL twice as well +#define LOCAL +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__TM·LOCAL__TM·AU + +#define LOCAL +#define _TM·CVT_ Str +#include "TM.lib.c" +#define SET__TM·LOCAL__TM·Str + +int main(){ + printf("running try_TM_3.cli.c on %s at %s\n", __DATE__, __TIME__); + + // AU tape + AU tape[] = {0xaa ,0x55 ,0xc2}; + TM·AU·Array·Tableau t_au; + TM·AU tm_au = TM·AU·Array·init_pe(&t_au ,tape ,3); + + printf("Initial TM·AU tape:\n"); + if( Binding·call(tm_au ,on_tape) ){ + Binding·call(tm_au ,rewind); + do{ + printf("%02x", (unsigned int) Binding·call(tm_au ,read)); + if( Binding·call(tm_au ,on_rightmost) ) break; + putchar(' '); + Binding·call(tm_au ,step); + }while(1); + printf("\n"); + } + + // Str tape + Str tape2[] = {"hello" ,"world" ,"Calderis"}; + TM·Str·Array·Tableau t_str; + TM·Str tm_str = TM·Str·Array·init_pe(&t_str ,tape2 ,3); + + printf("Initial TM·Str tape:\n"); + Binding·call(tm_str ,rewind); + do{ + printf("\"%s\"", Binding·call(tm_str ,read)); + if( Binding·call(tm_str ,on_rightmost) ) break; + putchar(' '); + Binding·call(tm_str ,step); + }while(1); + printf("\n"); + + // Test dismount + mount cycle + Binding·call(tm_au ,dismount); + Binding·call(tm_au ,mount); + printf("After dismount/remount, AU read: %02x\n", + (unsigned int) Binding·call(tm_au ,read)); + + // Test step_left from position 1 + Binding·call(tm_au ,rewind); + Binding·call(tm_au ,step); + Binding·call(tm_au ,step_left); + printf("After step to right and left again: %02x\n", + (unsigned int) Binding·call(tm_au ,read)); + + return 0; +} diff --git a/developer/example/try_TM_3.out b/developer/example/try_TM_3.out new file mode 100644 index 0000000..f1038da --- /dev/null +++ b/developer/example/try_TM_3.out @@ -0,0 +1,7 @@ +running try_TM_3.cli.c on Apr 5 2025 at 15:51:22 +Initial TM·AU tape: +aa 55 c2 01 +Initial TM·Str tape: +"hello" "world" "Calderis" "(null)" +After dismount/remount, AU read: aa +After step to right and left again: aa diff --git a/developer/example/try_TM_4.cli.c b/developer/example/try_TM_4.cli.c new file mode 100644 index 0000000..75327f1 --- /dev/null +++ b/developer/example/try_TM_4.cli.c @@ -0,0 +1,67 @@ +/* + try_TM_2.cli.c - Demonstrates two coexisting TM types: TM·AU and TM·str. +*/ + +#include +#include "cpp_ext.c" +#include "TM.lib.c" + +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__Binding__TM·AU + +typedef char* Str; +#define _TM·CVT_ Str +#include "TM.lib.c" +#define SET__Binding__TM·Str + +int main(){ + printf("running try_TM_2.cli.c on %s at %s\n", __DATE__, __TIME__); + + // TM·AU example + AU tape1[] = {0xAA ,0x55 ,0xC2}; + extent_t·AU extent1 = sizeof(tape1) / sizeof(AU) - 1; + + TM·AU·Array·Tableau t1; + TM·AU tm1 = TM·AU·Array·init_pe(&t1 ,tape1 ,extent1); + + // TM·Str example + Str tape2[] = {"hello", "world", "Calderis"}; + extent_t·Str extent2 = sizeof(tape2) / sizeof(Str) - 1; + + TM·Str·Array·Tableau t2; + TM·Str tm2 = TM·Str·Array·init_pe(&t2 ,tape2 ,extent2); + + if( Binding·call(tm1 ,on_tape) && Binding·call(tm2 ,on_tape) ){ + do{ + printf("%02x\n", (unsigned int) Binding·call(tm1 ,read)); + putchar(' '); + putchar(' '); + do{ + printf("%s", Binding·call(tm2 ,read)); + if( Binding·call(tm2 ,on_rightmost) ) break; + putchar(' '); + Binding·call(tm2 ,step); + }while(1); + putchar('\n'); + if( Binding·call(tm1 ,on_rightmost) ) break; + Binding·call(tm1 ,step); + Binding·call(tm2 ,rewind); + }while(1); + printf("\n"); + } + + return 0; +} + +// Bring in local implementations +#define LOCAL + +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__TM·LOCAL__TM·AU + +#define _TM·CVT_ Str +#include "TM.lib.c" +#define SET__TM·LOCAL__TM·Str + diff --git a/developer/example/try_TM_4.out b/developer/example/try_TM_4.out new file mode 100644 index 0000000..89a469a --- /dev/null +++ b/developer/example/try_TM_4.out @@ -0,0 +1,8 @@ +running try_TM_2.cli.c on Apr 5 2025 at 15:51:22 +aa + hello world Calderis +55 + hello world Calderis +c2 + hello world Calderis + diff --git a/developer/example/try_TM_5.cli.c b/developer/example/try_TM_5.cli.c new file mode 100644 index 0000000..e5494a3 --- /dev/null +++ b/developer/example/try_TM_5.cli.c @@ -0,0 +1,66 @@ +/* + try_TM_5.cli.c - Demonstrate dismount, ignored rewind, remount, + mix of reads/writes, and verification. +*/ + +#include +#include "cpp_ext.c" +#include "TM.lib.c" + +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__Binding__TM·AU + +int main(){ + printf("running try_TM_5.cli.c on %s at %s\n", __DATE__, __TIME__); + + // Start with 4 AU values + AU tape[] = { 0xAA ,0x55 ,0xC2 ,0x01 }; + extent_t·AU extent = sizeof(tape) / sizeof(AU) - 1; + + // Init the tableau and TM binding + TM·AU·Array·Tableau t; + TM·AU tm = TM·AU·Array·init_pe(&t ,tape ,extent); + + // Dismount tape + Binding·call(tm ,dismount); + + // This rewind will do nothing, since tape is dismounted + Binding·call(tm ,rewind); + + // Mount again (should put head at position[0]) + Binding·call(tm ,mount); + + // Overwrite tape with incrementing values starting at 0x10 + AU value = 0x10; + if( Binding·call(tm ,on_tape) ){ + do{ + Binding·call(tm ,write ,&value); + value++; + if( Binding·call(tm ,on_rightmost) ) break; + Binding·call(tm ,step); + }while(1); + } + + // Rewind and verify written values + Binding·call(tm ,rewind); + + printf("Verifying written tape:\n"); + if( Binding·call(tm ,on_tape) ){ + do{ + AU x = Binding·call(tm ,read); + printf("%02x", (unsigned int)x); + if( Binding·call(tm ,on_rightmost) ) break; + putchar(' '); + Binding·call(tm ,step); + }while(1); + putchar('\n'); + } + + return 0; +} + +#define LOCAL +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__TM·LOCAL__TM·AU diff --git a/developer/example/try_TM_5.out b/developer/example/try_TM_5.out new file mode 100644 index 0000000..ac2afb0 --- /dev/null +++ b/developer/example/try_TM_5.out @@ -0,0 +1,3 @@ +running try_TM_5.cli.c on Apr 5 2025 at 15:51:22 +Verifying written tape: +10 11 12 13 diff --git a/developer/example/try_TM_6.cli.c b/developer/example/try_TM_6.cli.c new file mode 100644 index 0000000..519a1e2 --- /dev/null +++ b/developer/example/try_TM_6.cli.c @@ -0,0 +1,47 @@ +/* + try_TM_6.cli.c — SingletonCircle test with TM·AU +*/ + +#include +#include "cpp_ext.c" +#include "TM.lib.c" + +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__Binding__TM·AU + +int main(){ + + printf("running try_TM_6.cli.c on %s at %s\n", __DATE__, __TIME__); + + // Init SingletonCircle tape with initial value 0x3F + TM·AU·SingletonCircle·Tableau t; + TM·AU tm = TM·AU·SingletonCircle·init(&t ,0x3F); + + printf("Initial value: %02x\n", (unsigned int) Binding·call(tm ,read)); + + // Overwrite the value + AU new_val = 0xA5; + Binding·call(tm ,write ,&new_val); + + // Step right (should be no-op) + Binding·call(tm ,step); + + // Confirm value persists + printf("After stepping, value: %02x\n", (unsigned int) Binding·call(tm ,read)); + + // Dismount and try to rewind (noop) + Binding·call(tm ,dismount); + Binding·call(tm ,rewind); // should do nothing + + // Mount again and verify value + Binding·call(tm ,mount); + printf("After remount, value: %02x\n", (unsigned int) Binding·call(tm ,read)); + + return 0; +} + +#define LOCAL +#define _TM·CVT_ AU +#include "TM.lib.c" +#define SET__TM·LOCAL__TM·AU diff --git a/developer/example/try_TM_6.out b/developer/example/try_TM_6.out new file mode 100644 index 0000000..2990de7 --- /dev/null +++ b/developer/example/try_TM_6.out @@ -0,0 +1,4 @@ +running try_TM_6.cli.c on Apr 5 2025 at 15:54:08 +Initial value: 3f +After stepping, value: a5 +After remount, value: a5