fix(ir): Binary syntax and func var declare

This commit is contained in:
2026-05-09 20:21:50 +08:00
parent 04284000d6
commit b8d678a634
2 changed files with 17 additions and 6 deletions
+15 -4
View File
@@ -84,7 +84,10 @@ impl Generator {
let temp_parameters = parameters.iter().map(|param| self.var_manager.declare_param_temp(param.data_type)).collect::<Vec<_>>(); let temp_parameters = parameters.iter().map(|param| self.var_manager.declare_param_temp(param.data_type)).collect::<Vec<_>>();
let mut body_instrs = vec![]; let mut body_instrs = vec![];
let block_instrs = self.generate_block_stmt(func_decl.body); 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::Declare(var));
} }
body_instrs.push(IRInstr::Entry); body_instrs.push(IRInstr::Entry);
@@ -285,6 +288,7 @@ struct VariableManager {
scopes: Vec<BTreeSet<String>>, scopes: Vec<BTreeSet<String>>,
global_counter: usize, global_counter: usize,
local_counter: usize, local_counter: usize,
local_var_type: Vec<Variable>,
} }
impl VariableManager { impl VariableManager {
@@ -294,6 +298,7 @@ impl VariableManager {
scopes: vec![BTreeSet::new()], scopes: vec![BTreeSet::new()],
global_counter: 0, global_counter: 0,
local_counter: 0, local_counter: 0,
local_var_type: vec![],
} }
} }
pub fn enter_scope(&mut self) { pub fn enter_scope(&mut self) {
@@ -324,8 +329,11 @@ impl VariableManager {
} }
_ => unreachable!(), _ => 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()); self.scopes.last_mut().unwrap().insert(name.to_string());
if matches!(var_type, VariableType::Local) {
self.local_var_type.push(variable);
}
Ok(variable) Ok(variable)
} }
pub fn declare_gloabal(&mut self, name: &str, var_data_type: IRType) -> Result<Variable, IRError> { pub fn declare_gloabal(&mut self, name: &str, var_data_type: IRType) -> Result<Variable, IRError> {
@@ -337,18 +345,21 @@ impl VariableManager {
pub fn declare_temp(&mut self, var_data_type: IRType) -> Variable { 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 }; let var = Variable { index: self.local_counter, var_type: VariableType::Temp, data_type: var_data_type };
self.local_counter += 1; self.local_counter += 1;
self.local_var_type.push(var);
var var
} }
pub fn declare_param_temp(&mut self, var_data_type: IRType) -> Variable { 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 }; let var = Variable { index: self.local_counter, var_type: VariableType::ParamTemp, data_type: var_data_type };
self.local_counter += 1; self.local_counter += 1;
self.local_var_type.push(var);
var var
} }
pub fn clear_local_counter(&mut self) { pub fn clear_local_counter(&mut self) {
self.local_counter = 0; self.local_counter = 0;
self.local_var_type.clear();
} }
pub fn get_cur_scope_variables(&self) -> Vec<Variable> { pub fn get_cur_func_variables(&self) -> Vec<Variable> {
self.scopes.last().unwrap().iter().filter_map(|name| self.variable_map.get(name).and_then(|vars| vars.last())).cloned().collect() self.local_var_type.iter().cloned().collect()
} }
pub fn get_variable(&self, name: &str) -> Option<Variable> { pub fn get_variable(&self, name: &str) -> Option<Variable> {
self.variable_map.get(name).and_then(|vars| vars.last()).cloned() self.variable_map.get(name).and_then(|vars| vars.last()).cloned()
+2 -2
View File
@@ -19,7 +19,7 @@ impl Display for IRInstr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
IRInstr::Entry => write!(f, "entry"), 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::Exit(v) => if let Some(v) = v { write!(f, "exit {}", v) } else { write!(f, "exit") },
IRInstr::FuncCall(func, args, dest) => { IRInstr::FuncCall(func, args, dest) => {
if let Some(dest) = dest { if let Some(dest) = dest {
@@ -89,7 +89,7 @@ pub struct Variable {
impl Display for Variable { impl Display for Variable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let prefix = match self.var_type { let prefix = match self.var_type {
VariableType::Global => "@", VariableType::Global => "@g",
VariableType::Local => "%l", VariableType::Local => "%l",
VariableType::Temp => "%t", VariableType::Temp => "%t",
VariableType::ParamTemp => "%t", VariableType::ParamTemp => "%t",