StorageEnvironment abstraction in lowering module.
This commit is contained in:
parent
6b51545114
commit
5edf8964dc
@ -1,25 +1,17 @@
|
||||
use dmc_lib::SyntheticFunctionSession;
|
||||
use dmc_lib::ast::expression_statement::ExpressionStatement;
|
||||
use dmc_lib::ast::statement::Statement;
|
||||
use dmc_lib::compile_statement_to_synthetic_function;
|
||||
use dmc_lib::constants_table::ConstantsTable;
|
||||
use dmc_lib::diagnostic::Diagnostics;
|
||||
use dmc_lib::ir::ir_parameter::{IrParameter, IrParameterId};
|
||||
use dmc_lib::ir::ir_variable::{IrVariable, IrVariableId};
|
||||
use dmc_lib::ir::variable_locations::VariableLocations;
|
||||
use dmc_lib::lexer::Lexer;
|
||||
use dmc_lib::lowering::SyntheticFunctionLoweringContext;
|
||||
use dmc_lib::parser::{parse_expression, parse_let_statement};
|
||||
use dmc_lib::semantic_analysis::analysis_context::AnalysisContext;
|
||||
use dmc_lib::semantic_analysis::symbol::SymbolId;
|
||||
use dmc_lib::token::TokenKind;
|
||||
use dvm_lib::vm::constant::{Constant, StringConstant};
|
||||
use dvm_lib::vm::function::Function;
|
||||
use dvm_lib::vm::operand::Operand;
|
||||
use dvm_lib::vm::{CallStack, DvmContext, loop_instructions, prepare_for_instruction_loop};
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::io::{BufRead, Write};
|
||||
use std::rc::Rc;
|
||||
//
|
||||
// pub fn repl(read: &mut impl BufRead, register_count: usize) {
|
||||
// let mut buffer = String::new();
|
||||
@ -306,20 +298,12 @@ use std::rc::Rc;
|
||||
pub fn repl_2(read: &mut impl BufRead, register_count: usize) {
|
||||
let mut buffer = String::new();
|
||||
|
||||
let mut analysis_context = AnalysisContext::new();
|
||||
|
||||
let mut session = SyntheticFunctionSession::new("__repl");
|
||||
let analysis_context = session.ctx_mut();
|
||||
analysis_context.push_scope("__repl_root_scope");
|
||||
analysis_context.push_scope("__repl_function_scope");
|
||||
analysis_context.push_scope("__repl_body_scope");
|
||||
|
||||
let fqn: Rc<str> = Rc::from("__repl");
|
||||
|
||||
let mut ir_variables: Vec<IrVariable> = Vec::new();
|
||||
let mut ir_parameters: Vec<IrParameter> = Vec::new();
|
||||
let mut symbols_to_variables: HashMap<SymbolId, IrVariableId> = HashMap::new();
|
||||
let mut symbols_to_parameters: HashMap<SymbolId, IrParameterId> = HashMap::new();
|
||||
|
||||
let mut variable_locations = VariableLocations::new();
|
||||
let mut constants_table = ConstantsTable::new();
|
||||
|
||||
let mut dvm_context = DvmContext::new();
|
||||
@ -354,15 +338,7 @@ pub fn repl_2(read: &mut impl BufRead, register_count: usize) {
|
||||
TokenKind::Let => {
|
||||
let compile_result = compile_let_statement_2(
|
||||
input,
|
||||
&mut analysis_context,
|
||||
&fqn,
|
||||
SyntheticFunctionLoweringContext {
|
||||
ir_variables: &mut ir_variables,
|
||||
symbols_to_variables: &mut symbols_to_variables,
|
||||
ir_parameters: &mut ir_parameters,
|
||||
symbols_to_parameters: &mut symbols_to_parameters,
|
||||
},
|
||||
&mut variable_locations,
|
||||
&mut session,
|
||||
register_count,
|
||||
&mut constants_table,
|
||||
);
|
||||
@ -382,20 +358,8 @@ pub fn repl_2(read: &mut impl BufRead, register_count: usize) {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let compile_result = compile_expression_2(
|
||||
input,
|
||||
&mut analysis_context,
|
||||
&fqn,
|
||||
SyntheticFunctionLoweringContext {
|
||||
ir_variables: &mut ir_variables,
|
||||
symbols_to_variables: &mut symbols_to_variables,
|
||||
ir_parameters: &mut ir_parameters,
|
||||
symbols_to_parameters: &mut symbols_to_parameters,
|
||||
},
|
||||
&mut variable_locations,
|
||||
register_count,
|
||||
&mut constants_table,
|
||||
);
|
||||
let compile_result =
|
||||
compile_expression_2(input, &mut session, register_count, &mut constants_table);
|
||||
match compile_result {
|
||||
Ok(function) => {
|
||||
dvm_context
|
||||
@ -449,10 +413,7 @@ pub fn repl_2(read: &mut impl BufRead, register_count: usize) {
|
||||
|
||||
fn compile_expression_2(
|
||||
input: &str,
|
||||
analysis_context: &mut AnalysisContext,
|
||||
fqn: &Rc<str>,
|
||||
synthetic_function_lowering_context: SyntheticFunctionLoweringContext,
|
||||
variable_locations: &mut VariableLocations,
|
||||
session: &mut SyntheticFunctionSession,
|
||||
register_count: usize,
|
||||
constants_table: &mut ConstantsTable,
|
||||
) -> Result<Function, Diagnostics> {
|
||||
@ -463,23 +424,12 @@ fn compile_expression_2(
|
||||
|
||||
let statement = Statement::Expression(ExpressionStatement::new(0, expression));
|
||||
|
||||
compile_statement_to_synthetic_function(
|
||||
&statement,
|
||||
analysis_context,
|
||||
fqn.clone(),
|
||||
synthetic_function_lowering_context,
|
||||
variable_locations,
|
||||
register_count,
|
||||
constants_table,
|
||||
)
|
||||
session.compile_statement(&statement, register_count, constants_table)
|
||||
}
|
||||
|
||||
fn compile_let_statement_2(
|
||||
input: &str,
|
||||
analysis_context: &mut AnalysisContext,
|
||||
fqn: &Rc<str>,
|
||||
synthetic_function_lowering_context: SyntheticFunctionLoweringContext,
|
||||
variable_locations: &mut VariableLocations,
|
||||
session: &mut SyntheticFunctionSession,
|
||||
register_count: usize,
|
||||
constants_table: &mut ConstantsTable,
|
||||
) -> Result<Function, Diagnostics> {
|
||||
@ -487,13 +437,6 @@ fn compile_let_statement_2(
|
||||
if !parse_diagnostics.is_empty() {
|
||||
return Err(parse_diagnostics);
|
||||
}
|
||||
compile_statement_to_synthetic_function(
|
||||
&Statement::Let(maybe_let_statement.unwrap()),
|
||||
analysis_context,
|
||||
fqn.clone(),
|
||||
synthetic_function_lowering_context,
|
||||
variable_locations,
|
||||
register_count,
|
||||
constants_table,
|
||||
)
|
||||
let statement = Statement::Let(maybe_let_statement.unwrap());
|
||||
session.compile_statement(&statement, register_count, constants_table)
|
||||
}
|
||||
|
||||
@ -2,11 +2,11 @@ use crate::ast::statement::Statement;
|
||||
use crate::constants_table::ConstantsTable;
|
||||
use crate::diagnostic::Diagnostics;
|
||||
use crate::ir::compile_dvm_function;
|
||||
use crate::ir::ir_variable::{IrVariable, IrVariableId};
|
||||
use crate::ir::variable_locations::VariableLocations;
|
||||
use crate::lowering::{
|
||||
SyntheticFunctionLoweringContext, lower_to_ir_compilation_unit, lower_to_ir_synthetic_function,
|
||||
};
|
||||
use crate::lowering::{lower_to_ir_compilation_unit, lower_to_ir_synthetic_function};
|
||||
use crate::parser::parse_compilation_unit;
|
||||
use crate::semantic_analysis::symbol::SymbolId;
|
||||
use crate::semantic_analysis::{analyze_compilation_unit, analyze_statement};
|
||||
use dvm_lib::vm::function::Function;
|
||||
use semantic_analysis::analysis_context::AnalysisContext;
|
||||
@ -77,29 +77,75 @@ pub fn compile_compilation_unit(
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compile_statement_to_synthetic_function(
|
||||
statement: &Statement,
|
||||
analysis_context: &mut AnalysisContext,
|
||||
pub struct SyntheticFunctionSession {
|
||||
fqn: Rc<str>,
|
||||
synthetic_function_lowering_context: SyntheticFunctionLoweringContext,
|
||||
variable_locations: &mut VariableLocations,
|
||||
ctx: Box<AnalysisContext>,
|
||||
env: Box<SyntheticEnvironment>,
|
||||
}
|
||||
|
||||
impl SyntheticFunctionSession {
|
||||
pub fn new(fqn: &str) -> Self {
|
||||
Self {
|
||||
fqn: fqn.into(),
|
||||
ctx: AnalysisContext::new().into(),
|
||||
env: SyntheticEnvironment::new().into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ctx(&self) -> &AnalysisContext {
|
||||
&self.ctx
|
||||
}
|
||||
|
||||
pub fn ctx_mut(&mut self) -> &mut AnalysisContext {
|
||||
&mut self.ctx
|
||||
}
|
||||
|
||||
pub fn compile_statement(
|
||||
&mut self,
|
||||
statement: &Statement,
|
||||
register_count: usize,
|
||||
constants_table: &mut ConstantsTable,
|
||||
) -> Result<Function, Diagnostics> {
|
||||
let diagnostics = analyze_statement(statement, analysis_context);
|
||||
let diagnostics = analyze_statement(statement, &mut self.ctx);
|
||||
if !diagnostics.is_empty() {
|
||||
return Err(diagnostics);
|
||||
}
|
||||
let ir_function = lower_to_ir_synthetic_function(
|
||||
statement,
|
||||
analysis_context,
|
||||
fqn,
|
||||
synthetic_function_lowering_context,
|
||||
);
|
||||
let ir_function = lower_to_ir_synthetic_function(statement, &self);
|
||||
Ok(compile_dvm_function(
|
||||
&ir_function,
|
||||
register_count,
|
||||
variable_locations,
|
||||
&mut VariableLocations::new(),
|
||||
constants_table,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SyntheticEnvironment {
|
||||
persisted_ir_variables: Vec<IrVariable>,
|
||||
persisted_symbols_to_variables: HashMap<SymbolId, IrVariableId>,
|
||||
}
|
||||
|
||||
impl SyntheticEnvironment {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
persisted_ir_variables: Vec::new(),
|
||||
persisted_symbols_to_variables: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn persisted_ir_variables(&self) -> &[IrVariable] {
|
||||
&self.persisted_ir_variables
|
||||
}
|
||||
|
||||
pub fn persisted_ir_variables_mut(&mut self) -> &mut Vec<IrVariable> {
|
||||
&mut self.persisted_ir_variables
|
||||
}
|
||||
|
||||
pub fn persisted_symbols_to_variables(&self) -> &HashMap<SymbolId, IrVariableId> {
|
||||
&self.persisted_symbols_to_variables
|
||||
}
|
||||
|
||||
pub fn persisted_symbols_to_variables_mut(&mut self) -> &mut HashMap<SymbolId, IrVariableId> {
|
||||
&mut self.persisted_symbols_to_variables
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
mod util;
|
||||
|
||||
use crate::SyntheticFunctionSession;
|
||||
use crate::ast::assign_statement::AssignStatement;
|
||||
use crate::ast::binary_expression::BinaryOperation;
|
||||
use crate::ast::call::Call;
|
||||
@ -27,7 +28,6 @@ use crate::semantic_analysis::symbol::{Symbol, SymbolId};
|
||||
use crate::semantic_analysis::type_info::TypeInfo;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Neg;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct LowerToIrResult {
|
||||
pub functions: Vec<IrFunction>,
|
||||
@ -46,27 +46,17 @@ pub fn lower_to_ir_compilation_unit(
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SyntheticFunctionLoweringContext<'a> {
|
||||
pub ir_variables: &'a mut Vec<IrVariable>,
|
||||
pub symbols_to_variables: &'a mut HashMap<SymbolId, IrVariableId>,
|
||||
pub ir_parameters: &'a mut Vec<IrParameter>,
|
||||
pub symbols_to_parameters: &'a mut HashMap<SymbolId, IrParameterId>,
|
||||
}
|
||||
|
||||
pub fn lower_to_ir_synthetic_function(
|
||||
statement: &Statement,
|
||||
analysis_ctx: &AnalysisContext,
|
||||
fqn: Rc<str>,
|
||||
synthetic_function_lowering_context: SyntheticFunctionLoweringContext,
|
||||
session: &SyntheticFunctionSession,
|
||||
) -> IrFunction {
|
||||
let mut fn_ctx = LowerToIrFunctionContext::with_variables_and_parameters(
|
||||
synthetic_function_lowering_context.ir_variables,
|
||||
synthetic_function_lowering_context.symbols_to_variables,
|
||||
synthetic_function_lowering_context.ir_parameters,
|
||||
synthetic_function_lowering_context.symbols_to_parameters,
|
||||
);
|
||||
let mut fn_ctx = LowerToIrFunctionContext::new(StorageEnvironment::with_persisted_variables(
|
||||
0,
|
||||
session.env.persisted_ir_variables(),
|
||||
session.env.persisted_symbols_to_variables(),
|
||||
));
|
||||
|
||||
lower_to_ir_statement(statement, analysis_ctx, &mut fn_ctx, true);
|
||||
lower_to_ir_statement(statement, &session.ctx, &mut fn_ctx, true);
|
||||
fn_ctx.finish_block();
|
||||
|
||||
// infer return type from statement
|
||||
@ -74,47 +64,33 @@ pub fn lower_to_ir_synthetic_function(
|
||||
Statement::Let(_) | Statement::Assign(_) => None,
|
||||
Statement::Expression(expression_statement) => {
|
||||
let type_info_id =
|
||||
analysis_ctx.nodes_to_type_infos()[&expression_statement.expression().node_id()];
|
||||
let type_info = &analysis_ctx.type_infos()[type_info_id];
|
||||
session.ctx.nodes_to_type_infos()[&expression_statement.expression().node_id()];
|
||||
let type_info = &session.ctx.type_infos()[type_info_id];
|
||||
return_type_info_to_ir_type_info(type_info)
|
||||
}
|
||||
};
|
||||
|
||||
IrFunction::new(
|
||||
fqn,
|
||||
fn_ctx.ir_parameters.clone(), // provide just a snapshot of those
|
||||
fn_ctx.ir_variables.clone(),
|
||||
session.fqn.clone(),
|
||||
fn_ctx.storage_env_mut().take_parameters(),
|
||||
fn_ctx.storage_env_mut().take_variables(),
|
||||
maybe_return_ir_type_info,
|
||||
fn_ctx.blocks,
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct LowerToIrFunctionContext<'a> {
|
||||
ir_variables: &'a mut Vec<IrVariable>,
|
||||
symbols_to_variables: &'a mut HashMap<SymbolId, IrVariableId>,
|
||||
ir_parameters: &'a mut Vec<IrParameter>,
|
||||
symbols_to_parameters: &'a mut HashMap<SymbolId, IrParameterId>,
|
||||
struct LowerToIrFunctionContext {
|
||||
storage_env: Box<StorageEnvironment>,
|
||||
blocks: Vec<IrBlock>,
|
||||
current_block_statements: Vec<IrStatement>,
|
||||
t_var_counter: usize,
|
||||
}
|
||||
|
||||
impl<'a> LowerToIrFunctionContext<'a> {
|
||||
fn with_variables_and_parameters(
|
||||
ir_variables: &'a mut Vec<IrVariable>,
|
||||
symbols_to_variables: &'a mut HashMap<SymbolId, IrVariableId>,
|
||||
ir_parameters: &'a mut Vec<IrParameter>,
|
||||
symbols_to_parameters: &'a mut HashMap<SymbolId, IrParameterId>,
|
||||
) -> Self {
|
||||
impl LowerToIrFunctionContext {
|
||||
fn new(storage_env: StorageEnvironment) -> Self {
|
||||
Self {
|
||||
ir_variables,
|
||||
symbols_to_variables,
|
||||
ir_parameters,
|
||||
symbols_to_parameters,
|
||||
storage_env: storage_env.into(),
|
||||
blocks: Vec::new(),
|
||||
current_block_statements: Vec::new(),
|
||||
t_var_counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,54 +108,127 @@ impl<'a> LowerToIrFunctionContext<'a> {
|
||||
self.blocks.push(ir_block);
|
||||
}
|
||||
|
||||
fn insert_ir_parameter(
|
||||
&mut self,
|
||||
ir_parameter: IrParameter,
|
||||
maybe_associated_symbol_id: Option<SymbolId>,
|
||||
) -> IrParameterId {
|
||||
self.ir_parameters.push(ir_parameter);
|
||||
let ir_parameter_id = self.ir_parameters.len() - 1;
|
||||
if let Some(associated_symbol_id) = maybe_associated_symbol_id {
|
||||
self.symbols_to_parameters
|
||||
.insert(associated_symbol_id, ir_parameter_id);
|
||||
fn storage_env(&self) -> &StorageEnvironment {
|
||||
&*self.storage_env
|
||||
}
|
||||
|
||||
fn storage_env_mut(&mut self) -> &mut StorageEnvironment {
|
||||
&mut *self.storage_env
|
||||
}
|
||||
}
|
||||
|
||||
struct StorageEnvironment {
|
||||
ir_variables: Vec<IrVariable>,
|
||||
symbols_to_variables: HashMap<SymbolId, IrVariableId>,
|
||||
current_parameter_stack_offset: isize,
|
||||
ir_parameters: Vec<IrParameter>,
|
||||
symbols_to_parameters: HashMap<SymbolId, IrParameterId>,
|
||||
t_var_counter: usize,
|
||||
}
|
||||
|
||||
impl StorageEnvironment {
|
||||
fn new(parameter_count: usize) -> Self {
|
||||
Self {
|
||||
ir_variables: Vec::new(),
|
||||
symbols_to_variables: HashMap::new(),
|
||||
current_parameter_stack_offset: (parameter_count as isize).neg(),
|
||||
ir_parameters: Vec::new(),
|
||||
symbols_to_parameters: HashMap::new(),
|
||||
t_var_counter: 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
fn with_persisted_variables(
|
||||
parameter_count: usize,
|
||||
persisted_ir_variables: &[IrVariable],
|
||||
persisted_symbols_to_variables: &HashMap<SymbolId, IrVariableId>,
|
||||
) -> Self {
|
||||
let mut this = Self::new(parameter_count);
|
||||
this.ir_variables = persisted_ir_variables.to_vec();
|
||||
this.symbols_to_variables = persisted_symbols_to_variables.clone();
|
||||
this
|
||||
}
|
||||
|
||||
fn next_parameter_stack_offset(&mut self) -> isize {
|
||||
let current = self.current_parameter_stack_offset;
|
||||
self.current_parameter_stack_offset += 1;
|
||||
current
|
||||
}
|
||||
|
||||
fn next_t_var_number(&mut self) -> usize {
|
||||
let t_var = self.t_var_counter;
|
||||
self.t_var_counter += 1;
|
||||
t_var
|
||||
}
|
||||
|
||||
fn new_parameter(&mut self, name: &str, ir_type_info: IrTypeInfo) -> IrParameterId {
|
||||
let ir_parameter = IrParameter::new(name, ir_type_info, self.next_parameter_stack_offset());
|
||||
self.ir_parameters.push(ir_parameter);
|
||||
self.ir_parameters.len() - 1
|
||||
}
|
||||
|
||||
fn new_parameter_for(
|
||||
&mut self,
|
||||
name: &str,
|
||||
ir_type_info: IrTypeInfo,
|
||||
symbol_id: SymbolId,
|
||||
) -> IrParameterId {
|
||||
let ir_parameter_id = self.new_parameter(name, ir_type_info);
|
||||
self.symbols_to_parameters
|
||||
.insert(symbol_id, ir_parameter_id);
|
||||
ir_parameter_id
|
||||
}
|
||||
|
||||
fn insert_ir_variable(
|
||||
&mut self,
|
||||
ir_variable: IrVariable,
|
||||
maybe_associated_symbol_id: Option<SymbolId>,
|
||||
) -> IrVariableId {
|
||||
fn new_variable(&mut self, name: &str, ir_type_info: IrTypeInfo) -> IrVariableId {
|
||||
let ir_variable = IrVariable::new(name, ir_type_info);
|
||||
self.ir_variables.push(ir_variable);
|
||||
let ir_variable_id = self.ir_variables.len() - 1;
|
||||
if let Some(associated_symbol_id) = maybe_associated_symbol_id {
|
||||
self.symbols_to_variables
|
||||
.insert(associated_symbol_id, ir_variable_id);
|
||||
self.ir_variables.len() - 1
|
||||
}
|
||||
|
||||
fn new_variable_for(
|
||||
&mut self,
|
||||
name: &str,
|
||||
ir_type_info: IrTypeInfo,
|
||||
symbol_id: SymbolId,
|
||||
) -> IrVariableId {
|
||||
let ir_variable_id = self.new_variable(name, ir_type_info);
|
||||
self.symbols_to_variables.insert(symbol_id, ir_variable_id);
|
||||
ir_variable_id
|
||||
}
|
||||
|
||||
fn make_t_var(&mut self, ir_type_info: IrTypeInfo) -> IrVariableId {
|
||||
let t_var_id = self.t_var_counter;
|
||||
self.t_var_counter += 1;
|
||||
let t_var_ir_variable = IrVariable::new(&format!("t_{}", t_var_id), ir_type_info);
|
||||
self.insert_ir_variable(t_var_ir_variable, None)
|
||||
fn new_t_var(&mut self, ir_type_info: IrTypeInfo) -> IrVariableId {
|
||||
let t_var_number = self.next_t_var_number();
|
||||
self.new_variable(&format!("t_{}", t_var_number), ir_type_info)
|
||||
}
|
||||
|
||||
fn get_variable_for(&self, symbol_id: SymbolId) -> IrVariableId {
|
||||
self.symbols_to_variables
|
||||
.get(&symbol_id)
|
||||
.cloned()
|
||||
.expect(&format!("No ir_variable for symbol_id {}", symbol_id))
|
||||
}
|
||||
|
||||
fn maybe_get_variable_for(&self, symbol_id: SymbolId) -> Option<IrVariableId> {
|
||||
self.symbols_to_variables.get(&symbol_id).cloned()
|
||||
}
|
||||
|
||||
fn maybe_get_parameter_for(&self, symbol_id: SymbolId) -> Option<IrParameterId> {
|
||||
self.symbols_to_parameters.get(&symbol_id).cloned()
|
||||
}
|
||||
|
||||
fn take_variables(&mut self) -> Vec<IrVariable> {
|
||||
std::mem::take(&mut self.ir_variables)
|
||||
}
|
||||
|
||||
fn take_parameters(&mut self) -> Vec<IrParameter> {
|
||||
std::mem::take(&mut self.ir_parameters)
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_to_ir_function(function: &Function, ctx: &AnalysisContext) -> IrFunction {
|
||||
let mut ir_variables = Vec::new();
|
||||
let mut symbols_to_variables = HashMap::new();
|
||||
let mut ir_parameters = Vec::new();
|
||||
let mut symbols_to_parameters = HashMap::new();
|
||||
|
||||
let mut fn_ctx = LowerToIrFunctionContext::with_variables_and_parameters(
|
||||
&mut ir_variables,
|
||||
&mut symbols_to_variables,
|
||||
&mut ir_parameters,
|
||||
&mut symbols_to_parameters,
|
||||
);
|
||||
let mut fn_ctx =
|
||||
LowerToIrFunctionContext::new(StorageEnvironment::new(function.parameters().len()));
|
||||
|
||||
lower_to_ir_parameters(function, ctx, &mut fn_ctx);
|
||||
|
||||
@ -208,13 +257,12 @@ fn lower_to_ir_function(function: &Function, ctx: &AnalysisContext) -> IrFunctio
|
||||
}
|
||||
fn_ctx.finish_block();
|
||||
|
||||
let blocks = fn_ctx.blocks; // must move it out beforehand to satisfy borrow checker
|
||||
IrFunction::new(
|
||||
function_symbol.fqn_owned(),
|
||||
ir_parameters,
|
||||
ir_variables,
|
||||
fn_ctx.storage_env_mut().take_parameters(),
|
||||
fn_ctx.storage_env_mut().take_variables(),
|
||||
return_type_info_to_ir_type_info(return_type_info),
|
||||
blocks,
|
||||
std::mem::take(&mut fn_ctx.blocks),
|
||||
)
|
||||
}
|
||||
|
||||
@ -223,18 +271,13 @@ fn lower_to_ir_parameters(
|
||||
ctx: &AnalysisContext,
|
||||
fn_ctx: &mut LowerToIrFunctionContext,
|
||||
) {
|
||||
let n_parameters = function.parameters().len() as isize;
|
||||
for (i, parameter) in function.parameters().iter().enumerate() {
|
||||
for parameter in function.parameters() {
|
||||
let parameter_type_info_id = ctx.nodes_to_type_infos()[¶meter.node_id()];
|
||||
let parameter_type_info = &ctx.type_infos()[parameter_type_info_id];
|
||||
let ir_parameter = IrParameter::new(
|
||||
fn_ctx.storage_env_mut().new_parameter_for(
|
||||
parameter.declared_name(),
|
||||
to_ir_type_info(parameter_type_info),
|
||||
n_parameters.neg() + (i as isize),
|
||||
);
|
||||
fn_ctx.insert_ir_parameter(
|
||||
ir_parameter,
|
||||
Some(ctx.nodes_to_symbols()[¶meter.node_id()]),
|
||||
ctx.nodes_to_symbols()[¶meter.node_id()],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -283,13 +326,16 @@ fn lower_to_ir_let_statement(
|
||||
let type_info_id = ctx.nodes_to_type_infos()[&let_statement.node_id()];
|
||||
let type_info = &ctx.type_infos()[type_info_id];
|
||||
|
||||
let ir_variable = IrVariable::new(let_statement.declared_name(), to_ir_type_info(type_info));
|
||||
let ir_variable_id = fn_ctx.insert_ir_variable(ir_variable, Some(symbol_id));
|
||||
let destination_ir_variable_id = fn_ctx.storage_env_mut().new_variable_for(
|
||||
let_statement.declared_name(),
|
||||
to_ir_type_info(type_info),
|
||||
symbol_id,
|
||||
);
|
||||
|
||||
let initializer_ir_operation =
|
||||
lower_expression_to_ir_operation(let_statement.initializer(), ctx, fn_ctx);
|
||||
|
||||
let ir_assign = IrAssign::new(ir_variable_id, initializer_ir_operation);
|
||||
let ir_assign = IrAssign::new(destination_ir_variable_id, initializer_ir_operation);
|
||||
let ir_statement = IrStatement::Assign(ir_assign);
|
||||
fn_ctx.current_block_statements.push(ir_statement);
|
||||
}
|
||||
@ -314,7 +360,9 @@ fn lower_to_ir_expression_statement(
|
||||
let result_type_info_id =
|
||||
ctx.nodes_to_type_infos()[&expression_statement.expression().node_id()];
|
||||
let result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||
let t_var_ir_variable_id = fn_ctx.make_t_var(to_ir_type_info(result_type_info));
|
||||
let t_var_ir_variable_id = fn_ctx
|
||||
.storage_env_mut()
|
||||
.new_t_var(to_ir_type_info(result_type_info));
|
||||
|
||||
let ir_statement = IrStatement::Assign(IrAssign::new(t_var_ir_variable_id, ir_operation));
|
||||
fn_ctx.current_block_statements.push(ir_statement);
|
||||
@ -329,7 +377,8 @@ fn lower_to_ir_assign_statement(
|
||||
match assign_statement.destination() {
|
||||
Expression::Identifier(identifier) => {
|
||||
let destination_symbol_id = ctx.nodes_to_symbols()[&identifier.node_id()];
|
||||
let destination_ir_variable_id = fn_ctx.symbols_to_variables[&destination_symbol_id];
|
||||
let destination_ir_variable_id =
|
||||
fn_ctx.storage_env().get_variable_for(destination_symbol_id);
|
||||
|
||||
let ir_operation =
|
||||
lower_expression_to_ir_operation(assign_statement.value(), ctx, fn_ctx);
|
||||
@ -368,7 +417,8 @@ fn lower_expression_to_ir_operation(
|
||||
Expression::Call(call) => IrOperation::Call(lower_to_ir_call(call, ctx, fn_ctx)),
|
||||
Expression::Identifier(identifier) => {
|
||||
let identifier_symbol_id = ctx.nodes_to_symbols()[&identifier.node_id()];
|
||||
let identifier_ir_variable_id = fn_ctx.symbols_to_variables[&identifier_symbol_id];
|
||||
let identifier_ir_variable_id =
|
||||
fn_ctx.storage_env().get_variable_for(identifier_symbol_id);
|
||||
let ir_expression = IrExpression::Variable(identifier_ir_variable_id);
|
||||
IrOperation::Load(ir_expression)
|
||||
}
|
||||
@ -403,7 +453,9 @@ fn lower_expression_to_ir_expression(
|
||||
// make destination temp var
|
||||
let result_type_info_id = ctx.nodes_to_type_infos()[&binary_expression.node_id()];
|
||||
let result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||
let destination_ir_variable_id = fn_ctx.make_t_var(to_ir_type_info(result_type_info));
|
||||
let destination_ir_variable_id = fn_ctx
|
||||
.storage_env_mut()
|
||||
.new_t_var(to_ir_type_info(result_type_info));
|
||||
|
||||
// make assign statement to destination temp var
|
||||
let ir_assign = IrAssign::new(destination_ir_variable_id, ir_operation);
|
||||
@ -425,7 +477,9 @@ fn lower_expression_to_ir_expression(
|
||||
));
|
||||
let result_type_info_id = ctx.nodes_to_type_infos()[&negative_expression.node_id()];
|
||||
let result_type_info = &ctx.type_infos()[result_type_info_id];
|
||||
let destination_ir_variable_id = fn_ctx.make_t_var(to_ir_type_info(result_type_info));
|
||||
let destination_ir_variable_id = fn_ctx
|
||||
.storage_env_mut()
|
||||
.new_t_var(to_ir_type_info(result_type_info));
|
||||
let ir_assign = IrAssign::new(destination_ir_variable_id, ir_operation);
|
||||
|
||||
// push the statement which does the multiply by negative one
|
||||
@ -441,8 +495,9 @@ fn lower_expression_to_ir_expression(
|
||||
// make temp var
|
||||
let return_type_info_id = ctx.nodes_to_type_infos()[&call.node_id()];
|
||||
let return_type_info = &ctx.type_infos()[return_type_info_id];
|
||||
let return_ir_type_info = to_ir_type_info(return_type_info);
|
||||
let t_var_ir_variable_id = fn_ctx.make_t_var(return_ir_type_info);
|
||||
let t_var_ir_variable_id = fn_ctx
|
||||
.storage_env_mut()
|
||||
.new_t_var(to_ir_type_info(return_type_info));
|
||||
|
||||
// assign call to temp var, return temp var expression
|
||||
let ir_operation = IrOperation::Call(ir_call);
|
||||
@ -456,12 +511,14 @@ fn lower_expression_to_ir_expression(
|
||||
}
|
||||
Expression::Identifier(identifier) => {
|
||||
let rhs_symbol_id = ctx.nodes_to_symbols()[&identifier.node_id()];
|
||||
if let Some(rhs_ir_variable_id) = fn_ctx.symbols_to_variables.get(&rhs_symbol_id) {
|
||||
IrExpression::Variable(*rhs_ir_variable_id)
|
||||
} else if let Some(rhs_ir_parameter_id) =
|
||||
fn_ctx.symbols_to_parameters.get(&rhs_symbol_id)
|
||||
if let Some(rhs_ir_variable_id) =
|
||||
fn_ctx.storage_env().maybe_get_variable_for(rhs_symbol_id)
|
||||
{
|
||||
IrExpression::Parameter(*rhs_ir_parameter_id)
|
||||
IrExpression::Variable(rhs_ir_variable_id)
|
||||
} else if let Some(rhs_ir_parameter_id) =
|
||||
fn_ctx.storage_env().maybe_get_parameter_for(rhs_symbol_id)
|
||||
{
|
||||
IrExpression::Parameter(rhs_ir_parameter_id)
|
||||
} else {
|
||||
panic!(
|
||||
"Could not find parameter or variable for symbol_id {}",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user