From e4e8b45cb4261630b2f474391c1d60ffedd395dc Mon Sep 17 00:00:00 2001 From: giles Date: Mon, 9 Mar 2026 00:54:20 +0000 Subject: [PATCH] Update py.sx scope: general SX-to-Python translator, not spec-only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- sx/sx/plans/self-hosting-bootstrapper.sx | 40 +++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/sx/sx/plans/self-hosting-bootstrapper.sx b/sx/sx/plans/self-hosting-bootstrapper.sx index 398646b..7cdbb6d 100644 --- a/sx/sx/plans/self-hosting-bootstrapper.sx +++ b/sx/sx/plans/self-hosting-bootstrapper.sx @@ -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."))