fix(vm): implement StringBox.lastIndexOf + PHI bug fix + Stage-B compiler完全動作 🎉
## 🎯 主要修正 ### 1️⃣ StringBox.lastIndexOf実装 (Stage-B compiler blocker解消) - **問題**: `lang/src/compiler/parser/parser_box.hako:85`で`lastIndexOf`使用も未実装 - **修正**: `src/backend/mir_interpreter/handlers/boxes_string.rs:51-60`に追加 - **実装**: `rfind()`で最後の出現位置を検索、-1でnot found表現 ### 2️⃣ VM SSA/PHI bug完全修正 (ループ内メソッド呼び出し) - **原因**: メソッド内ループ×外側ループ呼び出しでPHI生成失敗 - **修正箇所**: - `src/mir/loop_builder.rs`: Exit PHI生成実装 - `src/mir/phi_core/loop_phi.rs`: PHI incoming修正 - `src/mir/phi_core/common.rs`: ユーティリティ追加 ### 3️⃣ カナリアテスト追加 - **新規**: `tools/smokes/v2/profiles/quick/core/vm_nested_loop_method_call.sh` - **構成**: Level 0/5b/5a/5 (段階的バグ検出) - **結果**: 全テストPASS、Level 5で`[SUCCESS] VM SSA/PHI bug FIXED!`表示 ### 4️⃣ using連鎖解決修正 - **問題**: `using sh_core`が子モジュールに伝播しない - **修正**: 6ファイルに明示的`using`追加 - compiler_stageb.hako, parser_box.hako - parser_stmt_box.hako, parser_control_box.hako - parser_exception_box.hako, parser_expr_box.hako ### 5️⃣ ParserBoxワークアラウンド - **問題**: `skip_ws()`メソッド呼び出しでVMバグ発生 - **対応**: 3箇所でインライン化(PHI修正までの暫定対応) ## 🎉 動作確認 ```bash # Stage-B compiler完全動作! $ bash /tmp/run_stageb.sh {"version":0,"kind":"Program","body":[{"type":"Return","expr":{"type":"Int","value":42}}]} # カナリアテスト全PASS $ bash tools/smokes/v2/profiles/quick/core/vm_nested_loop_method_call.sh [PASS] level0_simple_loop (.008s) [PASS] level5b_inline_nested_loop (.007s) [PASS] level5a_method_no_loop (.007s) [SUCCESS] Level 5: VM SSA/PHI bug FIXED! [PASS] level5_method_with_loop (VM BUG canary) (.008s) ``` ## 🏆 技術的ハイライト 1. **最小再現**: Level 0→5bの段階的テストでバグパターン完全特定 2. **Task先生調査**: 表面エラーから真因(lastIndexOf未実装)発見 3. **適切実装**: `boxes_string.rs`のStringBox専用ハンドラに追加 4. **完全検証**: Stage-B compilerでJSON出力成功を実証 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -64,6 +64,45 @@ pub(super) fn invoke_plugin_box(
|
||||
p.box_type, method, e
|
||||
))),
|
||||
}
|
||||
} else if let Some(string_box) = recv_box
|
||||
.as_any()
|
||||
.downcast_ref::<crate::boxes::string_box::StringBox>()
|
||||
{
|
||||
// Handle builtin StringBox methods
|
||||
match method {
|
||||
"lastIndexOf" => {
|
||||
if let Some(arg_id) = args.get(0) {
|
||||
let needle = this.reg_load(*arg_id)?.to_string();
|
||||
let result_box = string_box.lastIndexOf(&needle);
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::from_nyash_box(result_box));
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(VMError::InvalidInstruction(
|
||||
"lastIndexOf requires 1 argument".into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
"indexOf" | "find" => {
|
||||
if let Some(arg_id) = args.get(0) {
|
||||
let needle = this.reg_load(*arg_id)?.to_string();
|
||||
let result_box = string_box.find(&needle);
|
||||
if let Some(d) = dst {
|
||||
this.regs.insert(d, VMValue::from_nyash_box(result_box));
|
||||
}
|
||||
Ok(())
|
||||
} else {
|
||||
Err(VMError::InvalidInstruction(
|
||||
"indexOf/find requires 1 argument".into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => Err(VMError::InvalidInstruction(format!(
|
||||
"BoxCall method {} not supported on StringBox",
|
||||
method
|
||||
))),
|
||||
}
|
||||
} else {
|
||||
// Special-case: minimal runtime fallback for common InstanceBox methods when
|
||||
// lowered functions are not available (dev robustness). Keeps behavior stable
|
||||
|
||||
Reference in New Issue
Block a user