Fixing bugs. WIP.

This commit is contained in:
Jesse Brault 2026-03-20 23:57:09 -05:00
parent 4e8fa159c0
commit 912f208705
8 changed files with 79 additions and 64 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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(())

View File

@ -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 {}

View File

@ -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) => {

View File

@ -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 => {

View File

@ -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
}

View File

@ -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;