Unify scoped effects: scope as general primitive, provide as sugar
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 12m54s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 12m54s
- Add `scope` special form to eval.sx: (scope name body...) or (scope name :value v body...) — general dynamic scope primitive - `provide` becomes sugar: (provide name value body...) calls scope - Rename provide-push!/provide-pop! to scope-push!/scope-pop! throughout all adapters (async, dom, html, sx) and platform implementations - Update boundary.sx: Tier 5 now "Scoped effects" with scope-push!/ scope-pop! as primary, provide-push!/provide-pop! as aliases - Add scope form handling to async adapter and aser wire format - Update sx-browser.js, sx_ref.py (bootstrapped output) - Add scopes.sx docs page, update provide/spreads/demo docs - Update nav-data, page-functions, docs page definitions 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-13T15:35:20Z";
|
||||
var SX_VERSION = "2026-03-13T16:48:03Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -86,8 +86,7 @@
|
||||
function SxSpread(attrs) { this.attrs = attrs || {}; }
|
||||
SxSpread.prototype._spread = true;
|
||||
|
||||
var _collectBuckets = {};
|
||||
var _provideStacks = {};
|
||||
var _scopeStacks = {};
|
||||
|
||||
function isSym(x) { return x != null && x._sym === true; }
|
||||
function isKw(x) { return x != null && x._kw === true; }
|
||||
@@ -151,44 +150,54 @@
|
||||
function isSpread(x) { return x != null && x._spread === true; }
|
||||
function spreadAttrs(s) { return s && s._spread ? s.attrs : {}; }
|
||||
|
||||
function sxCollect(bucket, value) {
|
||||
if (!_collectBuckets[bucket]) _collectBuckets[bucket] = [];
|
||||
var items = _collectBuckets[bucket];
|
||||
if (items.indexOf(value) === -1) items.push(value);
|
||||
function scopePush(name, value) {
|
||||
if (!_scopeStacks[name]) _scopeStacks[name] = [];
|
||||
_scopeStacks[name].push({value: value !== undefined ? value : NIL, emitted: [], dedup: false});
|
||||
}
|
||||
function sxCollected(bucket) {
|
||||
return _collectBuckets[bucket] ? _collectBuckets[bucket].slice() : [];
|
||||
}
|
||||
function sxClearCollected(bucket) {
|
||||
if (_collectBuckets[bucket]) _collectBuckets[bucket] = [];
|
||||
function scopePop(name) {
|
||||
if (_scopeStacks[name] && _scopeStacks[name].length) _scopeStacks[name].pop();
|
||||
}
|
||||
// Aliases — provide-push!/provide-pop! map to scope-push!/scope-pop!
|
||||
var providePush = scopePush;
|
||||
var providePop = scopePop;
|
||||
|
||||
function providePush(name, value) {
|
||||
if (!_provideStacks[name]) _provideStacks[name] = [];
|
||||
_provideStacks[name].push({value: value !== undefined ? value : NIL, emitted: []});
|
||||
}
|
||||
function providePop(name) {
|
||||
if (_provideStacks[name] && _provideStacks[name].length) _provideStacks[name].pop();
|
||||
}
|
||||
function sxContext(name) {
|
||||
if (_provideStacks[name] && _provideStacks[name].length) {
|
||||
return _provideStacks[name][_provideStacks[name].length - 1].value;
|
||||
if (_scopeStacks[name] && _scopeStacks[name].length) {
|
||||
return _scopeStacks[name][_scopeStacks[name].length - 1].value;
|
||||
}
|
||||
if (arguments.length > 1) return arguments[1];
|
||||
throw new Error("No provider for: " + name);
|
||||
}
|
||||
function sxEmit(name, value) {
|
||||
if (_provideStacks[name] && _provideStacks[name].length) {
|
||||
_provideStacks[name][_provideStacks[name].length - 1].emitted.push(value);
|
||||
if (_scopeStacks[name] && _scopeStacks[name].length) {
|
||||
var entry = _scopeStacks[name][_scopeStacks[name].length - 1];
|
||||
if (entry.dedup && entry.emitted.indexOf(value) !== -1) return NIL;
|
||||
entry.emitted.push(value);
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
function sxEmitted(name) {
|
||||
if (_provideStacks[name] && _provideStacks[name].length) {
|
||||
return _provideStacks[name][_provideStacks[name].length - 1].emitted.slice();
|
||||
if (_scopeStacks[name] && _scopeStacks[name].length) {
|
||||
return _scopeStacks[name][_scopeStacks[name].length - 1].emitted.slice();
|
||||
}
|
||||
return [];
|
||||
}
|
||||
function sxCollect(bucket, value) {
|
||||
if (!_scopeStacks[bucket] || !_scopeStacks[bucket].length) {
|
||||
if (!_scopeStacks[bucket]) _scopeStacks[bucket] = [];
|
||||
_scopeStacks[bucket].push({value: NIL, emitted: [], dedup: true});
|
||||
}
|
||||
var entry = _scopeStacks[bucket][_scopeStacks[bucket].length - 1];
|
||||
if (entry.emitted.indexOf(value) === -1) entry.emitted.push(value);
|
||||
}
|
||||
function sxCollected(bucket) {
|
||||
return sxEmitted(bucket);
|
||||
}
|
||||
function sxClearCollected(bucket) {
|
||||
if (_scopeStacks[bucket] && _scopeStacks[bucket].length) {
|
||||
_scopeStacks[bucket][_scopeStacks[bucket].length - 1].emitted = [];
|
||||
}
|
||||
}
|
||||
|
||||
function lambdaParams(f) { return f.params; }
|
||||
function lambdaBody(f) { return f.body; }
|
||||
@@ -517,14 +526,17 @@
|
||||
};
|
||||
|
||||
|
||||
// stdlib.spread — spread + collect primitives
|
||||
// stdlib.spread — spread + collect + scope primitives
|
||||
PRIMITIVES["make-spread"] = makeSpread;
|
||||
PRIMITIVES["spread?"] = isSpread;
|
||||
PRIMITIVES["spread-attrs"] = spreadAttrs;
|
||||
PRIMITIVES["collect!"] = sxCollect;
|
||||
PRIMITIVES["collected"] = sxCollected;
|
||||
PRIMITIVES["clear-collected!"] = sxClearCollected;
|
||||
// provide/context/emit! — render-time dynamic scope
|
||||
// scope — unified render-time dynamic scope
|
||||
PRIMITIVES["scope-push!"] = scopePush;
|
||||
PRIMITIVES["scope-pop!"] = scopePop;
|
||||
// provide-push!/provide-pop! — aliases for scope-push!/scope-pop!
|
||||
PRIMITIVES["provide-push!"] = providePush;
|
||||
PRIMITIVES["provide-pop!"] = providePop;
|
||||
PRIMITIVES["context"] = sxContext;
|
||||
@@ -796,10 +808,10 @@
|
||||
var args = rest(expr);
|
||||
return (isSxTruthy(!isSxTruthy(sxOr((typeOf(head) == "symbol"), (typeOf(head) == "lambda"), (typeOf(head) == "list")))) ? map(function(x) { return trampoline(evalExpr(x, env)); }, expr) : (isSxTruthy((typeOf(head) == "symbol")) ? (function() {
|
||||
var name = symbolName(head);
|
||||
return (isSxTruthy((name == "if")) ? sfIf(args, env) : (isSxTruthy((name == "when")) ? sfWhen(args, env) : (isSxTruthy((name == "cond")) ? sfCond(args, env) : (isSxTruthy((name == "case")) ? sfCase(args, env) : (isSxTruthy((name == "and")) ? sfAnd(args, env) : (isSxTruthy((name == "or")) ? sfOr(args, env) : (isSxTruthy((name == "let")) ? sfLet(args, env) : (isSxTruthy((name == "let*")) ? sfLet(args, env) : (isSxTruthy((name == "letrec")) ? sfLetrec(args, env) : (isSxTruthy((name == "lambda")) ? sfLambda(args, env) : (isSxTruthy((name == "fn")) ? sfLambda(args, env) : (isSxTruthy((name == "define")) ? sfDefine(args, env) : (isSxTruthy((name == "defcomp")) ? sfDefcomp(args, env) : (isSxTruthy((name == "defisland")) ? sfDefisland(args, env) : (isSxTruthy((name == "defmacro")) ? sfDefmacro(args, env) : (isSxTruthy((name == "defstyle")) ? sfDefstyle(args, env) : (isSxTruthy((name == "defhandler")) ? sfDefhandler(args, env) : (isSxTruthy((name == "defpage")) ? sfDefpage(args, env) : (isSxTruthy((name == "defquery")) ? sfDefquery(args, env) : (isSxTruthy((name == "defaction")) ? sfDefaction(args, env) : (isSxTruthy((name == "deftype")) ? sfDeftype(args, env) : (isSxTruthy((name == "defeffect")) ? sfDefeffect(args, env) : (isSxTruthy((name == "begin")) ? sfBegin(args, env) : (isSxTruthy((name == "do")) ? sfBegin(args, env) : (isSxTruthy((name == "quote")) ? sfQuote(args, env) : (isSxTruthy((name == "quasiquote")) ? sfQuasiquote(args, env) : (isSxTruthy((name == "->")) ? sfThreadFirst(args, env) : (isSxTruthy((name == "set!")) ? sfSetBang(args, env) : (isSxTruthy((name == "reset")) ? sfReset(args, env) : (isSxTruthy((name == "shift")) ? sfShift(args, env) : (isSxTruthy((name == "dynamic-wind")) ? sfDynamicWind(args, env) : (isSxTruthy((name == "provide")) ? sfProvide(args, env) : (isSxTruthy((name == "map")) ? hoMap(args, env) : (isSxTruthy((name == "map-indexed")) ? hoMapIndexed(args, env) : (isSxTruthy((name == "filter")) ? hoFilter(args, env) : (isSxTruthy((name == "reduce")) ? hoReduce(args, env) : (isSxTruthy((name == "some")) ? hoSome(args, env) : (isSxTruthy((name == "every?")) ? hoEvery(args, env) : (isSxTruthy((name == "for-each")) ? hoForEach(args, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? (function() {
|
||||
return (isSxTruthy((name == "if")) ? sfIf(args, env) : (isSxTruthy((name == "when")) ? sfWhen(args, env) : (isSxTruthy((name == "cond")) ? sfCond(args, env) : (isSxTruthy((name == "case")) ? sfCase(args, env) : (isSxTruthy((name == "and")) ? sfAnd(args, env) : (isSxTruthy((name == "or")) ? sfOr(args, env) : (isSxTruthy((name == "let")) ? sfLet(args, env) : (isSxTruthy((name == "let*")) ? sfLet(args, env) : (isSxTruthy((name == "letrec")) ? sfLetrec(args, env) : (isSxTruthy((name == "lambda")) ? sfLambda(args, env) : (isSxTruthy((name == "fn")) ? sfLambda(args, env) : (isSxTruthy((name == "define")) ? sfDefine(args, env) : (isSxTruthy((name == "defcomp")) ? sfDefcomp(args, env) : (isSxTruthy((name == "defisland")) ? sfDefisland(args, env) : (isSxTruthy((name == "defmacro")) ? sfDefmacro(args, env) : (isSxTruthy((name == "defstyle")) ? sfDefstyle(args, env) : (isSxTruthy((name == "defhandler")) ? sfDefhandler(args, env) : (isSxTruthy((name == "defpage")) ? sfDefpage(args, env) : (isSxTruthy((name == "defquery")) ? sfDefquery(args, env) : (isSxTruthy((name == "defaction")) ? sfDefaction(args, env) : (isSxTruthy((name == "deftype")) ? sfDeftype(args, env) : (isSxTruthy((name == "defeffect")) ? sfDefeffect(args, env) : (isSxTruthy((name == "begin")) ? sfBegin(args, env) : (isSxTruthy((name == "do")) ? sfBegin(args, env) : (isSxTruthy((name == "quote")) ? sfQuote(args, env) : (isSxTruthy((name == "quasiquote")) ? sfQuasiquote(args, env) : (isSxTruthy((name == "->")) ? sfThreadFirst(args, env) : (isSxTruthy((name == "set!")) ? sfSetBang(args, env) : (isSxTruthy((name == "reset")) ? sfReset(args, env) : (isSxTruthy((name == "shift")) ? sfShift(args, env) : (isSxTruthy((name == "dynamic-wind")) ? sfDynamicWind(args, env) : (isSxTruthy((name == "scope")) ? sfScope(args, env) : (isSxTruthy((name == "provide")) ? sfProvide(args, env) : (isSxTruthy((name == "map")) ? hoMap(args, env) : (isSxTruthy((name == "map-indexed")) ? hoMapIndexed(args, env) : (isSxTruthy((name == "filter")) ? hoFilter(args, env) : (isSxTruthy((name == "reduce")) ? hoReduce(args, env) : (isSxTruthy((name == "some")) ? hoSome(args, env) : (isSxTruthy((name == "every?")) ? hoEvery(args, env) : (isSxTruthy((name == "for-each")) ? hoForEach(args, env) : (isSxTruthy((isSxTruthy(envHas(env, name)) && isMacro(envGet(env, name)))) ? (function() {
|
||||
var mac = envGet(env, name);
|
||||
return makeThunk(expandMacro(mac, args, env), env);
|
||||
})() : (isSxTruthy((isSxTruthy(renderActiveP()) && isRenderExpr(expr))) ? renderExpr(expr, env) : evalCall(head, args, env))))))))))))))))))))))))))))))))))))))))));
|
||||
})() : (isSxTruthy((isSxTruthy(renderActiveP()) && isRenderExpr(expr))) ? renderExpr(expr, env) : evalCall(head, args, env)))))))))))))))))))))))))))))))))))))))))));
|
||||
})() : evalCall(head, args, env)));
|
||||
})(); };
|
||||
|
||||
@@ -1204,6 +1216,22 @@ return append_b(inits, nth(binding, 1)); }, bindings) : reduce(function(acc, pai
|
||||
callThunk(after, env);
|
||||
return result;
|
||||
})();
|
||||
})(); };
|
||||
|
||||
// sf-scope
|
||||
var sfScope = function(args, env) { return (function() {
|
||||
var name = trampoline(evalExpr(first(args), env));
|
||||
var rest = slice(args, 1);
|
||||
var val = NIL;
|
||||
var bodyExprs = NIL;
|
||||
(isSxTruthy((isSxTruthy((len(rest) >= 2)) && isSxTruthy((typeOf(first(rest)) == "keyword")) && (keywordName(first(rest)) == "value"))) ? ((val = trampoline(evalExpr(nth(rest, 1), env))), (bodyExprs = slice(rest, 2))) : (bodyExprs = rest));
|
||||
scopePush(name, val);
|
||||
return (function() {
|
||||
var result = NIL;
|
||||
{ var _c = bodyExprs; for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; result = trampoline(evalExpr(e, env)); } }
|
||||
scopePop(name);
|
||||
return result;
|
||||
})();
|
||||
})(); };
|
||||
|
||||
// sf-provide
|
||||
@@ -1212,9 +1240,9 @@ return append_b(inits, nth(binding, 1)); }, bindings) : reduce(function(acc, pai
|
||||
var val = trampoline(evalExpr(nth(args, 1), env));
|
||||
var bodyExprs = slice(args, 2);
|
||||
var result = NIL;
|
||||
providePush(name, val);
|
||||
scopePush(name, val);
|
||||
{ var _c = bodyExprs; for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; result = trampoline(evalExpr(e, env)); } }
|
||||
providePop(name);
|
||||
scopePop(name);
|
||||
return result;
|
||||
})(); };
|
||||
|
||||
@@ -1527,7 +1555,7 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return ""; if (_m =
|
||||
var renderValueToHtml = function(val, env) { return (function() { var _m = typeOf(val); if (_m == "nil") return ""; if (_m == "string") return escapeHtml(val); if (_m == "number") return (String(val)); if (_m == "boolean") return (isSxTruthy(val) ? "true" : "false"); if (_m == "list") return renderListToHtml(val, env); if (_m == "raw-html") return rawHtmlContent(val); if (_m == "spread") return (sxEmit("element-attrs", spreadAttrs(val)), ""); return escapeHtml((String(val))); })(); };
|
||||
|
||||
// RENDER_HTML_FORMS
|
||||
var RENDER_HTML_FORMS = ["if", "when", "cond", "case", "let", "let*", "begin", "do", "define", "defcomp", "defisland", "defmacro", "defstyle", "defhandler", "deftype", "defeffect", "map", "map-indexed", "filter", "for-each", "provide"];
|
||||
var RENDER_HTML_FORMS = ["if", "when", "cond", "case", "let", "let*", "begin", "do", "define", "defcomp", "defisland", "defmacro", "defstyle", "defhandler", "deftype", "defeffect", "map", "map-indexed", "filter", "for-each", "scope", "provide"];
|
||||
|
||||
// render-html-form?
|
||||
var isRenderHtmlForm = function(name) { return contains(RENDER_HTML_FORMS, name); };
|
||||
@@ -1567,18 +1595,30 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return ""; if (_m =
|
||||
var f = trampoline(evalExpr(nth(expr, 1), env));
|
||||
var coll = trampoline(evalExpr(nth(expr, 2), env));
|
||||
return join("", map(function(item) { return (isSxTruthy(isLambda(f)) ? renderLambdaHtml(f, [item], env) : renderToHtml(apply(f, [item]), env)); }, coll));
|
||||
})() : (isSxTruthy((name == "scope")) ? (function() {
|
||||
var scopeName = trampoline(evalExpr(nth(expr, 1), env));
|
||||
var restArgs = slice(expr, 2);
|
||||
var scopeVal = NIL;
|
||||
var bodyExprs = NIL;
|
||||
(isSxTruthy((isSxTruthy((len(restArgs) >= 2)) && isSxTruthy((typeOf(first(restArgs)) == "keyword")) && (keywordName(first(restArgs)) == "value"))) ? ((scopeVal = trampoline(evalExpr(nth(restArgs, 1), env))), (bodyExprs = slice(restArgs, 2))) : (bodyExprs = restArgs));
|
||||
scopePush(scopeName, scopeVal);
|
||||
return (function() {
|
||||
var result = (isSxTruthy((len(bodyExprs) == 1)) ? renderToHtml(first(bodyExprs), env) : join("", map(function(e) { return renderToHtml(e, env); }, bodyExprs)));
|
||||
scopePop(scopeName);
|
||||
return result;
|
||||
})();
|
||||
})() : (isSxTruthy((name == "provide")) ? (function() {
|
||||
var provName = trampoline(evalExpr(nth(expr, 1), env));
|
||||
var provVal = trampoline(evalExpr(nth(expr, 2), env));
|
||||
var bodyStart = 3;
|
||||
var bodyCount = (len(expr) - 3);
|
||||
providePush(provName, provVal);
|
||||
scopePush(provName, provVal);
|
||||
return (function() {
|
||||
var result = (isSxTruthy((bodyCount == 1)) ? renderToHtml(nth(expr, bodyStart), env) : join("", map(function(i) { return renderToHtml(nth(expr, i), env); }, range(bodyStart, (bodyStart + bodyCount)))));
|
||||
providePop(provName);
|
||||
scopePop(provName);
|
||||
return result;
|
||||
})();
|
||||
})() : renderValueToHtml(trampoline(evalExpr(expr, env)), env))))))))))))); };
|
||||
})() : renderValueToHtml(trampoline(evalExpr(expr, env)), env)))))))))))))); };
|
||||
|
||||
// render-lambda-html
|
||||
var renderLambdaHtml = function(f, args, env) { return (function() {
|
||||
@@ -1615,10 +1655,10 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return ""; if (_m =
|
||||
var attrs = first(parsed);
|
||||
var children = nth(parsed, 1);
|
||||
var isVoid = contains(VOID_ELEMENTS, tag);
|
||||
return (isSxTruthy(isVoid) ? (String("<") + String(tag) + String(renderAttrs(attrs)) + String(" />")) : (providePush("element-attrs", NIL), (function() {
|
||||
return (isSxTruthy(isVoid) ? (String("<") + String(tag) + String(renderAttrs(attrs)) + String(" />")) : (scopePush("element-attrs", NIL), (function() {
|
||||
var content = join("", map(function(c) { return renderToHtml(c, env); }, children));
|
||||
{ var _c = sxEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(attrs, spreadDict); } }
|
||||
providePop("element-attrs");
|
||||
scopePop("element-attrs");
|
||||
return (String("<") + String(tag) + String(renderAttrs(attrs)) + String(">") + String(content) + String("</") + String(tag) + String(">"));
|
||||
})()));
|
||||
})(); };
|
||||
@@ -1639,11 +1679,11 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return ""; if (_m =
|
||||
})(); }, {["i"]: 0, ["skip"]: false}, args);
|
||||
return (function() {
|
||||
var lakeAttrs = {["data-sx-lake"]: sxOr(lakeId, "")};
|
||||
providePush("element-attrs", NIL);
|
||||
scopePush("element-attrs", NIL);
|
||||
return (function() {
|
||||
var content = join("", map(function(c) { return renderToHtml(c, env); }, children));
|
||||
{ var _c = sxEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(lakeAttrs, spreadDict); } }
|
||||
providePop("element-attrs");
|
||||
scopePop("element-attrs");
|
||||
return (String("<") + String(lakeTag) + String(renderAttrs(lakeAttrs)) + String(">") + String(content) + String("</") + String(lakeTag) + String(">"));
|
||||
})();
|
||||
})();
|
||||
@@ -1665,11 +1705,11 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return ""; if (_m =
|
||||
})(); }, {["i"]: 0, ["skip"]: false}, args);
|
||||
return (function() {
|
||||
var marshAttrs = {["data-sx-marsh"]: sxOr(marshId, "")};
|
||||
providePush("element-attrs", NIL);
|
||||
scopePush("element-attrs", NIL);
|
||||
return (function() {
|
||||
var content = join("", map(function(c) { return renderToHtml(c, env); }, children));
|
||||
{ var _c = sxEmitted("element-attrs"); for (var _i = 0; _i < _c.length; _i++) { var spreadDict = _c[_i]; mergeSpreadAttrs(marshAttrs, spreadDict); } }
|
||||
providePop("element-attrs");
|
||||
scopePop("element-attrs");
|
||||
return (String("<") + String(marshTag) + String(renderAttrs(marshAttrs)) + String(">") + String(content) + String("</") + String(marshTag) + String(">"));
|
||||
})();
|
||||
})();
|
||||
@@ -1754,7 +1794,7 @@ return (function() {
|
||||
var childParts = [];
|
||||
var skip = false;
|
||||
var i = 0;
|
||||
providePush("element-attrs", NIL);
|
||||
scopePush("element-attrs", NIL);
|
||||
{ var _c = args; for (var _i = 0; _i < _c.length; _i++) { var arg = _c[_i]; (isSxTruthy(skip) ? ((skip = false), (i = (i + 1))) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((i + 1) < len(args)))) ? (function() {
|
||||
var val = aser(nth(args, (i + 1)), env);
|
||||
if (isSxTruthy(!isSxTruthy(isNil(val)))) {
|
||||
@@ -1775,7 +1815,7 @@ return (function() {
|
||||
attrParts.push((String(":") + String(k)));
|
||||
return append_b(attrParts, serialize(v));
|
||||
})(); } } } }
|
||||
providePop("element-attrs");
|
||||
scopePop("element-attrs");
|
||||
return (function() {
|
||||
var parts = concat([name], attrParts, childParts);
|
||||
return (String("(") + String(join(" ", parts)) + String(")"));
|
||||
@@ -1783,7 +1823,7 @@ return (function() {
|
||||
})(); };
|
||||
|
||||
// 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", "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"];
|
||||
|
||||
// HO_FORM_NAMES
|
||||
var HO_FORM_NAMES = ["map", "map-indexed", "filter", "reduce", "some", "every?", "for-each"];
|
||||
@@ -1854,15 +1894,28 @@ return result; }, args);
|
||||
return append_b(results, aser(lambdaBody(f), local));
|
||||
})() : invoke(f, item)); } }
|
||||
return (isSxTruthy(isEmpty(results)) ? NIL : results);
|
||||
})() : (isSxTruthy((name == "defisland")) ? (trampoline(evalExpr(expr, env)), serialize(expr)) : (isSxTruthy(sxOr((name == "define"), (name == "defcomp"), (name == "defmacro"), (name == "defstyle"), (name == "defhandler"), (name == "defpage"), (name == "defquery"), (name == "defaction"), (name == "defrelation"), (name == "deftype"), (name == "defeffect"))) ? (trampoline(evalExpr(expr, env)), NIL) : (isSxTruthy((name == "provide")) ? (function() {
|
||||
})() : (isSxTruthy((name == "defisland")) ? (trampoline(evalExpr(expr, env)), serialize(expr)) : (isSxTruthy(sxOr((name == "define"), (name == "defcomp"), (name == "defmacro"), (name == "defstyle"), (name == "defhandler"), (name == "defpage"), (name == "defquery"), (name == "defaction"), (name == "defrelation"), (name == "deftype"), (name == "defeffect"))) ? (trampoline(evalExpr(expr, env)), NIL) : (isSxTruthy((name == "scope")) ? (function() {
|
||||
var scopeName = trampoline(evalExpr(first(args), env));
|
||||
var restArgs = rest(args);
|
||||
var scopeVal = NIL;
|
||||
var bodyArgs = NIL;
|
||||
(isSxTruthy((isSxTruthy((len(restArgs) >= 2)) && isSxTruthy((typeOf(first(restArgs)) == "keyword")) && (keywordName(first(restArgs)) == "value"))) ? ((scopeVal = trampoline(evalExpr(nth(restArgs, 1), env))), (bodyArgs = slice(restArgs, 2))) : (bodyArgs = restArgs));
|
||||
scopePush(scopeName, scopeVal);
|
||||
return (function() {
|
||||
var result = NIL;
|
||||
{ var _c = bodyArgs; for (var _i = 0; _i < _c.length; _i++) { var body = _c[_i]; result = aser(body, env); } }
|
||||
scopePop(scopeName);
|
||||
return result;
|
||||
})();
|
||||
})() : (isSxTruthy((name == "provide")) ? (function() {
|
||||
var provName = trampoline(evalExpr(first(args), env));
|
||||
var provVal = trampoline(evalExpr(nth(args, 1), env));
|
||||
var result = NIL;
|
||||
providePush(provName, provVal);
|
||||
scopePush(provName, provVal);
|
||||
{ var _c = slice(args, 2); for (var _i = 0; _i < _c.length; _i++) { var body = _c[_i]; result = aser(body, env); } }
|
||||
providePop(provName);
|
||||
scopePop(provName);
|
||||
return result;
|
||||
})() : trampoline(evalExpr(expr, env))))))))))))))));
|
||||
})() : trampoline(evalExpr(expr, env)))))))))))))))));
|
||||
})(); };
|
||||
|
||||
// eval-case-aser
|
||||
@@ -1912,7 +1965,7 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return createFragme
|
||||
var renderDomElement = function(tag, args, env, ns) { return (function() {
|
||||
var newNs = (isSxTruthy((tag == "svg")) ? SVG_NS : (isSxTruthy((tag == "math")) ? MATH_NS : ns));
|
||||
var el = domCreateElement(tag, newNs);
|
||||
providePush("element-attrs", NIL);
|
||||
scopePush("element-attrs", NIL);
|
||||
reduce(function(state, arg) { return (function() {
|
||||
var skip = get(state, "skip");
|
||||
return (isSxTruthy(skip) ? assoc(state, "skip", false, "i", (get(state, "i") + 1)) : (isSxTruthy((isSxTruthy((typeOf(arg) == "keyword")) && ((get(state, "i") + 1) < len(args)))) ? (function() {
|
||||
@@ -1950,7 +2003,7 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return createFragme
|
||||
return domSetAttr(el, "style", (isSxTruthy((isSxTruthy(existing) && !isSxTruthy((existing == "")))) ? (String(existing) + String(";") + String(val)) : val));
|
||||
})() : domSetAttr(el, key, (String(val)))));
|
||||
})(); } } } }
|
||||
providePop("element-attrs");
|
||||
scopePop("element-attrs");
|
||||
return el;
|
||||
})(); };
|
||||
|
||||
@@ -2007,7 +2060,7 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return createFragme
|
||||
var renderDomUnknownComponent = function(name) { return error((String("Unknown component: ") + String(name))); };
|
||||
|
||||
// RENDER_DOM_FORMS
|
||||
var RENDER_DOM_FORMS = ["if", "when", "cond", "case", "let", "let*", "begin", "do", "define", "defcomp", "defisland", "defmacro", "defstyle", "defhandler", "map", "map-indexed", "filter", "for-each", "portal", "error-boundary", "provide"];
|
||||
var RENDER_DOM_FORMS = ["if", "when", "cond", "case", "let", "let*", "begin", "do", "define", "defcomp", "defisland", "defmacro", "defstyle", "defhandler", "map", "map-indexed", "filter", "for-each", "portal", "error-boundary", "scope", "provide"];
|
||||
|
||||
// render-dom-form?
|
||||
var isRenderDomForm = function(name) { return contains(RENDER_DOM_FORMS, name); };
|
||||
@@ -2149,15 +2202,26 @@ return (function() { var _m = typeOf(expr); if (_m == "nil") return createFragme
|
||||
return domAppend(frag, val);
|
||||
})(); } }
|
||||
return frag;
|
||||
})() : (isSxTruthy((name == "scope")) ? (function() {
|
||||
var scopeName = trampoline(evalExpr(nth(expr, 1), env));
|
||||
var restArgs = slice(expr, 2);
|
||||
var scopeVal = NIL;
|
||||
var bodyExprs = NIL;
|
||||
var frag = createFragment();
|
||||
(isSxTruthy((isSxTruthy((len(restArgs) >= 2)) && isSxTruthy((typeOf(first(restArgs)) == "keyword")) && (keywordName(first(restArgs)) == "value"))) ? ((scopeVal = trampoline(evalExpr(nth(restArgs, 1), env))), (bodyExprs = slice(restArgs, 2))) : (bodyExprs = restArgs));
|
||||
scopePush(scopeName, scopeVal);
|
||||
{ var _c = bodyExprs; for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; domAppend(frag, renderToDom(e, env, ns)); } }
|
||||
scopePop(scopeName);
|
||||
return frag;
|
||||
})() : (isSxTruthy((name == "provide")) ? (function() {
|
||||
var provName = trampoline(evalExpr(nth(expr, 1), env));
|
||||
var provVal = trampoline(evalExpr(nth(expr, 2), env));
|
||||
var frag = createFragment();
|
||||
providePush(provName, provVal);
|
||||
scopePush(provName, provVal);
|
||||
{ var _c = range(3, len(expr)); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; domAppend(frag, renderToDom(nth(expr, i), env, ns)); } }
|
||||
providePop(provName);
|
||||
scopePop(provName);
|
||||
return frag;
|
||||
})() : renderToDom(trampoline(evalExpr(expr, env)), env, ns))))))))))))))); };
|
||||
})() : renderToDom(trampoline(evalExpr(expr, env)), env, ns)))))))))))))))); };
|
||||
|
||||
// render-lambda-dom
|
||||
var renderLambdaDom = function(f, args, env, ns) { return (function() {
|
||||
@@ -6622,6 +6686,8 @@ return (isSxTruthy((_batchDepth == 0)) ? (function() {
|
||||
collect: sxCollect,
|
||||
collected: sxCollected,
|
||||
clearCollected: sxClearCollected,
|
||||
scopePush: scopePush,
|
||||
scopePop: scopePop,
|
||||
providePush: providePush,
|
||||
providePop: providePop,
|
||||
context: sxContext,
|
||||
|
||||
Reference in New Issue
Block a user