Bootstrap CEK as default evaluator on both JS and Python sides

SPEC_MODULES + SPEC_MODULE_ORDER for frames/cek in platform_js.py,
PLATFORM_CEK_JS + CEK_FIXUPS_JS constants, auto-inclusion in
run_js_sx.py, 70+ RENAMES in js.sx. Python: CEK always-include in
bootstrap_py.py, eval_expr/trampoline overridden to cek_run in
platform_py.py with _tree_walk_* preserved for test runners.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-14 01:13:11 +00:00
parent f3a9f3ccc0
commit 90febbd91e
7 changed files with 2005 additions and 110 deletions

View File

@@ -14,7 +14,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-13T23:56:11Z";
var SX_VERSION = "2026-03-14T01:00:32Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
@@ -2428,6 +2428,37 @@ return (isSxTruthy(testFn()) ? (function() {
return domListen(el, (isSxTruthy(isCheckbox) ? "change" : "input"), function(e) { return (isSxTruthy(isCheckbox) ? reset_b(sig, domGetProp(el, "checked")) : reset_b(sig, domGetProp(el, "value"))); });
})(); };
// *use-cek-reactive*
var _useCekReactive = true;
// enable-cek-reactive!
var enableCekReactive = function() { return (_useCekReactive = true); };
// cek-reactive-text
var cekReactiveText = function(expr, env) { return (function() {
var node = createTextNode("");
var updateFn = function(val) { return domSetTextContent(node, (String(val))); };
return (function() {
var initial = cekRun(makeCekState(expr, env, [makeReactiveResetFrame(env, updateFn, true)]));
domSetTextContent(node, (String(initial)));
return node;
})();
})(); };
// cek-reactive-attr
var cekReactiveAttr = function(el, attrName, expr, env) { return (function() {
var updateFn = function(val) { return (isSxTruthy(sxOr(isNil(val), (val == false))) ? domRemoveAttr(el, attrName) : (isSxTruthy((val == true)) ? domSetAttr(el, attrName, "") : domSetAttr(el, attrName, (String(val))))); };
(function() {
var existing = sxOr(domGetAttr(el, "data-sx-reactive-attrs"), "");
var updated = (isSxTruthy(isEmpty(existing)) ? attrName : (String(existing) + String(",") + String(attrName)));
return domSetAttr(el, "data-sx-reactive-attrs", updated);
})();
return (function() {
var initial = cekRun(makeCekState(expr, env, [makeReactiveResetFrame(env, updateFn, true)]));
return invoke(updateFn, initial);
})();
})(); };
// render-dom-portal
var renderDomPortal = function(args, env, ns) { return (function() {
var selector = trampoline(evalExpr(first(args), env));
@@ -3812,6 +3843,134 @@ callExpr.push(dictGet(kwargs, k)); } }
})(); }, keys(env)); };
// === Transpiled from frames (CEK continuation frames) ===
// make-cek-state
var makeCekState = function(control, env, kont) { return {"control": control, "env": env, "kont": kont, "phase": "eval", "value": NIL}; };
// make-cek-value
var makeCekValue = function(value, env, kont) { return {"control": NIL, "env": env, "kont": kont, "phase": "continue", "value": value}; };
// cek-terminal?
var cekTerminal_p = function(state) { return (isSxTruthy((get(state, "phase") == "continue")) && isEmpty(get(state, "kont"))); };
// cek-control
var cekControl = function(s) { return get(s, "control"); };
// cek-env
var cekEnv = function(s) { return get(s, "env"); };
// cek-kont
var cekKont = function(s) { return get(s, "kont"); };
// cek-phase
var cekPhase = function(s) { return get(s, "phase"); };
// cek-value
var cekValue = function(s) { return get(s, "value"); };
// make-if-frame
var makeIfFrame = function(thenExpr, elseExpr, env) { return {"type": "if", "then": thenExpr, "else": elseExpr, "env": env}; };
// make-when-frame
var makeWhenFrame = function(bodyExprs, env) { return {"type": "when", "body": bodyExprs, "env": env}; };
// make-begin-frame
var makeBeginFrame = function(remaining, env) { return {"type": "begin", "remaining": remaining, "env": env}; };
// make-let-frame
var makeLetFrame = function(name, remaining, body, local) { return {"type": "let", "name": name, "remaining": remaining, "body": body, "env": local}; };
// make-define-frame
var makeDefineFrame = function(name, env, hasEffects, effectList) { return {"type": "define", "name": name, "env": env, "has-effects": hasEffects, "effect-list": effectList}; };
// make-set-frame
var makeSetFrame = function(name, env) { return {"type": "set", "name": name, "env": env}; };
// make-arg-frame
var makeArgFrame = function(f, evaled, remaining, env, rawArgs) { return {"type": "arg", "f": f, "evaled": evaled, "remaining": remaining, "env": env, "raw-args": rawArgs}; };
// make-call-frame
var makeCallFrame = function(f, args, env) { return {"type": "call", "f": f, "args": args, "env": env}; };
// make-cond-frame
var makeCondFrame = function(remaining, env, scheme_p) { return {"type": "cond", "remaining": remaining, "env": env, "scheme": scheme_p}; };
// make-case-frame
var makeCaseFrame = function(matchVal, remaining, env) { return {"type": "case", "match-val": matchVal, "remaining": remaining, "env": env}; };
// make-thread-frame
var makeThreadFrame = function(remaining, env) { return {"type": "thread", "remaining": remaining, "env": env}; };
// make-map-frame
var makeMapFrame = function(f, remaining, results, env) { return {"type": "map", "f": f, "remaining": remaining, "results": results, "env": env}; };
// make-filter-frame
var makeFilterFrame = function(f, remaining, results, currentItem, env) { return {"type": "filter", "f": f, "remaining": remaining, "results": results, "current-item": currentItem, "env": env}; };
// make-reduce-frame
var makeReduceFrame = function(f, remaining, env) { return {"type": "reduce", "f": f, "remaining": remaining, "env": env}; };
// make-for-each-frame
var makeForEachFrame = function(f, remaining, env) { return {"type": "for-each", "f": f, "remaining": remaining, "env": env}; };
// make-scope-frame
var makeScopeFrame = function(name, remaining, env) { return {"type": "scope", "name": name, "remaining": remaining, "env": env}; };
// make-reset-frame
var makeResetFrame = function(env) { return {"type": "reset", "env": env}; };
// make-dict-frame
var makeDictFrame = function(remaining, results, env) { return {"type": "dict", "remaining": remaining, "results": results, "env": env}; };
// make-and-frame
var makeAndFrame = function(remaining, env) { return {"type": "and", "remaining": remaining, "env": env}; };
// make-or-frame
var makeOrFrame = function(remaining, env) { return {"type": "or", "remaining": remaining, "env": env}; };
// make-dynamic-wind-frame
var makeDynamicWindFrame = function(phase, bodyThunk, afterThunk, env) { return {"type": "dynamic-wind", "phase": phase, "body-thunk": bodyThunk, "after-thunk": afterThunk, "env": env}; };
// make-reactive-reset-frame
var makeReactiveResetFrame = function(env, updateFn, firstRender_p) { return {"type": "reactive-reset", "env": env, "update-fn": updateFn, "first-render": firstRender_p}; };
// make-deref-frame
var makeDerefFrame = function(env) { return {"type": "deref", "env": env}; };
// frame-type
var frameType = function(f) { return get(f, "type"); };
// kont-push
var kontPush = function(frame, kont) { return cons(frame, kont); };
// kont-top
var kontTop = function(kont) { return first(kont); };
// kont-pop
var kontPop = function(kont) { return rest(kont); };
// kont-empty?
var kontEmpty_p = function(kont) { return isEmpty(kont); };
// kont-capture-to-reset
var kontCaptureToReset = function(kont) { var scan = function(k, captured) { return (isSxTruthy(isEmpty(k)) ? error("shift without enclosing reset") : (function() {
var frame = first(k);
return (isSxTruthy(sxOr((frameType(frame) == "reset"), (frameType(frame) == "reactive-reset"))) ? [captured, rest(k)] : scan(rest(k), append(captured, [frame])));
})()); };
return scan(kont, []); };
// has-reactive-reset-frame?
var hasReactiveResetFrame_p = function(kont) { return (isSxTruthy(isEmpty(kont)) ? false : (isSxTruthy((frameType(first(kont)) == "reactive-reset")) ? true : hasReactiveResetFrame_p(rest(kont)))); };
// kont-capture-to-reactive-reset
var kontCaptureToReactiveReset = function(kont) { var scan = function(k, captured) { return (isSxTruthy(isEmpty(k)) ? error("reactive deref without enclosing reactive-reset") : (function() {
var frame = first(k);
return (isSxTruthy((frameType(frame) == "reactive-reset")) ? [captured, frame, rest(k)] : scan(rest(k), append(captured, [frame])));
})()); };
return scan(kont, []); };
// === Transpiled from page-helpers (pure data transformation helpers) ===
// special-form-category-map
@@ -4444,6 +4603,383 @@ return (function() {
})(); };
// === Transpiled from cek (explicit CEK machine evaluator) ===
// cek-run
var cekRun = function(state) { return (isSxTruthy(cekTerminal_p(state)) ? cekValue(state) : cekRun(cekStep(state))); };
// cek-step
var cekStep = function(state) { return (isSxTruthy((cekPhase(state) == "eval")) ? stepEval(state) : stepContinue(state)); };
// step-eval
var stepEval = function(state) { return (function() {
var expr = cekControl(state);
var env = cekEnv(state);
var kont = cekKont(state);
return (function() { var _m = typeOf(expr); if (_m == "number") return makeCekValue(expr, env, kont); if (_m == "string") return makeCekValue(expr, env, kont); if (_m == "boolean") return makeCekValue(expr, env, kont); if (_m == "nil") return makeCekValue(NIL, env, kont); if (_m == "symbol") return (function() {
var name = symbolName(expr);
return (function() {
var val = (isSxTruthy(envHas(env, name)) ? envGet(env, name) : (isSxTruthy(isPrimitive(name)) ? getPrimitive(name) : (isSxTruthy((name == "true")) ? true : (isSxTruthy((name == "false")) ? false : (isSxTruthy((name == "nil")) ? NIL : error((String("Undefined symbol: ") + String(name))))))));
return makeCekValue(val, env, kont);
})();
})(); if (_m == "keyword") return makeCekValue(keywordName(expr), env, kont); if (_m == "dict") return (function() {
var ks = keys(expr);
return (isSxTruthy(isEmpty(ks)) ? makeCekValue({}, env, kont) : (function() {
var firstKey = first(ks);
var remainingEntries = [];
{ var _c = rest(ks); for (var _i = 0; _i < _c.length; _i++) { var k = _c[_i]; remainingEntries.push([k, get(expr, k)]); } }
return makeCekState(get(expr, firstKey), env, kontPush(makeDictFrame(remainingEntries, [[firstKey]], env), kont));
})());
})(); if (_m == "list") return (isSxTruthy(isEmpty(expr)) ? makeCekValue([], env, kont) : stepEvalList(expr, env, kont)); return makeCekValue(expr, env, kont); })();
})(); };
// step-eval-list
var stepEvalList = function(expr, env, kont) { return (function() {
var head = first(expr);
var args = rest(expr);
return (isSxTruthy(!isSxTruthy(sxOr((typeOf(head) == "symbol"), (typeOf(head) == "lambda"), (typeOf(head) == "list")))) ? (isSxTruthy(isEmpty(expr)) ? makeCekValue([], env, kont) : makeCekState(first(expr), env, kontPush(makeMapFrame(NIL, rest(expr), [], env), kont))) : (isSxTruthy((typeOf(head) == "symbol")) ? (function() {
var name = symbolName(head);
return (isSxTruthy((name == "if")) ? stepSfIf(args, env, kont) : (isSxTruthy((name == "when")) ? stepSfWhen(args, env, kont) : (isSxTruthy((name == "cond")) ? stepSfCond(args, env, kont) : (isSxTruthy((name == "case")) ? stepSfCase(args, env, kont) : (isSxTruthy((name == "and")) ? stepSfAnd(args, env, kont) : (isSxTruthy((name == "or")) ? stepSfOr(args, env, kont) : (isSxTruthy((name == "let")) ? stepSfLet(args, env, kont) : (isSxTruthy((name == "let*")) ? stepSfLet(args, env, kont) : (isSxTruthy((name == "lambda")) ? stepSfLambda(args, env, kont) : (isSxTruthy((name == "fn")) ? stepSfLambda(args, env, kont) : (isSxTruthy((name == "define")) ? stepSfDefine(args, env, kont) : (isSxTruthy((name == "defcomp")) ? makeCekValue(sfDefcomp(args, env), env, kont) : (isSxTruthy((name == "defisland")) ? makeCekValue(sfDefisland(args, env), env, kont) : (isSxTruthy((name == "defmacro")) ? makeCekValue(sfDefmacro(args, env), env, kont) : (isSxTruthy((name == "defstyle")) ? makeCekValue(sfDefstyle(args, env), env, kont) : (isSxTruthy((name == "defhandler")) ? makeCekValue(sfDefhandler(args, env), env, kont) : (isSxTruthy((name == "defpage")) ? makeCekValue(sfDefpage(args, env), env, kont) : (isSxTruthy((name == "defquery")) ? makeCekValue(sfDefquery(args, env), env, kont) : (isSxTruthy((name == "defaction")) ? makeCekValue(sfDefaction(args, env), env, kont) : (isSxTruthy((name == "deftype")) ? makeCekValue(sfDeftype(args, env), env, kont) : (isSxTruthy((name == "defeffect")) ? makeCekValue(sfDefeffect(args, env), env, kont) : (isSxTruthy((name == "begin")) ? stepSfBegin(args, env, kont) : (isSxTruthy((name == "do")) ? stepSfBegin(args, env, kont) : (isSxTruthy((name == "quote")) ? makeCekValue((isSxTruthy(isEmpty(args)) ? NIL : first(args)), env, kont) : (isSxTruthy((name == "quasiquote")) ? makeCekValue(qqExpand(first(args), env), env, kont) : (isSxTruthy((name == "->")) ? stepSfThreadFirst(args, env, kont) : (isSxTruthy((name == "set!")) ? stepSfSet(args, env, kont) : (isSxTruthy((name == "letrec")) ? makeCekValue(sfLetrec(args, env), env, kont) : (isSxTruthy((name == "reset")) ? stepSfReset(args, env, kont) : (isSxTruthy((name == "shift")) ? stepSfShift(args, env, kont) : (isSxTruthy((name == "deref")) ? stepSfDeref(args, env, kont) : (isSxTruthy((name == "scope")) ? stepSfScope(args, env, kont) : (isSxTruthy((name == "provide")) ? stepSfProvide(args, env, kont) : (isSxTruthy((name == "dynamic-wind")) ? makeCekValue(sfDynamicWind(args, env), env, kont) : (isSxTruthy((name == "map")) ? stepHoMap(args, env, kont) : (isSxTruthy((name == "map-indexed")) ? makeCekValue(hoMapIndexed(args, env), env, kont) : (isSxTruthy((name == "filter")) ? stepHoFilter(args, env, kont) : (isSxTruthy((name == "reduce")) ? stepHoReduce(args, env, kont) : (isSxTruthy((name == "some")) ? makeCekValue(hoSome(args, env), env, kont) : (isSxTruthy((name == "every?")) ? makeCekValue(hoEvery(args, env), env, kont) : (isSxTruthy((name == "for-each")) ? stepHoForEach(args, env, kont) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? (function() {
var mac = envGet(env, name);
return makeCekState(expandMacro(mac, args, env), env, kont);
})() : (isSxTruthy((isSxTruthy(renderActiveP()) && isRenderExpr(expr))) ? makeCekValue(renderExpr(expr, env), env, kont) : stepEvalCall(head, args, env, kont))))))))))))))))))))))))))))))))))))))))))));
})() : stepEvalCall(head, args, env, kont)));
})(); };
// step-sf-if
var stepSfIf = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeIfFrame(nth(args, 1), (isSxTruthy((len(args) > 2)) ? nth(args, 2) : NIL), env), kont)); };
// step-sf-when
var stepSfWhen = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeWhenFrame(rest(args), env), kont)); };
// step-sf-begin
var stepSfBegin = function(args, env, kont) { return (isSxTruthy(isEmpty(args)) ? makeCekValue(NIL, env, kont) : (isSxTruthy((len(args) == 1)) ? makeCekState(first(args), env, kont) : makeCekState(first(args), env, kontPush(makeBeginFrame(rest(args), env), kont)))); };
// step-sf-let
var stepSfLet = function(args, env, kont) { return (isSxTruthy((typeOf(first(args)) == "symbol")) ? makeCekValue(sfNamedLet(args, env), env, kont) : (function() {
var bindings = first(args);
var body = rest(args);
var local = envExtend(env);
return (isSxTruthy(isEmpty(bindings)) ? stepSfBegin(body, local, kont) : (function() {
var firstBinding = (isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? first(bindings) : [first(bindings), nth(bindings, 1)]);
var restBindings = (isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? rest(bindings) : (function() {
var pairs = [];
reduce(function(acc, i) { return append_b(pairs, [nth(bindings, (i * 2)), nth(bindings, ((i * 2) + 1))]); }, NIL, range(1, (len(bindings) / 2)));
return pairs;
})());
return (function() {
var vname = (isSxTruthy((typeOf(first(firstBinding)) == "symbol")) ? symbolName(first(firstBinding)) : first(firstBinding));
return makeCekState(nth(firstBinding, 1), local, kontPush(makeLetFrame(vname, restBindings, body, local), kont));
})();
})());
})()); };
// step-sf-define
var stepSfDefine = function(args, env, kont) { return (function() {
var nameSym = first(args);
var hasEffects = (isSxTruthy((len(args) >= 4)) && isSxTruthy((typeOf(nth(args, 1)) == "keyword")) && (keywordName(nth(args, 1)) == "effects"));
var valIdx = (isSxTruthy((isSxTruthy((len(args) >= 4)) && isSxTruthy((typeOf(nth(args, 1)) == "keyword")) && (keywordName(nth(args, 1)) == "effects"))) ? 3 : 1);
var effectList = (isSxTruthy((isSxTruthy((len(args) >= 4)) && isSxTruthy((typeOf(nth(args, 1)) == "keyword")) && (keywordName(nth(args, 1)) == "effects"))) ? nth(args, 2) : NIL);
return makeCekState(nth(args, valIdx), env, kontPush(makeDefineFrame(symbolName(nameSym), env, hasEffects, effectList), kont));
})(); };
// step-sf-set!
var stepSfSet = function(args, env, kont) { return makeCekState(nth(args, 1), env, kontPush(makeSetFrame(symbolName(first(args)), env), kont)); };
// step-sf-and
var stepSfAnd = function(args, env, kont) { return (isSxTruthy(isEmpty(args)) ? makeCekValue(true, env, kont) : makeCekState(first(args), env, kontPush(makeAndFrame(rest(args), env), kont))); };
// step-sf-or
var stepSfOr = function(args, env, kont) { return (isSxTruthy(isEmpty(args)) ? makeCekValue(false, env, kont) : makeCekState(first(args), env, kontPush(makeOrFrame(rest(args), env), kont))); };
// step-sf-cond
var stepSfCond = function(args, env, kont) { return (function() {
var scheme_p = condScheme_p(args);
return (isSxTruthy(scheme_p) ? (isSxTruthy(isEmpty(args)) ? makeCekValue(NIL, env, kont) : (function() {
var clause = first(args);
var test = first(clause);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))), (isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")))) ? makeCekState(nth(clause, 1), env, kont) : makeCekState(test, env, kontPush(makeCondFrame(args, env, true), kont)));
})()) : (isSxTruthy((len(args) < 2)) ? makeCekValue(NIL, env, kont) : (function() {
var test = first(args);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))))) ? makeCekState(nth(args, 1), env, kont) : makeCekState(test, env, kontPush(makeCondFrame(args, env, false), kont)));
})()));
})(); };
// step-sf-case
var stepSfCase = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeCaseFrame(NIL, rest(args), env), kont)); };
// step-sf-thread-first
var stepSfThreadFirst = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeThreadFrame(rest(args), env), kont)); };
// step-sf-lambda
var stepSfLambda = function(args, env, kont) { return makeCekValue(sfLambda(args, env), env, kont); };
// step-sf-scope
var stepSfScope = function(args, env, kont) { return makeCekValue(sfScope(args, env), env, kont); };
// step-sf-provide
var stepSfProvide = function(args, env, kont) { return makeCekValue(sfProvide(args, env), env, kont); };
// step-sf-reset
var stepSfReset = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeResetFrame(env), kont)); };
// step-sf-shift
var stepSfShift = function(args, env, kont) { return (function() {
var kName = symbolName(first(args));
var body = nth(args, 1);
var capturedResult = kontCaptureToReset(kont);
var captured = first(capturedResult);
var restKont = nth(capturedResult, 1);
return (function() {
var k = makeCekContinuation(captured, restKont);
return (function() {
var shiftEnv = envExtend(env);
envSet(shiftEnv, kName, k);
return makeCekState(body, shiftEnv, restKont);
})();
})();
})(); };
// step-sf-deref
var stepSfDeref = function(args, env, kont) { return makeCekState(first(args), env, kontPush(makeDerefFrame(env), kont)); };
// reactive-shift-deref
var reactiveShiftDeref = function(sig, env, kont) { return (function() {
var scanResult = kontCaptureToReactiveReset(kont);
var capturedFrames = first(scanResult);
var resetFrame = nth(scanResult, 1);
var remainingKont = nth(scanResult, 2);
var updateFn = get(resetFrame, "update-fn");
return (function() {
var subDisposers = [];
return (function() {
var subscriber = function() { { var _c = subDisposers; for (var _i = 0; _i < _c.length; _i++) { var d = _c[_i]; invoke(d); } }
subDisposers = [];
return (function() {
var newReset = makeReactiveResetFrame(env, updateFn, false);
var newKont = concat(capturedFrames, [newReset], remainingKont);
return withIslandScope(function(d) { return append_b(subDisposers, d); }, function() { return cekRun(makeCekValue(signalValue(sig), env, newKont)); });
})(); };
signalAddSub(sig, subscriber);
registerInScope(function() { signalRemoveSub(sig, subscriber);
return forEach(function(d) { return invoke(d); }, subDisposers); });
return (function() {
var initialKont = concat(capturedFrames, [resetFrame], remainingKont);
return makeCekValue(signalValue(sig), env, initialKont);
})();
})();
})();
})(); };
// step-eval-call
var stepEvalCall = function(head, args, env, kont) { return makeCekState(head, env, kontPush(makeArgFrame(NIL, [], args, env, args), kont)); };
// step-ho-map
var stepHoMap = function(args, env, kont) { return makeCekValue(hoMap(args, env), env, kont); };
// step-ho-filter
var stepHoFilter = function(args, env, kont) { return makeCekValue(hoFilter(args, env), env, kont); };
// step-ho-reduce
var stepHoReduce = function(args, env, kont) { return makeCekValue(hoReduce(args, env), env, kont); };
// step-ho-for-each
var stepHoForEach = function(args, env, kont) { return makeCekValue(hoForEach(args, env), env, kont); };
// step-continue
var stepContinue = function(state) { return (function() {
var value = cekValue(state);
var env = cekEnv(state);
var kont = cekKont(state);
return (isSxTruthy(kontEmpty_p(kont)) ? state : (function() {
var frame = kontTop(kont);
var restK = kontPop(kont);
var ft = frameType(frame);
return (isSxTruthy((ft == "if")) ? (isSxTruthy((isSxTruthy(value) && !isSxTruthy(isNil(value)))) ? makeCekState(get(frame, "then"), get(frame, "env"), restK) : (isSxTruthy(isNil(get(frame, "else"))) ? makeCekValue(NIL, env, restK) : makeCekState(get(frame, "else"), get(frame, "env"), restK))) : (isSxTruthy((ft == "when")) ? (isSxTruthy((isSxTruthy(value) && !isSxTruthy(isNil(value)))) ? (function() {
var body = get(frame, "body");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(body)) ? makeCekValue(NIL, fenv, restK) : (isSxTruthy((len(body) == 1)) ? makeCekState(first(body), fenv, restK) : makeCekState(first(body), fenv, kontPush(makeBeginFrame(rest(body), fenv), restK))));
})() : makeCekValue(NIL, env, restK)) : (isSxTruthy((ft == "begin")) ? (function() {
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, fenv, restK) : (isSxTruthy((len(remaining) == 1)) ? makeCekState(first(remaining), fenv, restK) : makeCekState(first(remaining), fenv, kontPush(makeBeginFrame(rest(remaining), fenv), restK))));
})() : (isSxTruthy((ft == "let")) ? (function() {
var name = get(frame, "name");
var remaining = get(frame, "remaining");
var body = get(frame, "body");
var local = get(frame, "env");
envSet(local, name, value);
return (isSxTruthy(isEmpty(remaining)) ? stepSfBegin(body, local, restK) : (function() {
var nextBinding = first(remaining);
var vname = (isSxTruthy((typeOf(first(nextBinding)) == "symbol")) ? symbolName(first(nextBinding)) : first(nextBinding));
return makeCekState(nth(nextBinding, 1), local, kontPush(makeLetFrame(vname, rest(remaining), body, local), restK));
})());
})() : (isSxTruthy((ft == "define")) ? (function() {
var name = get(frame, "name");
var fenv = get(frame, "env");
var hasEffects = get(frame, "has-effects");
var effectList = get(frame, "effect-list");
if (isSxTruthy((isSxTruthy(isLambda(value)) && isNil(lambdaName(value))))) {
value.name = name;
}
envSet(fenv, name, value);
if (isSxTruthy(hasEffects)) {
(function() {
var effectNames = (isSxTruthy((typeOf(effectList) == "list")) ? map(function(e) { return (isSxTruthy((typeOf(e) == "symbol")) ? symbolName(e) : (String(e))); }, effectList) : [(String(effectList))]);
var effectAnns = (isSxTruthy(envHas(fenv, "*effect-annotations*")) ? envGet(fenv, "*effect-annotations*") : {});
effectAnns[name] = effectNames;
return envSet(fenv, "*effect-annotations*", effectAnns);
})();
}
return makeCekValue(value, fenv, restK);
})() : (isSxTruthy((ft == "set")) ? (function() {
var name = get(frame, "name");
var fenv = get(frame, "env");
envSet(fenv, name, value);
return makeCekValue(value, env, restK);
})() : (isSxTruthy((ft == "and")) ? (isSxTruthy(!isSxTruthy(value)) ? makeCekValue(value, env, restK) : (function() {
var remaining = get(frame, "remaining");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, env, restK) : makeCekState(first(remaining), get(frame, "env"), (isSxTruthy((len(remaining) == 1)) ? restK : kontPush(makeAndFrame(rest(remaining), get(frame, "env")), restK))));
})()) : (isSxTruthy((ft == "or")) ? (isSxTruthy(value) ? makeCekValue(value, env, restK) : (function() {
var remaining = get(frame, "remaining");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(false, env, restK) : makeCekState(first(remaining), get(frame, "env"), (isSxTruthy((len(remaining) == 1)) ? restK : kontPush(makeOrFrame(rest(remaining), get(frame, "env")), restK))));
})()) : (isSxTruthy((ft == "cond")) ? (function() {
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
var scheme_p = get(frame, "scheme");
return (isSxTruthy(scheme_p) ? (isSxTruthy(value) ? makeCekState(nth(first(remaining), 1), fenv, restK) : (function() {
var nextClauses = rest(remaining);
return (isSxTruthy(isEmpty(nextClauses)) ? makeCekValue(NIL, fenv, restK) : (function() {
var nextClause = first(nextClauses);
var nextTest = first(nextClause);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(nextTest) == "symbol")) && sxOr((symbolName(nextTest) == "else"), (symbolName(nextTest) == ":else"))), (isSxTruthy((typeOf(nextTest) == "keyword")) && (keywordName(nextTest) == "else")))) ? makeCekState(nth(nextClause, 1), fenv, restK) : makeCekState(nextTest, fenv, kontPush(makeCondFrame(nextClauses, fenv, true), restK)));
})());
})()) : (isSxTruthy(value) ? makeCekState(nth(remaining, 1), fenv, restK) : (function() {
var next = slice(remaining, 2);
return (isSxTruthy((len(next) < 2)) ? makeCekValue(NIL, fenv, restK) : (function() {
var nextTest = first(next);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(nextTest) == "keyword")) && (keywordName(nextTest) == "else")), (isSxTruthy((typeOf(nextTest) == "symbol")) && sxOr((symbolName(nextTest) == "else"), (symbolName(nextTest) == ":else"))))) ? makeCekState(nth(next, 1), fenv, restK) : makeCekState(nextTest, fenv, kontPush(makeCondFrame(next, fenv, false), restK)));
})());
})()));
})() : (isSxTruthy((ft == "case")) ? (function() {
var matchVal = get(frame, "match-val");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isNil(matchVal)) ? sfCaseStepLoop(value, remaining, fenv, restK) : sfCaseStepLoop(matchVal, remaining, fenv, restK));
})() : (isSxTruthy((ft == "thread")) ? (function() {
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? makeCekValue(value, fenv, restK) : (function() {
var form = first(remaining);
var restForms = rest(remaining);
return (function() {
var result = (isSxTruthy((typeOf(form) == "list")) ? (function() {
var f = trampoline(evalExpr(first(form), fenv));
var rargs = map(function(a) { return trampoline(evalExpr(a, fenv)); }, rest(form));
var allArgs = cons(value, rargs);
return (isSxTruthy((isSxTruthy(isCallable(f)) && !isSxTruthy(isLambda(f)))) ? apply(f, allArgs) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, allArgs, fenv)) : error((String("-> form not callable: ") + String(inspect(f))))));
})() : (function() {
var f = trampoline(evalExpr(form, fenv));
return (isSxTruthy((isSxTruthy(isCallable(f)) && !isSxTruthy(isLambda(f)))) ? f(value) : (isSxTruthy(isLambda(f)) ? trampoline(callLambda(f, [value], fenv)) : error((String("-> form not callable: ") + String(inspect(f))))));
})());
return (isSxTruthy(isEmpty(restForms)) ? makeCekValue(result, fenv, restK) : makeCekValue(result, fenv, kontPush(makeThreadFrame(restForms, fenv), restK)));
})();
})());
})() : (isSxTruthy((ft == "arg")) ? (function() {
var f = get(frame, "f");
var evaled = get(frame, "evaled");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
var rawArgs = get(frame, "raw-args");
return (isSxTruthy(isNil(f)) ? (isSxTruthy(isEmpty(remaining)) ? continueWithCall(value, [], fenv, rawArgs, restK) : makeCekState(first(remaining), fenv, kontPush(makeArgFrame(value, [], rest(remaining), fenv, rawArgs), restK))) : (function() {
var newEvaled = append(evaled, [value]);
return (isSxTruthy(isEmpty(remaining)) ? continueWithCall(f, newEvaled, fenv, rawArgs, restK) : makeCekState(first(remaining), fenv, kontPush(makeArgFrame(f, newEvaled, rest(remaining), fenv, rawArgs), restK)));
})());
})() : (isSxTruthy((ft == "dict")) ? (function() {
var remaining = get(frame, "remaining");
var results = get(frame, "results");
var fenv = get(frame, "env");
return (function() {
var lastResult = last(results);
var completed = append(slice(results, 0, (len(results) - 1)), [[first(lastResult), value]]);
return (isSxTruthy(isEmpty(remaining)) ? (function() {
var d = {};
{ var _c = completed; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; d[first(pair)] = nth(pair, 1); } }
return makeCekValue(d, fenv, restK);
})() : (function() {
var nextEntry = first(remaining);
return makeCekState(nth(nextEntry, 1), fenv, kontPush(makeDictFrame(rest(remaining), append(completed, [[first(nextEntry)]]), fenv), restK));
})());
})();
})() : (isSxTruthy((ft == "reset")) ? makeCekValue(value, env, restK) : (isSxTruthy((ft == "deref")) ? (function() {
var val = value;
var fenv = get(frame, "env");
return (isSxTruthy(!isSxTruthy(isSignal(val))) ? makeCekValue(val, fenv, restK) : (isSxTruthy(hasReactiveResetFrame_p(restK)) ? reactiveShiftDeref(val, fenv, restK) : ((function() {
var ctx = sxContext("sx-reactive", NIL);
return (isSxTruthy(ctx) ? (function() {
var depList = get(ctx, "deps");
var notifyFn = get(ctx, "notify");
return (isSxTruthy(!isSxTruthy(contains(depList, val))) ? (append_b(depList, val), signalAddSub(val, notifyFn)) : NIL);
})() : NIL);
})(), makeCekValue(signalValue(val), fenv, restK))));
})() : (isSxTruthy((ft == "reactive-reset")) ? (function() {
var updateFn = get(frame, "update-fn");
var first_p = get(frame, "first-render");
if (isSxTruthy((isSxTruthy(updateFn) && !isSxTruthy(first_p)))) {
invoke(updateFn, value);
}
return makeCekValue(value, env, restK);
})() : (isSxTruthy((ft == "scope")) ? (function() {
var name = get(frame, "name");
var remaining = get(frame, "remaining");
var fenv = get(frame, "env");
return (isSxTruthy(isEmpty(remaining)) ? (scopePop(name), makeCekValue(value, fenv, restK)) : makeCekState(first(remaining), fenv, kontPush(makeScopeFrame(name, rest(remaining), fenv), restK)));
})() : error((String("Unknown frame type: ") + String(ft))))))))))))))))))));
})());
})(); };
// continue-with-call
var continueWithCall = function(f, args, env, rawArgs, kont) { return (isSxTruthy(continuation_p(f)) ? (function() {
var arg = (isSxTruthy(isEmpty(args)) ? NIL : first(args));
var contData = continuationData(f);
return (function() {
var captured = get(contData, "captured");
var restK = get(contData, "rest-kont");
return makeCekValue(arg, env, concat(captured, restK));
})();
})() : (isSxTruthy((isSxTruthy(isCallable(f)) && isSxTruthy(!isSxTruthy(isLambda(f))) && isSxTruthy(!isSxTruthy(isComponent(f))) && !isSxTruthy(isIsland(f)))) ? makeCekValue(apply(f, args), env, kont) : (isSxTruthy(isLambda(f)) ? (function() {
var params = lambdaParams(f);
var local = envMerge(lambdaClosure(f), env);
return (isSxTruthy((len(args) > len(params))) ? error((String(sxOr(lambdaName(f), "lambda")) + String(" expects ") + String(len(params)) + String(" args, got ") + String(len(args)))) : (forEach(function(pair) { return envSet(local, first(pair), nth(pair, 1)); }, zip(params, args)), forEach(function(p) { return envSet(local, p, NIL); }, slice(params, len(args))), makeCekState(lambdaBody(f), local, kont)));
})() : (isSxTruthy(sxOr(isComponent(f), isIsland(f))) ? (function() {
var parsed = parseKeywordArgs(rawArgs, env);
var kwargs = first(parsed);
var children = nth(parsed, 1);
var local = envMerge(componentClosure(f), env);
{ var _c = componentParams(f); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envSet(local, p, sxOr(dictGet(kwargs, p), NIL)); } }
if (isSxTruthy(componentHasChildren(f))) {
envSet(local, "children", children);
}
return makeCekState(componentBody(f), local, kont);
})() : error((String("Not callable: ") + String(inspect(f)))))))); };
// sf-case-step-loop
var sfCaseStepLoop = function(matchVal, clauses, env, kont) { return (isSxTruthy((len(clauses) < 2)) ? makeCekValue(NIL, env, kont) : (function() {
var test = first(clauses);
var body = nth(clauses, 1);
return (isSxTruthy(sxOr((isSxTruthy((typeOf(test) == "keyword")) && (keywordName(test) == "else")), (isSxTruthy((typeOf(test) == "symbol")) && sxOr((symbolName(test) == "else"), (symbolName(test) == ":else"))))) ? makeCekState(body, env, kont) : (function() {
var testVal = trampoline(evalExpr(test, env));
return (isSxTruthy((matchVal == testVal)) ? makeCekState(body, env, kont) : sfCaseStepLoop(matchVal, slice(clauses, 2), env, kont));
})());
})()); };
// eval-expr-cek
var evalExprCek = function(expr, env) { return cekRun(makeCekState(expr, env, [])); };
// trampoline-cek
var trampolineCek = function(val) { return (isSxTruthy(isThunk(val)) ? evalExprCek(thunkExpr(val), thunkEnv(val)) : val); };
// =========================================================================
// Platform interface — DOM adapter (browser-only)
// =========================================================================
@@ -5754,6 +6290,27 @@ return (function() {
// =========================================================================
// Platform: CEK module — explicit CEK machine
// =========================================================================
// Standalone aliases for primitives used by cek.sx / frames.sx
var inc = PRIMITIVES["inc"];
var dec = PRIMITIVES["dec"];
var zip_pairs = PRIMITIVES["zip-pairs"];
var continuation_p = PRIMITIVES["continuation?"];
function makeCekContinuation(captured, restKont) {
var c = new Continuation(function(v) { return v !== undefined ? v : NIL; });
c._cek_data = {"captured": captured, "rest-kont": restKont};
return c;
}
function continuationData(c) {
return (c && c._cek_data) ? c._cek_data : {};
}
// =========================================================================
// Post-transpilation fixups
// =========================================================================
@@ -5878,6 +6435,94 @@ return (function() {
PRIMITIVES["build-routing-analysis"] = buildRoutingAnalysis;
PRIMITIVES["build-affinity-analysis"] = buildAffinityAnalysis;
// Override recursive cekRun with iterative loop (avoids stack overflow)
cekRun = function(state) {
while (!cekTerminal_p(state)) { state = cekStep(state); }
return cekValue(state);
};
// =========================================================================
// Extension: Delimited continuations (shift/reset)
// =========================================================================
function Continuation(fn) { this.fn = fn; }
Continuation.prototype._continuation = true;
Continuation.prototype.call = function(value) { return this.fn(value !== undefined ? value : NIL); };
function ShiftSignal(kName, body, env) {
this.kName = kName;
this.body = body;
this.env = env;
}
PRIMITIVES["continuation?"] = function(x) { return x != null && x._continuation === true; };
var _resetResume = [];
function sfReset(args, env) {
var body = args[0];
try {
return trampoline(evalExpr(body, env));
} catch (e) {
if (e instanceof ShiftSignal) {
var sig = e;
var cont = new Continuation(function(value) {
if (value === undefined) value = NIL;
_resetResume.push(value);
try {
return trampoline(evalExpr(body, env));
} finally {
_resetResume.pop();
}
});
var sigEnv = merge(sig.env);
sigEnv[sig.kName] = cont;
return trampoline(evalExpr(sig.body, sigEnv));
}
throw e;
}
}
function sfShift(args, env) {
if (_resetResume.length > 0) {
return _resetResume[_resetResume.length - 1];
}
var kName = symbolName(args[0]);
var body = args[1];
throw new ShiftSignal(kName, body, env);
}
// Wrap evalList to intercept reset/shift
var _baseEvalList = evalList;
evalList = function(expr, env) {
var head = expr[0];
if (isSym(head)) {
var name = head.name;
if (name === "reset") return sfReset(expr.slice(1), env);
if (name === "shift") return sfShift(expr.slice(1), env);
}
return _baseEvalList(expr, env);
};
// Wrap aserSpecial to handle reset/shift in SX wire mode
if (typeof aserSpecial === "function") {
var _baseAserSpecial = aserSpecial;
aserSpecial = function(name, expr, env) {
if (name === "reset") return sfReset(expr.slice(1), env);
if (name === "shift") return sfShift(expr.slice(1), env);
return _baseAserSpecial(name, expr, env);
};
}
// Wrap typeOf to recognize continuations
var _baseTypeOf = typeOf;
typeOf = function(x) {
if (x != null && x._continuation) return "continuation";
return _baseTypeOf(x);
};
// =========================================================================
// Async IO: Promise-aware rendering for client-side IO primitives
// =========================================================================