New lowering methods WIP.

This commit is contained in:
Jesse Brault 2026-04-22 10:35:56 -04:00
parent 4ae4f7e9e6
commit 50884e38fa
10 changed files with 341 additions and 5 deletions

View File

@ -17,6 +17,7 @@ use crate::symbol::expressible_symbol::ExpressibleSymbol;
use crate::symbol_table::SymbolTable; use crate::symbol_table::SymbolTable;
use crate::type_info::TypeInfo; use crate::type_info::TypeInfo;
use crate::types_table::TypesTable; use crate::types_table::TypesTable;
use std::thread::Builder;
pub struct Call { pub struct Call {
node_id: NodeId, node_id: NodeId,
@ -304,6 +305,7 @@ impl Call {
(nodes_to_types, diagnostics) (nodes_to_types, diagnostics)
} }
#[deprecated]
pub fn type_check( pub fn type_check(
&mut self, &mut self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -390,6 +392,7 @@ impl Call {
} }
} }
#[deprecated]
fn get_callee_symbol(&self, symbol_table: &SymbolTable) -> CallableSymbol { fn get_callee_symbol(&self, symbol_table: &SymbolTable) -> CallableSymbol {
match self.callee() { match self.callee() {
Expression::Identifier(identifier) => { Expression::Identifier(identifier) => {
@ -417,6 +420,7 @@ impl Call {
} }
} }
#[deprecated]
pub fn return_type_info<'a>( pub fn return_type_info<'a>(
&self, &self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -435,6 +439,51 @@ impl Call {
} }
} }
pub fn lower_to_ir(
&self,
builder: &mut IrBuilder,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
nodes_to_types: &NodesToTypes,
) -> IrCall {
let arguments = self
.arguments
.iter()
.map(|expression| {
expression.lower_to_ir_expression(
builder,
nodes_to_symbols,
symbols_to_types,
nodes_to_types,
)
})
.collect::<Vec<_>>();
let callee_symbol = nodes_to_symbols.get(&self.callee().node_id()).unwrap();
let callable_symbol = match callee_symbol {
Symbol::Class(class_symbol) => match class_symbol.constructor_symbol_owned() {
None => panic!(),
Some(constructor_symbol) => CallableSymbol::Constructor(constructor_symbol),
},
Symbol::Function(function_symbol) => CallableSymbol::Function(function_symbol.clone()),
_ => panic!(),
};
match callable_symbol {
CallableSymbol::Function(function_symbol) => IrCall::new(
fqn_parts_to_string(function_symbol.fqn_parts()),
arguments,
function_symbol.is_extern(),
),
CallableSymbol::Constructor(constructor_symbol) => IrCall::new(
fqn_parts_to_string(constructor_symbol.fqn_parts()),
arguments,
constructor_symbol.is_extern(),
),
CallableSymbol::ErrorPlaceholder => unreachable!(),
}
}
pub fn to_ir( pub fn to_ir(
&self, &self,
builder: &mut IrBuilder, builder: &mut IrBuilder,

View File

@ -5,7 +5,7 @@ use crate::ast::function::Function;
use crate::ast::helpers::{ use crate::ast::helpers::{
collect_diagnostics_into_mut, insert_declared_types_into, insert_resolved_types_into, collect_diagnostics_into_mut, insert_declared_types_into, insert_resolved_types_into,
}; };
use crate::ast::{NodesToSymbols, NodesToTypes, SymbolsToTypes}; use crate::ast::{FunctionReturnTypes, NodesToSymbols, NodesToTypes, SymbolsToTypes};
use crate::compile_pipeline::FileId; use crate::compile_pipeline::FileId;
use crate::diagnostic::{Diagnostic, Diagnostics}; use crate::diagnostic::{Diagnostic, Diagnostics};
use crate::ir::ir_class::IrClass; use crate::ir::ir_class::IrClass;
@ -245,8 +245,26 @@ impl CompilationUnit {
diagnostics_result!(diagnostics) diagnostics_result!(diagnostics)
} }
pub fn lower(&self, resolved_types: &NodesToTypes) -> (Vec<IrClass>, Vec<IrFunction>) { pub fn lower(
todo!() &self,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
nodes_to_types: &NodesToTypes,
function_return_types: &FunctionReturnTypes,
) -> (Vec<IrClass>, Vec<IrFunction>) {
let mut ir_classes = Vec::new();
let mut ir_functions = Vec::new();
for function in &self.functions {
ir_functions.push(function.lower_static(
nodes_to_symbols,
symbols_to_types,
nodes_to_types,
function_return_types,
));
}
(ir_classes, ir_functions)
} }
pub fn to_ir( pub fn to_ir(

View File

@ -321,6 +321,7 @@ impl Expression {
} }
} }
#[deprecated]
pub fn type_check( pub fn type_check(
&mut self, &mut self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -341,6 +342,7 @@ impl Expression {
} }
} }
#[deprecated]
pub fn type_info<'a>( pub fn type_info<'a>(
&'a self, &'a self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -369,6 +371,54 @@ impl Expression {
} }
} }
pub fn lower_to_ir_operation(
&self,
builder: &mut IrBuilder,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
nodes_to_types: &NodesToTypes,
) -> IrOperation {
match self {
Expression::Binary(binary_expression) => {}
Expression::Negative(negative_expression) => {
IrOperation::Load(negative_expression.lower_to_ir_expression(
builder,
nodes_to_symbols,
symbols_to_types,
nodes_to_types,
))
}
Expression::Call(call) => IrOperation::Call(call.lower_to_ir(
builder,
nodes_to_symbols,
symbols_to_types,
nodes_to_types,
)),
Expression::Identifier(identifier) => IrOperation::Load(
identifier.lower_to_ir_expression(builder, nodes_to_symbols, symbols_to_types),
),
Expression::Integer(integer_literal) => {
IrOperation::Load(IrExpression::Int(integer_literal.value()))
}
Expression::Double(double_literal) => {
IrOperation::Load(IrExpression::Double(double_literal.value()))
}
Expression::String(string_literal) => {
IrOperation::Load(IrExpression::String(string_literal.content().into()))
}
}
}
pub fn lower_to_ir_expression(
&self,
builder: &mut IrBuilder,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
nodes_to_types: &NodesToTypes,
) -> IrExpression {
todo!()
}
pub fn to_ir_operation( pub fn to_ir_operation(
&self, &self,
builder: &mut IrBuilder, builder: &mut IrBuilder,

View File

@ -9,7 +9,7 @@ use crate::ast::ir_builder::IrBuilder;
use crate::ast::parameter::Parameter; use crate::ast::parameter::Parameter;
use crate::ast::statement::Statement; use crate::ast::statement::Statement;
use crate::ast::type_use::TypeUse; use crate::ast::type_use::TypeUse;
use crate::ast::{NodeId, NodesToSymbols, NodesToTypes, SymbolsToTypes}; use crate::ast::{FunctionReturnTypes, NodeId, NodesToSymbols, NodesToTypes, SymbolsToTypes};
use crate::diagnostic::{Diagnostic, Diagnostics}; use crate::diagnostic::{Diagnostic, Diagnostics};
use crate::ir::ir_function::IrFunction; use crate::ir::ir_function::IrFunction;
use crate::ir::ir_parameter::IrParameter; use crate::ir::ir_parameter::IrParameter;
@ -236,6 +236,7 @@ impl Function {
(symbols_to_types, nodes_to_types, diagnostics) (symbols_to_types, nodes_to_types, diagnostics)
} }
#[deprecated]
pub fn gather_types(&self, symbol_table: &SymbolTable, types_table: &mut TypesTable) { pub fn gather_types(&self, symbol_table: &SymbolTable, types_table: &mut TypesTable) {
let function_symbol = symbol_table let function_symbol = symbol_table
.get_function_symbol_owned(self.scope_id.unwrap(), self.declared_name()) .get_function_symbol_owned(self.scope_id.unwrap(), self.declared_name())
@ -327,6 +328,7 @@ impl Function {
); );
} }
#[deprecated]
pub fn type_check( pub fn type_check(
&mut self, &mut self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -438,4 +440,59 @@ impl Function {
entry_block, entry_block,
) )
} }
pub fn lower_static(
&self,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
nodes_to_types: &NodesToTypes,
function_return_types: &FunctionReturnTypes,
) -> IrFunction {
let mut builder = IrBuilder::new();
let function_symbol = nodes_to_symbols
.get(&self.node_id)
.unwrap()
.unwrap_function_symbol();
// put parameters in builder
for (i, parameter_symbol) in function_symbol.parameters().iter().enumerate() {
let parameter_type_info = symbols_to_types
.get(&Symbol::Parameter(parameter_symbol.clone()))
.unwrap();
let stack_offset = (function_symbol.parameters().len() as isize).neg() + (i as isize);
let ir_parameter = Rc::new(IrParameter::new(
parameter_symbol.declared_name(),
parameter_type_info.clone(),
stack_offset,
));
builder.push_parameter(parameter_symbol, ir_parameter);
}
let entry_block_id = builder.new_block();
// lower statements
let return_type_info = function_return_types.get(function_symbol).unwrap();
let should_return_value = !matches!(return_type_info, TypeInfo::Void);
for (i, statement) in self.statements.iter().enumerate() {
let is_last = i == self.statements.len() - 1;
statement.lower(
&mut builder,
nodes_to_symbols,
symbols_to_types,
nodes_to_types,
should_return_value && is_last,
);
}
builder.finish_block();
let entry_block = builder.get_block(entry_block_id).clone();
IrFunction::new(
fqn_parts_to_string(function_symbol.fqn_parts()),
builder.parameters().iter().map(|p| (*p).clone()).collect(),
return_type_info,
entry_block,
)
}
} }

