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