diff --git a/docs/private b/docs/private index 905e8521..bd16c39e 160000 --- a/docs/private +++ b/docs/private @@ -1 +1 @@ -Subproject commit 905e8521c9ebe41fce6bfb4705e787d2288706e9 +Subproject commit bd16c39e699b0a189839b1559932bb9d63fb0c20 diff --git a/src/mir/join_ir/frontend/ast_lowerer/expr.rs b/src/mir/join_ir/frontend/ast_lowerer/expr.rs index 7962cd2a..e400c484 100644 --- a/src/mir/join_ir/frontend/ast_lowerer/expr.rs +++ b/src/mir/join_ir/frontend/ast_lowerer/expr.rs @@ -187,6 +187,65 @@ impl AstToJoinIrLowerer { (dst, insts) } + // Phase 51: フィールドアクセス対応(me.tokens 等) + "Field" => { + let object_expr = &expr["object"]; + let field_name = expr["field"] + .as_str() + .expect("Field must have 'field' string"); + + // object を再帰的に extract_value + let (object_var, object_insts) = self.extract_value(object_expr, ctx); + + // 結果変数を割り当て + let dst = ctx.alloc_var(); + + // FieldAccess 命令を生成 + let field_inst = JoinInst::FieldAccess { + dst, + object: object_var, + field: field_name.to_string(), + }; + + let mut insts = object_insts; + insts.push(field_inst); + + (dst, insts) + } + + // Phase 51: NewBox 対応(new ArrayBox() 等) + "NewBox" => { + let box_name = expr["box_name"] + .as_str() + .expect("NewBox must have 'box_name' string"); + let empty_args = vec![]; + let args_array = expr["args"].as_array().unwrap_or(&empty_args); + + // 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); + } + + // 結果変数を割り当て + let dst = ctx.alloc_var(); + + // NewBox 命令を生成 + let newbox_inst = JoinInst::NewBox { + dst, + box_name: box_name.to_string(), + args: arg_vars, + }; + + let mut insts = arg_insts; + insts.push(newbox_inst); + + (dst, insts) + } + _ => panic!("Unsupported expr type: {}", expr_type), } } diff --git a/src/mir/join_ir/json.rs b/src/mir/join_ir/json.rs index ee855b7a..dd30cebf 100644 --- a/src/mir/join_ir/json.rs +++ b/src/mir/join_ir/json.rs @@ -231,6 +231,33 @@ fn write_inst(inst: &JoinInst, out: &mut W) -> std::io::Result<()> { } write!(out, "}}")?; } + // Phase 51: FieldAccess instruction JSON serialization + JoinInst::FieldAccess { dst, object, field } => { + write!(out, "{{\"type\":\"field_access\"")?; + write!(out, ",\"dst\":{}", dst.0)?; + write!(out, ",\"object\":{}", object.0)?; + write!(out, ",\"field\":\"{}\"", escape_json_string(field))?; + write!(out, "}}")?; + } + // Phase 51: NewBox instruction JSON serialization + JoinInst::NewBox { + dst, + box_name, + args, + } => { + write!(out, "{{\"type\":\"new_box\"")?; + write!(out, ",\"dst\":{}", dst.0)?; + write!(out, ",\"box_name\":\"{}\"", escape_json_string(box_name))?; + write!(out, ",\"args\":[")?; + for (i, arg) in args.iter().enumerate() { + if i > 0 { + write!(out, ",")?; + } + write!(out, "{}", arg.0)?; + } + write!(out, "]")?; + write!(out, "}}")?; + } JoinInst::Compute(mir_like) => { write!(out, "{{\"type\":\"compute\",\"op\":")?; write_mir_like_inst(mir_like, out)?; diff --git a/src/mir/join_ir/mod.rs b/src/mir/join_ir/mod.rs index e4ed9551..29c83f94 100644 --- a/src/mir/join_ir/mod.rs +++ b/src/mir/join_ir/mod.rs @@ -322,6 +322,24 @@ pub enum JoinInst { args: Vec, }, + /// Phase 51: フィールドアクセス + /// object.field の構造を JoinIR で表現 + /// MIR 変換時に Load 命令に変換 + FieldAccess { + dst: VarId, + object: VarId, + field: String, + }, + + /// Phase 51: Box インスタンス生成 + /// new BoxName(args...) の構造を JoinIR で表現 + /// MIR 変換時に NewBox 命令に変換 + NewBox { + dst: VarId, + box_name: String, + args: Vec, + }, + /// Phase 41-4: 深いネスト if の複数変数 merge(else なし) /// /// # Pattern diff --git a/src/mir/join_ir_runner.rs b/src/mir/join_ir_runner.rs index 319e2a32..5a6851d3 100644 --- a/src/mir/join_ir_runner.rs +++ b/src/mir/join_ir_runner.rs @@ -225,6 +225,22 @@ fn execute_function( "NestedIfMerge is not supported in JoinIR Runner (use JoinIR→MIR→VM bridge instead)" )); } + // Phase 51: FieldAccess instruction execution + JoinInst::FieldAccess { .. } => { + // Phase 51: FieldAccess は JoinIR Runner では未対応 + // JoinIR → MIR 変換経由で VM が実行する + return Err(JoinRuntimeError::new( + "FieldAccess is not supported in JoinIR Runner (use JoinIR→MIR→VM bridge instead)" + )); + } + // Phase 51: NewBox instruction execution + JoinInst::NewBox { .. } => { + // Phase 51: NewBox は JoinIR Runner では未対応 + // JoinIR → MIR 変換経由で VM が実行する + return Err(JoinRuntimeError::new( + "NewBox is not supported in JoinIR Runner (use JoinIR→MIR→VM bridge instead)" + )); + } } } diff --git a/src/mir/join_ir_vm_bridge/convert.rs b/src/mir/join_ir_vm_bridge/convert.rs index 3a2bd0dc..4bb41e84 100644 --- a/src/mir/join_ir_vm_bridge/convert.rs +++ b/src/mir/join_ir_vm_bridge/convert.rs @@ -217,6 +217,33 @@ pub(crate) fn convert_join_function_to_mir( }; current_instructions.push(mir_inst); } + // Phase 51: FieldAccess → MIR BoxCall (getter pattern) + JoinInst::FieldAccess { dst, object, field } => { + // object.field を BoxCall(object, field, []) に変換 + // フィールドアクセスはメソッド呼び出しとして扱う(getter pattern) + let mir_inst = MirInstruction::BoxCall { + dst: Some(*dst), + box_val: *object, + method: field.clone(), + method_id: None, + args: vec![], + effects: EffectMask::PURE, + }; + current_instructions.push(mir_inst); + } + // Phase 51: NewBox → MIR NewBox + JoinInst::NewBox { + dst, + box_name, + args, + } => { + let mir_inst = MirInstruction::NewBox { + dst: *dst, + box_type: box_name.clone(), + args: args.clone(), + }; + current_instructions.push(mir_inst); + } JoinInst::Call { func, args,