// Selfhost Compiler MVP (Phase 15.3) // Reads tmp/ny_parser_input.ny and prints a minimal JSON v0 program. // Components are split under boxes/ and included here. include "apps/selfhost-compiler/boxes/debug_box.nyash" include "apps/selfhost-compiler/boxes/parser_box.nyash" include "apps/selfhost-compiler/boxes/emitter_box.nyash" static box Main { // ---- IO helper ---- read_all(path) { local fb = new FileBox() fb.open(path, "r") local s = fb.read() fb.close() if s == null { return "return 1+2*3" } return s } // ---- JSON helpers ---- esc_json(s) { local out = "" local i = 0 local n = s.length() loop(i < n) { local ch = s.substring(i, i+1) if ch == "\\" { out = out + "\\\\" } else { if ch == "\"" { out = out + "\\\"" } else { out = out + ch } } i = i + 1 } return out } // Parser delegation parse_program(src, stage3_flag) { local parser = new ParserBox() if stage3_flag == 1 { parser.stage3_enable(1) } // Collect using metadata (no-op acceptance in Stage‑15) parser.extract_usings(src) me._usings = parser.get_usings_json() return parser.parse_program2(src) } main(args) { // Debug setup me.dbg = new DebugBox() me.dbg.set_enabled(0) // Source selection (EXE-first friendly) // - default: safe constant // - positional arg: treat as input file path // - --read-tmp: use tmp/ny_parser_input.ny (requires FileBox plugin) local src = "return 1+2*3" local read_tmp = 0 local input_path = null local stage3_mode = 0 if args != null { local alen = args.length() local i = 0 loop(i < alen) { local a = args.get(i) if a == "--read-tmp" { read_tmp = 1 } else { if a == "--min-json" { /* handled later */ } else { if a == "--stage3" { stage3_mode = 1 } else { if input_path == null { input_path = a } } } } i = i + 1 } } if input_path != null { // Prefer explicit file when provided (requires FileBox plugin) local s1 = me.read_all(input_path) if s1 != null { src = s1 } } else { if read_tmp == 1 { // Optional: read tmp/ny_parser_input.ny (requires FileBox plugin; do not use in CI) local s2 = me.read_all("tmp/ny_parser_input.ny") if s2 != null { src = s2 } } } // Gate: minimal JSON when requested via script arg local min_mode = 0 if args != null { local alen = args.length() local i = 0 loop(i < alen) { local arg = args.get(i) if arg == "--min-json" { min_mode = 1 } i = i + 1 } } local json = null if min_mode == 1 { json = "{\"version\":0,\"kind\":\"Program\",\"body\":[{\"type\":\"Return\",\"expr\":{\"type\":\"Int\",\"value\":0}}]}" } else { json = me.parse_program(src, stage3_mode) } // Emit via EmitterBox (attach meta.usings when available) local emitter = new EmitterBox() json = emitter.emit_program(json, me._usings) // Output local console = new ConsoleBox() console.println(json) return 0 } }