bespoke bit copy transfers to and from processor native types
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 20 Feb 2025 10:50:46 +0000 (10:50 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Thu, 20 Feb 2025 10:50:46 +0000 (10:50 +0000)
developer/Python馃枆/fill_template
developer/Python馃枆/make_N_constants.py [new file with mode: 0755]
developer/Python馃枆/make_constants.py [deleted file]
developer/Python馃枆/template_N.py
developer/Python馃枆/template_conversion.py [new file with mode: 0644]
developer/experiment/try_letters_2.c [new file with mode: 0644]

index 4569e33..67e57ec 100755 (executable)
@@ -2,7 +2,6 @@
 
 import sys
 from template_N import N
-from make_constants import make_constants_block
 
 def write(code ,basename):
   filepath = "../cc/" + basename + ".lib.c" 
@@ -21,21 +20,35 @@ def main():
   
   type_name = "N32_1x32"
   digit_type = "uint32_t"
-  digit_extent = 0
-
-  constants_block = make_constants_block(type_name, digit_type, digit_extent)
-  code = N(type_name ,digit_type ,digit_extent ,constants_block)
+  digit_array_extent_type = "uint32_t"
+  digit_array_extent = 0
+  address_type = "uint64_t"
+
+  code = N(
+    type_name
+    ,digit_type 
+    ,digit_array_extent_type 
+    ,digit_array_extent 
+    ,address_type
+  )
   write(code ,type_name);
 
   #----------------------------------------
   # N32 made from 4 digits, each 8 bits.
 
-  type_name = "N32_4x8"
-  digit_type = "uint8_t"
-  digit_extent = 3
-
-  constants_block = make_constants_block(type_name, digit_type, digit_extent)
-  code = N(type_name ,digit_type ,digit_extent ,constants_block)
+  type_name = "N32_1x32"
+  digit_type = "uint32_t"
+  digit_array_extent_type = "uint8_t"
+  digit_array_extent = 3
+  address_type = "uint64_t"
+
+  code = N(
+    type_name
+    ,digit_type 
+    ,digit_array_extent_type 
+    ,digit_array_extent 
+    ,address_type
+  )
   write(code ,type_name);
 
 if __name__ == "__main__":
diff --git a/developer/Python馃枆/make_N_constants.py b/developer/Python馃枆/make_N_constants.py
new file mode 100755 (executable)
index 0000000..6a51113
--- /dev/null
@@ -0,0 +1,59 @@
+
+def make_N_constants(
+        namespace: str,
+        digit_type: str,
+        digit_array_extent: int
+) -> str:
+    """
+    Returns a block of code defining static compile-time constants:
+      static {namespace}T {namespace}constant[4] = {
+        { { ...zero... } },
+        { { ...one... } },
+        { { ...allbits... } },
+        { { ...msb... } }
+      };
+
+    The total digit count is digit_array_extent + 1.
+    """
+    digit_count = digit_array_extent + 1
+
+    def digits_zero():
+        return ", ".join("0" for _ in range(digit_count))
+
+    def digits_one():
+        # index 0 => 1, rest => 0
+        return ", ".join("1" if i == 0 else "0" for i in range(digit_count))
+
+    def digits_allbits():
+        # each digit => (digit_type)(-1)
+        return ", ".join(f"( {digit_type} )( -1 )" for _ in range(digit_count))
+
+    def digits_msb():
+        # top index => (digit_type)1 << ((sizeof(digit_type)*8)-1)
+        items = []
+        for i in range(digit_count):
+            if i == digit_count - 1:
+                items.append(f"( {digit_type} )1 << ((sizeof({digit_type})*8) - 1)")
+            else:
+                items.append("0")
+        return ", ".join(items)
+
+    return f'''
+static {namespace}T {namespace}constant[4] = {{
+  {{
+    // zero
+    {{ {digits_zero()} }}
+  }},
+  {{
+    // one
+    {{ {digits_one()} }}
+  }},
+  {{
+    // all one bits
+    {{ {digits_allbits()} }}
+  }},
+  {{
+    // msb
+    {{ {digits_msb()} }}
+  }}
+}};'''
diff --git a/developer/Python馃枆/make_constants.py b/developer/Python馃枆/make_constants.py
deleted file mode 100755 (executable)
index a177fde..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-def make_constants_block(namespace: str,
-                         digit_type: str,
-                         digit_extent: int) -> str:
-    """
-    Returns a block of code defining static compile-time constants:
-      static {namespace}T {namespace}constant[4] = {
-        { { ...zero... } },
-        { { ...one... } },
-        { { ...allbits... } },
-        { { ...msb... } }
-      };
-
-    The total digit count is digit_extent + 1.
-    """
-    digit_count = digit_extent + 1
-
-    def digits_zero():
-        return ", ".join("0" for _ in range(digit_count))
-
-    def digits_one():
-        # index 0 => 1, rest => 0
-        return ", ".join("1" if i == 0 else "0" for i in range(digit_count))
-
-    def digits_allbits():
-        # each digit => (digit_type)(-1)
-        return ", ".join(f"( {digit_type} )( -1 )" for _ in range(digit_count))
-
-    def digits_msb():
-        # top index => (digit_type)1 << ((sizeof(digit_type)*8)-1)
-        items = []
-        for i in range(digit_count):
-            if i == digit_count - 1:
-                items.append(f"( {digit_type} )1 << ((sizeof({digit_type})*8) - 1)")
-            else:
-                items.append("0")
-        return ", ".join(items)
-
-    return f'''\
-static {namespace}T {namespace}constant[4] = {{
-  {{
-    // zero
-    {{ {digits_zero()} }}
-  }},
-  {{
-    // one
-    {{ {digits_one()} }}
-  }},
-  {{
-    // all one bits
-    {{ {digits_allbits()} }}
-  }},
-  {{
-    // msb
-    {{ {digits_msb()} }}
-  }}
-}};'''
index bc2cc5e..8362083 100644 (file)
@@ -1,23 +1,36 @@
+
+from template_conversion import conversion
+from make_N_constants import make_N_constants
+
 def N(
-      namespace: str 
-      ,digit_type: str 
-      ,digit_array_extent_type: int
-      ,address_type: str
-      ,constants_block: str
-      ) -> str:
-
-    """
-    Returns a source code file for cc to munch on
-    """
-    template = template_N()
-    code = template.format(
-        NS = namespace
-        ,DIGIT_TYPE = digit_type
-        ,DIGIT_ARRAY_EXTENT_TYPE = digit_array_extent_type
-        ,AddressType = address_type
-        ,CONSTANTS_BLOCK = constants_block
-    )
-    return code
+      namespace 
+      ,digit_type 
+      ,digit_array_extent_type 
+      ,digit_array_extent 
+      ,address_type
+      ):
+  """
+  Returns a source code file for cc to munch on.
+  """
+
+  template = template_N()
+  code = (
+    template
+    .replace("NS" ,namespace)
+    .replace("DIGIT_TYPE" ,digit_type)
+    .replace("DIGIT_ARRAY_EXTENT_TYPE" ,str(digit_array_extent_type))
+    .replace("DIGIT_ARRAY_EXTENT" ,str(digit_array_extent))
+    .replace("ADDRESS_TYPE" ,address_type)
+    .replace("CONSTANTS_BLOCK"
+      ,make_N_constants(namespace ,digit_type ,digit_array_extent))
+    .replace("CONV_8" ,conversion("uint8_t"))
+    .replace("CONV_16" ,conversion("uint16_t"))
+    .replace("CONV_32" ,conversion("uint32_t"))
+    .replace("CONV_64" ,conversion("uint64_t"))
+    .replace("CONV_128" ,conversion("__uint128_t"))
+  )
+  
+  return code
 
 def template_N():
     return r'''
@@ -27,18 +40,18 @@ def template_N():
   T - Is the type for the tableau. 
 
 */
-#define {NS}路DEBUG
+#define NS路DEBUG
 
 #ifndef FACE
-#define {NS}路IMPLEMENTATION
+#define NS路IMPLEMENTATION
 #define FACE
 #endif
 
 //--------------------------------------------------------------------------------
 // Interface
 
-#ifndef {NS}路FACE
-#define {NS}路FACE
+#ifndef NS路FACE
+#define NS路FACE
 
   #include <stdint.h>
   #include <stdbool.h>
@@ -48,106 +61,157 @@ def template_N():
   //----------------------------------------
   // Instance Data (Declaration Only)
 
-  typedef {ADDRESS_TYPE} Address;
-// +3 - 1  due to 0x and the trailing null character, and being an extent
+  typedef ADDRESS_TYPE Address;
 
   // tableau type, encapsulated data is unavailable to user code
-  typedef struct {NS}路T {NS}路T;
+  typedef struct NS路T NS路T;
 
-  extern {NS}路T *{NS}路zero;
-  extern {NS}路T *{NS}路one;
-  extern {NS}路T *{NS}路all_one_bit;
-  extern {NS}路T *{NS}路lsb;
-  extern {NS}路T *{NS}路msb;
+  extern NS路T *NS路zero;
+  extern NS路T *NS路one;
+  extern NS路T *NS路all_one_bit;
+  extern NS路T *NS路lsb;
+  extern NS路T *NS路msb;
 
   //----------------------------------------
   // Return/Error Status and handlers
 
-  typedef enum{{
-    {NS}路Status路ok = 0
-    ,{NS}路Status路overflow = 1
-    ,{NS}路Status路accumulator_overflow = 2
-    ,{NS}路Status路carry = 3
-    ,{NS}路Status路borrow = 4
-    ,{NS}路Status路undefined_divide_by_zero = 5
-    ,{NS}路Status路undefined_modulus_zero = 6
-    ,{NS}路Status路gt_max_shift_count = 7
-    ,{NS}路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
-    ,{NS}路Status路one_word_product = 9
-    ,{NS}路Status路two_word_product = 10
-  }} {NS}路Status;
-
-  typedef enum{{
-    {NS}路Order_lt = -1
-    ,{NS}路Order_eq = 0
-    ,{NS}路Order_gt = 1
-  }} {NS}路Order;
+  typedef enum{
+    NS路Status路ok,
+    NS路Status路overflow,
+    NS路Status路accumulator_overflow,
+    NS路Status路carry,
+    NS路Status路borrow,
+    NS路Status路undefined_divide_by_zero,
+    NS路Status路undefined_modulus_zero,
+    NS路Status路gt_max_shift_count,
+    NS路Status路spill_eq_operand, // not currently signaled, result will be spill value
+    NS路Status路one_word_product,
+    NS路Status路two_word_product,
+    NS路Status路ConversionOverflow
+  } NS路Status;
+
+  typedef enum{
+    NS路Order_lt = -1
+    ,NS路Order_eq = 0
+    ,NS路Order_gt = 1
+  } NS路Order;
+
+  // Incomplete conversion NS路T -> PNT,  NS路T leftovers
+  typedef struct {
+    size_t scale; // this is in bytes
+    NS路T *d;      // digits, programmer must point this to a register
+  } NS路Leftover_N;
+
+  // Incomplete conversion PNT -> NS路T, PNT leftovers
+  #define NS路LEFTOVER_PNT(PNT)\
+    typedef struct {\
+      size_t scale; // this is in bytes\
+      PNT leftover;   // Residual value in PNT format\
+    } NS路Leftover_##PNT;
+
+  #ifdef UINT8_MAX
+    NS路LEFTOVER_PNT(uint8_t)
+  #endif
+  #ifdef UINT16_MAX
+    NS路LEFTOVER_PNT(uint16_t)
+  #endif
+  #ifdef UINT32_MAX
+    NS路LEFTOVER_PNT(uint32_t)
+  #endif
+  #ifdef UINT64_MAX
+    NS路LEFTOVER_PNT(uint64_t)
+  #endif
+  #ifdef __UINT128_MAX
+    NS路LEFTOVER_PNT(__uint128_t)
+  #endif
 
   // when alloc runs out of memory
-  typedef {NS}路T *( *{NS}路Allocate_MemoryFault )(Address);
+  typedef NS路T *( *NS路Allocate_MemoryFault )(Address);
 
   //----------------------------------------
   // Interface
 
-  typedef struct{{
+  #define NS路TO_TYPE(PNT) NS路Status (*to_##PNT)(const NS路T *, PNT *, NS路Leftover_N *)
+  #define NS路FROM_TYPE(PNT) NS路Status (*from_##PNT)(const PNT *, NS路T * ,NS路Leftover_##PNT *)
+
+  typedef struct{
 
     // memory allocation 
-    {NS}路T *(*allocate_array_zero)(Address, {NS}路Allocate_MemoryFault);
-    {NS}路T *(*allocate_array)(Address, {NS}路Allocate_MemoryFault);
-    void (*deallocate)({NS}路T*);
-    {NS}路T* (*access)({NS}路T*, Address);
+    NS路T *(*allocate_array_zero)(Address, NS路Allocate_MemoryFault);
+    NS路T *(*allocate_array)(Address, NS路Allocate_MemoryFault);
+    void (*deallocate)(NS路T*);
+    NS路T* (*access)(NS路T*, Address);
 
     // results fits in operand type functions
-    void (*copy)({NS}路T*, {NS}路T*);
-    void (*bit_and)({NS}路T*, {NS}路T*, {NS}路T*);
-    void (*bit_or)({NS}路T*, {NS}路T*, {NS}路T*);
-    void (*bit_complement)({NS}路T*, {NS}路T*);
-    void (*bit_twos_complement)({NS}路T*, {NS}路T*);
+    void (*copy)(NS路T*, NS路T*);
+    void (*bit_and)(NS路T*, NS路T*, NS路T*);
+    void (*bit_or)(NS路T*, NS路T*, NS路T*);
+    void (*bit_complement)(NS路T*, NS路T*);
+    void (*bit_twos_complement)(NS路T*, NS路T*);
 
     // tests  
-    {NS}路Order (*compare)({NS}路T*, {NS}路T*);
-    bool (*lt)({NS}路T*, {NS}路T*);
-    bool (*gt)({NS}路T*, {NS}路T*);
-    bool (*eq)({NS}路T*, {NS}路T*);
-    bool (*eq_zero)({NS}路T*);
+    NS路Order (*compare)(NS路T*, NS路T*);
+    bool (*lt)(NS路T*, NS路T*);
+    bool (*gt)(NS路T*, NS路T*);
+    bool (*eq)(NS路T*, NS路T*);
+    bool (*eq_zero)(NS路T*);
 
     // arithmetic
-    {NS}路Status (*accumulate)({NS}路T *accumulator1 ,{NS}路T *accumulator0 ,...);
-    {NS}路Status (*add)({NS}路T*, {NS}路T*, {NS}路T*);
-    bool (*increment)({NS}路T *a);
-    {NS}路Status (*subtract)({NS}路T*, {NS}路T*, {NS}路T*);
-    {NS}路Status (*multiply)({NS}路T*, {NS}路T*, {NS}路T*, {NS}路T*);
-    {NS}路Status (*divide)({NS}路T*, {NS}路T*, {NS}路T*, {NS}路T*);
-    {NS}路Status (*modulus)({NS}路T*, {NS}路T*, {NS}路T*);
+    NS路Status (*accumulate)(NS路T *accumulator1 ,NS路T *accumulator0 ,...);
+    NS路Status (*add)(NS路T*, NS路T*, NS路T*);
+    bool (*increment)(NS路T *a);
+    NS路Status (*subtract)(NS路T*, NS路T*, NS路T*);
+    NS路Status (*multiply)(NS路T*, NS路T*, NS路T*, NS路T*);
+    NS路Status (*divide)(NS路T*, NS路T*, NS路T*, NS路T*);
+    NS路Status (*modulus)(NS路T*, NS路T*, NS路T*);
 
     // shift
-    {NS}路Status (*shift_left)(Address, {NS}路T*, {NS}路T*, {NS}路T*);
-    {NS}路Status (*shift_right)(Address, {NS}路T*, {NS}路T*, {NS}路T*);
-    {NS}路Status (*arithmetic_shift_right)(Address, {NS}路T*, {NS}路T*);
+    NS路Status (*shift_left)(Address, NS路T*, NS路T*, NS路T*);
+    NS路Status (*shift_right)(Address, NS路T*, NS路T*, NS路T*);
+    NS路Status (*arithmetic_shift_right)(Address, NS路T*, NS路T*);
 
     // import/export
-    void (*to_string)(char [print_buffer_extent + 1] ,uint32_t value);
-    void (*from_uint32)({NS}路T *destination ,uint32_t value);
+    char *(*to_string)(NS路T *);
 
+    #ifdef UINT8_MAX
+      NS路TO_TYPE(uint8_t)
+      NS路FROM_TYPE(uint8_t)
+    #endif
+    #ifdef UINT16_MAX
+      NS路TO_TYPE(uint16_t)
+      NS路FROM_TYPE(uint16_t)
+    #endif
+    #ifdef UINT32_MAX
+      NS路TO_TYPE(uint32_t)
+      NS路FROM_TYPE(uint32_t)
+    #endif
+    #ifdef UINT64_MAX
+      NS路TO_TYPE(uint64_t)
+      NS路FROM_TYPE(uint64_t)
+    #endif
+    #ifdef __UINT128_MAX
+      NS路TO_TYPE(__uint128_t)
+      NS路FROM_TYPE(__uint128_t)
+    #endif
 
-  }} {NS}路M;
+  } NS路M;
 
-  Local const {NS}路M {NS}路m; // initialized in the LOCAL section
+  Local const NS路M NS路m; // initialized in the LOCAL section
 
 #endif
 
 //--------------------------------------------------------------------------------
 // Implementation
 
-#ifdef {NS}路IMPLEMENTATION
+#ifdef NS路IMPLEMENTATION
 
-  typedef {DIGIT_TYPE} Digit;
-  const {DIGIT_ARRAY_EXTENT_TYPE} digit_array_extent = {DIGIT_ARRAY_EXTENT};
+  typedef DIGIT_TYPE Digit;
+  const DIGIT_ARRAY_EXTENT_TYPE digit_array_extent = {DIGIT_ARRAY_EXTENT};
 
   // full type definition for Tableau
-  struct {NS}路T{{
+  struct NS路T{
     Digit d[digit_array_extent + 1];
-  }};
+  };
 
   // this part goes into Nlib.a
   #ifndef LOCAL
@@ -157,27 +221,27 @@ def template_N():
     #include <stdio.h>
 
     // the allocate an array of N32
-    {NS}路T *{NS}路allocate_array(Address extent ,{NS}路Allocate_MemoryFault memory_fault){{
-      {NS}路T *instance = malloc((extent + 1) * sizeof({NS}路T) );
-      if(!instance){{
+    NS路T *NS路allocate_array(Address extent ,NS路Allocate_MemoryFault memory_fault){
+      NS路T *instance = malloc((extent + 1) * sizeof(NS路T) );
+      if(!instance){
         return memory_fault ? memory_fault(extent) : NULL;
-      }}
+      }
       return instance;
-    }}
+    }
 
-    {NS}路T *{NS}路allocate_array_zero(Address extent ,{NS}路Allocate_MemoryFault memory_fault){{
-      {NS}路T *instance = calloc( extent + 1 ,sizeof({NS}路T) );
-      if(!instance){{
+    NS路T *NS路allocate_array_zero(Address extent ,NS路Allocate_MemoryFault memory_fault){
+      NS路T *instance = calloc( extent + 1 ,sizeof(NS路T) );
+      if(!instance){
         return memory_fault ? memory_fault(extent) : NULL;
-      }}
+      }
       return instance;
-    }}
+    }
 
-    void {NS}路deallocate({NS}路T *unencumbered){{
+    void NS路deallocate(NS路T *unencumbered){
       free(unencumbered);
-    }}
+    }
 
-  char *to_string({NS}路T *n) {
+  char *to_string(NS路T *n) {
     // Each byte requires two hex characters, plus "0x" prefix and null terminator
     const Address string_length = (sizeof(Digit) * (digit_array_extent + 1) * 2) + 3;   
     char *buffer = malloc(string_length);
@@ -204,356 +268,325 @@ def template_N():
   // This part is included after the user's code. If the code at top is a 'header, then this is a 'tailer'.
   #ifdef LOCAL
 
-    {CONSTANTS_BLOCK}
+    CONSTANTS_BLOCK
 
-    {NS}路T *{NS}路zero = &{NS}路constant[0];
-    {NS}路T *{NS}路one = &{NS}路constant[1];
-    {NS}路T *{NS}路all_one_bit = &{NS}路constant[2];
-    {NS}路T *{NS}路msb = &{NS}路constant[3];
-    {NS}路T *{NS}路lsb = &{NS}路constant[1];
+    NS路T *NS路zero = NS路constant + 0;
+    NS路T *NS路one =  NS路constant + 1;
+    NS路T *NS路all_one_bit = NS路constant + 2;
+    NS路T *NS路msb = &NS路constant + 3;
+    NS路T *NS路lsb = &NS路constant + 1;
 
     // temporary variables
     // making these LOCAL rather than reserving one block in the library is thread safe
     // allocating a block once is more efficient
     // library code writes these, they are not on the interface
 
-    Local {NS}路T {NS}路t[4];
+    Local NS路T NS路t[4];
 
 
     // allocation 
 
-    extern {NS}路T *{NS}路allocate_array(Address, {NS}路Allocate_MemoryFault);
-    extern {NS}路T *{NS}路allocate_array_zero(Address, {NS}路Allocate_MemoryFault);
-    extern void {NS}路deallocate({NS}路T *);
+    extern NS路T *NS路allocate_array(Address, NS路Allocate_MemoryFault);
+    extern NS路T *NS路allocate_array_zero(Address, NS路Allocate_MemoryFault);
+    extern void NS路deallocate(NS路T *);
 
     // so the user can access numbers in an array allocation
-    Local {NS}路T* {NS}路access({NS}路T *array ,Address index){{
+    Local NS路T* NS路access(NS路T *array ,Address index){
       return array + index;
-    }}
-
-    /*
-      // a hackish approach
-      void from_uint64_hack({NS}路T *n, uint64_t value) {
-        char buffer[24]; // Enough for "0xFFFFFFFFFFFFFFFF"
-        sprintf(buffer, "0x%llX", (unsigned long long)value);
-        from_string(n, buffer);
-      }
-
-     // as it should expand out to:
-      void from_uint64({NS}路T *n, uint64_t value) {
-        Digit *pd = n->d;
-        for (int i = 0; i <= digit_array_extent; i++, pd++) {
-          *pd = (Digit)(value & ((1ULL << (sizeof(Digit) * 8)) - 1)); // Extract lower bits
-          value >>= sizeof(Digit) * 8; // Shift right to process next part
-        }
-      }
-    */
-
-
-    #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
-      #define ENDIAN_DIRECTION -1  // Big-endian: Store high-to-low
-    #else
-      #define ENDIAN_DIRECTION 1   // Little-endian: Store low-to-high
-    #endif
-
-    #define DEFINE_FROM_UINT(TYPE) \
-      void from_##TYPE({{NS}}路T *n, TYPE value) {{ \
-        const Digit digit_mask = (Digit)((1ULL << (sizeof(Digit) * 8)) - 1); \
-        const Digit bits_in_digit = sizeof(Digit) * 8;
-        Digit *pd = (ENDIAN_DIRECTION == 1) ? n->d : (n->d + digit_array_extent); \
-        for (int i = 0; i <= digit_array_extent; i++, pd += ENDIAN_DIRECTION) {{ \
-          *pd = (Digit)(value & digit_mask); \
-          value >>= bits_in_digit; \
-        }} \
-      }}
-
-    #define DEFINE_TO_UINT(TYPE) \
-      TYPE to_##TYPE(const {{NS}}路T *n) {{ \
-        const Digit bits_in_digit = sizeof(Digit) * 8; \
-        TYPE value = 0; \
-        const Digit *pd = (ENDIAN_DIRECTION == 1) ? (n->d + digit_array_extent) : n->d; \
-        for (int i = 0; i <= digit_array_extent; i++, pd -= ENDIAN_DIRECTION) {{ \
-          value = (value << bits_in_digit) | *pd; \
-        }} \
-        return value; \
-      }}
-
-
-    #ifdef UINT8_MAX
-      DEFINE_FROM_UINT(uint8_t)
-      DEFINE_TO_UINT(uint8_t)
-    #endif
-
-    #ifdef UINT16_MAX
-      DEFINE_FROM_UINT(uint16_t)
-      DEFINE_TO_UINT(uint16_t)
-    #endif
-
-    #ifdef UINT32_MAX
-      DEFINE_FROM_UINT(uint32_t)
-      DEFINE_TO_UINT(uint32_t)
-    #endif
-
-    #ifdef UINT64_MAX
-      DEFINE_FROM_UINT(uint64_t)
-      DEFINE_TO_UINT(uint64_t)
-    #endif
-
-    #ifdef __UINT128_MAX
-      DEFINE_FROM_UINT(__uint128_t)
-      DEFINE_TO_UINT(__uint128_t)
-    #endif
+    }
 
     // copy, convenience copy
 
-    Local void {NS}路copy({NS}路T *destination ,{NS}路T *source){{
+    Local void NS路copy(NS路T *destination ,NS路T *source){
       if(source == destination) return; // that was easy! 
       *destination = *source;
-    }}
+    }
 
-    Local void {NS}路set_to_zero({NS}路T *instance){{
+    Local void NS路set_to_zero(NS路T *instance){
       instance->d0 = 0;
-    }}
+    }
 
-    Local void {NS}路set_to_one({NS}路T *instance){{
+    Local void NS路set_to_one(NS路T *instance){
       instance->d0 = 1;
-    }}
+    }
 
     // bit operations
 
-    Local void {NS}路bit_and({NS}路T *result, {NS}路T *a, {NS}路T *b){{
+    Local void NS路bit_and(NS路T *result, NS路T *a, NS路T *b){
       result->d0 = a->d0 & b->d0;
-    }}
+    }
 
     // result can be one of the operands
-    Local void {NS}路bit_or({NS}路T *result, {NS}路T *a, {NS}路T *b){{
+    Local void NS路bit_or(NS路T *result, NS路T *a, NS路T *b){
       result->d0 = a->d0 | b->d0;
-    }}
+    }
 
     // result can the same as the operand
-    Local void {NS}路bit_complement({NS}路T *result, {NS}路T *a){{
+    Local void NS路bit_complement(NS路T *result, NS路T *a){
       result->d0 = ~a->d0;
-    }}
+    }
 
     // result can the same as the operand
-    Local void {NS}路bit_twos_complement({NS}路T *result ,{NS}路T *a){{
+    Local void NS路bit_twos_complement(NS路T *result ,NS路T *a){
       result->d0 = ~a->d0 + 1;
-    }}
+    }
 
     // test functions
 
-    Local {NS}路Order {NS}路compare({NS}路T *a, {NS}路T *b){{
-      if(a->d0 < b->d0) return {NS}路Order_lt;
-      if(a->d0 > b->d0) return {NS}路Order_gt;
-      return {NS}路Order_eq;
-    }}
+    Local NS路Order NS路compare(NS路T *a, NS路T *b){
+      if(a->d0 < b->d0) return NS路Order_lt;
+      if(a->d0 > b->d0) return NS路Order_gt;
+      return NS路Order_eq;
+    }
 
-    Local bool {NS}路lt({NS}路T *a ,{NS}路T *b){{
+    Local bool NS路lt(NS路T *a ,NS路T *b){
       return  a->d0 < b->d0;
-    }}    
+    }    
 
-    Local bool {NS}路gt({NS}路T *a ,{NS}路T *b){{
+    Local bool NS路gt(NS路T *a ,NS路T *b){
       return  a->d0 > b->d0;
-    }}    
+    }    
 
-    Local bool {NS}路eq({NS}路T *a ,{NS}路T *b){{
+    Local bool NS路eq(NS路T *a ,NS路T *b){
       return  a->d0 == b->d0;
-    }}    
+    }    
 
-    Local bool {NS}路eq_zero({NS}路T *a){{
+    Local bool NS路eq_zero(NS路T *a){
       return  a->d0 == 0;
-    }}    
+    }    
 
 
     // arithmetic operations
 
-    // For a large number of summands for the lower precision Natural implementations, for accumulate/add/sub, the 'overflow' operand could overflow and thus this routine will halt and return {NS}路Status路accumulator1_overflow
+    // For a large number of summands for the lower precision Natural implementations, for accumulate/add/sub, the 'overflow' operand could overflow and thus this routine will halt and return NS路Status路accumulator1_overflow
     //
     // When accumulator1 and accumulator0 point to the same location, the result is the accumulator1 value.
-    Local {NS}路Status {NS}路accumulate({NS}路T *accumulator1 ,{NS}路T *accumulator0 ,...){{
+    Local NS路Status NS路accumulate(NS路T *accumulator1 ,NS路T *accumulator0 ,...){
 
       va_list args;
       va_start(args ,accumulator0);
       uint32_t sum = accumulator0->d0;
       uint32_t carry = 0;
-      {NS}路T *current;
+      NS路T *current;
 
-      while( (current = va_arg(args ,{NS}路T *)) ){{
+      while( (current = va_arg(args ,NS路T *)) ){
         sum += current->d0;
-        if(sum < current->d0){{  // Accumulator1 into carry
+        if(sum < current->d0){  // Accumulator1 into carry
           (carry)++;
-          if(carry == 0){{
+          if(carry == 0){
             va_end(args);
-            return {NS}路Status路accumulator1_overflow;
-          }}
-        }}
-      }}
+            return NS路Status路accumulator1_overflow;
+          }
+        }
+      }
       va_end(args);
 
       // wipes out prior value of accumulator1
       accumulator1->d0 = carry;
 
-      return {NS}路Status路ok;
-    }}
+      return NS路Status路ok;
+    }
 
-    Local {NS}路Status {NS}路add({NS}路T *sum ,{NS}路T *a ,{NS}路T *b){{
+    Local NS路Status NS路add(NS路T *sum ,NS路T *a ,NS路T *b){
       uint64_t result = (uint64_t)a->d0 + (uint64_t)b->d0;
       sum->d0 = (uint32_t)result;
-      return (result >> 32) ? {NS}路Status路carry : {NS}路Status路ok;
-    }}
+      return (result >> 32) ? NS路Status路carry : NS路Status路ok;
+    }
 
-    Local bool {NS}路increment({NS}路T *a){{
+    Local bool NS路increment(NS路T *a){
       a->d0++;
       return a->d0 == 0;
-    }}
+    }
 
-    Local {NS}路Status {NS}路subtract({NS}路T *difference ,{NS}路T *a ,{NS}路T *b){{
+    Local NS路Status NS路subtract(NS路T *difference ,NS路T *a ,NS路T *b){
       uint64_t diff = (uint64_t) a->d0 - (uint64_t) b->d0;
       difference->d0 = (uint32_t)diff;
-      return (diff > a->d0) ? {NS}路Status路borrow : {NS}路Status路ok;
-    }}
+      return (diff > a->d0) ? NS路Status路borrow : NS路Status路ok;
+    }
 
-    Local {NS}路Status {NS}路multiply({NS}路T *product1 ,{NS}路T *product0 ,{NS}路T *a ,{NS}路T *b){{
+    Local NS路Status NS路multiply(NS路T *product1 ,NS路T *product0 ,NS路T *a ,NS路T *b){
       uint64_t product = (uint64_t)a->d0 * (uint64_t)b->d0;
       product0->d0 = (uint32_t)product;
       product1->d0 = (uint32_t)(product >> 32);
 
-      if(product1->d0 == 0) return {NS}路Status路one_word_product;
-      return {NS}路Status路two_word_product;
-    }}
+      if(product1->d0 == 0) return NS路Status路one_word_product;
+      return NS路Status路two_word_product;
+    }
 
-    Local {NS}路Status {NS}路divide({NS}路T *remainder ,{NS}路T *quotient ,{NS}路T *a ,{NS}路T *b){{
-      if(b->d0 == 0) return {NS}路Status路undefined_divide_by_zero; 
+    Local NS路Status NS路divide(NS路T *remainder ,NS路T *quotient ,NS路T *a ,NS路T *b){
+      if(b->d0 == 0) return NS路Status路undefined_divide_by_zero; 
 
       quotient->d0 = a->d0 / b->d0;
       remainder->d0 = a->d0 - (quotient->d0 * b->d0);
 
-      return {NS}路Status路ok;
-    }}
+      return NS路Status路ok;
+    }
 
-    Local {NS}路Status {NS}路modulus({NS}路T *remainder ,{NS}路T *a ,{NS}路T *b){{
-      if(b->d0 == 0) return {NS}路Status路undefined_modulus_zero; 
+    Local NS路Status NS路modulus(NS路T *remainder ,NS路T *a ,NS路T *b){
+      if(b->d0 == 0) return NS路Status路undefined_modulus_zero; 
       uint32_t quotient = a->d0 / b->d0;
       remainder->d0 = a->d0 - (quotient * b->d0);
-      return {NS}路Status路ok;
-    }}
+      return NS路Status路ok;
+    }
 
     // bit motion
 
     typedef uint32_t (*ShiftOp)(uint32_t, uint32_t);
 
-    Local uint32_t shift_left_op(uint32_t value, uint32_t amount){{
+    Local uint32_t shift_left_op(uint32_t value, uint32_t amount){
       return value << amount;
-    }}
+    }
 
-    Local uint32_t shift_right_op(uint32_t value, uint32_t amount){{
+    Local uint32_t shift_right_op(uint32_t value, uint32_t amount){
       return value >> amount;
-    }}
+    }
 
     // modifies all three of its operands
     // in the case of duplicate operands this is the order: first modifies operand, then fill, then spill, 
-    Local {NS}路Status {NS}路shift
+    Local NS路Status NS路shift
     (
      uint32_t shift_count
-     ,{NS}路T *spill
-     ,{NS}路T *operand
-     ,{NS}路T *fill
+     ,NS路T *spill
+     ,NS路T *operand
+     ,NS路T *fill
      ,ShiftOp shift_op
      ,ShiftOp complement_shift_op
-     ){{
+     ){
 
       // If no result is needed, return immediately.
-      if(operand == NULL && spill == NULL) return {NS}路Status路ok;
+      if(operand == NULL && spill == NULL) return NS路Status路ok;
 
       // Treat NULL operand as zero.
-      if(operand == NULL){{
-        operand = &{NS}路t[0];
-        {NS}路copy(operand, {NS}路zero);
-      }}
+      if(operand == NULL){
+        operand = &NS路t[0];
+        NS路copy(operand, NS路zero);
+      }
 
       // Shifting more than one word breaks our fill/spill model.
-      if(shift_count > 31) return {NS}路Status路gt_max_shift_count;
+      if(shift_count > 31) return NS路Status路gt_max_shift_count;
 
       // The given operand is still required after it is modified, so we copy it.
-      {NS}路T *given_operand = &{NS}路t[1];
-      {NS}路copy(given_operand, operand);
+      NS路T *given_operand = &NS路t[1];
+      NS路copy(given_operand, operand);
 
       // Perform the shift
       operand->d0 = shift_op(given_operand->d0, shift_count);
-      if(fill != NULL){{
+      if(fill != NULL){
         fill->d0 = complement_shift_op(fill->d0, (32 - shift_count));
-        {NS}路bit_or(operand, operand, fill);
-      }}
-      if(spill != NULL){{
+        NS路bit_or(operand, operand, fill);
+      }
+      if(spill != NULL){
         spill->d0 = shift_op(spill->d0, shift_count);
         spill->d0 += complement_shift_op(given_operand->d0, (32 - shift_count));
-      }}
+      }
 
-      return {NS}路Status路ok;
-    }}
+      return NS路Status路ok;
+    }
 
     // Define concrete shift functions using valid C function pointers
-    Local {NS}路Status 
-    {NS}路shift_left(uint32_t shift_count, {NS}路T *spill, {NS}路T *operand, {NS}路T *fill){{
-      return {NS}路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
-    }}
+    Local NS路Status 
+    NS路shift_left(uint32_t shift_count, NS路T *spill, NS路T *operand, NS路T *fill){
+      return NS路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
+    }
 
-    Local {NS}路Status 
-    {NS}路shift_right(uint32_t shift_count, {NS}路T *spill, {NS}路T *operand, {NS}路T *fill){{
-      return {NS}路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
-    }}
+    Local NS路Status 
+    NS路shift_right(uint32_t shift_count, NS路T *spill, NS路T *operand, NS路T *fill){
+      return NS路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
+    }
 
-    Local {NS}路Status 
-    {NS}路arithmetic_shift_right(uint32_t shift_count, {NS}路T *operand, {NS}路T *spill){{
+    Local NS路Status 
+    NS路arithmetic_shift_right(uint32_t shift_count, NS路T *operand, NS路T *spill){
 
       // Guard against excessive shift counts
-      if(shift_count > 31) return {NS}路Status路gt_max_shift_count;
+      if(shift_count > 31) return NS路Status路gt_max_shift_count;
 
       // A NULL operand is treated as zero
-      if(operand == NULL){{
-        operand = &{NS}路t[0];
-        {NS}路copy(operand, {NS}路zero);
-      }}
+      if(operand == NULL){
+        operand = &NS路t[0];
+        NS路copy(operand, NS路zero);
+      }
 
       // Pick the fill value based on the sign bit
-      {NS}路T *fill = (operand->d0 & 0x80000000) ? {NS}路all_one_bit : {NS}路zero;
+      NS路T *fill = (operand->d0 & 0x80000000) ? NS路all_one_bit : NS路zero;
 
       // Call shift_right with the appropriate fill
-      return {NS}路shift_right(shift_count, spill, operand, fill);
-    }}
-
-    Local const {NS}路M {NS}路m = {{
-
-      .allocate_array = {NS}路allocate_array
-      ,.allocate_array_zero = {NS}路allocate_array_zero
-      ,.deallocate = {NS}路deallocate
-
-      ,.copy = {NS}路copy
-      ,.bit_and = {NS}路bit_and
-      ,.bit_or = {NS}路bit_or
-      ,.bit_complement = {NS}路bit_complement
-      ,.bit_twos_complement = {NS}路bit_twos_complement
-      ,.compare = {NS}路compare
-      ,.lt = {NS}路lt
-      ,.gt = {NS}路gt
-      ,.eq = {NS}路eq
-      ,.eq_zero = {NS}路eq_zero
-      ,.accumulate = {NS}路accumulate
-      ,.add = {NS}路add
-      ,.increment = {NS}路increment
-      ,.subtract = {NS}路subtract
-      ,.multiply = {NS}路multiply
-      ,.divide = {NS}路divide
-      ,.modulus = {NS}路modulus
-      ,.shift_left = {NS}路shift_left
-      ,.shift_right = {NS}路shift_right
-      ,.arithmetic_shift_right = {NS}路arithmetic_shift_right
-
-      ,.access = {NS}路access
-      ,.from_uint32 = {NS}路from_uint32
-    }};
+      return NS路shift_right(shift_count, spill, operand, fill);
+    }
+
+    #ifdef UINT8_MAX
+      CONV_8
+    #endif
+    #ifdef UINT16_MAX
+      CONV_16
+    #endif
+    #ifdef UINT32_MAX
+      CONV_32
+    #endif
+    #ifdef UINT64_MAX
+      CONV_64
+    #endif
+    #ifdef __UINT128_MAX
+      CONV_128
+    #endif
+
+    Local const NS路M NS路m = {
+
+      .allocate_array = NS路allocate_array
+      ,.allocate_array_zero = NS路allocate_array_zero
+      ,.deallocate = NS路deallocate
+
+      ,.copy = NS路copy
+      ,.bit_and = NS路bit_and
+      ,.bit_or = NS路bit_or
+      ,.bit_complement = NS路bit_complement
+      ,.bit_twos_complement = NS路bit_twos_complement
+      ,.compare = NS路compare
+      ,.lt = NS路lt
+      ,.gt = NS路gt
+      ,.eq = NS路eq
+      ,.eq_zero = NS路eq_zero
+      ,.accumulate = NS路accumulate
+      ,.add = NS路add
+      ,.increment = NS路increment
+      ,.subtract = NS路subtract
+      ,.multiply = NS路multiply
+      ,.divide = NS路divide
+      ,.modulus = NS路modulus
+      ,.shift_left = NS路shift_left
+      ,.shift_right = NS路shift_right
+      ,.arithmetic_shift_right = NS路arithmetic_shift_right
+
+      ,.access = NS路access
+      ,.from_uint32 = NS路from_uint32
+
+      #ifdef UINT8_MAX
+        ,.to_uint8_t = NS路to_uint8_t
+        ,.from_uint8_t = NS路from_uint8_t
+      #endif
+      #ifdef UINT16_MAX
+        ,.to_uint16_t = NS路to_uint16_t
+        ,.from_uint16_t = NS路from_uint16_t
+      #endif
+      #ifdef UINT32_MAX
+        ,.to_uint32_t = NS路to_uint32_t
+        ,.from_uint32_t = NS路from_uint32_t
+      #endif
+      #ifdef UINT64_MAX
+        ,.to_uint64_t = NS路to_uint64_t
+        ,.from_uint64_t = NS路from_uint64_t
+      #endif
+      #ifdef __UINT128_MAX
+        ,.to___uint128_t = NS路to___uint128_t
+        ,.from___uint128_t = NS路from___uint128_t
+      #endif
+
+    };
 
   #endif
 
 #endif
 '''
