Implement block/statement interference graph algorithm.

This commit is contained in:
Jesse Brault 2026-03-05 20:41:25 -06:00
parent c91bb35d8d
commit 272d288213
18 changed files with 334 additions and 47 deletions

View File

@ -5,7 +5,6 @@ use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_operation::IrOperation; use crate::ir::ir_operation::IrOperation;
use crate::ir::ir_statement::IrStatement; use crate::ir::ir_statement::IrStatement;
use crate::ir::ir_variable::IrVariable; use crate::ir::ir_variable::IrVariable;
use crate::symbol::ExpressibleSymbol;
use crate::symbol_table::SymbolTable; use crate::symbol_table::SymbolTable;
use crate::type_info::TypeInfo; use crate::type_info::TypeInfo;
@ -40,7 +39,7 @@ pub fn expression_to_ir_expression(
} }
Expression::Identifier(identifier) => { Expression::Identifier(identifier) => {
let expressible_symbol = identifier.expressible_symbol(); let expressible_symbol = identifier.expressible_symbol();
Some(IrExpression::Variable(expressible_symbol.ir_variable())) Some(expressible_symbol.ir_expression())
} }
Expression::Additive(additive_expression) => { Expression::Additive(additive_expression) => {
let ir_add = additive_expression.to_ir(builder, symbol_table); let ir_add = additive_expression.to_ir(builder, symbol_table);

View File

@ -7,6 +7,7 @@ use crate::ast::type_use::TypeUse;
use crate::constants_table::ConstantsTable; use crate::constants_table::ConstantsTable;
use crate::diagnostic::Diagnostic; use crate::diagnostic::Diagnostic;
use crate::ir::ir_function::IrFunction; use crate::ir::ir_function::IrFunction;
use crate::ir::ir_parameter::IrParameter;
use crate::ir::ir_variable::IrVariable; use crate::ir::ir_variable::IrVariable;
use crate::source_range::SourceRange; use crate::source_range::SourceRange;
use crate::symbol::FunctionSymbol; use crate::symbol::FunctionSymbol;
@ -167,13 +168,13 @@ impl Function {
// parameters // parameters
for parameter in &self.parameters { for parameter in &self.parameters {
let parameter_symbol = parameter.parameter_symbol(); let parameter_symbol = parameter.parameter_symbol();
let ir_variable = IrVariable::new( let ir_parameter = IrParameter::new(
parameter_symbol.borrow().name(), parameter_symbol.borrow().name(),
parameter_symbol.borrow().type_info().clone(), parameter_symbol.borrow().type_info().clone(),
); );
let as_rc = Rc::new(RefCell::new(ir_variable)); let as_rc = Rc::new(ir_parameter);
builder.parameters_mut().push(as_rc.clone()); builder.parameters_mut().push(as_rc.clone());
parameter_symbol.borrow_mut().set_ir_variable(as_rc); parameter_symbol.borrow_mut().set_ir_parameter(as_rc);
} }
let entry_block_id = builder.new_block(); let entry_block_id = builder.new_block();

View File

@ -1,4 +1,5 @@
use crate::ir::ir_block::IrBlock; use crate::ir::ir_block::IrBlock;
use crate::ir::ir_parameter::IrParameter;
use crate::ir::ir_statement::IrStatement; use crate::ir::ir_statement::IrStatement;
use crate::ir::ir_variable::IrVariable; use crate::ir::ir_variable::IrVariable;
use std::cell::RefCell; use std::cell::RefCell;
@ -6,7 +7,7 @@ use std::collections::HashMap;
use std::rc::Rc; use std::rc::Rc;
pub struct IrBuilder { pub struct IrBuilder {
parameters: Vec<Rc<RefCell<IrVariable>>>, parameters: Vec<Rc<IrParameter>>,
block_counter: usize, block_counter: usize,
t_var_counter: usize, t_var_counter: usize,
blocks: HashMap<usize, Rc<RefCell<IrBlock>>>, blocks: HashMap<usize, Rc<RefCell<IrBlock>>>,
@ -24,11 +25,11 @@ impl IrBuilder {
} }
} }
pub fn parameters(&self) -> &[Rc<RefCell<IrVariable>>] { pub fn parameters(&self) -> &[Rc<IrParameter>] {
&self.parameters &self.parameters
} }
pub fn parameters_mut(&mut self) -> &mut Vec<Rc<RefCell<IrVariable>>> { pub fn parameters_mut(&mut self) -> &mut Vec<Rc<IrParameter>> {
&mut self.parameters &mut self.parameters
} }
@ -86,6 +87,6 @@ impl IrBlockBuilder {
} }
pub fn build(self) -> IrBlock { pub fn build(self) -> IrBlock {
IrBlock::new(self.id, &format!("b{}:", self.id), self.statements) IrBlock::new(self.id, &format!("b{}", self.id), self.statements)
} }
} }

