testing environment setup and namespace template for N32 tests
authorThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 17 Feb 2025 09:44:14 +0000 (09:44 +0000)
committerThomas Walker Lynch <eknp9n@reasoningtechnology.com>
Mon, 17 Feb 2025 09:44:14 +0000 (09:44 +0000)
24 files changed:
developer/python/fill_template [new file with mode: 0755]
developer/python/fill_template.py [deleted file]
developer/tool馃枆/clean [new file with mode: 0755]
developer/tool馃枆/makefile
developer/tool馃枆/release
developer/tool馃枆/release_clean [new file with mode: 0755]
developer/tool馃枆/release_ls [new file with mode: 0755]
release/x86_64/fedora41/glibc_2.40/libN.a
tester/cc/N32.lib.c [deleted file]
tester/cc/test_N32PN.cli.c [new file with mode: 0644]
tester/cc馃枆/test_N32.cli.c [deleted file]
tester/deprecated馃枆/test_N32.cli.c [new file with mode: 0644]
tester/python/#fill_templates.py# [new file with mode: 0644]
tester/python/fill_template [new file with mode: 0755]
tester/python/template_test_N32.py [new file with mode: 0644]
tester/tool馃枆/clean [new file with mode: 0755]
tester/tool馃枆/make
tester/tool馃枆/makefile
tester/tool馃枆/pull_release [deleted file]
tester/tool馃枆/release [new file with mode: 0755]
tester/tool馃枆/release_clean [new file with mode: 0755]
tester/tool馃枆/release_pull [new file with mode: 0755]
tester/tool馃枆/release_test [deleted file]
tool_shared/bespoke馃枆/env

