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)
|
.try_insert_symbol_in_scope(double_symbol, global_scope_id)
|
||||||
.unwrap();
|
.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(
|
let string_len_symbol = Symbol::Function(FunctionSymbol::new(
|
||||||
"len".into(),
|
"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::diagnostic_helpers::symbol_already_declared;
|
||||||
use crate::semantic_analysis::scope::{Scope, ScopeId};
|
use crate::semantic_analysis::scope::{Scope, ScopeId};
|
||||||
use crate::semantic_analysis::symbol::{Symbol, SymbolId};
|
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 crate::source_range::SourceRange;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
struct AnalysisState {
|
struct AnalysisState {
|
||||||
fqn_stack: Vec<Rc<str>>,
|
fqn_stack: Vec<Rc<str>>,
|
||||||
@ -19,7 +39,7 @@ struct AnalysisState {
|
|||||||
nodes_to_scopes: HashMap<NodeId, ScopeId>,
|
nodes_to_scopes: HashMap<NodeId, ScopeId>,
|
||||||
symbols: Vec<Symbol>,
|
symbols: Vec<Symbol>,
|
||||||
nodes_to_symbols: HashMap<NodeId, SymbolId>,
|
nodes_to_symbols: HashMap<NodeId, SymbolId>,
|
||||||
type_infos: Vec<TypeInfo>,
|
type_infos: Box<TypeInfoContainer>,
|
||||||
symbols_to_type_infos: HashMap<SymbolId, TypeInfoId>,
|
symbols_to_type_infos: HashMap<SymbolId, TypeInfoId>,
|
||||||
nodes_to_type_infos: HashMap<NodeId, TypeInfoId>,
|
nodes_to_type_infos: HashMap<NodeId, TypeInfoId>,
|
||||||
}
|
}
|
||||||
@ -33,7 +53,7 @@ impl Default for AnalysisState {
|
|||||||
nodes_to_scopes: HashMap::new(),
|
nodes_to_scopes: HashMap::new(),
|
||||||
symbols: Vec::new(),
|
symbols: Vec::new(),
|
||||||
nodes_to_symbols: HashMap::new(),
|
nodes_to_symbols: HashMap::new(),
|
||||||
type_infos: Vec::new(),
|
type_infos: TypeInfoContainer::default().into(),
|
||||||
symbols_to_type_infos: HashMap::new(),
|
symbols_to_type_infos: HashMap::new(),
|
||||||
nodes_to_type_infos: HashMap::new(),
|
nodes_to_type_infos: HashMap::new(),
|
||||||
}
|
}
|
||||||
@ -73,7 +93,7 @@ impl AnalysisContext {
|
|||||||
|
|
||||||
#[deprecated]
|
#[deprecated]
|
||||||
pub fn type_infos(&self) -> &[TypeInfo] {
|
pub fn type_infos(&self) -> &[TypeInfo] {
|
||||||
&self.state.type_infos
|
&self.state.type_infos.infos
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated]
|
#[deprecated]
|
||||||
@ -326,8 +346,8 @@ impl AnalysisContext {
|
|||||||
|
|
||||||
#[deprecated]
|
#[deprecated]
|
||||||
pub fn insert_type_info(&mut self, type_info: TypeInfo) -> TypeInfoId {
|
pub fn insert_type_info(&mut self, type_info: TypeInfo) -> TypeInfoId {
|
||||||
self.state.type_infos.push(type_info);
|
self.state.type_infos.infos.push(type_info);
|
||||||
self.state.type_infos.len() - 1
|
self.state.type_infos.infos.len() - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated]
|
#[deprecated]
|
||||||
@ -336,8 +356,8 @@ impl AnalysisContext {
|
|||||||
type_info: TypeInfo,
|
type_info: TypeInfo,
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
) -> TypeInfoId {
|
) -> TypeInfoId {
|
||||||
self.state.type_infos.push(type_info);
|
self.state.type_infos.infos.push(type_info);
|
||||||
let type_info_id = self.state.type_infos.len() - 1;
|
let type_info_id = self.state.type_infos.infos.len() - 1;
|
||||||
self.state.nodes_to_type_infos.insert(node_id, type_info_id);
|
self.state.nodes_to_type_infos.insert(node_id, type_info_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);
|
let type_info_id = self.get_type_info_id_for_node(node_id);
|
||||||
self.state
|
self.state
|
||||||
.type_infos
|
.type_infos
|
||||||
|
.infos
|
||||||
.get(type_info_id)
|
.get(type_info_id)
|
||||||
.expect(&format!("invalid type_info_id {}", 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 {
|
pub fn get_type_info_by_id(&self, type_info_id: TypeInfoId) -> &TypeInfo {
|
||||||
self.state
|
self.state
|
||||||
.type_infos
|
.type_infos
|
||||||
|
.infos
|
||||||
.get(type_info_id)
|
.get(type_info_id)
|
||||||
.expect(&format!("invalid type_info_id {}", type_info_id))
|
.expect(&format!("invalid type_info_id {}", type_info_id))
|
||||||
}
|
}
|
||||||
@ -440,8 +462,8 @@ impl AnalysisContext {
|
|||||||
*type_info_id
|
*type_info_id
|
||||||
} else {
|
} else {
|
||||||
let type_info = TypeInfo::Class(ClassTypeInfo::new(class_symbol_id));
|
let type_info = TypeInfo::Class(ClassTypeInfo::new(class_symbol_id));
|
||||||
self.state.type_infos.push(type_info);
|
self.state.type_infos.infos.push(type_info);
|
||||||
let type_info_id = self.state.type_infos.len() - 1;
|
let type_info_id = self.state.type_infos.infos.len() - 1;
|
||||||
self.state
|
self.state
|
||||||
.symbols_to_type_infos
|
.symbols_to_type_infos
|
||||||
.insert(class_symbol_id, type_info_id);
|
.insert(class_symbol_id, type_info_id);
|
||||||
@ -453,20 +475,30 @@ impl AnalysisContext {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn int_type(&mut self) -> &TypeInfoId {
|
pub fn error_type(&self) -> &TypeInfoId {
|
||||||
todo!()
|
&self.state.type_infos.error_type_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn double_type(&mut self) -> &TypeInfoId {
|
pub fn instance_type(&mut self, class_symbol_id: SymbolId) -> &TypeInfoId {
|
||||||
todo!()
|
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
|
||||||
pub fn error_type(&self) -> TypeInfoId {
|
.type_infos
|
||||||
todo!()
|
.class_symbol_ids_to_type_info_ids
|
||||||
}
|
.get(&class_symbol_id)
|
||||||
|
.unwrap()
|
||||||
pub fn instance_type(&mut self, class_symbol_id: SymbolId) -> TypeInfoId {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn instance_type_by_fqn(&self, fqn: &str) -> TypeInfoId {
|
pub fn instance_type_by_fqn(&self, fqn: &str) -> TypeInfoId {
|
||||||
@ -481,6 +513,6 @@ impl AnalysisContext {
|
|||||||
self.state
|
self.state
|
||||||
.symbols_to_type_infos
|
.symbols_to_type_infos
|
||||||
.get(&symbol_id)
|
.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!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
TypeInfo::Instance(instance_type_info) => instance_type_info.negative_op_result(ctx),
|
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);
|
.with_error_code(BINARY_INCOMPATIBLE_TYPES);
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
|
|
||||||
ctx.error_type()
|
*ctx.error_type()
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.associate_node_to_type(binary_expression.node_id(), result_type_info_id);
|
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(),
|
negative_expression.source_range().end(),
|
||||||
);
|
);
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
ctx.error_type()
|
*ctx.error_type()
|
||||||
};
|
};
|
||||||
|
|
||||||
ctx.associate_node_to_type(negative_expression.node_id(), operand_type_info_id);
|
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(),
|
call.source_range().end(),
|
||||||
);
|
);
|
||||||
diagnostics.push(diagnostic);
|
diagnostics.push(diagnostic);
|
||||||
ctx.error_type()
|
*ctx.error_type()
|
||||||
}
|
}
|
||||||
TypeInfo::Class(class_type_info) => {
|
TypeInfo::Class(class_type_info) => {
|
||||||
let symbol = class_type_info.class_symbol_id();
|
let symbol = class_type_info.class_symbol_id();
|
||||||
ctx.instance_type(symbol)
|
*ctx.instance_type(symbol)
|
||||||
}
|
}
|
||||||
TypeInfo::Constructor(_) => {
|
TypeInfo::Constructor(_) => {
|
||||||
panic!("Cannot check expression type directly on ConstructorTypeInfo");
|
panic!("Cannot check expression type directly on ConstructorTypeInfo");
|
||||||
@ -295,6 +295,6 @@ fn resolve_types_call(
|
|||||||
TypeInfo::Instance(_) => {
|
TypeInfo::Instance(_) => {
|
||||||
unimplemented!("Calling instances of objects not yet supported.")
|
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