simplified, comging down to read and write type matching, is it possible?
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 20 Mar 2025 11:17:43 +0000 (11:17 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 20 Mar 2025 11:17:43 +0000 (11:17 +0000)
developer/cc馃枆/Core.lib.c
developer/cc馃枆/Map.lib.c
developer/cc馃枆/Map2.lib.c [new file with mode: 0644]
developer/cc馃枆/TM.lib.c
developer/cc馃枆/xi.c [new file with mode: 0644]
developer/document馃枆/alignment.org
developer/document馃枆/generalizing_type.org [new file with mode: 0644]
developer/experiment/xi.c [new file with mode: 0644]
developer/experiment/xi2_test.c [new file with mode: 0644]
developer/experiment/xi_test.c [new file with mode: 0644]

index 53e0632..f70d7ea 100644 (file)
   #include <stdint.h>
   #include <stddef.h>
 
+  // the template filling macro
+  #include <xi.c>
+
   //----------------------------------------
   // memory interface
   //----------------------------------------
 
-  #ifndef CVT  
-
     // Expand namespace with a macro parameter given value.
     // The namespace and the extended value will be evaluated for macros.
     // Greek capital letter 'Xi' for eXtend.
@@ -79,8 +80,6 @@
       ,Core路Status路derailed
     }Core路Status;
 
-  #endif
-
   //----------------------------------------
   // flag facility, argument guard facility
   //----------------------------------------
index 26297b8..2fd90cf 100644 (file)
- /*
-  Core - core memory operations.
+/* Map - mapping functions between tape machines.
 
-  This file has the template parameter: `CVT`
+   This file has two template parameters:
+   `CVT_read`  Cell Value Type for the source/read tape machine
+   `CVT_write` Cell Value Type for the destination/write tape machine
 
-  `CVT` Cell Value Type`. It is the type of the datum placed in a cell. By default (when the   macro CVT has no definition) the cell value type is taken as AUM. This file must
-  be included with CVT undefined, before inclusions with it defined.
-  `AU` `Addressable Unit for the machine`, on most all machines today this is uint8_t,
-  though the C standard has never required this.
-
-  'ATP' `At This Point' in the code. Acronym used in comments usually before pointing
-  out certain values variables must have.
-
-  'AToW' - At Time of Writing, also used in comments.
-
-  'Tape' is operated on by the Tape Machine.
-
-  'Area' is subset of an address space that is used as a virtual Tape by a machine.
-
-   An Area with zero elements has 'length == 0' or is 'empty'. In contrast, and
-   area located (position specified) with a null pointer is said not to exist.
-
-   When all the functions that have a specific type of operand given are group together
-   in a table, we call the table a 'Function Given Type X', table. In general we call
-   these FG (Function Given) tables. A specific instance of an FG table is an `fg` table.
+   By default (when the macros have no definition) the cell value types are taken as AU.
+   This file must be included with CVT_read and CVT_write undefined, before inclusions with them defined.
 
+   'Tape' is operated on by the Tape Machine.
+   'Area' is subset of an address space that is used as a virtual Tape by a machine.
+   An Area with zero elements has 'length == 0' or is 'empty'.
+   In contrast, and area located (position specified) with a null pointer is said not to exist.
 */
 
-#define Core路DEBUG
+#define Map路DEBUG
 
 #ifndef FACE
-#define Core路IMPLEMENTATION
-#define FAC
-#endif 
+  #define Map路IMPLEMENTATION
+  #define FACE
+#endif
 
 //--------------------------------------------------------------------------------
 // Interface
 
-#ifndef Core路FACE
-#define Core路FACE
+#ifndef Map路FACE
+  #define Map路FACE
 
   #include <stdint.h>
   #include <stddef.h>
+  #include "Core.lib.c"
+  #include "TM.lib.c"
 
-  //----------------------------------------
-  // memory interface
-  //----------------------------------------
-
-  #ifndef CVT  
-
-    // Expand namespace with a macro parameter given value.
-    // The namespace and the extended value will be evaluated for macros.
-    // Greek capital letter 'Xi' for eXtend.
-    #define _螢(a ,b) a##路##b
-    #define 螢(a ,b) _螢(a ,b)
-
-    // ask the machine what this is
-    // C language standard left this undefined, probably why unicode uses 'octet'
-    // AToW industry uses uint8_t
-    // reminds me of FORTRAN star types
-    #define AU uint8_t
-    #define AU2 uint16_t
-    #define UA4 uint32_t
-    #define UA8 uint64_t
-
-    #define AU_MAX ~(AU)0
-    #define AU2_MAX ~(AU2)0
-    #define UA4_MAX ~(AU4)0
-    #define UA8_MAX ~(AU8)0
-
-    // ask the compiler what this is
-    // when using enums we get this whether we want it or not
-    #define WU unsigned int
-    #define WU ~(WU)0
-
-    // extent is an address or an index.  It is not a length.
-    // The index scaling CVT type is appended to the end of the extent related identifiers..
-    // E.g. exent_of路AU(uint64_t) == 7 while exent_of路uint16_t(uint64_t) == 3;
-    // exent_of路AU of the address space is ~(uintptr)0;
-    #define extent_of路AU(x)(sizeof(x) - 1)
-    #define extent_t路AU size_t
-
-    // Funny, we seldom check for this, but maybe someone is running a microcontroller or something, so we will here. Also, too bad that address 0 can't be used.
-    #define extent_address_space路AU ~(uintptr)0;
-
-    typedef enum{
-       Core路Status路mu = 0
-      ,Core路Status路on_track
-      ,Core路Status路derailed
-    }Core路Status;
+  // if only one template parameter is given, we will assume both are the same
 
+  #if defined(CVT_read) && !defined(CVT_write)
+    #warning "Given CVT_read template value. Missing CVT_write template value, so setting it to CVT_read"
+    #define CVT_write CVT_read
   #endif
 
-  #ifdef CVT
-    #define 螢(extent_t ,CVT) size_t
-  #endif
-
-  //----------------------------------------
-  // argument guard interface
-  //----------------------------------------
-
-  #ifndef CVT  
-
-    typedef void (*Core路Flag路Fn)(WU *flag ,WU err);
-
-    void Core路Flag路count(WU *flag ,WU err){
-      if(err == WU_MAX){ *flag = WU_MAX; return;}
-
-      //*flag + err > WU_MAX
-      if(*flag > WU_MAX - err){ *flag = WU_MAX; return;}
-
-      (*flag) += err;
-    }
-
-    void Core路Flag路collect(WU *flag ,WU err){
-      (*flag) |= err;
-    }
-
-    typedef struct {
-      char *name;
-      Core路Flag路Fn flag_function;
-      WU flag;
-    } Core路Guard;
-
-    typedef struct {
-      void (*init)(Core路Guard *chk ,const char *name ,Core路Flag路Fn af);
-      void (*reset)(Core路Guard *chk);
-      void (*check)(
-         Core路Guard *chk
-        ,WU err
-        ,bool condition
-        ,char *message
-      );
-    } Core路Guard路FG;
-
-    // Default guard function table
-    // initialized in the implementation section below
-    Local Core路Guard路FG Core路Guard路fg;
-
-    #define Core路Guard路init_count(chk) \
-      Core路Guard chk; \
-      Core路Guard路fg.init(&chk ,__func__ ,Core路Flag路count);
-
-    #define Core路Guard路init_collect(chk) \
-      Core路Guard chk; \
-      Core路Guard路fg.init(&chk ,__func__ ,Core路Flag路collect);
-
-    #define Core路Guard路if_return(chk) if( chk.flag ) return Core路Status路derailed;
-    #define Core路Guard路return(chk)\
-      if( chk.flag ) return Core路Status路derailed;\
-      else return Core路Status路on_track;
-
-  #endif 
-
-  //----------------------------------------
-  // functions interface
-  //----------------------------------------
-  
-  // no state, this is merely a namespace
-
-  #ifndef CVT
-    typedef struct{
-      Core路Status (*on_track)();
-      Core路Status (*derailed)();
-      Core路Status (*is_aligned)(AU *p ,extent路AU alignment ,bool *flag);
-      Core路Status (*round_down)(AU *p ,extent路AU alignment ,AU **result);
-      Core路Status (*round_up)(AU *p ,extent路AU alignment ,AU **result);
-    } Core路F;
-    Local Core路F Core路f;
-  #endif 
-
-  #ifdef CVT
-    typedef struct{
-      // nothing here right now
-    } 螢(Core路F ,CVT);
-    Local 螢(Core路F ,CVT) 螢(Core路F ,CVT)路f;
+  #if !defined(CVT_read) && defined(CVT_write)
+    #warning "Given CVT_write template value. Missing CVT_read template value, so setting it to CVT_write"
+    #define CVT_read CVT_write
   #endif
 
   //----------------------------------------
-  // Tape Machine interface
+  // Map status and completion enums
   //----------------------------------------
 
-  #ifndef CVT
-
-    typedef struct Core路TM_NX;
-
-    /*
-      For an CVT machine tape, a mounted tape will be singleton or segment.
-    */
-    typedef enum{
-       Core路Tape路Topo路mu = 0 
-      ,Core路Tape路Topo路nonexistent = 1 
-      ,Core路Tape路Topo路empty       = 1 << 1
-      ,Core路Tape路Topo路singleton   = 1 << 2
-      ,Core路Tape路Topo路segment     = 1 << 3
-      ,Core路Tape路Topo路circle      = 1 << 4
-      ,Core路Tape路Topo路tail_cyclic = 1 << 5
-      ,Core路Tape路Topo路infinite    = 1 << 6
-    }Core路Tape路Topo;
-
-    const Core路Tape路Topo Core路Tape路Topo路finite_nz = 
-      Core路Tape路Topo路singleton | Core路Tape路Topo路segment
-      ;
-
-    // If tape machine does not support step left, then Status路leftmost 
-    // will be reported as Status路interim.
-    typedef enum{
-       Core路TM路Head路Status路mu = 0
-      ,Core路TM路Head路Status路not_on_tape = 1
-      ,Core路TM路Head路Status路origin    = 1 << 1
-      ,Core路TM路Head路Status路interim   = 1 << 2
-      ,Core路TM路Head路Status路rightmost = 1 << 3
-    } Core路TM路Head路Status;
-
-    const Core路TM路Head路Status Core路TM路Head路Status路on_tape = 
-      Core路TM路Head路Status路origin
-      | Core路TM路Head路Status路interim
-      | Core路TM路Head路Status路rightmost
+  #if !defined(CVT_read) && !defined(CVT_write)
+
+    typedef enum {
+       Map路Completion路mu = 0
+      ,Map路Completion路failed          = 1
+      ,Map路Completion路null_fn         = 1 << 1
+      ,Map路Completion路no_tape_access  = 1 << 2
+      ,Map路Completion路rightmost_read  = 1 << 3 
+      ,Map路Completion路rightmost_write = 1 << 4 
+    } Map路Completion;
+
+    // Masks for combinations
+    const uint Map路Completion路rightmost_both =
+        Map路Completion路rightmost_read
+      | Map路Completion路rightmost_write
       ;
 
-    // tape and area are included with Tape Machine to facilitate abstract interfaces.
-    typedef struct{
-
-      struct {
-        Core路Status (*topo)(Core路TM_NX *tm ,Core路Tape路Topo *topo);
-        Core路Status (*extent)(Core路TM_NX *tm ,extent_t路AU *result);
-      } tape;
-
-      struct {
-        // Initialize tm
-        Core路Status (*mount_pe)(Core路TM_NX *tm ,AU position[] ,extent_t路AU extent路AU);
-        Core路Status (*mount_pp)(Core路TM_NX *tm ,AU *position_left ,AU *position_right);
-  
-        // predicates
-        Core路Status (*encloses_pt)(Core路TM_NX *tm ,AU *pt ,bool *result);
-        Core路Status (*encloses_pt_strictly)(Core路TM_NX *tm ,AU *pt ,bool *result);
-        Core路Status (*encloses_area)(Core路TM_NX *outer ,Core路TM_NX *inner ,bool *flag);
-        Core路Status (*encloses_area_strictly)(
-          Core路TM_NX *outer ,Core路TM_NX *inner ,bool *flag
-        );
-        Core路Status (*overlap)(Core路TM_NX *a ,Core路TM_NX *b ,bool *result);
-      } area;
-
-      // tape machine functions
-      Core路Status (*mount)(Core路TM_NX *tm);
-      Core路Status (*dismount)(Core路TM_NX *tm);
-
-      Core路Status (*status)(Core路TM_NX *tm ,Core路TM路Head路Status *status);
-      Core路Status (*can_read)(Core路TM_NX *tm ,bool *flag);
-      Core路Status (*on_origin)(Core路TM_NX *tm ,bool *flag);
-      Core路Status (*on_rightmost)(Core路TM_NX *tm ,bool *flag);
-
-      Core路Status (*copy_datum)(Core路TM_NX *tm_read ,Core路TM_NX *tm_write);
-      Core路Status (*read)(Core路TM_NX *tm ,AU *read_pt);
-      Core路Status (*write)(Core路TM_NX *tm ,AU *write_pt);
-      Core路Status (*head_pt)(Core路TM_NX *tm ,AU *head_pt);
-
-      Core路Status (*rewind)(Core路TM_NX *tm);
-      Core路Status (*step)(Core路TM_NX *tm);
-      Core路Status (*step_left)(Core路TM_NX *tm);
-      Core路Status (*step_right)(Core路TM_NX *tm); // Synonym for step
-
-    } Core路TM_NX路FG;
-
-    Core路TM_NX路FG Core路TM_NX路fg;
-
-  #endif // #ifndef CVT
-
-  #ifndef CVT
-    typedef struct 螢(Core路TM_NX ,CVT);
-
-    typedef struct{
-
-      struct {
-        Core路Status (*extent)(螢(Core路TM_NX ,CVT) *tm ,螢(extent_t ,CVT) *result);
-      } tape;
-
-      struct {
-
-        // Initialize tm
-        Core路Status (*mount_pe)(Core路TM_NX tm ,CVT position[] ,螢(extent_t ,CVT) extent);
-        Core路Status (*mount_pp)(Core路TM_NX *tm ,CVT *position_left ,CVT *position_right);
-
-        // initializes inner
-        Core路Status (*largest_aligned)(Core路TM_NX_uint8_t *outer ,螢(Core路TM_NX ,CVT) *inner);
-
-        Core路Status (*encloses_pt)(螢(Core路TM_NX ,CVT) *tm ,CVT *pt ,bool *result);
-        Core路Status (*encloses_pt_strictly)(螢(Core路TM_NX ,CVT) *tm ,CVT *pt ,bool *result);
-
-        Core路Status (*encloses_area)(
-          螢(Core路TM_NX ,CVT) *outer ,螢(Core路TM_NX ,CVT) *inner ,bool *flag
-        );
-        Core路Status (*encloses_area_strictly)(
-          螢(Core路TM_NX ,CVT) *outer ,螢(Core路TM_NX ,CVT) *inner ,bool *flag
-        );
-        Core路Status (*overlap)(
-          螢(Core路TM_NX ,CVT) *a ,螢(Core路TM_NX ,CVT) *b ,bool *result
-        );
-      } area;
-
-      Core路Status (*copy_datum)( 螢(Core路TM_NX ,CVT) *tm_read ,螢(Core路TM_NX ,CVT) *tm_write );
-      Core路Status       (*read)( 螢(Core路TM_NX ,CVT) *tm ,CVT *remote_pt );
-      Core路Status      (*write)( 螢(Core路TM_NX ,CVT) *tm ,CVT *remote_pt );
-      Core路Status    (*head_pt)( 螢(Core路TM_NX ,CVT) *tm ,CVT *head_pt );
-
-
-    } 螢(Core路TM_NX ,CVT)路FG;
-
-    螢(Core路TM_NX ,CVT)路FG 螢(Core路TM_NX ,CVT)路fg;
-
-  #endif // #ifdef CVT
-
-  //----------------------------------------
-  // Map interface
-  //----------------------------------------
-
-  #ifndef CVT
-
-    typedef enum{
-       Core路Map路Status路mu = 0
-      ,Core路Map路Status路no_tape
-      ,Core路Map路Status路not_computable
-      ,Core路Map路Status路complete
-    } Core路Map路Status;
-
-    typedef enum{
-       Core路Map路Completion路mu = 0
-      ,Core路Map路Completion路null_fn                 = 1 
-      ,Core路Map路Completion路no_tape_access          = 1 << 1
-      ,Core路Map路Completion路failed                  = 1 << 2
-      ,Core路Map路Completion路perfect_fit             = 1 << 3
-      ,Core路Map路Completion路read_surplus            = 1 << 4
-      ,Core路Map路Completion路read_surplus_write_gap  = 1 << 5
-      ,Core路Map路Completion路write_available         = 1 << 6
-      ,Core路Map路Completion路write_gap               = 1 << 7
-    } Core路Map路Completion;
-
-    const uint Core路Map路Completion路derailed =
-        Core路Map路Completion路no_tape                
-      | Core路Map路Completion路not_computable         
-      | Core路Map路Completion路failed
+    const uint Map路Completion路derailed =
+        Map路Completion路failed
+      | Map路Completion路null_fn
+      | Map路Completion路no_tape_access
       ;
 
-    const uint Core路Map路Completion路on_track =
-        Core路Map路Completion路perfect_fit            
-      | Core路Map路Completion路read_surplus           
-      | Core路Map路Completion路read_surplus_write_gap 
-      | Core路Map路Completion路write_available        
-      | Core路Map路Completion路write_gap              
+    const uint Map路Completion路on_track =
+        Map路Completion路rightmost_read
+      | Map路Completion路rightmost_write
+      | Map路Completion路rightmost_both
       ;
 
-    typedef Core路Map路Fn (*Core路Map路Fn)(AU *x ,AU *fx);
-
-  #endif // #ifndef CVT
-
-  #ifdef CVT
-    typedef 螢(Core路Map ,CVT)路Fn (*Core路Map路Fn)(CVT *x ,CVT *fx);
-
-  #endif CVT
-
-#endif
-
-//--------------------------------------------------------------------------------
-// Implementation
-
-#ifdef Core路IMPLEMENTATION
-  // declarations available to all of the IMPLEMENTATION go here
-  //
-    #ifdef Core路DEBUG
-      #include <stdio.h>
-    #endif
-
-  // implementation to go into the lib.a file
-  //
-    #ifndef LOCAL
-    #endif 
-
-  #ifdef LOCAL
-
-    //----------------------------------------
-    // argument guard implementation
-    //----------------------------------------
-
-    #ifndef CVT
-      Local void Core路Guard路init(Core路Guard *chk ,Core路Flag路Fn af){
-        if( !chk ) return;
-        chk->flag_function = af;
-        chk->flag = 0;
-      }
-
-      Local void Core路Guard路reset(Core路Guard *chk){
-        if( !chk ) return;
-        chk->flag = 0;
-      }
-
-      Local void Core路Guard路check(
-         Core路Guard *chk
-        ,uint err
-        ,bool condition
-        ,const char *message
-      ){
-        if( !chk || !chk->flag_function ) return;
-        if( condition ) return;
-        fprintf(stderr ,"%s\n" ,message);
-        chk->flag_function(&chk->flag ,err);
-      }
-
-      Local Core路Guard路FG Core路Guard路fg = {
-         .init = Core路Guard路init
-        ,.reset = Core路Guard路reset
-        ,.check = Core路Guard路check
-      };
-    #endif // *ifndef CVG
-
-    //----------------------------------------
-    // Functions implementation
-    //----------------------------------------
-
-    #ifndef CVT
-
-      Core路Status Core路on_track(){ return Core路Status路on_track; }
-      Core路Status Core路derailed(){ return Core路Status路derailed; }
-
-      Local Core路Status Core路is_aligned(AU *p ,extent路AU alignment ,bool *flag){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,p ,"given NULL p");
-          Core路Guard路fg.check(&chk ,1 ,flag ,"flag is NULL, so nowhere to write result");
-          Core路Guard路if_return(chk);
-        #endif
-        *flag = ( (uintptr_t)p & alignment ) == 0;
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路round_down(AU *p ,extent路AU alignment ,AU **result){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,p ,"given NULL p to round");
-          Core路Guard路fg.check(&chk ,1 ,result ,"result is NULL, so nowhere to write result");
-          Core路Guard路if_return(chk);
-        #endif
-        *result = (AU *)( (uintptr_t)p & ~(uintptr_t)alignment );
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路round_up(AU *p ,extent路AU alignment ,AU **result){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,p ,"given NULL p to round");
-          Core路Guard路fg.check(&chk ,1 ,result ,"result is NULL, so nowhere to write result");
-          Core路Guard路if_return(chk);
-        #endif
-        *result = (AU *)( ( (uintptr_t)p + alignment ) & ~(uintptr_t)alignment );
-        return Core路Status路on_track;
-      }
-
-      Local Core路F Core路f = {
-        .on_track = Core路on_track
-        ,.derailed = Core路derailed
-        ,.is_aligned = Core路is_aligned
-        ,.round_down = round_down
-        ,.round_up = round_up
-      };
-
-    #endif // #ifndef CVT
-
-    #ifdef CVT
-
-      // Struct instance initialization
-      螢(Core路F ,CVT) 螢(Core路F ,CVT)路f = {
-      };
-
-    #endif
-
-  //----------------------------------------
-  // TM_NX implementation
-  //----------------------------------------
-
-  /*
-  TM_NX are initialized with calls to 'mount_pe' or 'mount_pp'.  These both bind the machine to a tape, and mount the tape. Hence, there is no such thing as an initialized which is not bound to a tape. (It is possible to dismount the tm->hd, then remount tm->hd, but the tape remains bound through that process.)
-
-  Because the TM_NX has no destructive operations, Once it is initialized the tape will never get shorter. With TM_MX it is not possible to mount an empty tape, because the minimum value of extent路AU is zero. Therefore the tape can never be empty.
-
-  For an initialized TM_NX, TM_NX.array.hd == NULL means the tape is currently not mounted.
-
-  C has no means of binding an operation to allocation apart from the initializer syntax, but the user might not initialize a tape machine after allocating one. There is no deterministic method available to a TM_NX to detect if a machine is uninitialized. However, if it happens that TM_NX.array.position == NULL, the only explanations are 1) a bug  2) the machine was not initialized - and the initialized data in TM_NX.array.position happened to be zero. 
-
-  It is an error to re-initialize the machine while it is being used, unfortunately this is a contract with the user, because the TM_NX has no way to detect if the machine was initialized in the first place. 
-
-  */
-
-  #ifndef CVT
-    struct{
-      AU *position;
-      extent路AU extent路AU;
-      AU *hd;
-    }Core路TM_NX;
-  #endif
-
-  #ifdef CVT
-    struct{
-      CVT *position;
-      extent路AU extent路AU;
-      CVT *hd;
-    }螢(Core路TM_NX ,CVT);
   #endif
 
   //----------------------------------------
-  // TM_NX implementation
+  // Map interface
   //----------------------------------------
 
