diff options
| author | Mel <einebeere@gmail.com> | 2021-11-20 00:31:28 +0100 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2021-11-20 00:31:28 +0100 |
| commit | 395d086f0dce355ccdcf3da149c309826c539b48 (patch) | |
| tree | 888ad59d8fcebcec0c04bcfd13364889c5047349 /src/types | |
| parent | 334f70f5a2f63ec636ac1a8bc375ce51effba424 (diff) | |
| download | rabbithole-395d086f0dce355ccdcf3da149c309826c539b48.tar.zst rabbithole-395d086f0dce355ccdcf3da149c309826c539b48.zip | |
Runtime types
Diffstat (limited to 'src/types')
| -rw-r--r-- | src/types/bag.rs | 123 | ||||
| -rw-r--r-- | src/types/mod.rs | 42 |
2 files changed, 165 insertions, 0 deletions
diff --git a/src/types/bag.rs b/src/types/bag.rs new file mode 100644 index 0000000..30202fd --- /dev/null +++ b/src/types/bag.rs @@ -0,0 +1,123 @@ +use std::{cell::RefCell, collections::HashMap}; + +use super::{RefValueMap, Type, TypeVariant}; + +#[derive(Clone)] +pub struct TypeBag { + global_associated_values: &'static GlobalAssociatedValues, + atomic_types: AtomicTypes, +} + +impl TypeBag { + pub fn new() -> Self { + // Hehe don't mind me + let leaked_values: &'static GlobalAssociatedValues = + Box::leak(Box::new(GlobalAssociatedValues::new())); + let atomic_types = AtomicTypes::new(&leaked_values); + + TypeBag { + global_associated_values: leaked_values, + atomic_types, + } + } + + pub fn create_type(&self, variant: TypeVariant) -> Type { + let global_associated_values_for_type = match variant { + TypeVariant::Fn { .. } => &self.global_associated_values.fn_values, + TypeVariant::Array(_) => &self.global_associated_values.array_values, + TypeVariant::Tuple(_) => &self.global_associated_values.tuple_values, + TypeVariant::Data { .. } => &self.global_associated_values.data_values, + TypeVariant::Str + | TypeVariant::Int + | TypeVariant::Float + | TypeVariant::Bool + | TypeVariant::Void => panic!("There should only be one type {:?}.", variant), + TypeVariant::Face(_) | TypeVariant::Var(_) => todo!("Implement abstract types."), + }; + + Type { + variant: Box::new(variant), + global_associated_values: global_associated_values_for_type, + } + } + + pub fn str(&self) -> Type { + self.atomic_types.str_type.clone() + } + + pub fn int(&self) -> Type { + self.atomic_types.int_type.clone() + } + + pub fn float(&self) -> Type { + self.atomic_types.float_type.clone() + } + + pub fn bool(&self) -> Type { + self.atomic_types.bool_type.clone() + } + + pub fn void(&self) -> Type { + self.atomic_types.void_type.clone() + } +} + +struct GlobalAssociatedValues { + str_values: RefValueMap, + int_values: RefValueMap, + float_values: RefValueMap, + bool_values: RefValueMap, + void_values: RefValueMap, + fn_values: RefValueMap, + array_values: RefValueMap, + tuple_values: RefValueMap, + data_values: RefValueMap, +} + +impl GlobalAssociatedValues { + fn new() -> Self { + GlobalAssociatedValues { + str_values: Self::create_value_map(), + int_values: Self::create_value_map(), + float_values: Self::create_value_map(), + bool_values: Self::create_value_map(), + void_values: Self::create_value_map(), + fn_values: Self::create_value_map(), + array_values: Self::create_value_map(), + tuple_values: Self::create_value_map(), + data_values: Self::create_value_map(), + } + } + + fn create_value_map() -> RefValueMap { + RefCell::new(HashMap::new()) + } +} + +#[derive(Clone)] +struct AtomicTypes { + str_type: Type, + int_type: Type, + float_type: Type, + bool_type: Type, + void_type: Type, +} + +impl AtomicTypes { + fn new(values: &'static GlobalAssociatedValues) -> Self { + AtomicTypes { + str_type: Self::create_single_type(TypeVariant::Str, &values.str_values), + int_type: Self::create_single_type(TypeVariant::Int, &values.int_values), + float_type: Self::create_single_type(TypeVariant::Float, &values.float_values), + bool_type: Self::create_single_type(TypeVariant::Bool, &values.bool_values), + void_type: Self::create_single_type(TypeVariant::Void, &values.void_values), + } + } + + fn create_single_type(variant: TypeVariant, values: &'static RefValueMap) -> Type { + Type { + variant: Box::new(variant), + global_associated_values: values, + } + } +} diff --git a/src/types/mod.rs b/src/types/mod.rs new file mode 100644 index 0000000..f3257eb --- /dev/null +++ b/src/types/mod.rs @@ -0,0 +1,42 @@ +pub mod bag; + +use std::cell::RefCell; +use std::collections::HashMap; + +use crate::interpret::value::ValueMap; +use crate::parse::ast::nodes::Identifier; + +#[derive(Debug, Clone)] +pub struct Type { + variant: Box<TypeVariant>, + global_associated_values: &'static RefValueMap, +} + +#[derive(Debug, Clone)] +pub enum TypeVariant { + // Concrete types + Str, + Int, + Float, + Bool, + Void, + Fn { + parameters: TypeMap, + returns: Type, + }, + Array(Type), + Tuple(Vec<Type>), + Data { + data: TypeMap, + associated_values: RefValueMap, + }, + // TODO: Implement abstract types. + // These should also definitely have `associated_values`, + // but as they're not implemented yet... + Face(TypeMap), + Var(TypeMap), +} + +type TypeMap = HashMap<Identifier, Type>; + +type RefValueMap = RefCell<ValueMap>; \ No newline at end of file |
