spec: math completeness — trig, quotient, gcd/lcm, radix number<->string
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Phase 15 implementation: - spec/primitives.sx: stdlib.math module — sin/cos/tan/asin/acos/atan/exp/log/expt/quotient/gcd/lcm/number->string/string->number (13 primitives) - JS platform: stdlib.math module; strict string->number parsing (rejects partial matches like "fg" in base 16) - OCaml: expt, quotient, gcd, lcm, number->string (radix), string->number (radix); atan updated to accept optional 2nd arg (atan2 form) - spec/tests/test-math.sx: 44 tests — trig/inverse trig, expt, quotient semantics, gcd/lcm, radix formatting/parsing, tower integration - JS: 2311/4801 (+2 net); OCaml: 4547/5629 (+1 net); zero regressions in math area Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -31,7 +31,7 @@
|
||||
// =========================================================================
|
||||
|
||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||
var SX_VERSION = "2026-05-01T12:34:38Z";
|
||||
var SX_VERSION = "2026-05-01T13:12:47Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -820,6 +820,49 @@
|
||||
};
|
||||
|
||||
|
||||
// stdlib.math
|
||||
PRIMITIVES["sin"] = Math.sin;
|
||||
PRIMITIVES["cos"] = Math.cos;
|
||||
PRIMITIVES["tan"] = Math.tan;
|
||||
PRIMITIVES["asin"] = Math.asin;
|
||||
PRIMITIVES["acos"] = Math.acos;
|
||||
PRIMITIVES["atan"] = function(y, x) { return arguments.length >= 2 ? Math.atan2(y, x) : Math.atan(y); };
|
||||
PRIMITIVES["exp"] = Math.exp;
|
||||
PRIMITIVES["log"] = Math.log;
|
||||
PRIMITIVES["expt"] = Math.pow;
|
||||
PRIMITIVES["quotient"] = function(a, b) { return Math.trunc(a / b); };
|
||||
PRIMITIVES["gcd"] = function(a, b) {
|
||||
a = Math.abs(a); b = Math.abs(b);
|
||||
while (b) { var t = b; b = a % b; a = t; }
|
||||
return a;
|
||||
};
|
||||
PRIMITIVES["lcm"] = function(a, b) {
|
||||
var g = PRIMITIVES["gcd"](Math.abs(a), Math.abs(b));
|
||||
return g === 0 ? 0 : Math.abs(a / g * b);
|
||||
};
|
||||
PRIMITIVES["number->string"] = function(n, r) {
|
||||
if (r === undefined || r === null) return String(n);
|
||||
return Math.floor(n).toString(r);
|
||||
};
|
||||
PRIMITIVES["string->number"] = function(s, r) {
|
||||
s = String(s);
|
||||
if (r !== undefined && r !== null) {
|
||||
var radix = r | 0;
|
||||
var valid = "0123456789abcdefghijklmnopqrstuvwxyz".slice(0, radix);
|
||||
var norm = s.toLowerCase();
|
||||
var start = norm[0] === '-' ? 1 : 0;
|
||||
if (norm.length <= start) return NIL;
|
||||
for (var i = start; i < norm.length; i++) {
|
||||
if (valid.indexOf(norm[i]) === -1) return NIL;
|
||||
}
|
||||
return parseInt(s, radix);
|
||||
}
|
||||
if (s === '') return NIL;
|
||||
var n = Number(s);
|
||||
return isNaN(n) ? NIL : n;
|
||||
};
|
||||
|
||||
|
||||
// stdlib.hash-table
|
||||
function SxHashTable() { this.data = new Map(); this._hash_table = true; }
|
||||
PRIMITIVES["make-hash-table"] = function() { return new SxHashTable(); };
|
||||
|
||||
Reference in New Issue
Block a user