-    //-----------------------------------
-    // common error messages
-
-    const char *螢(Core路TM_NX ,CVT)路Msg路tm="given NULL tm";
-    const char *螢(Core路TM_NX ,CVT)路Msg路flag="given NULL flag pointer";
-    const char *螢(Core路TM_NX ,CVT)路Msg路address=
-      "given NULL address pointer ,or address struct holds NULL address";
-    const char *螢(Core路TM_NX ,CVT)路Msg路address_on_tape=
-      "given address is not on the tape";
-    const char *螢(Core路TM_NX ,CVT)路Msg路extent路AU="given NULL extent路AU pointer";
-    const char *螢(Core路TM_NX ,CVT)路Msg路position=
-      "Null position.This is only possible when the tape machine has not been initialized.";
-
-    #ifndef CVT
-      Core路Status Core路TM_NX路topo(Core路TM_NX *tm ,Core路Tape路Topo *topo){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,topo ,"topo ptr is NULL, so nowhere to put result");
-          Core路Guard路if_return(chk);
-        #endif
-        if(tm->extent路AU == 0){
-          *topo = Core路Tape路Topo路singleton; 
-        }else{
-          *topo = Core路Tape路Topo路segment;
-        }
-        return Core路Status路on_track;
-      }
-
-      // extent路AU is an AU index
-      Local Core路Status Core路TM_NX路extent路AU(Core路TM_NX *tm ,extent路AU *extent路AU){
-        Core路Tape路Topo topo;
-        Core路Status status = Core路TM_NX_##CVT路topo(tm ,&topo);
-        boolean good_topo = 
-          (status == Core路Status路on_track) && (topo & Core路Tape路Topo路finite_nz)
-          ;
-
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,extent路AU ,Core路TM_NX路Msg路extent路AU);
-          Core路Guard路fg.check(
-            &chk ,0 ,good_topo
-            ,"Tape does not exist or topology does not have an extent路AU."
-          );
-          Core路Guard路if_return(chk);
-        #endif
-
-        if(!good_topo) return Core路Status路derailed;
-        *extent路AU = tm->array.extent路AU;
-        return Core路Status路on_track;
-      }
-
-    #endif
-
-    #ifdef CVT
-
-      //-----------------------------------
-      // Area functions within Core路TM_NX_##CVT
-
-      Core路Status Core路TM_NX_##CVT路topo(Core路TM_NX *tm ,Core路Tape路Topo *topo){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,topo ,"topo ptr is NULL, so nowhere to put result");
-          Core路Guard路if_return(chk);
-        #endif
-          if(tm->extent路AU == 0){
-            *topo = Core路Tape路Topo路singleton; 
-          }else{
-            *topo = Core路Tape路Topo路segment;
-          }
-          return Core路Status路on_track;
-      }
-
-
-      Local Core路Status Core路TM_NX_##CVT路mount_pe(
-        Core路TM_NX *tm ,void *position ,extent路AU extent路AU
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,position ,"given NULL position");
-          Core路Guard路if_return(chk);
-        #endif
-        tm->array.position = position->array.address;
-        tm->array.extent路AU = extent路AU;
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路mount_pp(
-        Core路TM_NX *tm ,void *position_left ,void *position_right
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          bool good_address = position_left && position_left->address;
-          Core路Guard路fg.check(&chk ,1 ,good_address ,Core路TM_NX_##CVT路Msg路address);
-          good_address = position_right && position_right->address;
-          Core路Guard路fg.check(&chk ,1 ,good_address ,Core路TM_NX_##CVT路Msg路address);
-          if(position_left && position_right){
-            Core路Guard路fg.check(
-              &chk ,1 ,position_right->array.address >= position_left->array.address
-              ,"position_right < position_left"
-            );
-          }
-          Core路Guard路if_return(chk);
-        #endif
-
-        extent路AU computed_extent路AU = 
-            (extent路AU)(
-              (uintptr_t)position_right->array.address - (uintptr_t)position_left->array.address
-            );
-
-        return Core路TM_NX_##CVT路mount_pe(tm ,position_left ,computed_extent路AU);
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路largest_aligned_64(
-        Core路TM_NX *outer ,Core路TM_NX *inner_64
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,outer ,"given NULL outer TM");
-          if(outer){
-            Core路Guard路fg.check(&chk ,1 ,outer->array.position ,"NULL outer->array.position");
-          }
-          Core路Guard路fg.check(&chk ,1 ,inner_64 ,"given NULL inner TM");
-          Core路Guard路fg.check(&chk ,1 ,outer->array.position ,"outer TM has NULL position");
-          Core路Guard路if_return(chk);
-        #endif
-
-        uintptr_t p0 = (uintptr_t)outer->array.position;
-        uintptr_t p1 = (uintptr_t)outer->array.position + outer->array.extent路AU;
-
-        CVT *p0_64 = (CVT *)( (p0 + 0x7) & ~(uintptr_t)0x7 );
-        CVT *p1_64 = (CVT *)( (p1 - 0x7) & ~(uintptr_t)0x7 );
-
-        if(p1_64 < p0_64){
-          inner_64->array.position = NULL;
-          inner_64->array.extent路AU = 0;
-          return Core路Status路derailed;
-        }
-
-        inner_64->array.position = p0_64;
-        inner_64->array.extent路AU = (extent路AU)(p1_64 - p0_64);
-        return Core路Status路on_track;
-      }
+  #if !defined(CVT_read) || !defined(CVT_write)
 
+    typedef struct {
+      Map路Completion (*copy_byte_to_byte)(
+        螢(TM路Array ,AU) *read_tm
+        ,螢(TM路Array ,AU) *write_tm
+      );
 
-      Local Core路Status Core路TM_NX_##CVT路encloses_pt(
-        Core路TM_NX *tm ,void *a ,bool *result
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          bool good_address = a && a->address;
-          Core路Guard路fg.check(&chk ,1 ,good_address ,Core路TM_NX_##CVT路Msg路address);
-          Core路Guard路fg.check(&chk ,1 ,result ,"given NULL result pointer");
-          Core路Guard路if_return(chk);
-        #endif
-
-        *result = 
-             (a->array.address >= tm->array.position) 
-          && (a->array.address <= tm->array.position + tm->array.extent路AU);
-
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路encloses_pt_strictly(
-        Core路TM_NX *tm ,void *a ,bool *result
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          bool good_address = a && a->address;
-          Core路Guard路fg.check(&chk ,1 ,good_address ,Core路TM_NX_##CVT路Msg路address);
-          Core路Guard路fg.check(&chk ,1 ,result ,"given NULL result pointer");
-          Core路Guard路if_return(chk);
-        #endif
-
-        *result = 
-             (a->array.address > tm->array.position) 
-          && (a->array.address < tm->array.position + tm->array.extent路AU);
-
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路encloses_tm(
-        Core路TM_NX *outer ,Core路TM_NX *inner ,bool *flag
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,outer ,"given NULL outer TM");
-          if(outer){
-            Core路Guard路fg.check(&chk ,1 ,outer->array.position ,"NULL outer->array.position");
-          }
-          Core路Guard路fg.check(&chk ,1 ,inner ,"given NULL inner TM");
-          if(inner){
-            Core路Guard路fg.check(&chk ,1 ,inner->array.position ,"NULL inner->array.position");
-          }
-          Core路Guard路fg.check(&chk ,1 ,flag ,"given NULL flag pointer");
-          Core路Guard路if_return(chk);
-        #endif
-
-        *flag =
-             (inner->array.position >= outer->array.position) 
-          && (inner->array.position + inner->array.extent路AU <= outer->array.position + outer->array.extent路AU);
-
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路encloses_tm_strictly(
-        Core路TM_NX *outer ,Core路TM_NX *inner ,bool *flag
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,outer ,"given NULL outer TM");
-          if(outer){
-            Core路Guard路fg.check(&chk ,1 ,outer->array.position ,"NULL outer->array.position");
-          }
-          Core路Guard路fg.check(&chk ,1 ,inner ,"given NULL inner TM");
-          if(inner){
-            Core路Guard路fg.check(&chk ,1 ,inner->array.position ,"NULL inner->array.position");
-          }
-          Core路Guard路fg.check(&chk ,1 ,flag ,"given NULL flag pointer");
-          Core路Guard路if_return(chk);
-        #endif
-
-        *flag =
-             (inner->array.position > outer->array.position) 
-          && (inner->array.position + inner->array.extent路AU < outer->array.position + outer->array.extent路AU);
-
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路overlap(
-        Core路TM_NX *a ,Core路TM_NX *b ,bool *result
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,a ,"given NULL TM A");
-          if(a){
-            Core路Guard路fg.check(&chk ,1 ,a->array.position ,"NULL a->array.position");
-          }
-          Core路Guard路fg.check(&chk ,1 ,b ,"given NULL TM B");
-          if(b){
-            Core路Guard路fg.check(&chk ,1 ,b->array.position ,"NULL b->array.position");
-          }
-          Core路Guard路fg.check(&chk ,1 ,result ,"given NULL result pointer");
-          Core路Guard路if_return(chk);
-        #endif
-
-        *result =
-             (a->array.position < b->array.position + b->array.extent路AU) 
-          && (b->array.position < a->array.position + a->array.extent路AU);
-
-        return Core路Status路on_track;
-      }
-
-
-      //-----------------------------------
-      // base Tape Machine operations
-
-      Local Core路Status Core路TM_NX_##CVT路mount(Core路TM_NX *tm){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,tm->array.position ,Core路TM_NX_##CVT路Msg路position);
-          Core路Guard路if_return(chk);
-        #endif
-
-        tm->array.hd = tm->array.position;
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路dismount(Core路TM_NX *tm){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路if_return(chk);
-        #endif
-
-        // Reset head position upon dismount
-        tm->array.hd = NULL;
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路status(
-        Core路TM_NX *tm ,Core路TM路Head路Status *status
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,status ,"given NULL status pointer");
-          Core路Guard路if_return(chk);
-        #endif
-
-        if(tm->array.hd == NULL){
-          *status = Core路TM路Head路Status路not_on_tape;
-        }else if(tm->array.hd == tm->array.position){
-          *status = Core路TM路Head路Status路origin;
-        }else if(tm->array.hd == tm->array.position + tm->array.extent路AU){
-          *status = Core路TM路Head路Status路rightmost;
-        }else{
-          *status = Core路TM路Head路Status路interim;
-        }
-
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路can_read(Core路TM_NX *tm ,bool *flag){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          if(tm){
-            // All initialized TM_NX_##CVT have an initialized position
-            // Maybe this catches that the machine is uninitialized?
-            Core路Guard路fg.check(&chk ,1 ,tm->array.position ,Core路TM_NX_##CVT路Msg路position);
-          }      
-          Core路Guard路fg.check(&chk ,1 ,flag ,Core路TM_NX_##CVT路Msg路flag);
-          Core路Guard路if_return(chk);
-        #endif
-        *flag = tm && tm->array.hd != NULL;
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路on_origin(
-        Core路TM_NX *tm ,bool *flag
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,tm && tm->array.position ,Core路TM_NX_##CVT路Msg路position);
-          Core路Guard路fg.check(&chk ,1 ,flag ,Core路TM_NX_##CVT路Msg路flag);
-          Core路Guard路if_return(chk);
-        #endif
-
-        *flag = (tm->array.hd == tm->array.position);
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路on_rightmost(
-        Core路TM_NX *tm ,bool *flag
-      ){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,flag ,Core路TM_NX_##CVT路Msg路flag);
-          Core路Guard路fg.check(&chk ,1 ,tm && tm->array.position ,Core路TM_NX_##CVT路Msg路position);
-          Core路Guard路if_return(chk);
-        #endif
-
-        *flag = tm->array.hd == (tm->array.position + tm->array.extent路AU);
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路copy_datum(Core路TM_NX *tm_read ,Core路TM_NX *tm_write){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm_read ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,tm_write ,Core路TM_NX_##CVT路Msg路tm);
-          if(tm_read && tm_write){
-            Core路Guard路fg.check(
-              &chk ,1 ,Core路TM_NX_##CVT路area.encloses_pt(tm_read ,tm_read->array.hd) 
-              ,"Source address is outside tape bounds"
-            );
-            Core路Guard路fg.check(
-              &chk ,1 ,Core路TM_NX_##CVT路area.encloses_pt(tm_write ,tm_write->array.hd) 
-              ,"Destination address is outside tape bounds"
-            );
-          }
-          Core路Guard路if_return(chk);
-        #endif
-
-        *(tm_write->array.hd) = *(tm_read->array.hd);
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路read(Core路TM_NX *tm ,void *read_pt){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          if(tm) Core路Guard路fg.check(&chk ,1 ,tm->array.hd ,Core路TM_NX_##CVT路Msg路address);
-          if(tm && tm->array.hd){
-            Core路Guard路fg.check(
-              &chk ,1 ,Core路TM_NX_##CVT路area.encloses_pt(tm ,tm->array.hd) 
-              ,"Given address is outside tape bounds"
-            );
-          }
-          Core路Guard路if_return(chk);
-        #endif
-
-        *(CVT *)read_pt = *(tm_array.hd);
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路write(Core路TM_NX *tm ,void *write_pt){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          if(tm) Core路Guard路fg.check(&chk ,1 ,tm->array.hd ,Core路TM_NX_##CVT路Msg路address);
-          if(tm && tm->array.hd){
-            Core路Guard路fg.check(
-              &chk ,1 ,Core路TM_NX_##CVT路area.encloses_pt(tm ,tm->array.hd) 
-              ,"Given address is outside tape bounds"
-            );
-          }
-          Core路Guard路if_return(chk);
-        #endif
-
-        *(tm->array.hd) = *(CVT *)write_pt;
-        return Core路Status路on_track;
-      }
-
-      Local Core路Status Core路TM_NX_##CVT路rewind(Core路TM_NX *tm){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          if(tm){
-            Core路Guard路fg.check(&chk ,1 ,tm->array.position ,Core路TM_NX_##CVT路Msg路position);
-          }
-          Core路Guard路if_return(chk);
-        #endif
-        tm->array.hd = tm->array.position;
-        return Core路Status路on_track;
-      }
-
-      Core路Status Core路TM_NX_##CVT路step(Core路TM_NX *tm){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,tm->array.position ,"step requested on unbound machine");
-          Core路Guard路fg.check(&chk ,1 ,tm->array.hd ,"step requested but tape not mounted");
-          Core路Guard路if_return(chk);
-        #endif
-        if( tm->array.hd < tm->array.position + tm->array.extent路AU ){
-          tm->array.hd++;
-          return Core路Status路on_track;
-        }
-        return Core路Status路derailed; // Stepping beyond tape bounds
-      }
-
-      Core路Status Core路TM_NX_##CVT路step_left(Core路TM_NX *tm){
-        #ifdef Core路Debug
-          Core路Guard路init_count(chk);
-          Core路Guard路fg.check(&chk ,1 ,tm ,Core路TM_NX_##CVT路Msg路tm);
-          Core路Guard路fg.check(&chk ,1 ,tm->array.position 
-            ,"step_left requested on unbound machine"
-          );
-          Core路Guard路fg.check(&chk ,1 ,tm->array.hd 
-            ,"step_left requested with no mounted head"
-          );
-          Core路Guard路if_return(chk);
-        #endif
-        if( tm->array.hd > tm->array.position ){
-          tm->array.hd--;
-          return Core路Status路on_track;
-        }
-        return Core路Status路derailed; // Stepping beyond left boundary
-      }
-
-      // step_right is a synonym for step
-
-
-      //----------------------------------------
-      // Initialization for Core路TM_NX_##CVT路fg
-
-      Local Core路TM_NX路FG Core路TM_NX_##CVT路fg = {
-         .mount = Core路TM_NX_##CVT路mount
-        ,.dismount = Core路TM_NX_##CVT路dismount
-
-        ,.status = Core路TM_NX_##CVT路status
-        ,.can_read = Core路TM_NX_##CVT路can_read
-        ,.on_origin = Core路TM_NX_##CVT路on_origin
-        ,.on_rightmost = Core路TM_NX_##CVT路on_rightmost
-
-        ,.read = Core路TM_NX_##CVT路read
-        ,.write = Core路TM_NX_##CVT路write
-
-        ,.rewind = Core路TM_NX_##CVT路rewind
-        ,.step = Core路TM_NX_##CVT路step
-        ,.step_left = Core路TM_NX_##CVT路step_left
-        ,.step_right = Core路TM_NX_##CVT路step_right // Synonym for step
-
-        ,.area = {
-           .topo = Core路TM_NX_##CVT路topo
-          ,.extent路AU = Core路TM_NX_##CVT路extent路AU
-
-          ,.mount_pe = Core路TM_NX_##CVT路mount_pe
-          ,.mount_pp = Core路TM_NX_##CVT路mount_pp
-          ,.largest_aligned_64 = Core路TM_NX_##CVT路largest_aligned_64
-
-          ,.encloses_pt = Core路TM_NX_##CVT路encloses_pt
-          ,.encloses_pt_strictly = Core路TM_NX_##CVT路encloses_pt_strictly
-          ,.encloses_tm = Core路TM_NX_##CVT路encloses_tm
-          ,.encloses_tm_strictly = Core路TM_NX_##CVT路encloses_tm_strictly
-          ,.overlap = Core路TM_NX_##CVT路overlap
-        }
-      };
-
-    #endif
-
-    //----------------------------------------
-    // Map implementation
-    //----------------------------------------
-
-
-Core路Map路Completion Core路map(TM_MX *tm_read ,TM_MX *tm_write ,Core路Map路Fn fn){
-
-  Core路Guard路init_collect(chk);
-  if(!fn) chk.flag |= Core路Map路Completion路null_fn;
-  bool tm_read_can_read=false ,tm_write_can_read=false;
-  Core路TM路Head路Status tm_read_status ,tm_write_status;
-  if(
-    tm_read->can_read(tm_read ,&tm_read_can_read) == Core路Status路derailed
-    || tm_write->can_read(tm_write ,&tm_write_can_read) == Core路Status路derailed
-    || !tm_read_can_read
-    || !tm_write_can_read
-  ){
-    chk.flag |= Core路Map路Completion路no_tape_access;
-  }
-  Core路Guard路return(chk);
-
-  do{
-    TM_MX路Remote d_remote;
-    if( tm_read->read(tm_read ,&d_addr ,&d_remote) != Core路Status路on_track ){
-      chk.flag |= Core路Map路Completion路failed;
-      break;
-    }
-
-    TM_MX路Remote r_remote;
-    if(map->fn(&d_remote ,&r_remote) != Core路Status路on_track){
-      chk.flag |= Core路Map路Completion路not_computable;
-      break;
-    }
-
-    Core路TM_NX路Address r_addr;
-    if( tm_write->write(tm_write ,&r_addr ,&r_remote) != Core路Status路on_track ){
-      chk.flag |= Core路Map路Completion路failed;
-      break;
-    }
-
-    if(
-      tm_read->step(tm_read) != Core路Status路on_track
-      || tm_write->step(tm_write) != Core路Status路on_track
-    ){
-      chk.flag |= Core路Map路Completion路failed;
-      break;
-    }
-
-    tm_read->status(tm_read ,&tm_read_status);
-    tm_write->status(tm_write ,&tm_write_status);
-
-    if(
-      tm_read_status & Core路TM路Head路Status路rightmost
-      && tm_write_status & Core路TM路Head路Status路rightmost
-    ){
-      chk.flag |= Core路Map路Completion路perfect_fit;
-      break;
-    }
-
-    if(tm_read_status & Core路TM路Head路Status路rightmost){
-      chk.flag |= Core路Map路Completion路read_surplus;
-      break;
-    }
-
-    if(tm_write_status & Core路TM路Head路Status路rightmost){
-      chk.flag |= Core路Map路Completion路write_available;
-      break;
-    }
-
-  }while(true);
-
-  Core路Guard路return(chk);
-}
-
-
-    // Map function using trampoline execution model
-    Local Core路Map路Status Core路map(Core路Map路Fn fn){
-      #ifdef Core路Debug
-      if(!fn){
-        fprintf(stderr,"Core路map:: given null function");
-        return Core路Map路argument_guard;
-      }
-      if(
-         true
-         && fn != Core路Map路by_##CVT
-         && fn != Core路Map路##CVT_by_##CVT
-         && fn != Core路write_hex
-         && fn != Core路read_hex
-      ){
-        fprintf(stderr,"Core路map:: unrecognized copy function\n");
-        return Core路Map路argument_guard;
-      ) 
-      #endif
-
-      while(fn) fn = fn();
-      return tf.copy.status;
-    }
-
-
-
-    //----------------------------------------
-    // copy byte_by_byte 
-    //----------------------------------------
-
-    Core路Map路Fn Core路Map路Map路ByteByByte路perfect_fit;
-    Core路Map路Fn Core路Map路Map路ByteByByte路read_surplus;
-    Core路Map路Fn Core路Map路Map路ByteByByte路write_available;
-
-    Local Core路Map路Fn Core路Map路##CVT_by_##CVT(){
-      if(Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.read) == Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.write))
-        return Core路Map路ByteByByte路perfect_fit;
-
-      if(Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.read) > Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.write))
-        return Core路Map路ByteByByte路read_surplus;
-
-      return Core路Map路ByteByByte路write_available;
-    }
-
-    Local Core路Map路Fn Core路Map路ByteByByte路perfect_fit(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
-
-      do{
-        **w = Core路tf.copy.read_fn_8(Core路tf.copy.read ,*r);
-        if(*r == r1) break;
-        (*r)++;
-        (*w)++;
-      }while(true);
-
-      Core路tf.copy.status = Core路Map路Status路perfect_fit;
-      return NULL;
-    }
-
-    Local Core路Map路Fn Core路Map路ByteByByte路read_surplus(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
-      CVT *w1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.write);
-
-      do{
-        **w = Core路tf.copy.read_fn_8(Core路tf.copy.read ,*r);
-        if(*w == w1) break;
-        (*r)++;
-        (*w)++;
-      }while(true);
-
-      Core路tf.copy.status = Core路Map路Status路write_available;
-      return NULL;
-    }
-
-    Local Core路Map路Fn Core路Map路ByteByByte路write_avalable(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
-
-      do{
-        **w = Core路tf.copy.read_fn_8(Core路tf.copy.read ,*r);
-        if(*r == r1) break;
-        (*r)++;
-        (*w)++;
-      }while(true);
-
-      Core路tf.copy.status = Core路Map路Status路read_surplus;
-      return NULL;
-    }
-
-    //----------------------------------------
-    // copy copy_64
-
-    // 64-bit copy function with updated TableauFace terminology
-    Core路Map路Fn Core路Map路by_##CVT;
-    Core路Map路Fn Core路Map路ByWord64路leadin;
-    Core路Map路Fn Core路Map路ByWord64路bulk;
-    Core路Map路Fn Core路Map路ByWord64路tail;
-
-    // Initialize the copy_64 process
-    Local Core路Map路Fn Core路Map路by_##CVT(){
-      // Determine the largest 64-bit aligned region within the read area
-      Core路TM_NX_##CVT路largest_aligned_64(Core路tf.copy.read ,&Core路tl.copy_64.area_64);
-
-      // Choose the correct function based on alignment
-      if(Core路TM_NX_##CVT路empty(&Core路tl.copy_64.area_64)) return Core路Map路ByWord64路tail;
-      if(Core路is_aligned_on_64(Core路TM_NX_##CVT路position(Core路tf.copy.read))) return Core路Map路ByWord64路bulk;
-      return Core路Map路ByWord64路leadin;
-    }
-
-    // Lead-in byte copy (until alignment)
-    Local Core路Map路Fn Core路Map路ByWord64路leadin(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r0_64 = Core路TM_NX_##CVT路position(&Core路tl.copy_64.area_64);
-      CVT **w = &Core路tf.copy.write_pt;
-
-      do{
-        **w = Core路tf.copy.read_fn_8(Core路tf.copy.read ,r0_64 ,*r);
-        if(*r == r0_64) break;
-        (*r)++;
-        (*w)++;
-      }while(true);
-
-      return Core路Map路ByWord64路bulk;
-    }
-
-    // Bulk word copy
-    Local Core路Map路Fn Core路Map路ByWord64路bulk(){
-      uint64_t **r = (uint64_t **)&Core路tf.copy.read_pt;
-      uint64_t **w = (uint64_t **)&Core路tf.copy.write_pt;
-      uint64_t *r1_64 = Core路TM_NX_##CVT路position_right(&Core路tl.copy_64.area_64);
-
-      do{
-        **w = Core路tf.copy.read_fn_64(Core路tf.copy.read ,r1_64 ,*r);
-        if(*r == r1_64) break;
-        (*r)++;
-        (*w)++;
-      }while(true);
-
-      return Core路Map路ByWord64路tail;
-    }
-
-    // Tail byte copy (unaligned trailing bytes)
-    Local Core路Map路Fn Core路Map路ByWord64路tail(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(&Core路tl.copy_64.area_64);
-      CVT **w = &Core路tf.copy.write_pt;
-
-      do{
-        **w = Core路tf.copy.read_fn_8(Core路tf.copy.read ,r1 ,*r);
-        if(*r == r1) break;
-        (*r)++;
-        (*w)++;
-      }while(true);
-
-      Core路tf.copy.status = Core路Map路Status路perfect_fit;
-      return NULL;
-    }
-
-    //----------------------------------------
-    // copy write hex
-
-    Local uint16_t Core路byte_to_hex(CVT byte){
-      static const char hex_digits[] = "0123456789ABCDEF";
-      return 
-          (hex_digits[byte >> 4] << 8) 
-        | hex_digits[byte & 0x0F];
-    }
-
-    // Forward Declarations
-    Core路Map路Fn Core路Map路write_hex;
-    Core路Map路Fn Core路Map路WriteHex路perfect_fit;
-    Core路Map路Fn Core路Map路WriteHex路read_surplus;
-    Core路Map路Fn Core路Map路WriteHex路write_available;
-
-    // Hex Encoding: Initialize Map
-    Local Core路Map路Fn Core路Map路write_hex(){
-      if(Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.read) == (Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.write) >> 1)){
-        return Core路Map路WriteHex路perfect_fit;
-      }
-      if(Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.read) > (Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.write) >> 1)){
-        return Core路Map路WriteHex路read_surplus;
-      }
-      return Core路Map路WriteHex路write_available;
-    }
-
-    Local Core路Map路Fn Core路Map路WriteHex路perfect_fit(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
-
-      do {
-        *(uint16_t *)*w = Core路hex.byte_to_hex(**r);
-        if(*r == r1) break;
-        (*r)++;
-        (*w) += 2;
-      } while(true);
-
-      Core路tf.copy.status = Core路Map路Status路perfect_fit;
-      return NULL;
-    }
-
-    // Hex Encoding: Read Surplus
-    Local Core路Map路Fn Core路Map路WriteHex路read_surplus(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.write);
-      CVT **w = &Core路tf.copy.write_pt;
-
-      do {
-        *(uint16_t *)*w = Core路write_hex.byte_to_hex(**r);
-        if(*r == r1) break;
-        (*r)++;
-        (*w) += 2;
-      } while(true);
-
-      Core路tf.copy.status = Core路Map路Status路read_surplus;
-      return NULL;
-    }
-
-    // Hex Encoding: Write Available
-    Local Core路Map路Fn Core路Map路WriteHex路write_available(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
-      CVT *w1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.write);
-
-      do {
-        *(uint16_t *)*w = Core路write_hex.byte_to_hex(**r);
-        if(*w == w1) break;
-        (*r)++;
-        (*w) += 2;
-      } while(true);
-
-      Core路tf.copy.status = Core路Map路Status路write_available;
-      return NULL;
-    }
-
-    //----------------------------------------
-    // copy read hex
-
-    Local CVT Core路hex_to_byte(uint16_t hex){
-      CVT high = hex >> 8;
-      CVT low = hex & 0xFF;
-
-      high = 
-          (high >= '0' && high <= '9') ? (high - '0')
-        : (high >= 'A' && high <= 'F') ? (high - 'A' + 10)
-        : (high >= 'a' && high <= 'f') ? (high - 'a' + 10)
-        : 0;
-
-      low = 
-          (low >= '0' && low <= '9') ? (low - '0')
-        : (low >= 'A' && low <= 'F') ? (low - 'A' + 10)
-        : (low >= 'a' && low <= 'f') ? (low - 'a' + 10)
-        : 0;
-
-      return (high << 4) | low;
-    }
-
-    Core路Map路Fn Core路Map路read_hex;
-    Core路Map路Fn Core路Map路ReadHex路perfect_fit;
-    Core路Map路Fn Core路Map路ReadHex路read_surplus;
-    Core路Map路Fn Core路Map路ReadHex路write_available;
-
-    Local Core路Map路Fn Core路Map路read_hex(){
-      if((Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.read) >> 1) == Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.write)){
-        return Core路Map路ReadHex路perfect_fit;
-      }
-      if((Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.read) >> 1) > Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.write)){
-        return Core路Map路ReadHex路read_surplus;
-      }
-      return Core路Map路ReadHex路write_available;
-    }
-
-    Local Core路Map路Fn Core路Map路ReadHex路perfect_fit(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
-
-      do {
-        **w = Core路hex_to_byte(*(uint16_t *)*r);
-        if(*r == r1) break;
-        (*r) += 2;
-        (*w)++;
-      } while(true);
-
-      Core路tf.copy.status = Core路Map路Status路perfect_fit;
-      return NULL;
-    }
-
-    Local Core路Map路Fn Core路Map路ReadHex路read_surplus(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.write);
-      CVT **w = &Core路tf.copy.write_pt;
-
-      do {
-        **w = Core路tf.read_hex.hex_to_byte(*(uint16_t *)*r);
-        if(*r == r1) break;
-        (*r) += 2;
-        (*w)++;
-      } while(true);
-
-      Core路tf.copy.status = Core路Map路Status路read_surplus;
-      return NULL;
-    }
-
-    Local Core路Map路Fn Core路Map路ReadHex路write_available(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
-      CVT *w1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.write);
-
-      do {
-        **w = Core路tf.read_hex.hex_to_byte(*(uint16_t *)*r);
-        if(*w == w1) break;
-        (*r) += 2;
-        (*w)++;
-      } while(true);
-
-      Core路tf.copy.status = Core路Map路Status路write_available;
-      return NULL;
-    }
-
-    //----------------------------------------
-    // copy read hex
-
-    Core路Map路Fn Core路Map路read_hex;
-    Core路Map路Fn Core路Map路ReadHex路perfect_fit;
-    Core路Map路Fn Core路Map路ReadHex路read_surplus;
-    Core路Map路Fn Core路Map路ReadHex路write_available;
+      Map路Completion (*copy_hex_to_byte)(
+        螢(TM路Array ,uint16_t) *read_tm
+        ,螢(TM路Array ,AU) *write_tm
+      );
 
