Fix 73 JS test failures: match transpiler, sxEq, deref frame, signals, stepper lib
Evaluator fixes (from broken match refactor in 8bba02f):
- Deref frame: use CEK state `value`, not `(get frame "value")`
- Deref frame: restore `(context "sx-reactive" nil)` (was undefined `get-tracking-context`)
- Scope-acc frame: restore missing `(get frame "value")` arg to make-scope-acc-frame
- Add missing `thread-insert-arg` helper for thread-first non-HO branch
Transpiler (hosts/javascript/transpiler.sx):
- Add `match` special form handler (IIFE with chained if/return, `_` wildcard)
- Replace `=`/`!=` infix `==` with `sxEq()` function call for proper symbol equality
JS platform (hosts/javascript/platform.py):
- Add `sxEq` for structural symbol/keyword comparison
- Add `componentFile`, `sort`, `defStore`/`useStore`/`clearStores` primitives
- Add `length`/`map`/`for-each`/`reduce` as VM-compatible HOF primitives
- Fix `SYM` → `makeSymbol` references
New files:
- sx/sx/stepper-lib.sx: extracted split-tag, build-code-tokens, steps-to-preview
JS tests: 0 → 1582/1585 passing (3 remaining are VM closure interop)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -835,6 +835,16 @@ PREAMBLE = '''\
|
||||
;(function(global) {
|
||||
"use strict";
|
||||
|
||||
// =========================================================================
|
||||
// Equality — used by transpiled code (= a b) → sxEq(a, b)
|
||||
// =========================================================================
|
||||
function sxEq(a, b) {
|
||||
if (a === b) return true;
|
||||
if (a && b && a._sym && b._sym) return a.name === b.name;
|
||||
if (a && b && a._kw && b._kw) return a.name === b.name;
|
||||
return false;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Types
|
||||
// =========================================================================
|
||||
@@ -944,8 +954,8 @@ PRIMITIVES_JS_MODULES: dict[str, str] = {
|
||||
|
||||
"core.comparison": '''
|
||||
// core.comparison
|
||||
PRIMITIVES["="] = function(a, b) { return a === b; };
|
||||
PRIMITIVES["!="] = function(a, b) { return a !== b; };
|
||||
PRIMITIVES["="] = sxEq;
|
||||
PRIMITIVES["!="] = function(a, b) { return !sxEq(a, b); };
|
||||
PRIMITIVES["<"] = function(a, b) { return a < b; };
|
||||
PRIMITIVES[">"] = function(a, b) { return a > b; };
|
||||
PRIMITIVES["<="] = function(a, b) { return a <= b; };
|
||||
@@ -1306,6 +1316,7 @@ PLATFORM_JS_PRE = '''
|
||||
function componentClosure(c) { return c.closure; }
|
||||
function componentHasChildren(c) { return c.hasChildren; }
|
||||
function componentName(c) { return c.name; }
|
||||
function componentFile(c) { return (c && c.file) ? c.file : NIL; }
|
||||
function componentAffinity(c) { return c.affinity || "auto"; }
|
||||
function componentParamTypes(c) { return (c && c._paramTypes) ? c._paramTypes : NIL; }
|
||||
function componentSetParamTypes_b(c, t) { if (c) c._paramTypes = t; return NIL; }
|
||||
@@ -2669,12 +2680,12 @@ PLATFORM_ORCHESTRATION_JS = """
|
||||
function cekTry(thunkFn, handlerFn) {
|
||||
try {
|
||||
var result = _wrapSxFn(thunkFn)();
|
||||
if (!handlerFn || handlerFn === NIL) return [SYM("ok"), result];
|
||||
if (!handlerFn || handlerFn === NIL) return [makeSymbol("ok"), result];
|
||||
return result;
|
||||
} catch (e) {
|
||||
var msg = (e && e.message) ? e.message : String(e);
|
||||
if (handlerFn && handlerFn !== NIL) return _wrapSxFn(handlerFn)(msg);
|
||||
return [SYM("error"), msg];
|
||||
return [makeSymbol("error"), msg];
|
||||
}
|
||||
}
|
||||
function errorMessage(e) {
|
||||
@@ -3223,6 +3234,43 @@ def fixups_js(has_html, has_sx, has_dom, has_signals=False, has_deps=False, has_
|
||||
// Core primitives that require native JS (cannot be expressed via FFI)
|
||||
// -----------------------------------------------------------------------
|
||||
PRIMITIVES["error"] = function(msg) { throw new Error(msg); };
|
||||
PRIMITIVES["sort"] = function(lst) {
|
||||
if (!Array.isArray(lst)) return lst;
|
||||
return lst.slice().sort(function(a, b) {
|
||||
if (a < b) return -1; if (a > b) return 1; return 0;
|
||||
});
|
||||
};
|
||||
|
||||
// Aliases for VM bytecode compatibility
|
||||
PRIMITIVES["length"] = PRIMITIVES["len"];
|
||||
// VM-compatible HOF primitives — use callPrimFn which handles native, lambda, and VM closures
|
||||
function callPrimFn(f, args) {
|
||||
if (typeof f === "function") return f.apply(null, args);
|
||||
if (f && f._lambda) return cekCall(f, args);
|
||||
if (f && f["vm-code"]) {
|
||||
// VM closure — call through call-primitive dispatch
|
||||
var cp = PRIMITIVES["vm-call-closure"];
|
||||
if (cp) return cp(f, args);
|
||||
}
|
||||
return cekCall(f, args);
|
||||
}
|
||||
PRIMITIVES["map"] = function(fn, lst) {
|
||||
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = tmp; }
|
||||
var result = [];
|
||||
for (var i = 0; i < lst.length; i++) result.push(callPrimFn(fn, [lst[i]]));
|
||||
return result;
|
||||
};
|
||||
PRIMITIVES["for-each"] = function(fn, lst) {
|
||||
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = tmp; }
|
||||
for (var i = 0; i < lst.length; i++) callPrimFn(fn, [lst[i]]);
|
||||
return NIL;
|
||||
};
|
||||
PRIMITIVES["reduce"] = function(fn, init, lst) {
|
||||
if (Array.isArray(fn)) { var tmp = fn; fn = lst; lst = init; init = tmp; }
|
||||
var acc = init;
|
||||
for (var i = 0; i < lst.length; i++) acc = callPrimFn(fn, [acc, lst[i]]);
|
||||
return acc;
|
||||
};
|
||||
|
||||
// FFI library functions — defined in dom.sx/browser.sx but not transpiled.
|
||||
// Registered here so runtime-evaluated SX code (data-init, islands) can use them.
|
||||
@@ -3303,14 +3351,30 @@ def fixups_js(has_html, has_sx, has_dom, has_signals=False, has_deps=False, has_
|
||||
PRIMITIVES["cek-try"] = function(thunkFn, handlerFn) {
|
||||
try {
|
||||
var result = _wrapSxFn(thunkFn)();
|
||||
if (!handlerFn || handlerFn === NIL) return [SYM("ok"), result];
|
||||
if (!handlerFn || handlerFn === NIL) return [makeSymbol("ok"), result];
|
||||
return result;
|
||||
} catch (e) {
|
||||
var msg = (e && e.message) ? e.message : String(e);
|
||||
if (handlerFn && handlerFn !== NIL) return _wrapSxFn(handlerFn)(msg);
|
||||
return [SYM("error"), msg];
|
||||
return [makeSymbol("error"), msg];
|
||||
}
|
||||
};''']
|
||||
};
|
||||
// Named stores — global mutable registry (mirrors OCaml sx_primitives.ml)
|
||||
var _storeRegistry = {};
|
||||
function defStore(name, initFn) {
|
||||
if (!_storeRegistry.hasOwnProperty(name)) {
|
||||
_storeRegistry[name] = _wrapSxFn(initFn)();
|
||||
}
|
||||
return _storeRegistry[name];
|
||||
}
|
||||
function useStore(name) {
|
||||
if (!_storeRegistry.hasOwnProperty(name)) throw new Error("Store not found: " + name);
|
||||
return _storeRegistry[name];
|
||||
}
|
||||
function clearStores() { _storeRegistry = {}; return NIL; }
|
||||
PRIMITIVES["def-store"] = defStore;
|
||||
PRIMITIVES["use-store"] = useStore;
|
||||
PRIMITIVES["clear-stores"] = clearStores;''']
|
||||
if has_deps:
|
||||
lines.append('''
|
||||
// Platform deps functions (native JS, not transpiled — need explicit registration)
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-0f97ea07.wasm
Normal file
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-0f97ea07.wasm
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user