Some light work on type analysis/analysis context. WIP.
This commit is contained in:
parent
3535fed61d
commit
618c3000f1
@ -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(),
|
||||
|
||||
@ -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<SymbolId, TypeInfoId>,
|
||||
infos: Vec<TypeInfo>,
|
||||
}
|
||||
|
||||
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<Rc<str>>,
|
||||
@ -19,7 +39,7 @@ struct AnalysisState {
|
||||
nodes_to_scopes: HashMap<NodeId, ScopeId>,
|
||||
symbols: Vec<Symbol>,
|
||||
nodes_to_symbols: HashMap<NodeId, SymbolId>,
|
||||
type_infos: Vec<TypeInfo>,
|
||||
type_infos: Box<TypeInfoContainer>,
|
||||
symbols_to_type_infos: HashMap<SymbolId, TypeInfoId>,
|
||||
nodes_to_type_infos: HashMap<NodeId, TypeInfoId>,
|
||||
}
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user