Spec eval-cond and process-bindings in render.sx (remove platform implementations)
eval-cond and process-bindings were hand-written platform JS in bootstrap_js.py rather than specced in .sx files. This violated the SX host architecture principle. Now specced in render.sx as shared render adapter helpers, bootstrapped to both JS and Python. eval-cond handles both scheme-style ((test body) ...) and clojure-style (test body test body ...) cond clauses. Returns unevaluated body expression for the adapter to render in its own mode. process-bindings evaluates let-binding pairs and returns extended env. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -273,6 +273,8 @@ class JSEmitter:
|
||||
"dict-delete!": "dictDelete",
|
||||
"process-bindings": "processBindings",
|
||||
"eval-cond": "evalCond",
|
||||
"eval-cond-scheme": "evalCondScheme",
|
||||
"eval-cond-clojure": "evalCondClojure",
|
||||
"for-each-indexed": "forEachIndexed",
|
||||
"index-of": "indexOf_",
|
||||
"component-has-children?": "componentHasChildren",
|
||||
@@ -1823,39 +1825,7 @@ PLATFORM_JS_POST = '''
|
||||
"map":1,"map-indexed":1,"filter":1,"reduce":1,"some":1,"every?":1,"for-each":1
|
||||
}; }
|
||||
|
||||
// processBindings and evalCond — exposed for DOM adapter render forms
|
||||
function processBindings(bindings, env) {
|
||||
var local = merge(env);
|
||||
for (var i = 0; i < bindings.length; i++) {
|
||||
var pair = bindings[i];
|
||||
if (Array.isArray(pair) && pair.length >= 2) {
|
||||
var name = isSym(pair[0]) ? pair[0].name : String(pair[0]);
|
||||
local[name] = trampoline(evalExpr(pair[1], local));
|
||||
}
|
||||
}
|
||||
return local;
|
||||
}
|
||||
function evalCond(clauses, env) {
|
||||
// Detect scheme-style ((test body) ...) vs clojure-style (test body test body ...)
|
||||
var scheme = clauses.length > 0 && Array.isArray(clauses[0]) && clauses[0].length === 2;
|
||||
if (scheme) {
|
||||
for (var i = 0; i < clauses.length; i++) {
|
||||
var clause = clauses[i];
|
||||
var test = clause[0], body = clause[1];
|
||||
if (isSym(test) && (test.name === "else" || test.name === ":else")) return body;
|
||||
if (isKw(test) && test.name === "else") return body;
|
||||
if (isSxTruthy(trampoline(evalExpr(test, env)))) return body;
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < clauses.length; i += 2) {
|
||||
var test = clauses[i];
|
||||
if (isSym(test) && test.name === ":else") return clauses[i + 1];
|
||||
if (isKw(test) && test.name === "else") return clauses[i + 1];
|
||||
if (isSxTruthy(trampoline(evalExpr(test, env)))) return clauses[i + 1];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// processBindings and evalCond — now specced in render.sx, bootstrapped above
|
||||
|
||||
function isDefinitionForm(name) {
|
||||
return name === "define" || name === "defcomp" || name === "defmacro" ||
|
||||
|
||||
Reference in New Issue
Block a user