From f36583b620a5bbdea82a5eaada2925c87dfbc985 Mon Sep 17 00:00:00 2001 From: giles Date: Sat, 7 Mar 2026 00:33:49 +0000 Subject: [PATCH] Fix: register append!/dict-set! in PRIMITIVES after it is defined The registrations were in the platform eval block which emits before var PRIMITIVES = {}. Moved to core.list and core.dict primitive sections. Co-Authored-By: Claude Opus 4.6 --- shared/static/scripts/sx-browser.js | 6 +++--- shared/sx/ref/bootstrap_js.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shared/static/scripts/sx-browser.js b/shared/static/scripts/sx-browser.js index 398f705..64b8fcd 100644 --- a/shared/static/scripts/sx-browser.js +++ b/shared/static/scripts/sx-browser.js @@ -14,7 +14,7 @@ // ========================================================================= var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } }); - var SX_VERSION = "2026-03-07T00:20:00Z"; + var SX_VERSION = "2026-03-07T00:33:33Z"; function isNil(x) { return x === NIL || x === null || x === undefined; } function isSxTruthy(x) { return x !== false && !isNil(x); } @@ -178,7 +178,6 @@ function envMerge(base, overlay) { return merge(base, overlay); } function dictSet(d, k, v) { d[k] = v; return v; } - PRIMITIVES["dict-set!"] = dictSet; function dictGet(d, k) { var v = d[k]; return v !== undefined ? v : NIL; } // Render-expression detection — lets the evaluator delegate to the active adapter. @@ -316,6 +315,7 @@ PRIMITIVES["nth"] = function(c, n) { return c && n >= 0 && n < c.length ? c[n] : NIL; }; PRIMITIVES["cons"] = function(x, c) { return [x].concat(c || []); }; PRIMITIVES["append"] = function(c, x) { return (c || []).concat([x]); }; + PRIMITIVES["append!"] = function(arr, x) { arr.push(x); return arr; }; PRIMITIVES["chunk-every"] = function(c, n) { var r = []; for (var i = 0; i < c.length; i += n) r.push(c.slice(i, i + n)); return r; }; @@ -342,6 +342,7 @@ for (var i = 1; i < arguments.length; i++) delete out[arguments[i]]; return out; }; + PRIMITIVES["dict-set!"] = function(d, k, v) { d[k] = v; return v; }; PRIMITIVES["into"] = function(target, coll) { if (Array.isArray(target)) return Array.isArray(coll) ? coll.slice() : Object.entries(coll); var r = {}; for (var i = 0; i < coll.length; i++) { var p = coll[i]; if (Array.isArray(p) && p.length >= 2) r[p[0]] = p[1]; } @@ -453,7 +454,6 @@ var range = PRIMITIVES["range"]; function zip(a, b) { var r = []; for (var i = 0; i < Math.min(a.length, b.length); i++) r.push([a[i], b[i]]); return r; } function append_b(arr, x) { arr.push(x); return arr; } - PRIMITIVES["append!"] = append_b; var apply = function(f, args) { return f.apply(null, args); }; // Additional primitive aliases used by adapter/engine transpiled code diff --git a/shared/sx/ref/bootstrap_js.py b/shared/sx/ref/bootstrap_js.py index 739b9a3..d87bc97 100644 --- a/shared/sx/ref/bootstrap_js.py +++ b/shared/sx/ref/bootstrap_js.py @@ -1500,6 +1500,7 @@ PRIMITIVES_JS_MODULES: dict[str, str] = { PRIMITIVES["nth"] = function(c, n) { return c && n >= 0 && n < c.length ? c[n] : NIL; }; PRIMITIVES["cons"] = function(x, c) { return [x].concat(c || []); }; PRIMITIVES["append"] = function(c, x) { return (c || []).concat([x]); }; + PRIMITIVES["append!"] = function(arr, x) { arr.push(x); return arr; }; PRIMITIVES["chunk-every"] = function(c, n) { var r = []; for (var i = 0; i < c.length; i += n) r.push(c.slice(i, i + n)); return r; }; @@ -1527,6 +1528,7 @@ PRIMITIVES_JS_MODULES: dict[str, str] = { for (var i = 1; i < arguments.length; i++) delete out[arguments[i]]; return out; }; + PRIMITIVES["dict-set!"] = function(d, k, v) { d[k] = v; return v; }; PRIMITIVES["into"] = function(target, coll) { if (Array.isArray(target)) return Array.isArray(coll) ? coll.slice() : Object.entries(coll); var r = {}; for (var i = 0; i < coll.length; i++) { var p = coll[i]; if (Array.isArray(p) && p.length >= 2) r[p[0]] = p[1]; } @@ -1712,7 +1714,6 @@ PLATFORM_JS_PRE = ''' function envMerge(base, overlay) { return merge(base, overlay); } function dictSet(d, k, v) { d[k] = v; return v; } - PRIMITIVES["dict-set!"] = dictSet; function dictGet(d, k) { var v = d[k]; return v !== undefined ? v : NIL; } // Render-expression detection — lets the evaluator delegate to the active adapter. @@ -1792,7 +1793,6 @@ PLATFORM_JS_POST = ''' var range = PRIMITIVES["range"]; function zip(a, b) { var r = []; for (var i = 0; i < Math.min(a.length, b.length); i++) r.push([a[i], b[i]]); return r; } function append_b(arr, x) { arr.push(x); return arr; } - PRIMITIVES["append!"] = append_b; var apply = function(f, args) { return f.apply(null, args); }; // Additional primitive aliases used by adapter/engine transpiled code