Replace invoke with cek-call in reactive island primitives
All signal operations (computed, effect, batch, etc.) now dispatch function calls through cek-call, which routes SX lambdas via cek-run and native callables via apply. This replaces the invoke shim. Key changes: - cek.sx: add cek-call (defined before reactive-shift-deref), replace invoke in subscriber disposal and ReactiveResetFrame handler - signals.sx: replace all 11 invoke calls with cek-call - js.sx: fix octal escape in js-quote-string (char-from-code 0) - platform_js.py: fix JS append to match Python (list concat semantics), add Continuation type guard in PLATFORM_CEK_JS, add scheduleIdle safety check, module ordering (cek before signals) - platform_py.py: fix ident-char regex (remove [ ] from valid chars), module ordering (cek before signals) - run_js_sx.py: emit PLATFORM_CEK_JS before transpiled spec files - page-functions.sx: add cek and provide page functions for SX URLs Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,17 +20,21 @@ logger = logging.getLogger("sx.boundary_parser")
|
||||
|
||||
# Allow standalone use (from bootstrappers) or in-project imports
|
||||
try:
|
||||
from shared.sx.parser import parse_all
|
||||
from shared.sx.types import Symbol, Keyword, NIL as SX_NIL
|
||||
except ImportError:
|
||||
import sys
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
_PROJECT = os.path.abspath(os.path.join(_HERE, "..", "..", ".."))
|
||||
sys.path.insert(0, _PROJECT)
|
||||
from shared.sx.parser import parse_all
|
||||
from shared.sx.types import Symbol, Keyword, NIL as SX_NIL
|
||||
|
||||
|
||||
def _get_parse_all():
|
||||
"""Lazy import to avoid circular dependency when parser.py loads sx_ref.py."""
|
||||
from shared.sx.parser import parse_all
|
||||
return parse_all
|
||||
|
||||
|
||||
def _ref_dir() -> str:
|
||||
return os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
@@ -81,7 +85,7 @@ def _extract_declarations(
|
||||
|
||||
Returns (io_names, {service: helper_names}).
|
||||
"""
|
||||
exprs = parse_all(source)
|
||||
exprs = _get_parse_all()(source)
|
||||
io_names: set[str] = set()
|
||||
helpers: dict[str, set[str]] = {}
|
||||
|
||||
@@ -144,7 +148,7 @@ def parse_primitives_sx() -> frozenset[str]:
|
||||
def parse_primitives_by_module() -> dict[str, frozenset[str]]:
|
||||
"""Parse primitives.sx and return primitives grouped by module."""
|
||||
source = _read_file("primitives.sx")
|
||||
exprs = parse_all(source)
|
||||
exprs = _get_parse_all()(source)
|
||||
modules: dict[str, set[str]] = {}
|
||||
current_module = "_unscoped"
|
||||
|
||||
@@ -204,7 +208,7 @@ def parse_primitive_param_types() -> dict[str, dict]:
|
||||
type of the &rest parameter (or None if no &rest, or None if untyped &rest).
|
||||
"""
|
||||
source = _read_file("primitives.sx")
|
||||
exprs = parse_all(source)
|
||||
exprs = _get_parse_all()(source)
|
||||
result: dict[str, dict] = {}
|
||||
|
||||
for expr in exprs:
|
||||
@@ -293,7 +297,7 @@ def parse_boundary_effects() -> dict[str, list[str]]:
|
||||
Pure primitives from primitives.sx are not included (they have no effects).
|
||||
"""
|
||||
source = _read_file("boundary.sx")
|
||||
exprs = parse_all(source)
|
||||
exprs = _get_parse_all()(source)
|
||||
result: dict[str, list[str]] = {}
|
||||
|
||||
_DECL_FORMS = {
|
||||
@@ -338,7 +342,7 @@ def parse_boundary_effects() -> dict[str, list[str]]:
|
||||
def parse_boundary_types() -> frozenset[str]:
|
||||
"""Parse boundary.sx and return the declared boundary type names."""
|
||||
source = _read_file("boundary.sx")
|
||||
exprs = parse_all(source)
|
||||
exprs = _get_parse_all()(source)
|
||||
for expr in exprs:
|
||||
if (isinstance(expr, list) and len(expr) >= 2
|
||||
and isinstance(expr[0], Symbol)
|
||||
|
||||
Reference in New Issue
Block a user