feat(parser,ir,backend): Fully support func params and disable r0-r3 alloc temporarily

This commit is contained in:
2026-05-19 20:10:11 +08:00
parent a5b1cb6c9a
commit 3f64f1a965
6 changed files with 71 additions and 14 deletions
+14 -6
View File
@@ -106,7 +106,9 @@ impl Generator {
Ok(p) => p,
Err(()) => return vec![],
};
let temp_parameters = parameters.iter().map(|param| self.var_manager.declare_param_temp(param.data_type)).collect::<Vec<_>>();
let temp_parameters = parameters.iter().enumerate()
.map(|(i, param)| self.var_manager.declare_param_temp(param.data_type, i))
.collect::<Vec<_>>();
let mut body_instrs = vec![];
self.func_exit = Some((self.request_label(), {
let ret_type = func_decl.return_type.into();
@@ -118,14 +120,14 @@ impl Generator {
}));
let block_instrs = self.generate_block_stmt(func_decl.body);
for var in self.var_manager.get_cur_func_variables() {
if matches!(var.var_type, VariableType::ParamTemp) {
if matches!(var.var_type, VariableType::ParamTemp(_)) {
continue;
}
body_instrs.push(IRInstr::Declare(var));
}
body_instrs.push(IRInstr::Entry);
parameters.iter().zip(temp_parameters.iter()).for_each(|(param, temp_param)| {
body_instrs.push(IRInstr::Move(*temp_param, MoveRValue::Var(*param)));
body_instrs.push(IRInstr::Move(*param, MoveRValue::Var(*temp_param)));
});
body_instrs.extend(block_instrs);
let func_exit = self.func_exit.take().unwrap();
@@ -140,7 +142,7 @@ impl Generator {
return_type: func_decl.return_type.into(),
};
self.function_map.insert(func.name.clone(), func.clone());
vec![IRInstr::DefineFunc(func, parameters, body_instrs)]
vec![IRInstr::DefineFunc(func, temp_parameters, body_instrs)]
}
fn generate_block_stmt(&mut self, block_stmt: BlockStmt) -> Vec<IRInstr> {
let mut instrs = vec![];
@@ -633,7 +635,9 @@ impl Generator {
return None;
}
for (i, arg) in args.into_iter().enumerate() {
self.current_exit_label.push(None);
let (arg_instrs, arg_var) = self.generate_expr(arg)?;
self.current_exit_label.pop();
let parameter_type = func_def.parameter_types.get(i).unwrap();
if *parameter_type != arg_var.map_or(IRType::Void, |v| v.data_type) {
self.diagnostic.add_from_ir_error(IRError::TypeMismatch(*parameter_type, arg_var.map_or(IRType::Void, |v| v.data_type)), expr.span);
@@ -737,8 +741,8 @@ impl VariableManager {
self.local_var_type.push(var);
var
}
pub fn declare_param_temp(&mut self, var_data_type: IRType) -> Variable {
let var = Variable { index: self.local_counter, var_type: VariableType::ParamTemp, data_type: var_data_type };
pub fn declare_param_temp(&mut self, var_data_type: IRType, param_index: usize) -> Variable {
let var = Variable { index: self.local_counter, var_type: VariableType::ParamTemp(param_index), data_type: var_data_type };
self.local_counter += 1;
self.local_var_type.push(var);
var
@@ -830,4 +834,8 @@ mod tests {
fn test_if_while() {
test_case("26-32,34-41,46-51,57");
}
#[test]
fn test_func() {
test_case("12-13,58-60");
}
}
+2 -2
View File
@@ -116,7 +116,7 @@ impl Display for MoveRValue {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum VariableType {
Global,
ParamTemp,
ParamTemp(usize),
Local,
Temp,
}
@@ -155,7 +155,7 @@ impl Display for Variable {
VariableType::Global => "@g",
VariableType::Local => "%l",
VariableType::Temp => "%t",
VariableType::ParamTemp => "%t",
VariableType::ParamTemp(_) => "%t",
};
write!(f, "{}{}", prefix, self.index)
}