feat(parser,ir,backend): Fully support func params and disable r0-r3 alloc temporarily
This commit is contained in:
+14
-6
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user