Files
hakorune/apps/selfhost/compiler/compiler.nyash
Selfhosting Dev 81211c22ad feat: MIR Call命令統一Phase 3.1-3.2完了!統一Call実装進行中
 Phase 3.1-3.2実装完了
- build_indirect_call_expressionでCallTarget::Value使用
- print関数をcall_global print()として統一
- build_function_callでemit_unified_call使用
- ExternCall(env.console.log)→Callee::Global(print)完全移行

🏗️ MIR統一基盤構築
- src/mir/definitions/call_unified.rs: 統一定義(297行)
- emit_unified_call()と便利メソッド3種実装
- NYASH_MIR_UNIFIED_CALL=1で段階移行制御
- VM実行器でCallee対応実装済み

📊 進捗状況(26%削減見込み)
- Phase 1-2:  基盤構築完了
- Phase 3.1-3.2:  基本関数統一完了
- Phase 3.3: 🔄 BoxCall統一中
- Phase 4: 📅 Python LLVM(最優先・63%削減)
- Phase 5: 📅 PyVM/VM統一

📚 ドキュメント更新
- CLAUDE.md: テストスクリプト参考集追加
- CURRENT_TASK.md: Phase 3進捗更新
- python-llvm-priority-rationale.md: 優先順位戦略文書化
- mir-call-unification-master-plan.md: スケジュール最新化

🎯 6種類→1種類: Call/BoxCall/PluginInvoke/ExternCall/NewBox/NewClosure → MirCall統一へ

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-24 01:05:44 +09:00

159 lines
4.7 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"
// Prepass libs (ScopeBox/LoopForm)
include "apps/lib/scopebox_inject.nyash"
include "apps/lib/loopform_normalize.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 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)
}
// Optional prepasses driven by CLI flags (mapped from env by runner)
local do_scopebox = 0
local do_loopform = 0
if args != null {
local alen3 = args.length()
local i3 = 0
loop(i3 < alen3) {
local a3 = args.get(i3)
if a3 == "--scopebox" { do_scopebox = 1 }
if a3 == "--loopform" { do_loopform = 1 }
i3 = i3 + 1
}
}
if emit_mir == 1 {
// Lower minimal AST to MIR JSON (Return(Int) only for MVP)
local mir = new MirEmitterBox()
local aj = ast_json
if do_scopebox == 1 { aj = new ScopeBoxInject().apply(aj) }
if do_loopform == 1 { aj = new LoopFormNormalize().apply(aj) }
json = mir.emit_mir_min(aj)
} else {
// Emit Stage1 JSON with metadata
local emitter = new EmitterBox()
local aj2 = ast_json
if do_scopebox == 1 { aj2 = new ScopeBoxInject().apply(aj2) }
if do_loopform == 1 { aj2 = new LoopFormNormalize().apply(aj2) }
json = emitter.emit_program(aj2, me._usings)
}
// Output JSON
local console = new ConsoleBox()
console.println(json)
return 0
}
}