Remove invoke from platform interfaces, add cek-call integration tests

- platform_js.py: remove invoke function definition and PRIMITIVES
  registration, switch domListen handler wrapping to cek-call
- platform_py.py: remove invoke function definition
- run_signal_tests.py: remove invoke patch, use cek_call in batch wrapper
- run_cek_reactive_tests.py: remove invoke, fix primitive lookup to use
  two-level is_primitive/get_primitive, increase recursion limit for
  interpreted CEK evaluation
- test-cek-reactive.sx: add 7 new tests covering cek-call dispatch with
  computed, effect, cleanup, batch coalescing

All 79 tests pass (20 signal + 43 CEK + 16 CEK reactive).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-14 10:29:32 +00:00
parent 6581211a10
commit d0a5ce1070
7 changed files with 70 additions and 70 deletions

View File

@@ -14,7 +14,7 @@
// =========================================================================
var NIL = Object.freeze({ _nil: true, toString: function() { return "nil"; } });
var SX_VERSION = "2026-03-14T10:16:03Z";
var SX_VERSION = "2026-03-14T10:27:39Z";
function isNil(x) { return x === NIL || x === null || x === undefined; }
function isSxTruthy(x) { return x !== false && !isNil(x); }
@@ -218,17 +218,6 @@
return new Island(name, params, hasChildren, body, merge(env));
}
// invoke — call any callable (native fn or SX lambda) with args.
// Transpiled code emits direct calls f(args) which fail on SX lambdas
// from runtime-evaluated island bodies. invoke dispatches correctly.
function invoke() {
var f = arguments[0];
var args = Array.prototype.slice.call(arguments, 1);
if (isLambda(f)) return trampoline(callLambda(f, args, lambdaClosure(f)));
if (typeof f === 'function') return f.apply(null, args);
return NIL;
}
// JSON / dict helpers for island state serialization
function jsonSerialize(obj) {
return JSON.stringify(obj);
@@ -5192,8 +5181,8 @@ return (function() {
// If lambda takes 0 params, call without event arg (convenience for on-click handlers)
var wrapped = isLambda(handler)
? (lambdaParams(handler).length === 0
? function(e) { try { invoke(handler); } catch(err) { console.error("[sx-ref] domListen handler error:", name, err); } }
: function(e) { try { invoke(handler, e); } catch(err) { console.error("[sx-ref] domListen handler error:", name, err); } })
? function(e) { try { cekCall(handler, NIL); } catch(err) { console.error("[sx-ref] domListen handler error:", name, err); } }
: function(e) { try { cekCall(handler, [e]); } catch(err) { console.error("[sx-ref] domListen handler error:", name, err); } })
: handler;
if (name === "click") logInfo("domListen: click on <" + (el.tagName||"?").toLowerCase() + "> text=" + (el.textContent||"").substring(0,20) + " isLambda=" + isLambda(handler));
el.addEventListener(name, wrapped);
@@ -6393,7 +6382,6 @@ return (function() {
PRIMITIVES["stop-propagation"] = stopPropagation_;
PRIMITIVES["error-message"] = errorMessage;
PRIMITIVES["schedule-idle"] = scheduleIdle;
PRIMITIVES["invoke"] = invoke;
PRIMITIVES["error"] = function(msg) { throw new Error(msg); };
PRIMITIVES["filter"] = filter;
// DOM primitives for sx-on:* handlers and data-init scripts