c-tier bignum — arbitrary-precision integers unblock secp256k1 widths
Adds tagged bignum support alongside the existing 48-bit fixnum on the C tier. Tag 6 = bignum, heap struct sign-magnitude with u64 little-endian limbs. Reader emits bignums for any literal past the fixnum range; +, -, *, quotient, remainder, modulo, expt, =, <, >, abs, odd?, even?, integer?, exact?, number->string, string->number all promote fixnum → bignum on overflow & demote back when results fit. Boehm GC owns every allocation. Schoolbook O(n²) mul + shift-subtract divmod is sufficient at our 4-limb / 256-bit scale. Before: (expt 2 48) = 0, (expt 2 256) = 0, secp256k1-p = -4294968273. After: all three return their exact arbitrary-precision values, matching Python tier byte-for-byte. Validated: - c/test.c — 85/85 pass (+2 new bignum unit tests). - tests/functional.lsp — 205/205 pass on both C & Python tiers. - tests/bignum-cross-tier.lsp — 33/33 pass byte-identical on both tiers (diff produces no output). - ecdsa/runs/lumbda-sweep-003/c-tier-bignum-probe.lsp — all four assertions now match the Python oracle. - ecdsa Phase B byte-identity sweep inside QEMU guest: n+1=9 p=251 sha256 c668bbe3... — matches Python oracle. n+1=18 p=131071 sha256 8a031f96... — matches Python oracle. n+1=33 p=2³²-5 sha256 0bc56905... — matches Python oracle. Previously the n+1=33 C tier emitted sha256 b024d6d9... (26,078 fewer Toffolis due to silent fixnum wrap). Bignums close that gate. secp256k1 production-width emit (n+1=257) is now structurally unblocked on C tier; downstream agent (#55) drives that next-step on the ecdsa side. Asm tier inherits in a follow-up port.
This commit is contained in:
parent
cf68c0da15
commit
2f342c3be2
11 changed files with 918 additions and 29 deletions
6
c/eval.c
6
c/eval.c
|
|
@ -480,7 +480,7 @@ static bool is_literal(SyntaxTransformer *st, const char *name) {
|
|||
static bool sr_match(SyntaxTransformer *st, Value pat, Value form, Env *bindings) {
|
||||
if (IS_NIL(pat)) return IS_NIL(form);
|
||||
if (pat == VAL_TRUE || pat == VAL_FALSE) return pat == form;
|
||||
if (IS_INT(pat) || IS_DOUBLE(pat)) return values_equal(pat, form);
|
||||
if (IS_INT(pat) || IS_DOUBLE(pat) || IS_BIGNUM(pat)) return values_equal(pat, form);
|
||||
|
||||
if (IS_SYM(pat)) {
|
||||
const char *pname = sym_name(pat);
|
||||
|
|
@ -573,7 +573,7 @@ static bool sr_match(SyntaxTransformer *st, Value pat, Value form, Env *bindings
|
|||
|
||||
static Value sr_expand(SyntaxTransformer *st, Value tmpl, Env *bindings) {
|
||||
if (IS_NIL(tmpl) || tmpl == VAL_TRUE || tmpl == VAL_FALSE) return tmpl;
|
||||
if (IS_INT(tmpl) || IS_DOUBLE(tmpl)) return tmpl;
|
||||
if (IS_INT(tmpl) || IS_DOUBLE(tmpl) || IS_BIGNUM(tmpl)) return tmpl;
|
||||
if (IS_STRING(tmpl)) return tmpl;
|
||||
|
||||
if (IS_SYM(tmpl)) {
|
||||
|
|
@ -669,7 +669,7 @@ Value leval(Value expr, Env *env) {
|
|||
/* Self-evaluating */
|
||||
if (IS_NIL(expr) || IS_VOID(expr) || IS_TRUE(expr) || IS_FALSE(expr) ||
|
||||
IS_EOF(expr) || IS_CHAR(expr)) return expr;
|
||||
if (IS_INT(expr) || IS_DOUBLE(expr) || IS_RATIONAL(expr)) return expr;
|
||||
if (IS_INT(expr) || IS_DOUBLE(expr) || IS_RATIONAL(expr) || IS_BIGNUM(expr)) return expr;
|
||||
if (IS_STRING(expr)) return expr;
|
||||
if (IS_VECTOR(expr)) return expr;
|
||||
if (IS_BUILTIN(expr)) return expr;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue