More fixes to type info, etc. WIP.
This commit is contained in:
parent
fc83cf7827
commit
344761022b
@ -262,11 +262,12 @@ mod tests {
|
|||||||
fn compile_up_to_type_check(
|
fn compile_up_to_type_check(
|
||||||
compilation_unit: &mut CompilationUnit,
|
compilation_unit: &mut CompilationUnit,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
) -> Result<TypesTable, Vec<Diagnostic>> {
|
types_table: &mut TypesTable,
|
||||||
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
compilation_unit.init_scopes(symbol_table);
|
compilation_unit.init_scopes(symbol_table);
|
||||||
compilation_unit.gather_symbols_into(symbol_table)?;
|
compilation_unit.gather_symbols_into(symbol_table)?;
|
||||||
compilation_unit.check_names(symbol_table)?;
|
compilation_unit.check_names(symbol_table)?;
|
||||||
compilation_unit.gather_types(symbol_table)
|
compilation_unit.gather_types_into(symbol_table, types_table)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -281,7 +282,8 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
let mut types_table = compile_up_to_type_check(&mut compilation_unit, &mut symbol_table)?;
|
let mut types_table = TypesTable::new();
|
||||||
|
compile_up_to_type_check(&mut compilation_unit, &mut symbol_table, &mut types_table)?;
|
||||||
let diagnostics = compilation_unit
|
let diagnostics = compilation_unit
|
||||||
.type_check(&symbol_table, &mut types_table)
|
.type_check(&symbol_table, &mut types_table)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@ -303,7 +305,8 @@ mod tests {
|
|||||||
",
|
",
|
||||||
)?;
|
)?;
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
let mut types_table = compile_up_to_type_check(&mut compilation_unit, &mut symbol_table)?;
|
let mut types_table = TypesTable::new();
|
||||||
|
compile_up_to_type_check(&mut compilation_unit, &mut symbol_table, &mut types_table)?;
|
||||||
let diagnostics = compilation_unit
|
let diagnostics = compilation_unit
|
||||||
.type_check(&symbol_table, &mut types_table)
|
.type_check(&symbol_table, &mut types_table)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
@ -323,7 +326,8 @@ mod tests {
|
|||||||
",
|
",
|
||||||
)?;
|
)?;
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
let mut types_table = compile_up_to_type_check(&mut compilation_unit, &mut symbol_table)?;
|
let mut types_table = TypesTable::new();
|
||||||
|
compile_up_to_type_check(&mut compilation_unit, &mut symbol_table, &mut types_table)?;
|
||||||
let diagnostics = compilation_unit
|
let diagnostics = compilation_unit
|
||||||
.type_check(&symbol_table, &mut types_table)
|
.type_check(&symbol_table, &mut types_table)
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|||||||
@ -125,18 +125,16 @@ impl Call {
|
|||||||
TypeInfo::Function(function_symbol) => {
|
TypeInfo::Function(function_symbol) => {
|
||||||
CallableSymbol::Function(function_symbol.clone())
|
CallableSymbol::Function(function_symbol.clone())
|
||||||
}
|
}
|
||||||
TypeInfo::ClassInstance(class_symbol) => {
|
TypeInfo::Class(class_symbol) => match class_symbol.constructor_symbol_owned() {
|
||||||
match class_symbol.constructor_symbol_owned() {
|
None => {
|
||||||
None => {
|
diagnostics.push(class_has_no_constructor(
|
||||||
diagnostics.push(class_has_no_constructor(
|
class_symbol.declared_name(),
|
||||||
class_symbol.declared_name(),
|
self.callee.source_range(),
|
||||||
self.callee.source_range(),
|
));
|
||||||
));
|
return Err(diagnostics);
|
||||||
return Err(diagnostics);
|
|
||||||
}
|
|
||||||
Some(constructor_symbol) => CallableSymbol::Constructor(constructor_symbol),
|
|
||||||
}
|
}
|
||||||
}
|
Some(constructor_symbol) => CallableSymbol::Constructor(constructor_symbol),
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
diagnostics.push(Diagnostic::new(
|
diagnostics.push(Diagnostic::new(
|
||||||
&format!(
|
&format!(
|
||||||
|
|||||||
@ -203,12 +203,11 @@ impl Class {
|
|||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
types_table: &mut TypesTable,
|
types_table: &mut TypesTable,
|
||||||
) -> Result<(), Vec<Diagnostic>> {
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
// instance type
|
// class type
|
||||||
let class_symbol = self.get_class_symbol_owned(symbol_table);
|
let class_symbol = self.get_class_symbol_owned(symbol_table);
|
||||||
types_table.class_instance_types_mut().insert(
|
types_table
|
||||||
class_symbol.clone(),
|
.class_types_mut()
|
||||||
TypeInfo::ClassInstance(class_symbol.clone()),
|
.insert(class_symbol.clone(), TypeInfo::Class(class_symbol.clone()));
|
||||||
);
|
|
||||||
|
|
||||||
// constructor return type
|
// constructor return type
|
||||||
// this works for both declared and default constructors
|
// this works for both declared and default constructors
|
||||||
@ -219,6 +218,11 @@ impl Class {
|
|||||||
.constructor_return_types_mut()
|
.constructor_return_types_mut()
|
||||||
.insert(constructor_symbol, TypeInfo::ClassInstance(class_symbol));
|
.insert(constructor_symbol, TypeInfo::ClassInstance(class_symbol));
|
||||||
|
|
||||||
|
// now the constructor (parameters, etc.)
|
||||||
|
if let Some(constructor) = &self.constructor {
|
||||||
|
constructor.gather_types_into(symbol_table, types_table);
|
||||||
|
}
|
||||||
|
|
||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
|
|
||||||
// generic params
|
// generic params
|
||||||
|
|||||||
@ -95,26 +95,26 @@ impl CompilationUnit {
|
|||||||
diagnostics_result!(diagnostics)
|
diagnostics_result!(diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gather_types(&self, symbol_table: &SymbolTable) -> Result<TypesTable, Vec<Diagnostic>> {
|
pub fn gather_types_into(
|
||||||
let mut types_table = TypesTable::new();
|
&self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
types_table: &mut TypesTable,
|
||||||
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
let mut diagnostics = Vec::new();
|
let mut diagnostics = Vec::new();
|
||||||
|
|
||||||
for class in &self.classes {
|
for class in &self.classes {
|
||||||
handle_diagnostics!(
|
handle_diagnostics!(class.gather_types(symbol_table, types_table), diagnostics);
|
||||||
class.gather_types(symbol_table, &mut types_table),
|
|
||||||
diagnostics
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for function in &self.functions {
|
for function in &self.functions {
|
||||||
function.gather_types(symbol_table, &mut types_table);
|
function.gather_types(symbol_table, types_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
for extern_function in &self.extern_functions {
|
for extern_function in &self.extern_functions {
|
||||||
extern_function.gather_types(symbol_table, &mut types_table);
|
extern_function.gather_types(symbol_table, types_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
ok_or_err_diagnostics!(types_table, diagnostics)
|
diagnostics_result!(diagnostics)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_check(
|
pub fn type_check(
|
||||||
|
|||||||
@ -113,6 +113,12 @@ impl Constructor {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gather_types_into(&self, symbol_table: &SymbolTable, types_table: &mut TypesTable) {
|
||||||
|
for parameter in &self.parameters {
|
||||||
|
parameter.gather_types_into(symbol_table, types_table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn type_check(
|
pub fn type_check(
|
||||||
&mut self,
|
&mut self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
@ -187,7 +193,7 @@ impl Constructor {
|
|||||||
let alloc_assign_destination = IrVariable::new_vr(
|
let alloc_assign_destination = IrVariable::new_vr(
|
||||||
ir_builder.new_t_var().into(),
|
ir_builder.new_t_var().into(),
|
||||||
ir_builder.current_block().id(),
|
ir_builder.current_block().id(),
|
||||||
&TypeInfo::ClassInstance(class_symbol.clone()),
|
&TypeInfo::Class(class_symbol.clone()),
|
||||||
);
|
);
|
||||||
let self_variable = Rc::new(RefCell::new(alloc_assign_destination));
|
let self_variable = Rc::new(RefCell::new(alloc_assign_destination));
|
||||||
|
|
||||||
@ -276,7 +282,7 @@ impl Constructor {
|
|||||||
IrFunction::new(
|
IrFunction::new(
|
||||||
fqn_parts_to_string(constructor_symbol.fqn_parts()),
|
fqn_parts_to_string(constructor_symbol.fqn_parts()),
|
||||||
ir_parameters,
|
ir_parameters,
|
||||||
&TypeInfo::ClassInstance(class_symbol.clone()),
|
&TypeInfo::Class(class_symbol.clone()),
|
||||||
entry_block.clone(),
|
entry_block.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,6 +92,11 @@ impl ExternFunction {
|
|||||||
types_table
|
types_table
|
||||||
.function_return_types_mut()
|
.function_return_types_mut()
|
||||||
.insert(function_symbol, resolved_return_type);
|
.insert(function_symbol, resolved_return_type);
|
||||||
|
|
||||||
|
// parameters
|
||||||
|
for parameter in &self.parameters {
|
||||||
|
parameter.gather_types_into(symbol_table, types_table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_check_parameters(
|
fn type_check_parameters(
|
||||||
|
|||||||
@ -141,6 +141,14 @@ impl Function {
|
|||||||
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())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// self type (the signature)
|
||||||
|
types_table.function_types_mut().insert(
|
||||||
|
function_symbol.clone(),
|
||||||
|
TypeInfo::Function(function_symbol.clone()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// put return type (temporary, this is deprecated)
|
||||||
if let Some(type_use) = &self.return_type {
|
if let Some(type_use) = &self.return_type {
|
||||||
let resolved_return_type = type_use.type_info(symbol_table, types_table).clone();
|
let resolved_return_type = type_use.type_info(symbol_table, types_table).clone();
|
||||||
types_table
|
types_table
|
||||||
@ -151,6 +159,11 @@ impl Function {
|
|||||||
.function_return_types_mut()
|
.function_return_types_mut()
|
||||||
.insert(function_symbol, TypeInfo::Void);
|
.insert(function_symbol, TypeInfo::Void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parameters
|
||||||
|
for parameter in &self.parameters {
|
||||||
|
parameter.gather_types_into(symbol_table, types_table);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_return_type_info(
|
fn get_return_type_info(
|
||||||
|
|||||||
@ -224,10 +224,27 @@ impl Identifier {
|
|||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
types_table: &'a TypesTable,
|
types_table: &'a TypesTable,
|
||||||
) -> &'a TypeInfo {
|
) -> &'a TypeInfo {
|
||||||
let variable_symbol = symbol_table
|
let expressible_symbol = symbol_table
|
||||||
.get_variable_symbol(self.scope_id.unwrap(), &self.name)
|
.find_expressible_symbol(self.scope_id.unwrap(), &self.name)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
types_table.variable_types().get(variable_symbol).unwrap()
|
match expressible_symbol {
|
||||||
|
ExpressibleSymbol::Class(class_symbol) => {
|
||||||
|
types_table.class_types().get(&class_symbol).unwrap()
|
||||||
|
}
|
||||||
|
ExpressibleSymbol::Field(field_symbol) => {
|
||||||
|
types_table.field_types().get(&field_symbol).unwrap()
|
||||||
|
}
|
||||||
|
ExpressibleSymbol::Function(function_symbol) => {
|
||||||
|
types_table.function_types().get(&function_symbol).unwrap()
|
||||||
|
}
|
||||||
|
ExpressibleSymbol::Parameter(parameter_symbol) => types_table
|
||||||
|
.parameter_types()
|
||||||
|
.get(¶meter_symbol)
|
||||||
|
.unwrap(),
|
||||||
|
ExpressibleSymbol::Variable(variable_symbol) => {
|
||||||
|
types_table.variable_types().get(&variable_symbol).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ir_expression(
|
pub fn ir_expression(
|
||||||
|
|||||||
@ -52,6 +52,16 @@ impl Parameter {
|
|||||||
self.type_use.check_names(symbol_table)
|
self.type_use.check_names(symbol_table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gather_types_into(&self, symbol_table: &SymbolTable, types_table: &mut TypesTable) {
|
||||||
|
let type_info = self.type_use.type_info(symbol_table, types_table).clone();
|
||||||
|
let parameter_symbol = symbol_table
|
||||||
|
.get_parameter_symbol_owned(self.scope_id.unwrap(), &self.declared_name)
|
||||||
|
.unwrap();
|
||||||
|
types_table
|
||||||
|
.parameter_types_mut()
|
||||||
|
.insert(parameter_symbol, type_info);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn type_check(
|
pub fn type_check(
|
||||||
&mut self,
|
&mut self,
|
||||||
symbol_table: &SymbolTable,
|
symbol_table: &SymbolTable,
|
||||||
|
|||||||
@ -89,7 +89,10 @@ impl TypeUse {
|
|||||||
TypeSymbol::Class(class_symbol) => types_table
|
TypeSymbol::Class(class_symbol) => types_table
|
||||||
.class_instance_types()
|
.class_instance_types()
|
||||||
.get(&class_symbol)
|
.get(&class_symbol)
|
||||||
.unwrap(),
|
.expect(&format!(
|
||||||
|
"Could not get TypeInfo for {}",
|
||||||
|
self.declared_name
|
||||||
|
)),
|
||||||
TypeSymbol::GenericParameter(generic_parameter_symbol) => types_table
|
TypeSymbol::GenericParameter(generic_parameter_symbol) => types_table
|
||||||
.generic_parameter_types()
|
.generic_parameter_types()
|
||||||
.get(&generic_parameter_symbol)
|
.get(&generic_parameter_symbol)
|
||||||
@ -105,7 +108,7 @@ impl TypeUse {
|
|||||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||||
|
|
||||||
match self.type_info(symbol_table, types_table) {
|
match self.type_info(symbol_table, types_table) {
|
||||||
TypeInfo::ClassInstance(class_symbol) => {
|
TypeInfo::Class(class_symbol) => {
|
||||||
// check number of params/args match
|
// check number of params/args match
|
||||||
let generic_parameters = class_symbol.generic_parameters();
|
let generic_parameters = class_symbol.generic_parameters();
|
||||||
if generic_parameters.len() != self.generic_arguments.len() {
|
if generic_parameters.len() != self.generic_arguments.len() {
|
||||||
@ -168,6 +171,7 @@ mod tests {
|
|||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
use crate::parser::parse_compilation_unit;
|
use crate::parser::parse_compilation_unit;
|
||||||
use crate::symbol_table::SymbolTable;
|
use crate::symbol_table::SymbolTable;
|
||||||
|
use crate::types_table::TypesTable;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn type_check_generics() -> Result<(), Vec<Diagnostic>> {
|
fn type_check_generics() -> Result<(), Vec<Diagnostic>> {
|
||||||
@ -184,11 +188,12 @@ mod tests {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
|
let mut types_table = TypesTable::new();
|
||||||
|
|
||||||
compilation_unit.init_scopes(&mut symbol_table);
|
compilation_unit.init_scopes(&mut symbol_table);
|
||||||
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
||||||
compilation_unit.check_names(&mut symbol_table)?;
|
compilation_unit.check_names(&mut symbol_table)?;
|
||||||
let mut types_table = compilation_unit.gather_types(&symbol_table)?;
|
compilation_unit.gather_types_into(&symbol_table, &mut types_table)?;
|
||||||
compilation_unit.type_check(&mut symbol_table, &mut types_table)?;
|
compilation_unit.type_check(&mut symbol_table, &mut types_table)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -1 +1,46 @@
|
|||||||
mod symbols;
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
|
use crate::symbol_table::SymbolTable;
|
||||||
|
use crate::type_info::TypeInfo;
|
||||||
|
use crate::types_table::TypesTable;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
fn create_simple_primitive(name: &str) -> ClassSymbol {
|
||||||
|
ClassSymbol::new(
|
||||||
|
&Rc::from(name),
|
||||||
|
None,
|
||||||
|
vec![Rc::from(name)],
|
||||||
|
true,
|
||||||
|
0, // global
|
||||||
|
vec![],
|
||||||
|
None,
|
||||||
|
vec![],
|
||||||
|
vec![],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_intrinsic_symbols(symbol_table: &mut SymbolTable) {
|
||||||
|
let primitives = [
|
||||||
|
create_simple_primitive("Int"),
|
||||||
|
create_simple_primitive("Double"),
|
||||||
|
create_simple_primitive("String"),
|
||||||
|
];
|
||||||
|
for primitive in primitives {
|
||||||
|
symbol_table.insert_class_symbol(Rc::new(primitive));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_intrinsic_types(symbol_table: &SymbolTable, types_table: &mut TypesTable) {
|
||||||
|
let primitives = ["Int", "Double", "String"];
|
||||||
|
for primitive in primitives {
|
||||||
|
let symbol = symbol_table.get_class_symbol(0, primitive).unwrap().clone();
|
||||||
|
let type_info = match primitive {
|
||||||
|
"Int" => TypeInfo::Integer,
|
||||||
|
"Double" => TypeInfo::Double,
|
||||||
|
"String" => TypeInfo::String,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
types_table
|
||||||
|
.class_instance_types_mut()
|
||||||
|
.insert(symbol, type_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
use crate::symbol_table::SymbolTable;
|
|
||||||
|
|
||||||
pub fn add_intrinsic_symbols(symbol_table: &mut SymbolTable) {}
|
|
||||||
@ -124,6 +124,7 @@ mod tests {
|
|||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
use crate::parser::parse_compilation_unit;
|
use crate::parser::parse_compilation_unit;
|
||||||
use crate::symbol_table::SymbolTable;
|
use crate::symbol_table::SymbolTable;
|
||||||
|
use crate::types_table::TypesTable;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn overlapping_assignments_bug_when_k_2() -> Result<(), Vec<Diagnostic>> {
|
fn overlapping_assignments_bug_when_k_2() -> Result<(), Vec<Diagnostic>> {
|
||||||
@ -139,12 +140,13 @@ mod tests {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
|
let mut types_table = TypesTable::new();
|
||||||
|
|
||||||
compilation_unit.init_scopes(&mut symbol_table);
|
compilation_unit.init_scopes(&mut symbol_table);
|
||||||
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
||||||
compilation_unit.check_names(&mut symbol_table)?;
|
compilation_unit.check_names(&mut symbol_table)?;
|
||||||
let mut types_table = compilation_unit.gather_types(&symbol_table)?;
|
compilation_unit.gather_types_into(&symbol_table, &mut types_table)?;
|
||||||
compilation_unit.type_check(&mut symbol_table, &mut types_table)?;
|
compilation_unit.type_check(&symbol_table, &mut types_table)?;
|
||||||
|
|
||||||
let main = compilation_unit
|
let main = compilation_unit
|
||||||
.functions()
|
.functions()
|
||||||
|
|||||||
@ -51,7 +51,7 @@ impl IrField {
|
|||||||
TypeInfo::Integer => VmTypeInfo::Int,
|
TypeInfo::Integer => VmTypeInfo::Int,
|
||||||
TypeInfo::Double => VmTypeInfo::Double,
|
TypeInfo::Double => VmTypeInfo::Double,
|
||||||
TypeInfo::String => VmTypeInfo::String,
|
TypeInfo::String => VmTypeInfo::String,
|
||||||
TypeInfo::ClassInstance(class_symbol) => {
|
TypeInfo::Class(class_symbol) => {
|
||||||
VmTypeInfo::ClassInstance(fqn_parts_to_string(class_symbol.fqn_parts()).into())
|
VmTypeInfo::ClassInstance(fqn_parts_to_string(class_symbol.fqn_parts()).into())
|
||||||
}
|
}
|
||||||
TypeInfo::GenericType(_) => VmTypeInfo::Any,
|
TypeInfo::GenericType(_) => VmTypeInfo::Any,
|
||||||
|
|||||||
@ -2,7 +2,7 @@ pub mod ast;
|
|||||||
pub mod constants_table;
|
pub mod constants_table;
|
||||||
pub mod diagnostic;
|
pub mod diagnostic;
|
||||||
pub mod error_codes;
|
pub mod error_codes;
|
||||||
mod intrinsics;
|
pub mod intrinsics;
|
||||||
pub mod ir;
|
pub mod ir;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|||||||
@ -11,7 +11,11 @@ pub enum TypeInfo {
|
|||||||
Double,
|
Double,
|
||||||
String,
|
String,
|
||||||
Function(Rc<FunctionSymbol>),
|
Function(Rc<FunctionSymbol>),
|
||||||
|
Class(Rc<ClassSymbol>),
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
ClassInstance(Rc<ClassSymbol>),
|
ClassInstance(Rc<ClassSymbol>),
|
||||||
|
|
||||||
GenericType(Rc<GenericParameterSymbol>),
|
GenericType(Rc<GenericParameterSymbol>),
|
||||||
Void,
|
Void,
|
||||||
}
|
}
|
||||||
@ -33,6 +37,9 @@ impl Display for TypeInfo {
|
|||||||
}
|
}
|
||||||
write!(f, ")")
|
write!(f, ")")
|
||||||
}
|
}
|
||||||
|
TypeInfo::Class(class_symbol) => {
|
||||||
|
write!(f, "Class({:?})", class_symbol)
|
||||||
|
}
|
||||||
TypeInfo::ClassInstance(class_symbol) => {
|
TypeInfo::ClassInstance(class_symbol) => {
|
||||||
write!(f, "{}", class_symbol.declared_name())
|
write!(f, "{}", class_symbol.declared_name())
|
||||||
}
|
}
|
||||||
@ -68,6 +75,10 @@ impl TypeInfo {
|
|||||||
TypeInfo::Function(_) => {
|
TypeInfo::Function(_) => {
|
||||||
unimplemented!("Type matching on Functions not yet supported.")
|
unimplemented!("Type matching on Functions not yet supported.")
|
||||||
}
|
}
|
||||||
|
TypeInfo::Class(class_symbol) => match other {
|
||||||
|
TypeInfo::Class(other_class_symbol) => class_symbol == other_class_symbol,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
TypeInfo::ClassInstance(class_symbol) => {
|
TypeInfo::ClassInstance(class_symbol) => {
|
||||||
match other {
|
match other {
|
||||||
TypeInfo::ClassInstance(other_class_symbol) => {
|
TypeInfo::ClassInstance(other_class_symbol) => {
|
||||||
|
|||||||
@ -10,10 +10,12 @@ use std::collections::HashMap;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct TypesTable {
|
pub struct TypesTable {
|
||||||
|
class_types: HashMap<Rc<ClassSymbol>, TypeInfo>,
|
||||||
class_instance_types: HashMap<Rc<ClassSymbol>, TypeInfo>,
|
class_instance_types: HashMap<Rc<ClassSymbol>, TypeInfo>,
|
||||||
generic_parameter_types: HashMap<Rc<GenericParameterSymbol>, TypeInfo>,
|
generic_parameter_types: HashMap<Rc<GenericParameterSymbol>, TypeInfo>,
|
||||||
field_types: HashMap<Rc<FieldSymbol>, TypeInfo>,
|
field_types: HashMap<Rc<FieldSymbol>, TypeInfo>,
|
||||||
constructor_return_types: HashMap<Rc<ConstructorSymbol>, TypeInfo>,
|
constructor_return_types: HashMap<Rc<ConstructorSymbol>, TypeInfo>,
|
||||||
|
function_types: HashMap<Rc<FunctionSymbol>, TypeInfo>,
|
||||||
function_return_types: HashMap<Rc<FunctionSymbol>, TypeInfo>,
|
function_return_types: HashMap<Rc<FunctionSymbol>, TypeInfo>,
|
||||||
parameter_types: HashMap<Rc<ParameterSymbol>, TypeInfo>,
|
parameter_types: HashMap<Rc<ParameterSymbol>, TypeInfo>,
|
||||||
variable_types: HashMap<Rc<VariableSymbol>, TypeInfo>,
|
variable_types: HashMap<Rc<VariableSymbol>, TypeInfo>,
|
||||||
@ -22,16 +24,26 @@ pub struct TypesTable {
|
|||||||
impl TypesTable {
|
impl TypesTable {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
class_types: HashMap::new(),
|
||||||
class_instance_types: HashMap::new(),
|
class_instance_types: HashMap::new(),
|
||||||
generic_parameter_types: HashMap::new(),
|
generic_parameter_types: HashMap::new(),
|
||||||
field_types: HashMap::new(),
|
field_types: HashMap::new(),
|
||||||
parameter_types: HashMap::new(),
|
parameter_types: HashMap::new(),
|
||||||
variable_types: HashMap::new(),
|
variable_types: HashMap::new(),
|
||||||
|
function_types: HashMap::new(),
|
||||||
function_return_types: HashMap::new(),
|
function_return_types: HashMap::new(),
|
||||||
constructor_return_types: HashMap::new(),
|
constructor_return_types: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn class_types(&self) -> &HashMap<Rc<ClassSymbol>, TypeInfo> {
|
||||||
|
&self.class_types
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn class_types_mut(&mut self) -> &mut HashMap<Rc<ClassSymbol>, TypeInfo> {
|
||||||
|
&mut self.class_types
|
||||||
|
}
|
||||||
|
|
||||||
pub fn class_instance_types(&self) -> &HashMap<Rc<ClassSymbol>, TypeInfo> {
|
pub fn class_instance_types(&self) -> &HashMap<Rc<ClassSymbol>, TypeInfo> {
|
||||||
&self.class_instance_types
|
&self.class_instance_types
|
||||||
}
|
}
|
||||||
@ -74,18 +86,30 @@ impl TypesTable {
|
|||||||
&mut self.variable_types
|
&mut self.variable_types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn function_types(&self) -> &HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
||||||
|
&self.function_types
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function_types_mut(&mut self) -> &mut HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
||||||
|
&mut self.function_types
|
||||||
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn function_return_types(&self) -> &HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
pub fn function_return_types(&self) -> &HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
||||||
&self.function_return_types
|
&self.function_return_types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn function_return_types_mut(&mut self) -> &mut HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
pub fn function_return_types_mut(&mut self) -> &mut HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
||||||
&mut self.function_return_types
|
&mut self.function_return_types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn constructor_return_types(&self) -> &HashMap<Rc<ConstructorSymbol>, TypeInfo> {
|
pub fn constructor_return_types(&self) -> &HashMap<Rc<ConstructorSymbol>, TypeInfo> {
|
||||||
&self.constructor_return_types
|
&self.constructor_return_types
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[deprecated]
|
||||||
pub fn constructor_return_types_mut(
|
pub fn constructor_return_types_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> &mut HashMap<Rc<ConstructorSymbol>, TypeInfo> {
|
) -> &mut HashMap<Rc<ConstructorSymbol>, TypeInfo> {
|
||||||
|
|||||||
@ -2,8 +2,10 @@
|
|||||||
mod e2e_tests {
|
mod e2e_tests {
|
||||||
use dmc_lib::constants_table::ConstantsTable;
|
use dmc_lib::constants_table::ConstantsTable;
|
||||||
use dmc_lib::diagnostic::Diagnostic;
|
use dmc_lib::diagnostic::Diagnostic;
|
||||||
|
use dmc_lib::intrinsics::{insert_intrinsic_symbols, insert_intrinsic_types};
|
||||||
use dmc_lib::parser::parse_compilation_unit;
|
use dmc_lib::parser::parse_compilation_unit;
|
||||||
use dmc_lib::symbol_table::SymbolTable;
|
use dmc_lib::symbol_table::SymbolTable;
|
||||||
|
use dmc_lib::types_table::TypesTable;
|
||||||
use dvm_lib::vm::class::Class;
|
use dvm_lib::vm::class::Class;
|
||||||
use dvm_lib::vm::constant::{Constant, StringConstant};
|
use dvm_lib::vm::constant::{Constant, StringConstant};
|
||||||
use dvm_lib::vm::function::Function;
|
use dvm_lib::vm::function::Function;
|
||||||
@ -36,11 +38,16 @@ mod e2e_tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
|
symbol_table.push_module_scope("global_scope");
|
||||||
|
insert_intrinsic_symbols(&mut symbol_table);
|
||||||
|
|
||||||
|
let mut types_table = TypesTable::new();
|
||||||
|
insert_intrinsic_types(&symbol_table, &mut types_table);
|
||||||
|
|
||||||
compilation_unit.init_scopes(&mut symbol_table);
|
compilation_unit.init_scopes(&mut symbol_table);
|
||||||
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
||||||
compilation_unit.check_names(&mut symbol_table)?;
|
compilation_unit.check_names(&mut symbol_table)?;
|
||||||
let mut types_table = compilation_unit.gather_types(&symbol_table)?;
|
compilation_unit.gather_types_into(&symbol_table, &mut types_table)?;
|
||||||
compilation_unit.type_check(&symbol_table, &mut types_table)?;
|
compilation_unit.type_check(&symbol_table, &mut types_table)?;
|
||||||
|
|
||||||
let (ir_classes, mut ir_functions) = compilation_unit.to_ir(&symbol_table, &types_table);
|
let (ir_classes, mut ir_functions) = compilation_unit.to_ir(&symbol_table, &types_table);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user