js: numeric tower — integer?/float?/exact?/inexact? + epoch Integer fix
Add integer?/float?/exact?/inexact? predicates (Number.isInteger check). Add truncate/remainder/modulo/random-int/exact->inexact/inexact->exact/parse-number. inexact->exact uses Math.round (rounds to nearest, matching OCaml). Fix sx_server.ml epoch/blob/io-response protocol to accept Integer as well as Number — parser now produces Integer for whole-number literals. JS: 60 new passing tests (1880→1940). OCaml: 4874/394 baseline unchanged. Note: 6 tests fail in JS due to platform limitation (JS cannot distinguish float 2.0 from integer 2). 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-04-26T10:01:22Z";
|
||||
var SX_VERSION = "2026-04-26T12:42:00Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -387,11 +387,18 @@
|
||||
if (n === undefined || n === 0) return Math.round(x);
|
||||
var f = Math.pow(10, n); return Math.round(x * f) / f;
|
||||
};
|
||||
PRIMITIVES["truncate"] = Math.trunc;
|
||||
PRIMITIVES["remainder"] = function(a, b) { return a % b; };
|
||||
PRIMITIVES["modulo"] = function(a, b) { var r = a % b; return (r !== 0 && (r < 0) !== (b < 0)) ? r + b : r; };
|
||||
PRIMITIVES["min"] = Math.min;
|
||||
PRIMITIVES["max"] = Math.max;
|
||||
PRIMITIVES["sqrt"] = Math.sqrt;
|
||||
PRIMITIVES["pow"] = Math.pow;
|
||||
PRIMITIVES["clamp"] = function(x, lo, hi) { return Math.max(lo, Math.min(hi, x)); };
|
||||
PRIMITIVES["random-int"] = function(lo, hi) { return Math.floor(Math.random() * (hi - lo + 1)) + lo; };
|
||||
PRIMITIVES["exact->inexact"] = function(x) { return x; };
|
||||
PRIMITIVES["inexact->exact"] = Math.round;
|
||||
PRIMITIVES["parse-number"] = function(s) { var n = Number(s); return isNaN(n) ? null : n; };
|
||||
|
||||
|
||||
// core.comparison
|
||||
@@ -410,6 +417,10 @@
|
||||
// core.predicates
|
||||
PRIMITIVES["nil?"] = isNil;
|
||||
PRIMITIVES["number?"] = function(x) { return typeof x === "number"; };
|
||||
PRIMITIVES["integer?"] = function(x) { return typeof x === "number" && Number.isInteger(x); };
|
||||
PRIMITIVES["float?"] = function(x) { return typeof x === "number" && !Number.isInteger(x); };
|
||||
PRIMITIVES["exact?"] = function(x) { return typeof x === "number" && Number.isInteger(x); };
|
||||
PRIMITIVES["inexact?"] = function(x) { return typeof x === "number" && !Number.isInteger(x); };
|
||||
PRIMITIVES["string?"] = function(x) { return typeof x === "string"; };
|
||||
PRIMITIVES["list?"] = Array.isArray;
|
||||
PRIMITIVES["dict?"] = function(x) { return x !== null && typeof x === "object" && !Array.isArray(x) && !x._sym && !x._kw; };
|
||||
|
||||
Reference in New Issue
Block a user