+
+
+
diff --git a/developer/Python馃枆/template_conversion.py b/developer/Python馃枆/template_conversion.py
new file mode 100644 (file)
index 0000000..d751cdd
--- /dev/null
@@ -0,0 +1,94 @@
+
+# gt_extent_type is large enough to hold a sizeof(NS路T)-1 or sizeof(TYPE)-1
+def conversion(type: str):
+  """
+  Returns a source code file for cc to munch on
+  """
+  template = template_conversion()
+  code = template.replace("TYPE", type)
+  return code
+
+# The Digit array is always least significant digit at d[0]
+def template_conversion():
+    return r'''
+
+// NS路T -> PNT, possible NS路T leftovers
+NS路Status NS路to_TYPE
+ (
+  const NS路T *source
+  ,TYPE *destination
+  ,NS路Leftover_N *leftover
+  ){
+
+  uint8_t *s = (uint8_t *)source;
+  uint8_t *d = (uint8_t *)destination;
+
+  if( sizeof(NS路T) <= sizeof(TYPE) ){
+    *destination = 0;
+    memcpy( d, s, sizeof(NS路T) );
+    return NS路Status路ok;
+  }
+
+  memcpy( destination ,s ,sizeof(TYPE) );
+  s += sizeof(TYPE);
+  const size_t 未 = sizeof(NS路T) - sizeof(TYPE);
+
+  if( memcmp(NS路constant + 0 ,s ,未) == 0 ){
+    return NS路Status路ok;
+  }
+  // else there are leftovers
+  
+  if( leftover == NULL || leftover->d == NULL){ // then nowhere to put the leftovers
+    return NS路Status路ConversionOverflow;
+  }
+
+  // copy the part leftover into the leftover struct
+  leftover->scale = sizeof(TYPE);
+  uint8_t *lod = (uint8_t *)(leftover->d);
+  memcpy(lod ,s ,未);
+
+  // zero out the upper bytes of the leftover struct
+  lod += 未;
+  memset(lod, 0, sizeof(NS路T) - 未);  // Zero remaining bytes safely
+
+  return NS路Status路ConversionOverflow;
+}
+
+// PNT -> NS路T, possible PNT leftovers
+NS路Status NS路from_TYPE
+ (
+  const TYPE *s // source
+  ,NS路T *destination
+  ,NS路Leftover_PNT *leftover
+  ){
+  uint8_t *d = (uint8_t *)destination; // NS路T
+
+  // source allocation smaller: copy then zero out the top of destination
+  if( sizeof(TYPE) <= sizeof(NS路T)  ){
+    memcpy( d, s, sizeof(TYPE) );
+    d += sizeof(TYPE);
+    memset( d, 0, sizeof(NS路T) - sizeof(TYPE) );  // Zero out remaining bytes
+    return NS路Status路ok;
+  }
+
+  // The source allocation is larger: copy then potentially spill to leftovers
+
+  memcpy( d, s, sizeof(NS路T) );
+
+  TYPE mask = ~(TYPE)0 << (sizeof(NS路T) << 3);
+  TYPE unscaled_leftover = *source & mask;
+
+  if(unscaled_leftover == 0) return NS路Status路ok;
+
+  if(leftover == NULL){ // then nowhere to put the leftovers
+    return NS路Status路ConversionOverflow;
+  }
+  
+  leftover->scale = sizeof(NS路T);
+  leftover->leftover = unscaled_leftover >> (sizeof(NS路T) << 3);
+
+  return NS路Status路ConversionOverflow;
+
+}
+'''
diff --git a/developer/experiment/try_letters_2.c b/developer/experiment/try_letters_2.c
new file mode 100644 (file)
index 0000000..234e578
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stdio.h>
+
+// Define interface and instance types
+typedef struct {
+    void (*print_value)(int);
+} N32路M;  // Interface type
+
+typedef struct {
+    int value;
+} N32路未;  // Instance type
+
+// Function implementation for the interface
+void print_value_function(int value) {
+    printf("Value: %d\n", value);
+}
+
+// Default interface instance
+const N32路M N32路m = {
+    .print_value = print_value_function
+};
+
+int main() {
+    // Create an instance
+    N32路未 instance = { 99 };
+    int 螖 = 5;
+
+    // Call function via interface
+    printf("Calling via interface: ");
+    N32路m.print_value(instance.value);
+    N32路m.print_value(螖);
+
+    return 0;
+}