Fixing bugs. WIP.
This commit is contained in:
parent
4e8fa159c0
commit
912f208705
@ -205,6 +205,14 @@ impl Class {
|
||||
|
||||
let mut diagnostics = Vec::new();
|
||||
|
||||
// generic params
|
||||
for generic_parameter in &self.generic_parameters {
|
||||
handle_diagnostics!(
|
||||
generic_parameter.gather_types(symbol_table, types_table),
|
||||
diagnostics
|
||||
);
|
||||
}
|
||||
|
||||
// field types
|
||||
for field in &self.fields {
|
||||
handle_diagnostics!(field.gather_types(symbol_table, types_table), diagnostics);
|
||||
|
||||
@ -3,6 +3,7 @@ use crate::diagnostic::Diagnostic;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::type_info::TypeInfo;
|
||||
use crate::types_table::TypesTable;
|
||||
use crate::{diagnostics_result, handle_diagnostics};
|
||||
use std::cell::RefCell;
|
||||
@ -53,6 +54,32 @@ impl GenericParameter {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn gather_types(
|
||||
&self,
|
||||
symbol_table: &SymbolTable,
|
||||
types_table: &mut TypesTable,
|
||||
) -> Result<(), Vec<Diagnostic>> {
|
||||
// self param
|
||||
let generic_parameter_symbol = symbol_table
|
||||
.get_generic_parameter_symbol_owned(self.scope_id.unwrap(), &self.declared_name)
|
||||
.unwrap();
|
||||
types_table.generic_parameter_types_mut().insert(
|
||||
generic_parameter_symbol.clone(),
|
||||
TypeInfo::GenericType(generic_parameter_symbol),
|
||||
);
|
||||
|
||||
let mut diagnostics = Vec::new();
|
||||
|
||||
for type_use in &self.extends {
|
||||
handle_diagnostics!(
|
||||
type_use.gather_types(symbol_table, types_table),
|
||||
diagnostics
|
||||
);
|
||||
}
|
||||
|
||||
diagnostics_result!(diagnostics)
|
||||
}
|
||||
|
||||
pub fn type_check(
|
||||
&mut self,
|
||||
symbol_table: &SymbolTable,
|
||||
|
||||
@ -2,7 +2,6 @@ use crate::ast::diagnostic_factories::symbol_not_found;
|
||||
use crate::diagnostic::Diagnostic;
|
||||
use crate::error_codes::INCORRECT_GENERIC_ARGUMENTS;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::type_symbol::TypeSymbol;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::type_info::TypeInfo;
|
||||
@ -57,55 +56,24 @@ impl TypeUse {
|
||||
|
||||
// check generic args
|
||||
for type_use in &self.generic_arguments {
|
||||
type_use.check_names(symbol_table);
|
||||
diagnostics.append(&mut type_use.check_names(symbol_table));
|
||||
}
|
||||
|
||||
diagnostics
|
||||
}
|
||||
|
||||
pub fn gather_declared_names(
|
||||
&mut self,
|
||||
symbol_table: &mut SymbolTable,
|
||||
) -> Result<(), Vec<Diagnostic>> {
|
||||
self.scope_id = Some(symbol_table.current_scope_id());
|
||||
let mut inner_diagnostics: Vec<Diagnostic> = vec![];
|
||||
for generic_argument in &mut self.generic_arguments {
|
||||
handle_diagnostics!(
|
||||
generic_argument.gather_declared_names(symbol_table),
|
||||
inner_diagnostics
|
||||
);
|
||||
}
|
||||
diagnostics_result!(inner_diagnostics)
|
||||
}
|
||||
|
||||
pub fn check_name_usages(
|
||||
&mut self,
|
||||
pub fn gather_types(
|
||||
&self,
|
||||
symbol_table: &SymbolTable,
|
||||
class_context: Option<&Rc<ClassSymbol>>,
|
||||
types_table: &mut TypesTable,
|
||||
) -> Result<(), Vec<Diagnostic>> {
|
||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||
|
||||
if symbol_table
|
||||
.find_type_symbol(self.scope_id.unwrap(), &self.declared_name)
|
||||
.is_none()
|
||||
{
|
||||
// this is wonky
|
||||
let diagnostic = Diagnostic::new(
|
||||
&format!("Unable to resolve symbol {}", self.declared_name),
|
||||
self.declared_name_source_range.start(),
|
||||
self.declared_name_source_range.end(),
|
||||
)
|
||||
.with_reporter(file!(), line!());
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
for generic_argument in &mut self.generic_arguments {
|
||||
let mut diagnostics = Vec::new();
|
||||
for type_use in &self.generic_arguments {
|
||||
handle_diagnostics!(
|
||||
generic_argument.check_name_usages(symbol_table, class_context),
|
||||
type_use.gather_types(symbol_table, types_table),
|
||||
diagnostics
|
||||
);
|
||||
}
|
||||
|
||||
diagnostics_result!(diagnostics)
|
||||
}
|
||||
|
||||
@ -157,12 +125,12 @@ impl TypeUse {
|
||||
maybe_return_diagnostics!(diagnostics);
|
||||
|
||||
// check that each arg is assignable to the param's extends
|
||||
for i in 0..self.generic_arguments.len() {
|
||||
let generic_parameter_symbol = &generic_parameters[i];
|
||||
if generic_parameter_symbol.extends().len() > 0 {
|
||||
unimplemented!("Generic extends not implemented yet.")
|
||||
}
|
||||
}
|
||||
// for i in 0..self.generic_arguments.len() {
|
||||
// let generic_parameter_symbol = &generic_parameters[i];
|
||||
// if generic_parameter_symbol.extends().len() > 0 {
|
||||
// unimplemented!("Generic extends not implemented yet.")
|
||||
// }
|
||||
// }
|
||||
}
|
||||
_ => {
|
||||
// cannot extend a non-class type (except for Any)
|
||||
@ -199,7 +167,6 @@ mod tests {
|
||||
use crate::diagnostic::Diagnostic;
|
||||
use crate::parser::parse_compilation_unit;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::types_table::TypesTable;
|
||||
|
||||
#[test]
|
||||
fn type_check_generics() -> Result<(), Vec<Diagnostic>> {
|
||||
@ -214,11 +181,11 @@ mod tests {
|
||||
)?;
|
||||
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut types_table = TypesTable::new();
|
||||
|
||||
compilation_unit.init_scopes(&mut symbol_table);
|
||||
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
||||
compilation_unit.check_names(&mut symbol_table)?;
|
||||
let mut types_table = compilation_unit.gather_types(&symbol_table)?;
|
||||
compilation_unit.type_check(&mut symbol_table, &mut types_table)?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::type_info::TypeInfo;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -7,7 +6,6 @@ pub struct GenericParameterSymbol {
|
||||
declared_name: Rc<str>,
|
||||
declared_name_source_range: SourceRange,
|
||||
scope_id: usize,
|
||||
extends: Option<Vec<TypeInfo>>,
|
||||
}
|
||||
|
||||
impl GenericParameterSymbol {
|
||||
@ -20,7 +18,6 @@ impl GenericParameterSymbol {
|
||||
declared_name: declared_name.clone(),
|
||||
declared_name_source_range: declared_name_source_range.clone(),
|
||||
scope_id,
|
||||
extends: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,14 +36,6 @@ impl GenericParameterSymbol {
|
||||
pub fn scope_id(&self) -> usize {
|
||||
self.scope_id
|
||||
}
|
||||
|
||||
pub fn set_extends(&mut self, extends: Vec<TypeInfo>) {
|
||||
self.extends = Some(extends);
|
||||
}
|
||||
|
||||
pub fn extends(&self) -> &[TypeInfo] {
|
||||
self.extends.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for GenericParameterSymbol {}
|
||||
|
||||
@ -289,6 +289,17 @@ impl SymbolTable {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_generic_parameter_symbol_owned(
|
||||
&self,
|
||||
scope_id: usize,
|
||||
name: &str,
|
||||
) -> Option<Rc<GenericParameterSymbol>> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Class(class_scope) => class_scope.generic_parameter_symbols().get(name).cloned(),
|
||||
_ => panic!("scope_id {} cannot contain generic types", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_field_symbol(&self, scope_id: usize, name: &str) -> Option<&FieldSymbol> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::ClassBody(class_body_scope) => {
|
||||
|
||||
@ -77,11 +77,11 @@ impl TypeInfo {
|
||||
}
|
||||
}
|
||||
TypeInfo::GenericType(generic_parameter_symbol) => {
|
||||
if generic_parameter_symbol.extends().len() > 0 {
|
||||
unimplemented!(
|
||||
"Assigning to generic parameter type with extends type uses not yet supported."
|
||||
);
|
||||
}
|
||||
// if generic_parameter_symbol.extends().len() > 0 {
|
||||
// unimplemented!(
|
||||
// "Assigning to generic parameter type with extends type uses not yet supported."
|
||||
// );
|
||||
// }
|
||||
true
|
||||
}
|
||||
TypeInfo::Void => {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::field_symbol::FieldSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use crate::symbol::variable_symbol::VariableSymbol;
|
||||
use crate::type_info::TypeInfo;
|
||||
@ -9,6 +10,7 @@ use std::rc::Rc;
|
||||
|
||||
pub struct TypesTable {
|
||||
class_instance_types: HashMap<Rc<ClassSymbol>, TypeInfo>,
|
||||
generic_parameter_types: HashMap<Rc<GenericParameterSymbol>, TypeInfo>,
|
||||
field_types: HashMap<Rc<FieldSymbol>, TypeInfo>,
|
||||
parameter_types: HashMap<Rc<ParameterSymbol>, TypeInfo>,
|
||||
variable_types: HashMap<Rc<VariableSymbol>, TypeInfo>,
|
||||
@ -19,6 +21,7 @@ impl TypesTable {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
class_instance_types: HashMap::new(),
|
||||
generic_parameter_types: HashMap::new(),
|
||||
field_types: HashMap::new(),
|
||||
parameter_types: HashMap::new(),
|
||||
variable_types: HashMap::new(),
|
||||
@ -34,6 +37,16 @@ impl TypesTable {
|
||||
&mut self.class_instance_types
|
||||
}
|
||||
|
||||
pub fn generic_parameter_types(&self) -> &HashMap<Rc<GenericParameterSymbol>, TypeInfo> {
|
||||
&self.generic_parameter_types
|
||||
}
|
||||
|
||||
pub fn generic_parameter_types_mut(
|
||||
&mut self,
|
||||
) -> &mut HashMap<Rc<GenericParameterSymbol>, TypeInfo> {
|
||||
&mut self.generic_parameter_types
|
||||
}
|
||||
|
||||
pub fn field_types(&self) -> &HashMap<Rc<FieldSymbol>, TypeInfo> {
|
||||
&self.field_types
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ mod e2e_tests {
|
||||
use dvm_lib::vm::function::Function;
|
||||
use dvm_lib::vm::operand::Operand;
|
||||
use dvm_lib::vm::value::Value;
|
||||
use dvm_lib::vm::{call, CallStack, DvmContext};
|
||||
use dvm_lib::vm::{CallStack, DvmContext, call};
|
||||
use std::rc::Rc;
|
||||
|
||||
const REGISTER_COUNT: usize = 8;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user