Fix bootstrapper dict literal transpilation: emit values through emit()
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 4m51s

The SX parser produces native Python dicts for {:key val} syntax, but
both JSEmitter and PyEmitter had no dict case in emit() — falling through
to str(expr) which output raw AST. This broke client-side routing because
process-page-scripts used {"parsed" (parse-route-pattern ...)} and the
function call was emitted as a JS array of Symbols instead of an actual
function call.

Add _emit_native_dict() to both bootstrappers + 8 unit tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 16:24:44 +00:00
parent dd1c1c9a3c
commit 3749fe9625
4 changed files with 83 additions and 2 deletions

View File

@@ -52,6 +52,8 @@ class PyEmitter:
return self._emit_symbol(expr.name)
if isinstance(expr, Keyword):
return self._py_string(expr.name)
if isinstance(expr, dict):
return self._emit_native_dict(expr)
if isinstance(expr, list):
return self._emit_list(expr)
return str(expr)
@@ -526,6 +528,13 @@ class PyEmitter:
parts = [self.emit(e) for e in exprs]
return "_sx_begin(" + ", ".join(parts) + ")"
def _emit_native_dict(self, expr: dict) -> str:
"""Emit a native Python dict (from parser's {:key val} syntax)."""
parts = []
for key, val in expr.items():
parts.append(f"{self._py_string(key)}: {self.emit(val)}")
return "{" + ", ".join(parts) + "}"
def _emit_dict_literal(self, expr) -> str:
pairs = expr[1:]
parts = []