View File

@ -96,9 +96,9 @@ impl LetStatement {
Expression::String(string_literal) => { Expression::String(string_literal) => {
IrOperation::Load(IrExpression::String(string_literal.content().into())) IrOperation::Load(IrExpression::String(string_literal.content().into()))
} }
Expression::Identifier(identifier) => IrOperation::Load(IrExpression::Variable( Expression::Identifier(identifier) => {
identifier.expressible_symbol().ir_variable(), IrOperation::Load(identifier.expressible_symbol().ir_expression())
)), }
Expression::Additive(additive_expression) => { Expression::Additive(additive_expression) => {
IrOperation::Add(additive_expression.to_ir(builder, symbol_table)) IrOperation::Add(additive_expression.to_ir(builder, symbol_table))
} }

View File

@ -1,5 +1,8 @@
use crate::ir::ir_expression::IrExpression; use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_variable::IrVariable;
use std::collections::HashSet;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc;
pub struct IrAdd { pub struct IrAdd {
left: Box<IrExpression>, left: Box<IrExpression>,
@ -20,3 +23,12 @@ impl Display for IrAdd {
write!(f, "{} + {}", self.left, self.right) write!(f, "{} + {}", self.left, self.right)
} }
} }
impl IrAdd {
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
let mut set = HashSet::new();
set.extend(self.left.uses());
set.extend(self.right.uses());
set
}
}

View File

