Fix aser list flattening bug, add wire format test suite (41 tests)
The sync aser-call in adapter-sx.sx didn't flatten list results from map/filter in positional children — serialize(list) wrapped in parens creating ((div ...) ...) which re-parses as an invalid call. Rewrote aser-call from reduce to for-each (bootstrapper can't nest for-each inside reduce lambdas) and added list flattening in both aser-call and aser-fragment. Also adds test-aser.sx (41 tests), render-sx platform function, expanded test-render.sx (+7 map/filter children tests), and specs async-eval-slot-inner in adapter-async.sx. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -134,6 +134,28 @@ def render_html(sx_source):
|
||||
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)
|
||||
render_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 +280,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": []},
|
||||
@@ -296,8 +319,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",
|
||||
@@ -773,9 +797,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