diff --git a/Makefile b/Makefile
index 7e5efb4..67bb015 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ SRC_DIRS ?= ./src
SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c -or -name *.s)
HDRS := $(shell find $(SRC_DIRS) -name *.h)
-OBJS := $(addsuffix .o,$(basename $(SRCS)))
+OBJS := $(addsuffix .o,$(basename $(SRCS)))
DEPS := $(OBJS:.o=.d)
TESTS := $(shell find unit-tests -name *.sh)
@@ -21,6 +21,8 @@ DEBUGFLAGS := -g3
all: $(TARGET)
+Debug: $(TARGET)
+
$(TARGET): $(OBJS) Makefile
$(CC) $(DEBUGFLAGS) $(LDFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LOADLIBES) $(LDLIBS)
diff --git a/post-scarcity.cbp b/post-scarcity.cbp
new file mode 100644
index 0000000..a1f42e0
--- /dev/null
+++ b/post-scarcity.cbp
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/post-scarcity.cscope_file_list b/post-scarcity.cscope_file_list
new file mode 100644
index 0000000..6fbf5ec
--- /dev/null
+++ b/post-scarcity.cscope_file_list
@@ -0,0 +1,58 @@
+"/home/simon/workspace/post-scarcity/utils_src/readprintwc/readprintwc.c"
+"/home/simon/workspace/post-scarcity/src/memory/vectorspace.c"
+"/home/simon/workspace/post-scarcity/src/arith/peano.c"
+"/home/simon/workspace/post-scarcity/src/init.c"
+"/home/simon/workspace/post-scarcity/src/utils.h"
+"/home/simon/workspace/post-scarcity/src/ops/intern.h"
+"/home/simon/workspace/post-scarcity/src/arith/ratio.h"
+"/home/simon/workspace/post-scarcity/src/io/io.c"
+"/home/simon/workspace/post-scarcity/src/memory/conspage.h"
+"/home/simon/workspace/post-scarcity/src/time/psse_time.h"
+"/home/simon/workspace/post-scarcity/src/memory/cursor.h"
+"/home/simon/workspace/post-scarcity/src/memory/dump.h"
+"/home/simon/workspace/post-scarcity/src/ops/intern.c"
+"/home/simon/workspace/post-scarcity/src/memory/lookup3.c"
+"/home/simon/workspace/post-scarcity/src/io/fopen.h"
+"/home/simon/workspace/post-scarcity/src/version.h"
+"/home/simon/workspace/post-scarcity/src/memory/consspaceobject.h"
+"/home/simon/workspace/post-scarcity/src/ops/meta.h"
+"/home/simon/workspace/post-scarcity/src/arith/real.c"
+"/home/simon/workspace/post-scarcity/src/ops/loop.c"
+"/home/simon/workspace/post-scarcity/src/arith/integer.h"
+"/home/simon/workspace/post-scarcity/src/time/psse_time.c"
+"/home/simon/workspace/post-scarcity/src/memory/vectorspace.h"
+"/home/simon/workspace/post-scarcity/src/memory/hashmap.c"
+"/home/simon/workspace/post-scarcity/src/io/read.c"
+"/home/simon/workspace/post-scarcity/src/ops/lispops.h"
+"/home/simon/workspace/post-scarcity/src/ops/loop.h"
+"/home/simon/workspace/post-scarcity/src/memory/stack.h"
+"/home/simon/workspace/post-scarcity/utils_src/tagvalcalc/tagvalcalc.c"
+"/home/simon/workspace/post-scarcity/src/debug.c"
+"/home/simon/workspace/post-scarcity/src/io/read.h"
+"/home/simon/workspace/post-scarcity/src/ops/meta.c"
+"/home/simon/workspace/post-scarcity/src/memory/dump.c"
+"/home/simon/workspace/post-scarcity/src/repl.c"
+"/home/simon/workspace/post-scarcity/src/io/print.c"
+"/home/simon/workspace/post-scarcity/src/memory/hashmap.h"
+"/home/simon/workspace/post-scarcity/src/utils.c"
+"/home/simon/workspace/post-scarcity/src/io/io.h"
+"/home/simon/workspace/post-scarcity/src/memory/stack.c"
+"/home/simon/workspace/post-scarcity/utils_src/debugflags/debugflags.c"
+"/home/simon/workspace/post-scarcity/src/memory/consspaceobject.c"
+"/home/simon/workspace/post-scarcity/src/memory/conspage.c"
+"/home/simon/workspace/post-scarcity/src/memory/cursor.c"
+"/home/simon/workspace/post-scarcity/src/arith/ratio.c"
+"/home/simon/workspace/post-scarcity/Makefile"
+"/home/simon/workspace/post-scarcity/src/arith/peano.h"
+"/home/simon/workspace/post-scarcity/src/memory/lookup3.h"
+"/home/simon/workspace/post-scarcity/src/arith/real.h"
+"/home/simon/workspace/post-scarcity/src/ops/equal.c"
+"/home/simon/workspace/post-scarcity/src/ops/lispops.c"
+"/home/simon/workspace/post-scarcity/src/authorise.h"
+"/home/simon/workspace/post-scarcity/src/io/print.h"
+"/home/simon/workspace/post-scarcity/src/authorise.c"
+"/home/simon/workspace/post-scarcity/src/debug.h"
+"/home/simon/workspace/post-scarcity/src/arith/integer.c"
+"/home/simon/workspace/post-scarcity/src/ops/equal.h"
+"/home/simon/workspace/post-scarcity/src/repl.h"
+"/home/simon/workspace/post-scarcity/src/io/fopen.c"
diff --git a/post-scarcity.layout b/post-scarcity.layout
new file mode 100644
index 0000000..98bd2b3
--- /dev/null
+++ b/post-scarcity.layout
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arith/integer.c b/src/arith/integer.c
index eef171b..63f7dd2 100644
--- a/src/arith/integer.c
+++ b/src/arith/integer.c
@@ -87,9 +87,10 @@ __int128_t cell_value( struct cons_pointer c, char op, bool is_first_cell ) {
/**
* Overwrite the value field of the integer indicated by `new` with
- * the least significant 60 bits of `val`, and return the more significant
- * bits (if any) right-shifted by 60 places. Destructive, primitive, do not
- * use in any context except primitive operations on integers.
+ * the least significant INTEGER_BITS bits of `val`, and return the
+ * more significant bits (if any) right-shifted by INTEGER_BITS places.
+ * Destructive, primitive, do not use in any context except primitive
+ * operations on integers.
*
* @param val the value to represent;
* @param less_significant the less significant words of this bignum, if any,
@@ -106,7 +107,7 @@ __int128_t int128_to_integer( __int128_t val,
if ( MAX_INTEGER >= val ) {
carry = 0;
} else {
- carry = val >> 60;
+ carry = val >> INTEGER_BITS;
debug_printf( DEBUG_ARITH,
L"int128_to_integer: 64 bit overflow; setting carry to %ld\n",
( int64_t ) carry );
@@ -136,7 +137,7 @@ struct cons_pointer make_integer_128( __int128_t val,
less_significant =
make_integer( ( long int ) val & MAX_INTEGER,
less_significant );
- val = val >> 60;
+ val = val >> INTEGER_BITS;
}
} while ( nilp( result ) );
@@ -290,7 +291,7 @@ struct cons_pointer multiply_integers( struct cons_pointer a,
/* if xj exceeds one digit, break it into the digit dj and
* the carry */
- carry = xj >> 60;
+ carry = xj >> INTEGER_BITS;
struct cons_pointer dj = make_integer( xj & MAX_INTEGER, NIL );
/* destructively modify ri by appending dj */
@@ -361,7 +362,7 @@ struct cons_pointer integer_to_string( struct cons_pointer int_pointer,
while ( accumulator > 0 || !nilp( next ) ) {
if ( accumulator < MAX_INTEGER && !nilp( next ) ) {
accumulator +=
- ( pointer2cell( next ).payload.integer.value << 60 );
+ ( pointer2cell( next ).payload.integer.value << INTEGER_BITS );
next = pointer2cell( next ).payload.integer.more;
}
int offset = ( int ) ( accumulator % base );
diff --git a/src/arith/peano.h b/src/arith/peano.h
index b1d3087..163d47d 100644
--- a/src/arith/peano.h
+++ b/src/arith/peano.h
@@ -14,12 +14,13 @@
/**
* The maximum value we will allow in an integer cell.
- *
- * NOTE: 20250312 this is 2^60. WHY? Given that we're using the sign bit
- * inside the int64 record, we only have 63 value bits; but why did I decide
- * not to use all 63?
*/
-#define MAX_INTEGER ((__int128_t)0x0fffffffffffffffL)
+#define MAX_INTEGER ((__int128_t)0x7fffffffffffffffL)
+/**
+ * @brief Number of value bits in an integer cell
+ *
+ */
+#define INTEGER_BITS 63
bool zerop( struct cons_pointer arg );
diff --git a/state-of-play.md b/state-of-play.md
new file mode 100644
index 0000000..bd38ead
--- /dev/null
+++ b/state-of-play.md
@@ -0,0 +1,28 @@
+# State of Play
+
+## 20250313
+
+OK, the 60 bit integer cell happens in `int128_to_integer` in `arith/integer.c`. It seems to be being done consistently; but there is no obvious reason. `MAX_INTEGER` is defined in `arith/peano.h`. I've changed both to use 63 bits, and this makes no change to the number of unit tests that fail.
+
+With this change, `(fact 21)`, which was previously printing nothing, now prints a value, `11,891,611,015,076,642,816`. However, this value is definitively wrong, should be `51,090,942,171,709,440,000`. But, I hadn't fixed the shift in `integer_to_string`; have now... still no change in number of failed tests...
+
+But `(fact 21)` gives a different wrong value, `4,974,081,987,435,560,960`. Factorial values returned by `fact` are correct (agree with SBCL running the same code) up to `(fact 20)`, with both 60 bit integer cells and 63 bit integer cells giving correct values.
+
+Uhhhmmm... but I'd missed two other places where I'd had the number of significant bits as a numeric literal. Fixed those and now `(fact 21)` does not return a printable answer at all, although the internal representation is definitely wrong. So we may be seeing why I chose 60 bits.
+
+Bother.
+
+## 20250312
+
+Printing of bignums definitely doesn't work; I'm not persuaded that reading of bignums works right either, and there are probably problems with bignum arithmetic too.
+
+The internal memory representation of a number rolls over from one cell to two cells at 1152921504606846976, and I'm not at all certain why it does because this is neither 263 nor 264.
+
+| | | |
+| -------------- | -------------------- | ---- |
+| 262 | 4611686018427387904 | |
+| 263 | 9223372036854775808 | |
+| 264 | 18446744073709551616 | |
+| Mystery number | 1152921504606846976 | |
+
+In fact, our mystery number turns out (by inspection) to be 260. But **why**?