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