Files
hakorune/apps/selfhost-compiler/compiler.nyash

130 lines
3.7 KiB
Plaintext
Raw Normal View History

// 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.
// Prefer using for module declaration (Runner strips and registers)
using "apps/selfhost-compiler/boxes/debug_box.nyash" as DebugBoxMod
using "apps/selfhost-compiler/boxes/parser_box.nyash" as ParserBoxMod
using "apps/selfhost-compiler/boxes/emitter_box.nyash" as EmitterBoxMod
using "apps/selfhost-compiler/boxes/mir_emitter_box.nyash" as MirEmitterBoxMod
// (removed) Transitional duplicate using lines to avoid resolver duplicate-import error
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 Stage15)
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
local emit_mir = 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 }
if arg == "--emit-mir" { emit_mir = 1 }
i = i + 1
}
}
local json = null
local ast_json = null
if min_mode == 1 {
ast_json = "{\"version\":0,\"kind\":\"Program\",\"body\":[{\"type\":\"Return\",\"expr\":{\"type\":\"Int\",\"value\":0}}]}"
} else {
ast_json = me.parse_program(src, stage3_mode)
}
if emit_mir == 1 {
// Lower minimal AST to MIR JSON (Return(Int) only for MVP)
json = MirEmitterBox.emit_mir_min(ast_json)
} else {
// Emit Stage1 JSON with metadata
json = EmitterBox.emit_program(ast_json, me._usings)
}
// Output JSON
local console = new ConsoleBox()
console.println(json)
return 0
}
}