-    Local Core路Map路Fn Core路Map路read_hex(){
-      if((Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.read) >> 1) == Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.write)){
-        return Core路Map路ReadHex路perfect_fit;
-      }
-      if((Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.read) >> 1) > Core路TM_NX_##CVT路extent_by路AU(Core路tf.copy.write)){
-        return Core路Map路ReadHex路read_surplus;
-      }
-      return Core路Map路ReadHex路write_available;
-    }
+      Map路Completion (*copy_byte_to_hex)(
+        螢(TM路Array ,AU) *read_tm
+        ,螢(TM路Array ,uint16_t) *write_tm
+      );
 
-    Local Core路Map路Fn Core路Map路ReadHex路perfect_fit(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
+      // Terminate string function
+      Map路Completion (*terminate_string)(
+        螢(TM路Array ,AU) *write_tm
+      );
+    } Map路FG;
 
-      do {
-        **w = Core路hex_to_byte(*(uint16_t *)*r);
-        if(*r == r1) break;
-        (*r) += 2;
-        (*w)++;
-      } while(true);
+     // a default function given table
+     Map路FG Map路fg;
 
-      Core路tf.copy.status = Core路Map路Status路perfect_fit;
-      return NULL;
-    }
+  #endif
 
-    Local Core路Map路Fn Core路Map路ReadHex路read_surplus(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.write);
-      CVT **w = &Core路tf.copy.write_pt;
 
