Work on constructor with new lowering api. WIP.
This commit is contained in:
parent
1bd1e5c23a
commit
d50cc24d0a
@ -1,4 +1,3 @@
|
|||||||
use crate::ast::NodesToSymbols;
|
|
||||||
use crate::ast::field::Field;
|
use crate::ast::field::Field;
|
||||||
use crate::ast::fqn_context::FqnContext;
|
use crate::ast::fqn_context::FqnContext;
|
||||||
use crate::ast::fqn_util::fqn_parts_to_string;
|
use crate::ast::fqn_util::fqn_parts_to_string;
|
||||||
@ -8,6 +7,7 @@ use crate::ast::helpers::{
|
|||||||
use crate::ast::ir_builder::IrBuilder;
|
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::{NodeId, NodesToSymbols, NodesToTypes, SymbolsToTypes};
|
||||||
use crate::diagnostic::{Diagnostic, Diagnostics};
|
use crate::diagnostic::{Diagnostic, Diagnostics};
|
||||||
use crate::ir::ir_allocate::IrAllocate;
|
use crate::ir::ir_allocate::IrAllocate;
|
||||||
use crate::ir::ir_assign::IrAssign;
|
use crate::ir::ir_assign::IrAssign;
|
||||||
@ -34,6 +34,7 @@ use std::ops::Neg;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct Constructor {
|
pub struct Constructor {
|
||||||
|
node_id: NodeId,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
ctor_keyword_source_range: SourceRange,
|
ctor_keyword_source_range: SourceRange,
|
||||||
parameters: Vec<Parameter>,
|
parameters: Vec<Parameter>,
|
||||||
@ -43,12 +44,14 @@ pub struct Constructor {
|
|||||||
|
|
||||||
impl Constructor {
|
impl Constructor {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
node_id: NodeId,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
ctor_keyword_source_range: SourceRange,
|
ctor_keyword_source_range: SourceRange,
|
||||||
parameters: Vec<Parameter>,
|
parameters: Vec<Parameter>,
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
node_id,
|
||||||
is_public,
|
is_public,
|
||||||
ctor_keyword_source_range,
|
ctor_keyword_source_range,
|
||||||
parameters,
|
parameters,
|
||||||
@ -123,6 +126,7 @@ impl Constructor {
|
|||||||
(names_table, diagnostics)
|
(names_table, diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn check_names(&self, symbol_table: &SymbolTable) -> Vec<Diagnostic> {
|
pub fn check_names(&self, symbol_table: &SymbolTable) -> Vec<Diagnostic> {
|
||||||
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
||||||
for parameter in &self.parameters {
|
for parameter in &self.parameters {
|
||||||
@ -131,6 +135,7 @@ impl Constructor {
|
|||||||
diagnostics
|
diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn analyze_local_names(
|
pub fn analyze_local_names(
|
||||||
&self,
|
&self,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
@ -142,12 +147,14 @@ impl Constructor {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn gather_types_into(&self, symbol_table: &SymbolTable, types_table: &mut TypesTable) {
|
pub fn gather_types_into(&self, symbol_table: &SymbolTable, types_table: &mut TypesTable) {
|
||||||
for parameter in &self.parameters {
|
for parameter in &self.parameters {
|
||||||
parameter.gather_types_into(symbol_table, types_table);
|
parameter.gather_types_into(symbol_table, types_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn type_check(
|
pub fn type_check(
|
||||||
&mut self,
|
&mut self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
@ -180,6 +187,7 @@ impl Constructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn to_ir(
|
pub fn to_ir(
|
||||||
&self,
|
&self,
|
||||||
class_symbol: &Rc<ClassSymbol>,
|
class_symbol: &Rc<ClassSymbol>,
|
||||||
@ -315,4 +323,139 @@ impl Constructor {
|
|||||||
entry_block.clone(),
|
entry_block.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lower_to_ir(
|
||||||
|
&self,
|
||||||
|
class_symbol: &Rc<ClassSymbol>,
|
||||||
|
fields: &[Field],
|
||||||
|
nodes_to_symbols: &NodesToSymbols,
|
||||||
|
symbols_to_types: &SymbolsToTypes,
|
||||||
|
nodes_to_types: &NodesToTypes,
|
||||||
|
) -> IrFunction {
|
||||||
|
let mut ir_builder = IrBuilder::new();
|
||||||
|
|
||||||
|
// gather ir_parameters
|
||||||
|
let mut ir_parameters = Vec::new();
|
||||||
|
let base_offset = (self.parameters.len() as isize).neg();
|
||||||
|
for (i, parameter) in self.parameters.iter().enumerate() {
|
||||||
|
let symbol = nodes_to_symbols.get(¶meter.node_id()).unwrap();
|
||||||
|
let parameter_type = symbols_to_types.get(symbol).unwrap();
|
||||||
|
let offset = base_offset + i as isize;
|
||||||
|
let ir_parameter = Rc::new(IrParameter::new(
|
||||||
|
symbol.declared_name(),
|
||||||
|
parameter_type.clone(),
|
||||||
|
offset,
|
||||||
|
));
|
||||||
|
|
||||||
|
// save in builder
|
||||||
|
ir_builder.push_parameter(symbol.unwrap_parameter_symbol(), ir_parameter.clone());
|
||||||
|
|
||||||
|
// push for saving to IrFunction
|
||||||
|
ir_parameters.push(ir_parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// entry-block
|
||||||
|
let entry_block_id = ir_builder.new_block();
|
||||||
|
|
||||||
|
// PART 1: Make self object
|
||||||
|
let self_variable = Rc::new(RefCell::new(IrVariable::new_vr(
|
||||||
|
ir_builder.new_t_var().into(),
|
||||||
|
ir_builder.current_block().id(),
|
||||||
|
&TypeInfo::ParameterizedClass(class_symbol.clone(), Vec::new()), // todo: figure out the correct TypeInfo for this
|
||||||
|
)));
|
||||||
|
|
||||||
|
// save self variable in builder
|
||||||
|
ir_builder
|
||||||
|
.set_self_parameter_or_variable(IrParameterOrVariable::Variable(self_variable.clone()));
|
||||||
|
|
||||||
|
// allocate the self object
|
||||||
|
let ir_assign = IrAssign::new(
|
||||||
|
self_variable.clone(),
|
||||||
|
IrOperation::Allocate(IrAllocate::new(class_symbol.declared_name_owned())),
|
||||||
|
);
|
||||||
|
ir_builder
|
||||||
|
.current_block_mut()
|
||||||
|
.add_statement(IrStatement::Assign(ir_assign));
|
||||||
|
|
||||||
|
// PART 2: Initialize fields that are initialized OUTSIDE the constructor
|
||||||
|
for field in fields {
|
||||||
|
if let Some(initializer) = field.initializer() {
|
||||||
|
let symbol = nodes_to_symbols.get(&field.node_id()).unwrap();
|
||||||
|
let field_type = symbols_to_types.get(symbol).unwrap();
|
||||||
|
let field_symbol = symbol.unwrap_field_symbol();
|
||||||
|
|
||||||
|
// 1. Get a mut ref to the field
|
||||||
|
// mut t_var: Type = &mut self.x
|
||||||
|
let ir_get_field_ref_mut = IrGetFieldRefMut::new(
|
||||||
|
IrParameterOrVariable::Variable(self_variable.clone()),
|
||||||
|
field_symbol.field_index(),
|
||||||
|
);
|
||||||
|
let field_ref_mut_ir_variable = Rc::new(RefCell::new(IrVariable::new_vr(
|
||||||
|
ir_builder.new_t_var().into(),
|
||||||
|
ir_builder.current_block().id(),
|
||||||
|
field_type,
|
||||||
|
)));
|
||||||
|
let ir_assign = IrAssign::new(
|
||||||
|
field_ref_mut_ir_variable.clone(),
|
||||||
|
IrOperation::GetFieldRefMut(ir_get_field_ref_mut),
|
||||||
|
);
|
||||||
|
ir_builder
|
||||||
|
.current_block_mut()
|
||||||
|
.add_statement(IrStatement::Assign(ir_assign));
|
||||||
|
|
||||||
|
// save the mut ref for later uses if needed
|
||||||
|
ir_builder.field_mut_pointer_variables_mut().insert(
|
||||||
|
field.declared_name_owned(),
|
||||||
|
field_ref_mut_ir_variable.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2. Evaluate initializer and save result to mut field ref
|
||||||
|
let ir_expression = initializer.lower_to_ir_expression(
|
||||||
|
&mut ir_builder,
|
||||||
|
nodes_to_symbols,
|
||||||
|
symbols_to_types,
|
||||||
|
nodes_to_types,
|
||||||
|
);
|
||||||
|
let ir_set_field = IrSetField::new(&field_ref_mut_ir_variable, ir_expression);
|
||||||
|
ir_builder
|
||||||
|
.current_block_mut()
|
||||||
|
.add_statement(IrStatement::SetField(ir_set_field));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PART 3. Constructor statements
|
||||||
|
for statement in &self.statements {
|
||||||
|
statement.lower(
|
||||||
|
&mut ir_builder,
|
||||||
|
nodes_to_symbols,
|
||||||
|
symbols_to_types,
|
||||||
|
nodes_to_types,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// PART 4. Return finished self object
|
||||||
|
let ir_return_statement = IrStatement::Return(IrReturn::new(Some(IrExpression::Variable(
|
||||||
|
self_variable.clone(),
|
||||||
|
))));
|
||||||
|
ir_builder
|
||||||
|
.current_block_mut()
|
||||||
|
.add_statement(ir_return_statement);
|
||||||
|
|
||||||
|
// Finish up the builder and return IrFunction
|
||||||
|
ir_builder.finish_block();
|
||||||
|
let entry_block = ir_builder.get_block(entry_block_id);
|
||||||
|
|
||||||
|
let constructor_symbol = nodes_to_symbols
|
||||||
|
.get(&self.node_id)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap_constructor_symbol();
|
||||||
|
|
||||||
|
IrFunction::new(
|
||||||
|
fqn_parts_to_string(constructor_symbol.fqn_parts()),
|
||||||
|
ir_parameters,
|
||||||
|
&TypeInfo::Class(class_symbol.clone()), // TODO
|
||||||
|
entry_block.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,6 +45,10 @@ impl Field {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn node_id(&self) -> NodeId {
|
||||||
|
self.node_id
|
||||||
|
}
|
||||||
|
|
||||||
pub fn declared_name(&self) -> &str {
|
pub fn declared_name(&self) -> &str {
|
||||||
&self.declared_name
|
&self.declared_name
|
||||||
}
|
}
|
||||||
|
|||||||
@ -848,6 +848,7 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
if let Some(ctor_keyword) = ctor_keyword {
|
if let Some(ctor_keyword) = ctor_keyword {
|
||||||
let constructor = Constructor::new(
|
let constructor = Constructor::new(
|
||||||
|
self.next_node_id(),
|
||||||
is_public,
|
is_public,
|
||||||
SourceRange::new(ctor_keyword.start(), ctor_keyword.end()),
|
SourceRange::new(ctor_keyword.start(), ctor_keyword.end()),
|
||||||
parameters,
|
parameters,
|
||||||
|
|||||||
@ -131,4 +131,18 @@ impl Symbol {
|
|||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_parameter_symbol(&self) -> &Rc<ParameterSymbol> {
|
||||||
|
match self {
|
||||||
|
Symbol::Parameter(parameter_symbol) => parameter_symbol,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_constructor_symbol(&self) -> &Rc<ConstructorSymbol> {
|
||||||
|
match self {
|
||||||
|
Symbol::Constructor(constructor_symbol) => constructor_symbol,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user