-#note also the .gitignore files in the tool and developer directories and any
-# other directory that might have one.
+# note also the .gitignore files in other directories
#*#
*~
--- /dev/null
+/*
+ N_32 - a processor native type
+
+ For binary operations: a op b -> c
+
+ To use N_32, first allocate a block of N_32. Do the arithmetic,
+ if any results need be kept, copy them to another block. Then deallocate
+ the block. Do not allocate numbers one at a time, or it would be slow.
+
+*/
+
+#ifndef IFACE
+#define N_32路IMPLEMENTATION
+#define IFACE
+#endif
+
+#ifndef N_32路IFACE
+#define N_32路IFACE
+
+ //----------------------------------------
+ // The instance data
+ // no way to avoid adding this definition to the interface due to the use of inline functions
+
+ typedef uint32_t Extent;
+ typedef uint32_t Digit;;
+
+ struct N_32 {
+ Digit d0;
+ };
+
+ const N_32 N_32路zero;
+ const N_32 N_32路one;
+ const N_32 N_32路all_ones;
+
+
+ //----------------------------------------
+ // error status return values, and error handlers
+ //
+
+ typedef enum {
+ N_32路Status路ok = 0
+ ,N_32路Status路overflow = 1
+ ,N_32路Status路accumulator_overflow = 2
+ ,N_32路Status路carry = 3
+ ,N_32路Status路borrow = 4
+ ,N_32路Status路undefined_divide_by_zero = 5
+ ,N_32路Status路undefined_modulus_zero = 6
+ } N_32路Status;
+
+ typedef enum {
+ N_32路Order路lt = -1 // Less Than
+ ,N_32路Order路eq = 0 // Equal
+ ,N_32路Order路gt = 1 // Greater Than
+ } N_32路Order;
+
+ typedef N_32 *( *N_32路Allocate路MemoryFault )(Extent);
+
+ //----------------------------------------
+ // inline interface
+ //
+
+ // copy, convenience copy
+
+ inline void N_32路copy(N_32 *destination ,N_32 *source){
+ *destination = *source;
+ }
+
+ inline N_32 N_32路c(N_32 *source){
+ return *source;
+ }
+
+ inline N_32 N_32路c_zero(void){
+ return c(N_32路zero);
+ }
+
+ inline N_32 N_32路c_one(void){
+ return c(N_32路one);
+ }
+
+ inline N_32 N_32路c_all_ones(void){
+ return c(N_32路all_ones);
+ }
+
+
+ inline void N_32路set_to_zero(N_32 *instance){
+ instance->d0 = 0;
+ }
+
+ inline void N_32路set_to_one(N_32 *instance){
+ instance->d0 = 1;
+ }
+
+ // bit operations
+
+ inline void N_32路and(N_32 *result ,N_32 *a ,N_32 *b){
+ result->d0 = a->d0 & b->d0;
+ }
+
+ inline void N_32路or(N_32 *result ,N_32 *a ,N_32 *b){
+ result->d0 = a->d0 | b->d0;
+ }
+
+ inline void N_32路complement(N_32 *result ,N_32 *a){
+ result->d0 = ~a->d0;
+ }
+
+ inline void N_32路twos_complement(N_32 *result ,N_32 *a){
+ result->d0 = ~a->d0 + 1;
+ }
+
+ inline bool N_32路lsb_is_set(N_32 *a){
+ return a->d0 & 0x0000001;
+ }
+
+ inline bool N_32路msb_is_set(N_32 *a){
+ return a->d0 & 0x8000000;
+ }
+
+ // for low precision Natural, and large number of summands for accumulate/add/sub, overflow could overflow and thus this op would fail
+ inline N_32路Status N_32路accumulate(N_32 *overflow ,N_32 *accumulator ,...){
+ va_list args;
+ va_start(args ,accumulator);
+
+ uint64_t *sum = &accumulator->d0;
+ uint64_t *carry = &overflow->d0;
+ N_32 *current;
+
+ while( (current = va_arg(args ,N_32 *)) ){
+ *sum += current->d0;
+ if(*sum < current->d0){ // Overflow into carry
+ (*carry)++;
+ if(*carry == 0){
+ va_end(args);
+ return N_32路Status路accumulator_overflow;
+ }
+ }
+ }
+ va_end(args);
+
+ if(*carry == 0) return N_32路Status路ok;
+ return N_32路Status路OVERFLOW;
+ }
+
+ inline N_32路Order N_32路compare(N_32 *a ,N_32 *b){
+ if(a->d0 < b->d0) return N_32路order路lt;
+ if(a->d0 > b->d0) return N_32路order路gt;
+ return N_32路order路eq;
+ }
+
+ inline bool N_32路lt(N_32 *a ,N_32 *b){
+ return a->d0 < b->d0;
+ }
+
+ inline bool N_32路gt(N_32 *a ,N_32 *b){
+ return a->d0 > b->d0;
+ }
+
+ inline bool N_32路eq(N_32 *a ,N_32 *b){
+ return a->d0 == b->d0;
+ }
+
+ // arithmetic operations
+
+ inline N_32路Status N_32路add(N_32 *sum ,N_32 *a ,N_32 *b){
+ uint64_t result = (uint64_t)a->d0 + (uint64_t)b->d0;
+ sum->d0 = (uint32_t)result;
+ return (result >> 32) ? N_32路Status路carry : N_32路Status路ok;
+ }
+
+ inline N_32路Status N_32路next(N_32 *overflow ,N_32 *result ,N_32 *a){
+ uint64_t sum = (uint64_t)a->d0 + (uint64_t)1;
+ result->d0 = (uint32_t)sum;
+ overflow->d0 = (uint32_t)(sum >> 32);
+
+ if(overflow->d0 == 0) return N_32路status路ok;
+ return N_32路status路overflow;
+ }
+
+ inline N_32路Status N_32路subtract(N_32 *difference ,N_32 *a ,N_32 *b){
+ uint64_t diff = (uint64_t)a->d0 - (uint64_t)b->d0;
+ difference->d0 = (uint32_t)diff;
+ return (diff > a->d0) ? N_32路Status路borrow : N_32路Status路ok;
+ }
+
+ inline N_32路Status N_32路multiply(N_32 *overflow ,N_32 *result ,N_32 *a ,N_32 *b){
+ uint64_t product = (uint64_t)a->d0 * (uint64_t)b->d0;
+ result->d0 = (uint32_t)product;
+ overflow->d0 = (uint32_t)(product >> 32);
+
+ if(overflow->d0 == 0) return N_32路status路ok;
+ return N_32路status路overflow;
+ }
+
+ inline N_32路Status N_32路divide(N_32 *remainder ,N_32 *quotient ,N_32 *a ,N_32 *b){
+ if(b->d0 == 0) return N_32路Status路undefined_divide_by_zero;
+
+ quotient->d0 = a->d0 / b->d0;
+ remainder->d0 = a->d0 - (quotient->d0 * b->d0);
+
+ return N_32路Status路ok;
+ }
+
+ inline N_32路Status N_32路modulus(N_32 *remainder ,N_32 *a ,N_32 *b){
+ if(b->d0 == 0) return N_32路Status路undefined_modulus_zero;
+ uint32_t quotient = a->d0 / b->d0;
+ remainder->d0 = a->d0 - (quotient * b->d0);
+ return N_32路Status路ok;
+ }
+
+ // shift
+ inline void N_32路shift_left(Extent shift ,N_32 *sink ,N_32 *result ,N_32 *source){
+ *sink = *source;
+ result->d0 = source->d0 << shift;
+ sink->d0 = source->d0 >> (32 - shift);
+ }
+
+ inline void N_32路shift_right(Extent shift ,N_32 *source ,N_32 *result ,N_32 *sink){
+ *sink = *source;
+ result->d0 = source->d0 >> shift;
+ sink->d0 = source->d0 << (32 - shift);
+ }
+
+ inline void N_32路arithmetic_shift_right(Extent shift ,N_32 *result ,N_32 *sink){
+ N_32 source;
+ N_32 source = msb_is_set(result) ? N_32路all_ones : N_32路zero;
+ N_32路shift_right(shift ,&source ,result ,sink);
+ }
+
+ //----------------------------------------
+ // compiled interface
+
+ typedef struct {
+ N_32路Allocate allocate;
+ N_32路Zero zero;
+ N_32路One one;
+ N_32路Deallocate deallocate;
+ } N_32路Interface;
+
+ extern const N_32路Interface N_32路interface;
+
+
+#endif
+
+#ifdef N_32路IMPLEMENTATION
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+
+ const N_32 N_32路zero = { .d0 = 0 };
+ const N_32 N_32路one = { .d0 = 1 };
+ const N_32 N_32路all_ones = { .d0 = ~(uint32_t)0 };
+
+ // the allocate an array of N_32
+ N_32 *N_32路allocate( Extent extent ,N_32 *(*memory_fault)(Extent) ){
+ N_32 *instance = malloc((extent + 1) * sizeof(N_32) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ N_32 *N_32路alloc_zero( Extent extent ,N_32 *(*memory_fault)(Extent) ){
+ N_32 *instance = calloc( extent + 1 ,sizeof(N_32) );
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ return instance;
+ }
+
+ // initialize all with x
+ N_32 *N_32路alloc_x(Extent extent ,N_32 *(*memory_fault)(Extent) ,N_32 *x){
+ N_32 *instance = malloc((extent + 1) * sizeof(N_32));
+ if(!instance){
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ N_32 *pt = instance;
+ while( pt <= instance + extent ){
+ *pt = *x;
+ pt++;
+ }
+ return instance;
+ }
+
+ const N_32路Interface N_32路interface = {
+ .allocate = N_32路allocate
+ ,.allocate_zero = N_32路alloc_zero
+ ,.allocate_all_x = N_32路alloc_x
+ ,.deallocate = N_32路deallocate
+ };
+
+ void N_32路deallocate(N_32 *unencumbered){
+ free(unencumbered);
+ }
+
+#endif
--- /dev/null
+/*
+ A digit count followed by that many digits.
+
+ Extent_Digit_Instance:
+ - 'NN' stands for Natural Number representation.
+ - 'Extent' refers to the maximum array index.
+ - 'Digit' specifies that the representation involves digits.
+ - 'Instance' differentiates this from the interface struct, ensuring clarity in alternative representations.
+*/
+
+#ifndef IFACE
+#define NN_Extent_Digit路IMPLEMENTATION
+#define IFACE
+#endif
+
+#ifndef NN_Extent_Digit路IFACE
+#define NN_Extent_Digit路IFACE
+
+ typedef uint32_t Extent;
+
+ // interface function signatures
+ //
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Copy路MemoryFault)
+ (
+ Extent extent
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Copy)
+ (
+ NN_Extent_Digit *original
+ ,NN_Extent_Digit路Copy路MemoryFault memory_fault
+ );
+
+ typedef void (*NN_Extent_Digit路Accumulate)
+ (
+ NN_Extent_Digit *accumulator ,...
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Add)
+ (
+ NN_Extent_Digit *summand ,...
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Multiply)
+ (
+ NN_Extent_Digit *factor ,...
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Rotate_Right_Digit)
+ (
+ Extent count
+ ,NN_Extent_Digit *a
+ ,NN_Extent_Digit *b
+ ,NN_Extent_Digit *c
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Rotate_Left_Digit)
+ (
+ Extent count
+ ,NN_Extent_Digit *a
+ ,NN_Extent_Digit *b
+ ,NN_Extent_Digit *c
+ );
+
+ typedef NN_Extent_Digit *(*NN_Extent_Digit路Allocate路MemoryFault)
+ (
+ Extent extent
+ );
+
+ // interface struct definition
+ //
+ typedef struct {
+ NN_Extent_Digit路Copy copy;
+ NN_Extent_Digit路Accumulate accumulate;
+ NN_Extent_Digit路Add add;
+ NN_Extent_Digit路Multiply multiply;
+ NN_Extent_Digit路Rotate_Right_Digit rotate_right_digit;
+ NN_Extent_Digit路Rotate_Left_Digit rotate_left_digit;
+ } NN_Extent_Digit;
+
+ // an extent is a maximum array index
+ NN_Extent_Digit *NN_Extent_Digit路allocate(Extent extent, NN_Extent_Digit路Allocate路MemoryFault memory_fault);
+ void NN_Extent_Digit路deallocate(NN_Extent_Digit *unencumbered);
+
+#endif
+
+#ifdef NN_Extent_Digit路IMPLEMENTATION
+
+ #include <stdarg.h>
+ #include <stdlib.h>
+ typedef uint32_t Digit;
+
+ typedef struct {
+ Extent extent;
+ Digit a[];
+ } Instance;
+
+ NN_Extent_Digit *allocate(Extent extent, NN_Extent_Digit路Allocate路MemoryFault memory_fault){
+ Extent allocation_size = sizeof(NN_Extent_Digit_Instance) + extent * sizeof(Digit) + sizeof(Digit);
+ Instance *instance = malloc(allocation_size);
+ if (!instance) {
+ return memory_fault ? memory_fault(extent) : NULL;
+ }
+ instance->extent = extent;
+
+ // nope-> need to allocate an interface signature struct and assign the method
+ // function pointers to it. It will also need a field for holding the instance,
+ // yes, declare a new interface struct that has an extra field on the bottom for
+ // the instance pointer .. but then what of interface inheritance? hmmm. Perhaps
+ // that is better done by composition anyway.
+ return (NN_Extent_Digit *)instance;
+ }
+
+ void deallocate(NN_Extent_Digit *unencumbered){
+ free(unencumbered);
+ }
+
+#endif
#ifndef Mpblock路ENVIRONMENT_H
#define Mpblock路ENVIRONMENT_H
- #include <stdint.h>
- #include <stdbool.h>
- typedef unsigned int uint;
#define FREE(pt) free(pt); (pt) = NULL;
#endif
--- /dev/null
+
+#include "environment.h"
+#include <stdio.h>
+#include <setjmp.h>
+#include <signal.h>
+
+#define IFACE
+#include "Natural_32.lib.c"
+
+#define TEST_COUNT 10 // Adjust as needed
+
+jmp_buf test_env;
+const char *current_test = NULL;
+
+void signal_handler(int sig){
+ printf("Failed due to Exception: %s (Signal %d)\n", current_test, sig);
+ longjmp(test_env, 1);
+}
+
+int main(void){
+ bool test_results[TEST_COUNT] = {false};
+ const char *test_names[TEST_COUNT] = {
+ "Addition",
+ "Subtraction",
+ "Multiplication",
+ "Division",
+ "Modulus",
+ "Shift Left",
+ "Shift Right",
+ "Comparison",
+ "Complement",
+ "Two's Complement"
+ };
+
+ int pass_count = 0, fail_count = 0;
+ bool *test_ptr = test_results;
+ const char **name_ptr = test_names;
+
+ // Install signal handler
+ signal(SIGFPE, signal_handler);
+ signal(SIGSEGV, signal_handler);
+ signal(SIGABRT, signal_handler);
+
+ Natural_32 a, b, result, overflow;
+ Natural_32路set_to_zero(&a);
+ Natural_32路set_to_one(&b);
+
+ // Macro to run tests with proper failure messaging
+ #define RUN_TEST(expr) \
+ current_test = *name_ptr; \
+ if(setjmp(test_env) == 0){ \
+ if(expr){ \
+ *test_ptr++ = true; \
+ pass_count++; \
+ } else { \
+ printf("Failed due to Bad Return Value: %s\n", *name_ptr); \
+ *test_ptr++ = false; \
+ fail_count++; \
+ } \
+ } else { \
+ *test_ptr++ = false; \
+ fail_count++; \
+ } \
+ name_ptr++;
+
+ RUN_TEST(Natural_32路add(&result, &a, &b) == Natural_32路Status路ok && result.d0 == 1);
+ RUN_TEST(Natural_32路subtract(&result, &b, &a) == Natural_32路Status路ok && result.d0 == 1);
+ RUN_TEST(Natural_32路multiply(&overflow, &result, &b, &b) == Natural_32路Status路ok && result.d0 == 1 && overflow.d0 == 0);
+ RUN_TEST(Natural_32路divide(&result, &overflow, &b, &b) == Natural_32路Status路ok && result.d0 == 1 && overflow.d0 == 0);
+ RUN_TEST(Natural_32路modulus(&result, &b, &b) == Natural_32路Status路ok && result.d0 == 0);
+
+ Natural_32路shift_left(1, &overflow, &result, &b);
+ RUN_TEST(result.d0 == 2 && overflow.d0 == 0);
+
+ Natural_32路shift_right(1, &b, &result, &overflow);
+ RUN_TEST(result.d0 == 0 && overflow.d0 == 1);
+
+ RUN_TEST(Natural_32路compare(&a, &b) == Natural_32路Order路lt);
+
+ Natural_32路complement(&result, &a);
+ RUN_TEST(result.d0 == ~0);
+
+ Natural_32路twos_complement(&result, &b);
+ RUN_TEST(result.d0 == (uint32_t)(-1));
+
+ printf("Pass: %d, Fail: %d\n", pass_count, fail_count);
+ return fail_count > 0 ? 1 : 0;
+}
--- /dev/null
+/*
+
+ A placeholder to see if make etc. is working.
+
+*/
+
+#define IFACE
+#include <stdio.h>
+#include <stdlib.h>
+
+// No need to define IMPLEMENTATION as `main` is one and done.
+
+int main(int argc ,char *argv[] ,char *envp[]){
+ if(argc != 1){
+ fprintf(stderr, "Usage: %s\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ fprintf(stderr, "%s done\n", argv[0]);
+
+ return 0;
+}
--- /dev/null
+*
+!/.gitignore
+++ /dev/null
-#!/usr/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
- echo "$script_afp:: This script must be sourced, not executed."
- exit 1
-fi
-
-# without this bash takes non-matching globs literally
-shopt -s nullglob
-
-# --------------------------------------------------------------------------------
-# project definition
-
-# actual absolute director path for this script file
-
- script_adp(){
- dirname "$script_afp"
- }
-
-# assume this script is located $REPO_HOME/tools_shared/bespoke and work backwards
-# to get $REPO_HOME, etc.
-
- REPO_HOME=$(dirname "$(dirname "$(script_adp)")")
- echo REPO_HOME "$REPO_HOME"
-
- PROJECT=$(basename "$REPO_HOME")
- echo PROJECT "$PROJECT"
-
- # set the prompt decoration to the name of the project
- PROMPT_DECOR=$PROJECT
-
- # include the project bespoke tools
- PATH="$REPO_HOME"/tool_shared/bespoke馃枆:"$PATH"
-
- export REPO_HOME PROJECT PROMPT_DECOR PATH
-
-# --------------------------------------------------------------------------------
-# The project administrator sets up the following tools for all roles to use:
-#
- PATH="$REPO_HOME/tool_shared/third_party/RT-project-share/release/bash:$PATH"
- PATH="$REPO_HOME/tool_shared/third_party/RT-project-share/release/amd64:$PATH"
- PATH="$REPO_HOME/tool_shared/third_party/emacs/bin:$PATH"
-
- # after having installed Itellij IDEA
- PATH="$REPO_HOME/tool_shared/third_party/idea-IC-243.21565.193/bin:$PATH"
-
- JAVA_HOME="$REPO_HOME/tool_shared/third_party/jdk-23.0.1"
- MOSAIC_HOME="$REPO_HOME/tool_shared/third_party/Mosaic"
-
- export PATH JAVA_HOME MOSAIC_HOME
-
-# --------------------------------------------------------------------------------
-# the following functions are provided for other scripts to use.
-# at the top of files that make use of these functions put the following line:
-# script_afp=$(realpath "${BASH_SOURCE[0]}")
-#
-
- ## script's filename
- script_fn(){
- basename "$script_afp"
- }
-
- ## script's dirpath relative to $REPO_HOME
- script_fp(){
- realpath --relative-to="${REPO_HOME}" "$script_afp"
- }
-
- ## script's dirpath relative to $REPO_HOME
- script_dp(){
- dirname "$(script_fp)"
- }
-
- export -f script_adp script_fn script_dp script_fp
-
-# --------------------------------------------------------------------------------
-# closing
-#
-
- export ENV=$(script_fp)
- echo ENV "$ENV"
-
--- /dev/null
+*
+!/.gitignore
+++ /dev/null
-#!/bin/env bash
-script_afp=$(realpath "${BASH_SOURCE[0]}")
-
-echo v0.1
-