Implement js.sx: self-hosting SX-to-JavaScript bootstrapper
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>
This commit is contained in:
1382
shared/sx/ref/js.sx
Normal file
1382
shared/sx/ref/js.sx
Normal file
File diff suppressed because it is too large
Load Diff
101
shared/sx/ref/run_js_sx.py
Normal file
101
shared/sx/ref/run_js_sx.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Bootstrap runner: execute js.sx against spec files to produce sx-ref.js.
|
||||
|
||||
This is the G1 bootstrapper — js.sx (SX-to-JavaScript translator written in SX)
|
||||
is loaded into the Python evaluator, which then uses it to translate the
|
||||
spec .sx files into JavaScript.
|
||||
|
||||
The output (transpiled defines only) should be identical to what
|
||||
bootstrap_js.py's JSEmitter produces.
|
||||
|
||||
Usage:
|
||||
python run_js_sx.py > /tmp/sx_ref_g1.js
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
_PROJECT = os.path.abspath(os.path.join(_HERE, "..", "..", ".."))
|
||||
sys.path.insert(0, _PROJECT)
|
||||
|
||||
from shared.sx.parser import parse_all
|
||||
from shared.sx.types import Symbol
|
||||
|
||||
|
||||
def load_js_sx() -> dict:
|
||||
"""Load js.sx into an evaluator environment and return it."""
|
||||
js_sx_path = os.path.join(_HERE, "js.sx")
|
||||
with open(js_sx_path) as f:
|
||||
source = f.read()
|
||||
|
||||
exprs = parse_all(source)
|
||||
|
||||
from shared.sx.evaluator import evaluate, make_env
|
||||
|
||||
env = make_env()
|
||||
for expr in exprs:
|
||||
evaluate(expr, env)
|
||||
|
||||
return env
|
||||
|
||||
|
||||
def extract_defines(source: str) -> list[tuple[str, list]]:
|
||||
"""Parse .sx source, return list of (name, define-expr) for top-level defines."""
|
||||
exprs = parse_all(source)
|
||||
defines = []
|
||||
for expr in exprs:
|
||||
if isinstance(expr, list) and expr and isinstance(expr[0], Symbol):
|
||||
if expr[0].name == "define":
|
||||
name = expr[1].name if isinstance(expr[1], Symbol) else str(expr[1])
|
||||
defines.append((name, expr))
|
||||
return defines
|
||||
|
||||
|
||||
def main():
|
||||
from shared.sx.evaluator import evaluate
|
||||
|
||||
# Load js.sx into evaluator
|
||||
env = load_js_sx()
|
||||
|
||||
# Same file list and order as bootstrap_js.py compile_ref_to_js() with all adapters
|
||||
sx_files = [
|
||||
("eval.sx", "eval"),
|
||||
("render.sx", "render (core)"),
|
||||
("parser.sx", "parser"),
|
||||
("adapter-html.sx", "adapter-html"),
|
||||
("adapter-sx.sx", "adapter-sx"),
|
||||
("adapter-dom.sx", "adapter-dom"),
|
||||
("engine.sx", "engine"),
|
||||
("orchestration.sx", "orchestration"),
|
||||
("boot.sx", "boot"),
|
||||
("deps.sx", "deps (component dependency analysis)"),
|
||||
("router.sx", "router (client-side route matching)"),
|
||||
("signals.sx", "signals (reactive signal runtime)"),
|
||||
]
|
||||
|
||||
# Translate each spec file using js.sx
|
||||
for filename, label in sx_files:
|
||||
filepath = os.path.join(_HERE, filename)
|
||||
if not os.path.exists(filepath):
|
||||
continue
|
||||
with open(filepath) as f:
|
||||
src = f.read()
|
||||
defines = extract_defines(src)
|
||||
|
||||
# Convert defines to SX-compatible format
|
||||
sx_defines = [[name, expr] for name, expr in defines]
|
||||
|
||||
print(f"\n // === Transpiled from {label} ===\n")
|
||||
env["_defines"] = sx_defines
|
||||
result = evaluate(
|
||||
[Symbol("js-translate-file"), Symbol("_defines")],
|
||||
env,
|
||||
)
|
||||
print(result)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user