cortex_lang/preprocessing/
module.rs1use std::collections::{HashMap, HashSet};
2
3use thiserror::Error;
4
5use crate::parsing::ast::{expression::{OptionalIdentifier, PathError, PathIdent}, top_level::{Bundle, Extension, PFunction, Struct}, r#type::CortexType};
6
7#[derive(Error, Debug, PartialEq)]
8pub enum ModuleError {
9 #[error("Module \"{0}\" already exists")]
10 ModuleAlreadyExists(String),
11 #[error("Module \"{0}\" was not found")]
12 ModuleDoesNotExist(String),
13 #[error("Path error: \"{0}\"")]
14 PathError(PathError),
15
16 #[error("Function \"{0}\" already exists")]
17 FunctionAlreadyExists(String),
18 #[error("Type \"{0}\" already exists")]
19 TypeAlreadyExists(String),
20
21 #[error("Duplicate type argument name: {0}")]
22 DuplicateTypeArgumentName(String),
23}
24
25pub struct TypeDefinition {
26 pub(crate) fields: HashMap<String, CortexType>,
27 pub(crate) type_param_names: Vec<String>,
28 pub(crate) is_heap_allocated: bool,
29}
30
31
32pub struct Module {
33 children: HashMap<String, Module>,
34 functions: HashMap<String, PFunction>,
35 structs: HashMap<String, Struct>,
36 bundles: HashMap<String, Bundle>,
37 extensions: Vec<Extension>,
38}
39
40impl Module {
41 pub fn new() -> Self {
42 Self::with_children(HashMap::new())
43 }
44 pub fn with_children(children: HashMap<String, Module>) -> Self {
45 Module {
46 children: children,
47 functions: HashMap::new(),
48 structs: HashMap::new(),
49 bundles: HashMap::new(),
50 extensions: Vec::new(),
51 }
52 }
53
54 pub fn add_child(&mut self, name: String, module: Module) -> Result<(), ModuleError> {
55 if self.children.contains_key(&name) {
56 Err(ModuleError::ModuleAlreadyExists(name))
57 } else {
58 self.children.insert(name, module);
59 Ok(())
60 }
61 }
62
63 pub fn get_module_for(&self, path: &PathIdent) -> Result<&Module, ModuleError> {
64 if path.is_final() {
65 return Ok(self);
66 }
67 let front = path.get_front().map_err(|e| ModuleError::PathError(e))?;
68 if self.children.contains_key(front) {
69 let child = self.children.get(front).unwrap();
70 let next_path = path.pop_front().map_err(|e| ModuleError::PathError(e))?;
71 child.get_module_for(&next_path)
72 } else {
73 Err(ModuleError::ModuleDoesNotExist(front.clone()))
74 }
75 }
76 pub fn get_module_for_mut(&mut self, path: &PathIdent) -> Result<&mut Module, ModuleError> {
77 if path.is_final() {
78 return Ok(self);
79 }
80 let front = path.get_front().map_err(|e| ModuleError::PathError(e))?;
81 if self.children.contains_key(front) {
82 let child = self.children.get_mut(front).unwrap();
83 let next_path = path.pop_front().map_err(|e| ModuleError::PathError(e))?;
84 child.get_module_for_mut(&next_path)
85 } else {
86 Err(ModuleError::ModuleDoesNotExist(front.clone()))
87 }
88 }
89 pub fn children_iter(&mut self) -> impl Iterator<Item = (String, Module)> {
90 let children = std::mem::take(&mut self.children);
91 children.into_iter()
92 }
93
94 pub fn add_module(&mut self, path: &PathIdent, module: Module) -> Result<(), ModuleError> {
95 if path.is_final() {
96 let name = path.get_front().map_err(|e| ModuleError::PathError(e))?.clone();
97 self.add_child(name, module)?;
98 return Ok(());
99 }
100 let front = path.get_front().map_err(|e| ModuleError::PathError(e))?;
101 if self.children.contains_key(front) {
102 let child = self.children.get_mut(front).unwrap();
103 let next_path = path.pop_front().map_err(|e| ModuleError::PathError(e))?;
104 child.add_module(&next_path, module)
105 } else {
106 Err(ModuleError::ModuleDoesNotExist(front.clone()))
107 }
108 }
109
110 pub fn take_functions(&mut self) -> Result<Vec<PFunction>, ModuleError> {
111 let res = std::mem::take(&mut self.functions).into_values().collect();
112 Ok(res)
113 }
114 pub fn add_function(&mut self, func: PFunction) -> Result<(), ModuleError> {
115 match &func.name {
116 OptionalIdentifier::Ident(name) => {
117 if self.functions.contains_key(name) {
118 Err(ModuleError::FunctionAlreadyExists(name.clone()))
119 } else {
120 let mut seen_type_param_names = HashSet::new();
121 for t in &func.type_param_names {
122 if seen_type_param_names.contains(t) {
123 return Err(ModuleError::DuplicateTypeArgumentName(t.clone()));
124 }
125 seen_type_param_names.insert(t);
126 }
127
128 self.functions.insert(name.clone(), func);
129 Ok(())
130 }
131 },
132 OptionalIdentifier::Ignore => Ok(()),
133 }
134 }
135
136 pub fn take_structs(&mut self) -> Result<Vec<Struct>, ModuleError> {
137 let res = std::mem::take(&mut self.structs).into_values().collect();
138 Ok(res)
139 }
140 pub fn add_struct(&mut self, item: Struct) -> Result<(), ModuleError> {
141 match &item.name {
142 OptionalIdentifier::Ident(name) => {
143 if self.structs.contains_key(name) {
144 Err(ModuleError::TypeAlreadyExists(name.clone()))
145 } else {
146 let mut seen_type_param_names = HashSet::new();
147 for t in &item.type_param_names {
148 if seen_type_param_names.contains(t) {
149 return Err(ModuleError::DuplicateTypeArgumentName(t.clone()));
150 }
151 seen_type_param_names.insert(t);
152 }
153
154 self.structs.insert(name.clone(), item);
155 Ok(())
156 }
157 },
158 OptionalIdentifier::Ignore => Ok(()),
159 }
160 }
161
162 pub fn take_bundles(&mut self) -> Result<Vec<Bundle>, ModuleError> {
163 let res = std::mem::take(&mut self.bundles).into_values().collect();
164 Ok(res)
165 }
166 pub fn add_bundle(&mut self, item: Bundle) -> Result<(), ModuleError> {
167 match &item.name {
168 OptionalIdentifier::Ident(name) => {
169 if self.bundles.contains_key(name) {
170 Err(ModuleError::TypeAlreadyExists(name.clone()))
171 } else {
172 let mut seen_type_param_names = HashSet::new();
173 for t in &item.type_param_names {
174 if seen_type_param_names.contains(t) {
175 return Err(ModuleError::DuplicateTypeArgumentName(t.clone()));
176 }
177 seen_type_param_names.insert(t);
178 }
179
180 self.bundles.insert(name.clone(), item);
181 Ok(())
182 }
183 },
184 OptionalIdentifier::Ignore => Ok(()),
185 }
186 }
187
188 pub fn take_extensions(&mut self) -> Result<Vec<Extension>, ModuleError> {
189 let res = std::mem::take(&mut self.extensions);
190 Ok(res)
191 }
192 pub fn add_extension(&mut self, item: Extension) -> Result<(), ModuleError> {
193 let mut seen_type_param_names = HashSet::new();
194 for t in &item.type_param_names {
195 if seen_type_param_names.contains(t) {
196 return Err(ModuleError::DuplicateTypeArgumentName(t.clone()));
197 }
198 seen_type_param_names.insert(t);
199 }
200
201 self.extensions.push(item);
202 Ok(())
203 }
204}