ezno_checker/
type_mappings.rs

1use crate::{
2	features::variables::VariableWithValue,
3	types::{TypeId, TypeStore},
4	GeneralContext, RangeMap, VariableId,
5};
6use source_map::{SourceId, SpanWithSource};
7use std::{collections::HashMap, path::PathBuf};
8
9/// **PER MODULE**
10/// [`TypeMappings`] is used to retaining information between passes, including the synthesise and checking passes
11/// This for use in the both use in the compiler and compiler plugins
12/// Checking things are held on [`crate::Memory`], function things are held on [`crate::HoistedFunctionContainer`]
13/// and module things on [`crate::ModuleData`]
14#[derive(Default, Debug)]
15pub struct TypeMappings {
16	/// Figures out the types of the expressions in the AST
17	pub expressions_to_instances: RangeMap<Instance>,
18	/// [Variable] data to a AST mapping.
19	/// **THIS INFORMATION IS CURRENTLY USED IN TYPE CHECKING AND SO IS NOT JUST FOR LATER ANALYSIS**
20	pub variables_to_constraints: VariablesToTypes,
21	/// Property to type, TODO kind of temp
22	pub properties_to_types: RangeMap<TypeId>,
23	/// Data to a AST mapping. For classes this points to the shape
24	pub types_to_types: RangeMap<TypeId>,
25	pub import_statements_to_pointing_path: RangeMap<PathBuf>,
26
27	/// For places where there are two `var` statements in
28	pub var_aliases: HashMap<u32, VariableId>,
29
30	/// Variable restriction. Cached after hoisting pass. TODO temp needs tidy
31	pub variable_restrictions: HashMap<(SourceId, u32), (TypeId, SpanWithSource)>,
32	/// Temp
33	pub special_expressions: RangeMap<SpecialExpressions>,
34}
35
36#[derive(Debug)]
37pub enum SpecialExpressions {
38	CompileOut,
39	Marker,
40}
41
42#[derive(Default, Debug)]
43pub struct VariablesToTypes(pub(crate) HashMap<VariableId, TypeId>);
44
45// TODO these are temp
46impl TypeMappings {
47	#[must_use]
48	pub fn print_type_mappings(
49		&self,
50		_source: &str,
51		_env: &GeneralContext,
52		_types: &TypeStore,
53	) -> String {
54		todo!()
55		// let mut buf = "Expression type mappings:\n".to_owned();
56		// for (pos, instance) in self.expressions_to_instances.iter() {
57		// 	buf.push_str(
58		// 		source.get((pos.0.start as usize)..(pos.0.end as usize)).unwrap_or_default(),
59		// 	);
60		// 	buf.push_str(" has type ");
61		// 	buf.push_str(&print_type(types, instance.get_value(), env));
62		// 	buf.push('\n')
63		// }
64		// buf
65	}
66}
67
68/// See <https://www.internalpointers.com/post/understanding-meaning-lexpressions-and-rexpressions-c> for a understanding
69/// of `LValue` vs `RValue`
70#[derive(Clone, Debug)]
71pub enum Instance {
72	LValue(VariableWithValue),
73	RValue(TypeId),
74	/// Result FROM getter
75	GValue(TypeId),
76}
77
78impl Instance {
79	#[must_use]
80	pub fn get_variable_id(&self) -> Option<VariableId> {
81		match self {
82			Self::LValue(variable) => Some(variable.0.get_id()),
83			Self::RValue(_) | Self::GValue(_) => None,
84		}
85	}
86
87	#[must_use]
88	pub fn get_value(self) -> TypeId {
89		match self {
90			Instance::LValue(l) => l.1,
91			Instance::GValue(value) | Instance::RValue(value) => value,
92		}
93	}
94
95	#[must_use]
96	pub fn get_value_on_ref(&self) -> TypeId {
97		match self {
98			Instance::LValue(l) => l.1,
99			Instance::GValue(value) | Instance::RValue(value) => *value,
100		}
101	}
102}