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:
nyash-codex
2025-11-27 17:05:46 +09:00
parent 6a5701ead9
commit 588129db65
15 changed files with 1891 additions and 69 deletions

View File

@ -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 への拡張