Update py.sx scope: general SX-to-Python translator, not spec-only
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m37s

The translation rules are mechanical and apply to all SX forms — HTML tags,
components, macros, islands, page forms. Bootstrapping the spec is the first
test case (fixed-point proof); phases 6-9 extend to full SX compilation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 00:54:20 +00:00
parent db1691d8f5
commit e4e8b45cb4

View File

@@ -280,14 +280,38 @@ diff sx_ref_g1.py sx_ref_g2.py" "bash"))
;; What py.sx is NOT
;; -----------------------------------------------------------------------
(~doc-section :title "Scope and Non-Goals" :id "scope"
(p (code "py.sx") " is " (em "not") " a general-purpose SX-to-Python compiler. "
"It only needs to translate the restricted SX subset used in the spec files:")
(ul :class "list-disc pl-6 space-y-1 text-stone-700"
(li "No " (code "defcomp") " / " (code "defmacro") " emission — those are runtime constructs that " (code "eval.sx") " itself handles")
(li "No HTML rendering — that's inside the spec, not the translation")
(li "No I/O — the spec is pure functions")
(li "No " (code "defpage") " / " (code "defhandler") " — those are app-level forms"))
(~doc-section :title "Scope" :id "scope"
(p (code "py.sx") " is a general-purpose SX-to-Python translator. "
"The translation rules are mechanical and apply to " (em "all") " SX, "
"not just the spec subset.")
(~doc-subsection :title "Why General?"
(p "Every SX form has a straightforward Python equivalent:")
(ul :class "list-disc pl-6 space-y-1 text-stone-700"
(li (code "(div :class \"foo\" ...)") " → " (code "render_element(\"div\", {\"class\": \"foo\"}, ...)"))
(li (code "(~card :title \"hi\")") " → component function call with keyword args")
(li (code "defcomp") " → function definition with " (code "&key") " / " (code "&rest") " argument parsing")
(li (code "defmacro") " → function that returns AST (macros expand before translation)")
(li (code "defpage") " → route registration + handler function")
(li (code "defisland") " → island registration (same shape as " (code "defcomp") ")")
(li "I/O primitives → calls to host-provided functions"))
(p "The spec files are the " (em "first test case") " — because we can verify correctness "
"by diffing G0 and G1 output. But the translator itself is target-agnostic: "
"it translates SX syntax, not SX semantics."))
(~doc-subsection :title "Bootstrapping First, Then Everything"
(p "The implementation plan above starts with the spec subset (Phases 1-5) because "
"that's where the fixed-point proof lives. Once G1 == G0, extend to full SX:")
(ul :class "list-disc pl-6 space-y-1 text-stone-700"
(li (strong "Phase 6") ": Component and macro forms — " (code "defcomp") ", "
(code "defmacro") ", " (code "defisland") ", component calling convention")
(li (strong "Phase 7") ": HTML/DOM tags — translate " (code "(div ...)") " to render calls")
(li (strong "Phase 8") ": Page forms — " (code "defpage") ", " (code "defhandler") ", route wiring")
(li (strong "Phase 9") ": Full application files — translate any " (code ".sx") " file to a Python module"))
(p "At that point, " (code "py.sx") " can compile " (em "itself") " — and any SX application — "
"into Python. The bootstrapper is just the proof that the translation is correct. "
"The translator is the real product."))
(p "The full RENAMES table from " (code "bootstrap_py.py") " (200+ entries) moves into "
(code "py.sx") " as a dict literal. This is the largest single piece — "
"a mapping from SX names to their exact Python equivalents."))