@ -1,25 +1,33 @@
use crate::ir::ir_operation::IrOperation; use crate::ir::ir_operation::IrOperation;
use crate::ir::ir_variable::IrVariable; use crate::ir::ir_variable::IrVariable;
use std::cell::RefCell; use std::collections::HashSet;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc; use std::rc::Rc;
pub struct IrAssign { pub struct IrAssign {
destination: Rc<RefCell<IrVariable>>, destination: Rc<IrVariable>,
initializer: Box<IrOperation>, initializer: Box<IrOperation>,
} }
impl IrAssign { impl IrAssign {
pub fn new(destination: IrVariable, initializer: IrOperation) -> Self { pub fn new(destination: IrVariable, initializer: IrOperation) -> Self {
Self { Self {
destination: Rc::new(RefCell::new(destination)), destination: Rc::new(destination),
initializer: initializer.into(), initializer: initializer.into(),
} }
} }
pub fn destination(&self) -> &Rc<RefCell<IrVariable>> { pub fn destination(&self) -> &Rc<IrVariable> {
&self.destination &self.destination
} }
pub fn initializer(&self) -> &IrOperation {
&self.initializer
}
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
self.initializer.uses()
}
} }
impl Display for IrAssign { impl Display for IrAssign {
@ -27,8 +35,8 @@ impl Display for IrAssign {
write!( write!(
f, f,
"{}: {} = {}", "{}: {} = {}",
self.destination.borrow(), self.destination,
self.destination.borrow().type_info(), self.destination.type_info(),
self.initializer self.initializer
) )
} }

View File

@ -1,5 +1,7 @@
use crate::ir::ir_statement::IrStatement; use crate::ir::ir_statement::IrStatement;
use crate::ir::ir_variable::IrVariable;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::{HashMap, HashSet};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc; use std::rc::Rc;
@ -29,14 +31,136 @@ impl IrBlock {
pub fn statements(&self) -> &[IrStatement] { pub fn statements(&self) -> &[IrStatement] {
&self.statements &self.statements
} }
fn definitions(&self) -> HashSet<Rc<IrVariable>> {
let mut set = HashSet::new();
for statement in &self.statements {
set.extend(statement.definitions())
}
set
}
fn uses(&self) -> HashSet<Rc<IrVariable>> {
let mut set = HashSet::new();
for statement in &self.statements {
set.extend(statement.uses());
}
set
}
fn live_in_live_out(
&self,
) -> (
HashMap<usize, HashSet<Rc<IrVariable>>>,
HashMap<usize, HashSet<Rc<IrVariable>>>,
) {
let mut live_in: HashMap<usize, HashSet<Rc<IrVariable>>> = HashMap::new();
let mut live_out: HashMap<usize, HashSet<Rc<IrVariable>>> = HashMap::new();
loop {
let mut did_work = false;
for (statement_index, statement) in self.statements.iter().enumerate().rev() {
// init if necessary
if !live_in.contains_key(&statement_index) {
live_in.insert(statement_index, HashSet::new());
}
if !live_out.contains_key(&statement_index) {
live_out.insert(statement_index, HashSet::new());
}
// out (union of successors ins)
// for now, a statement can only have one successor
// this will need to be updated when we add jumps
if let Some(successor_live_in) = live_in.get(&(statement_index + 1)) {
let statement_live_out = live_out.get_mut(&statement_index).unwrap();
for ir_variable in successor_live_in {
if statement_live_out.insert(ir_variable.clone()) {
did_work = true;
}
}
}
// in: use(s) U ( out(s) - def(s) )
let mut new_ins = statement.uses();
let statement_live_out = live_out.get(&statement_index).unwrap();
let defs = statement.definitions();
let rhs = statement_live_out - &defs;
new_ins.extend(rhs);
let statement_live_in = live_in.get_mut(&statement_index).unwrap();
for new_in in new_ins {
if statement_live_in.insert(new_in) {
did_work = true;
}
}
}
if !did_work {
break;
}
}
(live_in, live_out)
}
fn interference_graph(&self) -> HashMap<Rc<IrVariable>, HashSet<Rc<IrVariable>>> {
let mut all_variables: HashSet<Rc<IrVariable>> = HashSet::new();
for statement in &self.statements {
all_variables.extend(statement.definitions());
all_variables.extend(statement.uses());
}
let mut graph: HashMap<Rc<IrVariable>, HashSet<Rc<IrVariable>>> = HashMap::new();
for variable in all_variables {
graph.insert(variable, HashSet::new());
}
let (_, live_out) = self.live_in_live_out();
for (statement_index, statement) in self.statements.iter().enumerate() {
let statement_live_out = live_out.get(&statement_index).unwrap();
for definition_variable in statement.definitions() {
for live_out_variable in statement_live_out {
if definition_variable != *live_out_variable {
graph
.get_mut(&definition_variable)
.unwrap()
.insert(live_out_variable.clone());
graph
.get_mut(live_out_variable)
.unwrap()
.insert(definition_variable.clone());
}
}
}
}
graph
}
} }
impl Display for IrBlock { impl Display for IrBlock {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
writeln!(f, " {}", self.debug_label)?; writeln!(f, " {}:", self.debug_label)?;
for statement in &self.statements {
writeln!(f, " {}", statement)?; let (live_in, live_out) = self.live_in_live_out();
for (statement_index, statement) in self.statements.iter().enumerate() {
let statement_live_in = live_in.get(&statement_index).unwrap();
let statement_live_out = live_out.get(&statement_index).unwrap();
writeln!(
f,
" {} // live_in: {:?}, live_out: {:?}",
statement, statement_live_in, statement_live_out
)?;
} }
writeln!(f, " // ---- {} meta ----", self.debug_label)?;
writeln!(f, " // definitions: {:?}", self.definitions())?;
writeln!(f, " // uses: {:?}", self.uses())?;
writeln!(
f,
" // interference graph: {:?}",
self.interference_graph()
)?;
Ok(()) Ok(())
} }
} }

View File

