fix(joinir): Stage-1 string concat BinOp::Or → Add + ArrayBox support
Fixes: 1. BinOp::Or → BinOp::Add for string concatenation in Stage-1 lowering 2. ArrayBox/MapBox support via JoinValue::BoxRef (ChatGPT implementation) Results: - n=0: JoinIR → "init" ✅ (VM → "void" PHI bug) - n=3: JoinIR → "ABC" ✅ (VM → "void" PHI bug) Stage-1 JoinIR VM Bridge now fully working! 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -252,7 +252,7 @@ fn build_stage1_using_resolver_joinir(module: &crate::mir::MirModule) -> Option<
|
||||
.body
|
||||
.push(JoinInst::Compute(MirLikeInst::BinOp {
|
||||
dst: new_prefix,
|
||||
op: BinOpKind::Or, // String concatenation uses Or in JoinIR
|
||||
op: BinOpKind::Add, // String concatenation uses Add
|
||||
lhs: prefix_loop,
|
||||
rhs: entry_value,
|
||||
}));
|
||||
|
||||
@ -12,7 +12,10 @@
|
||||
// - Phase 30.x: Stage-1 UsingResolver minimal A/B test
|
||||
|
||||
use crate::ast::ASTNode;
|
||||
use crate::backend::VM;
|
||||
use crate::backend::{VM, VMValue};
|
||||
use crate::boxes::array::ArrayBox;
|
||||
use crate::boxes::basic::StringBox;
|
||||
use crate::boxes::map_box::MapBox;
|
||||
use crate::mir::join_ir::lowering::stage1_using_resolver::lower_stage1_usingresolver_to_joinir;
|
||||
use crate::mir::join_ir::JoinFuncId;
|
||||
use crate::mir::join_ir_ops::JoinValue;
|
||||
@ -20,6 +23,24 @@ use crate::mir::join_ir_vm_bridge::run_joinir_via_vm;
|
||||
use crate::mir::MirCompiler;
|
||||
use crate::parser::NyashParser;
|
||||
|
||||
fn join_value_from_box(b: Box<dyn crate::box_trait::NyashBox>) -> JoinValue {
|
||||
let vm_val = VMValue::from_nyash_box(b);
|
||||
JoinValue::from_vm_value(&vm_val).expect("box conversion failed")
|
||||
}
|
||||
|
||||
fn make_entries(values: &[&str]) -> JoinValue {
|
||||
let mut arr = ArrayBox::new();
|
||||
for v in values {
|
||||
let _ = arr.push(Box::new(StringBox::new(*v)));
|
||||
}
|
||||
join_value_from_box(Box::new(arr))
|
||||
}
|
||||
|
||||
fn make_empty_map() -> JoinValue {
|
||||
let map = MapBox::new();
|
||||
join_value_from_box(Box::new(map))
|
||||
}
|
||||
|
||||
/// 実験トグルチェック(モジュール内に閉じ込め)
|
||||
fn require_experiment_toggle() -> bool {
|
||||
if std::env::var("NYASH_JOINIR_VM_BRIDGE").ok().as_deref() != Some("1") {
|
||||
@ -245,28 +266,16 @@ fn joinir_vm_bridge_stage1_usingresolver_route_b_execution() {
|
||||
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] JoinIR module created: {} functions", join_module.functions.len());
|
||||
|
||||
// Stage-1 JoinIR の引数:
|
||||
// resolve_entries(entries, n, modules, seen, prefix_init)
|
||||
// - entries: ArrayBox (JoinValue 未対応)
|
||||
// - n: Integer
|
||||
// - modules: MapBox (JoinValue 未対応)
|
||||
// - seen: MapBox (JoinValue 未対応)
|
||||
// - prefix_init: String
|
||||
//
|
||||
// n=0 の場合、ループは実行されないので entries/modules/seen にアクセスしない
|
||||
// → Int(0) で呼び出してみて、何が起こるか確認
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] Attempting run_joinir_via_vm with n=0");
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] Note: ArrayBox/MapBox args passed as Int(0) placeholder");
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] Attempting run_joinir_via_vm with n=0 (Array/Map supported)");
|
||||
|
||||
// JoinIR bridge 呼び出し - どこで止まるか観察
|
||||
let result = run_joinir_via_vm(
|
||||
&join_module,
|
||||
JoinFuncId::new(0),
|
||||
&[
|
||||
JoinValue::Int(0), // entries placeholder (should not be accessed if n=0)
|
||||
JoinValue::Int(0), // n = 0 (loop won't execute)
|
||||
JoinValue::Int(0), // modules placeholder
|
||||
JoinValue::Int(0), // seen placeholder
|
||||
make_entries(&[]),
|
||||
JoinValue::Int(0), // n = 0 (loop won't execute)
|
||||
make_empty_map(),
|
||||
make_empty_map(),
|
||||
JoinValue::Str("init".to_string()), // prefix_init
|
||||
],
|
||||
);
|
||||
@ -275,22 +284,24 @@ fn joinir_vm_bridge_stage1_usingresolver_route_b_execution() {
|
||||
Ok(value) => {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] ✅ Execution succeeded: {:?}", value);
|
||||
// n=0 の場合、ループは実行されず prefix_init がそのまま返るはず
|
||||
match value {
|
||||
match &value {
|
||||
JoinValue::Str(s) => {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] Result: {:?}", s);
|
||||
if s == "init" {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] ✅ JoinIR returned correct 'init'!");
|
||||
} else {
|
||||
panic!("expected 'init', got {}", s);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] Unexpected result type: {:?}", value);
|
||||
panic!("Unexpected result type: {:?}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] ❌ Execution failed: {:?}", e);
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b] This error shows where VM bridge needs extension");
|
||||
// エラーが出ても panic しない - 何が足りないかの情報を得るため
|
||||
panic!("JoinIR bridge failed: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,10 +348,10 @@ fn joinir_vm_bridge_stage1_usingresolver_route_b_with_entries() {
|
||||
&join_module,
|
||||
JoinFuncId::new(0),
|
||||
&[
|
||||
JoinValue::Int(0), // entries - Int(0) では get() 失敗するはず
|
||||
make_entries(&["A", "B", "C"]),
|
||||
JoinValue::Int(3), // n = 3 (loop will execute 3 times)
|
||||
JoinValue::Int(0), // modules placeholder
|
||||
JoinValue::Int(0), // seen placeholder
|
||||
make_empty_map(),
|
||||
make_empty_map(),
|
||||
JoinValue::Str("".to_string()), // prefix_init = ""
|
||||
],
|
||||
);
|
||||
@ -354,18 +365,17 @@ fn joinir_vm_bridge_stage1_usingresolver_route_b_with_entries() {
|
||||
if s == "ABC" {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b_with_entries] ✅ JoinIR returned correct 'ABC'!");
|
||||
} else {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b_with_entries] ⚠️ Got '{}' (possibly partial or wrong)", s);
|
||||
panic!("expected 'ABC', got {}", s);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b_with_entries] Unexpected result type: {:?}", value);
|
||||
panic!("[joinir_vm_bridge_test/stage1/route_b_with_entries] Unexpected result type: {:?}", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b_with_entries] ❌ Execution failed: {:?}", e);
|
||||
eprintln!("[joinir_vm_bridge_test/stage1/route_b_with_entries] This shows ArrayBox/BoxCall needs JoinIR extension");
|
||||
// エラーを期待通り - ArrayBox サポートが必要なことを確認
|
||||
panic!("JoinIR bridge failed: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user