View File

@ -521,6 +521,7 @@ impl Identifier {
(resolved_types, Diagnostics::new()) (resolved_types, Diagnostics::new())
} }
#[deprecated]
pub fn type_info<'a>( pub fn type_info<'a>(
&self, &self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -553,6 +554,55 @@ impl Identifier {
} }
} }
pub fn lower_to_ir_expression(
&self,
builder: &mut IrBuilder,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
) -> IrExpression {
let symbol = nodes_to_symbols.get(&self.node_id).unwrap();
match &symbol.unwrap_expressible_symbol() {
ExpressibleSymbol::Class(_class_symbol) => {
todo!()
}
ExpressibleSymbol::Field(field_symbol) => {
let field_type = symbols_to_types.get(symbol).unwrap();
let read_destination = Rc::new(RefCell::new(IrVariable::new_vr(
builder.new_t_var().into(),
builder.current_block().id(),
field_type,
)));
let ir_read_field = IrReadField::new(
get_or_init_field_pointer_variable(builder, field_symbol, field_type).clone(),
);
builder
.current_block_mut()
.add_statement(IrStatement::Assign(IrAssign::new(
read_destination.clone(),
IrOperation::ReadField(ir_read_field),
)));
IrExpression::Variable(read_destination)
}
ExpressibleSymbol::Function(_function_symbol) => {
todo!()
}
ExpressibleSymbol::Parameter(parameter_symbol) => IrExpression::Parameter(
builder
.parameters_map()
.get(parameter_symbol)
.unwrap()
.clone(),
),
ExpressibleSymbol::Variable(variable_symbol) => IrExpression::Variable(
builder
.local_variables()
.get(variable_symbol)
.unwrap()
.clone(),
),
}
}
pub fn ir_expression( pub fn ir_expression(
&self, &self,
builder: &mut IrBuilder, builder: &mut IrBuilder,

View File

@ -132,7 +132,7 @@ impl LetStatement {
{ {
let (ns, mut ds) = self let (ns, mut ds) = self
.initializer .initializer
.resolve_names_method(symbol_table, self_class_symbol); .resolve_names_method(symbol_table, self_class_symbol); // todo
insert_resolved_names_into(ns, &mut nodes_to_symbols); insert_resolved_names_into(ns, &mut nodes_to_symbols);
diagnostics.append(&mut ds); diagnostics.append(&mut ds);
} }
@ -216,6 +216,7 @@ impl LetStatement {
(resolved_symbol_type_infos, resolved_types, diagnostics) (resolved_symbol_type_infos, resolved_types, diagnostics)
} }
#[deprecated]
pub fn type_check( pub fn type_check(
&mut self, &mut self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -320,4 +321,35 @@ impl LetStatement {
.add_statement(IrStatement::Assign(ir_assign)); .add_statement(IrStatement::Assign(ir_assign));
as_rc as_rc
} }
pub fn lower(
&self,
builder: &mut IrBuilder,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
nodes_to_types: &NodesToTypes,
) {
let init_operation = self
.initializer
.lower_to_ir_operation(builder, nodes_to_types);
let destination_symbol = nodes_to_symbols.get(&self.node_id).unwrap();
let destination_type_info = symbols_to_types.get(destination_symbol).unwrap();
let vr_variable = Rc::new(RefCell::new(IrVariable::new_vr(
self.declared_name().into(),
builder.current_block().id(),
destination_type_info,
)));
// save local variable to builder
builder.local_variables_mut().insert(
destination_symbol.unwrap_variable_symbol().clone(),
vr_variable.clone(),
);
let ir_assign = IrAssign::new(vr_variable, init_operation);
builder
.current_block_mut()
.add_statement(IrStatement::Assign(ir_assign));
}
} }

View File

@ -1,6 +1,8 @@
use crate::symbol::Symbol; use crate::symbol::Symbol;
use crate::symbol::function_symbol::FunctionSymbol;
use crate::type_info::TypeInfo; use crate::type_info::TypeInfo;
use std::collections::HashMap; use std::collections::HashMap;
use std::rc::Rc;
pub mod assign_statement; pub mod assign_statement;
pub mod binary_expression; pub mod binary_expression;
@ -34,3 +36,4 @@ pub type NodeId = usize;
pub type NodesToSymbols = HashMap<NodeId, Symbol>; pub type NodesToSymbols = HashMap<NodeId, Symbol>;
pub type SymbolsToTypes = HashMap<Symbol, TypeInfo>; pub type SymbolsToTypes = HashMap<Symbol, TypeInfo>;
pub type NodesToTypes = HashMap<NodeId, TypeInfo>; pub type NodesToTypes = HashMap<NodeId, TypeInfo>;
pub type FunctionReturnTypes = HashMap<Rc<FunctionSymbol>, TypeInfo>;

View File

@ -147,6 +147,7 @@ impl NegativeExpression {
(nodes_to_types, diagnostics) (nodes_to_types, diagnostics)
} }
#[deprecated]
pub fn type_check( pub fn type_check(
&mut self, &mut self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -167,6 +168,56 @@ impl NegativeExpression {
} }
} }
pub fn lower_to_ir_expression(
&self,
builder: &mut IrBuilder,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
nodes_to_types: &NodesToTypes,
) -> IrExpression {
let base_ir_expression = self.operand.lower_to_ir_expression(
builder,
nodes_to_symbols,
symbols_to_types,
nodes_to_types,
);
match base_ir_expression {
IrExpression::Parameter(ir_parameter) => {
let destination = Rc::new(RefCell::new(IrVariable::new_vr(
builder.new_t_var().into(),
builder.current_block().id(),
ir_parameter.type_info(),
)));
let rhs = match ir_parameter.type_info() {
TypeInfo::Integer => IrExpression::Int(-1),
TypeInfo::Double => IrExpression::Double(-1.0),
_ => panic!(),
};
let operation = IrOperation::Binary(IrBinaryOperation::new(
IrExpression::Parameter(ir_parameter),
rhs,
IrBinaryOperator::Multiply,
));
let ir_assign = IrAssign::new(destination.clone(), operation);
builder
.current_block_mut()
.add_statement(IrStatement::Assign(ir_assign));
IrExpression::Variable(destination)
}
IrExpression::Variable(ir_variable) => {}
IrExpression::Int(i) => {}
IrExpression::Double(d) => {}
IrExpression::String(_) => {
panic!();
}
}
}
pub fn to_ir( pub fn to_ir(
&self, &self,
builder: &mut IrBuilder, builder: &mut IrBuilder,

View File

@ -160,6 +160,7 @@ impl Statement {
} }
} }
#[deprecated]
pub fn type_check( pub fn type_check(
&mut self, &mut self,
symbol_table: &SymbolTable, symbol_table: &SymbolTable,
@ -177,6 +178,7 @@ impl Statement {
} }
} }
#[deprecated]
pub fn to_ir( pub fn to_ir(
&self, &self,
builder: &mut IrBuilder, builder: &mut IrBuilder,
@ -196,4 +198,21 @@ impl Statement {
} }
} }
} }
pub fn lower(
&self,
builder: &mut IrBuilder,
nodes_to_symbols: &NodesToSymbols,
symbols_to_types: &SymbolsToTypes,
nodes_to_types: &NodesToTypes,
is_return_statement: bool,
) {
match self {
Statement::Let(let_statement) => {
let_statement.lower(builder, nodes_to_symbols, symbols_to_types, nodes_to_types);
}
Statement::Expression(expression_statement) => {}
Statement::Assign(assign_statement) => {}
}
}
} }

View File

@ -112,4 +112,11 @@ impl Symbol {
_ => panic!(), _ => panic!(),
} }
} }
pub fn unwrap_variable_symbol(&self) -> &Rc<VariableSymbol> {
match self {
Symbol::Variable(variable_symbol) => variable_symbol,
_ => panic!(),
}
}
} }