diff --git a/src/ir/generator.rs b/src/ir/generator.rs index 2154867..f51eb25 100644 --- a/src/ir/generator.rs +++ b/src/ir/generator.rs @@ -84,7 +84,10 @@ impl Generator { let temp_parameters = parameters.iter().map(|param| self.var_manager.declare_param_temp(param.data_type)).collect::>(); let mut body_instrs = vec![]; let block_instrs = self.generate_block_stmt(func_decl.body); - for var in self.var_manager.get_cur_scope_variables() { + for var in self.var_manager.get_cur_func_variables() { + if matches!(var.var_type, VariableType::ParamTemp) { + continue; + } body_instrs.push(IRInstr::Declare(var)); } body_instrs.push(IRInstr::Entry); @@ -285,6 +288,7 @@ struct VariableManager { scopes: Vec>, global_counter: usize, local_counter: usize, + local_var_type: Vec, } impl VariableManager { @@ -294,6 +298,7 @@ impl VariableManager { scopes: vec![BTreeSet::new()], global_counter: 0, local_counter: 0, + local_var_type: vec![], } } pub fn enter_scope(&mut self) { @@ -324,8 +329,11 @@ impl VariableManager { } _ => unreachable!(), }; - self.variable_map.entry(name.to_string()).or_default().push(variable.clone()); + self.variable_map.entry(name.to_string()).or_default().push(variable); self.scopes.last_mut().unwrap().insert(name.to_string()); + if matches!(var_type, VariableType::Local) { + self.local_var_type.push(variable); + } Ok(variable) } pub fn declare_gloabal(&mut self, name: &str, var_data_type: IRType) -> Result { @@ -337,18 +345,21 @@ impl VariableManager { pub fn declare_temp(&mut self, var_data_type: IRType) -> Variable { let var = Variable { index: self.local_counter, var_type: VariableType::Temp, data_type: var_data_type }; self.local_counter += 1; + 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 }; self.local_counter += 1; + self.local_var_type.push(var); var } pub fn clear_local_counter(&mut self) { self.local_counter = 0; + self.local_var_type.clear(); } - pub fn get_cur_scope_variables(&self) -> Vec { - self.scopes.last().unwrap().iter().filter_map(|name| self.variable_map.get(name).and_then(|vars| vars.last())).cloned().collect() + pub fn get_cur_func_variables(&self) -> Vec { + self.local_var_type.iter().cloned().collect() } pub fn get_variable(&self, name: &str) -> Option { self.variable_map.get(name).and_then(|vars| vars.last()).cloned() diff --git a/src/ir/types.rs b/src/ir/types.rs index 4329c10..cd7dc86 100644 --- a/src/ir/types.rs +++ b/src/ir/types.rs @@ -19,7 +19,7 @@ impl Display for IRInstr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { IRInstr::Entry => write!(f, "entry"), - IRInstr::Binary(dest, left, op, right) => write!(f, "{} = {} {} {}", dest, op, left, right), + IRInstr::Binary(dest, left, op, right) => write!(f, "{} = {} {},{}", dest, op, left, right), IRInstr::Exit(v) => if let Some(v) = v { write!(f, "exit {}", v) } else { write!(f, "exit") }, IRInstr::FuncCall(func, args, dest) => { if let Some(dest) = dest { @@ -89,7 +89,7 @@ pub struct Variable { impl Display for Variable { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let prefix = match self.var_type { - VariableType::Global => "@", + VariableType::Global => "@g", VariableType::Local => "%l", VariableType::Temp => "%t", VariableType::ParamTemp => "%t",