From: Thomas Walker Lynch Date: Wed, 12 Feb 2025 03:36:07 +0000 (+0000) Subject: for first push X-Git-Url: https://git.reasoningtechnology.com/style/static/git-logo.png?a=commitdiff_plain;h=ed23e5921361aa5cd32d5b9f6062738a706fd33c;p=N for first push --- diff --git a/.gitignore b/.gitignore index 02b640c..bf925e3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ -#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 #*# *~ diff --git "a/developer/cc\360\237\226\211/Natural_32.lib.c" "b/developer/cc\360\237\226\211/Natural_32.lib.c" new file mode 100644 index 0000000..9ad039e --- /dev/null +++ "b/developer/cc\360\237\226\211/Natural_32.lib.c" @@ -0,0 +1,295 @@ +/* + 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 + #include + + 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 diff --git "a/developer/cc\360\237\226\211/deprecated/NN_Count_Digit.lib.c" "b/developer/cc\360\237\226\211/deprecated/NN_Count_Digit.lib.c" new file mode 100644 index 0000000..9d604a9 --- /dev/null +++ "b/developer/cc\360\237\226\211/deprecated/NN_Count_Digit.lib.c" @@ -0,0 +1,118 @@ +/* + 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 + #include + 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 diff --git "a/developer/cc\360\237\226\211/environment.h" "b/developer/cc\360\237\226\211/environment.h" index a9d3518..d82898f 100644 --- "a/developer/cc\360\237\226\211/environment.h" +++ "b/developer/cc\360\237\226\211/environment.h" @@ -1,9 +1,6 @@ #ifndef Mpblock·ENVIRONMENT_H #define Mpblock·ENVIRONMENT_H - #include - #include - typedef unsigned int uint; #define FREE(pt) free(pt); (pt) = NULL; #endif diff --git "a/developer/cc\360\237\226\211/test_Natural_32_0.cli.c" "b/developer/cc\360\237\226\211/test_Natural_32_0.cli.c" new file mode 100644 index 0000000..2c344e7 --- /dev/null +++ "b/developer/cc\360\237\226\211/test_Natural_32_0.cli.c" @@ -0,0 +1,88 @@ + +#include "environment.h" +#include +#include +#include + +#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; +} diff --git "a/developer/cc\360\237\226\211/test_setup.cli.c" "b/developer/cc\360\237\226\211/test_setup.cli.c" new file mode 100644 index 0000000..f1c6e68 --- /dev/null +++ "b/developer/cc\360\237\226\211/test_setup.cli.c" @@ -0,0 +1,22 @@ +/* + + A placeholder to see if make etc. is working. + +*/ + +#define IFACE +#include +#include + +// 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; +} diff --git a/developer/scratchpad/.githolder b/developer/scratchpad/.githolder deleted file mode 100644 index e69de29..0000000 diff --git a/developer/scratchpad/.gitignore b/developer/scratchpad/.gitignore new file mode 100644 index 0000000..120f485 --- /dev/null +++ b/developer/scratchpad/.gitignore @@ -0,0 +1,2 @@ +* +!/.gitignore diff --git a/scratchpad/.githolder b/scratchpad/.githolder new file mode 100644 index 0000000..e69de29 diff --git a/tool_shared/env b/tool_shared/env deleted file mode 100644 index 01f47a3..0000000 --- a/tool_shared/env +++ /dev/null @@ -1,81 +0,0 @@ -#!/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" - diff --git a/tool_shared/third_party/.gitignore b/tool_shared/third_party/.gitignore new file mode 100644 index 0000000..120f485 --- /dev/null +++ b/tool_shared/third_party/.gitignore @@ -0,0 +1,2 @@ +* +!/.gitignore diff --git a/tool_shared/version b/tool_shared/version deleted file mode 100755 index be170e5..0000000 --- a/tool_shared/version +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/env bash -script_afp=$(realpath "${BASH_SOURCE[0]}") - -echo v0.1 -