Fix VM correctness: get nil-safe, scope/context/collect! as primitives
- get primitive returns nil for type mismatches (list+string) instead of raising — matches JS/Python behavior, fixes find-nav-match errors - scope-peek, collect!, collected, clear-collected! registered as real primitives in sx_primitives table (not just env bindings) so the CEK step-sf-context can find them via get-primitive - step-sf-context checks scope-peek hashtable BEFORE walking CEK continuation — bridges aser's scope-push!/pop! with CEK's context - context, emit!, emitted added to SPECIAL_FORM_NAMES and handled in aser-special (scope operations in aser rendering mode) - sx-context NativeFn for VM-compiled code paths - VM execution errors no longer mark functions as permanently failed — bytecode is correct, errors are from runtime data - kbd, samp, var added to HTML_TAGS + sx-browser.js rebuilt Co-Authored-By: Claude Opus 4.6 (1M context) <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-23T08:09:30Z";
|
||||
var SX_VERSION = "2026-03-23T08:59:15Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -2759,7 +2759,7 @@ PRIMITIVES["aser-call"] = aserCall;
|
||||
PRIMITIVES["aser-expand-component"] = aserExpandComponent;
|
||||
|
||||
// SPECIAL_FORM_NAMES
|
||||
var SPECIAL_FORM_NAMES = ["if", "when", "cond", "case", "and", "or", "let", "let*", "lambda", "fn", "define", "defcomp", "defmacro", "defstyle", "defhandler", "defpage", "defquery", "defaction", "defrelation", "begin", "do", "quote", "quasiquote", "->", "set!", "letrec", "dynamic-wind", "defisland", "deftype", "defeffect", "scope", "provide"];
|
||||
var SPECIAL_FORM_NAMES = ["if", "when", "cond", "case", "and", "or", "let", "let*", "lambda", "fn", "define", "defcomp", "defmacro", "defstyle", "defhandler", "defpage", "defquery", "defaction", "defrelation", "begin", "do", "quote", "quasiquote", "->", "set!", "letrec", "dynamic-wind", "defisland", "deftype", "defeffect", "scope", "provide", "context", "emit!", "emitted"];
|
||||
PRIMITIVES["SPECIAL_FORM_NAMES"] = SPECIAL_FORM_NAMES;
|
||||
|
||||
// HO_FORM_NAMES
|
||||
@@ -2855,7 +2855,22 @@ return result; }, args);
|
||||
{ var _c = slice(args, 2); for (var _i = 0; _i < _c.length; _i++) { var body = _c[_i]; result = aser(body, env); } }
|
||||
scopePop(provName);
|
||||
return result;
|
||||
})() : trampoline(evalExpr(expr, env)))))))))))))))));
|
||||
})() : (isSxTruthy((name == "context")) ? (function() {
|
||||
var ctxName = trampoline(evalExpr(first(args), env));
|
||||
var defaultVal = (isSxTruthy((len(args) >= 2)) ? trampoline(evalExpr(nth(args, 1), env)) : NIL);
|
||||
return (function() {
|
||||
var val = scopePeek(ctxName);
|
||||
return (isSxTruthy(isNil(val)) ? defaultVal : val);
|
||||
})();
|
||||
})() : (isSxTruthy((name == "emit!")) ? (function() {
|
||||
var emitName = trampoline(evalExpr(first(args), env));
|
||||
var emitVal = trampoline(evalExpr(nth(args, 1), env));
|
||||
scopeEmit(emitName, emitVal);
|
||||
return NIL;
|
||||
})() : (isSxTruthy((name == "emitted")) ? (function() {
|
||||
var emitName = trampoline(evalExpr(first(args), env));
|
||||
return sxOr(scopePeek(emitName), []);
|
||||
})() : trampoline(evalExpr(expr, env))))))))))))))))))));
|
||||
})(); };
|
||||
PRIMITIVES["aser-special"] = aserSpecial;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user