Work on classes and lowering to IR. WIP.
This commit is contained in:
parent
11d368ab1a
commit
1bd1e5c23a
@ -11,7 +11,7 @@ use crate::ast::helpers::{
|
|||||||
resolve_ctor_name,
|
resolve_ctor_name,
|
||||||
};
|
};
|
||||||
use crate::ast::statement::Statement;
|
use crate::ast::statement::Statement;
|
||||||
use crate::ast::{NodeId, NodesToSymbols};
|
use crate::ast::{FunctionReturnTypes, NodeId, NodesToSymbols, NodesToTypes, SymbolsToTypes};
|
||||||
use crate::diagnostic::{Diagnostic, Diagnostics};
|
use crate::diagnostic::{Diagnostic, Diagnostics};
|
||||||
use crate::error_codes::{FIELD_MULTIPLE_INIT, FIELD_UNINIT};
|
use crate::error_codes::{FIELD_MULTIPLE_INIT, FIELD_UNINIT};
|
||||||
use crate::ir::ir_class::{IrClass, IrField};
|
use crate::ir::ir_class::{IrClass, IrField};
|
||||||
@ -187,6 +187,7 @@ impl Class {
|
|||||||
(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();
|
||||||
|
|
||||||
@ -231,6 +232,7 @@ impl Class {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn analyze_local_names(&self, symbol_table: &mut SymbolTable) -> Vec<Diagnostic> {
|
pub fn analyze_local_names(&self, symbol_table: &mut SymbolTable) -> Vec<Diagnostic> {
|
||||||
let class_symbol = self.get_class_symbol_owned(symbol_table);
|
let class_symbol = self.get_class_symbol_owned(symbol_table);
|
||||||
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
let mut diagnostics: Vec<Diagnostic> = Vec::new();
|
||||||
@ -244,6 +246,7 @@ impl Class {
|
|||||||
diagnostics
|
diagnostics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn gather_types(
|
pub fn gather_types(
|
||||||
&self,
|
&self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
@ -472,6 +475,7 @@ impl Class {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn type_check(
|
pub fn type_check(
|
||||||
&mut self,
|
&mut self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
@ -485,6 +489,7 @@ impl Class {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn to_ir(
|
pub fn to_ir(
|
||||||
&self,
|
&self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
@ -529,4 +534,43 @@ impl Class {
|
|||||||
|
|
||||||
(ir_class, ir_functions)
|
(ir_class, ir_functions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lower_to_ir(
|
||||||
|
&self,
|
||||||
|
nodes_to_symbols: &NodesToSymbols,
|
||||||
|
symbols_to_types: &SymbolsToTypes,
|
||||||
|
nodes_to_types: &NodesToTypes,
|
||||||
|
function_return_types: &FunctionReturnTypes,
|
||||||
|
) -> (IrClass, Vec<IrFunction>) {
|
||||||
|
let mut ir_functions = Vec::new();
|
||||||
|
|
||||||
|
if let Some(constructor) = &self.constructor {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
|
||||||
|
for function in &self.functions {
|
||||||
|
ir_functions.push(function.lower_to_ir_static(
|
||||||
|
nodes_to_symbols,
|
||||||
|
symbols_to_types,
|
||||||
|
nodes_to_types,
|
||||||
|
function_return_types,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let self_class_symbol = nodes_to_symbols
|
||||||
|
.get(&self.node_id)
|
||||||
|
.unwrap()
|
||||||
|
.unwrap_class_symbol();
|
||||||
|
|
||||||
|
let ir_class = IrClass::new(
|
||||||
|
self_class_symbol.declared_name_owned(),
|
||||||
|
fqn_parts_to_string(self_class_symbol.fqn_parts()).into(),
|
||||||
|
self.fields
|
||||||
|
.iter()
|
||||||
|
.map(|field| field.lower_to_ir_field(nodes_to_symbols, symbols_to_types))
|
||||||
|
.collect(),
|
||||||
|
);
|
||||||
|
|
||||||
|
(ir_class, ir_functions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -245,7 +245,7 @@ impl CompilationUnit {
|
|||||||
diagnostics_result!(diagnostics)
|
diagnostics_result!(diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower(
|
pub fn lower_to_ir(
|
||||||
&self,
|
&self,
|
||||||
nodes_to_symbols: &NodesToSymbols,
|
nodes_to_symbols: &NodesToSymbols,
|
||||||
symbols_to_types: &SymbolsToTypes,
|
symbols_to_types: &SymbolsToTypes,
|
||||||
@ -256,7 +256,7 @@ impl CompilationUnit {
|
|||||||
let mut ir_functions = Vec::new();
|
let mut ir_functions = Vec::new();
|
||||||
|
|
||||||
for function in &self.functions {
|
for function in &self.functions {
|
||||||
ir_functions.push(function.lower_static(
|
ir_functions.push(function.lower_to_ir_static(
|
||||||
nodes_to_symbols,
|
nodes_to_symbols,
|
||||||
symbols_to_types,
|
symbols_to_types,
|
||||||
nodes_to_types,
|
nodes_to_types,
|
||||||
@ -264,9 +264,21 @@ impl CompilationUnit {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for class in &self.classes {
|
||||||
|
let (ir_class, mut class_ir_functions) = class.lower_to_ir(
|
||||||
|
nodes_to_symbols,
|
||||||
|
symbols_to_types,
|
||||||
|
nodes_to_types,
|
||||||
|
function_return_types,
|
||||||
|
);
|
||||||
|
ir_classes.push(ir_class);
|
||||||
|
ir_functions.append(&mut class_ir_functions);
|
||||||
|
}
|
||||||
|
|
||||||
(ir_classes, ir_functions)
|
(ir_classes, ir_functions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn to_ir(
|
pub fn to_ir(
|
||||||
&self,
|
&self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
use crate::ast::NodesToSymbols;
|
|
||||||
use crate::ast::expression::Expression;
|
use crate::ast::expression::Expression;
|
||||||
use crate::ast::helpers::insert_resolved_names_into;
|
use crate::ast::helpers::insert_resolved_names_into;
|
||||||
use crate::ast::type_use::TypeUse;
|
use crate::ast::type_use::TypeUse;
|
||||||
|
use crate::ast::{NodeId, NodesToSymbols, SymbolsToTypes};
|
||||||
use crate::diagnostic::{Diagnostic, Diagnostics};
|
use crate::diagnostic::{Diagnostic, Diagnostics};
|
||||||
use crate::diagnostic_factories::field_has_no_type_or_init;
|
use crate::diagnostic_factories::field_has_no_type_or_init;
|
||||||
|
use crate::ir::ir_class::IrField;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
use crate::symbol::class_symbol::ClassSymbol;
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol::field_symbol::FieldSymbol;
|
use crate::symbol::field_symbol::FieldSymbol;
|
||||||
@ -12,6 +13,7 @@ use crate::types_table::TypesTable;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct Field {
|
pub struct Field {
|
||||||
|
node_id: NodeId,
|
||||||
declared_name: Rc<str>,
|
declared_name: Rc<str>,
|
||||||
declared_name_source_range: SourceRange,
|
declared_name_source_range: SourceRange,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
@ -23,6 +25,7 @@ pub struct Field {
|
|||||||
|
|
||||||
impl Field {
|
impl Field {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
node_id: NodeId,
|
||||||
declared_name: &str,
|
declared_name: &str,
|
||||||
declared_name_source_range: SourceRange,
|
declared_name_source_range: SourceRange,
|
||||||
is_public: bool,
|
is_public: bool,
|
||||||
@ -31,6 +34,7 @@ impl Field {
|
|||||||
initializer: Option<Expression>,
|
initializer: Option<Expression>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
node_id,
|
||||||
declared_name: declared_name.into(),
|
declared_name: declared_name.into(),
|
||||||
declared_name_source_range,
|
declared_name_source_range,
|
||||||
is_public,
|
is_public,
|
||||||
@ -215,4 +219,18 @@ impl Field {
|
|||||||
None => Ok(()),
|
None => Ok(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lower_to_ir_field(
|
||||||
|
&self,
|
||||||
|
nodes_to_symbols: &NodesToSymbols,
|
||||||
|
symbols_to_types: &SymbolsToTypes,
|
||||||
|
) -> IrField {
|
||||||
|
let symbol = nodes_to_symbols.get(&self.node_id).unwrap();
|
||||||
|
let field_type = symbols_to_types.get(symbol).unwrap();
|
||||||
|
IrField::new(
|
||||||
|
self.declared_name.clone(),
|
||||||
|
symbol.unwrap_field_symbol().field_index(), // todo: this needs to be stored NOT in the symbol
|
||||||
|
field_type.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ use crate::source_range::SourceRange;
|
|||||||
use crate::symbol::Symbol;
|
use crate::symbol::Symbol;
|
||||||
use crate::symbol::class_symbol::ClassSymbol;
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol::function_symbol::FunctionSymbol;
|
use crate::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||||
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;
|
||||||
@ -33,7 +34,8 @@ pub struct Function {
|
|||||||
parameters: Vec<Parameter>,
|
parameters: Vec<Parameter>,
|
||||||
return_type: Option<TypeUse>,
|
return_type: Option<TypeUse>,
|
||||||
statements: Vec<Statement>,
|
statements: Vec<Statement>,
|
||||||
scope_id: Option<usize>,
|
container_scope_id: Option<usize>,
|
||||||
|
function_scope_id: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
@ -54,7 +56,8 @@ impl Function {
|
|||||||
parameters,
|
parameters,
|
||||||
return_type,
|
return_type,
|
||||||
statements,
|
statements,
|
||||||
scope_id: None,
|
container_scope_id: None,
|
||||||
|
function_scope_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,9 +74,10 @@ impl Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_scopes(&mut self, symbol_table: &mut SymbolTable, container_scope: usize) {
|
pub fn init_scopes(&mut self, symbol_table: &mut SymbolTable, container_scope: usize) {
|
||||||
self.scope_id = Some(container_scope);
|
self.container_scope_id = Some(container_scope);
|
||||||
let function_scope =
|
let function_scope =
|
||||||
symbol_table.push_function_scope(&format!("function_scope({})", self.declared_name));
|
symbol_table.push_function_scope(&format!("function_scope({})", self.declared_name));
|
||||||
|
self.function_scope_id = Some(function_scope);
|
||||||
|
|
||||||
for parameter in &mut self.parameters {
|
for parameter in &mut self.parameters {
|
||||||
parameter.init_scopes(symbol_table, function_scope);
|
parameter.init_scopes(symbol_table, function_scope);
|
||||||
@ -102,6 +106,17 @@ impl Function {
|
|||||||
let mut all_symbols: Vec<Symbol> = vec![];
|
let mut all_symbols: Vec<Symbol> = vec![];
|
||||||
|
|
||||||
let mut parameter_symbols = Vec::new();
|
let mut parameter_symbols = Vec::new();
|
||||||
|
|
||||||
|
if is_method {
|
||||||
|
let self_parameter_symbol = Rc::new(ParameterSymbol::new(
|
||||||
|
&Rc::from("self"),
|
||||||
|
None,
|
||||||
|
self.function_scope_id.unwrap(),
|
||||||
|
));
|
||||||
|
parameter_symbols.push(self_parameter_symbol.clone());
|
||||||
|
all_symbols.push(Symbol::Parameter(self_parameter_symbol))
|
||||||
|
}
|
||||||
|
|
||||||
collect_parameter_symbols_into(&self.parameters, &mut all_symbols, &mut parameter_symbols);
|
collect_parameter_symbols_into(&self.parameters, &mut all_symbols, &mut parameter_symbols);
|
||||||
|
|
||||||
let function_symbol = Rc::new(FunctionSymbol::new(
|
let function_symbol = Rc::new(FunctionSymbol::new(
|
||||||
@ -110,7 +125,7 @@ impl Function {
|
|||||||
fqn_context.resolve(self.declared_name()),
|
fqn_context.resolve(self.declared_name()),
|
||||||
false,
|
false,
|
||||||
is_method,
|
is_method,
|
||||||
self.scope_id.unwrap(),
|
self.container_scope_id.unwrap(),
|
||||||
parameter_symbols,
|
parameter_symbols,
|
||||||
));
|
));
|
||||||
all_symbols.push(Symbol::Function(function_symbol.clone()));
|
all_symbols.push(Symbol::Function(function_symbol.clone()));
|
||||||
@ -239,7 +254,7 @@ impl Function {
|
|||||||
#[deprecated]
|
#[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.container_scope_id.unwrap(), self.declared_name())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// self type (the signature)
|
// self type (the signature)
|
||||||
@ -336,7 +351,7 @@ impl Function {
|
|||||||
) -> Result<(), Vec<Diagnostic>> {
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
let mut diagnostics = vec![];
|
let mut diagnostics = vec![];
|
||||||
let function_symbol = symbol_table
|
let function_symbol = symbol_table
|
||||||
.get_function_symbol(self.scope_id.unwrap(), self.declared_name())
|
.get_function_symbol(self.container_scope_id.unwrap(), self.declared_name())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
@ -408,6 +423,7 @@ impl Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn to_ir(
|
pub fn to_ir(
|
||||||
&self,
|
&self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
@ -416,7 +432,7 @@ impl Function {
|
|||||||
) -> IrFunction {
|
) -> IrFunction {
|
||||||
let mut builder = IrBuilder::new();
|
let mut builder = IrBuilder::new();
|
||||||
let function_symbol = symbol_table
|
let function_symbol = symbol_table
|
||||||
.get_function_symbol(self.scope_id.unwrap(), self.declared_name())
|
.get_function_symbol(self.container_scope_id.unwrap(), self.declared_name())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
@ -441,7 +457,7 @@ impl Function {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn lower_static(
|
pub fn lower_to_ir_static(
|
||||||
&self,
|
&self,
|
||||||
nodes_to_symbols: &NodesToSymbols,
|
nodes_to_symbols: &NodesToSymbols,
|
||||||
symbols_to_types: &SymbolsToTypes,
|
symbols_to_types: &SymbolsToTypes,
|
||||||
|
|||||||
@ -52,7 +52,7 @@ impl Parameter {
|
|||||||
pub fn make_symbol(&self) -> ParameterSymbol {
|
pub fn make_symbol(&self) -> ParameterSymbol {
|
||||||
ParameterSymbol::new(
|
ParameterSymbol::new(
|
||||||
&self.declared_name,
|
&self.declared_name,
|
||||||
self.declared_name_source_range.clone(),
|
Some(self.declared_name_source_range.clone()),
|
||||||
self.scope_id.unwrap(),
|
self.scope_id.unwrap(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -899,6 +899,7 @@ impl<'a> Parser<'a> {
|
|||||||
|
|
||||||
if let Some(identifier) = identifier {
|
if let Some(identifier) = identifier {
|
||||||
let field = Field::new(
|
let field = Field::new(
|
||||||
|
self.next_node_id(),
|
||||||
self.token_text(&identifier),
|
self.token_text(&identifier),
|
||||||
SourceRange::new(identifier.start(), identifier.end()),
|
SourceRange::new(identifier.start(), identifier.end()),
|
||||||
is_public,
|
is_public,
|
||||||
|
|||||||
@ -36,7 +36,7 @@ impl ExpressibleSymbol {
|
|||||||
Some(function_symbol.declared_name_source_range())
|
Some(function_symbol.declared_name_source_range())
|
||||||
}
|
}
|
||||||
ExpressibleSymbol::Parameter(parameter_symbol) => {
|
ExpressibleSymbol::Parameter(parameter_symbol) => {
|
||||||
Some(parameter_symbol.declared_name_source_range())
|
parameter_symbol.declared_name_source_range()
|
||||||
}
|
}
|
||||||
ExpressibleSymbol::Variable(variable_symbol) => {
|
ExpressibleSymbol::Variable(variable_symbol) => {
|
||||||
Some(variable_symbol.declared_name_source_range())
|
Some(variable_symbol.declared_name_source_range())
|
||||||
|
|||||||
@ -72,9 +72,7 @@ impl Symbol {
|
|||||||
Some(constructor_symbol.declared_name_source_range())
|
Some(constructor_symbol.declared_name_source_range())
|
||||||
}
|
}
|
||||||
Symbol::Function(function_symbol) => Some(function_symbol.declared_name_source_range()),
|
Symbol::Function(function_symbol) => Some(function_symbol.declared_name_source_range()),
|
||||||
Symbol::Parameter(parameter_symbol) => {
|
Symbol::Parameter(parameter_symbol) => parameter_symbol.declared_name_source_range(),
|
||||||
Some(parameter_symbol.declared_name_source_range())
|
|
||||||
}
|
|
||||||
Symbol::Variable(variable_symbol) => Some(variable_symbol.declared_name_source_range()),
|
Symbol::Variable(variable_symbol) => Some(variable_symbol.declared_name_source_range()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,4 +117,18 @@ impl Symbol {
|
|||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_class_symbol(&self) -> &Rc<ClassSymbol> {
|
||||||
|
match self {
|
||||||
|
Symbol::Class(class_symbol) => class_symbol,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unwrap_field_symbol(&self) -> &Rc<FieldSymbol> {
|
||||||
|
match self {
|
||||||
|
Symbol::Field(field_symbol) => field_symbol,
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,17 @@
|
|||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
use crate::symbol::Symbol;
|
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct ParameterSymbol {
|
pub struct ParameterSymbol {
|
||||||
declared_name: Rc<str>,
|
declared_name: Rc<str>,
|
||||||
declared_name_source_range: SourceRange,
|
declared_name_source_range: Option<SourceRange>,
|
||||||
scope_id: usize,
|
scope_id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParameterSymbol {
|
impl ParameterSymbol {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
declared_name: &Rc<str>,
|
declared_name: &Rc<str>,
|
||||||
declared_name_source_range: SourceRange,
|
declared_name_source_range: Option<SourceRange>,
|
||||||
scope_id: usize,
|
scope_id: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -30,8 +29,8 @@ impl ParameterSymbol {
|
|||||||
self.declared_name.clone()
|
self.declared_name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declared_name_source_range(&self) -> &SourceRange {
|
pub fn declared_name_source_range(&self) -> Option<&SourceRange> {
|
||||||
&self.declared_name_source_range
|
self.declared_name_source_range.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scope_id(&self) -> usize {
|
pub fn scope_id(&self) -> usize {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user