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

136 lines
4.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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
// Transitional: keep include for Phase-15 compatibility
include "apps/selfhost-compiler/boxes/debug_box.nyash"
include "apps/selfhost-compiler/boxes/parser_box.nyash"
include "apps/selfhost-compiler/boxes/emitter_box.nyash"
include "apps/selfhost-compiler/boxes/mir_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 ParserBoxMod.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 DebugBoxMod.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)
local mir = new MirEmitterBoxMod.MirEmitterBox()
json = mir.emit_mir_min(ast_json)
} else {
// Emit Stage1 JSON with metadata
local emitter = new EmitterBoxMod.EmitterBox()
json = emitter.emit_program(ast_json, me._usings)
}
// Output JSON
local console = new ConsoleBox()
console.println(json)
return 0
}
}