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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
use std::{cell::RefCell, collections::HashMap};
use super::{RefValueMap, Type, TypeKind};
#[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, kind: TypeKind) -> Type {
let global_associated_values_for_type = match kind {
TypeKind::Fn { .. } => &self.global_associated_values.fn_values,
TypeKind::Array(_) => &self.global_associated_values.array_values,
TypeKind::Tuple(_) => &self.global_associated_values.tuple_values,
TypeKind::Data { .. } => &self.global_associated_values.data_values,
TypeKind::Str | TypeKind::Int | TypeKind::Float | TypeKind::Bool | TypeKind::Void => {
panic!("There should only be one type {:?}.", kind)
}
TypeKind::Face(_) | TypeKind::Var(_) => todo!("Implement abstract types."),
};
Type {
kind: Box::new(kind),
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(TypeKind::Str, &values.str_values),
int_type: Self::create_single_type(TypeKind::Int, &values.int_values),
float_type: Self::create_single_type(TypeKind::Float, &values.float_values),
bool_type: Self::create_single_type(TypeKind::Bool, &values.bool_values),
void_type: Self::create_single_type(TypeKind::Void, &values.void_values),
}
}
fn create_single_type(kind: TypeKind, values: &'static RefValueMap) -> Type {
Type {
kind: Box::new(kind),
global_associated_values: values,
}
}
}
|