-      do {
-        **w = Core路hex_to_byte(*(uint16_t *)*r);
-        if(*r == r1) break;
-        (*r) += 2;
-        (*w)++;
-      } while(true);
+  #if defined(CVT_read) && defined(CVT_write)
 
-      Core路tf.copy.status = Core路Map路Status路read_surplus;
-      return NULL;
-    }
+    // Function passed to map type signature must be this:
+    typedef Core路Status (*螢(Map路fn ,CVT_read ,CVT_write))(
+      CVT_read *read_value
+      ,CVT_write *write_value
+    );
 
-    Local Core路Map路Fn Core路Map路ReadHex路write_available(){
-      CVT **r = &Core路tf.copy.read_pt;
-      CVT *r1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.read);
-      CVT **w = &Core路tf.copy.write_pt;
-      CVT *w1 = Core路TM_NX_##CVT路position_right(Core路tf.copy.write);
+    typedef struct {
+      // Map a function over all elements from read_tm to write_tm
+      Map路Completion (*map)(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+      );
 
-      do {
-        **w = Core路hex_to_byte(*(uint16_t *)*r);
-        if(*w == w1) break;
-        (*r) += 2;
-        (*w)++;
-      } while(true);
+      // Map a function over elements from read_tm to write_tm until a condition is met
+      Map路Completion (*map_while)(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+        ,bool (*condition)(螢(TM路Array ,CVT_read) *read_tm)
+      );
 
-      Core路tf.copy.status = Core路Map路Status路write_available;
-      return NULL;
-    }
+      // Map a function over n elements from read_tm to write_tm
+      Map路Completion (*map_extent)(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+        ,螢(extent_t ,CVT_read) extent
+      );
 
+    } 螢(Map路FG ,CVT_read ,CVT_write);
 
+    // Default function given table
+    螢(Map路FG ,CVT_read ,CVT_write) 螢(Map路fg ,CVT_read ,CVT_write);
 
-  #endif // LOCAL
+  #endif
 
