feat(joinir): Phase 34-6 MethodCall 構造と本物の substring 意味論
**Phase 34-6 実装完了**: MethodCall 構造を JoinIR に追加し、本物の substring
呼び出しを通すことに成功。
## 主要変更
### 1. MethodCall 構造追加 (34-6.1)
- `src/mir/join_ir/mod.rs`: JoinInst::MethodCall バリアント (+8 lines)
- 構造: `{ dst, receiver, method, args }`
- 設計原則: JoinIR は構造のみ、意味論は MIR レベル
### 2. extract_value 更新 (34-6.2)
- `src/mir/join_ir/frontend/ast_lowerer.rs`: Method 処理本物化 (+37 lines)
- receiver/args を extract_value で再帰処理
- ダミー Const(0) 削除 → 本物の MethodCall 生成
- cond 処理修正: ValueId(0) ハードコード → extract_value で取得
### 3. JoinIR→MIR 変換実装 (34-6.3)
- `src/mir/join_ir_vm_bridge.rs`: MethodCall → BoxCall 変換 (+12 lines)
- `src/mir/join_ir/json.rs`: MethodCall JSON シリアライゼーション (+16 lines)
- `src/mir/join_ir_runner.rs`: MethodCall 未対応エラー (+7 lines)
### 4. テスト更新 (34-6.4)
- `docs/.../fixtures/json_shape_read_value.program.json`: 本物の substring 構造
- `src/tests/joinir_frontend_if_select.rs`: run_joinir_via_vm 使用
- テスト成功: v="hello", at=3 → "hel" ✅
## 成果
- ✅ テスト全通過(1 passed; 0 failed)
- ✅ 設計原則確立: JoinIR = 構造 SSOT、意味論 = MIR レベル
- ✅ Phase 33-10 原則との整合性: Method でも同じ原則適用
**ドキュメント更新**: CURRENT_TASK.md + TASKS.md(Phase 34-6 完了記録)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -79,7 +79,7 @@ impl AstToJoinIrLowerer {
|
||||
/// Program(JSON v0) → JoinModule
|
||||
///
|
||||
/// Phase 34-2/34-3/34-4: simple/local/json_shape pattern に対応
|
||||
/// Phase 34-5: extract_value 統一化(Int/Var/Method 対応)
|
||||
/// Phase 34-5: extract_value 統一化(Int/Var/Method 構造まで)
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
@ -112,7 +112,7 @@ impl AstToJoinIrLowerer {
|
||||
/// If Return pattern の共通 lowering
|
||||
///
|
||||
/// Phase 34-2/34-3/34-4: simple/local/json_shape 対応
|
||||
/// Phase 34-5: extract_value ベースに統一(Int/Var/Method 対応)
|
||||
/// Phase 34-5: extract_value ベースに統一(Int/Var/Method 構造まで)
|
||||
///
|
||||
/// - simple: `if cond { return 10 } else { return 20 }`
|
||||
/// - local: `if cond { x=10 } else { x=20 }; return x` (意味論的)
|
||||
@ -192,23 +192,24 @@ impl AstToJoinIrLowerer {
|
||||
ctx.register_param(param_name, crate::mir::ValueId(i as u32));
|
||||
}
|
||||
|
||||
// 6. then/else の expr を extract_value で処理
|
||||
let (then_var, mut then_insts) = self.extract_value(&then_ret["expr"], &mut ctx);
|
||||
// Phase 34-6: cond/then/else の expr を extract_value で処理
|
||||
let (cond_var, cond_insts) = self.extract_value(&if_stmt["cond"], &mut ctx);
|
||||
let (then_var, then_insts) = self.extract_value(&then_ret["expr"], &mut ctx);
|
||||
let (else_var, else_insts) = self.extract_value(&else_ret["expr"], &mut ctx);
|
||||
|
||||
// 7. Select 結果変数を割り当て
|
||||
let result_var = ctx.alloc_var();
|
||||
|
||||
// 8. JoinIR 命令列を組み立て
|
||||
// 8. JoinIR 命令列を組み立て(cond → then → else → Select の順)
|
||||
let mut insts = Vec::new();
|
||||
|
||||
// cond の計算命令を先頭に追加
|
||||
insts.extend(cond_insts);
|
||||
|
||||
// then/else の計算命令を追加
|
||||
insts.extend(then_insts);
|
||||
insts.extend(else_insts);
|
||||
|
||||
// パラメータ: cond (VarId(0))
|
||||
let cond_var = crate::mir::ValueId(0);
|
||||
|
||||
// Select: result = Select(cond, then_var, else_var)
|
||||
insts.push(JoinInst::Select {
|
||||
dst: result_var,
|
||||
@ -315,27 +316,44 @@ impl AstToJoinIrLowerer {
|
||||
(var_id, vec![])
|
||||
}
|
||||
|
||||
// 段階 2: Method 呼び出し対応(最小版 - pattern match のみ)
|
||||
// Phase 34-6: Method 呼び出し構造の完全実装
|
||||
"Method" => {
|
||||
// Phase 34-5: pattern match のみ実装
|
||||
// 実際の JoinIR 生成は Phase 34-6 以降で対応
|
||||
let method = expr["method"]
|
||||
// receiver.method(args...) の構造を抽出
|
||||
let receiver_expr = &expr["receiver"];
|
||||
let method_name = expr["method"]
|
||||
.as_str()
|
||||
.expect("Method must have 'method' field");
|
||||
let args_array = expr["args"]
|
||||
.as_array()
|
||||
.expect("Method must have 'args' array");
|
||||
|
||||
// substring メソッドのパターンマッチ
|
||||
match method {
|
||||
"substring" => {
|
||||
// Phase 34-5: ダミー実装(Int 0 を返す)
|
||||
let dst = ctx.alloc_var();
|
||||
let inst = JoinInst::Compute(crate::mir::join_ir::MirLikeInst::Const {
|
||||
dst,
|
||||
value: ConstValue::Integer(0),
|
||||
});
|
||||
(dst, vec![inst])
|
||||
}
|
||||
_ => panic!("Unsupported method: {}", method),
|
||||
// receiver を extract_value で処理
|
||||
let (receiver_var, mut receiver_insts) = self.extract_value(receiver_expr, ctx);
|
||||
|
||||
// args を extract_value で処理
|
||||
let mut arg_vars = Vec::new();
|
||||
let mut arg_insts = Vec::new();
|
||||
for arg_expr in args_array {
|
||||
let (arg_var, arg_inst) = self.extract_value(arg_expr, ctx);
|
||||
arg_vars.push(arg_var);
|
||||
arg_insts.extend(arg_inst);
|
||||
}
|
||||
|
||||
// MethodCall 命令を生成
|
||||
let dst = ctx.alloc_var();
|
||||
let method_call_inst = JoinInst::MethodCall {
|
||||
dst,
|
||||
receiver: receiver_var,
|
||||
method: method_name.to_string(),
|
||||
args: arg_vars,
|
||||
};
|
||||
|
||||
// すべての命令を結合(receiver → args → MethodCall の順)
|
||||
let mut insts = receiver_insts;
|
||||
insts.extend(arg_insts);
|
||||
insts.push(method_call_inst);
|
||||
|
||||
(dst, insts)
|
||||
}
|
||||
|
||||
_ => panic!("Unsupported expr type: {}", expr_type),
|
||||
@ -352,5 +370,5 @@ impl Default for AstToJoinIrLowerer {
|
||||
// Phase 34-2: IfSelectTest.* simple pattern 実装
|
||||
// Phase 34-3: local pattern 対応(simple と同じ JoinIR 出力)
|
||||
// Phase 34-4: Stage-1/meta 実用関数対応(JsonShapeToMap._read_value_from_pair/1)
|
||||
// Phase 34-5: extract_value 統一化(Int/Var/Method 対応)
|
||||
// Phase 34-6 以降: Loop/Break/Continue の AST→JoinIR 対応
|
||||
// Phase 34-5: extract_value 統一化(Int/Var/Method 構造まで)
|
||||
// Phase 34-6 以降: MethodCall 構造の JoinIR への明示と JoinIR→MIR 変換側での Method/Call 意味論実装、その後 Loop/Break/Continue への拡張
|
||||
|
||||
Reference in New Issue
Block a user