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 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
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user