-#endif // IMPLEMENTATION
+#endif // #ifndef Map路FACE
diff --git a/developer/cc馃枆/Map2.lib.c b/developer/cc馃枆/Map2.lib.c
new file mode 100644 (file)
index 0000000..931c0c2
--- /dev/null
@@ -0,0 +1,500 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Map - mapping functions between tape machines.
+
+   This file has two template parameters:
+   `CVT_read`  Cell Value Type for the source/read tape machine
+   `CVT_write` Cell Value Type for the destination/write tape machine
+
+   By default (when the macros have no definition) the cell value types are taken as AU.
+   This file must be included with CVT_read and CVT_write undefined, before inclusions with them defined.
+
+   'Tape' is operated on by the Tape Machine.
+   'Area' is subset of an address space that is used as a virtual Tape by a machine.
+   An Area with zero elements has 'length == 0' or is 'empty'.
+   In contrast, and area located (position specified) with a null pointer is said not to exist.
+*/
+
+#define Map路DEBUG
+
+#ifndef FACE
+  #define Map路IMPLEMENTATION
+  #define FACE
+#endif
+
+//--------------------------------------------------------------------------------
+// Interface
+
+#ifndef Map路FACE
+  #define Map路FACE
+
+  #include <stdint.h>
+  #include <stddef.h>
+  #include "Core.lib.c"
+  #include "TM.lib.c"
+
+  // if only one template parameter is given, we will assume both are the same
+
+  #if defined(CVT_read) && !defined(CVT_write)
+    #warning "Given CVT_read template value. Missing CVT_write template value, so setting it to CVT_read"
+    #define CVT_write CVT_read
+  #endif
+
+  #if !defined(CVT_read) && defined(CVT_write)
+    #warning "Given CVT_write template value. Missing CVT_read template value, so setting it to CVT_write"
+    #define CVT_read CVT_write
+  #endif
+
+  //----------------------------------------
+  // Map status and completion enums
+  //----------------------------------------
+
+  #if !defined(CVT_read) && !defined(CVT_write)
+
+    typedef enum {
+       Map路Completion路mu = 0
+      ,Map路Completion路failed          = 1
+      ,Map路Completion路null_fn         = 1 << 1
+      ,Map路Completion路no_tape_access  = 1 << 2
+      ,Map路Completion路rightmost_read  = 1 << 3 
+      ,Map路Completion路rightmost_write = 1 << 4 
+    } Map路Completion;
+
+    // Masks for combinations
+    const uint Map路Completion路rightmost_both =
+        Map路Completion路rightmost_read
+      | Map路Completion路rightmost_write
+      ;
+
+    const uint Map路Completion路derailed =
+        Map路Completion路failed
+      | Map路Completion路null_fn
+      | Map路Completion路no_tape_access
+      ;
+
+    const uint Map路Completion路on_track =
+        Map路Completion路rightmost_read
+      | Map路Completion路rightmost_write
+      | Map路Completion路rightmost_both
+      ;
+
+  #endif
+
+  //----------------------------------------
+  // Map interface
+  //----------------------------------------
+
+  #if !defined(CVT_read) || !defined(CVT_write)
+    typedef struct {
+      Map路Completion (*copy_byte_to_byte)(
+        螢(TM路Array ,AU) *read_tm
+        ,螢(TM路Array ,AU) *write_tm
+      );
+
+      Map路Completion (*copy_hex_to_byte)(
+        螢(TM路Array ,uint16_t) *read_tm
+        ,螢(TM路Array ,AU) *write_tm
+      );
+
+      Map路Completion (*copy_byte_to_hex)(
+        螢(TM路Array ,AU) *read_tm
+        ,螢(TM路Array ,uint16_t) *write_tm
+      );
+
+      // Terminate string function
+      Map路Completion (*terminate_string)(
+        螢(TM路Array ,AU) *write_tm
+      );
+    }
+  #endif
+
+
+  #if defined(CVT_read) && defined(CVT_write)
+
+    // Function passed to map type signature must be this:
+    typedef Core路Status (*螢(Map路fn ,CVT_read ,CVT_write))(
+      CVT_read *read_value
+      ,CVT_write *write_value
+    );
+
+    typedef struct {
+      // Map a function over all elements from read_tm to write_tm
+      Map路Completion (*map)(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+      );
+
+      // Map a function over elements from read_tm to write_tm until a condition is met
+      Map路Completion (*map_while)(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+        ,bool (*condition)(螢(TM路Array ,CVT_read) *read_tm)
+      );
+
+      // Map a function over n elements from read_tm to write_tm
+      Map路Completion (*map_extent)(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+        ,螢(extent_t ,CVT_read) extent
+      );
+
+    } 螢(Map路FG ,CVT_read ,CVT_write);
+
+    // Default function given table
+    螢(Map路FG ,CVT_read ,CVT_write) 螢(Map路fg ,CVT_read ,CVT_write);
+  #endif // !defined(CVT_read) && !defined(CVT_write)
+
+#endif // #ifndef Map路FACE
+
+//--------------------------------------------------------------------------------
+// Implementation
+
+#ifdef Map路IMPLEMENTATION
+
+  // declarations available to all of the IMPLEMENTATION go here
+  #ifdef Map路DEBUG
+    #include <stdio.h>
+  #endif
+
+  // implementation to go into the lib.a file
+  #ifndef LOCAL
+  #endif
+
+  #ifdef LOCAL
+    //----------------------------------------
+    // Map implementation
+    //----------------------------------------
+
+    #if !defined(CVT_read) && !defined(CVT_write)
+      //-----------------------------------
+      // common error messages
+      const char *Map路Msg路read_tm = "given NULL read_tm";
+      const char *Map路Msg路write_tm = "given NULL write_tm";
+      const char *Map路Msg路map_fn = "given NULL map_fn";
+      const char *Map路Msg路condition = "given NULL condition function";
+
+      //-----------------------------------
+      // Helper functions for copy operations
+      
+      // Byte to byte copy function
+      Local Core路Status Map路byte_to_byte_fn(AU *read_value, AU *write_value) {
+        *write_value = *read_value;
+        return Core路Status路on_track;
+      }
+      
+      // Hex to byte conversion function
+      Local Core路Status Map路hex_to_byte_fn(uint16_t *read_value, AU *write_value) {
+        // Convert hex value to byte
+        *write_value = (AU)(*read_value & 0xFF);
+        return Core路Status路on_track;
+      }
+      
+      // Byte to hex conversion function
+      Local Core路Status Map路byte_to_hex_fn(AU *read_value, uint16_t *write_value) {
+        // Convert byte to lowercase hex representation (no prefix)
+        static const char hex_chars[] = "0123456789abcdef";
+        *write_value = hex_chars[(*read_value >> 4) & 0x0F];
+        return Core路Status路on_track;
+      }
+    #endif // !defined(CVT_read) && !defined(CVT_write)
+
+    #if defined(CVT_read) && defined(CVT_write)
+      //-----------------------------------
+      // Map implementation with specific types
+
+      // Map a function over all elements from read_tm to write_tm
+      Local Core路Status 螢(Map ,CVT_read ,CVT_write)路map(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+      ){
+        #ifdef Map路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,read_tm ,Map路Msg路read_tm);
+          Core路Guard路fg.check(&chk ,1 ,write_tm ,Map路Msg路write_tm);
+          Core路Guard路fg.check(&chk ,1 ,map_fn ,Map路Msg路map_fn);
+          Core路Guard路if_return(chk);
+        #endif
+
+        // Rewind both tape machines to ensure we start at the beginning
+        螢(TM路Array ,CVT_read)路fg.rewind(read_tm);
+        螢(TM路Array ,CVT_write)路fg.rewind(write_tm);
+
+        // Initial check if can_read (not part of the loop)
+        if(!螢(TM路Array ,CVT_read)路fg.can_read(read_tm)) return Core路Status路on_track;
+
+        // Track completion status
+        uint completion = 0;
+
+        // Following the first-rest pattern described in TTCA
+        while(1){
+          // Read value from source
+          CVT_read read_value;
+          螢(TM路Array ,CVT_read)路fg.read(read_tm ,&read_value);
+
+          // Apply mapping function to get write value
+          CVT_write write_value;
+          Core路Status status = map_fn(&read_value ,&write_value);
+          if(status != Core路gStatus路on_track) {
+            completion |= Core路Map路Completion路failed;
+            return status;
+          }
+
+          // Write result to destination
+          螢(TM路Array ,CVT_write)路fg.write(write_tm ,&write_value);
+
+          // Check if we're at the rightmost position for read
+          bool read_rightmost = 螢(TM路Array ,CVT_read)路fg.on_rightmost(read_tm);
+          if(read_rightmost) {
+            completion |= Core路Map路Completion路rightmost_read;
+          }
+
+          // Check if we're at the rightmost position for write
+          bool write_rightmost = 螢(TM路Array ,CVT_write)路fg.on_rightmost(write_tm);
+          if(write_rightmost) {
+            completion |= Core路Map路Completion路rightmost_write;
+          }
+
+          // Break if either machine is at rightmost
+          if(read_rightmost || write_rightmost) break;
+
+          // Step both machines
+          螢(TM路Array ,CVT_read)路fg.step(read_tm);
+          螢(TM路Array ,CVT_write)路fg.step(write_tm);
+        }
+
+        return Core路Status路on_track;
+      }
+
+      // Map a function over elements from read_tm to write_tm until a condition is met
+      Local Core路Status 螢(Map ,CVT_read ,CVT_write)路map_while(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+        ,bool (*condition)(CVT_read *value)
+      ){
+        #ifdef Map路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,read_tm ,Map路Msg路read_tm);
+          Core路Guard路fg.check(&chk ,1 ,write_tm ,Map路Msg路write_tm);
+          Core路Guard路fg.check(&chk ,1 ,map_fn ,Map路Msg路map_fn);
+          Core路Guard路fg.check(&chk ,1 ,condition ,Map路Msg路condition);
+          Core路Guard路if_return(chk);
+        #endif
+
+        // Rewind both tape machines to ensure we start at the beginning
+        螢(TM路Array ,CVT_read)路fg.rewind(read_tm);
+        螢(TM路Array ,CVT_write)路fg.rewind(write_tm);
+
+        // Initial check if can_read (not part of the loop)
+        if(!螢(TM路Array ,CVT_read)路fg.can_read(read_tm)) return Core路Status路on_track;
+
+        // Track completion status
+        uint completion = 0;
+
+        // Following the first-rest pattern described in TTCA
+        while(1){
+          // Read value from source
+          CVT_read read_value;
+          螢(TM路Array ,CVT_read)路fg.read(read_tm ,&read_value);
+
+          // Check condition
+          if(!condition(&read_value)) break;
+
+          // Apply mapping function to get write value
+          CVT_write write_value;
+          Core路Status status = map_fn(&read_value ,&write_value);
+          if(status != Core路Status路on_track) {
+            completion |= Core路Map路Completion路failed;
+            return status;
+          }
+
+          // Write result to destination
+          螢(TM路Array ,CVT_write)路fg.write(write_tm ,&write_value);
+
+          // Check if we're at the rightmost position for read
+          bool read_rightmost = 螢(TM路Array ,CVT_read)路fg.on_rightmost(read_tm);
+          if(read_rightmost) {
+            completion |= Core路Map路Completion路rightmost_read;
+          }
+
+          // Check if we're at the rightmost position for write
+          bool write_rightmost = 螢(TM路Array ,CVT_write)路fg.on_rightmost(write_tm);
+          if(write_rightmost) {
+            completion |= Core路Map路Completion路rightmost_write;
+          }
+
+          // Break if either machine is at rightmost
+          if(read_rightmost || write_rightmost) break;
+
+          // Step both machines
+          螢(TM路Array ,CVT_read)路fg.step(read_tm);
+          螢(TM路Array ,CVT_write)路fg.step(write_tm);
+        }
+
+        return Core路Status路on_track;
+      }
+
+      // Map a function over n elements from read_tm to write_tm
+      Local Core路Status 螢(Map ,CVT_read ,CVT_write)路map_n(
+        螢(TM路Array ,CVT_read) *read_tm
+        ,螢(TM路Array ,CVT_write) *write_tm
+        ,螢(Map路fn ,CVT_read ,CVT_write) map_fn
+        ,size_t n
+      ){
+        #ifdef Map路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,read_tm ,Map路Msg路read_tm);
+          Core路Guard路fg.check(&chk ,1 ,write_tm ,Map路Msg路write_tm);
+          Core路Guard路fg.check(&chk ,1 ,map_fn ,Map路Msg路map_fn);
+          Core路Guard路if_return(chk);
+        #endif
+
+        // Rewind both tape machines to ensure we start at the beginning
+        螢(TM路Array ,CVT_read)路fg.rewind(read_tm);
+        螢(TM路Array ,CVT_write)路fg.rewind(write_tm);
+
+        // Initial check if can_read (not part of the loop)
+        if(!螢(TM路Array ,CVT_read)路fg.can_read(read_tm)) return Core路Status路on_track;
+        
+        // Track completion status
+        uint completion = 0;
+        
+        // Following the first-rest pattern described in TTCA
+        size_t count = 0;
+        while(count < n){
+          // Read value from source
+          CVT_read read_value;
+          螢(TM路Array ,CVT_read)路fg.read(read_tm ,&read_value);
+
+          // Apply mapping function to get write value
+          CVT_write write_value;
+          Core路Status status = map_fn(&read_value ,&write_value);
+          if(status != Core路Status路on_track) {
+            completion |= Core路Map路Completion路failed;
+            return status;
+          }
+
+          // Write result to destination
+          螢(TM路Array ,CVT_write)路fg.write(write_tm ,&write_value);
+
+          // Increment count
+          count++;
+
+          // Check if we're at the rightmost position for read
+          bool read_rightmost = 螢(TM路Array ,CVT_read)路fg.on_rightmost(read_tm);
+          if(read_rightmost) {
+            completion |= Core路Map路Completion路rightmost_read;
+          }
+
+          // Check if we're at the rightmost position for write
+          bool write_rightmost = 螢(TM路Array ,CVT_write)路fg.on_rightmost(write_tm);
+          if(write_rightmost) {
+            completion |= Core路Map路Completion路rightmost_write;
+          }
+
+          // Break if either machine is at rightmost
+          if(read_rightmost || write_rightmost) break;
+
+          // Step both machines
+          螢(TM路Array ,CVT_read)路fg.step(read_tm);
+          螢(TM路Array ,CVT_write)路fg.step(write_tm);
+        }
+
+        return Core路Status路on_track;
+      }
+
+      // Initialize the function given table
+      螢(Map路FG ,CVT_read ,CVT_write) 螢(Map路fg ,CVT_read ,CVT_write) = {
+        .map = 螢(Map ,CVT_read ,CVT_write)路map
+        ,.map_while = 螢(Map ,CVT_read ,CVT_write)路map_while
+        ,.map_n = 螢(Map ,CVT_read ,CVT_write)路map_n
+      };
+    #endif // defined(CVT_read) && defined(CVT_write)
+
+    //----------------------------------------
+    // Copy functions implementation
+    //----------------------------------------
+
+    // Byte to byte copy
+    Local Core路Status Map路copy_byte_to_byte(
+      螢(TM路Array ,AU) *read_tm
+      ,螢(TM路Array ,AU) *write_tm
+    ){
+      #ifdef Map路DEBUG
+        Core路Guard路init_count(chk);
+        Core路Guard路fg.check(&chk ,1 ,read_tm ,Map路Msg路read_tm);
+        Core路Guard路fg.check(&chk ,1 ,write_tm ,Map路Msg路write_tm);
+        Core路Guard路if_return(chk);
+      #endif
+
+      return 螢(Map ,AU ,AU)路fg.map(read_tm, write_tm, Map路byte_to_byte_fn);
+    }
+
+    // Hex to byte copy
+    Local Core路Status Map路copy_hex_to_byte(
+      螢(TM路Array ,uint16_t) *read_tm
+      ,螢(TM路Array ,AU) *write_tm
+    ){
+      #ifdef Map路DEBUG
+        Core路Guard路init_count(chk);
+        Core路Guard路fg.check(&chk ,1 ,read_tm ,Map路Msg路read_tm);
+        Core路Guard路fg.check(&chk ,1 ,write_tm ,Map路Msg路write_tm);
+        Core路Guard路if_return(chk);
+      #endif
+
+      return <response clipped><NOTE>To save on context only part of this file has been shown to you. You should retry this tool after you have searched inside the file with `grep -n` in order to find the line numbers of what you are looking for.</NOTE>
index 947bbed..9936426 100644 (file)
@@ -13,6 +13,8 @@
    An Area with zero elements has 'length == 0' or is 'empty'. In contrast ,and
    area located (position specified) with a null pointer is said not to exist.
 
+   Template variable: CVT
+
 */
 
 #define TM路DEBUG
 #define FACE
 #endif 
 
+#if defined(Array) && !defined(CVT)
+  #error "Array implementation requires CVT to be defined"
+#endif
+
+
 //--------------------------------------------------------------------------------
 // Interface
 
-#ifndef TM路FACE
-#define TM路FACE
+#ifndef 螢(TM路FACE ,CVT)
+#define 螢(TM路FACE ,CVT)
 
   #include <stdint.h>
   #include <stddef.h>
       | TM路Head路Status路interim
       | TM路Head路Status路rightmost
       ;
-  #endif // #ifndef CVT
 
-  #ifndef CVT
-    typedef struct 螢(TM路Array ,CVT);
+    typedef struct TM;
 
     // tape and area are included with Tape Machine to facilitate abstract interfaces.
     typedef struct{
 
       struct {
-        Core路Status      (*topo)  ( 螢(TM路Array ,CVT) *tm ,TM路Tape路Topo *result );
-        螢(extent_t ,CVT) (*extent)( 螢(TM路Array ,CVT) *tm );
+        Core路Status      (*topo)  ( TM *tm ,TM路Tape路Topo *result );
+        螢(extent_t ,CVT) (*extent)( TM *tm );
       } tape;
 
       struct {
         // Initialize tm
-        Core路Status (*mount_pe)(螢(TM路Array ,CVT) *tm ,CVT position[] ,螢(extent_t ,CVT) extent);
-        Core路Status (*mount_pp)(螢(TM路Array ,CVT) *tm ,CVT *position_left ,CVT *position_right);
+        Core路Status (*mount_pe)(TM *tm ,CVT position[] ,螢(extent_t ,CVT) extent);
+        Core路Status (*mount_pp)(TM *tm ,CVT *position_left ,CVT *position_right);
       } area;
 
       // tape machine functions
-      Core路Status (*mount)   (螢(TM路Array ,CVT) *tm);
-      Core路Status (*dismount)(螢(TM路Array ,CVT) *tm);
+      Core路Status (*mount)   (TM *tm);
+      Core路Status (*dismount)(TM *tm);
 
-      TM路Head路Status (*status)        (螢(TM路Array ,CVT) *tm ,TM路Head路Status *status);
-      Core路Status    (*head_on_format)(螢(TM路Array ,CVT) *tm ,bool *flag);
+      TM路Head路Status (*status)        (TM *tm ,TM路Head路Status *status);
+      Core路Status    (*head_on_format)(TM *tm ,bool *flag);
 
-      bool (*can_read)    (螢(TM路Array ,CVT) *tm);
-      bool (*on_origin)   (螢(TM路Array ,CVT) *tm);
-      bool (*on_rightmost)(螢(TM路Array ,CVT) *tm);
+      bool (*can_read)    (TM *tm);
+      bool (*on_leftmost) (TM *tm);
+      bool (*on_rightmost)(TM *tm);
 
-      void (*step)      (螢(TM路Array ,CVT) *tm);
-      void (*step_left) (螢(TM路Array ,CVT) *tm);
-      void (*step_right)(螢(TM路Array ,CVT) *tm); // Synonym for step
-      void (*rewind)    (螢(TM路Array ,CVT) *tm);
+      void (*step)      (TM *tm);
+      void (*step_left) (TM *tm);
+      void (*step_right)(TM *tm); // Synonym for step
+      void (*rewind)    (TM *tm);
 
-      void (*copy_datum)( 螢(TM路Array ,CVT) *tm_read ,螢(TM路Array ,CVT) *tm_write );
-      void (*read)      ( 螢(TM路Array ,CVT) *tm ,CVT *remote_pt );
-      void (*write)     ( 螢(TM路Array ,CVT) *tm ,CVT *remote_pt );
+      void (*copy_datum)( TM *tm_read ,TM *tm_write );
+      void (*apply)( TM *tm_read , TM路FN);
 
-    } 螢(TM路Array ,CVT)路FG;
+    } TM路FG;
 
