Add CEK Machine section under Geography with live island demos
geography/cek.sx: overview page (three registers, deref-as-shift explanation) + demo page with 5 live islands (counter, computed chain, reactive attrs, stopwatch effect+cleanup, batch coalescing). Nav entry, router routes, defpage definitions. CEK exports (cekRun, makeCekState, makeReactiveResetFrame, evalExpr) added to Sx public API via platform_js.py. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
// =========================================================================
|
||||
|
||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||
var SX_VERSION = "2026-03-14T01:00:32Z";
|
||||
var SX_VERSION = "2026-03-14T01:23:35Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -1391,7 +1391,7 @@ var d2 = hexDigitValue(nth(source, pos));
|
||||
var _ = (pos = (pos + 1));
|
||||
var d3 = hexDigitValue(nth(source, pos));
|
||||
var _ = (pos = (pos + 1));
|
||||
buf = (String(buf) + String(charFromCode(((((d0 * 4096) + (d1 * 256)) + (d2 * 16)) + d3))));
|
||||
buf = (String(buf) + String(charFromCode((d0 * 4096))));
|
||||
continue; } } else { buf = (String(buf) + String((isSxTruthy((esc == "n")) ? "\n" : (isSxTruthy((esc == "t")) ? "\t" : (isSxTruthy((esc == "r")) ? "\r" : esc)))));
|
||||
pos = (pos + 1);
|
||||
continue; } } } else { buf = (String(buf) + String(ch));
|
||||
@@ -6442,87 +6442,6 @@ return forEach(function(d) { return invoke(d); }, subDisposers); });
|
||||
};
|
||||
|
||||
|
||||
// =========================================================================
|
||||
// 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
|
||||
// =========================================================================
|
||||
@@ -7320,6 +7239,14 @@ return forEach(function(d) { return invoke(d); }, subDisposers); });
|
||||
context: sxContext,
|
||||
emit: sxEmit,
|
||||
emitted: sxEmitted,
|
||||
cekRun: cekRun,
|
||||
makeCekState: makeCekState,
|
||||
makeCekValue: makeCekValue,
|
||||
cekStep: cekStep,
|
||||
cekTerminal: cekTerminal_p,
|
||||
cekValue: cekValue,
|
||||
makeReactiveResetFrame: makeReactiveResetFrame,
|
||||
evalExpr: evalExpr,
|
||||
_version: "ref-2.0 (boot+dom+engine+html+orchestration+parser+sx, bootstrap-compiled)"
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user