fix(ir): Binary syntax and func var declare
This commit is contained in:
+15
-4
@@ -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 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<BTreeSet<String>>,
|
||||
global_counter: usize,
|
||||
local_counter: usize,
|
||||
local_var_type: Vec<Variable>,
|
||||
}
|
||||
|
||||
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<Variable, IRError> {
|
||||
@@ -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<Variable> {
|
||||
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<Variable> {
|
||||
self.local_var_type.iter().cloned().collect()
|
||||
}
|
||||
pub fn get_variable(&self, name: &str) -> Option<Variable> {
|
||||
self.variable_map.get(name).and_then(|vars| vars.last()).cloned()
|
||||
|
||||
+2
-2
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user