#!/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()