-    螢(TM路Array ,CVT)路FG 螢(TM路Array ,CVT)路fg;
+
+  #endif // #ifndef CVT
+
+  #ifdef CVT
+
+
+    typedef struct{
+
+      void (*read)      ( TM *tm ,CVT *remote_pt );
+      void (*write)     ( TM *tm ,CVT *remote_pt );
+
+    } 螢(TM ,CVT);
+
+    // default table for TM implemented by an Array
+    #ifdef Array
+      螢(TM ,CVT)路FG 螢(TM路Array ,CVT)路fg;
+    #endif
 
   #endif // #ifdef CVT
 
 
   #ifdef LOCAL
 
+    //----------------------------------------
+    // Dispatch wrapper
+    //----------------------------------------
+
+    #ifndef CVT
+
+      //-----------------------------------
+      // common error messages
+
+      const char *TM路Array路Msg路tm="given NULL tm";
+      const char *TM路Array路Msg路flag="given NULL flag pointer";
+      const char *TM路Array路Msg路result="given NULL result pointer";
+      const char *TM路Array路Msg路position=
+        "Null position.This is only possible when the tape machine has not been initialized.";
+
+    #endif // #ifndef CVT
+
+    #ifdef CVT
+
+      struct{
+        螢(TM ,CVT)路FG *fg
+      }螢(TM ,CVT);
+
+      //-----------------------------------
+      // TM路Array.tape implementation
+
+      /*
+        For an Array Tape Machine ,a bound tape will be singleton or segment.
+        An initialized Array Tape Machine always has a bound tape.
+      */
+      Core路Status 螢(TM ,CVT)路topo(螢(TM路Array ,CVT) *tm ,TM路Tape路Topo *result){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
+          Core路Guard路fg.check(&chk ,1 ,result ,TM路Array路Msg路result);
+          Core路Guard路if_return(chk);
+        #endif
+        if(tm->extent == 0){
+          *result = TM路Tape路Topo路singleton; 
+        }else{
+          *result = TM路Tape路Topo路segment;
+        }
+        return Core路Status路on_track;
+      }
+
+      // check the topo to make sure tape has extent before calling this
+      // `extent路CVT` returns the index to the rightmost cell in the array.
+      Local  螢(extent_t ,CVT) 螢(TM路Array ,CVT)路extent(螢(TM路Array ,CVT) *tm){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Tape路Topo topo = Core路Tape路Topo路mu;
+          Core路Status status = 螢(TM路Array ,CVT)路topo(tm ,&topo);
+          bool good_topo = 
+            (status == Core路Status路on_track) && (topo & Core路Tape路Topo路finite_nz)
+            ;
+          Core路Guard路fg.check(&chk ,1 ,good_topo ,"Tape does not have an extent.");
+          Core路Guard路assert(chk);
+        #endif
+
+        *result = tm->extent;
+        return Core路Status路on_track;
+      }
+
+      //-----------------------------------
+      // TM路Array.area implementation 
+
+      Local Core路Status 螢(TM路Array ,CVT)路mount_pe(
+        螢(TM路Array ,CVT) *tm ,CVT *position ,螢(extent_t ,CVT) extent
+      ){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
+          Core路Guard路fg.check(&chk ,1 ,position ,"Given NULL position.");
+          Core路Guard路if_return(chk);
+        #endif
+        tm->position = position;
+        tm->extent = extent;
+        tm->hd = position; // mount the head on the origin cell
+        return Core路Status路on_track;
+      }
+
+      // If size of CVT is not a power of two this can perform a divide
+      Local Core路Status 螢(TM路Array ,CVT)路mount_pp(
+        螢(TM路Array ,CVT) *tm ,CVT *pos_leftmost ,CVT *pos_rightmost
+      ){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,pos_leftmost  ,"Null pos_leftmost.");
+          Core路Guard路fg.check(&chk ,1 ,pos_rightmost ,"Null pos_rightmost.");
+          if(pos_leftmost && pos_rightmost){
+            Core路Guard路fg.check(&chk ,1 ,pos_rightmost >= pos_leftmost 
+              ,"pos_rightmost < pos_leftmost"
+            );
+          }
+          Core路Guard路if_return(chk);
+        #endif
+
+        螢(extent_t ,CVT) extent = pos_rightmost - pos_leftmost);
+        return 螢(TM路Array ,CVT)路mount_pe(tm ,pos_leftmost ,extent);
+      }
+
+      //-----------------------------------
+      // base Tape Machine operations
+
+      Local Core路Status 螢(TM路Array ,CVT)路mount(螢(TM路Array ,CVT) *tm){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
+          if(tm) Core路Guard路fg.check(&chk ,1 ,tm->position ,TM路Array路Msg路position);
+          Core路Guard路if_return(chk);
+        #endif
+
+        // mounting an already mounted head does nothing ,perhaps you meant `rewind`?
+        if(!tm->hd) tm->hd = tm->position;
+        return Core路Status路on_track;
+      }
+
+      Local Core路Status 螢(TM路Array ,CVT)路dismount(螢(TM路Array ,CVT) *tm){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
+          Core路Guard路if_return(chk);
+        #endif
+
+        tm->hd = NULL;
+        return Core路Status路on_track;
+      }
+
+      Local TM路Head路Status 螢(TM路Array ,CVT)路status(
+        螢(TM路Array ,CVT) *tm ,TM路Head路Status *status
+      ){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
+          Core路Guard路fg.check(&chk ,1 ,status ,"given NULL status pointer");
+          Core路Guard路if_return(chk);
+        #endif
+
+        if(tm->hd == NULL){
+          *status = TM路Head路Status路not_on_tape;
+        }else if(tm->hd == tm->position){
+          *status = TM路Head路Status路origin;
+        }else if(tm->hd == tm->position + tm->extent){
+          *status = TM路Head路Status路rightmost;
+        }else{
+          *status = TM路Head路Status路interim;
+        }
+
+        return Core路Status路on_track;
+      }
+
+     // Stronger than `can_read`. Used mostly for debugging.
+     // as it checks for a legal head position.
+      Local Core路Status 螢(TM路Array ,CVT)路head_on_format(
+        螢(TM路Array ,CVT) *tm ,bool *flag
+      ){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
+          if(tm) Core路Guard路fg.check(&chk ,1 ,tm->position ,TM路Array路Msg路position);
+          Core路Guard路fg.check(&chk ,1 ,flag ,TM路Array路Msg路flag);
+          Core路Guard路if_return(chk);
+        #endif
+
+        *flag = 
+             tm->hd
+          && tm->hd >= tm->position
+          && tm->hd - tm->position <= tm->extent
+          && ( (AU *)tm->hd - (AU *)tm->position ) % sizeof(CVT) == 0 // '%' expensive
+          ;
+        return Core路Status路on_track;
+      }
+
+      bool 螢(TM路Array ,CVT)路can_read(螢(TM路Array ,CVT) *tm){
+        return tm && tm->position && tm->hd;
+      }
+
+      // can_read was true
+      bool 螢(TM路Array ,CVT)路on_origin(螢(TM路Array ,CVT) *tm){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          bool flag = true ,s;
+          s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
+          Core路Guard路assert(chk);
+        #endif
+        return tm->hd == tm->position;
+      }
+
+      // can_read was true
+      bool 螢(TM路Array ,CVT)路on_rightmost(螢(TM路Array ,CVT) *tm){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          bool flag = true ,s;
+          s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
+          Core路Guard路assert(chk);
+        #endif
+        return tm->hd == tm->position;
+      }
+
+      void 螢(TM路Array ,CVT)路step(螢(TM路Array ,CVT) *tm){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          bool flag = true ,s;
+          s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
+          Core路Guard路assert(chk);
+        #endif
+        tm->hd++;
+      }
+
+      void 螢(TM路Array ,CVT)路step_left(螢(TM路Array ,CVT) *tm){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          bool flag = true ,s;
+          s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
+          Core路Guard路assert(chk);
+        #endif
+        tm->hd--;
+      }
+
+      void 螢(TM路Array ,CVT)路rewind(螢(TM路Array ,CVT) *tm){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          bool flag = true ,s;
+          s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
+          Core路Guard路assert(chk);
+        #endif
+        tm->hd = tm->position;
+      }
+
+      // tm_can_read must be true for both machines.
+      void 螢(TM路Array ,CVT)路copy_datum(螢(TM路Array ,CVT) *tm_read ,螢(TM路Array ,CVT) *tm_write){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          bool flag = true ,s;
+          s = 螢(TM路Array ,CVT)路head_on_format(tm_read ,flag) == Control路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"tm_read head off track");
+          s = 螢(TM路Array ,CVT)路head_on_format(tm_write ,flag) == Control路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"tm_write head off track");
+          Core路Guard路assert(chk);
+        #endif
+
+        *(tm_write->hd) = *(tm_read->hd);
+        return Core路Status路on_track;
+      }
+
+      void 螢(TM路Array ,CVT)路read(螢(TM路Array ,CVT) *tm ,CVT *read_pt){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          bool flag = true ,s;
+          s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
+          Core路Guard路assert(chk);
+        #endif
+
+        *read_pt = *(tm->hd);
+      }
+
+      void 螢(TM路Array ,CVT)路write(螢(TM路Array ,CVT) *tm ,CVT *write_pt){
+        #ifdef TM路DEBUG
+          Core路Guard路init_count(chk);
+          bool flag = true ,s;
+          s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+          Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
+          Core路Guard路assert(chk);
+        #endif
+
+        *(tm->hd) = *write_pt;
+      }
+
+      // step_right is a synonym for step
+
+
+      //----------------------------------------
+      // Initialization for 螢(TM路Array ,CVT)路fg
+
+      Local 螢(TM路Array ,CVT)路FG 螢(TM路Array ,CVT)路fg = {
+        .tape = {
+           .topo   = 螢(TM路Array ,CVT)路topo
+           .extent = 螢(TM路Array ,CVT)路extent
+        }
+
+        ,.area = {
+           .mount_pe = 螢(TM路Array ,CVT)路mount_pe
+          ,.mount_pp = 螢(TM路Array ,CVT)路mount_pp
+        }
+
+        ,.mount    = 螢(TM路Array ,CVT)路mount
+        ,.dismount = 螢(TM路Array ,CVT)路dismount
+
+        ,.status         = 螢(TM路Array ,CVT)路status
+        ,.head_on_format = 螢(TM路Array ,CVT)路head_on_format
+
+        ,.can_read     = 螢(TM路Array ,CVT)路can_read
+        ,.on_origin    = 螢(TM路Array ,CVT)路on_origin
+        ,.on_rightmost = 螢(TM路Array ,CVT)路on_rightmost
+
+        ,.step = 螢(TM路Array ,CVT)路step
+        ,.step_left = 螢(TM路Array ,CVT)路step_left
+        ,.step_right = 螢(TM路Array ,CVT)路step_right // Synonym for step
+        ,.rewind = 螢(TM路Array ,CVT)路rewind
+
+        ,.copy_datum = 螢(TM路Array ,CVT)路copy_datum
+        ,.read = 螢(TM路Array ,CVT)路read
+        ,.write = 螢(TM路Array ,CVT)路write
+
+      };
+
+    #endif // ifdef CVT
+
+
     //----------------------------------------
     // TM路Array implementation
     //----------------------------------------
     /*
       TM路Array is bound to a tape with head on the tape via mount_pe or mount_pp.  
 
-      Once a tape is bound ,it remains so ,though the head can be dismounted
+      Once a tape is bound, it remains so, though the head can be dismounted
       and remounted.
 
-      C lacks an allocation-bound initialization feature ,so the library user is responsible
+      C lacks an allocation-bound initialization featureso the library user is responsible
       to make sure a TM路Array has been initialized before use.
 
-      The TM路Array has no locking facility ,so it is not possible to know if it is in use.
+      The TM路Array has no locking facilityso it is not possible to know if it is in use.
 
       Re-initializing a TM路Array while in use can lead to unspecified badness. Use `rewind` instead.
     */
