Move defstyle/deftype/defeffect to web-forms.sx — domain forms, not core

These are domain definition forms (same pattern as defhandler, defpage,
etc.), not core language constructs. Moving them to web-forms.sx keeps
the core evaluator + types.sx cleaner for WASM compilation.

web-forms.sx now loaded in both JS and Python build pipelines.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-24 12:22:08 +00:00
parent 9caf8b6e94
commit 26e16f6aa4
6 changed files with 253 additions and 93 deletions

View File

@@ -14,7 +14,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-24T12:07:57Z";
var SX_VERSION = "2026-03-24T12:19:33Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
@@ -2338,6 +2338,171 @@ PRIMITIVES["escape-html"] = escapeHtml;
PRIMITIVES["escape-attr"] = escapeAttr;
// === Transpiled from web-forms (defstyle, deftype, defeffect, defrelation) ===
// parse-key-params
var parseKeyParams = function(paramsExpr) { return (function() {
var params = [];
{ var _c = paramsExpr; for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; if (isSxTruthy((typeOf(p) == "symbol"))) {
(function() {
var name = symbolName(p);
return (isSxTruthy(!isSxTruthy((name == "&key"))) ? append_b(params, name) : NIL);
})();
} } }
return params;
})(); };
PRIMITIVES["parse-key-params"] = parseKeyParams;
// parse-handler-args
var parseHandlerArgs = function(args) { return (function() {
var opts = {};
var params = [];
var body = NIL;
var i = 0;
var n = len(args);
var done = false;
{ var _c = range(0, n); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; if (isSxTruthy((isSxTruthy(!isSxTruthy(done)) && (idx == i)))) {
(function() {
var arg = nth(args, idx);
return (isSxTruthy((typeOf(arg) == "keyword")) ? ((isSxTruthy(((idx + 1) < n)) ? (function() {
var val = nth(args, (idx + 1));
return dictSet(opts, keywordName(arg), (isSxTruthy((typeOf(val) == "keyword")) ? keywordName(val) : val));
})() : NIL), (i = (idx + 2))) : (isSxTruthy((typeOf(arg) == "list")) ? ((params = parseKeyParams(arg)), (isSxTruthy(((idx + 1) < n)) ? (body = nth(args, (idx + 1))) : NIL), (done = true)) : ((body = arg), (done = true))));
})();
} } }
return {["opts"]: opts, ["params"]: params, ["body"]: body};
})(); };
PRIMITIVES["parse-handler-args"] = parseHandlerArgs;
// (register-special-form! ...)
registerSpecialForm("defhandler", function(args, env) { return (function() {
var nameSym = first(args);
var name = symbolName(first(args));
var parsed = parseHandlerArgs(rest(args));
var opts = get(parsed, "opts");
var params = get(parsed, "params");
var body = get(parsed, "body");
return (function() {
var hdef = {["__type"]: "handler", ["name"]: name, ["params"]: params, ["body"]: body, ["closure"]: env, ["path"]: sxOr(get(opts, "path"), NIL), ["method"]: sxOr(get(opts, "method"), "get"), ["csrf"]: (function() {
var v = get(opts, "csrf");
return (isSxTruthy(isNil(v)) ? true : v);
})(), ["returns"]: sxOr(get(opts, "returns"), "element")};
envBind(env, (String("handler:") + String(name)), hdef);
return hdef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defquery", function(args, env) { return (function() {
var name = symbolName(first(args));
var paramsRaw = nth(args, 1);
var params = parseKeyParams(paramsRaw);
var hasDoc = (isSxTruthy((len(args) >= 4)) && (typeOf(nth(args, 2)) == "string"));
var doc = (isSxTruthy(hasDoc) ? nth(args, 2) : "");
var body = (isSxTruthy(hasDoc) ? nth(args, 3) : nth(args, 2));
return (function() {
var qdef = {["__type"]: "query", ["name"]: name, ["params"]: params, ["doc"]: doc, ["body"]: body, ["closure"]: env};
envBind(env, (String("query:") + String(name)), qdef);
return qdef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defaction", function(args, env) { return (function() {
var name = symbolName(first(args));
var paramsRaw = nth(args, 1);
var params = parseKeyParams(paramsRaw);
var hasDoc = (isSxTruthy((len(args) >= 4)) && (typeOf(nth(args, 2)) == "string"));
var doc = (isSxTruthy(hasDoc) ? nth(args, 2) : "");
var body = (isSxTruthy(hasDoc) ? nth(args, 3) : nth(args, 2));
return (function() {
var adef = {["__type"]: "action", ["name"]: name, ["params"]: params, ["doc"]: doc, ["body"]: body, ["closure"]: env};
envBind(env, (String("action:") + String(name)), adef);
return adef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defpage", function(args, env) { return (function() {
var name = symbolName(first(args));
var slots = {};
var n = len(args);
{ var _c = range(0, ((n - 1) / 2)); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; (function() {
var kIdx = (1 + (idx * 2));
var vIdx = (2 + (idx * 2));
return (isSxTruthy((isSxTruthy((kIdx < n)) && isSxTruthy((vIdx < n)) && (typeOf(nth(args, kIdx)) == "keyword"))) ? dictSet(slots, keywordName(nth(args, kIdx)), nth(args, vIdx)) : NIL);
})(); } }
return (function() {
var pdef = {["__type"]: "page", ["name"]: name, ["path"]: sxOr(get(slots, "path"), ""), ["auth"]: sxOr(get(slots, "auth"), "public"), ["layout"]: get(slots, "layout"), ["data"]: get(slots, "data"), ["content"]: get(slots, "content"), ["filter"]: get(slots, "filter"), ["aside"]: get(slots, "aside"), ["menu"]: get(slots, "menu"), ["stream"]: get(slots, "stream"), ["fallback"]: get(slots, "fallback"), ["shell"]: get(slots, "shell"), ["closure"]: env};
envBind(env, (String("page:") + String(name)), pdef);
return pdef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defrelation", function(args, env) { return (function() {
var name = symbolName(first(args));
var slots = {};
var n = len(args);
{ var _c = range(0, ((n - 1) / 2)); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; (function() {
var kIdx = (1 + (idx * 2));
var vIdx = (2 + (idx * 2));
return (isSxTruthy((isSxTruthy((kIdx < n)) && isSxTruthy((vIdx < n)) && (typeOf(nth(args, kIdx)) == "keyword"))) ? dictSet(slots, keywordName(nth(args, kIdx)), nth(args, vIdx)) : NIL);
})(); } }
return (function() {
var rdef = {["__type"]: "relation", ["name"]: name, ["slots"]: slots, ["closure"]: env};
envBind(env, (String("relation:") + String(name)), rdef);
return rdef;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defstyle", function(args, env) { return (function() {
var nameSym = first(args);
var value = trampoline(evalExpr(nth(args, 1), env));
envBind(env, symbolName(nameSym), value);
return value;
})(); });
// normalize-type-body
var normalizeTypeBody = function(body) { return (isSxTruthy(isNil(body)) ? "nil" : (isSxTruthy((typeOf(body) == "symbol")) ? symbolName(body) : (isSxTruthy((typeOf(body) == "string")) ? body : (isSxTruthy((typeOf(body) == "keyword")) ? keywordName(body) : (isSxTruthy((typeOf(body) == "dict")) ? mapDict(function(k, v) { return normalizeTypeBody(v); }, body) : (isSxTruthy((typeOf(body) == "list")) ? (isSxTruthy(isEmpty(body)) ? "any" : (function() {
var headName = (isSxTruthy((typeOf(first(body)) == "symbol")) ? symbolName(first(body)) : (String(first(body))));
return (isSxTruthy((headName == "union")) ? cons("or", map(normalizeTypeBody, rest(body))) : cons(headName, map(normalizeTypeBody, rest(body))));
})()) : (String(body)))))))); };
PRIMITIVES["normalize-type-body"] = normalizeTypeBody;
// (register-special-form! ...)
registerSpecialForm("deftype", function(args, env) { return (function() {
var nameOrForm = first(args);
var bodyExpr = nth(args, 1);
var typeName = NIL;
var typeParams = [];
(isSxTruthy((typeOf(nameOrForm) == "symbol")) ? (typeName = symbolName(nameOrForm)) : (isSxTruthy((typeOf(nameOrForm) == "list")) ? ((typeName = symbolName(first(nameOrForm))), (typeParams = map(function(p) { return (isSxTruthy((typeOf(p) == "symbol")) ? symbolName(p) : (String(p))); }, rest(nameOrForm)))) : NIL));
return (function() {
var body = normalizeTypeBody(bodyExpr);
var registry = (isSxTruthy(envHas(env, "*type-registry*")) ? envGet(env, "*type-registry*") : {});
registry[typeName] = {"name": typeName, "params": typeParams, "body": body};
envBind(env, "*type-registry*", registry);
return NIL;
})();
})(); });
// (register-special-form! ...)
registerSpecialForm("defeffect", function(args, env) { return (function() {
var effectName = (isSxTruthy((typeOf(first(args)) == "symbol")) ? symbolName(first(args)) : (String(first(args))));
var registry = (isSxTruthy(envHas(env, "*effect-registry*")) ? envGet(env, "*effect-registry*") : []);
if (isSxTruthy(!isSxTruthy(contains(registry, effectName)))) {
registry.push(effectName);
}
envBind(env, "*effect-registry*", registry);
return NIL;
})(); });
// WEB_FORM_NAMES
var WEB_FORM_NAMES = ["defhandler", "defpage", "defquery", "defaction", "defrelation", "defstyle", "deftype", "defeffect"];
PRIMITIVES["WEB_FORM_NAMES"] = WEB_FORM_NAMES;
// === Transpiled from parser ===
// sx-parse