📚 Phase 15 - セルフホスティング戦略の明確化とEXE-first実装
## 主な変更点 ### 🎯 戦略の転換と明確化 - PyVMを開発ツールとして位置づけ(本番経路ではない) - EXE-first戦略を明確に優先(build_compiler_exe.sh実装済み) - Phase順序の整理: 15.2(LLVM)→15.3(コンパイラ)→15.4(VM) ### 🚀 セルフホスティング基盤の実装 - apps/selfhost-compiler/にNyashコンパイラMVP実装 - compiler.nyash: メインエントリー(位置引数対応) - boxes/: parser_box, emitter_box, debug_box分離 - tools/build_compiler_exe.sh: ネイティブEXEビルド+dist配布 - Python MVPパーサーStage-2完成(local/if/loop/call/method/new) ### 📝 ドキュメント整備 - Phase 15 README/ROADMAP更新(Self-Hosting優先明記) - docs/guides/exe-first-wsl.md: WSLクイックスタート追加 - docs/private/papers/: 論文G~L、爆速事件簿41事例収録 ### 🔧 技術的改善 - JSON v0 Bridge: If/Loop PHI生成実装(ChatGPT協力) - PyVM/llvmliteパリティ検証スイート追加 - using/namespace機能(gated実装、Phase 15では非解決) ## 次のステップ 1. パーサー無限ループ修正(未実装関数の実装) 2. EXEビルドとセルフホスティング実証 3. c0→c1→c1'ブートストラップループ確立 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -180,6 +180,7 @@ fn lower_expr(f: &mut MirFunction, cur_bb: BasicBlockId, e: &ExprV0) -> Result<(
|
||||
"shortcircuit",
|
||||
"<json_v0>"
|
||||
);
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") { eprintln!("[bridge/logical] op={} rhs_bb={} fall_bb={} merge_bb={}", if is_and {"and"} else {"or"}, rhs_bb.0, fall_bb.0, merge_bb.0); }
|
||||
// false/true constant in fall_bb depending on op
|
||||
let cdst = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(fall_bb) {
|
||||
@ -187,15 +188,16 @@ fn lower_expr(f: &mut MirFunction, cur_bb: BasicBlockId, e: &ExprV0) -> Result<(
|
||||
bb.add_instruction(MirInstruction::Const { dst: cdst, value: cval });
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
}
|
||||
// evaluate rhs in rhs_bb
|
||||
let (rval, _rhs_end) = lower_expr(f, rhs_bb, rhs)?;
|
||||
if let Some(bb) = f.get_block_mut(rhs_bb) {
|
||||
// evaluate rhs starting at rhs_bb and ensure the terminal block jumps to merge
|
||||
let (rval, rhs_end) = lower_expr(f, rhs_bb, rhs)?;
|
||||
if let Some(bb) = f.get_block_mut(rhs_end) {
|
||||
if !bb.is_terminated() { bb.set_terminator(MirInstruction::Jump { target: merge_bb }); }
|
||||
}
|
||||
// merge with phi
|
||||
if std::env::var("NYASH_CLI_VERBOSE").ok().as_deref() == Some("1") { eprintln!("[bridge/logical] rhs_end={} jump->merge_bb={}", rhs_end.0, merge_bb.0); }
|
||||
// merge with phi (use actual predecessors rhs_end and fall_bb)
|
||||
let out = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(merge_bb) {
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs: vec![(rhs_bb, rval), (fall_bb, cdst)] });
|
||||
bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs: vec![(rhs_end, rval), (fall_bb, cdst)] });
|
||||
}
|
||||
Ok((out, merge_bb))
|
||||
}
|
||||
@ -213,6 +215,16 @@ fn lower_expr(f: &mut MirFunction, cur_bb: BasicBlockId, e: &ExprV0) -> Result<(
|
||||
Ok((dst, cur))
|
||||
}
|
||||
ExprV0::Method { recv, method, args } => {
|
||||
// Heuristic: new ConsoleBox().println(x) → externcall env.console.log(x)
|
||||
let recv_is_console_new = matches!(&**recv, ExprV0::New { class, .. } if class == "ConsoleBox");
|
||||
if recv_is_console_new && (method == "println" || method == "print" || method == "log") {
|
||||
let (arg_ids, cur2) = lower_args(f, cur_bb, args)?;
|
||||
let dst = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(cur2) {
|
||||
bb.add_instruction(MirInstruction::ExternCall { dst: Some(dst), iface_name: "env.console".into(), method_name: "log".into(), args: arg_ids, effects: EffectMask::READ });
|
||||
}
|
||||
return Ok((dst, cur2));
|
||||
}
|
||||
let (recv_v, cur) = lower_expr(f, cur_bb, recv)?;
|
||||
let (arg_ids, cur2) = lower_args(f, cur, args)?;
|
||||
let dst = f.next_value_id();
|
||||
@ -275,6 +287,15 @@ fn lower_expr_with_vars(
|
||||
Ok((dst, cur))
|
||||
}
|
||||
ExprV0::Method { recv, method, args } => {
|
||||
let recv_is_console_new = matches!(&**recv, ExprV0::New { class, .. } if class == "ConsoleBox");
|
||||
if recv_is_console_new && (method == "println" || method == "print" || method == "log") {
|
||||
let (arg_ids, cur2) = lower_args_with_vars(f, cur_bb, args, vars)?;
|
||||
let dst = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(cur2) {
|
||||
bb.add_instruction(MirInstruction::ExternCall { dst: Some(dst), iface_name: "env.console".into(), method_name: "log".into(), args: arg_ids, effects: EffectMask::READ });
|
||||
}
|
||||
return Ok((dst, cur2));
|
||||
}
|
||||
let (recv_v, cur) = lower_expr_with_vars(f, cur_bb, recv, vars)?;
|
||||
let (arg_ids, cur2) = lower_args_with_vars(f, cur, args, vars)?;
|
||||
let dst = f.next_value_id();
|
||||
@ -341,10 +362,10 @@ fn lower_expr_with_vars(
|
||||
bb.add_instruction(MirInstruction::Const { dst: cdst, value: cval });
|
||||
bb.set_terminator(MirInstruction::Jump { target: merge_bb });
|
||||
}
|
||||
let (rval, _rhs_end) = lower_expr_with_vars(f, rhs_bb, rhs, vars)?;
|
||||
if let Some(bb) = f.get_block_mut(rhs_bb) { if !bb.is_terminated() { bb.set_terminator(MirInstruction::Jump { target: merge_bb }); } }
|
||||
let (rval, rhs_end) = lower_expr_with_vars(f, rhs_bb, rhs, vars)?;
|
||||
if let Some(bb) = f.get_block_mut(rhs_end) { if !bb.is_terminated() { bb.set_terminator(MirInstruction::Jump { target: merge_bb }); } }
|
||||
let out = f.next_value_id();
|
||||
if let Some(bb) = f.get_block_mut(merge_bb) { bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs: vec![(rhs_bb, rval), (fall_bb, cdst)] }); }
|
||||
if let Some(bb) = f.get_block_mut(merge_bb) { bb.insert_instruction_after_phis(MirInstruction::Phi { dst: out, inputs: vec![(rhs_end, rval), (fall_bb, cdst)] }); }
|
||||
Ok((out, merge_bb))
|
||||
}
|
||||
_ => lower_expr(f, cur_bb, e),
|
||||
@ -603,7 +624,8 @@ fn lex(input: &str) -> Result<Vec<Tok>, String> {
|
||||
let mut toks = Vec::new();
|
||||
while i < n {
|
||||
let c = bytes[i] as char;
|
||||
if c.is_whitespace() { i += 1; continue; }
|
||||
// Treat semicolon as whitespace (Stage-1 minimal ASI: optional ';')
|
||||
if c.is_whitespace() || c == ';' { i += 1; continue; }
|
||||
match c {
|
||||
'+' => { toks.push(Tok::Plus); i+=1; }
|
||||
'-' => { toks.push(Tok::Minus); i+=1; }
|
||||
|
||||
Reference in New Issue
Block a user