Split env-bind! from env-set!: fix lexical scoping and closures
Two fundamental environment bugs fixed: 1. env-set! was used for both binding creation (let, define, params) and mutation (set!). Binding creation must NOT walk the scope chain — it should set on the immediate env. Only set! should walk. Fix: introduce env-bind! for all binding creation. env-set! now exclusively means "mutate existing binding, walk scope chain". Changed across spec (eval.sx, cek.sx, render.sx) and all web adapters (dom, html, sx, async, boot, orchestration, forms). 2. makeLambda/makeComponent/makeMacro/makeIsland used merge(env) to flatten the closure into a plain object, destroying the prototype chain. This meant set! inside closures couldn't reach the original binding — it modified a snapshot copy instead. Fix: store env directly as closure (no merge). The prototype chain is preserved, so set! walks up to the original scope. Tests: 499/516 passing (96.7%), up from 485/516. Fixed: define self-reference, let scope isolation, set! through closures, counter-via-closure pattern, recursive functions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1162,12 +1162,12 @@ PLATFORM_JS_PRE = '''
|
|||||||
function makeSymbol(n) { return new Symbol(n); }
|
function makeSymbol(n) { return new Symbol(n); }
|
||||||
function makeKeyword(n) { return new Keyword(n); }
|
function makeKeyword(n) { return new Keyword(n); }
|
||||||
|
|
||||||
function makeLambda(params, body, env) { return new Lambda(params, body, merge(env)); }
|
function makeLambda(params, body, env) { return new Lambda(params, body, env); }
|
||||||
function makeComponent(name, params, hasChildren, body, env, affinity) {
|
function makeComponent(name, params, hasChildren, body, env, affinity) {
|
||||||
return new Component(name, params, hasChildren, body, merge(env), affinity);
|
return new Component(name, params, hasChildren, body, env, affinity);
|
||||||
}
|
}
|
||||||
function makeMacro(params, restParam, body, env, name) {
|
function makeMacro(params, restParam, body, env, name) {
|
||||||
return new Macro(params, restParam, body, merge(env), name);
|
return new Macro(params, restParam, body, env, name);
|
||||||
}
|
}
|
||||||
function makeThunk(expr, env) { return new Thunk(expr, env); }
|
function makeThunk(expr, env) { return new Thunk(expr, env); }
|
||||||
|
|
||||||
@@ -1257,7 +1257,7 @@ PLATFORM_JS_PRE = '''
|
|||||||
|
|
||||||
// Island platform
|
// Island platform
|
||||||
function makeIsland(name, params, hasChildren, body, env) {
|
function makeIsland(name, params, hasChildren, body, env) {
|
||||||
return new Island(name, params, hasChildren, body, merge(env));
|
return new Island(name, params, hasChildren, body, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON / dict helpers for island state serialization
|
// JSON / dict helpers for island state serialization
|
||||||
@@ -1272,6 +1272,11 @@ PLATFORM_JS_PRE = '''
|
|||||||
|
|
||||||
function envHas(env, name) { return name in env; }
|
function envHas(env, name) { return name in env; }
|
||||||
function envGet(env, name) { return env[name]; }
|
function envGet(env, name) { return env[name]; }
|
||||||
|
function envBind(env, name, val) {
|
||||||
|
// Direct property set — creates or overwrites on THIS env only.
|
||||||
|
// Used by let, define, defcomp, lambda param binding.
|
||||||
|
env[name] = val;
|
||||||
|
}
|
||||||
function envSet(env, name, val) {
|
function envSet(env, name, val) {
|
||||||
// Walk prototype chain to find where the variable is defined (for set!)
|
// Walk prototype chain to find where the variable is defined (for set!)
|
||||||
var obj = env;
|
var obj = env;
|
||||||
|
|||||||
@@ -72,8 +72,9 @@ env["cek-eval"] = function(s) {
|
|||||||
env["eval-expr-cek"] = function(expr, e) { return Sx.eval(expr, e || env); };
|
env["eval-expr-cek"] = function(expr, e) { return Sx.eval(expr, e || env); };
|
||||||
env["env-get"] = function(e, k) { return e && e[k] !== undefined ? e[k] : null; };
|
env["env-get"] = function(e, k) { return e && e[k] !== undefined ? e[k] : null; };
|
||||||
env["env-has?"] = function(e, k) { return e && k in e; };
|
env["env-has?"] = function(e, k) { return e && k in e; };
|
||||||
|
env["env-bind!"] = function(e, k, v) { if (e) e[k] = v; return v; };
|
||||||
env["env-set!"] = function(e, k, v) { if (e) e[k] = v; return v; };
|
env["env-set!"] = function(e, k, v) { if (e) e[k] = v; return v; };
|
||||||
env["env-extend"] = function(e) { return Object.assign({}, e); };
|
env["env-extend"] = function(e) { return Object.create(e); };
|
||||||
env["env-merge"] = function(a, b) { return Object.assign({}, a, b); };
|
env["env-merge"] = function(a, b) { return Object.assign({}, a, b); };
|
||||||
|
|
||||||
// Missing primitives referenced by tests
|
// Missing primitives referenced by tests
|
||||||
|
|||||||
@@ -107,6 +107,7 @@
|
|||||||
"get-primitive" "getPrimitive"
|
"get-primitive" "getPrimitive"
|
||||||
"env-has?" "envHas"
|
"env-has?" "envHas"
|
||||||
"env-get" "envGet"
|
"env-get" "envGet"
|
||||||
|
"env-bind!" "envBind"
|
||||||
"env-set!" "envSet"
|
"env-set!" "envSet"
|
||||||
"env-extend" "envExtend"
|
"env-extend" "envExtend"
|
||||||
"env-merge" "envMerge"
|
"env-merge" "envMerge"
|
||||||
@@ -989,6 +990,11 @@
|
|||||||
", " (js-expr (nth args 1))
|
", " (js-expr (nth args 1))
|
||||||
", " (js-expr (nth args 2)) ")")
|
", " (js-expr (nth args 2)) ")")
|
||||||
|
|
||||||
|
(= op "env-bind!")
|
||||||
|
(str "envBind(" (js-expr (nth args 0))
|
||||||
|
", " (js-expr (nth args 1))
|
||||||
|
", " (js-expr (nth args 2)) ")")
|
||||||
|
|
||||||
(= op "env-set!")
|
(= op "env-set!")
|
||||||
(str "envSet(" (js-expr (nth args 0))
|
(str "envSet(" (js-expr (nth args 0))
|
||||||
", " (js-expr (nth args 1))
|
", " (js-expr (nth args 1))
|
||||||
@@ -1396,6 +1402,10 @@
|
|||||||
"] = " (js-expr (nth expr 3)) ";")
|
"] = " (js-expr (nth expr 3)) ";")
|
||||||
(= name "append!")
|
(= name "append!")
|
||||||
(str (js-expr (nth expr 1)) ".push(" (js-expr (nth expr 2)) ");")
|
(str (js-expr (nth expr 1)) ".push(" (js-expr (nth expr 2)) ");")
|
||||||
|
(= name "env-bind!")
|
||||||
|
(str "envBind(" (js-expr (nth expr 1))
|
||||||
|
", " (js-expr (nth expr 2))
|
||||||
|
", " (js-expr (nth expr 3)) ");")
|
||||||
(= name "env-set!")
|
(= name "env-set!")
|
||||||
(str "envSet(" (js-expr (nth expr 1))
|
(str "envSet(" (js-expr (nth expr 1))
|
||||||
", " (js-expr (nth expr 2))
|
", " (js-expr (nth expr 2))
|
||||||
|
|||||||
@@ -498,10 +498,23 @@ def env_get(env, name):
|
|||||||
return env.get(name, NIL)
|
return env.get(name, NIL)
|
||||||
|
|
||||||
|
|
||||||
def env_set(env, name, val):
|
def env_bind(env, name, val):
|
||||||
|
"""Create/overwrite binding on THIS env only (let, define, param binding)."""
|
||||||
env[name] = val
|
env[name] = val
|
||||||
|
|
||||||
|
|
||||||
|
def env_set(env, name, val):
|
||||||
|
"""Mutate existing binding, walking scope chain (set!)."""
|
||||||
|
if hasattr(env, 'set'):
|
||||||
|
try:
|
||||||
|
env.set(name, val)
|
||||||
|
except KeyError:
|
||||||
|
# Not found anywhere — bind on immediate env
|
||||||
|
env[name] = val
|
||||||
|
else:
|
||||||
|
env[name] = val
|
||||||
|
|
||||||
|
|
||||||
def env_extend(env):
|
def env_extend(env):
|
||||||
return _ensure_env(env).extend()
|
return _ensure_env(env).extend()
|
||||||
|
|
||||||
|
|||||||
@@ -107,6 +107,7 @@
|
|||||||
"get-primitive" "get_primitive"
|
"get-primitive" "get_primitive"
|
||||||
"env-has?" "env_has"
|
"env-has?" "env_has"
|
||||||
"env-get" "env_get"
|
"env-get" "env_get"
|
||||||
|
"env-bind!" "env_bind"
|
||||||
"env-set!" "env_set"
|
"env-set!" "env_set"
|
||||||
"env-extend" "env_extend"
|
"env-extend" "env_extend"
|
||||||
"env-merge" "env_merge"
|
"env-merge" "env_merge"
|
||||||
@@ -524,11 +525,16 @@
|
|||||||
", " (py-expr-with-cells (nth args 1) cell-vars)
|
", " (py-expr-with-cells (nth args 1) cell-vars)
|
||||||
", " (py-expr-with-cells (nth args 2) cell-vars) ")")
|
", " (py-expr-with-cells (nth args 2) cell-vars) ")")
|
||||||
|
|
||||||
(= op "env-set!")
|
(= op "env-bind!")
|
||||||
(str "_sx_dict_set(" (py-expr-with-cells (nth args 0) cell-vars)
|
(str "_sx_dict_set(" (py-expr-with-cells (nth args 0) cell-vars)
|
||||||
", " (py-expr-with-cells (nth args 1) cell-vars)
|
", " (py-expr-with-cells (nth args 1) cell-vars)
|
||||||
", " (py-expr-with-cells (nth args 2) cell-vars) ")")
|
", " (py-expr-with-cells (nth args 2) cell-vars) ")")
|
||||||
|
|
||||||
|
(= op "env-set!")
|
||||||
|
(str "env_set(" (py-expr-with-cells (nth args 0) cell-vars)
|
||||||
|
", " (py-expr-with-cells (nth args 1) cell-vars)
|
||||||
|
", " (py-expr-with-cells (nth args 2) cell-vars) ")")
|
||||||
|
|
||||||
(= op "set-lambda-name!")
|
(= op "set-lambda-name!")
|
||||||
(str "_sx_set_attr(" (py-expr-with-cells (nth args 0) cell-vars)
|
(str "_sx_set_attr(" (py-expr-with-cells (nth args 0) cell-vars)
|
||||||
", 'name', " (py-expr-with-cells (nth args 1) cell-vars) ")")
|
", 'name', " (py-expr-with-cells (nth args 1) cell-vars) ")")
|
||||||
@@ -901,10 +907,14 @@
|
|||||||
(= name "append!")
|
(= name "append!")
|
||||||
(str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
(str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
||||||
".append(" (py-expr-with-cells (nth expr 2) cell-vars) ")")
|
".append(" (py-expr-with-cells (nth expr 2) cell-vars) ")")
|
||||||
(= name "env-set!")
|
(= name "env-bind!")
|
||||||
(str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
(str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
||||||
"[" (py-expr-with-cells (nth expr 2) cell-vars)
|
"[" (py-expr-with-cells (nth expr 2) cell-vars)
|
||||||
"] = " (py-expr-with-cells (nth expr 3) cell-vars))
|
"] = " (py-expr-with-cells (nth expr 3) cell-vars))
|
||||||
|
(= name "env-set!")
|
||||||
|
(str pad "env_set(" (py-expr-with-cells (nth expr 1) cell-vars)
|
||||||
|
", " (py-expr-with-cells (nth expr 2) cell-vars)
|
||||||
|
", " (py-expr-with-cells (nth expr 3) cell-vars) ")")
|
||||||
(= name "set-lambda-name!")
|
(= name "set-lambda-name!")
|
||||||
(str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
(str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
||||||
".name = " (py-expr-with-cells (nth expr 2) cell-vars))
|
".name = " (py-expr-with-cells (nth expr 2) cell-vars))
|
||||||
@@ -1098,10 +1108,14 @@
|
|||||||
(append! lines (str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
(append! lines (str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
||||||
"[" (py-expr-with-cells (nth expr 2) cell-vars)
|
"[" (py-expr-with-cells (nth expr 2) cell-vars)
|
||||||
"] = " (py-expr-with-cells (nth expr 3) cell-vars)))
|
"] = " (py-expr-with-cells (nth expr 3) cell-vars)))
|
||||||
(= name "env-set!")
|
(= name "env-bind!")
|
||||||
(append! lines (str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
(append! lines (str pad (py-expr-with-cells (nth expr 1) cell-vars)
|
||||||
"[" (py-expr-with-cells (nth expr 2) cell-vars)
|
"[" (py-expr-with-cells (nth expr 2) cell-vars)
|
||||||
"] = " (py-expr-with-cells (nth expr 3) cell-vars)))
|
"] = " (py-expr-with-cells (nth expr 3) cell-vars)))
|
||||||
|
(= name "env-set!")
|
||||||
|
(append! lines (str pad "env_set(" (py-expr-with-cells (nth expr 1) cell-vars)
|
||||||
|
", " (py-expr-with-cells (nth expr 2) cell-vars)
|
||||||
|
", " (py-expr-with-cells (nth expr 3) cell-vars) ")"))
|
||||||
:else
|
:else
|
||||||
(append! lines (py-statement-with-cells expr indent cell-vars)))))))))
|
(append! lines (py-statement-with-cells expr indent cell-vars)))))))))
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
|
||||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||||
var SX_VERSION = "2026-03-15T11:07:52Z";
|
var SX_VERSION = "2026-03-15T11:38:02Z";
|
||||||
|
|
||||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||||
@@ -122,12 +122,12 @@
|
|||||||
function makeSymbol(n) { return new Symbol(n); }
|
function makeSymbol(n) { return new Symbol(n); }
|
||||||
function makeKeyword(n) { return new Keyword(n); }
|
function makeKeyword(n) { return new Keyword(n); }
|
||||||
|
|
||||||
function makeLambda(params, body, env) { return new Lambda(params, body, merge(env)); }
|
function makeLambda(params, body, env) { return new Lambda(params, body, env); }
|
||||||
function makeComponent(name, params, hasChildren, body, env, affinity) {
|
function makeComponent(name, params, hasChildren, body, env, affinity) {
|
||||||
return new Component(name, params, hasChildren, body, merge(env), affinity);
|
return new Component(name, params, hasChildren, body, env, affinity);
|
||||||
}
|
}
|
||||||
function makeMacro(params, restParam, body, env, name) {
|
function makeMacro(params, restParam, body, env, name) {
|
||||||
return new Macro(params, restParam, body, merge(env), name);
|
return new Macro(params, restParam, body, env, name);
|
||||||
}
|
}
|
||||||
function makeThunk(expr, env) { return new Thunk(expr, env); }
|
function makeThunk(expr, env) { return new Thunk(expr, env); }
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@
|
|||||||
|
|
||||||
// Island platform
|
// Island platform
|
||||||
function makeIsland(name, params, hasChildren, body, env) {
|
function makeIsland(name, params, hasChildren, body, env) {
|
||||||
return new Island(name, params, hasChildren, body, merge(env));
|
return new Island(name, params, hasChildren, body, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON / dict helpers for island state serialization
|
// JSON / dict helpers for island state serialization
|
||||||
@@ -232,6 +232,11 @@
|
|||||||
|
|
||||||
function envHas(env, name) { return name in env; }
|
function envHas(env, name) { return name in env; }
|
||||||
function envGet(env, name) { return env[name]; }
|
function envGet(env, name) { return env[name]; }
|
||||||
|
function envBind(env, name, val) {
|
||||||
|
// Direct property set — creates or overwrites on THIS env only.
|
||||||
|
// Used by let, define, defcomp, lambda param binding.
|
||||||
|
env[name] = val;
|
||||||
|
}
|
||||||
function envSet(env, name, val) {
|
function envSet(env, name, val) {
|
||||||
// Walk prototype chain to find where the variable is defined (for set!)
|
// Walk prototype chain to find where the variable is defined (for set!)
|
||||||
var obj = env;
|
var obj = env;
|
||||||
@@ -843,7 +848,7 @@ PRIMITIVES["eval-call"] = evalCall;
|
|||||||
var callLambda = function(f, args, callerEnv) { return (function() {
|
var callLambda = function(f, args, callerEnv) { return (function() {
|
||||||
var params = lambdaParams(f);
|
var params = lambdaParams(f);
|
||||||
var local = envMerge(lambdaClosure(f), callerEnv);
|
var local = envMerge(lambdaClosure(f), callerEnv);
|
||||||
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))), makeThunk(lambdaBody(f), local)));
|
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 envBind(local, first(pair), nth(pair, 1)); }, zip(params, args)), forEach(function(p) { return envBind(local, p, NIL); }, slice(params, len(args))), makeThunk(lambdaBody(f), local)));
|
||||||
})(); };
|
})(); };
|
||||||
PRIMITIVES["call-lambda"] = callLambda;
|
PRIMITIVES["call-lambda"] = callLambda;
|
||||||
|
|
||||||
@@ -853,9 +858,9 @@ PRIMITIVES["call-lambda"] = callLambda;
|
|||||||
var kwargs = first(parsed);
|
var kwargs = first(parsed);
|
||||||
var children = nth(parsed, 1);
|
var children = nth(parsed, 1);
|
||||||
var local = envMerge(componentClosure(comp), env);
|
var local = envMerge(componentClosure(comp), env);
|
||||||
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envSet(local, p, sxOr(dictGet(kwargs, p), NIL)); } }
|
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, sxOr(dictGet(kwargs, p), NIL)); } }
|
||||||
if (isSxTruthy(componentHasChildren(comp))) {
|
if (isSxTruthy(componentHasChildren(comp))) {
|
||||||
envSet(local, "children", children);
|
envBind(local, "children", children);
|
||||||
}
|
}
|
||||||
return makeThunk(componentBody(comp), local);
|
return makeThunk(componentBody(comp), local);
|
||||||
})(); };
|
})(); };
|
||||||
@@ -951,13 +956,13 @@ PRIMITIVES["sf-or"] = sfOr;
|
|||||||
var local = envExtend(env);
|
var local = envExtend(env);
|
||||||
(isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? forEach(function(binding) { return (function() {
|
(isSxTruthy((isSxTruthy((typeOf(first(bindings)) == "list")) && (len(first(bindings)) == 2))) ? forEach(function(binding) { return (function() {
|
||||||
var vname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding));
|
var vname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding));
|
||||||
return envSet(local, vname, trampoline(evalExpr(nth(binding, 1), local)));
|
return envBind(local, vname, trampoline(evalExpr(nth(binding, 1), local)));
|
||||||
})(); }, bindings) : (function() {
|
})(); }, bindings) : (function() {
|
||||||
var i = 0;
|
var i = 0;
|
||||||
return reduce(function(acc, pairIdx) { return (function() {
|
return reduce(function(acc, pairIdx) { return (function() {
|
||||||
var vname = (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)));
|
var vname = (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)));
|
||||||
var valExpr = nth(bindings, ((pairIdx * 2) + 1));
|
var valExpr = nth(bindings, ((pairIdx * 2) + 1));
|
||||||
return envSet(local, vname, trampoline(evalExpr(valExpr, local)));
|
return envBind(local, vname, trampoline(evalExpr(valExpr, local)));
|
||||||
})(); }, NIL, range(0, (len(bindings) / 2)));
|
})(); }, NIL, range(0, (len(bindings) / 2)));
|
||||||
})());
|
})());
|
||||||
{ var _c = slice(body, 0, (len(body) - 1)); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
|
{ var _c = slice(body, 0, (len(body) - 1)); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
|
||||||
@@ -978,7 +983,7 @@ return append_b(inits, nth(binding, 1)); }, bindings) : reduce(function(acc, pai
|
|||||||
var loopBody = (isSxTruthy((len(body) == 1)) ? first(body) : cons(makeSymbol("begin"), body));
|
var loopBody = (isSxTruthy((len(body) == 1)) ? first(body) : cons(makeSymbol("begin"), body));
|
||||||
var loopFn = makeLambda(params, loopBody, env);
|
var loopFn = makeLambda(params, loopBody, env);
|
||||||
loopFn.name = loopName;
|
loopFn.name = loopName;
|
||||||
envSet(lambdaClosure(loopFn), loopName, loopFn);
|
envBind(lambdaClosure(loopFn), loopName, loopFn);
|
||||||
return (function() {
|
return (function() {
|
||||||
var initVals = map(function(e) { return trampoline(evalExpr(e, env)); }, inits);
|
var initVals = map(function(e) { return trampoline(evalExpr(e, env)); }, inits);
|
||||||
return callLambda(loopFn, initVals, env);
|
return callLambda(loopFn, initVals, env);
|
||||||
@@ -1006,14 +1011,14 @@ PRIMITIVES["sf-lambda"] = sfLambda;
|
|||||||
if (isSxTruthy((isSxTruthy(isLambda(value)) && isNil(lambdaName(value))))) {
|
if (isSxTruthy((isSxTruthy(isLambda(value)) && isNil(lambdaName(value))))) {
|
||||||
value.name = symbolName(nameSym);
|
value.name = symbolName(nameSym);
|
||||||
}
|
}
|
||||||
envSet(env, symbolName(nameSym), value);
|
envBind(env, symbolName(nameSym), value);
|
||||||
if (isSxTruthy(hasEffects)) {
|
if (isSxTruthy(hasEffects)) {
|
||||||
(function() {
|
(function() {
|
||||||
var effectsRaw = nth(args, 2);
|
var effectsRaw = nth(args, 2);
|
||||||
var effectList = (isSxTruthy((typeOf(effectsRaw) == "list")) ? map(function(e) { return (isSxTruthy((typeOf(e) == "symbol")) ? symbolName(e) : (String(e))); }, effectsRaw) : [(String(effectsRaw))]);
|
var effectList = (isSxTruthy((typeOf(effectsRaw) == "list")) ? map(function(e) { return (isSxTruthy((typeOf(e) == "symbol")) ? symbolName(e) : (String(e))); }, effectsRaw) : [(String(effectsRaw))]);
|
||||||
var effectAnns = (isSxTruthy(envHas(env, "*effect-annotations*")) ? envGet(env, "*effect-annotations*") : {});
|
var effectAnns = (isSxTruthy(envHas(env, "*effect-annotations*")) ? envGet(env, "*effect-annotations*") : {});
|
||||||
effectAnns[symbolName(nameSym)] = effectList;
|
effectAnns[symbolName(nameSym)] = effectList;
|
||||||
return envSet(env, "*effect-annotations*", effectAnns);
|
return envBind(env, "*effect-annotations*", effectAnns);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@@ -1042,10 +1047,10 @@ PRIMITIVES["sf-define"] = sfDefine;
|
|||||||
var effectList = (isSxTruthy((typeOf(effects) == "list")) ? map(function(e) { return (isSxTruthy((typeOf(e) == "symbol")) ? symbolName(e) : (String(e))); }, effects) : [(String(effects))]);
|
var effectList = (isSxTruthy((typeOf(effects) == "list")) ? map(function(e) { return (isSxTruthy((typeOf(e) == "symbol")) ? symbolName(e) : (String(e))); }, effects) : [(String(effects))]);
|
||||||
var effectAnns = (isSxTruthy(envHas(env, "*effect-annotations*")) ? envGet(env, "*effect-annotations*") : {});
|
var effectAnns = (isSxTruthy(envHas(env, "*effect-annotations*")) ? envGet(env, "*effect-annotations*") : {});
|
||||||
effectAnns[symbolName(nameSym)] = effectList;
|
effectAnns[symbolName(nameSym)] = effectList;
|
||||||
return envSet(env, "*effect-annotations*", effectAnns);
|
return envBind(env, "*effect-annotations*", effectAnns);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
envSet(env, symbolName(nameSym), comp);
|
envBind(env, symbolName(nameSym), comp);
|
||||||
return comp;
|
return comp;
|
||||||
})();
|
})();
|
||||||
})(); };
|
})(); };
|
||||||
@@ -1097,7 +1102,7 @@ PRIMITIVES["parse-comp-params"] = parseCompParams;
|
|||||||
var hasChildren = nth(parsed, 1);
|
var hasChildren = nth(parsed, 1);
|
||||||
return (function() {
|
return (function() {
|
||||||
var island = makeIsland(compName, params, hasChildren, body, env);
|
var island = makeIsland(compName, params, hasChildren, body, env);
|
||||||
envSet(env, symbolName(nameSym), island);
|
envBind(env, symbolName(nameSym), island);
|
||||||
return island;
|
return island;
|
||||||
})();
|
})();
|
||||||
})(); };
|
})(); };
|
||||||
@@ -1113,7 +1118,7 @@ PRIMITIVES["sf-defisland"] = sfDefisland;
|
|||||||
var restParam = nth(parsed, 1);
|
var restParam = nth(parsed, 1);
|
||||||
return (function() {
|
return (function() {
|
||||||
var mac = makeMacro(params, restParam, body, env, symbolName(nameSym));
|
var mac = makeMacro(params, restParam, body, env, symbolName(nameSym));
|
||||||
envSet(env, symbolName(nameSym), mac);
|
envBind(env, symbolName(nameSym), mac);
|
||||||
return mac;
|
return mac;
|
||||||
})();
|
})();
|
||||||
})(); };
|
})(); };
|
||||||
@@ -1132,7 +1137,7 @@ PRIMITIVES["parse-macro-params"] = parseMacroParams;
|
|||||||
var sfDefstyle = function(args, env) { return (function() {
|
var sfDefstyle = function(args, env) { return (function() {
|
||||||
var nameSym = first(args);
|
var nameSym = first(args);
|
||||||
var value = trampoline(evalExpr(nth(args, 1), env));
|
var value = trampoline(evalExpr(nth(args, 1), env));
|
||||||
envSet(env, symbolName(nameSym), value);
|
envBind(env, symbolName(nameSym), value);
|
||||||
return value;
|
return value;
|
||||||
})(); };
|
})(); };
|
||||||
PRIMITIVES["sf-defstyle"] = sfDefstyle;
|
PRIMITIVES["sf-defstyle"] = sfDefstyle;
|
||||||
@@ -1162,7 +1167,7 @@ PRIMITIVES["normalize-type-body"] = normalizeTypeBody;
|
|||||||
var body = normalizeTypeBody(bodyExpr);
|
var body = normalizeTypeBody(bodyExpr);
|
||||||
var registry = (isSxTruthy(envHas(env, "*type-registry*")) ? envGet(env, "*type-registry*") : {});
|
var registry = (isSxTruthy(envHas(env, "*type-registry*")) ? envGet(env, "*type-registry*") : {});
|
||||||
registry[typeName] = makeTypeDef(typeName, typeParams, body);
|
registry[typeName] = makeTypeDef(typeName, typeParams, body);
|
||||||
envSet(env, "*type-registry*", registry);
|
envBind(env, "*type-registry*", registry);
|
||||||
return NIL;
|
return NIL;
|
||||||
})();
|
})();
|
||||||
})(); };
|
})(); };
|
||||||
@@ -1175,7 +1180,7 @@ PRIMITIVES["sf-deftype"] = sfDeftype;
|
|||||||
if (isSxTruthy(!isSxTruthy(contains(registry, effectName)))) {
|
if (isSxTruthy(!isSxTruthy(contains(registry, effectName)))) {
|
||||||
registry.push(effectName);
|
registry.push(effectName);
|
||||||
}
|
}
|
||||||
envSet(env, "*effect-registry*", registry);
|
envBind(env, "*effect-registry*", registry);
|
||||||
return NIL;
|
return NIL;
|
||||||
})(); };
|
})(); };
|
||||||
PRIMITIVES["sf-defeffect"] = sfDefeffect;
|
PRIMITIVES["sf-defeffect"] = sfDefeffect;
|
||||||
@@ -1237,18 +1242,18 @@ PRIMITIVES["sf-set!"] = sfSetBang;
|
|||||||
var vname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding));
|
var vname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : first(binding));
|
||||||
names.push(vname);
|
names.push(vname);
|
||||||
valExprs.push(nth(binding, 1));
|
valExprs.push(nth(binding, 1));
|
||||||
return envSet(local, vname, NIL);
|
return envBind(local, vname, NIL);
|
||||||
})(); }, bindings) : reduce(function(acc, pairIdx) { return (function() {
|
})(); }, bindings) : reduce(function(acc, pairIdx) { return (function() {
|
||||||
var vname = (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)));
|
var vname = (isSxTruthy((typeOf(nth(bindings, (pairIdx * 2))) == "symbol")) ? symbolName(nth(bindings, (pairIdx * 2))) : nth(bindings, (pairIdx * 2)));
|
||||||
var valExpr = nth(bindings, ((pairIdx * 2) + 1));
|
var valExpr = nth(bindings, ((pairIdx * 2) + 1));
|
||||||
names.push(vname);
|
names.push(vname);
|
||||||
valExprs.push(valExpr);
|
valExprs.push(valExpr);
|
||||||
return envSet(local, vname, NIL);
|
return envBind(local, vname, NIL);
|
||||||
})(); }, NIL, range(0, (len(bindings) / 2))));
|
})(); }, NIL, range(0, (len(bindings) / 2))));
|
||||||
(function() {
|
(function() {
|
||||||
var values = map(function(e) { return trampoline(evalExpr(e, local)); }, valExprs);
|
var values = map(function(e) { return trampoline(evalExpr(e, local)); }, valExprs);
|
||||||
{ var _c = zip(names, values); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; envSet(local, first(pair), nth(pair, 1)); } }
|
{ var _c = zip(names, values); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; envBind(local, first(pair), nth(pair, 1)); } }
|
||||||
return forEach(function(val) { return (isSxTruthy(isLambda(val)) ? forEach(function(n) { return envSet(lambdaClosure(val), n, envGet(local, n)); }, names) : NIL); }, values);
|
return forEach(function(val) { return (isSxTruthy(isLambda(val)) ? forEach(function(n) { return envBind(lambdaClosure(val), n, envGet(local, n)); }, names) : NIL); }, values);
|
||||||
})();
|
})();
|
||||||
{ var _c = slice(body, 0, (len(body) - 1)); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
|
{ var _c = slice(body, 0, (len(body) - 1)); for (var _i = 0; _i < _c.length; _i++) { var e = _c[_i]; trampoline(evalExpr(e, local)); } }
|
||||||
return makeThunk(last(body), local);
|
return makeThunk(last(body), local);
|
||||||
@@ -1297,9 +1302,9 @@ PRIMITIVES["sf-provide"] = sfProvide;
|
|||||||
// expand-macro
|
// expand-macro
|
||||||
var expandMacro = function(mac, rawArgs, env) { return (function() {
|
var expandMacro = function(mac, rawArgs, env) { return (function() {
|
||||||
var local = envMerge(macroClosure(mac), env);
|
var local = envMerge(macroClosure(mac), env);
|
||||||
{ var _c = mapIndexed(function(i, p) { return [p, i]; }, macroParams(mac)); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; envSet(local, first(pair), (isSxTruthy((nth(pair, 1) < len(rawArgs))) ? nth(rawArgs, nth(pair, 1)) : NIL)); } }
|
{ var _c = mapIndexed(function(i, p) { return [p, i]; }, macroParams(mac)); for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; envBind(local, first(pair), (isSxTruthy((nth(pair, 1) < len(rawArgs))) ? nth(rawArgs, nth(pair, 1)) : NIL)); } }
|
||||||
if (isSxTruthy(macroRestParam(mac))) {
|
if (isSxTruthy(macroRestParam(mac))) {
|
||||||
envSet(local, macroRestParam(mac), slice(rawArgs, len(macroParams(mac))));
|
envBind(local, macroRestParam(mac), slice(rawArgs, len(macroParams(mac))));
|
||||||
}
|
}
|
||||||
return trampoline(evalExpr(macroBody(mac), local));
|
return trampoline(evalExpr(macroBody(mac), local));
|
||||||
})(); };
|
})(); };
|
||||||
@@ -1435,7 +1440,7 @@ PRIMITIVES["eval-cond-clojure"] = evalCondClojure;
|
|||||||
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(pair) == "list")) && (len(pair) >= 2)))) {
|
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var pair = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(pair) == "list")) && (len(pair) >= 2)))) {
|
||||||
(function() {
|
(function() {
|
||||||
var name = (isSxTruthy((typeOf(first(pair)) == "symbol")) ? symbolName(first(pair)) : (String(first(pair))));
|
var name = (isSxTruthy((typeOf(first(pair)) == "symbol")) ? symbolName(first(pair)) : (String(first(pair))));
|
||||||
return envSet(local, name, trampoline(evalExpr(nth(pair, 1), local)));
|
return envBind(local, name, trampoline(evalExpr(nth(pair, 1), local)));
|
||||||
})();
|
})();
|
||||||
} } }
|
} } }
|
||||||
return local;
|
return local;
|
||||||
@@ -1722,7 +1727,7 @@ PRIMITIVES["dispatch-html-form"] = dispatchHtmlForm;
|
|||||||
// render-lambda-html
|
// render-lambda-html
|
||||||
var renderLambdaHtml = function(f, args, env) { return (function() {
|
var renderLambdaHtml = function(f, args, env) { return (function() {
|
||||||
var local = envMerge(lambdaClosure(f), env);
|
var local = envMerge(lambdaClosure(f), env);
|
||||||
forEachIndexed(function(i, p) { return envSet(local, p, nth(args, i)); }, lambdaParams(f));
|
forEachIndexed(function(i, p) { return envBind(local, p, nth(args, i)); }, lambdaParams(f));
|
||||||
return renderToHtml(lambdaBody(f), local);
|
return renderToHtml(lambdaBody(f), local);
|
||||||
})(); };
|
})(); };
|
||||||
PRIMITIVES["render-lambda-html"] = renderLambdaHtml;
|
PRIMITIVES["render-lambda-html"] = renderLambdaHtml;
|
||||||
@@ -1741,9 +1746,9 @@ PRIMITIVES["render-lambda-html"] = renderLambdaHtml;
|
|||||||
})(); }, {["i"]: 0, ["skip"]: false}, args);
|
})(); }, {["i"]: 0, ["skip"]: false}, args);
|
||||||
return (function() {
|
return (function() {
|
||||||
var local = envMerge(componentClosure(comp), env);
|
var local = envMerge(componentClosure(comp), env);
|
||||||
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envSet(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
||||||
if (isSxTruthy(componentHasChildren(comp))) {
|
if (isSxTruthy(componentHasChildren(comp))) {
|
||||||
envSet(local, "children", makeRawHtml(join("", map(function(c) { return renderToHtml(c, env); }, children))));
|
envBind(local, "children", makeRawHtml(join("", map(function(c) { return renderToHtml(c, env); }, children))));
|
||||||
}
|
}
|
||||||
return renderToHtml(componentBody(comp), local);
|
return renderToHtml(componentBody(comp), local);
|
||||||
})();
|
})();
|
||||||
@@ -1834,9 +1839,9 @@ PRIMITIVES["render-html-marsh"] = renderHtmlMarsh;
|
|||||||
return (function() {
|
return (function() {
|
||||||
var local = envMerge(componentClosure(island), env);
|
var local = envMerge(componentClosure(island), env);
|
||||||
var islandName = componentName(island);
|
var islandName = componentName(island);
|
||||||
{ var _c = componentParams(island); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envSet(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
{ var _c = componentParams(island); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
||||||
if (isSxTruthy(componentHasChildren(island))) {
|
if (isSxTruthy(componentHasChildren(island))) {
|
||||||
envSet(local, "children", makeRawHtml(join("", map(function(c) { return renderToHtml(c, env); }, children))));
|
envBind(local, "children", makeRawHtml(join("", map(function(c) { return renderToHtml(c, env); }, children))));
|
||||||
}
|
}
|
||||||
return (function() {
|
return (function() {
|
||||||
var bodyHtml = renderToHtml(componentBody(island), local);
|
var bodyHtml = renderToHtml(componentBody(island), local);
|
||||||
@@ -1987,7 +1992,7 @@ return result; }, args);
|
|||||||
var coll = trampoline(evalExpr(nth(args, 1), env));
|
var coll = trampoline(evalExpr(nth(args, 1), env));
|
||||||
return map(function(item) { return (isSxTruthy(isLambda(f)) ? (function() {
|
return map(function(item) { return (isSxTruthy(isLambda(f)) ? (function() {
|
||||||
var local = envMerge(lambdaClosure(f), env);
|
var local = envMerge(lambdaClosure(f), env);
|
||||||
envSet(local, first(lambdaParams(f)), item);
|
envBind(local, first(lambdaParams(f)), item);
|
||||||
return aser(lambdaBody(f), local);
|
return aser(lambdaBody(f), local);
|
||||||
})() : cekCall(f, [item])); }, coll);
|
})() : cekCall(f, [item])); }, coll);
|
||||||
})() : (isSxTruthy((name == "map-indexed")) ? (function() {
|
})() : (isSxTruthy((name == "map-indexed")) ? (function() {
|
||||||
@@ -1995,8 +2000,8 @@ return result; }, args);
|
|||||||
var coll = trampoline(evalExpr(nth(args, 1), env));
|
var coll = trampoline(evalExpr(nth(args, 1), env));
|
||||||
return mapIndexed(function(i, item) { return (isSxTruthy(isLambda(f)) ? (function() {
|
return mapIndexed(function(i, item) { return (isSxTruthy(isLambda(f)) ? (function() {
|
||||||
var local = envMerge(lambdaClosure(f), env);
|
var local = envMerge(lambdaClosure(f), env);
|
||||||
envSet(local, first(lambdaParams(f)), i);
|
envBind(local, first(lambdaParams(f)), i);
|
||||||
envSet(local, nth(lambdaParams(f), 1), item);
|
envBind(local, nth(lambdaParams(f), 1), item);
|
||||||
return aser(lambdaBody(f), local);
|
return aser(lambdaBody(f), local);
|
||||||
})() : cekCall(f, [i, item])); }, coll);
|
})() : cekCall(f, [i, item])); }, coll);
|
||||||
})() : (isSxTruthy((name == "for-each")) ? (function() {
|
})() : (isSxTruthy((name == "for-each")) ? (function() {
|
||||||
@@ -2005,7 +2010,7 @@ return result; }, args);
|
|||||||
var results = [];
|
var results = [];
|
||||||
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var item = _c[_i]; (isSxTruthy(isLambda(f)) ? (function() {
|
{ var _c = coll; for (var _i = 0; _i < _c.length; _i++) { var item = _c[_i]; (isSxTruthy(isLambda(f)) ? (function() {
|
||||||
var local = envMerge(lambdaClosure(f), env);
|
var local = envMerge(lambdaClosure(f), env);
|
||||||
envSet(local, first(lambdaParams(f)), item);
|
envBind(local, first(lambdaParams(f)), item);
|
||||||
return append_b(results, aser(lambdaBody(f), local));
|
return append_b(results, aser(lambdaBody(f), local));
|
||||||
})() : cekCall(f, [item])); } }
|
})() : cekCall(f, [item])); } }
|
||||||
return (isSxTruthy(isEmpty(results)) ? NIL : results);
|
return (isSxTruthy(isEmpty(results)) ? NIL : results);
|
||||||
@@ -2143,7 +2148,7 @@ PRIMITIVES["render-dom-element"] = renderDomElement;
|
|||||||
})(); }, {["i"]: 0, ["skip"]: false}, args);
|
})(); }, {["i"]: 0, ["skip"]: false}, args);
|
||||||
return (function() {
|
return (function() {
|
||||||
var local = envMerge(componentClosure(comp), env);
|
var local = envMerge(componentClosure(comp), env);
|
||||||
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envSet(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
||||||
if (isSxTruthy(componentHasChildren(comp))) {
|
if (isSxTruthy(componentHasChildren(comp))) {
|
||||||
(function() {
|
(function() {
|
||||||
var childFrag = createFragment();
|
var childFrag = createFragment();
|
||||||
@@ -2151,7 +2156,7 @@ PRIMITIVES["render-dom-element"] = renderDomElement;
|
|||||||
var result = renderToDom(c, env, ns);
|
var result = renderToDom(c, env, ns);
|
||||||
return (isSxTruthy(!isSxTruthy(isSpread(result))) ? domAppend(childFrag, result) : NIL);
|
return (isSxTruthy(!isSxTruthy(isSpread(result))) ? domAppend(childFrag, result) : NIL);
|
||||||
})(); } }
|
})(); } }
|
||||||
return envSet(local, "children", childFrag);
|
return envBind(local, "children", childFrag);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
return renderToDom(componentBody(comp), local, ns);
|
return renderToDom(componentBody(comp), local, ns);
|
||||||
@@ -2355,7 +2360,7 @@ PRIMITIVES["dispatch-render-form"] = dispatchRenderForm;
|
|||||||
// render-lambda-dom
|
// render-lambda-dom
|
||||||
var renderLambdaDom = function(f, args, env, ns) { return (function() {
|
var renderLambdaDom = function(f, args, env, ns) { return (function() {
|
||||||
var local = envMerge(lambdaClosure(f), env);
|
var local = envMerge(lambdaClosure(f), env);
|
||||||
forEachIndexed(function(i, p) { return envSet(local, p, nth(args, i)); }, lambdaParams(f));
|
forEachIndexed(function(i, p) { return envBind(local, p, nth(args, i)); }, lambdaParams(f));
|
||||||
return renderToDom(lambdaBody(f), local, ns);
|
return renderToDom(lambdaBody(f), local, ns);
|
||||||
})(); };
|
})(); };
|
||||||
PRIMITIVES["render-lambda-dom"] = renderLambdaDom;
|
PRIMITIVES["render-lambda-dom"] = renderLambdaDom;
|
||||||
@@ -2375,12 +2380,12 @@ PRIMITIVES["render-lambda-dom"] = renderLambdaDom;
|
|||||||
return (function() {
|
return (function() {
|
||||||
var local = envMerge(componentClosure(island), env);
|
var local = envMerge(componentClosure(island), env);
|
||||||
var islandName = componentName(island);
|
var islandName = componentName(island);
|
||||||
{ var _c = componentParams(island); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envSet(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
{ var _c = componentParams(island); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
||||||
if (isSxTruthy(componentHasChildren(island))) {
|
if (isSxTruthy(componentHasChildren(island))) {
|
||||||
(function() {
|
(function() {
|
||||||
var childFrag = createFragment();
|
var childFrag = createFragment();
|
||||||
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; domAppend(childFrag, renderToDom(c, env, ns)); } }
|
{ var _c = children; for (var _i = 0; _i < _c.length; _i++) { var c = _c[_i]; domAppend(childFrag, renderToDom(c, env, ns)); } }
|
||||||
return envSet(local, "children", childFrag);
|
return envBind(local, "children", childFrag);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
return (function() {
|
return (function() {
|
||||||
@@ -3657,9 +3662,9 @@ PRIMITIVES["bind-sse-swap"] = bindSseSwap;
|
|||||||
var exprs = sxParse(body);
|
var exprs = sxParse(body);
|
||||||
return domListen(el, eventName, function(e) { return (function() {
|
return domListen(el, eventName, function(e) { return (function() {
|
||||||
var handlerEnv = envExtend({});
|
var handlerEnv = envExtend({});
|
||||||
envSet(handlerEnv, "event", e);
|
envBind(handlerEnv, "event", e);
|
||||||
envSet(handlerEnv, "this", el);
|
envBind(handlerEnv, "this", el);
|
||||||
envSet(handlerEnv, "detail", eventDetail(e));
|
envBind(handlerEnv, "detail", eventDetail(e));
|
||||||
return forEach(function(expr) { return evalExpr(expr, handlerEnv); }, exprs);
|
return forEach(function(expr) { return evalExpr(expr, handlerEnv); }, exprs);
|
||||||
})(); });
|
})(); });
|
||||||
})()) : NIL);
|
})()) : NIL);
|
||||||
@@ -3921,7 +3926,7 @@ PRIMITIVES["sx-hydrate-islands"] = sxHydrateIslands;
|
|||||||
var kwargs = sxOr(first(sxParse(stateSx)), {});
|
var kwargs = sxOr(first(sxParse(stateSx)), {});
|
||||||
var disposers = [];
|
var disposers = [];
|
||||||
var local = envMerge(componentClosure(comp), env);
|
var local = envMerge(componentClosure(comp), env);
|
||||||
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envSet(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
{ var _c = componentParams(comp); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, (isSxTruthy(dictHas(kwargs, p)) ? dictGet(kwargs, p) : NIL)); } }
|
||||||
return (function() {
|
return (function() {
|
||||||
var bodyDom = withIslandScope(function(disposable) { return append_b(disposers, disposable); }, function() { return renderToDom(componentBody(comp), local, NIL); });
|
var bodyDom = withIslandScope(function(disposable) { return append_b(disposers, disposable); }, function() { return renderToDom(componentBody(comp), local, NIL); });
|
||||||
domSetTextContent(el, "");
|
domSetTextContent(el, "");
|
||||||
@@ -4957,7 +4962,7 @@ PRIMITIVES["step-sf-reset"] = stepSfReset;
|
|||||||
var k = makeCekContinuation(captured, restKont);
|
var k = makeCekContinuation(captured, restKont);
|
||||||
return (function() {
|
return (function() {
|
||||||
var shiftEnv = envExtend(env);
|
var shiftEnv = envExtend(env);
|
||||||
envSet(shiftEnv, kName, k);
|
envBind(shiftEnv, kName, k);
|
||||||
return makeCekState(body, shiftEnv, restKont);
|
return makeCekState(body, shiftEnv, restKont);
|
||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
@@ -5087,7 +5092,7 @@ PRIMITIVES["step-ho-for-each"] = stepHoForEach;
|
|||||||
var remaining = get(frame, "remaining");
|
var remaining = get(frame, "remaining");
|
||||||
var body = get(frame, "body");
|
var body = get(frame, "body");
|
||||||
var local = get(frame, "env");
|
var local = get(frame, "env");
|
||||||
envSet(local, name, value);
|
envBind(local, name, value);
|
||||||
return (isSxTruthy(isEmpty(remaining)) ? stepSfBegin(body, local, restK) : (function() {
|
return (isSxTruthy(isEmpty(remaining)) ? stepSfBegin(body, local, restK) : (function() {
|
||||||
var nextBinding = first(remaining);
|
var nextBinding = first(remaining);
|
||||||
var vname = (isSxTruthy((typeOf(first(nextBinding)) == "symbol")) ? symbolName(first(nextBinding)) : first(nextBinding));
|
var vname = (isSxTruthy((typeOf(first(nextBinding)) == "symbol")) ? symbolName(first(nextBinding)) : first(nextBinding));
|
||||||
@@ -5101,13 +5106,13 @@ PRIMITIVES["step-ho-for-each"] = stepHoForEach;
|
|||||||
if (isSxTruthy((isSxTruthy(isLambda(value)) && isNil(lambdaName(value))))) {
|
if (isSxTruthy((isSxTruthy(isLambda(value)) && isNil(lambdaName(value))))) {
|
||||||
value.name = name;
|
value.name = name;
|
||||||
}
|
}
|
||||||
envSet(fenv, name, value);
|
envBind(fenv, name, value);
|
||||||
if (isSxTruthy(hasEffects)) {
|
if (isSxTruthy(hasEffects)) {
|
||||||
(function() {
|
(function() {
|
||||||
var effectNames = (isSxTruthy((typeOf(effectList) == "list")) ? map(function(e) { return (isSxTruthy((typeOf(e) == "symbol")) ? symbolName(e) : (String(e))); }, effectList) : [(String(effectList))]);
|
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*") : {});
|
var effectAnns = (isSxTruthy(envHas(fenv, "*effect-annotations*")) ? envGet(fenv, "*effect-annotations*") : {});
|
||||||
effectAnns[name] = effectNames;
|
effectAnns[name] = effectNames;
|
||||||
return envSet(fenv, "*effect-annotations*", effectAnns);
|
return envBind(fenv, "*effect-annotations*", effectAnns);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
return makeCekValue(value, fenv, restK);
|
return makeCekValue(value, fenv, restK);
|
||||||
@@ -5274,15 +5279,15 @@ PRIMITIVES["step-continue"] = stepContinue;
|
|||||||
})() : (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() {
|
})() : (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 params = lambdaParams(f);
|
||||||
var local = envMerge(lambdaClosure(f), env);
|
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)));
|
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 envBind(local, first(pair), nth(pair, 1)); }, zip(params, args)), forEach(function(p) { return envBind(local, p, NIL); }, slice(params, len(args))), makeCekState(lambdaBody(f), local, kont)));
|
||||||
})() : (isSxTruthy(sxOr(isComponent(f), isIsland(f))) ? (function() {
|
})() : (isSxTruthy(sxOr(isComponent(f), isIsland(f))) ? (function() {
|
||||||
var parsed = parseKeywordArgs(rawArgs, env);
|
var parsed = parseKeywordArgs(rawArgs, env);
|
||||||
var kwargs = first(parsed);
|
var kwargs = first(parsed);
|
||||||
var children = nth(parsed, 1);
|
var children = nth(parsed, 1);
|
||||||
var local = envMerge(componentClosure(f), env);
|
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)); } }
|
{ var _c = componentParams(f); for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; envBind(local, p, sxOr(dictGet(kwargs, p), NIL)); } }
|
||||||
if (isSxTruthy(componentHasChildren(f))) {
|
if (isSxTruthy(componentHasChildren(f))) {
|
||||||
envSet(local, "children", children);
|
envBind(local, "children", children);
|
||||||
}
|
}
|
||||||
return makeCekState(componentBody(f), local, kont);
|
return makeCekState(componentBody(f), local, kont);
|
||||||
})() : error((String("Not callable: ") + String(inspect(f)))))))); };
|
})() : error((String("Not callable: ") + String(inspect(f)))))))); };
|
||||||
|
|||||||
16
spec/cek.sx
16
spec/cek.sx
@@ -396,7 +396,7 @@
|
|||||||
(let ((k (make-cek-continuation captured rest-kont)))
|
(let ((k (make-cek-continuation captured rest-kont)))
|
||||||
;; Evaluate shift body with k bound, continuation goes to rest-kont
|
;; Evaluate shift body with k bound, continuation goes to rest-kont
|
||||||
(let ((shift-env (env-extend env)))
|
(let ((shift-env (env-extend env)))
|
||||||
(env-set! shift-env k-name k)
|
(env-bind! shift-env k-name k)
|
||||||
(make-cek-state body shift-env rest-kont))))))
|
(make-cek-state body shift-env rest-kont))))))
|
||||||
|
|
||||||
|
|
||||||
@@ -604,7 +604,7 @@
|
|||||||
(body (get frame "body"))
|
(body (get frame "body"))
|
||||||
(local (get frame "env")))
|
(local (get frame "env")))
|
||||||
;; Bind the value
|
;; Bind the value
|
||||||
(env-set! local name value)
|
(env-bind! local name value)
|
||||||
;; More bindings?
|
;; More bindings?
|
||||||
(if (empty? remaining)
|
(if (empty? remaining)
|
||||||
;; All bindings done — evaluate body
|
;; All bindings done — evaluate body
|
||||||
@@ -628,7 +628,7 @@
|
|||||||
(effect-list (get frame "effect-list")))
|
(effect-list (get frame "effect-list")))
|
||||||
(when (and (lambda? value) (nil? (lambda-name value)))
|
(when (and (lambda? value) (nil? (lambda-name value)))
|
||||||
(set-lambda-name! value name))
|
(set-lambda-name! value name))
|
||||||
(env-set! fenv name value)
|
(env-bind! fenv name value)
|
||||||
;; Effect annotation
|
;; Effect annotation
|
||||||
(when has-effects
|
(when has-effects
|
||||||
(let ((effect-names (if (= (type-of effect-list) "list")
|
(let ((effect-names (if (= (type-of effect-list) "list")
|
||||||
@@ -640,7 +640,7 @@
|
|||||||
(env-get fenv "*effect-annotations*")
|
(env-get fenv "*effect-annotations*")
|
||||||
(dict))))
|
(dict))))
|
||||||
(dict-set! effect-anns name effect-names)
|
(dict-set! effect-anns name effect-names)
|
||||||
(env-set! fenv "*effect-annotations*" effect-anns)))
|
(env-bind! fenv "*effect-annotations*" effect-anns)))
|
||||||
(make-cek-value value fenv rest-k))
|
(make-cek-value value fenv rest-k))
|
||||||
|
|
||||||
;; --- SetFrame: value evaluated ---
|
;; --- SetFrame: value evaluated ---
|
||||||
@@ -969,10 +969,10 @@
|
|||||||
" expects " (len params) " args, got " (len args)))
|
" expects " (len params) " args, got " (len args)))
|
||||||
(do
|
(do
|
||||||
(for-each
|
(for-each
|
||||||
(fn (pair) (env-set! local (first pair) (nth pair 1)))
|
(fn (pair) (env-bind! local (first pair) (nth pair 1)))
|
||||||
(zip params args))
|
(zip params args))
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p) (env-set! local p nil))
|
(fn (p) (env-bind! local p nil))
|
||||||
(slice params (len args)))
|
(slice params (len args)))
|
||||||
(make-cek-state (lambda-body f) local kont))))
|
(make-cek-state (lambda-body f) local kont))))
|
||||||
|
|
||||||
@@ -983,10 +983,10 @@
|
|||||||
(children (nth parsed 1))
|
(children (nth parsed 1))
|
||||||
(local (env-merge (component-closure f) env)))
|
(local (env-merge (component-closure f) env)))
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p) (env-set! local p (or (dict-get kwargs p) nil)))
|
(fn (p) (env-bind! local p (or (dict-get kwargs p) nil)))
|
||||||
(component-params f))
|
(component-params f))
|
||||||
(when (component-has-children? f)
|
(when (component-has-children? f)
|
||||||
(env-set! local "children" children))
|
(env-bind! local "children" children))
|
||||||
(make-cek-state (component-body f) local kont))
|
(make-cek-state (component-body f) local kont))
|
||||||
|
|
||||||
:else (error (str "Not callable: " (inspect f))))))
|
:else (error (str "Not callable: " (inspect f))))))
|
||||||
|
|||||||
47
spec/eval.sx
47
spec/eval.sx
@@ -229,10 +229,10 @@
|
|||||||
(do
|
(do
|
||||||
;; Bind params — provided args first, then nil for missing
|
;; Bind params — provided args first, then nil for missing
|
||||||
(for-each
|
(for-each
|
||||||
(fn (pair) (env-set! local (first pair) (nth pair 1)))
|
(fn (pair) (env-bind! local (first pair) (nth pair 1)))
|
||||||
(zip params args))
|
(zip params args))
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p) (env-set! local p nil))
|
(fn (p) (env-bind! local p nil))
|
||||||
(slice params (len args)))
|
(slice params (len args)))
|
||||||
;; Return thunk for TCO
|
;; Return thunk for TCO
|
||||||
(make-thunk (lambda-body f) local))))))
|
(make-thunk (lambda-body f) local))))))
|
||||||
@@ -247,11 +247,11 @@
|
|||||||
(local (env-merge (component-closure comp) env)))
|
(local (env-merge (component-closure comp) env)))
|
||||||
;; Bind keyword params
|
;; Bind keyword params
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p) (env-set! local p (or (dict-get kwargs p) nil)))
|
(fn (p) (env-bind! local p (or (dict-get kwargs p) nil)))
|
||||||
(component-params comp))
|
(component-params comp))
|
||||||
;; Bind children if component accepts them
|
;; Bind children if component accepts them
|
||||||
(when (component-has-children? comp)
|
(when (component-has-children? comp)
|
||||||
(env-set! local "children" children))
|
(env-bind! local "children" children))
|
||||||
;; Return thunk — body evaluated in local env
|
;; Return thunk — body evaluated in local env
|
||||||
(make-thunk (component-body comp) local))))
|
(make-thunk (component-body comp) local))))
|
||||||
|
|
||||||
@@ -423,7 +423,7 @@
|
|||||||
(let ((vname (if (= (type-of (first binding)) "symbol")
|
(let ((vname (if (= (type-of (first binding)) "symbol")
|
||||||
(symbol-name (first binding))
|
(symbol-name (first binding))
|
||||||
(first binding))))
|
(first binding))))
|
||||||
(env-set! local vname (trampoline (eval-expr (nth binding 1) local)))))
|
(env-bind! local vname (trampoline (eval-expr (nth binding 1) local)))))
|
||||||
bindings)
|
bindings)
|
||||||
;; Clojure-style
|
;; Clojure-style
|
||||||
(let ((i 0))
|
(let ((i 0))
|
||||||
@@ -433,7 +433,7 @@
|
|||||||
(symbol-name (nth bindings (* pair-idx 2)))
|
(symbol-name (nth bindings (* pair-idx 2)))
|
||||||
(nth bindings (* pair-idx 2))))
|
(nth bindings (* pair-idx 2))))
|
||||||
(val-expr (nth bindings (inc (* pair-idx 2)))))
|
(val-expr (nth bindings (inc (* pair-idx 2)))))
|
||||||
(env-set! local vname (trampoline (eval-expr val-expr local)))))
|
(env-bind! local vname (trampoline (eval-expr val-expr local)))))
|
||||||
nil
|
nil
|
||||||
(range 0 (/ (len bindings) 2)))))
|
(range 0 (/ (len bindings) 2)))))
|
||||||
;; Evaluate body — last expression in tail position
|
;; Evaluate body — last expression in tail position
|
||||||
@@ -480,7 +480,7 @@
|
|||||||
(loop-fn (make-lambda params loop-body env)))
|
(loop-fn (make-lambda params loop-body env)))
|
||||||
;; Self-reference: loop can call itself by name
|
;; Self-reference: loop can call itself by name
|
||||||
(set-lambda-name! loop-fn loop-name)
|
(set-lambda-name! loop-fn loop-name)
|
||||||
(env-set! (lambda-closure loop-fn) loop-name loop-fn)
|
(env-bind! (lambda-closure loop-fn) loop-name loop-fn)
|
||||||
;; Evaluate initial values in enclosing env, then call
|
;; Evaluate initial values in enclosing env, then call
|
||||||
(let ((init-vals (map (fn (e) (trampoline (eval-expr e env))) inits)))
|
(let ((init-vals (map (fn (e) (trampoline (eval-expr e env))) inits)))
|
||||||
(call-lambda loop-fn init-vals env))))))
|
(call-lambda loop-fn init-vals env))))))
|
||||||
@@ -522,7 +522,7 @@
|
|||||||
(value (trampoline (eval-expr (nth args val-idx) env))))
|
(value (trampoline (eval-expr (nth args val-idx) env))))
|
||||||
(when (and (lambda? value) (nil? (lambda-name value)))
|
(when (and (lambda? value) (nil? (lambda-name value)))
|
||||||
(set-lambda-name! value (symbol-name name-sym)))
|
(set-lambda-name! value (symbol-name name-sym)))
|
||||||
(env-set! env (symbol-name name-sym) value)
|
(env-bind! env (symbol-name name-sym) value)
|
||||||
;; Store effect annotation if declared
|
;; Store effect annotation if declared
|
||||||
(when has-effects
|
(when has-effects
|
||||||
(let ((effects-raw (nth args 2))
|
(let ((effects-raw (nth args 2))
|
||||||
@@ -535,7 +535,7 @@
|
|||||||
(env-get env "*effect-annotations*")
|
(env-get env "*effect-annotations*")
|
||||||
(dict))))
|
(dict))))
|
||||||
(dict-set! effect-anns (symbol-name name-sym) effect-list)
|
(dict-set! effect-anns (symbol-name name-sym) effect-list)
|
||||||
(env-set! env "*effect-annotations*" effect-anns)))
|
(env-bind! env "*effect-annotations*" effect-anns)))
|
||||||
value)))
|
value)))
|
||||||
|
|
||||||
|
|
||||||
@@ -570,8 +570,8 @@
|
|||||||
(env-get env "*effect-annotations*")
|
(env-get env "*effect-annotations*")
|
||||||
(dict))))
|
(dict))))
|
||||||
(dict-set! effect-anns (symbol-name name-sym) effect-list)
|
(dict-set! effect-anns (symbol-name name-sym) effect-list)
|
||||||
(env-set! env "*effect-annotations*" effect-anns)))
|
(env-bind! env "*effect-annotations*" effect-anns)))
|
||||||
(env-set! env (symbol-name name-sym) comp)
|
(env-bind! env (symbol-name name-sym) comp)
|
||||||
comp))))
|
comp))))
|
||||||
|
|
||||||
(define defcomp-kwarg
|
(define defcomp-kwarg
|
||||||
@@ -646,7 +646,7 @@
|
|||||||
(params (first parsed))
|
(params (first parsed))
|
||||||
(has-children (nth parsed 1)))
|
(has-children (nth parsed 1)))
|
||||||
(let ((island (make-island comp-name params has-children body env)))
|
(let ((island (make-island comp-name params has-children body env)))
|
||||||
(env-set! env (symbol-name name-sym) island)
|
(env-bind! env (symbol-name name-sym) island)
|
||||||
island))))
|
island))))
|
||||||
|
|
||||||
|
|
||||||
@@ -659,7 +659,7 @@
|
|||||||
(params (first parsed))
|
(params (first parsed))
|
||||||
(rest-param (nth parsed 1)))
|
(rest-param (nth parsed 1)))
|
||||||
(let ((mac (make-macro params rest-param body env (symbol-name name-sym))))
|
(let ((mac (make-macro params rest-param body env (symbol-name name-sym))))
|
||||||
(env-set! env (symbol-name name-sym) mac)
|
(env-bind! env (symbol-name name-sym) mac)
|
||||||
mac))))
|
mac))))
|
||||||
|
|
||||||
(define parse-macro-params
|
(define parse-macro-params
|
||||||
@@ -688,7 +688,7 @@
|
|||||||
;; (defstyle name expr) — bind name to evaluated expr (string, function, etc.)
|
;; (defstyle name expr) — bind name to evaluated expr (string, function, etc.)
|
||||||
(let ((name-sym (first args))
|
(let ((name-sym (first args))
|
||||||
(value (trampoline (eval-expr (nth args 1) env))))
|
(value (trampoline (eval-expr (nth args 1) env))))
|
||||||
(env-set! env (symbol-name name-sym) value)
|
(env-bind! env (symbol-name name-sym) value)
|
||||||
value)))
|
value)))
|
||||||
|
|
||||||
|
|
||||||
@@ -749,7 +749,7 @@
|
|||||||
(dict))))
|
(dict))))
|
||||||
(dict-set! registry type-name
|
(dict-set! registry type-name
|
||||||
(make-type-def type-name type-params body))
|
(make-type-def type-name type-params body))
|
||||||
(env-set! env "*type-registry*" registry)
|
(env-bind! env "*type-registry*" registry)
|
||||||
nil))))
|
nil))))
|
||||||
|
|
||||||
|
|
||||||
@@ -764,7 +764,7 @@
|
|||||||
(list))))
|
(list))))
|
||||||
(when (not (contains? registry effect-name))
|
(when (not (contains? registry effect-name))
|
||||||
(append! registry effect-name))
|
(append! registry effect-name))
|
||||||
(env-set! env "*effect-registry*" registry)
|
(env-bind! env "*effect-registry*" registry)
|
||||||
nil)))
|
nil)))
|
||||||
|
|
||||||
|
|
||||||
@@ -879,7 +879,7 @@
|
|||||||
(first binding))))
|
(first binding))))
|
||||||
(append! names vname)
|
(append! names vname)
|
||||||
(append! val-exprs (nth binding 1))
|
(append! val-exprs (nth binding 1))
|
||||||
(env-set! local vname nil)))
|
(env-bind! local vname nil)))
|
||||||
bindings)
|
bindings)
|
||||||
;; Clojure-style
|
;; Clojure-style
|
||||||
(reduce
|
(reduce
|
||||||
@@ -890,21 +890,21 @@
|
|||||||
(val-expr (nth bindings (inc (* pair-idx 2)))))
|
(val-expr (nth bindings (inc (* pair-idx 2)))))
|
||||||
(append! names vname)
|
(append! names vname)
|
||||||
(append! val-exprs val-expr)
|
(append! val-exprs val-expr)
|
||||||
(env-set! local vname nil)))
|
(env-bind! local vname nil)))
|
||||||
nil
|
nil
|
||||||
(range 0 (/ (len bindings) 2))))
|
(range 0 (/ (len bindings) 2))))
|
||||||
;; Second pass: evaluate values (they can see each other's names)
|
;; Second pass: evaluate values (they can see each other's names)
|
||||||
(let ((values (map (fn (e) (trampoline (eval-expr e local))) val-exprs)))
|
(let ((values (map (fn (e) (trampoline (eval-expr e local))) val-exprs)))
|
||||||
;; Bind final values
|
;; Bind final values
|
||||||
(for-each
|
(for-each
|
||||||
(fn (pair) (env-set! local (first pair) (nth pair 1)))
|
(fn (pair) (env-bind! local (first pair) (nth pair 1)))
|
||||||
(zip names values))
|
(zip names values))
|
||||||
;; Patch lambda closures so they see the final bindings
|
;; Patch lambda closures so they see the final bindings
|
||||||
(for-each
|
(for-each
|
||||||
(fn (val)
|
(fn (val)
|
||||||
(when (lambda? val)
|
(when (lambda? val)
|
||||||
(for-each
|
(for-each
|
||||||
(fn (n) (env-set! (lambda-closure val) n (env-get local n)))
|
(fn (n) (env-bind! (lambda-closure val) n (env-get local n)))
|
||||||
names)))
|
names)))
|
||||||
values))
|
values))
|
||||||
;; Evaluate body
|
;; Evaluate body
|
||||||
@@ -998,14 +998,14 @@
|
|||||||
;; Bind positional params (unevaluated)
|
;; Bind positional params (unevaluated)
|
||||||
(for-each
|
(for-each
|
||||||
(fn (pair)
|
(fn (pair)
|
||||||
(env-set! local (first pair)
|
(env-bind! local (first pair)
|
||||||
(if (< (nth pair 1) (len raw-args))
|
(if (< (nth pair 1) (len raw-args))
|
||||||
(nth raw-args (nth pair 1))
|
(nth raw-args (nth pair 1))
|
||||||
nil)))
|
nil)))
|
||||||
(map-indexed (fn (i p) (list p i)) (macro-params mac)))
|
(map-indexed (fn (i p) (list p i)) (macro-params mac)))
|
||||||
;; Bind &rest param
|
;; Bind &rest param
|
||||||
(when (macro-rest-param mac)
|
(when (macro-rest-param mac)
|
||||||
(env-set! local (macro-rest-param mac)
|
(env-bind! local (macro-rest-param mac)
|
||||||
(slice raw-args (len (macro-params mac)))))
|
(slice raw-args (len (macro-params mac)))))
|
||||||
;; Evaluate body → new AST
|
;; Evaluate body → new AST
|
||||||
(trampoline (eval-expr (macro-body mac) local)))))
|
(trampoline (eval-expr (macro-body mac) local)))))
|
||||||
@@ -1153,7 +1153,8 @@
|
|||||||
;; Environment:
|
;; Environment:
|
||||||
;; (env-has? env name) → boolean
|
;; (env-has? env name) → boolean
|
||||||
;; (env-get env name) → value
|
;; (env-get env name) → value
|
||||||
;; (env-set! env name val) → void (mutating)
|
;; (env-bind! env name val) → void (create binding on THIS env, no chain walk)
|
||||||
|
;; (env-set! env name val) → void (mutate existing binding, walks scope chain)
|
||||||
;; (env-extend env) → new env inheriting from env
|
;; (env-extend env) → new env inheriting from env
|
||||||
;; (env-merge base overlay) → new env with overlay on top
|
;; (env-merge base overlay) → new env with overlay on top
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -184,7 +184,7 @@
|
|||||||
(let ((name (if (= (type-of (first pair)) "symbol")
|
(let ((name (if (= (type-of (first pair)) "symbol")
|
||||||
(symbol-name (first pair))
|
(symbol-name (first pair))
|
||||||
(str (first pair)))))
|
(str (first pair)))))
|
||||||
(env-set! local name (trampoline (eval-expr (nth pair 1) local))))))
|
(env-bind! local name (trampoline (eval-expr (nth pair 1) local))))))
|
||||||
bindings)
|
bindings)
|
||||||
local)))
|
local)))
|
||||||
|
|
||||||
|
|||||||
@@ -229,7 +229,7 @@
|
|||||||
;; Build env: closure + caller env + params
|
;; Build env: closure + caller env + params
|
||||||
(let ((local (env-merge (component-closure comp) env)))
|
(let ((local (env-merge (component-closure comp) env)))
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p) (env-set! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
(fn (p) (env-bind! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
||||||
(component-params comp))
|
(component-params comp))
|
||||||
;; Pre-render children to raw HTML
|
;; Pre-render children to raw HTML
|
||||||
(when (component-has-children? comp)
|
(when (component-has-children? comp)
|
||||||
@@ -237,7 +237,7 @@
|
|||||||
(for-each
|
(for-each
|
||||||
(fn (c) (append! parts (async-render c env ctx)))
|
(fn (c) (append! parts (async-render c env ctx)))
|
||||||
children)
|
children)
|
||||||
(env-set! local "children"
|
(env-bind! local "children"
|
||||||
(make-raw-html (join "" parts)))))
|
(make-raw-html (join "" parts)))))
|
||||||
(async-render (component-body comp) local ctx)))))
|
(async-render (component-body comp) local ctx)))))
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@
|
|||||||
(let ((local (env-merge (component-closure island) env))
|
(let ((local (env-merge (component-closure island) env))
|
||||||
(island-name (component-name island)))
|
(island-name (component-name island)))
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p) (env-set! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
(fn (p) (env-bind! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
||||||
(component-params island))
|
(component-params island))
|
||||||
;; Pre-render children
|
;; Pre-render children
|
||||||
(when (component-has-children? island)
|
(when (component-has-children? island)
|
||||||
@@ -262,7 +262,7 @@
|
|||||||
(for-each
|
(for-each
|
||||||
(fn (c) (append! parts (async-render c env ctx)))
|
(fn (c) (append! parts (async-render c env ctx)))
|
||||||
children)
|
children)
|
||||||
(env-set! local "children"
|
(env-bind! local "children"
|
||||||
(make-raw-html (join "" parts)))))
|
(make-raw-html (join "" parts)))))
|
||||||
(let ((body-html (async-render (component-body island) local ctx))
|
(let ((body-html (async-render (component-body island) local ctx))
|
||||||
(state-json (serialize-island-state kwargs)))
|
(state-json (serialize-island-state kwargs)))
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
(fn ((f :as lambda) (args :as list) (env :as dict) ctx)
|
(fn ((f :as lambda) (args :as list) (env :as dict) ctx)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(for-each-indexed
|
(for-each-indexed
|
||||||
(fn (i p) (env-set! local p (nth args i)))
|
(fn (i p) (env-bind! local p (nth args i)))
|
||||||
(lambda-params f))
|
(lambda-params f))
|
||||||
(async-render (lambda-body f) local ctx))))
|
(async-render (lambda-body f) local ctx))))
|
||||||
|
|
||||||
@@ -517,7 +517,7 @@
|
|||||||
(let ((name (if (= (type-of (first pair)) "symbol")
|
(let ((name (if (= (type-of (first pair)) "symbol")
|
||||||
(symbol-name (first pair))
|
(symbol-name (first pair))
|
||||||
(str (first pair)))))
|
(str (first pair)))))
|
||||||
(env-set! local name (async-eval (nth pair 1) local ctx)))))
|
(env-bind! local name (async-eval (nth pair 1) local ctx)))))
|
||||||
bindings)
|
bindings)
|
||||||
;; Clojure-style: (name val name val ...)
|
;; Clojure-style: (name val name val ...)
|
||||||
(async-process-bindings-flat bindings local ctx)))
|
(async-process-bindings-flat bindings local ctx)))
|
||||||
@@ -538,7 +538,7 @@
|
|||||||
(symbol-name item)
|
(symbol-name item)
|
||||||
(str item))))
|
(str item))))
|
||||||
(when (< (inc i) (len bindings))
|
(when (< (inc i) (len bindings))
|
||||||
(env-set! local name
|
(env-bind! local name
|
||||||
(async-eval (nth bindings (inc i)) local ctx))))
|
(async-eval (nth bindings (inc i)) local ctx))))
|
||||||
(set! skip true)
|
(set! skip true)
|
||||||
(set! i (inc i)))))
|
(set! i (inc i)))))
|
||||||
@@ -735,7 +735,7 @@
|
|||||||
(lambda? f)
|
(lambda? f)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(for-each-indexed
|
(for-each-indexed
|
||||||
(fn (i p) (env-set! local p (nth evaled-args i)))
|
(fn (i p) (env-bind! local p (nth evaled-args i)))
|
||||||
(lambda-params f))
|
(lambda-params f))
|
||||||
(async-aser (lambda-body f) local ctx))
|
(async-aser (lambda-body f) local ctx))
|
||||||
(component? f)
|
(component? f)
|
||||||
@@ -807,7 +807,7 @@
|
|||||||
(async-parse-aser-kw-args args kwargs children env ctx)
|
(async-parse-aser-kw-args args kwargs children env ctx)
|
||||||
(let ((local (env-merge (component-closure comp) env)))
|
(let ((local (env-merge (component-closure comp) env)))
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p) (env-set! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
(fn (p) (env-bind! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
||||||
(component-params comp))
|
(component-params comp))
|
||||||
(when (component-has-children? comp)
|
(when (component-has-children? comp)
|
||||||
(let ((child-parts (list)))
|
(let ((child-parts (list)))
|
||||||
@@ -823,7 +823,7 @@
|
|||||||
(when (not (nil? result))
|
(when (not (nil? result))
|
||||||
(append! child-parts (serialize result))))))
|
(append! child-parts (serialize result))))))
|
||||||
children)
|
children)
|
||||||
(env-set! local "children"
|
(env-bind! local "children"
|
||||||
(make-sx-expr (str "(<> " (join " " child-parts) ")")))))
|
(make-sx-expr (str "(<> " (join " " child-parts) ")")))))
|
||||||
(async-aser (component-body comp) local ctx)))))
|
(async-aser (component-body comp) local ctx)))))
|
||||||
|
|
||||||
@@ -1033,7 +1033,7 @@
|
|||||||
;; set!
|
;; set!
|
||||||
(= name "set!")
|
(= name "set!")
|
||||||
(let ((value (async-eval (nth args 1) env ctx)))
|
(let ((value (async-eval (nth args 1) env ctx)))
|
||||||
(env-set! env (symbol-name (first args)) value)
|
(env-bind! env (symbol-name (first args)) value)
|
||||||
value)
|
value)
|
||||||
|
|
||||||
;; map
|
;; map
|
||||||
@@ -1197,7 +1197,7 @@
|
|||||||
(lambda? f)
|
(lambda? f)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(for-each-indexed
|
(for-each-indexed
|
||||||
(fn (i p) (env-set! local p (nth args i)))
|
(fn (i p) (env-bind! local p (nth args i)))
|
||||||
(lambda-params f))
|
(lambda-params f))
|
||||||
(async-eval (lambda-body f) local ctx))
|
(async-eval (lambda-body f) local ctx))
|
||||||
:else
|
:else
|
||||||
@@ -1217,7 +1217,7 @@
|
|||||||
(fn (item)
|
(fn (item)
|
||||||
(if (lambda? f)
|
(if (lambda? f)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(env-set! local (first (lambda-params f)) item)
|
(env-bind! local (first (lambda-params f)) item)
|
||||||
(append! results (async-aser (lambda-body f) local ctx)))
|
(append! results (async-aser (lambda-body f) local ctx)))
|
||||||
(append! results (async-invoke f item))))
|
(append! results (async-invoke f item))))
|
||||||
coll)
|
coll)
|
||||||
@@ -1234,8 +1234,8 @@
|
|||||||
(fn (item)
|
(fn (item)
|
||||||
(if (lambda? f)
|
(if (lambda? f)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(env-set! local (first (lambda-params f)) i)
|
(env-bind! local (first (lambda-params f)) i)
|
||||||
(env-set! local (nth (lambda-params f) 1) item)
|
(env-bind! local (nth (lambda-params f) 1) item)
|
||||||
(append! results (async-aser (lambda-body f) local ctx)))
|
(append! results (async-aser (lambda-body f) local ctx)))
|
||||||
(append! results (async-invoke f i item)))
|
(append! results (async-invoke f i item)))
|
||||||
(set! i (inc i)))
|
(set! i (inc i)))
|
||||||
@@ -1252,7 +1252,7 @@
|
|||||||
(fn (item)
|
(fn (item)
|
||||||
(if (lambda? f)
|
(if (lambda? f)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(env-set! local (first (lambda-params f)) item)
|
(env-bind! local (first (lambda-params f)) item)
|
||||||
(append! results (async-aser (lambda-body f) local ctx)))
|
(append! results (async-aser (lambda-body f) local ctx)))
|
||||||
(append! results (async-invoke f item))))
|
(append! results (async-invoke f item))))
|
||||||
coll)
|
coll)
|
||||||
|
|||||||
@@ -307,7 +307,7 @@
|
|||||||
;; Bind params from kwargs
|
;; Bind params from kwargs
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p)
|
(fn (p)
|
||||||
(env-set! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
(env-bind! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
||||||
(component-params comp))
|
(component-params comp))
|
||||||
|
|
||||||
;; If component accepts children, pre-render them to a fragment
|
;; If component accepts children, pre-render them to a fragment
|
||||||
@@ -320,7 +320,7 @@
|
|||||||
(when (not (spread? result))
|
(when (not (spread? result))
|
||||||
(dom-append child-frag result))))
|
(dom-append child-frag result))))
|
||||||
children)
|
children)
|
||||||
(env-set! local "children" child-frag)))
|
(env-bind! local "children" child-frag)))
|
||||||
|
|
||||||
(render-to-dom (component-body comp) local ns)))))
|
(render-to-dom (component-body comp) local ns)))))
|
||||||
|
|
||||||
@@ -687,7 +687,7 @@
|
|||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(for-each-indexed
|
(for-each-indexed
|
||||||
(fn (i p)
|
(fn (i p)
|
||||||
(env-set! local p (nth args i)))
|
(env-bind! local p (nth args i)))
|
||||||
(lambda-params f))
|
(lambda-params f))
|
||||||
(render-to-dom (lambda-body f) local ns))))
|
(render-to-dom (lambda-body f) local ns))))
|
||||||
|
|
||||||
@@ -734,7 +734,7 @@
|
|||||||
;; Bind params from kwargs
|
;; Bind params from kwargs
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p)
|
(fn (p)
|
||||||
(env-set! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
(env-bind! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
||||||
(component-params island))
|
(component-params island))
|
||||||
|
|
||||||
;; If island accepts children, pre-render them to a fragment
|
;; If island accepts children, pre-render them to a fragment
|
||||||
@@ -743,7 +743,7 @@
|
|||||||
(for-each
|
(for-each
|
||||||
(fn (c) (dom-append child-frag (render-to-dom c env ns)))
|
(fn (c) (dom-append child-frag (render-to-dom c env ns)))
|
||||||
children)
|
children)
|
||||||
(env-set! local "children" child-frag)))
|
(env-bind! local "children" child-frag)))
|
||||||
|
|
||||||
;; Create the island container element
|
;; Create the island container element
|
||||||
(let ((container (dom-create-element "span" nil))
|
(let ((container (dom-create-element "span" nil))
|
||||||
|
|||||||
@@ -277,7 +277,7 @@
|
|||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(for-each-indexed
|
(for-each-indexed
|
||||||
(fn (i p)
|
(fn (i p)
|
||||||
(env-set! local p (nth args i)))
|
(env-bind! local p (nth args i)))
|
||||||
(lambda-params f))
|
(lambda-params f))
|
||||||
(render-to-html (lambda-body f) local))))
|
(render-to-html (lambda-body f) local))))
|
||||||
|
|
||||||
@@ -315,11 +315,11 @@
|
|||||||
;; Bind params from kwargs
|
;; Bind params from kwargs
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p)
|
(fn (p)
|
||||||
(env-set! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
(env-bind! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
||||||
(component-params comp))
|
(component-params comp))
|
||||||
;; If component accepts children, pre-render them to raw HTML
|
;; If component accepts children, pre-render them to raw HTML
|
||||||
(when (component-has-children? comp)
|
(when (component-has-children? comp)
|
||||||
(env-set! local "children"
|
(env-bind! local "children"
|
||||||
(make-raw-html (join "" (map (fn (c) (render-to-html c env)) children)))))
|
(make-raw-html (join "" (map (fn (c) (render-to-html c env)) children)))))
|
||||||
(render-to-html (component-body comp) local)))))
|
(render-to-html (component-body comp) local)))))
|
||||||
|
|
||||||
@@ -481,12 +481,12 @@
|
|||||||
;; Bind params from kwargs
|
;; Bind params from kwargs
|
||||||
(for-each
|
(for-each
|
||||||
(fn (p)
|
(fn (p)
|
||||||
(env-set! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
(env-bind! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
||||||
(component-params island))
|
(component-params island))
|
||||||
|
|
||||||
;; If island accepts children, pre-render them to raw HTML
|
;; If island accepts children, pre-render them to raw HTML
|
||||||
(when (component-has-children? island)
|
(when (component-has-children? island)
|
||||||
(env-set! local "children"
|
(env-bind! local "children"
|
||||||
(make-raw-html (join "" (map (fn (c) (render-to-html c env)) children)))))
|
(make-raw-html (join "" (map (fn (c) (render-to-html c env)) children)))))
|
||||||
|
|
||||||
;; Render the island body as HTML
|
;; Render the island body as HTML
|
||||||
|
|||||||
@@ -289,7 +289,7 @@
|
|||||||
(map (fn (item)
|
(map (fn (item)
|
||||||
(if (lambda? f)
|
(if (lambda? f)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(env-set! local (first (lambda-params f)) item)
|
(env-bind! local (first (lambda-params f)) item)
|
||||||
(aser (lambda-body f) local))
|
(aser (lambda-body f) local))
|
||||||
(cek-call f (list item))))
|
(cek-call f (list item))))
|
||||||
coll))
|
coll))
|
||||||
@@ -301,8 +301,8 @@
|
|||||||
(map-indexed (fn (i item)
|
(map-indexed (fn (i item)
|
||||||
(if (lambda? f)
|
(if (lambda? f)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(env-set! local (first (lambda-params f)) i)
|
(env-bind! local (first (lambda-params f)) i)
|
||||||
(env-set! local (nth (lambda-params f) 1) item)
|
(env-bind! local (nth (lambda-params f) 1) item)
|
||||||
(aser (lambda-body f) local))
|
(aser (lambda-body f) local))
|
||||||
(cek-call f (list i item))))
|
(cek-call f (list i item))))
|
||||||
coll))
|
coll))
|
||||||
@@ -315,7 +315,7 @@
|
|||||||
(for-each (fn (item)
|
(for-each (fn (item)
|
||||||
(if (lambda? f)
|
(if (lambda? f)
|
||||||
(let ((local (env-merge (lambda-closure f) env)))
|
(let ((local (env-merge (lambda-closure f) env)))
|
||||||
(env-set! local (first (lambda-params f)) item)
|
(env-bind! local (first (lambda-params f)) item)
|
||||||
(append! results (aser (lambda-body f) local)))
|
(append! results (aser (lambda-body f) local)))
|
||||||
(cek-call f (list item))))
|
(cek-call f (list item))))
|
||||||
coll)
|
coll)
|
||||||
|
|||||||
@@ -361,7 +361,7 @@
|
|||||||
;; Bind params from kwargs
|
;; Bind params from kwargs
|
||||||
(for-each
|
(for-each
|
||||||
(fn ((p :as string))
|
(fn ((p :as string))
|
||||||
(env-set! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
(env-bind! local p (if (dict-has? kwargs p) (dict-get kwargs p) nil)))
|
||||||
(component-params comp))
|
(component-params comp))
|
||||||
|
|
||||||
;; Render the island body in a reactive scope
|
;; Render the island body in a reactive scope
|
||||||
|
|||||||
10
web/forms.sx
10
web/forms.sx
@@ -98,7 +98,7 @@
|
|||||||
(params (get parsed "params"))
|
(params (get parsed "params"))
|
||||||
(body (get parsed "body")))
|
(body (get parsed "body")))
|
||||||
(let ((hdef (make-handler-def name params body env opts)))
|
(let ((hdef (make-handler-def name params body env opts)))
|
||||||
(env-set! env (str "handler:" name) hdef)
|
(env-bind! env (str "handler:" name) hdef)
|
||||||
hdef))))
|
hdef))))
|
||||||
|
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
(doc (if has-doc (nth args 2) ""))
|
(doc (if has-doc (nth args 2) ""))
|
||||||
(body (if has-doc (nth args 3) (nth args 2))))
|
(body (if has-doc (nth args 3) (nth args 2))))
|
||||||
(let ((qdef (make-query-def name params doc body env)))
|
(let ((qdef (make-query-def name params doc body env)))
|
||||||
(env-set! env (str "query:" name) qdef)
|
(env-bind! env (str "query:" name) qdef)
|
||||||
qdef))))
|
qdef))))
|
||||||
|
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
(doc (if has-doc (nth args 2) ""))
|
(doc (if has-doc (nth args 2) ""))
|
||||||
(body (if has-doc (nth args 3) (nth args 2))))
|
(body (if has-doc (nth args 3) (nth args 2))))
|
||||||
(let ((adef (make-action-def name params doc body env)))
|
(let ((adef (make-action-def name params doc body env)))
|
||||||
(env-set! env (str "action:" name) adef)
|
(env-bind! env (str "action:" name) adef)
|
||||||
adef))))
|
adef))))
|
||||||
|
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@
|
|||||||
(nth args (+ idx 1))))))
|
(nth args (+ idx 1))))))
|
||||||
(range 1 max-i 2)))
|
(range 1 max-i 2)))
|
||||||
(let ((pdef (make-page-def name slots env)))
|
(let ((pdef (make-page-def name slots env)))
|
||||||
(env-set! env (str "page:" name) pdef)
|
(env-bind! env (str "page:" name) pdef)
|
||||||
pdef))))
|
pdef))))
|
||||||
|
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@
|
|||||||
(bindings (stream-chunk-bindings chunk)))
|
(bindings (stream-chunk-bindings chunk)))
|
||||||
(for-each
|
(for-each
|
||||||
(fn ((key :as string))
|
(fn ((key :as string))
|
||||||
(env-set! env (normalize-binding-key key)
|
(env-bind! env (normalize-binding-key key)
|
||||||
(get bindings key)))
|
(get bindings key)))
|
||||||
(keys bindings))
|
(keys bindings))
|
||||||
env)))
|
env)))
|
||||||
|
|||||||
@@ -1103,9 +1103,9 @@
|
|||||||
(dom-listen el event-name
|
(dom-listen el event-name
|
||||||
(fn (e)
|
(fn (e)
|
||||||
(let ((handler-env (env-extend (dict))))
|
(let ((handler-env (env-extend (dict))))
|
||||||
(env-set! handler-env "event" e)
|
(env-bind! handler-env "event" e)
|
||||||
(env-set! handler-env "this" el)
|
(env-bind! handler-env "this" el)
|
||||||
(env-set! handler-env "detail" (event-detail e))
|
(env-bind! handler-env "detail" (event-detail e))
|
||||||
(for-each
|
(for-each
|
||||||
(fn (expr) (eval-expr expr handler-env))
|
(fn (expr) (eval-expr expr handler-env))
|
||||||
exprs))))))))))
|
exprs))))))))))
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
(defsuite "deref signal without reactive-reset"
|
(defsuite "deref signal without reactive-reset"
|
||||||
(deftest "deref signal returns current value"
|
(deftest "deref signal returns current value"
|
||||||
(let ((s (signal 99)))
|
(let ((s (signal 99)))
|
||||||
(env-set! (test-env) "test-sig" s)
|
(env-bind! (test-env) "test-sig" s)
|
||||||
(let ((result (eval-expr-cek
|
(let ((result (eval-expr-cek
|
||||||
(sx-parse-one "(deref test-sig)")
|
(sx-parse-one "(deref test-sig)")
|
||||||
(test-env))))
|
(test-env))))
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
(deftest "deref signal in expression returns computed value"
|
(deftest "deref signal in expression returns computed value"
|
||||||
(let ((s (signal 10)))
|
(let ((s (signal 10)))
|
||||||
(env-set! (test-env) "test-sig" s)
|
(env-bind! (test-env) "test-sig" s)
|
||||||
(let ((result (eval-expr-cek
|
(let ((result (eval-expr-cek
|
||||||
(sx-parse-one "(+ 5 (deref test-sig))")
|
(sx-parse-one "(+ 5 (deref test-sig))")
|
||||||
(test-env))))
|
(test-env))))
|
||||||
@@ -67,7 +67,7 @@
|
|||||||
(make-cek-state
|
(make-cek-state
|
||||||
(sx-parse-one "(deref test-sig)")
|
(sx-parse-one "(deref test-sig)")
|
||||||
(let ((e (env-extend (test-env))))
|
(let ((e (env-extend (test-env))))
|
||||||
(env-set! e "test-sig" s)
|
(env-bind! e "test-sig" s)
|
||||||
e)
|
e)
|
||||||
(list (make-reactive-reset-frame
|
(list (make-reactive-reset-frame
|
||||||
(test-env)
|
(test-env)
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
;; Set up reactive-reset with tracking update-fn
|
;; Set up reactive-reset with tracking update-fn
|
||||||
(scope-push! "sx-island-scope" nil)
|
(scope-push! "sx-island-scope" nil)
|
||||||
(let ((e (env-extend (test-env))))
|
(let ((e (env-extend (test-env))))
|
||||||
(env-set! e "test-sig" s)
|
(env-bind! e "test-sig" s)
|
||||||
(cek-run
|
(cek-run
|
||||||
(make-cek-state
|
(make-cek-state
|
||||||
(sx-parse-one "(deref test-sig)")
|
(sx-parse-one "(deref test-sig)")
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
(update-calls (list)))
|
(update-calls (list)))
|
||||||
(scope-push! "sx-island-scope" nil)
|
(scope-push! "sx-island-scope" nil)
|
||||||
(let ((e (env-extend (test-env))))
|
(let ((e (env-extend (test-env))))
|
||||||
(env-set! e "test-sig" s)
|
(env-bind! e "test-sig" s)
|
||||||
;; (str "val=" (deref test-sig)) — continuation captures (str "val=" [HOLE])
|
;; (str "val=" (deref test-sig)) — continuation captures (str "val=" [HOLE])
|
||||||
(let ((result (cek-run
|
(let ((result (cek-run
|
||||||
(make-cek-state
|
(make-cek-state
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
;; Create island scope with collector that accumulates disposers
|
;; Create island scope with collector that accumulates disposers
|
||||||
(scope-push! "sx-island-scope" (fn (d) (append! disposers d)))
|
(scope-push! "sx-island-scope" (fn (d) (append! disposers d)))
|
||||||
(let ((e (env-extend (test-env))))
|
(let ((e (env-extend (test-env))))
|
||||||
(env-set! e "test-sig" s)
|
(env-bind! e "test-sig" s)
|
||||||
(cek-run
|
(cek-run
|
||||||
(make-cek-state
|
(make-cek-state
|
||||||
(sx-parse-one "(deref test-sig)")
|
(sx-parse-one "(deref test-sig)")
|
||||||
@@ -266,7 +266,7 @@
|
|||||||
|
|
||||||
(deftest "for-each through CEK"
|
(deftest "for-each through CEK"
|
||||||
(let ((log (list)))
|
(let ((log (list)))
|
||||||
(env-set! (test-env) "test-log" log)
|
(env-bind! (test-env) "test-log" log)
|
||||||
(eval-expr-cek
|
(eval-expr-cek
|
||||||
(sx-parse-one "(for-each (fn (x) (append! test-log x)) (list 1 2 3))")
|
(sx-parse-one "(for-each (fn (x) (append! test-log x)) (list 1 2 3))")
|
||||||
(test-env))
|
(test-env))
|
||||||
|
|||||||
Reference in New Issue
Block a user