@ -1,4 +1,6 @@
use crate::ir::ir_expression::IrExpression; use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_variable::IrVariable;
use std::collections::HashSet;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc; use std::rc::Rc;
@ -14,6 +16,14 @@ impl IrCall {
arguments, arguments,
} }
} }
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
let mut set = HashSet::new();
for argument in &self.arguments {
set.extend(argument.uses());
}
set
}
} }
impl Display for IrCall { impl Display for IrCall {

View File

@ -1,10 +1,12 @@
use crate::ir::ir_parameter::IrParameter;
use crate::ir::ir_variable::IrVariable; use crate::ir::ir_variable::IrVariable;
use std::cell::RefCell; use std::collections::HashSet;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc; use std::rc::Rc;
pub enum IrExpression { pub enum IrExpression {
Variable(Rc<RefCell<IrVariable>>), Parameter(Rc<IrParameter>),
Variable(Rc<IrVariable>),
Int(i32), Int(i32),
String(Rc<str>), String(Rc<str>),
} }
@ -12,8 +14,11 @@ pub enum IrExpression {
impl Display for IrExpression { impl Display for IrExpression {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {
IrExpression::Parameter(ir_parameter) => {
write!(f, "{}", ir_parameter)
}
IrExpression::Variable(ir_variable) => { IrExpression::Variable(ir_variable) => {
write!(f, "{}", ir_variable.borrow()) write!(f, "{}", ir_variable)
} }
IrExpression::Int(i) => { IrExpression::Int(i) => {
write!(f, "{}", i) write!(f, "{}", i)
@ -24,3 +29,24 @@ impl Display for IrExpression {
} }
} }
} }
impl IrExpression {
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
let mut set = HashSet::new();
match self {
IrExpression::Parameter(_) => {
// no-op
}
IrExpression::Variable(ir_variable) => {
set.insert(ir_variable.clone());
}
IrExpression::Int(_) => {
// no-op
}
IrExpression::String(_) => {
// no-op
}
}
set
}
}

View File

@ -1,4 +1,5 @@
use crate::ir::ir_block::IrBlock; use crate::ir::ir_block::IrBlock;
use crate::ir::ir_parameter::IrParameter;
use crate::ir::ir_variable::IrVariable; use crate::ir::ir_variable::IrVariable;
use crate::type_info::TypeInfo; use crate::type_info::TypeInfo;
use std::cell::RefCell; use std::cell::RefCell;
@ -7,7 +8,7 @@ use std::rc::Rc;
pub struct IrFunction { pub struct IrFunction {
name: Rc<str>, name: Rc<str>,
parameters: Vec<Rc<RefCell<IrVariable>>>, parameters: Vec<Rc<IrParameter>>,
return_type_info: TypeInfo, return_type_info: TypeInfo,
entry: Rc<RefCell<IrBlock>>, entry: Rc<RefCell<IrBlock>>,
} }
@ -15,7 +16,7 @@ pub struct IrFunction {
impl IrFunction { impl IrFunction {
pub fn new( pub fn new(
name: Rc<str>, name: Rc<str>,
parameters: &[Rc<RefCell<IrVariable>>], parameters: &[Rc<IrParameter>],
return_type_info: TypeInfo, return_type_info: TypeInfo,
entry: Rc<RefCell<IrBlock>>, entry: Rc<RefCell<IrBlock>>,
) -> Self { ) -> Self {
@ -32,12 +33,7 @@ impl Display for IrFunction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "fn {}(", self.name)?; write!(f, "fn {}(", self.name)?;
for (i, parameter) in self.parameters.iter().enumerate() { for (i, parameter) in self.parameters.iter().enumerate() {
write!( write!(f, "{}: {}", parameter, parameter.type_info())?;
f,
"{}: {}",
parameter.borrow(),
parameter.borrow().type_info()
)?;
if i < self.parameters.len() - 1 { if i < self.parameters.len() - 1 {
write!(f, ", ")?; write!(f, ", ")?;
} }

View File

@ -1,7 +1,10 @@
use crate::ir::ir_add::IrAdd; use crate::ir::ir_add::IrAdd;
use crate::ir::ir_call::IrCall; use crate::ir::ir_call::IrCall;
use crate::ir::ir_expression::IrExpression; use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_variable::IrVariable;
use std::collections::HashSet;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc;
pub enum IrOperation { pub enum IrOperation {
Load(IrExpression), Load(IrExpression),
@ -24,3 +27,13 @@ impl Display for IrOperation {
} }
} }
} }
impl IrOperation {
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
match self {
IrOperation::Load(ir_expression) => ir_expression.uses(),
IrOperation::Add(ir_add) => ir_add.uses(),
IrOperation::Call(ir_call) => ir_call.uses(),
}
}
}

View File

@ -0,0 +1,27 @@
use crate::type_info::TypeInfo;
use std::fmt::{Display, Formatter};
use std::rc::Rc;
pub struct IrParameter {
name: Rc<str>,
type_info: TypeInfo,
}
impl IrParameter {
pub fn new(name: &str, type_info: TypeInfo) -> Self {
Self {
name: name.into(),
type_info,
}
}
pub fn type_info(&self) -> &TypeInfo {
&self.type_info
}
}
impl Display for IrParameter {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name)
}
}

View File

@ -1,5 +1,8 @@
use crate::ir::ir_expression::IrExpression; use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_variable::IrVariable;
use std::collections::HashSet;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc;
pub struct IrReturn { pub struct IrReturn {
value: Option<IrExpression>, value: Option<IrExpression>,
@ -9,6 +12,10 @@ impl IrReturn {
pub fn new(value: Option<IrExpression>) -> Self { pub fn new(value: Option<IrExpression>) -> Self {
Self { value } Self { value }
} }
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
self.value.as_ref().map_or(HashSet::new(), |v| v.uses())
}
} }
impl Display for IrReturn { impl Display for IrReturn {

View File

@ -1,7 +1,10 @@
use crate::ir::ir_assign::IrAssign; use crate::ir::ir_assign::IrAssign;
use crate::ir::ir_call::IrCall; use crate::ir::ir_call::IrCall;
use crate::ir::ir_return::IrReturn; use crate::ir::ir_return::IrReturn;
use crate::ir::ir_variable::IrVariable;
use std::collections::HashSet;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc;
pub enum IrStatement { pub enum IrStatement {
Assign(IrAssign), Assign(IrAssign),
@ -9,6 +12,38 @@ pub enum IrStatement {
Return(IrReturn), Return(IrReturn),
} }
impl IrStatement {
pub fn definitions(&self) -> HashSet<Rc<IrVariable>> {
let mut set = HashSet::new();
match self {
IrStatement::Assign(ir_assign) => {
set.insert(ir_assign.destination().clone());
}
IrStatement::Call(_) => {
// no-op
}
IrStatement::Return(_) => {
// no-op
}
}
set
}
pub fn uses(&self) -> HashSet<Rc<IrVariable>> {
let mut set = HashSet::new();
match self {
IrStatement::Assign(ir_assign) => {
set.extend(ir_assign.uses());
}
IrStatement::Call(ir_call) => {
set.extend(ir_call.uses());
}
IrStatement::Return(ir_return) => set.extend(ir_return.uses()),
}
set
}
}
impl Display for IrStatement { impl Display for IrStatement {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self { match self {

View File

@ -1,7 +1,9 @@
use crate::type_info::TypeInfo; use crate::type_info::TypeInfo;
use std::fmt::{Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::rc::Rc; use std::rc::Rc;
/// Represents a virtual register
pub struct IrVariable { pub struct IrVariable {
name: Rc<str>, name: Rc<str>,
type_info: TypeInfo, type_info: TypeInfo,
@ -15,6 +17,10 @@ impl IrVariable {
} }
} }
pub fn name(&self) -> &str {
&self.name
}
pub fn type_info(&self) -> &TypeInfo { pub fn type_info(&self) -> &TypeInfo {
&self.type_info &self.type_info
} }
@ -25,3 +31,23 @@ impl Display for IrVariable {
write!(f, "{}", self.name) write!(f, "{}", self.name)
} }
} }
impl Debug for IrVariable {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.name)
}
}
impl Hash for IrVariable {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
}
}
impl PartialEq for IrVariable {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
impl Eq for IrVariable {}

View File

@ -5,6 +5,7 @@ pub mod ir_call;
pub mod ir_expression; pub mod ir_expression;
pub mod ir_function; pub mod ir_function;
pub mod ir_operation; pub mod ir_operation;
pub mod ir_parameter;
pub mod ir_return; pub mod ir_return;
pub mod ir_statement; pub mod ir_statement;
pub mod ir_variable; pub mod ir_variable;

View File

@ -1,3 +1,5 @@
use crate::ir::ir_expression::IrExpression;
use crate::ir::ir_parameter::IrParameter;
use crate::ir::ir_variable::IrVariable; use crate::ir::ir_variable::IrVariable;
use crate::type_info::TypeInfo; use crate::type_info::TypeInfo;
use std::cell::RefCell; use std::cell::RefCell;
@ -48,7 +50,7 @@ impl FunctionSymbol {
pub struct ParameterSymbol { pub struct ParameterSymbol {
name: Rc<str>, name: Rc<str>,
type_info: TypeInfo, type_info: TypeInfo,
ir_variable: Option<Rc<RefCell<IrVariable>>>, ir_parameter: Option<Rc<IrParameter>>,
#[deprecated] #[deprecated]
stack_frame_offset: Option<isize>, stack_frame_offset: Option<isize>,
@ -59,7 +61,7 @@ impl ParameterSymbol {
Self { Self {
name: name.into(), name: name.into(),
type_info, type_info,
ir_variable: None, ir_parameter: None,
stack_frame_offset: None, stack_frame_offset: None,
} }
} }
@ -76,14 +78,12 @@ impl ParameterSymbol {
&self.type_info &self.type_info
} }
pub fn set_ir_variable(&mut self, ir_variable: Rc<RefCell<IrVariable>>) { pub fn set_ir_parameter(&mut self, ir_parameter: Rc<IrParameter>) {
self.ir_variable = Some(ir_variable); self.ir_parameter = Some(ir_parameter);
} }
pub fn ir_variable(&self) -> &Rc<RefCell<IrVariable>> { pub fn ir_parameter(&self) -> &Rc<IrParameter> {
self.ir_variable self.ir_parameter.as_ref().unwrap()
.as_ref()
.expect("ir_variable not yet initialized")
} }
#[deprecated] #[deprecated]
@ -100,7 +100,7 @@ impl ParameterSymbol {
pub struct VariableSymbol { pub struct VariableSymbol {
name: Rc<str>, name: Rc<str>,
type_info: Option<TypeInfo>, type_info: Option<TypeInfo>,
ir_variable: Option<Rc<RefCell<IrVariable>>>, ir_variable: Option<Rc<IrVariable>>,
#[deprecated] #[deprecated]
register: Option<usize>, register: Option<usize>,
@ -134,11 +134,11 @@ impl VariableSymbol {
.expect("TypeInfo not initialized. Did you type check?") .expect("TypeInfo not initialized. Did you type check?")
} }
pub fn set_ir_variable(&mut self, ir_variable: Rc<RefCell<IrVariable>>) { pub fn set_ir_variable(&mut self, ir_variable: Rc<IrVariable>) {
self.ir_variable = Some(ir_variable); self.ir_variable = Some(ir_variable);
} }
pub fn ir_variable(&self) -> &Rc<RefCell<IrVariable>> { pub fn ir_variable(&self) -> &Rc<IrVariable> {
self.ir_variable self.ir_variable
.as_ref() .as_ref()
.expect("ir_variable not yet initialized") .expect("ir_variable not yet initialized")
@ -160,16 +160,16 @@ pub enum ExpressibleSymbol {
} }
impl ExpressibleSymbol { impl ExpressibleSymbol {
pub fn ir_variable(&self) -> Rc<RefCell<IrVariable>> { pub fn ir_expression(&self) -> IrExpression {
match self { match self {
ExpressibleSymbol::Function(_) => { ExpressibleSymbol::Function(_) => {
panic!("Cannot get ir_variable for FunctionSymbol"); panic!("Cannot get ir_variable for FunctionSymbol");
} }
ExpressibleSymbol::Parameter(parameter_symbol) => { ExpressibleSymbol::Parameter(parameter_symbol) => {
parameter_symbol.borrow().ir_variable().clone() IrExpression::Parameter(parameter_symbol.borrow().ir_parameter().clone())
} }
ExpressibleSymbol::Variable(variable_symbol) => { ExpressibleSymbol::Variable(variable_symbol) => {
variable_symbol.borrow().ir_variable().clone() IrExpression::Variable(variable_symbol.borrow().ir_variable().clone())
} }
} }
} }

View File

@ -8,4 +8,5 @@ fn main()
let y = add(1, 2) let y = add(1, 2)
println(y) println(y)
println(add(3, add(4, 5))) println(add(3, add(4, 5)))
println(y)
end end