WIP: pre-existing changes from WASM browser work + test infrastructure
Accumulated changes from WASM browser development sessions: - sx_runtime.ml: signal subscription + notify, env unwrap tolerance - sx_browser.bc.js: rebuilt js_of_ocaml browser kernel - sx_browser.bc.wasm.js + assets: WASM browser kernel build - sx-platform.js browser tests (test_js, test_platform, test_wasm) - Playwright sx-inspect.js: interactive page inspector tool - harness-web.sx: DOM assertion updates - deploy.sh, Dockerfile, dune-project: build config updates - test-stepper.sx: stepper unit tests - reader-macro-demo plan update Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
// =========================================================================
|
||||
|
||||
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
|
||||
var SX_VERSION = "2026-03-26T11:30:03Z";
|
||||
var SX_VERSION = "2026-03-26T16:13:53Z";
|
||||
|
||||
function isNil(x) { return x === NIL || x === null || x === undefined; }
|
||||
function isSxTruthy(x) { return x !== false && !isNil(x); }
|
||||
@@ -6583,6 +6583,400 @@ PRIMITIVES["bridge-event"] = bridgeEvent;
|
||||
PRIMITIVES["resource"] = resource;
|
||||
|
||||
|
||||
// === Transpiled from types (gradual type system) ===
|
||||
|
||||
// base-types
|
||||
var baseTypes = ["number", "string", "boolean", "nil", "symbol", "keyword", "element", "any", "never", "list", "dict", "lambda", "component", "island", "macro", "signal"];
|
||||
PRIMITIVES["base-types"] = baseTypes;
|
||||
|
||||
// type-any?
|
||||
var typeAny_p = function(t) { return (t == "any"); };
|
||||
PRIMITIVES["type-any?"] = typeAny_p;
|
||||
|
||||
// type-never?
|
||||
var typeNever_p = function(t) { return (t == "never"); };
|
||||
PRIMITIVES["type-never?"] = typeNever_p;
|
||||
|
||||
// type-nullable?
|
||||
var typeNullable_p = function(t) { return (isSxTruthy((t == "any")) ? true : (isSxTruthy((t == "nil")) ? true : (isSxTruthy((isSxTruthy((typeOf(t) == "string")) && endsWith(t, "?"))) ? true : (isSxTruthy((isSxTruthy((typeOf(t) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(t))) && (first(t) == "or"))) ? contains(rest(t), "nil") : false)))); };
|
||||
PRIMITIVES["type-nullable?"] = typeNullable_p;
|
||||
|
||||
// nullable-base
|
||||
var nullableBase = function(t) { return (isSxTruthy((isSxTruthy((typeOf(t) == "string")) && isSxTruthy(endsWith(t, "?")) && !isSxTruthy((t == "?")))) ? slice(t, 0, (stringLength(t) - 1)) : t); };
|
||||
PRIMITIVES["nullable-base"] = nullableBase;
|
||||
|
||||
// subtype?
|
||||
var subtype_p = function(a, b) { return (isSxTruthy(typeAny_p(b)) ? true : (isSxTruthy(typeNever_p(a)) ? true : (isSxTruthy(typeAny_p(a)) ? false : (isSxTruthy((a == b)) ? true : (isSxTruthy((a == "nil")) ? typeNullable_p(b) : (isSxTruthy((isSxTruthy((typeOf(b) == "string")) && endsWith(b, "?"))) ? (function() {
|
||||
var base = nullableBase(b);
|
||||
return sxOr((a == base), (a == "nil"));
|
||||
})() : (isSxTruthy((isSxTruthy((typeOf(a) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(a))) && (first(a) == "or"))) ? isEvery(function(member) { return subtype_p(member, b); }, rest(a)) : (isSxTruthy((isSxTruthy((typeOf(b) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(b))) && (first(b) == "or"))) ? some(function(member) { return subtype_p(a, member); }, rest(b)) : (isSxTruthy((isSxTruthy((typeOf(a) == "list")) && isSxTruthy((typeOf(b) == "list")) && isSxTruthy((len(a) == 2)) && isSxTruthy((len(b) == 2)) && isSxTruthy((first(a) == "list-of")) && (first(b) == "list-of"))) ? subtype_p(nth(a, 1), nth(b, 1)) : (isSxTruthy((isSxTruthy((a == "list")) && isSxTruthy((typeOf(b) == "list")) && isSxTruthy((len(b) == 2)) && (first(b) == "list-of"))) ? typeAny_p(nth(b, 1)) : (isSxTruthy((isSxTruthy((typeOf(a) == "list")) && isSxTruthy((len(a) == 2)) && isSxTruthy((first(a) == "list-of")) && (b == "list"))) ? true : false))))))))))); };
|
||||
PRIMITIVES["subtype?"] = subtype_p;
|
||||
|
||||
// type-union
|
||||
var typeUnion = function(a, b) { return (isSxTruthy((a == b)) ? a : (isSxTruthy(typeAny_p(a)) ? "any" : (isSxTruthy(typeAny_p(b)) ? "any" : (isSxTruthy(typeNever_p(a)) ? b : (isSxTruthy(typeNever_p(b)) ? a : (isSxTruthy(subtype_p(a, b)) ? b : (isSxTruthy(subtype_p(b, a)) ? a : (isSxTruthy((a == "nil")) ? (isSxTruthy((isSxTruthy((typeOf(b) == "string")) && !isSxTruthy(endsWith(b, "?")))) ? (String(b) + String("?")) : ["or", a, b]) : (isSxTruthy((b == "nil")) ? (isSxTruthy((isSxTruthy((typeOf(a) == "string")) && !isSxTruthy(endsWith(a, "?")))) ? (String(a) + String("?")) : ["or", a, b]) : ["or", a, b]))))))))); };
|
||||
PRIMITIVES["type-union"] = typeUnion;
|
||||
|
||||
// narrow-type
|
||||
var narrowType = function(t, predicateName) { return (isSxTruthy((predicateName == "nil?")) ? ["nil", narrowExcludeNil(t)] : (isSxTruthy((predicateName == "string?")) ? ["string", narrowExclude(t, "string")] : (isSxTruthy((predicateName == "number?")) ? ["number", narrowExclude(t, "number")] : (isSxTruthy((predicateName == "list?")) ? ["list", narrowExclude(t, "list")] : (isSxTruthy((predicateName == "dict?")) ? ["dict", narrowExclude(t, "dict")] : (isSxTruthy((predicateName == "boolean?")) ? ["boolean", narrowExclude(t, "boolean")] : [t, t])))))); };
|
||||
PRIMITIVES["narrow-type"] = narrowType;
|
||||
|
||||
// narrow-exclude-nil
|
||||
var narrowExcludeNil = function(t) { return (isSxTruthy((t == "nil")) ? "never" : (isSxTruthy((t == "any")) ? "any" : (isSxTruthy((isSxTruthy((typeOf(t) == "string")) && endsWith(t, "?"))) ? nullableBase(t) : (isSxTruthy((isSxTruthy((typeOf(t) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(t))) && (first(t) == "or"))) ? (function() {
|
||||
var members = filter(function(m) { return !isSxTruthy((m == "nil")); }, rest(t));
|
||||
return (isSxTruthy((len(members) == 1)) ? first(members) : (isSxTruthy(isEmpty(members)) ? "never" : cons("or", members)));
|
||||
})() : t)))); };
|
||||
PRIMITIVES["narrow-exclude-nil"] = narrowExcludeNil;
|
||||
|
||||
// narrow-exclude
|
||||
var narrowExclude = function(t, excluded) { return (isSxTruthy((t == excluded)) ? "never" : (isSxTruthy((t == "any")) ? "any" : (isSxTruthy((isSxTruthy((typeOf(t) == "list")) && isSxTruthy(!isSxTruthy(isEmpty(t))) && (first(t) == "or"))) ? (function() {
|
||||
var members = filter(function(m) { return !isSxTruthy((m == excluded)); }, rest(t));
|
||||
return (isSxTruthy((len(members) == 1)) ? first(members) : (isSxTruthy(isEmpty(members)) ? "never" : cons("or", members)));
|
||||
})() : t))); };
|
||||
PRIMITIVES["narrow-exclude"] = narrowExclude;
|
||||
|
||||
// infer-type
|
||||
var inferType = function(node, typeEnv, primTypes, typeRegistry) { return (function() {
|
||||
var kind = typeOf(node);
|
||||
return (isSxTruthy((kind == "number")) ? "number" : (isSxTruthy((kind == "string")) ? "string" : (isSxTruthy((kind == "boolean")) ? "boolean" : (isSxTruthy(isNil(node)) ? "nil" : (isSxTruthy((kind == "keyword")) ? "keyword" : (isSxTruthy((kind == "symbol")) ? (function() {
|
||||
var name = symbolName(node);
|
||||
return (isSxTruthy(dictHas(typeEnv, name)) ? get(typeEnv, name) : (isSxTruthy((name == "true")) ? "boolean" : (isSxTruthy((name == "false")) ? "boolean" : (isSxTruthy((name == "nil")) ? "nil" : (isSxTruthy(dictHas(primTypes, name)) ? get(primTypes, name) : "any")))));
|
||||
})() : (isSxTruthy((kind == "dict")) ? "dict" : (isSxTruthy((kind == "list")) ? inferListType(node, typeEnv, primTypes, typeRegistry) : "any"))))))));
|
||||
})(); };
|
||||
PRIMITIVES["infer-type"] = inferType;
|
||||
|
||||
// infer-list-type
|
||||
var inferListType = function(node, typeEnv, primTypes, typeRegistry) { return (isSxTruthy(isEmpty(node)) ? "list" : (function() {
|
||||
var head = first(node);
|
||||
var args = rest(node);
|
||||
return (isSxTruthy(!isSxTruthy((typeOf(head) == "symbol"))) ? "any" : (function() {
|
||||
var name = symbolName(head);
|
||||
return (isSxTruthy((name == "if")) ? inferIfType(args, typeEnv, primTypes, typeRegistry) : (isSxTruthy((name == "when")) ? (isSxTruthy((len(args) >= 2)) ? typeUnion(inferType(last(args), typeEnv, primTypes, typeRegistry), "nil") : "nil") : (isSxTruthy(sxOr((name == "cond"), (name == "case"))) ? "any" : (isSxTruthy((name == "let")) ? inferLetType(args, typeEnv, primTypes, typeRegistry) : (isSxTruthy(sxOr((name == "do"), (name == "begin"))) ? (isSxTruthy(isEmpty(args)) ? "nil" : inferType(last(args), typeEnv, primTypes, typeRegistry)) : (isSxTruthy(sxOr((name == "lambda"), (name == "fn"))) ? "lambda" : (isSxTruthy((name == "and")) ? (isSxTruthy(isEmpty(args)) ? "boolean" : inferType(last(args), typeEnv, primTypes, typeRegistry)) : (isSxTruthy((name == "or")) ? (isSxTruthy(isEmpty(args)) ? "boolean" : reduce(typeUnion, "never", map(function(a) { return inferType(a, typeEnv, primTypes, typeRegistry); }, args))) : (isSxTruthy((name == "map")) ? (isSxTruthy((len(args) >= 2)) ? (function() {
|
||||
var fnType = inferType(first(args), typeEnv, primTypes, typeRegistry);
|
||||
return (isSxTruthy((isSxTruthy((typeOf(fnType) == "list")) && (first(fnType) == "->"))) ? ["list-of", last(fnType)] : "list");
|
||||
})() : "list") : (isSxTruthy((name == "filter")) ? (isSxTruthy((len(args) >= 2)) ? inferType(nth(args, 1), typeEnv, primTypes, typeRegistry) : "list") : (isSxTruthy((name == "reduce")) ? "any" : (isSxTruthy((name == "list")) ? "list" : (isSxTruthy((name == "dict")) ? "dict" : (isSxTruthy((name == "quote")) ? "any" : (isSxTruthy((name == "str")) ? "string" : (isSxTruthy((name == "not")) ? "boolean" : (isSxTruthy((name == "get")) ? (isSxTruthy((isSxTruthy((len(args) >= 2)) && !isSxTruthy(isNil(typeRegistry)))) ? (function() {
|
||||
var dictType = inferType(first(args), typeEnv, primTypes, typeRegistry);
|
||||
var keyArg = nth(args, 1);
|
||||
var keyName = (isSxTruthy((typeOf(keyArg) == "keyword")) ? keywordName(keyArg) : (isSxTruthy((typeOf(keyArg) == "string")) ? keyArg : NIL));
|
||||
return (isSxTruthy((isSxTruthy(keyName) && isSxTruthy((typeOf(dictType) == "string")) && dictHas(typeRegistry, dictType))) ? (function() {
|
||||
var resolved = resolveType(dictType, typeRegistry);
|
||||
return (isSxTruthy((isSxTruthy((typeOf(resolved) == "dict")) && dictHas(resolved, keyName))) ? get(resolved, keyName) : "any");
|
||||
})() : "any");
|
||||
})() : "any") : (isSxTruthy(startsWith(name, "~")) ? "element" : (isSxTruthy(dictHas(primTypes, name)) ? get(primTypes, name) : "any")))))))))))))))))));
|
||||
})());
|
||||
})()); };
|
||||
PRIMITIVES["infer-list-type"] = inferListType;
|
||||
|
||||
// infer-if-type
|
||||
var inferIfType = function(args, typeEnv, primTypes, typeRegistry) { return (isSxTruthy((len(args) < 2)) ? "nil" : (function() {
|
||||
var thenType = inferType(nth(args, 1), typeEnv, primTypes, typeRegistry);
|
||||
return (isSxTruthy((len(args) >= 3)) ? typeUnion(thenType, inferType(nth(args, 2), typeEnv, primTypes, typeRegistry)) : typeUnion(thenType, "nil"));
|
||||
})()); };
|
||||
PRIMITIVES["infer-if-type"] = inferIfType;
|
||||
|
||||
// infer-let-type
|
||||
var inferLetType = function(args, typeEnv, primTypes, typeRegistry) { return (isSxTruthy((len(args) < 2)) ? "nil" : (function() {
|
||||
var bindings = first(args);
|
||||
var body = last(args);
|
||||
var extended = merge(typeEnv, {});
|
||||
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var binding = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(binding) == "list")) && (len(binding) >= 2)))) {
|
||||
(function() {
|
||||
var name = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : (String(first(binding))));
|
||||
var valType = inferType(nth(binding, 1), extended, primTypes, typeRegistry);
|
||||
return dictSet(extended, name, valType);
|
||||
})();
|
||||
} } }
|
||||
return inferType(body, extended, primTypes, typeRegistry);
|
||||
})()); };
|
||||
PRIMITIVES["infer-let-type"] = inferLetType;
|
||||
|
||||
// make-diagnostic
|
||||
var makeDiagnostic = function(level, message, component, expr) { return {"level": level, "component": component, "expr": expr, "message": message}; };
|
||||
PRIMITIVES["make-diagnostic"] = makeDiagnostic;
|
||||
|
||||
// check-primitive-call
|
||||
var checkPrimitiveCall = function(name, args, typeEnv, primTypes, primParamTypes, compName, typeRegistry) { return (function() {
|
||||
var diagnostics = [];
|
||||
if (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(primParamTypes))) && dictHas(primParamTypes, name)))) {
|
||||
(function() {
|
||||
var sig = get(primParamTypes, name);
|
||||
var positional = get(sig, "positional");
|
||||
var restType = get(sig, "rest-type");
|
||||
return forEach(function(idx) { return (isSxTruthy((idx < len(args))) ? (isSxTruthy((idx < len(positional))) ? (function() {
|
||||
var paramInfo = nth(positional, idx);
|
||||
var argExpr = nth(args, idx);
|
||||
return (function() {
|
||||
var expectedType = nth(paramInfo, 1);
|
||||
return (isSxTruthy(!isSxTruthy(isNil(expectedType))) ? (function() {
|
||||
var actual = inferType(argExpr, typeEnv, primTypes, typeRegistry);
|
||||
return (isSxTruthy((isSxTruthy(!isSxTruthy(typeAny_p(expectedType))) && isSxTruthy(!isSxTruthy(typeAny_p(actual))) && !isSxTruthy(subtypeResolved_p(actual, expectedType, typeRegistry)))) ? append_b(diagnostics, makeDiagnostic("error", (String("Argument ") + String((idx + 1)) + String(" of `") + String(name) + String("` expects ") + String(expectedType) + String(", got ") + String(actual)), compName, argExpr)) : NIL);
|
||||
})() : NIL);
|
||||
})();
|
||||
})() : (isSxTruthy(!isSxTruthy(isNil(restType))) ? (function() {
|
||||
var argExpr = nth(args, idx);
|
||||
var actual = inferType(argExpr, typeEnv, primTypes, typeRegistry);
|
||||
return (isSxTruthy((isSxTruthy(!isSxTruthy(typeAny_p(restType))) && isSxTruthy(!isSxTruthy(typeAny_p(actual))) && !isSxTruthy(subtypeResolved_p(actual, restType, typeRegistry)))) ? append_b(diagnostics, makeDiagnostic("error", (String("Argument ") + String((idx + 1)) + String(" of `") + String(name) + String("` expects ") + String(restType) + String(", got ") + String(actual)), compName, argExpr)) : NIL);
|
||||
})() : NIL)) : NIL); }, range(0, len(args), 1));
|
||||
})();
|
||||
}
|
||||
return diagnostics;
|
||||
})(); };
|
||||
PRIMITIVES["check-primitive-call"] = checkPrimitiveCall;
|
||||
|
||||
// check-component-call
|
||||
var checkComponentCall = function(compName, comp, callArgs, typeEnv, primTypes, typeRegistry) { return (function() {
|
||||
var diagnostics = [];
|
||||
var paramTypes = componentParamTypes(comp);
|
||||
var params = componentParams(comp);
|
||||
if (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(paramTypes))) && !isSxTruthy(isEmpty(keys(paramTypes)))))) {
|
||||
(function() {
|
||||
var i = 0;
|
||||
var providedKeys = [];
|
||||
{ var _c = range(0, len(callArgs), 1); for (var _i = 0; _i < _c.length; _i++) { var idx = _c[_i]; if (isSxTruthy((idx < len(callArgs)))) {
|
||||
(function() {
|
||||
var arg = nth(callArgs, idx);
|
||||
return (isSxTruthy((typeOf(arg) == "keyword")) ? (function() {
|
||||
var keyName = keywordName(arg);
|
||||
providedKeys.push(keyName);
|
||||
return (isSxTruthy(((idx + 1) < len(callArgs))) ? (function() {
|
||||
var valExpr = nth(callArgs, (idx + 1));
|
||||
return (isSxTruthy(dictHas(paramTypes, keyName)) ? (function() {
|
||||
var expected = get(paramTypes, keyName);
|
||||
var actual = inferType(valExpr, typeEnv, primTypes, typeRegistry);
|
||||
return (isSxTruthy((isSxTruthy(!isSxTruthy(typeAny_p(expected))) && isSxTruthy(!isSxTruthy(typeAny_p(actual))) && !isSxTruthy(subtypeResolved_p(actual, expected, typeRegistry)))) ? append_b(diagnostics, makeDiagnostic("error", (String("Keyword :") + String(keyName) + String(" of ") + String(compName) + String(" expects ") + String(expected) + String(", got ") + String(actual)), compName, valExpr)) : NIL);
|
||||
})() : NIL);
|
||||
})() : NIL);
|
||||
})() : NIL);
|
||||
})();
|
||||
} } }
|
||||
{ var _c = params; for (var _i = 0; _i < _c.length; _i++) { var paramName = _c[_i]; if (isSxTruthy((isSxTruthy(dictHas(paramTypes, paramName)) && isSxTruthy(!isSxTruthy(contains(providedKeys, paramName))) && !isSxTruthy(typeNullable_p(get(paramTypes, paramName)))))) {
|
||||
diagnostics.push(makeDiagnostic("warning", (String("Required param :") + String(paramName) + String(" of ") + String(compName) + String(" not provided")), compName, NIL));
|
||||
} } }
|
||||
return forEach(function(key) { return (isSxTruthy(!isSxTruthy(contains(params, key))) ? append_b(diagnostics, makeDiagnostic("warning", (String("Unknown keyword :") + String(key) + String(" passed to ") + String(compName)), compName, NIL)) : NIL); }, providedKeys);
|
||||
})();
|
||||
}
|
||||
return diagnostics;
|
||||
})(); };
|
||||
PRIMITIVES["check-component-call"] = checkComponentCall;
|
||||
|
||||
// check-body-walk
|
||||
var checkBodyWalk = function(node, compName, typeEnv, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations) { return (function() {
|
||||
var kind = typeOf(node);
|
||||
return (isSxTruthy((kind == "list")) ? (isSxTruthy(!isSxTruthy(isEmpty(node))) ? (function() {
|
||||
var head = first(node);
|
||||
var args = rest(node);
|
||||
if (isSxTruthy((typeOf(head) == "symbol"))) {
|
||||
(function() {
|
||||
var name = symbolName(head);
|
||||
if (isSxTruthy(startsWith(name, "~"))) {
|
||||
(function() {
|
||||
var compVal = envGet(env, name);
|
||||
return (isSxTruthy((typeOf(compVal) == "component")) ? forEach(function(d) { return append_b(diagnostics, d); }, checkComponentCall(name, compVal, args, typeEnv, primTypes, typeRegistry)) : NIL);
|
||||
})();
|
||||
if (isSxTruthy(!isSxTruthy(isNil(effectAnnotations)))) {
|
||||
(function() {
|
||||
var callerEffects = getEffects(compName, effectAnnotations);
|
||||
return forEach(function(d) { return append_b(diagnostics, d); }, checkEffectCall(name, callerEffects, effectAnnotations, compName));
|
||||
})();
|
||||
}
|
||||
}
|
||||
if (isSxTruthy((isSxTruthy(!isSxTruthy(startsWith(name, "~"))) && isSxTruthy(!isSxTruthy(isNil(primParamTypes))) && dictHas(primParamTypes, name)))) {
|
||||
{ var _c = checkPrimitiveCall(name, args, typeEnv, primTypes, primParamTypes, compName, typeRegistry); for (var _i = 0; _i < _c.length; _i++) { var d = _c[_i]; diagnostics.push(d); } }
|
||||
}
|
||||
if (isSxTruthy((isSxTruthy(!isSxTruthy(startsWith(name, "~"))) && !isSxTruthy(isNil(effectAnnotations))))) {
|
||||
(function() {
|
||||
var callerEffects = getEffects(compName, effectAnnotations);
|
||||
return forEach(function(d) { return append_b(diagnostics, d); }, checkEffectCall(name, callerEffects, effectAnnotations, compName));
|
||||
})();
|
||||
}
|
||||
if (isSxTruthy(sxOr((name == "let"), (name == "let*")))) {
|
||||
if (isSxTruthy((len(args) >= 2))) {
|
||||
(function() {
|
||||
var bindings = first(args);
|
||||
var bodyExprs = rest(args);
|
||||
var extended = merge(typeEnv, {});
|
||||
{ var _c = bindings; for (var _i = 0; _i < _c.length; _i++) { var binding = _c[_i]; if (isSxTruthy((isSxTruthy((typeOf(binding) == "list")) && (len(binding) >= 2)))) {
|
||||
(function() {
|
||||
var bname = (isSxTruthy((typeOf(first(binding)) == "symbol")) ? symbolName(first(binding)) : (String(first(binding))));
|
||||
var valType = inferType(nth(binding, 1), extended, primTypes, typeRegistry);
|
||||
return dictSet(extended, bname, valType);
|
||||
})();
|
||||
} } }
|
||||
return forEach(function(body) { return checkBodyWalk(body, compName, extended, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations); }, bodyExprs);
|
||||
})();
|
||||
}
|
||||
}
|
||||
return (isSxTruthy((name == "define")) ? (isSxTruthy((len(args) >= 2)) ? (function() {
|
||||
var defName = (isSxTruthy((typeOf(first(args)) == "symbol")) ? symbolName(first(args)) : NIL);
|
||||
var defVal = nth(args, 1);
|
||||
if (isSxTruthy(defName)) {
|
||||
typeEnv[defName] = inferType(defVal, typeEnv, primTypes, typeRegistry);
|
||||
}
|
||||
return checkBodyWalk(defVal, compName, typeEnv, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations);
|
||||
})() : NIL) : NIL);
|
||||
})();
|
||||
}
|
||||
return forEach(function(child) { return checkBodyWalk(child, compName, typeEnv, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations); }, args);
|
||||
})() : NIL) : NIL);
|
||||
})(); };
|
||||
PRIMITIVES["check-body-walk"] = checkBodyWalk;
|
||||
|
||||
// check-component
|
||||
var checkComponent = function(compName, env, primTypes, primParamTypes, typeRegistry, effectAnnotations) { return (function() {
|
||||
var comp = envGet(env, compName);
|
||||
var diagnostics = [];
|
||||
if (isSxTruthy((typeOf(comp) == "component"))) {
|
||||
(function() {
|
||||
var body = componentBody(comp);
|
||||
var params = componentParams(comp);
|
||||
var paramTypes = componentParamTypes(comp);
|
||||
var typeEnv = {};
|
||||
{ var _c = params; for (var _i = 0; _i < _c.length; _i++) { var p = _c[_i]; typeEnv[p] = (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(paramTypes))) && dictHas(paramTypes, p))) ? get(paramTypes, p) : "any"); } }
|
||||
if (isSxTruthy(componentHasChildren(comp))) {
|
||||
typeEnv["children"] = ["list-of", "element"];
|
||||
}
|
||||
return checkBodyWalk(body, compName, typeEnv, primTypes, primParamTypes, env, diagnostics, typeRegistry, effectAnnotations);
|
||||
})();
|
||||
}
|
||||
return diagnostics;
|
||||
})(); };
|
||||
PRIMITIVES["check-component"] = checkComponent;
|
||||
|
||||
// check-all
|
||||
var checkAll = function(env, primTypes, primParamTypes, typeRegistry, effectAnnotations) { return (function() {
|
||||
var allDiagnostics = [];
|
||||
{ var _c = keys(env); for (var _i = 0; _i < _c.length; _i++) { var name = _c[_i]; (function() {
|
||||
var val = envGet(env, name);
|
||||
return (isSxTruthy((typeOf(val) == "component")) ? forEach(function(d) { return append_b(allDiagnostics, d); }, checkComponent(name, env, primTypes, primParamTypes, typeRegistry, effectAnnotations)) : NIL);
|
||||
})(); } }
|
||||
return allDiagnostics;
|
||||
})(); };
|
||||
PRIMITIVES["check-all"] = checkAll;
|
||||
|
||||
// build-type-registry
|
||||
var buildTypeRegistry = function(primDeclarations, ioDeclarations) { return (function() {
|
||||
var registry = {};
|
||||
{ var _c = primDeclarations; for (var _i = 0; _i < _c.length; _i++) { var decl = _c[_i]; (function() {
|
||||
var name = get(decl, "name");
|
||||
var returns = get(decl, "returns");
|
||||
return (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(name))) && !isSxTruthy(isNil(returns)))) ? dictSet(registry, name, returns) : NIL);
|
||||
})(); } }
|
||||
{ var _c = ioDeclarations; for (var _i = 0; _i < _c.length; _i++) { var decl = _c[_i]; (function() {
|
||||
var name = get(decl, "name");
|
||||
var returns = get(decl, "returns");
|
||||
return (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(name))) && !isSxTruthy(isNil(returns)))) ? dictSet(registry, name, returns) : NIL);
|
||||
})(); } }
|
||||
return registry;
|
||||
})(); };
|
||||
PRIMITIVES["build-type-registry"] = buildTypeRegistry;
|
||||
|
||||
// type-def-name
|
||||
var typeDefName = function(td) { return get(td, "name"); };
|
||||
PRIMITIVES["type-def-name"] = typeDefName;
|
||||
|
||||
// type-def-params
|
||||
var typeDefParams = function(td) { return get(td, "params"); };
|
||||
PRIMITIVES["type-def-params"] = typeDefParams;
|
||||
|
||||
// type-def-body
|
||||
var typeDefBody = function(td) { return get(td, "body"); };
|
||||
PRIMITIVES["type-def-body"] = typeDefBody;
|
||||
|
||||
// resolve-type
|
||||
var resolveType = function(t, registry) { return (isSxTruthy(isNil(registry)) ? t : (isSxTruthy((typeOf(t) == "string")) ? (isSxTruthy(dictHas(registry, t)) ? (function() {
|
||||
var td = get(registry, t);
|
||||
return (function() {
|
||||
var params = typeDefParams(td);
|
||||
var body = typeDefBody(td);
|
||||
return (isSxTruthy(isEmpty(params)) ? resolveType(body, registry) : t);
|
||||
})();
|
||||
})() : t) : (isSxTruthy((typeOf(t) == "list")) ? (isSxTruthy(isEmpty(t)) ? t : (function() {
|
||||
var head = first(t);
|
||||
return (isSxTruthy(sxOr((head == "or"), (head == "list-of"), (head == "->"), (head == "dict-of"))) ? cons(head, map(function(m) { return resolveType(m, registry); }, rest(t))) : (isSxTruthy((isSxTruthy((typeOf(head) == "string")) && dictHas(registry, head))) ? (function() {
|
||||
var td = get(registry, head);
|
||||
var params = typeDefParams(td);
|
||||
var body = typeDefBody(td);
|
||||
var args = rest(t);
|
||||
return (isSxTruthy((len(params) == len(args))) ? resolveType(substituteTypeVars(body, params, args), registry) : t);
|
||||
})() : t));
|
||||
})()) : (isSxTruthy((typeOf(t) == "dict")) ? mapDict(function(k, v) { return resolveType(v, registry); }, t) : t)))); };
|
||||
PRIMITIVES["resolve-type"] = resolveType;
|
||||
|
||||
// substitute-type-vars
|
||||
var substituteTypeVars = function(body, params, args) { return (function() {
|
||||
var subst = {};
|
||||
{ var _c = range(0, len(params), 1); for (var _i = 0; _i < _c.length; _i++) { var i = _c[_i]; subst[nth(params, i)] = nth(args, i); } }
|
||||
return substituteInType(body, subst);
|
||||
})(); };
|
||||
PRIMITIVES["substitute-type-vars"] = substituteTypeVars;
|
||||
|
||||
// substitute-in-type
|
||||
var substituteInType = function(t, subst) { return (isSxTruthy((typeOf(t) == "string")) ? (isSxTruthy(dictHas(subst, t)) ? get(subst, t) : t) : (isSxTruthy((typeOf(t) == "list")) ? map(function(m) { return substituteInType(m, subst); }, t) : (isSxTruthy((typeOf(t) == "dict")) ? mapDict(function(k, v) { return substituteInType(v, subst); }, t) : t))); };
|
||||
PRIMITIVES["substitute-in-type"] = substituteInType;
|
||||
|
||||
// subtype-resolved?
|
||||
var subtypeResolved_p = function(a, b, registry) { return (isSxTruthy(isNil(registry)) ? subtype_p(a, b) : (function() {
|
||||
var ra = resolveType(a, registry);
|
||||
var rb = resolveType(b, registry);
|
||||
return (isSxTruthy((isSxTruthy((typeOf(ra) == "dict")) && (typeOf(rb) == "dict"))) ? isEvery(function(key) { return (isSxTruthy(dictHas(ra, key)) && subtypeResolved_p(get(ra, key), get(rb, key), registry)); }, keys(rb)) : subtype_p(ra, rb));
|
||||
})()); };
|
||||
PRIMITIVES["subtype-resolved?"] = subtypeResolved_p;
|
||||
|
||||
// get-effects
|
||||
var getEffects = function(name, effectAnnotations) { return (isSxTruthy(isNil(effectAnnotations)) ? NIL : (isSxTruthy(dictHas(effectAnnotations, name)) ? get(effectAnnotations, name) : NIL)); };
|
||||
PRIMITIVES["get-effects"] = getEffects;
|
||||
|
||||
// effects-subset?
|
||||
var effectsSubset_p = function(calleeEffects, callerEffects) { return (isSxTruthy(isNil(callerEffects)) ? true : (isSxTruthy(isNil(calleeEffects)) ? true : isEvery(function(e) { return contains(callerEffects, e); }, calleeEffects))); };
|
||||
PRIMITIVES["effects-subset?"] = effectsSubset_p;
|
||||
|
||||
// check-effect-call
|
||||
var checkEffectCall = function(calleeName, callerEffects, effectAnnotations, compName) { return (function() {
|
||||
var diagnostics = [];
|
||||
var calleeEffects = getEffects(calleeName, effectAnnotations);
|
||||
if (isSxTruthy((isSxTruthy(!isSxTruthy(isNil(callerEffects))) && isSxTruthy(!isSxTruthy(isNil(calleeEffects))) && !isSxTruthy(effectsSubset_p(calleeEffects, callerEffects))))) {
|
||||
diagnostics.push(makeDiagnostic("error", (String("`") + String(calleeName) + String("` has effects ") + String(join(", ", calleeEffects)) + String(" but `") + String(compName) + String("` only allows ") + String((isSxTruthy(isEmpty(callerEffects)) ? "[pure]" : join(", ", callerEffects)))), compName, NIL));
|
||||
}
|
||||
return diagnostics;
|
||||
})(); };
|
||||
PRIMITIVES["check-effect-call"] = checkEffectCall;
|
||||
|
||||
// build-effect-annotations
|
||||
var buildEffectAnnotations = function(ioDeclarations) { return (function() {
|
||||
var annotations = {};
|
||||
{ var _c = ioDeclarations; for (var _i = 0; _i < _c.length; _i++) { var decl = _c[_i]; (function() {
|
||||
var name = get(decl, "name");
|
||||
return (isSxTruthy(!isSxTruthy(isNil(name))) ? dictSet(annotations, name, ["io"]) : NIL);
|
||||
})(); } }
|
||||
return annotations;
|
||||
})(); };
|
||||
PRIMITIVES["build-effect-annotations"] = buildEffectAnnotations;
|
||||
|
||||
// check-component-effects
|
||||
var checkComponentEffects = function(compName, env, effectAnnotations) { return (function() {
|
||||
var comp = envGet(env, compName);
|
||||
var diagnostics = [];
|
||||
if (isSxTruthy((typeOf(comp) == "component"))) {
|
||||
(function() {
|
||||
var body = componentBody(comp);
|
||||
return checkBodyWalk(body, compName, {}, {}, NIL, env, diagnostics, NIL, effectAnnotations);
|
||||
})();
|
||||
}
|
||||
return diagnostics;
|
||||
})(); };
|
||||
PRIMITIVES["check-component-effects"] = checkComponentEffects;
|
||||
|
||||
// check-all-effects
|
||||
var checkAllEffects = function(env, effectAnnotations) { return (function() {
|
||||
var allDiagnostics = [];
|
||||
{ var _c = keys(env); for (var _i = 0; _i < _c.length; _i++) { var name = _c[_i]; (function() {
|
||||
var val = envGet(env, name);
|
||||
return (isSxTruthy((typeOf(val) == "component")) ? forEach(function(d) { return append_b(allDiagnostics, d); }, checkComponentEffects(name, env, effectAnnotations)) : NIL);
|
||||
})(); } }
|
||||
return allDiagnostics;
|
||||
})(); };
|
||||
PRIMITIVES["check-all-effects"] = checkAllEffects;
|
||||
|
||||
|
||||
// =========================================================================
|
||||
// Post-transpilation fixups
|
||||
// =========================================================================
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/start-9e868ccd.wasm
Normal file
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/start-9e868ccd.wasm
Normal file
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["/builtin/blackbox.ml","/root/.opam/5.2.0/lib/ocaml/std_exit.ml"],"sourcesContent":["(* generated code *)","(**************************************************************************)\n(* *)\n(* OCaml *)\n(* *)\n(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)\n(* *)\n(* Copyright 1996 Institut National de Recherche en Informatique et *)\n(* en Automatique. *)\n(* *)\n(* All rights reserved. This file is distributed under the terms of *)\n(* the GNU Lesser General Public License version 2.1, with the *)\n(* special exception on linking described in the file LICENSE. *)\n(* *)\n(**************************************************************************)\n\n(* Ensure that [at_exit] functions are called at the end of every program *)\n\nlet _ = do_at_exit()\n"],"names":[],"mappings":"6GCiBQ,IDjBR,QCiBQ,cAAY","ignoreList":[0]}
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-02032b37.wasm
Normal file
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-02032b37.wasm
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-2dae9b2f.wasm
Normal file
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-2dae9b2f.wasm
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-30805295.wasm
Normal file
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-30805295.wasm
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-ea36a0db.wasm
Normal file
BIN
shared/static/wasm/sx_browser.bc.wasm.assets/sx-ea36a0db.wasm
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
1821
shared/static/wasm/sx_browser.bc.wasm.js
Normal file
1821
shared/static/wasm/sx_browser.bc.wasm.js
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user