diff --git a/developer/python/fill_template b/developer/python/fill_template
new file mode 100755 (executable)
index 0000000..bf73da9
--- /dev/null
@@ -0,0 +1,27 @@
+#+BEGIN_SRC python
+#!/usr/bin/env python3
+
+from get_template import get_template
+from make_constants import make_constants_block
+
+def fill_template(namespace: str,
+                  digit_extent: int,
+                  digit_type: str) -> str:
+    """
+    Renders the final .lib.c code by merging:
+      - the base template from get_template()
+      - the compile-time constants block from make_constants_block()
+      - placeholders for namespace, digit_extent, digit_type, extent_type
+    """
+    template = get_template()
+    constants_block = make_constants_block(namespace, digit_type, digit_extent)
+
+    # Substitute placeholders
+    code = template.format(
+        NAMESPACE = namespace,
+        DIGIT_EXTENT = digit_extent,
+        DIGIT_TYPE = digit_type,
+        CONSTANTS_BLOCK = constants_block
+    )
+    return code
+#+END_SRC
diff --git a/developer/python/fill_template.py b/developer/python/fill_template.py
deleted file mode 100755 (executable)
index bf73da9..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#+BEGIN_SRC python
-#!/usr/bin/env python3
-
-from get_template import get_template
-from make_constants import make_constants_block
-
-def fill_template(namespace: str,
-                  digit_extent: int,
-                  digit_type: str) -> str:
-    """
-    Renders the final .lib.c code by merging:
-      - the base template from get_template()
-      - the compile-time constants block from make_constants_block()
-      - placeholders for namespace, digit_extent, digit_type, extent_type
-    """
-    template = get_template()
-    constants_block = make_constants_block(namespace, digit_type, digit_extent)
-
-    # Substitute placeholders
-    code = template.format(
-        NAMESPACE = namespace,
-        DIGIT_EXTENT = digit_extent,
-        DIGIT_TYPE = digit_type,
-        CONSTANTS_BLOCK = constants_block
-    )
-    return code
-#+END_SRC
diff --git a/developer/tool馃枆/clean b/developer/tool馃枆/clean
new file mode 100755 (executable)
index 0000000..cbb86b8
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="developer/tool馃枆/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+set -e
+set -x
+
+
+cd "$REPO_HOME"/developer || exit 1
+
+# remove library pulled from release and other scratchpad files
+  rm_na scratchpad/{makefile-cc.deps,*.o} || true
+
+# remove built executables
+  rm_na -f machine/* || true
+
+set +x
+echo "$(script_fn) done."
index 64bb614..56f2283 100644 (file)
@@ -7,7 +7,7 @@ CFLAGS+=-Werror -include "$(RT-INCOMMON)/make/RT_0.h"
 LINKFLAGS+= -l$(PROJECT)
 LIBFILE=$(LIBDIR)/lib$(PROJECT).a
 
-include $(RT-INCOMMON)/make/targets
+include $(RT-INCOMMON)/make/targets_developer
 -include $(DEPFILE)
 
 
index feb8bcf..8dc8993 100755 (executable)
@@ -11,9 +11,6 @@ script_afp=$(realpath "${BASH_SOURCE[0]}")
     exit 1
   fi
 
-set -e
-set -x
-
   cd "$REPO_HOME"/developer || exit 1
 
   if [ ! -d scratchpad ]; then
@@ -21,15 +18,16 @@ set -x
     exit 1
   fi
 
+#set -e
+#set -x
+
   release_dir=$(release_dir)
   mkdir -p ${release_dir}
 
-  install_file scratchpad/libN.a ${release_dir} "ug+r"
-
-  # header files
-  install_file {cc,cc馃枆}/*.lib.c ${release_dir} "ug+r"
-
+  install_file scratchpad/libN.a ${release_dir} "ug+r"  || true
+  install_file cc馃枆/*.lib.c ${release_dir} "ug+r"  || true
+  install_file cc/*.lib.c ${release_dir} "ug+r" || true
 
-set +x
+#set +x
 echo "$(script_fn) done."
 
diff --git a/developer/tool馃枆/release_clean b/developer/tool馃枆/release_clean
new file mode 100755 (executable)
index 0000000..52309e6
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# before running this, make library is built and is in the scratchpad directory
+
+# input guards
+
+  env_must_be="developer/tool馃枆/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+set -e
+set -x
+
+  cd "$REPO_HOME"/developer || exit 1
+
+  release_dir=$(release_dir)
+
+  if [ ! -d ${release_dir} ]; then
+    echo "$(script_fp):: no release directory: " ${release_dir}
+    exit 1
+  fi
+
+  rm_na -rf ${release_dir}/*
+
+set +x
+echo "$(script_fn) done."
+
diff --git a/developer/tool馃枆/release_ls b/developer/tool馃枆/release_ls
new file mode 100755 (executable)
index 0000000..52550b6
--- /dev/null
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# before running this, make library is built and is in the scratchpad directory
+
+# input guards
+
+  env_must_be="developer/tool馃枆/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+  release_dir=$(release_dir)
+
+  if [ ! -d ${release_dir} ]; then
+    echo "$(script_fp):: no release directory: " ${release_dir}
+    exit 1
+  fi
+
+  ls $@ ${release_dir}
+
+
index 2818416..15d0154 100644 (file)
Binary files a/release/x86_64/fedora41/glibc_2.40/libN.a and b/release/x86_64/fedora41/glibc_2.40/libN.a differ
diff --git a/tester/cc/N32.lib.c b/tester/cc/N32.lib.c
deleted file mode 100644 (file)
index fba3c21..0000000
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
-  N32 - a processor native type
-
-  For binary operations:  a op b -> c
-
-  See the document on the proper use of the Natural types.
-
-  On the subject of multiple pointers indicating the same location in memory:
-
-  When a routine has multiple results, and one or more of the result location
-  pointers point to the same storage, the routine will either return an error
-  status, or have defined behavior.
-
-  When a routine has multiple operands, in any combination, those
-  pointers can point to the same location, and the routine will
-  function as advertised.
-
-  When an operand functions as both an input and a result, perhaps due
-  to a result pointer pointing to the same place as an operand
-  pointer, the routine will function as advertised. (Internally the
-  routine might make a temporary copy of the operand to accomplish
-  this.)
-
-*/
-
-#define N32路DEBUG
-
-#ifndef FACE
-#define N32路IMPLEMENTATION
-#define FACE
-#endif
-
-//--------------------------------------------------------------------------------
-// Interface
-
-#ifndef N32路FACE
-#define N32路FACE
-
-  #include <stdint.h>
-  #include <stdbool.h>
-  #include <stdarg.h>
-  #include <stdlib.h>
-
-  //----------------------------------------
-  // Instance Data (Declaration Only)
-
-  typedef uint32_t Extent;
-  typedef uint32_t Digit;
-
-  typedef struct N32路T N32路T;
-
-  extern N32路T *N32路zero;
-  extern N32路T *N32路one;
-  extern N32路T *N32路all_one_bit;
-  extern N32路T *N32路lsb;
-  extern N32路T *N32路msb;
-
-  //----------------------------------------
-  // Return/Error Status and handlers
-
-  typedef enum{
-    N32路Status路ok = 0
-    ,N32路Status路overflow = 1
-    ,N32路Status路accumulator1_overflow = 2
-    ,N32路Status路carry = 3
-    ,N32路Status路borrow = 4
-    ,N32路Status路undefined_divide_by_zero = 5
-    ,N32路Status路undefined_modulus_zero = 6
-    ,N32路Status路gt_max_shift_count = 7
-    ,N32路Status路spill_eq_operand = 8 // not currently signaled, result will be spill value
-    ,N32路Status路one_word_product = 9
-    ,N32路Status路two_word_product = 10
-  } N32路Status;
-
-  typedef enum{
-    N32路Order_lt = -1
-    ,N32路Order_eq = 0
-    ,N32路Order_gt = 1
-  } N32路Order;
-
-  typedef N32路T *( *N32路Allocate_MemoryFault )(Extent);
-
-  //----------------------------------------
-  // Interface
-
-  typedef struct{
-
-    N32路T *(*allocate_array_zero)(Extent, N32路Allocate_MemoryFault);
-    N32路T *(*allocate_array)(Extent, N32路Allocate_MemoryFault);
-    void (*deallocate)(N32路T*);
-
-    void (*copy)(N32路T*, N32路T*);
-    void (*bit_and)(N32路T*, N32路T*, N32路T*);
-    void (*bit_or)(N32路T*, N32路T*, N32路T*);
-    void (*bit_complement)(N32路T*, N32路T*);
-    void (*bit_twos_complement)(N32路T*, N32路T*);
-    N32路Order (*compare)(N32路T*, N32路T*);
-    bool (*lt)(N32路T*, N32路T*);
-    bool (*gt)(N32路T*, N32路T*);
-    bool (*eq)(N32路T*, N32路T*);
-    bool (*eq_zero)(N32路T*);
-    N32路Status (*accumulate)(N32路T *accumulator1 ,N32路T *accumulator0 ,...);
-    N32路Status (*add)(N32路T*, N32路T*, N32路T*);
-    bool (*increment)(N32路T *a);
-    N32路Status (*subtract)(N32路T*, N32路T*, N32路T*);
-    N32路Status (*multiply)(N32路T*, N32路T*, N32路T*, N32路T*);
-    N32路Status (*divide)(N32路T*, N32路T*, N32路T*, N32路T*);
-    N32路Status (*modulus)(N32路T*, N32路T*, N32路T*);
-    N32路Status (*shift_left)(Extent, N32路T*, N32路T*, N32路T*);
-    N32路Status (*shift_right)(Extent, N32路T*, N32路T*, N32路T*);
-    N32路Status (*arithmetic_shift_right)(Extent, N32路T*, N32路T*);
-
-    N32路T* (*access)(N32路T*, Extent);
-    void (*from_uint32)(N32路T *destination ,uint32_t value);
-  } N32路螞;
-
-  Local const N32路螞 N32路位; // initialized in the LOCAL section
-
-#endif
-
-//--------------------------------------------------------------------------------
-// Implementation
-
-#ifdef N32路IMPLEMENTATION
-
-  // this part goes into the library
-  #ifndef LOCAL
-
-    #include <stdarg.h>
-    #include <stdlib.h>
-
-    struct N32路T{
-      Digit d0;
-    };
-
-    N32路T N32路constant[4] = {
-      {.d0 = 0},
-      {.d0 = 1},
-      {.d0 = ~(uint32_t)0},
-      {.d0 = 1 << 31}
-    };
-
-    N32路T *N32路zero = &N32路constant[0];
-    N32路T *N32路one = &N32路constant[1];
-    N32路T *N32路all_one_bit = &N32路constant[2];
-    N32路T *N32路msb = &N32路constant[3];
-    N32路T *N32路lsb = &N32路constant[1];
-
-    // the allocate an array of N32
-    N32路T *N32路allocate_array(Extent extent ,N32路Allocate_MemoryFault memory_fault){
-      N32路T *instance = malloc((extent + 1) * sizeof(N32路T) );
-      if(!instance){
-        return memory_fault ? memory_fault(extent) : NULL;
-      }
-      return instance;
-    }
-
-    N32路T *N32路allocate_array_zero(Extent extent ,N32路Allocate_MemoryFault memory_fault){
-      N32路T *instance = calloc( extent + 1 ,sizeof(N32路T) );
-      if(!instance){
-        return memory_fault ? memory_fault(extent) : NULL;
-      }
-      return instance;
-    }
-
-    void N32路deallocate(N32路T *unencumbered){
-      free(unencumbered);
-    }
-
-  #endif
-
-  // This part is included after the library user's code
-  #ifdef LOCAL
-
-    // instance
-
-    struct N32路T{
-      Digit d0;
-    };
-
-    // 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 N32路T N32路t[4];
-
-
-    // allocation 
-
-    extern N32路T *N32路allocate_array(Extent, N32路Allocate_MemoryFault);
-    extern N32路T *N32路allocate_array_zero(Extent, N32路Allocate_MemoryFault);
-    extern void N32路deallocate(N32路T *);
-
-    // so the user can access numbers in an array allocation
-    Local N32路T* N32路access(N32路T *array ,Extent index){
-      return &array[index];
-    }
-
-    Local void N32路from_uint32(N32路T *destination ,uint32_t value){
-      if(destination == NULL) return;
-      destination->d0 = value;
-    }
-
-    // copy, convenience copy
-
-    Local void N32路copy(N32路T *destination ,N32路T *source){
-      if(source == destination) return; // that was easy! 
-      *destination = *source;
-    }
-
-    Local void N32路set_to_zero(N32路T *instance){
-      instance->d0 = 0;
-    }
-
-    Local void N32路set_to_one(N32路T *instance){
-      instance->d0 = 1;
-    }
-
-    // bit operations
-
-    Local void N32路bit_and(N32路T *result, N32路T *a, N32路T *b){
-      result->d0 = a->d0 & b->d0;
-    }
-
-    // result can be one of the operands
-    Local void N32路bit_or(N32路T *result, N32路T *a, N32路T *b){
-      result->d0 = a->d0 | b->d0;
-    }
-
-    // result can the same as the operand
-    Local void N32路bit_complement(N32路T *result, N32路T *a){
-      result->d0 = ~a->d0;
-    }
-
-    // result can the same as the operand
-    Local void N32路bit_twos_complement(N32路T *result ,N32路T *a){
-      result->d0 = ~a->d0 + 1;
-    }
-
-    // test functions
-
-    Local N32路Order N32路compare(N32路T *a, N32路T *b){
-      if(a->d0 < b->d0) return N32路Order_lt;
-      if(a->d0 > b->d0) return N32路Order_gt;
-      return N32路Order_eq;
-    }
-
-    Local bool N32路lt(N32路T *a ,N32路T *b){
-      return  a->d0 < b->d0;
-    }    
-
-    Local bool N32路gt(N32路T *a ,N32路T *b){
-      return  a->d0 > b->d0;
-    }    
-
-    Local bool N32路eq(N32路T *a ,N32路T *b){
-      return  a->d0 == b->d0;
-    }    
-
-    Local bool N32路eq_zero(N32路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 N32路Status路accumulator1_overflow
-    //
-    // When accumulator1 and accumulator0 point to the same location, the result is the accumulator1 value.
-    Local N32路Status N32路accumulate(N32路T *accumulator1 ,N32路T *accumulator0 ,...){
-
-      va_list args;
-      va_start(args ,accumulator0);
-      uint32_t sum = accumulator0->d0;
-      uint32_t carry = 0;
-      N32路T *current;
-
-      while( (current = va_arg(args ,N32路T *)) ){
-        sum += current->d0;
-        if(sum < current->d0){  // Accumulator1 into carry
-          (carry)++;
-          if(carry == 0){
-            va_end(args);
-            return N32路Status路accumulator1_overflow;
-          }
-        }
-      }
-      va_end(args);
-
-      // wipes out prior value of accumulator1
-      accumulator1->d0 = carry;
-
-      return N32路Status路ok;
-    }
-
-    Local N32路Status N32路add(N32路T *sum ,N32路T *a ,N32路T *b){
-      uint64_t result = (uint64_t)a->d0 + (uint64_t)b->d0;
-      sum->d0 = (uint32_t)result;
-      return (result >> 32) ? N32路Status路carry : N32路Status路ok;
-    }
-
-    Local bool N32路increment(N32路T *a){
-      a->d0++;
-      return a->d0 == 0;
-    }
-
-    Local N32路Status N32路subtract(N32路T *difference ,N32路T *a ,N32路T *b){
-      uint64_t diff = (uint64_t) a->d0 - (uint64_t) b->d0;
-      difference->d0 = (uint32_t)diff;
-      return (diff > a->d0) ? N32路Status路borrow : N32路Status路ok;
-    }
-
-
-    Local N32路Status N32路multiply(N32路T *product1 ,N32路T *product0 ,N32路T *a ,N32路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 N32路Status路one_word_product;
-      return N32路Status路two_word_product;
-    }
-
-    Local N32路Status N32路divide(N32路T *remainder ,N32路T *quotient ,N32路T *a ,N32路T *b){
-      if(b->d0 == 0) return N32路Status路undefined_divide_by_zero; 
-
-      quotient->d0 = a->d0 / b->d0;
-      remainder->d0 = a->d0 - (quotient->d0 * b->d0);
-
-      return N32路Status路ok;
-    }
-
-    Local N32路Status N32路modulus(N32路T *remainder ,N32路T *a ,N32路T *b){
-      if(b->d0 == 0) return N32路Status路undefined_modulus_zero; 
-      uint32_t quotient = a->d0 / b->d0;
-      remainder->d0 = a->d0 - (quotient * b->d0);
-      return N32路Status路ok;
-    }
-
-    // bit motion
-
-    typedef uint32_t (*ShiftOp)(uint32_t, uint32_t);
-
-    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){
-      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 N32路Status N32路shift
-    (
-     uint32_t shift_count
-     ,N32路T *spill
-     ,N32路T *operand
-     ,N32路T *fill
-     ,ShiftOp shift_op
-     ,ShiftOp complement_shift_op
-     ){
-
-      // If no result is needed, return immediately.
-      if(operand == NULL && spill == NULL) return N32路Status路ok;
-
-      // Treat NULL operand as zero.
-      if(operand == NULL){
-        operand = &N32路t[0];
-        N32路copy(operand, N32路zero);
-      }
-
-      // Shifting more than one word breaks our fill/spill model.
-      if(shift_count > 31) return N32路Status路gt_max_shift_count;
-
-      // The given operand is still required after it is modified, so we copy it.
-      N32路T *given_operand = &N32路t[1];
-      N32路copy(given_operand, operand);
-
-      // Perform the shift
-      operand->d0 = shift_op(given_operand->d0, shift_count);
-      if(fill != NULL){
-        fill->d0 = complement_shift_op(fill->d0, (32 - shift_count));
-        N32路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 N32路Status路ok;
-    }
-
-    // Define concrete shift functions using valid C function pointers
-    Local N32路Status 
-    N32路shift_left(uint32_t shift_count, N32路T *spill, N32路T *operand, N32路T *fill){
-      return N32路shift(shift_count, spill, operand, fill, shift_left_op, shift_right_op);
-    }
-
-    Local N32路Status 
-    N32路shift_right(uint32_t shift_count, N32路T *spill, N32路T *operand, N32路T *fill){
-      return N32路shift(shift_count, spill, operand, fill, shift_right_op, shift_left_op);
-    }
-
-    Local N32路Status 
-    N32路arithmetic_shift_right(uint32_t shift_count, N32路T *operand, N32路T *spill){
-
-      // Guard against excessive shift counts
-      if(shift_count > 31) return N32路Status路gt_max_shift_count;
-
-      // A NULL operand is treated as zero
-      if(operand == NULL){
-        operand = &N32路t[0];
-        N32路copy(operand, N32路zero);
-      }
-
-      // Pick the fill value based on the sign bit
-      N32路T *fill = (operand->d0 & 0x80000000) ? N32路all_one_bit : N32路zero;
-
-      // Call shift_right with the appropriate fill
-      return N32路shift_right(shift_count, spill, operand, fill);
-    }
-
-    Local const N32路螞 N32路位 = {
-
-      .allocate_array = N32路allocate_array
-      ,.allocate_array_zero = N32路allocate_array_zero
-      ,.deallocate = N32路deallocate
-
-      ,.copy = N32路copy
-      ,.bit_and = N32路bit_and
-      ,.bit_or = N32路bit_or
-      ,.bit_complement = N32路bit_complement
-      ,.bit_twos_complement = N32路bit_twos_complement
-      ,.compare = N32路compare
-      ,.lt = N32路lt
-      ,.gt = N32路gt
-      ,.eq = N32路eq
-      ,.eq_zero = N32路eq_zero
-      ,.accumulate = N32路accumulate
-      ,.add = N32路add
-      ,.increment = N32路increment
-      ,.subtract = N32路subtract
-      ,.multiply = N32路multiply
-      ,.divide = N32路divide
-      ,.modulus = N32路modulus
-      ,.shift_left = N32路shift_left
-      ,.shift_right = N32路shift_right
-      ,.arithmetic_shift_right = N32路arithmetic_shift_right
-
-      ,.access = N32路access
-      ,.from_uint32 = N32路from_uint32
-    };
-
-  #endif
-
-#endif
diff --git a/tester/cc/test_N32PN.cli.c b/tester/cc/test_N32PN.cli.c
new file mode 100644 (file)
index 0000000..e17581a
--- /dev/null
@@ -0,0 +1,364 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <setjmp.h>
+
+// Enable interface section
+#define FACE
+#include "N32PN.lib.c"
+#undef FACE
+
+// Jump buffer for signal handling
+static sigjmp_buf jump_buffer;
+
+// Signal handler for catching fatal errors
+void signal_handler(int signal){
+  siglongjmp(jump_buffer ,1); // Jump back to test_head on error
+}
+
+// Test function prototypes
+bool test_copy();
+bool test_bitwise_operations();
+bool test_comparisons();
+bool test_arithmetic();
+bool test_shifts();
+
+// Test array (null-terminated)
+typedef bool (*TestFunction)();
+typedef struct{
+  TestFunction function;
+  const char *name;
+}TestEntry;
+
+TestEntry test_list[] = {
+   {test_copy ,"test_copy"}
+  ,{test_bitwise_operations ,"test_bitwise_operations"}
+  ,{test_comparisons ,"test_comparisons"}
+  ,{test_arithmetic ,"test_arithmetic"}
+  ,{test_shifts ,"test_shifts"}
+  ,{NULL ,NULL}  // Null termination
+};
+
+// The test runner
+int test_head(){
+  int pass_count = 0;
+  int fail_count = 0;
+
+  // Set up signal handlers
+  signal(SIGSEGV ,signal_handler);  // Catch segmentation faults
+  signal(SIGFPE ,signal_handler);   // Catch floating point errors
+  signal(SIGABRT ,signal_handler);  // Catch abort() calls
+
+  for(TestEntry *entry = test_list; entry->function != NULL; entry++){
+    if( sigsetjmp(jump_buffer ,1) == 0 ){
+      // Run the test normally
+      if( !entry->function() ){
+        printf("Failed: %s\n" ,entry->name);
+        fail_count++;
+      }else{
+        pass_count++;
+      }
+    }else{
+      // If a signal was caught
+      printf("Failed due to signaling: %s\n" ,entry->name);
+      fail_count++;
+    }
+  }
+
+  printf("Tests passed: %d\n" ,pass_count);
+  printf("Tests failed: %d\n" ,fail_count);
+  return (fail_count == 0) ? 0 : 1;
+}
+
+// Main function
+int main(int argc ,char **argv){
+  return test_head();
+}
+
+//------------------------------------------------------------------------------
+// Test Implementations
+//------------------------------------------------------------------------------
+
+bool test_copy(){
+  // Allocate memory
+  N32PN路T *array = N32PN路位.allocate_array(2 ,NULL);
+  if( !array ) return false;
+
+  // Access elements via access function
+  N32PN路T *a = N32PN路位.access(array ,0);
+  N32PN路T *b = N32PN路位.access(array ,1);
+
+  // Assign value and copy
+  N32PN路位.from_uint32(a ,42);
+  N32PN路位.copy(b ,a);
+
+  bool success = ( N32PN路位.compare(b ,a) == N32PN路Order_eq );
+  N32PN路位.deallocate(array);
+  return success;
+}
+
+bool test_arithmetic(){
+  // Allocate memory
+  N32PN路T *array = N32PN路位.allocate_array(3 ,NULL);
+  if( !array ) return false;
+
+  N32PN路T *a = N32PN路位.access(array ,0);
+  N32PN路T *b = N32PN路位.access(array ,1);
+  N32PN路T *result = N32PN路位.access(array ,2);
+
+  N32PN路位.from_uint32(a ,20);
+  N32PN路位.from_uint32(b ,22);
+
+  if( N32PN路位.add(result ,a ,b) != N32PN路Status路ok ) return false;
+  if( N32PN路位.compare(result ,N32PN路位.access(array ,0)) != N32PN路Order_gt ) return false;
+
+  if( N32PN路位.subtract(result ,b ,a) != N32PN路Status路ok ) return false;
+  if( N32PN路位.compare(result ,N32PN路位.access(array ,0)) != N32PN路Order_lt ) return false;
+
+  N32PN路位.deallocate(array);
+  return true;
+}
+
+bool test_bitwise_operations(){
+  // Allocate memory
+  N32PN路T *array = N32PN路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  N32PN路T *a = N32PN路位.access(array, 0);
+  N32PN路T *b = N32PN路位.access(array, 1);
+  N32PN路T *result = N32PN路位.access(array, 2);
+
+  // a = 0x0F0F0F0F, b = 0xF0F0F0F0
+  N32PN路位.from_uint32(a, 0x0F0F0F0F);
+  N32PN路位.from_uint32(b, 0xF0F0F0F0);
+
+  // bit_and => expect 0x00000000
+  N32PN路位.bit_and(result, a, b);
+  N32PN路位.from_uint32(a, 0x00000000);
+  if(N32PN路位.compare(result, a) != N32PN路Order_eq){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  // Reset a to 0x0F0F0F0F for next tests
+  N32PN路位.from_uint32(a, 0x0F0F0F0F);
+
+  // bit_or => expect 0xFFFFFFFF
+  N32PN路位.bit_or(result, a, b);
+  N32PN路位.from_uint32(b, 0xFFFFFFFF);
+  if(N32PN路位.compare(result, b) != N32PN路Order_eq){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  // bit_complement(a=0x0F0F0F0F) => expect 0xF0F0F0F0
+  N32PN路位.from_uint32(a, 0x0F0F0F0F);
+  N32PN路位.bit_complement(result, a);
+  N32PN路位.from_uint32(b, 0xF0F0F0F0);
+  if(N32PN路位.compare(result, b) != N32PN路Order_eq){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  // bit_twos_complement(a=0x0F0F0F0F) => expect 0xF0F0F0F1
+  N32PN路位.from_uint32(a, 0x0F0F0F0F);
+  N32PN路位.bit_twos_complement(result, a);
+  N32PN路位.from_uint32(b, 0xF0F0F0F1);
+  if(N32PN路位.compare(result, b) != N32PN路Order_eq){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  N32PN路位.deallocate(array);
+  return true;
+}
+
+bool test_comparisons(){
+  // Allocate memory
+  N32PN路T *array = N32PN路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  N32PN路T *a = N32PN路位.access(array, 0);
+  N32PN路T *b = N32PN路位.access(array, 1);
+  N32PN路T *c = N32PN路位.access(array, 2);
+
+  // First set: a=0, b=42, c=42
+  N32PN路位.from_uint32(a, 0);
+  N32PN路位.from_uint32(b, 42);
+  N32PN路位.from_uint32(c, 42);
+
+  // eq_zero(a) => true
+  if(!N32PN路位.eq_zero(a)){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // eq_zero(b) => false
+  if(N32PN路位.eq_zero(b)){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // eq(b, c) => true
+  if(!N32PN路位.eq(b, c)){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // eq(a, b) => false
+  if(N32PN路位.eq(a, b)){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // compare(a, b) => N32PN路Order_lt
+  if(N32PN路位.compare(a, b) != N32PN路Order_lt){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // compare(b, a) => N32PN路Order_gt
+  if(N32PN路位.compare(b, a) != N32PN路Order_gt){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // compare(b, c) => N32PN路Order_eq
+  if(N32PN路位.compare(b, c) != N32PN路Order_eq){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // lt(a, b) => true, gt(b, a) => true
+  if(!N32PN路位.lt(a, b) || !N32PN路位.gt(b, a)){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  // Second set: a=100, b=50
+  N32PN路位.from_uint32(a, 100);
+  N32PN路位.from_uint32(b, 50);
+  if(N32PN路位.compare(a, b) != N32PN路Order_gt){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // eq_zero(a) => false
+  if(N32PN路位.eq_zero(a)){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  // eq_zero(b) => false
+  if(N32PN路位.eq_zero(b)){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  N32PN路位.deallocate(array);
+  return true;
+}
+
+bool test_shifts(){
+  // Allocate memory for operand, fill, spill
+  N32PN路T *array = N32PN路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  N32PN路T *operand = N32PN路位.access(array, 0);
+  N32PN路T *fill    = N32PN路位.access(array, 1);
+  N32PN路T *spill   = N32PN路位.access(array, 2);
+
+  // Subtest A: shift_left(4) with operand=1 => expect operand=16, fill=0, spill=0
+  N32PN路位.from_uint32(operand, 1);
+  N32PN路位.from_uint32(fill, 0);
+  N32PN路位.from_uint32(spill, 0);
+  if(N32PN路位.shift_left(4, spill, operand, fill) != N32PN路Status路ok){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  N32PN路T *temp = N32PN路位.allocate_array(1, NULL);
+  if(!temp){
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  N32PN路位.from_uint32(temp, 16);
+  if(N32PN路位.compare(operand, temp) != N32PN路Order_eq){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  if(N32PN路位.compare(fill, N32PN路zero) != N32PN路Order_eq){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  if(N32PN路位.compare(spill, N32PN路zero) != N32PN路Order_eq){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  // Subtest B: shift_left(1) with operand=0x80000000 => expect operand=0, spill=1
+  N32PN路位.from_uint32(operand, 0x80000000);
+  N32PN路位.from_uint32(fill, 0);
+  N32PN路位.from_uint32(spill, 0);
+  if(N32PN路位.shift_left(1, spill, operand, fill) != N32PN路Status路ok){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  if(!N32PN路位.eq_zero(operand)){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  N32PN路位.from_uint32(temp, 1);
+  if(N32PN路位.compare(spill, temp) != N32PN路Order_eq){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  // Subtest C: shift_right(1) with operand=0x80000000 => expect operand=0x40000000, spill=0
+  N32PN路位.from_uint32(operand, 0x80000000);
+  N32PN路位.from_uint32(fill, 0);
+  N32PN路位.from_uint32(spill, 0);
+  if(N32PN路位.shift_right(1, spill, operand, fill) != N32PN路Status路ok){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  N32PN路位.from_uint32(temp, 0x40000000);
+  if(N32PN路位.compare(operand, temp) != N32PN路Order_eq){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  if(!N32PN路位.eq_zero(spill)){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  // Subtest D: arithmetic_shift_right(1) with operand=0x80000000 => expect operand=0xC0000000, spill=0
+  N32PN路位.from_uint32(operand, 0x80000000);
+  N32PN路位.from_uint32(spill, 0);
+  if(N32PN路位.arithmetic_shift_right(1, operand, spill) != N32PN路Status路ok){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  N32PN路位.from_uint32(temp, 0xC0000000);
+  if(N32PN路位.compare(operand, temp) != N32PN路Order_eq){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+  if(!N32PN路位.eq_zero(spill)){
+    N32PN路位.deallocate(temp);
+    N32PN路位.deallocate(array);
+    return false;
+  }
+
+  N32PN路位.deallocate(temp);
+  N32PN路位.deallocate(array);
+  return true;
+}
+
+
+
+// Include the local section of N32PN.lib.c for testing
+#define LOCAL
+#include "N32PN.lib.c"
+#undef LOCAL
diff --git a/tester/cc馃枆/test_N32.cli.c b/tester/cc馃枆/test_N32.cli.c
deleted file mode 100644 (file)
index 563711f..0000000
+++ /dev/null
@@ -1,364 +0,0 @@
-#include <stdio.h>
-#include <stdbool.h>
-#include <signal.h>
-#include <setjmp.h>
-
-// Enable interface section
-#define FACE
-#include "N32.lib.c"
-#undef FACE
-
-// Jump buffer for signal handling
-static sigjmp_buf jump_buffer;
-
-// Signal handler for catching fatal errors
-void signal_handler(int signal){
-  siglongjmp(jump_buffer ,1); // Jump back to test_head on error
-}
-
-// Test function prototypes
-bool test_copy();
-bool test_bitwise_operations();
-bool test_comparisons();
-bool test_arithmetic();
-bool test_shifts();
-
-// Test array (null-terminated)
-typedef bool (*TestFunction)();
-typedef struct{
-  TestFunction function;
-  const char *name;
-}TestEntry;
-
-TestEntry test_list[] = {
-   {test_copy ,"test_copy"}
-  ,{test_bitwise_operations ,"test_bitwise_operations"}
-  ,{test_comparisons ,"test_comparisons"}
-  ,{test_arithmetic ,"test_arithmetic"}
-  ,{test_shifts ,"test_shifts"}
-  ,{NULL ,NULL}  // Null termination
-};
-
-// The test runner
-int test_head(){
-  int pass_count = 0;
-  int fail_count = 0;
-
-  // Set up signal handlers
-  signal(SIGSEGV ,signal_handler);  // Catch segmentation faults
-  signal(SIGFPE ,signal_handler);   // Catch floating point errors
-  signal(SIGABRT ,signal_handler);  // Catch abort() calls
-
-  for(TestEntry *entry = test_list; entry->function != NULL; entry++){
-    if( sigsetjmp(jump_buffer ,1) == 0 ){
-      // Run the test normally
-      if( !entry->function() ){
-        printf("Failed: %s\n" ,entry->name);
-        fail_count++;
-      }else{
-        pass_count++;
-      }
-    }else{
-      // If a signal was caught
-      printf("Failed due to signaling: %s\n" ,entry->name);
-      fail_count++;
-    }
-  }
-
-  printf("Tests passed: %d\n" ,pass_count);
-  printf("Tests failed: %d\n" ,fail_count);
-  return (fail_count == 0) ? 0 : 1;
-}
-
-// Main function
-int main(int argc ,char **argv){
-  return test_head();
-}
-
-//------------------------------------------------------------------------------
-// Test Implementations
-//------------------------------------------------------------------------------
-
-bool test_copy(){
-  // Allocate memory
-  N32路T *array = N32路位.allocate_array(2 ,NULL);
-  if( !array ) return false;
-
-  // Access elements via access function
-  N32路T *a = N32路位.access(array ,0);
-  N32路T *b = N32路位.access(array ,1);
-
-  // Assign value and copy
-  N32路位.from_uint32(a ,42);
-  N32路位.copy(b ,a);
-
-  bool success = ( N32路位.compare(b ,a) == N32路Order_eq );
-  N32路位.deallocate(array);
-  return success;
-}
-
-bool test_arithmetic(){
-  // Allocate memory
-  N32路T *array = N32路位.allocate_array(3 ,NULL);
-  if( !array ) return false;
-
-  N32路T *a = N32路位.access(array ,0);
-  N32路T *b = N32路位.access(array ,1);
-  N32路T *result = N32路位.access(array ,2);
-
-  N32路位.from_uint32(a ,20);
-  N32路位.from_uint32(b ,22);
-
-  if( N32路位.add(result ,a ,b) != N32路Status路ok ) return false;
-  if( N32路位.compare(result ,N32路位.access(array ,0)) != N32路Order_gt ) return false;
-
-  if( N32路位.subtract(result ,b ,a) != N32路Status路ok ) return false;
-  if( N32路位.compare(result ,N32路位.access(array ,0)) != N32路Order_lt ) return false;
-
-  N32路位.deallocate(array);
-  return true;
-}
-
-bool test_bitwise_operations(){
-  // Allocate memory
-  N32路T *array = N32路位.allocate_array(3, NULL);
-  if(!array) return false;
-
-  N32路T *a = N32路位.access(array, 0);
-  N32路T *b = N32路位.access(array, 1);
-  N32路T *result = N32路位.access(array, 2);
-
-  // a = 0x0F0F0F0F, b = 0xF0F0F0F0
-  N32路位.from_uint32(a, 0x0F0F0F0F);
-  N32路位.from_uint32(b, 0xF0F0F0F0);
-
-  // bit_and => expect 0x00000000
-  N32路位.bit_and(result, a, b);
-  N32路位.from_uint32(a, 0x00000000);
-  if(N32路位.compare(result, a) != N32路Order_eq){
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  // Reset a to 0x0F0F0F0F for next tests
-  N32路位.from_uint32(a, 0x0F0F0F0F);
-
-  // bit_or => expect 0xFFFFFFFF
-  N32路位.bit_or(result, a, b);
-  N32路位.from_uint32(b, 0xFFFFFFFF);
-  if(N32路位.compare(result, b) != N32路Order_eq){
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  // bit_complement(a=0x0F0F0F0F) => expect 0xF0F0F0F0
-  N32路位.from_uint32(a, 0x0F0F0F0F);
-  N32路位.bit_complement(result, a);
-  N32路位.from_uint32(b, 0xF0F0F0F0);
-  if(N32路位.compare(result, b) != N32路Order_eq){
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  // bit_twos_complement(a=0x0F0F0F0F) => expect 0xF0F0F0F1
-  N32路位.from_uint32(a, 0x0F0F0F0F);
-  N32路位.bit_twos_complement(result, a);
-  N32路位.from_uint32(b, 0xF0F0F0F1);
-  if(N32路位.compare(result, b) != N32路Order_eq){
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  N32路位.deallocate(array);
-  return true;
-}
-
-bool test_comparisons(){
-  // Allocate memory
-  N32路T *array = N32路位.allocate_array(3, NULL);
-  if(!array) return false;
-
-  N32路T *a = N32路位.access(array, 0);
-  N32路T *b = N32路位.access(array, 1);
-  N32路T *c = N32路位.access(array, 2);
-
-  // First set: a=0, b=42, c=42
-  N32路位.from_uint32(a, 0);
-  N32路位.from_uint32(b, 42);
-  N32路位.from_uint32(c, 42);
-
-  // eq_zero(a) => true
-  if(!N32路位.eq_zero(a)){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // eq_zero(b) => false
-  if(N32路位.eq_zero(b)){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // eq(b, c) => true
-  if(!N32路位.eq(b, c)){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // eq(a, b) => false
-  if(N32路位.eq(a, b)){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // compare(a, b) => N32路Order_lt
-  if(N32路位.compare(a, b) != N32路Order_lt){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // compare(b, a) => N32路Order_gt
-  if(N32路位.compare(b, a) != N32路Order_gt){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // compare(b, c) => N32路Order_eq
-  if(N32路位.compare(b, c) != N32路Order_eq){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // lt(a, b) => true, gt(b, a) => true
-  if(!N32路位.lt(a, b) || !N32路位.gt(b, a)){
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  // Second set: a=100, b=50
-  N32路位.from_uint32(a, 100);
-  N32路位.from_uint32(b, 50);
-  if(N32路位.compare(a, b) != N32路Order_gt){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // eq_zero(a) => false
-  if(N32路位.eq_zero(a)){
-    N32路位.deallocate(array);
-    return false;
-  }
-  // eq_zero(b) => false
-  if(N32路位.eq_zero(b)){
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  N32路位.deallocate(array);
-  return true;
-}
-
-bool test_shifts(){
-  // Allocate memory for operand, fill, spill
-  N32路T *array = N32路位.allocate_array(3, NULL);
-  if(!array) return false;
-
-  N32路T *operand = N32路位.access(array, 0);
-  N32路T *fill    = N32路位.access(array, 1);
-  N32路T *spill   = N32路位.access(array, 2);
-
-  // Subtest A: shift_left(4) with operand=1 => expect operand=16, fill=0, spill=0
-  N32路位.from_uint32(operand, 1);
-  N32路位.from_uint32(fill, 0);
-  N32路位.from_uint32(spill, 0);
-  if(N32路位.shift_left(4, spill, operand, fill) != N32路Status路ok){
-    N32路位.deallocate(array);
-    return false;
-  }
-  N32路T *temp = N32路位.allocate_array(1, NULL);
-  if(!temp){
-    N32路位.deallocate(array);
-    return false;
-  }
-  N32路位.from_uint32(temp, 16);
-  if(N32路位.compare(operand, temp) != N32路Order_eq){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-  if(N32路位.compare(fill, N32路zero) != N32路Order_eq){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-  if(N32路位.compare(spill, N32路zero) != N32路Order_eq){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  // Subtest B: shift_left(1) with operand=0x80000000 => expect operand=0, spill=1
-  N32路位.from_uint32(operand, 0x80000000);
-  N32路位.from_uint32(fill, 0);
-  N32路位.from_uint32(spill, 0);
-  if(N32路位.shift_left(1, spill, operand, fill) != N32路Status路ok){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-  if(!N32路位.eq_zero(operand)){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-  N32路位.from_uint32(temp, 1);
-  if(N32路位.compare(spill, temp) != N32路Order_eq){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  // Subtest C: shift_right(1) with operand=0x80000000 => expect operand=0x40000000, spill=0
-  N32路位.from_uint32(operand, 0x80000000);
-  N32路位.from_uint32(fill, 0);
-  N32路位.from_uint32(spill, 0);
-  if(N32路位.shift_right(1, spill, operand, fill) != N32路Status路ok){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-  N32路位.from_uint32(temp, 0x40000000);
-  if(N32路位.compare(operand, temp) != N32路Order_eq){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-  if(!N32路位.eq_zero(spill)){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  // Subtest D: arithmetic_shift_right(1) with operand=0x80000000 => expect operand=0xC0000000, spill=0
-  N32路位.from_uint32(operand, 0x80000000);
-  N32路位.from_uint32(spill, 0);
-  if(N32路位.arithmetic_shift_right(1, operand, spill) != N32路Status路ok){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-  N32路位.from_uint32(temp, 0xC0000000);
-  if(N32路位.compare(operand, temp) != N32路Order_eq){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-  if(!N32路位.eq_zero(spill)){
-    N32路位.deallocate(temp);
-    N32路位.deallocate(array);
-    return false;
-  }
-
-  N32路位.deallocate(temp);
-  N32路位.deallocate(array);
-  return true;
-}
-
-
-
-// Include the local section of N32.lib.c for testing
-#define LOCAL
-#include "N32.lib.c"
-#undef LOCAL
diff --git a/tester/deprecated馃枆/test_N32.cli.c b/tester/deprecated馃枆/test_N32.cli.c
new file mode 100644 (file)
index 0000000..563711f
--- /dev/null
@@ -0,0 +1,364 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <setjmp.h>
+
+// Enable interface section
+#define FACE
+#include "N32.lib.c"
+#undef FACE
+
+// Jump buffer for signal handling
+static sigjmp_buf jump_buffer;
+
+// Signal handler for catching fatal errors
+void signal_handler(int signal){
+  siglongjmp(jump_buffer ,1); // Jump back to test_head on error
+}
+
+// Test function prototypes
+bool test_copy();
+bool test_bitwise_operations();
+bool test_comparisons();
+bool test_arithmetic();
+bool test_shifts();
+
+// Test array (null-terminated)
+typedef bool (*TestFunction)();
+typedef struct{
+  TestFunction function;
+  const char *name;
+}TestEntry;
+
+TestEntry test_list[] = {
+   {test_copy ,"test_copy"}
+  ,{test_bitwise_operations ,"test_bitwise_operations"}
+  ,{test_comparisons ,"test_comparisons"}
+  ,{test_arithmetic ,"test_arithmetic"}
+  ,{test_shifts ,"test_shifts"}
+  ,{NULL ,NULL}  // Null termination
+};
+
+// The test runner
+int test_head(){
+  int pass_count = 0;
+  int fail_count = 0;
+
+  // Set up signal handlers
+  signal(SIGSEGV ,signal_handler);  // Catch segmentation faults
+  signal(SIGFPE ,signal_handler);   // Catch floating point errors
+  signal(SIGABRT ,signal_handler);  // Catch abort() calls
+
+  for(TestEntry *entry = test_list; entry->function != NULL; entry++){
+    if( sigsetjmp(jump_buffer ,1) == 0 ){
+      // Run the test normally
+      if( !entry->function() ){
+        printf("Failed: %s\n" ,entry->name);
+        fail_count++;
+      }else{
+        pass_count++;
+      }
+    }else{
+      // If a signal was caught
+      printf("Failed due to signaling: %s\n" ,entry->name);
+      fail_count++;
+    }
+  }
+
+  printf("Tests passed: %d\n" ,pass_count);
+  printf("Tests failed: %d\n" ,fail_count);
+  return (fail_count == 0) ? 0 : 1;
+}
+
+// Main function
+int main(int argc ,char **argv){
+  return test_head();
+}
+
+//------------------------------------------------------------------------------
+// Test Implementations
+//------------------------------------------------------------------------------
+
+bool test_copy(){
+  // Allocate memory
+  N32路T *array = N32路位.allocate_array(2 ,NULL);
+  if( !array ) return false;
+
+  // Access elements via access function
+  N32路T *a = N32路位.access(array ,0);
+  N32路T *b = N32路位.access(array ,1);
+
+  // Assign value and copy
+  N32路位.from_uint32(a ,42);
+  N32路位.copy(b ,a);
+
+  bool success = ( N32路位.compare(b ,a) == N32路Order_eq );
+  N32路位.deallocate(array);
+  return success;
+}
+
+bool test_arithmetic(){
+  // Allocate memory
+  N32路T *array = N32路位.allocate_array(3 ,NULL);
+  if( !array ) return false;
+
+  N32路T *a = N32路位.access(array ,0);
+  N32路T *b = N32路位.access(array ,1);
+  N32路T *result = N32路位.access(array ,2);
+
+  N32路位.from_uint32(a ,20);
+  N32路位.from_uint32(b ,22);
+
+  if( N32路位.add(result ,a ,b) != N32路Status路ok ) return false;
+  if( N32路位.compare(result ,N32路位.access(array ,0)) != N32路Order_gt ) return false;
+
+  if( N32路位.subtract(result ,b ,a) != N32路Status路ok ) return false;
+  if( N32路位.compare(result ,N32路位.access(array ,0)) != N32路Order_lt ) return false;
+
+  N32路位.deallocate(array);
+  return true;
+}
+
+bool test_bitwise_operations(){
+  // Allocate memory
+  N32路T *array = N32路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  N32路T *a = N32路位.access(array, 0);
+  N32路T *b = N32路位.access(array, 1);
+  N32路T *result = N32路位.access(array, 2);
+
+  // a = 0x0F0F0F0F, b = 0xF0F0F0F0
+  N32路位.from_uint32(a, 0x0F0F0F0F);
+  N32路位.from_uint32(b, 0xF0F0F0F0);
+
+  // bit_and => expect 0x00000000
+  N32路位.bit_and(result, a, b);
+  N32路位.from_uint32(a, 0x00000000);
+  if(N32路位.compare(result, a) != N32路Order_eq){
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  // Reset a to 0x0F0F0F0F for next tests
+  N32路位.from_uint32(a, 0x0F0F0F0F);
+
+  // bit_or => expect 0xFFFFFFFF
+  N32路位.bit_or(result, a, b);
+  N32路位.from_uint32(b, 0xFFFFFFFF);
+  if(N32路位.compare(result, b) != N32路Order_eq){
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  // bit_complement(a=0x0F0F0F0F) => expect 0xF0F0F0F0
+  N32路位.from_uint32(a, 0x0F0F0F0F);
+  N32路位.bit_complement(result, a);
+  N32路位.from_uint32(b, 0xF0F0F0F0);
+  if(N32路位.compare(result, b) != N32路Order_eq){
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  // bit_twos_complement(a=0x0F0F0F0F) => expect 0xF0F0F0F1
+  N32路位.from_uint32(a, 0x0F0F0F0F);
+  N32路位.bit_twos_complement(result, a);
+  N32路位.from_uint32(b, 0xF0F0F0F1);
+  if(N32路位.compare(result, b) != N32路Order_eq){
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  N32路位.deallocate(array);
+  return true;
+}
+
+bool test_comparisons(){
+  // Allocate memory
+  N32路T *array = N32路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  N32路T *a = N32路位.access(array, 0);
+  N32路T *b = N32路位.access(array, 1);
+  N32路T *c = N32路位.access(array, 2);
+
+  // First set: a=0, b=42, c=42
+  N32路位.from_uint32(a, 0);
+  N32路位.from_uint32(b, 42);
+  N32路位.from_uint32(c, 42);
+
+  // eq_zero(a) => true
+  if(!N32路位.eq_zero(a)){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // eq_zero(b) => false
+  if(N32路位.eq_zero(b)){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // eq(b, c) => true
+  if(!N32路位.eq(b, c)){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // eq(a, b) => false
+  if(N32路位.eq(a, b)){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // compare(a, b) => N32路Order_lt
+  if(N32路位.compare(a, b) != N32路Order_lt){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // compare(b, a) => N32路Order_gt
+  if(N32路位.compare(b, a) != N32路Order_gt){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // compare(b, c) => N32路Order_eq
+  if(N32路位.compare(b, c) != N32路Order_eq){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // lt(a, b) => true, gt(b, a) => true
+  if(!N32路位.lt(a, b) || !N32路位.gt(b, a)){
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  // Second set: a=100, b=50
+  N32路位.from_uint32(a, 100);
+  N32路位.from_uint32(b, 50);
+  if(N32路位.compare(a, b) != N32路Order_gt){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // eq_zero(a) => false
+  if(N32路位.eq_zero(a)){
+    N32路位.deallocate(array);
+    return false;
+  }
+  // eq_zero(b) => false
+  if(N32路位.eq_zero(b)){
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  N32路位.deallocate(array);
+  return true;
+}
+
+bool test_shifts(){
+  // Allocate memory for operand, fill, spill
+  N32路T *array = N32路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  N32路T *operand = N32路位.access(array, 0);
+  N32路T *fill    = N32路位.access(array, 1);
+  N32路T *spill   = N32路位.access(array, 2);
+
+  // Subtest A: shift_left(4) with operand=1 => expect operand=16, fill=0, spill=0
+  N32路位.from_uint32(operand, 1);
+  N32路位.from_uint32(fill, 0);
+  N32路位.from_uint32(spill, 0);
+  if(N32路位.shift_left(4, spill, operand, fill) != N32路Status路ok){
+    N32路位.deallocate(array);
+    return false;
+  }
+  N32路T *temp = N32路位.allocate_array(1, NULL);
+  if(!temp){
+    N32路位.deallocate(array);
+    return false;
+  }
+  N32路位.from_uint32(temp, 16);
+  if(N32路位.compare(operand, temp) != N32路Order_eq){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+  if(N32路位.compare(fill, N32路zero) != N32路Order_eq){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+  if(N32路位.compare(spill, N32路zero) != N32路Order_eq){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  // Subtest B: shift_left(1) with operand=0x80000000 => expect operand=0, spill=1
+  N32路位.from_uint32(operand, 0x80000000);
+  N32路位.from_uint32(fill, 0);
+  N32路位.from_uint32(spill, 0);
+  if(N32路位.shift_left(1, spill, operand, fill) != N32路Status路ok){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+  if(!N32路位.eq_zero(operand)){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+  N32路位.from_uint32(temp, 1);
+  if(N32路位.compare(spill, temp) != N32路Order_eq){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  // Subtest C: shift_right(1) with operand=0x80000000 => expect operand=0x40000000, spill=0
+  N32路位.from_uint32(operand, 0x80000000);
+  N32路位.from_uint32(fill, 0);
+  N32路位.from_uint32(spill, 0);
+  if(N32路位.shift_right(1, spill, operand, fill) != N32路Status路ok){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+  N32路位.from_uint32(temp, 0x40000000);
+  if(N32路位.compare(operand, temp) != N32路Order_eq){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+  if(!N32路位.eq_zero(spill)){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  // Subtest D: arithmetic_shift_right(1) with operand=0x80000000 => expect operand=0xC0000000, spill=0
+  N32路位.from_uint32(operand, 0x80000000);
+  N32路位.from_uint32(spill, 0);
+  if(N32路位.arithmetic_shift_right(1, operand, spill) != N32路Status路ok){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+  N32路位.from_uint32(temp, 0xC0000000);
+  if(N32路位.compare(operand, temp) != N32路Order_eq){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+  if(!N32路位.eq_zero(spill)){
+    N32路位.deallocate(temp);
+    N32路位.deallocate(array);
+    return false;
+  }
+
+  N32路位.deallocate(temp);
+  N32路位.deallocate(array);
+  return true;
+}
+
+
+
+// Include the local section of N32.lib.c for testing
+#define LOCAL
+#include "N32.lib.c"
+#undef LOCAL
diff --git a/tester/python/#fill_templates.py# b/tester/python/#fill_templates.py#
new file mode 100644 (file)
index 0000000..95519a3
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+
+import sys
+from template_test_N32 import test_N32
+
+def write(code ,basename):
+    filepath = "../cc/" + "test_" + basename + ".cli.c" 
+    with open(filepath, "w") as f:
+      f.write(code)
+    print("Generated " + filepath)
+    
+
+def main():
+    """
+    generates `.c` source code from templates
+    """
+
+    # base line test N32 test
+    type_name = "N32PN"
+    code = test_N32(namespace = type_name)
+    write(code ,type_name);
+
+if __name__ == "__main__":
+    main()
diff --git a/tester/python/fill_template b/tester/python/fill_template
new file mode 100755 (executable)
index 0000000..95519a3
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+
+import sys
+from template_test_N32 import test_N32
+
+def write(code ,basename):
+    filepath = "../cc/" + "test_" + basename + ".cli.c" 
+    with open(filepath, "w") as f:
+      f.write(code)
+    print("Generated " + filepath)
+    
+
+def main():
+    """
+    generates `.c` source code from templates
+    """
+
+    # base line test N32 test
+    type_name = "N32PN"
+    code = test_N32(namespace = type_name)
+    write(code ,type_name);
+
+if __name__ == "__main__":
+    main()
diff --git a/tester/python/template_test_N32.py b/tester/python/template_test_N32.py
new file mode 100644 (file)
index 0000000..e2211d4
--- /dev/null
@@ -0,0 +1,381 @@
+# {NAMESPACE} must be a N32 type.
+#
+# test_N32 can be used to test any 32 bit natural number types. As examples: N32PN the processor native type; N32_4_by_8 a 32 bit natural number type made of 4 digits, where each digit is 8 bits.
+#
+
+def test_N32(namespace: str) -> str:
+    """
+    Returns a source code file for cc.
+    """
+    template = template_test_N32()
+    code = template.format(
+        NAMESPACE = namespace
+    )
+    return code
+
+def template_test_N32():
+    return r'''#include <stdio.h>
+#include <stdbool.h>
+#include <signal.h>
+#include <setjmp.h>
+
+// Enable interface section
+#define FACE
+#include "{NAMESPACE}.lib.c"
+#undef FACE
+
+// Jump buffer for signal handling
+static sigjmp_buf jump_buffer;
+
+// Signal handler for catching fatal errors
+void signal_handler(int signal){{
+  siglongjmp(jump_buffer ,1); // Jump back to test_head on error
+}}
+
+// Test function prototypes
+bool test_copy();
+bool test_bitwise_operations();
+bool test_comparisons();
+bool test_arithmetic();
+bool test_shifts();
+
+// Test array (null-terminated)
+typedef bool (*TestFunction)();
+typedef struct{{
+  TestFunction function;
+  const char *name;
+}}TestEntry;
+
+TestEntry test_list[] = {{
+   {{test_copy ,"test_copy"}}
+  ,{{test_bitwise_operations ,"test_bitwise_operations"}}
+  ,{{test_comparisons ,"test_comparisons"}}
+  ,{{test_arithmetic ,"test_arithmetic"}}
+  ,{{test_shifts ,"test_shifts"}}
+  ,{{NULL ,NULL}}  // Null termination
+}};
+
+// The test runner
+int test_head(){{
+  int pass_count = 0;
+  int fail_count = 0;
+
+  // Set up signal handlers
+  signal(SIGSEGV ,signal_handler);  // Catch segmentation faults
+  signal(SIGFPE ,signal_handler);   // Catch floating point errors
+  signal(SIGABRT ,signal_handler);  // Catch abort() calls
+
+  for(TestEntry *entry = test_list; entry->function != NULL; entry++){{
+    if( sigsetjmp(jump_buffer ,1) == 0 ){{
+      // Run the test normally
+      if( !entry->function() ){{
+        printf("Failed: %s\n" ,entry->name);
+        fail_count++;
+      }}else{{
+        pass_count++;
+      }}
+    }}else{{
+      // If a signal was caught
+      printf("Failed due to signaling: %s\n" ,entry->name);
+      fail_count++;
+    }}
+  }}
+
+  printf("Tests passed: %d\n" ,pass_count);
+  printf("Tests failed: %d\n" ,fail_count);
+  return (fail_count == 0) ? 0 : 1;
+}}
+
+// Main function
+int main(int argc ,char **argv){{
+  return test_head();
+}}
+
+//------------------------------------------------------------------------------
+// Test Implementations
+//------------------------------------------------------------------------------
+
+bool test_copy(){{
+  // Allocate memory
+  {NAMESPACE}路T *array = {NAMESPACE}路位.allocate_array(2 ,NULL);
+  if( !array ) return false;
+
+  // Access elements via access function
+  {NAMESPACE}路T *a = {NAMESPACE}路位.access(array ,0);
+  {NAMESPACE}路T *b = {NAMESPACE}路位.access(array ,1);
+
+  // Assign value and copy
+  {NAMESPACE}路位.from_uint32(a ,42);
+  {NAMESPACE}路位.copy(b ,a);
+
+  bool success = ( {NAMESPACE}路位.compare(b ,a) == {NAMESPACE}路Order_eq );
+  {NAMESPACE}路位.deallocate(array);
+  return success;
+}}
+
+bool test_arithmetic(){{
+  // Allocate memory
+  {NAMESPACE}路T *array = {NAMESPACE}路位.allocate_array(3 ,NULL);
+  if( !array ) return false;
+
+  {NAMESPACE}路T *a = {NAMESPACE}路位.access(array ,0);
+  {NAMESPACE}路T *b = {NAMESPACE}路位.access(array ,1);
+  {NAMESPACE}路T *result = {NAMESPACE}路位.access(array ,2);
+
+  {NAMESPACE}路位.from_uint32(a ,20);
+  {NAMESPACE}路位.from_uint32(b ,22);
+
+  if( {NAMESPACE}路位.add(result ,a ,b) != {NAMESPACE}路Status路ok ) return false;
+  if( {NAMESPACE}路位.compare(result ,{NAMESPACE}路位.access(array ,0)) != {NAMESPACE}路Order_gt ) return false;
+
+  if( {NAMESPACE}路位.subtract(result ,b ,a) != {NAMESPACE}路Status路ok ) return false;
+  if( {NAMESPACE}路位.compare(result ,{NAMESPACE}路位.access(array ,0)) != {NAMESPACE}路Order_lt ) return false;
+
+  {NAMESPACE}路位.deallocate(array);
+  return true;
+}}
+
+bool test_bitwise_operations(){{
+  // Allocate memory
+  {NAMESPACE}路T *array = {NAMESPACE}路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  {NAMESPACE}路T *a = {NAMESPACE}路位.access(array, 0);
+  {NAMESPACE}路T *b = {NAMESPACE}路位.access(array, 1);
+  {NAMESPACE}路T *result = {NAMESPACE}路位.access(array, 2);
+
+  // a = 0x0F0F0F0F, b = 0xF0F0F0F0
+  {NAMESPACE}路位.from_uint32(a, 0x0F0F0F0F);
+  {NAMESPACE}路位.from_uint32(b, 0xF0F0F0F0);
+
+  // bit_and => expect 0x00000000
+  {NAMESPACE}路位.bit_and(result, a, b);
+  {NAMESPACE}路位.from_uint32(a, 0x00000000);
+  if({NAMESPACE}路位.compare(result, a) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  // Reset a to 0x0F0F0F0F for next tests
+  {NAMESPACE}路位.from_uint32(a, 0x0F0F0F0F);
+
+  // bit_or => expect 0xFFFFFFFF
+  {NAMESPACE}路位.bit_or(result, a, b);
+  {NAMESPACE}路位.from_uint32(b, 0xFFFFFFFF);
+  if({NAMESPACE}路位.compare(result, b) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  // bit_complement(a=0x0F0F0F0F) => expect 0xF0F0F0F0
+  {NAMESPACE}路位.from_uint32(a, 0x0F0F0F0F);
+  {NAMESPACE}路位.bit_complement(result, a);
+  {NAMESPACE}路位.from_uint32(b, 0xF0F0F0F0);
+  if({NAMESPACE}路位.compare(result, b) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  // bit_twos_complement(a=0x0F0F0F0F) => expect 0xF0F0F0F1
+  {NAMESPACE}路位.from_uint32(a, 0x0F0F0F0F);
+  {NAMESPACE}路位.bit_twos_complement(result, a);
+  {NAMESPACE}路位.from_uint32(b, 0xF0F0F0F1);
+  if({NAMESPACE}路位.compare(result, b) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  {NAMESPACE}路位.deallocate(array);
+  return true;
+}}
+
+bool test_comparisons(){{
+  // Allocate memory
+  {NAMESPACE}路T *array = {NAMESPACE}路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  {NAMESPACE}路T *a = {NAMESPACE}路位.access(array, 0);
+  {NAMESPACE}路T *b = {NAMESPACE}路位.access(array, 1);
+  {NAMESPACE}路T *c = {NAMESPACE}路位.access(array, 2);
+
+  // First set: a=0, b=42, c=42
+  {NAMESPACE}路位.from_uint32(a, 0);
+  {NAMESPACE}路位.from_uint32(b, 42);
+  {NAMESPACE}路位.from_uint32(c, 42);
+
+  // eq_zero(a) => true
+  if(!{NAMESPACE}路位.eq_zero(a)){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // eq_zero(b) => false
+  if({NAMESPACE}路位.eq_zero(b)){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // eq(b, c) => true
+  if(!{NAMESPACE}路位.eq(b, c)){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // eq(a, b) => false
+  if({NAMESPACE}路位.eq(a, b)){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // compare(a, b) => {NAMESPACE}路Order_lt
+  if({NAMESPACE}路位.compare(a, b) != {NAMESPACE}路Order_lt){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // compare(b, a) => {NAMESPACE}路Order_gt
+  if({NAMESPACE}路位.compare(b, a) != {NAMESPACE}路Order_gt){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // compare(b, c) => {NAMESPACE}路Order_eq
+  if({NAMESPACE}路位.compare(b, c) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // lt(a, b) => true, gt(b, a) => true
+  if(!{NAMESPACE}路位.lt(a, b) || !{NAMESPACE}路位.gt(b, a)){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  // Second set: a=100, b=50
+  {NAMESPACE}路位.from_uint32(a, 100);
+  {NAMESPACE}路位.from_uint32(b, 50);
+  if({NAMESPACE}路位.compare(a, b) != {NAMESPACE}路Order_gt){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // eq_zero(a) => false
+  if({NAMESPACE}路位.eq_zero(a)){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  // eq_zero(b) => false
+  if({NAMESPACE}路位.eq_zero(b)){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  {NAMESPACE}路位.deallocate(array);
+  return true;
+}}
+
+bool test_shifts(){{
+  // Allocate memory for operand, fill, spill
+  {NAMESPACE}路T *array = {NAMESPACE}路位.allocate_array(3, NULL);
+  if(!array) return false;
+
+  {NAMESPACE}路T *operand = {NAMESPACE}路位.access(array, 0);
+  {NAMESPACE}路T *fill    = {NAMESPACE}路位.access(array, 1);
+  {NAMESPACE}路T *spill   = {NAMESPACE}路位.access(array, 2);
+
+  // Subtest A: shift_left(4) with operand=1 => expect operand=16, fill=0, spill=0
+  {NAMESPACE}路位.from_uint32(operand, 1);
+  {NAMESPACE}路位.from_uint32(fill, 0);
+  {NAMESPACE}路位.from_uint32(spill, 0);
+  if({NAMESPACE}路位.shift_left(4, spill, operand, fill) != {NAMESPACE}路Status路ok){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  {NAMESPACE}路T *temp = {NAMESPACE}路位.allocate_array(1, NULL);
+  if(!temp){{
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  {NAMESPACE}路位.from_uint32(temp, 16);
+  if({NAMESPACE}路位.compare(operand, temp) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  if({NAMESPACE}路位.compare(fill, {NAMESPACE}路zero) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  if({NAMESPACE}路位.compare(spill, {NAMESPACE}路zero) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  // Subtest B: shift_left(1) with operand=0x80000000 => expect operand=0, spill=1
+  {NAMESPACE}路位.from_uint32(operand, 0x80000000);
+  {NAMESPACE}路位.from_uint32(fill, 0);
+  {NAMESPACE}路位.from_uint32(spill, 0);
+  if({NAMESPACE}路位.shift_left(1, spill, operand, fill) != {NAMESPACE}路Status路ok){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  if(!{NAMESPACE}路位.eq_zero(operand)){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  {NAMESPACE}路位.from_uint32(temp, 1);
+  if({NAMESPACE}路位.compare(spill, temp) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  // Subtest C: shift_right(1) with operand=0x80000000 => expect operand=0x40000000, spill=0
+  {NAMESPACE}路位.from_uint32(operand, 0x80000000);
+  {NAMESPACE}路位.from_uint32(fill, 0);
+  {NAMESPACE}路位.from_uint32(spill, 0);
+  if({NAMESPACE}路位.shift_right(1, spill, operand, fill) != {NAMESPACE}路Status路ok){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  {NAMESPACE}路位.from_uint32(temp, 0x40000000);
+  if({NAMESPACE}路位.compare(operand, temp) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  if(!{NAMESPACE}路位.eq_zero(spill)){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  // Subtest D: arithmetic_shift_right(1) with operand=0x80000000 => expect operand=0xC0000000, spill=0
+  {NAMESPACE}路位.from_uint32(operand, 0x80000000);
+  {NAMESPACE}路位.from_uint32(spill, 0);
+  if({NAMESPACE}路位.arithmetic_shift_right(1, operand, spill) != {NAMESPACE}路Status路ok){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  {NAMESPACE}路位.from_uint32(temp, 0xC0000000);
+  if({NAMESPACE}路位.compare(operand, temp) != {NAMESPACE}路Order_eq){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+  if(!{NAMESPACE}路位.eq_zero(spill)){{
+    {NAMESPACE}路位.deallocate(temp);
+    {NAMESPACE}路位.deallocate(array);
+    return false;
+  }}
+
+  {NAMESPACE}路位.deallocate(temp);
+  {NAMESPACE}路位.deallocate(array);
+  return true;
+}}
+
+
+
+// Include the local section of {NAMESPACE}.lib.c for testing
+#define LOCAL
+#include "{NAMESPACE}.lib.c"
+#undef LOCAL
+'''
diff --git a/tester/tool馃枆/clean b/tester/tool馃枆/clean
new file mode 100755 (executable)
index 0000000..cebc4c0
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="tester/tool馃枆/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+set -e
+set -x
+
+
+cd "$REPO_HOME"/tester || exit 1
+
+# remove library pulled from release and other scratchpad files
+  rm_na scratchpad/{makefile-cc.deps,*.o} || true
+
+# remove built executables
+  rm_na -f machine/* || true
+
+set +x
+echo "$(script_fn) done."
index e0f787f..ed0e7c5 100755 (executable)
@@ -12,9 +12,9 @@ script_afp=$(realpath "${BASH_SOURCE[0]}")
 set -e
 set -x
 
-cd "$REPO_HOME"/tester || exit 1
+  cd "$REPO_HOME"/tester || exit 1
 
-/bin/make -f tool馃枆/makefile $@
+  /bin/make -f tool馃枆/makefile $@
 
 set +x
 echo "$(script_fn) done."
index a0da057..9b933d5 100644 (file)
@@ -1,5 +1,4 @@
 
-
 RT-INCOMMON:=$(REPO_HOME)/tool_shared/third_party/RT-project-share/release
 
 include $(RT-INCOMMON)/make/environment_RT_0
@@ -8,11 +7,5 @@ CFLAGS+=-Werror -include "$(RT-INCOMMON)/make/RT_0.h"
 LINKFLAGS+= -l$(PROJECT)
 LIBFILE=$(LIBDIR)/lib$(PROJECT).a
 
-include $(RT-INCOMMON)/make/targets
+include $(RT-INCOMMON)/make/targets_tester
 -include $(DEPFILE)
-
-
-
-
-
-
diff --git a/tester/tool馃枆/pull_release b/tester/tool馃枆/pull_release
deleted file mode 100755 (executable)
index a083b91..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# before running this script, gather everything needed for the release on the scratchpad
-
-# input guards
-
-  env_must_be="tester/tool馃枆/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-set -e
-set -x
-
-  cd "$REPO_HOME"/tester || exit 1
-
-  if [ ! -d scratchpad ]; then
-    echo "$(script_fp):: no scratchpad directory"
-    exit 1
-  fi
-
-  release_dir=$(release_dir)
-
-  if [ ! -d ${release_dir} ]; then
-    echo "$(script_fp):: no release directory to pull install files from"
-    exit 1
-  fi
-
-
-  cp ${release_dir}/libN.a scratchpad || true
-  cp ${release_dir}/*.lib.c cc || true
-
-set +x
-echo "$(script_fn) done."
-
diff --git a/tester/tool馃枆/release b/tester/tool馃枆/release
new file mode 100755 (executable)
index 0000000..ecbf3ff
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# include tests in the project release
+
+# input guards
+
+  env_must_be="tester/tool馃枆/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+set -e
+set -x
+
+  cd "$REPO_HOME"/tester || exit 1
+
+  if [ ! -d scratchpad ]; then
+    echo "$(script_fp):: no scratchpad directory"
+    exit 1
+  fi
+
+  release_dir=$(release_dir)
+
+  if [ ! -d ${release_dir} ]; then
+    echo "$(script_fp):: no release directory to pull install files from"
+    exit 1
+  fi
+
+  install_file machine/* ${release_dir} "ug+rx"
+
+
+
+
+set +x
+echo "$(script_fn) done."
+
diff --git a/tester/tool馃枆/release_clean b/tester/tool馃枆/release_clean
new file mode 100755 (executable)
index 0000000..2e0da45
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# input guards
+
+  env_must_be="tester/tool馃枆/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+set -e
+set -x
+
+
+cd "$REPO_HOME"/tester || exit 1
+
+# remove library pulled from release and other scratchpad files
+  rm_na -rf scratchpad/* || true
+
+# remove cc files pulled from release
+  rm_na -f cc/* || true
+
+# remove built executables
+  rm_na -f machine/* || true
+
+set +x
+echo "$(script_fn) done."
diff --git a/tester/tool馃枆/release_pull b/tester/tool馃枆/release_pull
new file mode 100755 (executable)
index 0000000..7c1182e
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+script_afp=$(realpath "${BASH_SOURCE[0]}")
+
+# pulls the library and include files down from the project release directory
+
+# input guards
+
+  env_must_be="tester/tool馃枆/env"
+  if [ "$ENV" != "$env_must_be" ]; then
+    echo "$(script_fp):: error: must be run in the $env_must_be environment"
+    exit 1
+  fi
+
+  cd "$REPO_HOME"/tester || exit 1
+
+  if [ ! -d scratchpad ]; then
+    echo "$(script_fp):: no scratchpad directory"
+    exit 1
+  fi
+
+  release_dir=$(release_dir)
+
+  if [ ! -d ${release_dir} ]; then
+    echo "$(script_fp):: no release directory to pull install files from"
+    exit 1
+  fi
+
+  cp -f ${release_dir}/libN.a scratchpad || true
+  cp -f ${release_dir}/*.lib.c cc || true
+
+echo "$(script_fn) done."
+
diff --git a/tester/tool馃枆/release_test b/tester/tool馃枆/release_test
deleted file mode 100755 (executable)
index 3d31406..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-# release test machine code
-
-# input guards
-
-  env_must_be="tester/tool馃枆/env"
-  if [ "$ENV" != "$env_must_be" ]; then
-    echo "$(script_fp):: error: must be run in the $env_must_be environment"
-    exit 1
-  fi
-
-set -e
-set -x
-
-  cd "$REPO_HOME"/tester || exit 1
-
-  if [ ! -d scratchpad ]; then
-    echo "$(script_fp):: no scratchpad directory"
-    exit 1
-  fi
-
-  release_dir=$(release_dir)
-
-  if [ ! -d ${release_dir} ]; then
-    echo "$(script_fp):: no release directory to pull install files from"
-    exit 1
-  fi
-
-  install_file machine/* ${release_dir} "ug+rx"
-
-
-
-
-set +x
-echo "$(script_fn) done."
-
index f9671cc..0ab3899 100644 (file)
@@ -78,7 +78,7 @@ shopt -s nullglob
 
   install_file() {
     if [ "$#" -lt 3 ]; then
-      echo "Usage: install_file <source1> <source2> ... <target_dir> <permissions>"
+      echo "env::install_file usage: install_file <source1> <source2> ... <target_dir> <permissions>"
       return 1
     fi
 
@@ -87,23 +87,23 @@ shopt -s nullglob
     sources=("${@:1:$#-2}")  # All other arguments are source files
 
     if [ ! -d "$target_dp" ]; then
-      echo "Error: Target directory '$target_dp' does not exist."
+      echo "env::install_file no install done: target directory '$target_dp' does not exist."
       return 1
     fi
 
     for source_fp in "${sources[@]}"; do
       if [ ! -f "$source_fp" ]; then
-        echo "Error: Source file '$source_fp' does not exist."
+        echo "env::install_file: source file '$source_fp' does not exist."
         return 1
       fi
 
       target_file="$target_dp/$(basename "$source_fp")"
 
       if ! install -m "$perms" "$source_fp" "$target_file"; then
-        echo "Error: Failed to install $(basename "$source_fp") to $target_dp"
+        echo "env::install_file: Failed to install $(basename "$source_fp") to $target_dp"
         return 1
       else
-        echo "Installed $(basename "$source_fp") to $target_dp with permissions $perms"
+        echo "env::install_file: installed $(basename "$source_fp") to $target_dp with permissions $perms"
       fi
     done
   }