Two bugs fixed:
1. process-bindings used merge(env) which returns {} for Env objects
(Env is not a dict subclass). Changed to env-extend in render.sx
and adapter-async.sx. This caused "Undefined symbol: theme" etc.
2. async-aser-eval-call passed evaled-args list to async-invoke(&rest),
double-wrapping it. Changed to inline apply + coroutine check.
Also: bootstrap define-async into sx_ref.py (Phase 6), replace ~1000 LOC
hand-written async_eval_ref.py with 24-line thin re-export shim.
Test runner now uses Env (not flat dict) for render envs to catch scope bugs.
8 new regression tests (4 scope chain, 2 native callable arity, 2 render).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix qq-expand in eval.sx: use concat+list instead of append to prevent
nested lists from being flattened during quasiquote expansion
- Update append primitive to match spec ("if x is list, concatenate")
- Rebuild sx_ref.py with quasiquote fix
- Make relations.py self-contained: parse defrelation AST directly
without depending on the evaluator (25/25 tests pass)
- Replace hand-written JSEmitter with js.sx self-hosting bootstrapper
- Guard server-only tests in test-eval.sx with runtime check
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Configurable page shell (~sx-page-shell kwargs + SX_SHELL app config)
so each app controls its own assets — sx docs loads only sx-browser.js
- SX-evaluated sx-on:* handlers (eval-expr instead of new Function)
with DOM primitives registered in PRIMITIVES table
- data-init boot mode for pure SX initialization scripts
- Jiggle animation on links while fetching
- Nav: 3-column grid for centered alignment, is-leaf sizing,
fix map-indexed param order (index, item), guard mod-by-zero
- Async route eval failure now falls back to server fetch
instead of silently rendering nothing
- Remove duplicate h1 title from ~doc-page
- Re-bootstrap sx-ref.js + sx-browser.js
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Documents the self-hosting process for js.sx including the G0 bug
where Python's `if fn_expr` treated 0/False/"" as falsy, emitting
NIL instead of the correct value. Adds live verification page,
translation differences table, and nav entry.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SX-to-JavaScript translator written in SX itself. When executed by the
Python evaluator against the spec files, produces output identical to
the hand-written bootstrap_js.py JSEmitter.
- 1,382 lines, 61 defines
- 431/431 defines match across all 22 spec files (G0 == G1)
- 267 defines in the standard compilation, 151,763 bytes identical
- camelCase mangling, var declarations, function(){} syntax
- Self-tail-recursive optimization (zero-arg → while loops)
- JS-native statement patterns: d[k]=v, arr.push(x), f.name=x
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>