Merge branch 'main' into worktree-typed-sx
# Conflicts: # shared/sx/ref/platform_py.py # shared/sx/ref/sx_ref.py
This commit is contained in:
@@ -20,7 +20,7 @@ _PROJECT = os.path.abspath(os.path.join(_HERE, "..", "..", ".."))
|
||||
sys.path.insert(0, _PROJECT)
|
||||
|
||||
from shared.sx.parser import parse_all
|
||||
from shared.sx.evaluator import _eval, _trampoline, _call_lambda
|
||||
from shared.sx.ref.sx_ref import eval_expr as _eval, trampoline as _trampoline, call_lambda as _call_lambda
|
||||
from shared.sx.types import Symbol, Keyword, Lambda, NIL, Component, Island
|
||||
|
||||
# --- Test state ---
|
||||
@@ -127,13 +127,38 @@ def render_html(sx_source):
|
||||
except ImportError:
|
||||
raise RuntimeError("render-to-html not available — sx_ref.py not built")
|
||||
exprs = parse_all(sx_source)
|
||||
render_env = dict(env)
|
||||
# Use Env (not flat dict) so tests exercise the real scope chain path.
|
||||
render_env = _Env(dict(env))
|
||||
result = ""
|
||||
for expr in exprs:
|
||||
result += _render_to_html(expr, render_env)
|
||||
return result
|
||||
|
||||
|
||||
# --- Render SX (aser) platform function ---
|
||||
|
||||
def render_sx(sx_source):
|
||||
"""Parse SX source and serialize to SX wire format via the bootstrapped evaluator."""
|
||||
try:
|
||||
from shared.sx.ref.sx_ref import aser as _aser, serialize as _serialize
|
||||
except ImportError:
|
||||
raise RuntimeError("aser not available — sx_ref.py not built")
|
||||
exprs = parse_all(sx_source)
|
||||
# Use Env (not flat dict) so tests exercise the real scope chain path.
|
||||
# Using dict(env) hides bugs where merge() drops Env parent scopes.
|
||||
render_env = _Env(dict(env))
|
||||
result = ""
|
||||
for expr in exprs:
|
||||
val = _aser(expr, render_env)
|
||||
if isinstance(val, str):
|
||||
result += val
|
||||
elif val is None or val is NIL:
|
||||
pass
|
||||
else:
|
||||
result += _serialize(val)
|
||||
return result
|
||||
|
||||
|
||||
# --- Signal platform primitives ---
|
||||
# Implements the signal runtime platform interface for testing signals.sx
|
||||
|
||||
@@ -258,6 +283,7 @@ SPECS = {
|
||||
"parser": {"file": "test-parser.sx", "needs": ["sx-parse"]},
|
||||
"router": {"file": "test-router.sx", "needs": []},
|
||||
"render": {"file": "test-render.sx", "needs": ["render-html"]},
|
||||
"aser": {"file": "test-aser.sx", "needs": ["render-sx"]},
|
||||
"deps": {"file": "test-deps.sx", "needs": []},
|
||||
"engine": {"file": "test-engine.sx", "needs": []},
|
||||
"orchestration": {"file": "test-orchestration.sx", "needs": []},
|
||||
@@ -297,8 +323,9 @@ env = _Env({
|
||||
"make-keyword": make_keyword,
|
||||
"symbol-name": symbol_name,
|
||||
"keyword-name": keyword_name,
|
||||
# Render platform function
|
||||
# Render platform functions
|
||||
"render-html": render_html,
|
||||
"render-sx": render_sx,
|
||||
# Extra primitives needed by spec modules (router.sx, deps.sx)
|
||||
"for-each-indexed": "_deferred", # replaced below
|
||||
"dict-set!": "_deferred",
|
||||
@@ -848,9 +875,9 @@ def main():
|
||||
print(f"# --- {spec_name} ---")
|
||||
eval_file(spec["file"], env)
|
||||
|
||||
# Reset render state after render tests to avoid leaking
|
||||
# Reset render state after render/aser tests to avoid leaking
|
||||
# into subsequent specs (bootstrapped evaluator checks render_active)
|
||||
if spec_name == "render":
|
||||
if spec_name in ("render", "aser"):
|
||||
try:
|
||||
from shared.sx.ref.sx_ref import set_render_active_b
|
||||
set_render_active_b(False)
|
||||
|
||||
Reference in New Issue
Block a user