cortex_lang/preprocessing/
module.rs

1use 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}