diff --git a/developer/cc馃枆/xi.c b/developer/cc馃枆/xi.c
new file mode 100644 (file)
index 0000000..ae2b85c
--- /dev/null
@@ -0,0 +1,66 @@
+/* Xi (螢) macro implementation with variable argument support
+ *
+ * This file provides macros from 螢0 through 螢10 along with a selector
+ * that automatically chooses the right macro based on argument count.
+ *
+ * Usage:
+ *   螢(a)                 -> a
+ *   螢(a ,b)              -> a路b
+ *   螢(a ,b ,c)           -> a路b路c
+ *   ...
+ *   螢(a ,b ,c ,d ,e ,f) -> a路b路c路d路e路f
+ *
+ * For Map with two template parameters:
+ *   螢(Map ,CVT_read ,CVT_write) -> Map路CVT_read路CVT_write
+ */
+
+#ifndef XI_C
+#define XI_C
+
+// 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__)
+
+#endif /* XI_C */
index aa9ee34..c77db25 100644 (file)
@@ -1,13 +1,28 @@
 
+*recovering alignment of pointers that point to array cells (elements)
 
 Interesting observation, recovering alignment for a pointer into an array is expensive.  It requires modulus against the element size to find how far off the pointer is.
 
+*converving alignment
+
 If one starts aligned, say on zero, then only increments by the element size, alignment is not ever lost.  However, if an element pointer is computed by a imprecise process, and rounding is recovered to get it back again, then the modulus is required.
 
+*power of radix boundaries
+
 However, modulus is not hard on powers of the radix boundaries. 
 
 So either a) in the first place make elements a power of the radix in size, perhaps even using padding,  b)  change the radix of the number system so the native element size if the radix, or a power there of  c) never do a computation that loses alignment.
 
 As a consequence it is expensive to compute the extent of an object with arbitrary CVT (Cell Value Type).  Given the two bounding pointers, one must subtract and divide by the sizeof(CVT) to recover the extent, and divide is expensive. In contrast when given the position and extent, the address of the rightmost cell can be recovered with an addition. 
 
+*store base and extent, rather than two pointers
+
 It follows that if the extent is needed that it makes more sense to store the position and extent for an interval than it does to store two bounding pointers.
+
+*unaligned bound
+
+`on_rightmost` is a precise predicate. If the head pointer were advanced by a value other than sizeof(CVT) then it could step right over the base pointer to the rightmost cell.  If this was part of looping, the loop would continue.
+
+A situation where this could happen, suppose we want to copy a block of memory.  We walk AU by AU (byte by byte)  up to an aligned on AU8 address.  Then we copy AU8 by AU8.  Here is the problem, the actual data being copied ends on an AU pointer boundary, not an AU8 pointer boundary.  It is not difficult to round down to an AU8 because 8 is a power of two. This round down is required, to the point of the last full AU8 that can be copied, to stop the AU8 copy. This is not a problem for AU8 because 8 is a power of two.  
+
+However, if the increment were by the size of CVT,  and the boundary was given given by an AU pointer, then rounding down requires a modulus operation to know where the last CVT fits in.  It is not clear what use case exists for this.
diff --git a/developer/document馃枆/generalizing_type.org b/developer/document馃枆/generalizing_type.org
new file mode 100644 (file)
index 0000000..73bba86
--- /dev/null
@@ -0,0 +1,109 @@
+* Generalizing type
+
+** Passing an TM FG table instance
+
+1. Suppose we have a generic TM FG table with the declared functions constituting the architecture (user's view, interface) of a tape machine.
+
+2. Instances of this TM FG table to represent different implementations of the architecture. Say TM路Array路fg for a TM implemented as an array, and TM路Function路fg for a function implementation (for example the Natural_Number in the Java implementation).
+
+3. Now suppose we have a function `map` that is given a TM_read, a TM_write, and a function.
+   The map does not care how the TM is implemented.
+
+   If these first two arguments are declared as TM FG type, then they can accept any fg table whether it be an Array implementation, a Function implementation, etc. The map can then pick the functions it needs, such as step, and rightmost, from the
+   table, and thus get tape behavior. 
+
+   This achieves what we wanted, a map function that can use a tape machine and does not care what the implementation of that tape machine is.
+
+   However, the TM functions that map calls require to be given a first argument of that holds the TM instance data. Without this it can not know which machine is being operated on.
+   Furthermore, the instance data type must match the TM fg table type.
+
+   Given steps 1 through 3 we never passed in instance data to map, only a TM FG table insance. So map has a type, but not the data.
+
+   
+** Passing TM instance data, compile in the fg table.
+
+1. As noted, `map` is given a TM_read, a TM_write, and a function. For these first two
+   arguments, suppose we pass in the instance data, i.e. struct pointers.
+
+2. The TM路Array struct will hold a base pointer to the array, and the head location.  The TM路Function struct would hold a handle recognized by the functions, or some state used by them.
+
+3. Then we have a map function for each architecture type, and we compile into each of these a call to the correct default TM路fg table.  The map路Array will have compiled into it, TM路Array路fg, and the map路Function will have compiled into it TM路Function路fg etc.
+
+4. This approach works, but we duplicate the map code many times just to get the types to match the calls.
+   
+
+** Passing in both, the TM instance data, and corresponding TM FG tables instances.
+
+1. Say we have one generic `map` that given 5 arguments: TM_read (an instance), TM_read_fg, a TM_write (an instance), and TM_write_fg.
+
+2. The instance parameters must be declared `void *` to prevent argument checking on them, otherwise it will be necessary to implement many map functions for each instance type combination.
+
+3. This works, though we have no way to know if the correct type of instance data, that matches the fg table, was actually passed in.
+
+4. We could create many wrapper functions to accomplish the instance data type check, then to call a central map function with `void *` instance data pointers. With any luck the optimizer would make this extra layer go away, so it will be efficient.  Still map now has 5 arguments instead the three that are natural for the problem.
+
+
+** Using a "vtable"
+
+1. All TM instance types are structs with a first field that points to the fg table,
+   no matter the implementation type. This is not a serious requirement because
+   each implementation type already has an struct for its implementation data. However it does make an instance bigger, and it is not clear that the optimizer will be able to
+   discombobulation it all.
+
+2. Then a generic fg table is created, where the functions have the signatures as specified
+   in the FG table. However, each of these functions follows the fg table pointer in the
+   the instance data given to it as a first argument, and then calls that function.
+
+3. It works, and it is a tried and true method.
+
+** Using a pointer pair ..
+
+1. Instead of the instance data being called the 'TM type', a pair is the 'TM type',
+   the first member of the pair points to an instance, the second to a corresponding
+   fg table.
+
+2. Again there are some generic TM functions, each accepts a pair as a first argument, and then calls the corresponding fg table function while giving it the instance pointer
+   from the pair as the first argument.
+
+3. This approach packs the same information as the vtable approach. If there is a
+   one to one correspondence between instances and pairs, then it is larger by one pointer.
+
+4. This is a type of 'link' from our continuations, but the tableau pointer is gone due
+   to using a stack frame, and the continuation table pointer is gone due to flow through sequencing. Thus it is two pointers instead of 4.
+
+5. Hopefully the optimizer would recognize that the pair pointers are redundant. They are only needed to ensure that the instance and fg table go together. 
+
+** Instance curried dispatch function
+1. In this case a pointer to a function is the 'TM type'. There is an enum that gives numeric tags to each of the functions in the FG struct instance.
+
+2. The tag for the desired fg function to be called is passed as the first argument to the dispatch function, and the remaining arguments are for the fg function.
+
+3. The dispatch function has the instance data and fg table pointer curried into it, so it then calls the correct fg function while handing it the correct instance data.
+
+4. In C it is not immediately obvious how to create a function on the fly each time an
+   instance is created, to curry the instance data into it, and then later how to call
+   the newly created function.
+
+** Self-typed Instance and dispatch function
+
+1. With this method, an extra field is added to the instance data that identifies its type. Then a globally available TM specific dispatch function is called to run the desired fg function on the data.  It is similar to the dispatch function from above, but the instance data is an additional argument.
+
+2. The dispatch function uses the type information to know which fg table to call. This type information could be a pointer to the appropriate fg table.
+
+3. This approach differs from the vtable method in that all the arguments are given to the one TM dispatch function, and it figures out how to do the dispatch. There is not a wrapper-per-function. 
+
+** Which approach?
+
+We want to be able to declare an instance as a local variable, where it will end up being on the stack frame. We want to avoid heap allocation for performance reasons, but not exclude use of heap memory.
+
+Dynamically created functions are out of the question. Dispatch approaches require the enum table so as to have tags. This is not show stopper. However, having one dispatch function means the argument types are not checked. That is a problem.
+
+Doubled up argument, one for the instance, the other for the table, either require wrappers, or not checking that an instance really goes with the data. Besides it is a lot of typing.
+
+The pointer pair approach requires the separate maintenance of the pair. When these are local variables, then the pair has to be tied to the instance. This would require the user to be aware of the existence of both the instance data and the pair, so as to pass them to an initializer.  This could be avoided if the pair would combined with the instance, but that
+is identical to the vtable approach (the instance pointer no longer being needed).
+
+So we are lead to the vtable. Though we are still hoping for the curried dispatch function - lol.
+
+
diff --git a/developer/experiment/xi.c b/developer/experiment/xi.c
new file mode 100644 (file)
index 0000000..3a13ea5
--- /dev/null
@@ -0,0 +1,68 @@
+/* Xi (螢) macro implementation with variable argument support
+ *
+ * This file provides macros from 螢0 through 螢10 along with a selector
+ * that automatically chooses the right macro based on argument count.
+ *
+ * Usage:
+ *   螢(a)                 -> a
+ *   螢(a ,b)              -> a路b
+ *   螢(a ,b ,c)           -> a路b路c
+ *   ...
+ *   螢(a ,b ,c ,d ,e ,f) -> a路b路c路d路e路f
+ *
+ * For Map with two template parameters:
+ *   螢(Map ,CVT_read ,CVT_write) -> Map路CVT_read路CVT_write
+ */
+
+#warning "beware all those who traverse here"
+
+#ifndef XI_C
+#define XI_C
+
+// 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__)
+
+#endif /* XI_C */
diff --git a/developer/experiment/xi2_test.c b/developer/experiment/xi2_test.c
new file mode 100644 (file)
index 0000000..b00205e
--- /dev/null
@@ -0,0 +1,62 @@
+#warning "beware all those who traverse here"
+
+// 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__)
+
+// Test cases
+#include <stdio.h>
+
+int main() {
+    printf("Testing macros:\n");
+    
+    // Test with different argument counts
+    printf("螢0(): %s\n", 螢());
+    printf("螢1(hello): %s\n", 螢(hello));
+    printf("螢2(hello, world): %s\n", 螢(hello, world));
+    printf("螢3(a, b, c): %s\n", 螢(a, b, c));
+    
+    return 0;
+}
diff --git a/developer/experiment/xi_test.c b/developer/experiment/xi_test.c
new file mode 100644 (file)
index 0000000..d9e435f
--- /dev/null
@@ -0,0 +1,39 @@
+#include <stdio.h>
+
+#include "xi.c"
+
+struct a{
+  int x;
+} 螢(X) ,螢(Y ,Y) ,螢(Z ,Z ,Z);
+
+
+int main(){
+
+  X.x = 3;
+  Y路Y.x = 5;
+  Z路Z路Z.x = 7;
+
+  螢(); // should do nothing, as it expands to nothing.
+
+  printf("%x" ,X.x); // notice no cdot, just 'X'
+  printf("%x" ,Y路Y.x);
+  printf("%x" ,Z路Z路Z.x);
+
+}
+
+
+/*
+2025-03-20T08:20:34Z[developer]
+Thomas-developer@Stanley搂/home/Thomas-masu/developer/N/developer/experiment搂
+> gcc xi_test.c
+In file included from xi_test.c:3:
+xi.c:17:2: warning: #warning "beware all those who traverse here" [-Wcpp]
+   17 | #warning "beware all those who traverse here"
+      |  ^~~~~~~
+
+2025-03-20T08:21:28Z[developer]
+Thomas-developer@Stanley搂/home/Thomas-masu/developer/N/developer/experiment搂
+> ./a.out
+357
+2025-03-20T08:21:34Z[developer]
+*/