MIR builder (modularized): fix Call emission to new schema; switch AwaitExpression; drop legacy Array* cases. Tests: fix optimizer test get_block signature. Interpreter: annotate unreachable legacy constructor path in execute_new().

This commit is contained in:
Moe Charm
2025-08-25 19:52:42 +09:00
parent b8e416fb03
commit 8fb99d0763
3 changed files with 22 additions and 50 deletions

View File

@ -106,6 +106,8 @@ impl NyashInterpreter {
} }
// Unified registry is authoritative; legacy implementation removed // Unified registry is authoritative; legacy implementation removed
// NOTE: Legacy constructor path below is unreachable and kept only for reference during migration.
// TODO(migration): remove legacy block after all callsites are confirmed on Unified Registry.
return Err(RuntimeError::UndefinedClass { name: class.to_string() }); return Err(RuntimeError::UndefinedClass { name: class.to_string() });
// Try basic type constructors first // Try basic type constructors first

View File

@ -182,14 +182,22 @@ impl MirBuilder {
for arg in args { for arg in args {
arg_values.push(self.build_expression(arg)?); arg_values.push(self.build_expression(arg)?);
} }
// Prepare function identifier as a const String value id
let func_val = self.value_gen.next();
self.emit_instruction(MirInstruction::Const {
dst: func_val,
value: ConstValue::String(name),
})?;
// Destination for the call result
let dst = self.value_gen.next(); let dst = self.value_gen.next();
// For now, treat all function calls as Box method calls // Emit Call with conservative read effects
self.emit_instruction(MirInstruction::Call { self.emit_instruction(MirInstruction::Call {
dst, dst: Some(dst),
function: name, func: func_val,
arguments: arg_values, args: arg_values,
effects: EffectMask::READ.add(Effect::ReadHeap),
})?; })?;
Ok(dst) Ok(dst)
@ -461,49 +469,11 @@ impl MirBuilder {
self.build_field_access(*object.clone(), field.clone()) self.build_field_access(*object.clone(), field.clone())
}, },
ASTNode::ArrayAccess { array, index, .. } => {
// Build array and index expressions
let array_val = self.build_expression(*array)?;
let index_val = self.build_expression(*index)?;
// Generate ArrayGet instruction
let result = self.value_gen.next();
self.emit_instruction(MirInstruction::ArrayGet {
dst: result,
array: array_val,
index: index_val,
effects: EffectMask::READ.add(Effect::ReadHeap),
})?;
Ok(result)
},
ASTNode::ArrayLiteral { elements, .. } => {
// Create new ArrayBox
let array_val = self.build_new_expression("ArrayBox".to_string(), vec![])?;
// Add each element
for elem in elements {
let elem_val = self.build_expression(elem)?;
// array.push(elem)
self.emit_instruction(MirInstruction::BoxCall {
dst: None,
box_val: array_val,
method: "push".to_string(),
args: vec![elem_val],
effects: EffectMask::WRITE.add(Effect::WriteHeap),
})?;
}
Ok(array_val)
},
ASTNode::New { class, arguments, .. } => { ASTNode::New { class, arguments, .. } => {
self.build_new_expression(class.clone(), arguments.clone()) self.build_new_expression(class.clone(), arguments.clone())
}, },
ASTNode::Await { expression, .. } => { ASTNode::AwaitExpression { expression, .. } => {
self.build_await_expression(*expression) self.build_await_expression(*expression)
}, },

View File

@ -511,7 +511,7 @@ mod tests {
// Ensure TypeOp remains in bb0 // Ensure TypeOp remains in bb0
let f = module.get_function("main").unwrap(); let f = module.get_function("main").unwrap();
let block = f.get_block(&bb0).unwrap(); let block = f.get_block(bb0).unwrap();
let has_typeop = block.all_instructions().any(|i| matches!(i, MirInstruction::TypeOp { .. })); let has_typeop = block.all_instructions().any(|i| matches!(i, MirInstruction::TypeOp { .. }));
assert!(has_typeop, "TypeOp should not be dropped by DCE when used by print"); assert!(has_typeop, "TypeOp should not be dropped by DCE when used by print");
} }