diff --git a/dmc-lib/src/intrinsics.rs b/dmc-lib/src/intrinsics.rs index 612ff5e..53e3ad1 100644 --- a/dmc-lib/src/intrinsics.rs +++ b/dmc-lib/src/intrinsics.rs @@ -31,7 +31,7 @@ pub fn add_primitive_symbols_and_type_infos(ctx: &mut AnalysisContext, global_sc .try_insert_symbol_in_scope(double_symbol, global_scope_id) .unwrap(); - let int_instance_type_info_id = ctx.instance_type(int_symbol_id); + let int_instance_type_info_id = *ctx.instance_type(int_symbol_id); let string_len_symbol = Symbol::Function(FunctionSymbol::new( "len".into(), diff --git a/dmc-lib/src/semantic_analysis/analysis_context/mod.rs b/dmc-lib/src/semantic_analysis/analysis_context/mod.rs index cd2cbd3..17184fc 100644 --- a/dmc-lib/src/semantic_analysis/analysis_context/mod.rs +++ b/dmc-lib/src/semantic_analysis/analysis_context/mod.rs @@ -6,11 +6,31 @@ use crate::diagnostic_factories::symbol_not_found; use crate::semantic_analysis::diagnostic_helpers::symbol_already_declared; use crate::semantic_analysis::scope::{Scope, ScopeId}; use crate::semantic_analysis::symbol::{Symbol, SymbolId}; -use crate::semantic_analysis::type_info::{ClassTypeInfo, TypeInfo, TypeInfoId}; +use crate::semantic_analysis::type_info::{ClassTypeInfo, InstanceTypeInfo, TypeInfo, TypeInfoId}; use crate::source_range::SourceRange; use std::collections::HashMap; use std::rc::Rc; +#[derive(Debug, Clone)] +struct TypeInfoContainer { + error_type_id: TypeInfoId, + class_symbol_ids_to_type_info_ids: HashMap, + infos: Vec, +} + +impl Default for TypeInfoContainer { + fn default() -> Self { + let mut infos = vec![]; + infos.push(TypeInfo::__Error); + let error_type_id = infos.len() - 1; + Self { + error_type_id, + class_symbol_ids_to_type_info_ids: HashMap::new(), + infos, + } + } +} + #[derive(Debug, Clone)] struct AnalysisState { fqn_stack: Vec>, @@ -19,7 +39,7 @@ struct AnalysisState { nodes_to_scopes: HashMap, symbols: Vec, nodes_to_symbols: HashMap, - type_infos: Vec, + type_infos: Box, symbols_to_type_infos: HashMap, nodes_to_type_infos: HashMap, } @@ -33,7 +53,7 @@ impl Default for AnalysisState { nodes_to_scopes: HashMap::new(), symbols: Vec::new(), nodes_to_symbols: HashMap::new(), - type_infos: Vec::new(), + type_infos: TypeInfoContainer::default().into(), symbols_to_type_infos: HashMap::new(), nodes_to_type_infos: HashMap::new(), } @@ -73,7 +93,7 @@ impl AnalysisContext { #[deprecated] pub fn type_infos(&self) -> &[TypeInfo] { - &self.state.type_infos + &self.state.type_infos.infos } #[deprecated] @@ -326,8 +346,8 @@ impl AnalysisContext { #[deprecated] pub fn insert_type_info(&mut self, type_info: TypeInfo) -> TypeInfoId { - self.state.type_infos.push(type_info); - self.state.type_infos.len() - 1 + self.state.type_infos.infos.push(type_info); + self.state.type_infos.infos.len() - 1 } #[deprecated] @@ -336,8 +356,8 @@ impl AnalysisContext { type_info: TypeInfo, node_id: NodeId, ) -> TypeInfoId { - self.state.type_infos.push(type_info); - let type_info_id = self.state.type_infos.len() - 1; + self.state.type_infos.infos.push(type_info); + let type_info_id = self.state.type_infos.infos.len() - 1; self.state.nodes_to_type_infos.insert(node_id, type_info_id); type_info_id } @@ -374,6 +394,7 @@ impl AnalysisContext { let type_info_id = self.get_type_info_id_for_node(node_id); self.state .type_infos + .infos .get(type_info_id) .expect(&format!("invalid type_info_id {}", type_info_id)) } @@ -381,6 +402,7 @@ impl AnalysisContext { pub fn get_type_info_by_id(&self, type_info_id: TypeInfoId) -> &TypeInfo { self.state .type_infos + .infos .get(type_info_id) .expect(&format!("invalid type_info_id {}", type_info_id)) } @@ -440,8 +462,8 @@ impl AnalysisContext { *type_info_id } else { let type_info = TypeInfo::Class(ClassTypeInfo::new(class_symbol_id)); - self.state.type_infos.push(type_info); - let type_info_id = self.state.type_infos.len() - 1; + self.state.type_infos.infos.push(type_info); + let type_info_id = self.state.type_infos.infos.len() - 1; self.state .symbols_to_type_infos .insert(class_symbol_id, type_info_id); @@ -453,20 +475,30 @@ impl AnalysisContext { todo!() } - pub fn int_type(&mut self) -> &TypeInfoId { - todo!() + pub fn error_type(&self) -> &TypeInfoId { + &self.state.type_infos.error_type_id } - pub fn double_type(&mut self) -> &TypeInfoId { - todo!() - } - - pub fn error_type(&self) -> TypeInfoId { - todo!() - } - - pub fn instance_type(&mut self, class_symbol_id: SymbolId) -> TypeInfoId { - todo!() + pub fn instance_type(&mut self, class_symbol_id: SymbolId) -> &TypeInfoId { + if !self + .state + .type_infos + .class_symbol_ids_to_type_info_ids + .contains_key(&class_symbol_id) + { + let type_info = TypeInfo::Instance(InstanceTypeInfo::new(class_symbol_id)); + self.state.type_infos.infos.push(type_info); + let type_info_id = self.state.type_infos.infos.len() - 1; + self.state + .type_infos + .class_symbol_ids_to_type_info_ids + .insert(class_symbol_id, type_info_id); + } + self.state + .type_infos + .class_symbol_ids_to_type_info_ids + .get(&class_symbol_id) + .unwrap() } pub fn instance_type_by_fqn(&self, fqn: &str) -> TypeInfoId { @@ -481,6 +513,6 @@ impl AnalysisContext { self.state .symbols_to_type_infos .get(&symbol_id) - .and_then(|type_info_id| self.state.type_infos.get(*type_info_id)) + .and_then(|type_info_id| self.state.type_infos.infos.get(*type_info_id)) } } diff --git a/dmc-lib/src/semantic_analysis/type_analysis/check/helpers.rs b/dmc-lib/src/semantic_analysis/type_analysis/check/helpers.rs index 782b707..79d08b7 100644 --- a/dmc-lib/src/semantic_analysis/type_analysis/check/helpers.rs +++ b/dmc-lib/src/semantic_analysis/type_analysis/check/helpers.rs @@ -52,6 +52,6 @@ pub fn negative_op_result(operand: &TypeInfo, ctx: &AnalysisContext) -> TypeInfo unreachable!() } TypeInfo::Instance(instance_type_info) => instance_type_info.negative_op_result(ctx), - TypeInfo::__Error => ctx.error_type(), + TypeInfo::__Error => *ctx.error_type(), } } diff --git a/dmc-lib/src/semantic_analysis/type_analysis/check/mod.rs b/dmc-lib/src/semantic_analysis/type_analysis/check/mod.rs index db8ff93..ad1027a 100644 --- a/dmc-lib/src/semantic_analysis/type_analysis/check/mod.rs +++ b/dmc-lib/src/semantic_analysis/type_analysis/check/mod.rs @@ -224,7 +224,7 @@ fn resolve_types_binary_expression( .with_error_code(BINARY_INCOMPATIBLE_TYPES); diagnostics.push(diagnostic); - ctx.error_type() + *ctx.error_type() }; ctx.associate_node_to_type(binary_expression.node_id(), result_type_info_id); @@ -252,7 +252,7 @@ fn resolve_types_negative_expression( negative_expression.source_range().end(), ); diagnostics.push(diagnostic); - ctx.error_type() + *ctx.error_type() }; ctx.associate_node_to_type(negative_expression.node_id(), operand_type_info_id); @@ -282,11 +282,11 @@ fn resolve_types_call( call.source_range().end(), ); diagnostics.push(diagnostic); - ctx.error_type() + *ctx.error_type() } TypeInfo::Class(class_type_info) => { let symbol = class_type_info.class_symbol_id(); - ctx.instance_type(symbol) + *ctx.instance_type(symbol) } TypeInfo::Constructor(_) => { panic!("Cannot check expression type directly on ConstructorTypeInfo"); @@ -295,6 +295,6 @@ fn resolve_types_call( TypeInfo::Instance(_) => { unimplemented!("Calling instances of objects not yet supported.") } - TypeInfo::__Error => ctx.error_type(), + TypeInfo::__Error => *ctx.error_type(), } }