swamp_script_modules/
symtbl.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/script
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use crate::modules::ModuleRef;
6use seq_map::SeqMap;
7use std::fmt::Debug;
8use std::rc::Rc;
9use swamp_script_node::Node;
10use swamp_script_semantic::prelude::*;
11use swamp_script_types::ParameterizedTypeBlueprint;
12use swamp_script_types::prelude::*;
13use tiny_ver::TinyVersion;
14
15#[derive(Debug, Clone)]
16pub enum FuncDef {
17    Internal(InternalFunctionDefinitionRef),
18    Intrinsic(IntrinsicFunctionDefinitionRef),
19    External(ExternalFunctionDefinitionRef),
20}
21
22#[derive(Clone, Eq, PartialEq, Debug)]
23pub struct TypeParameterName {
24    pub resolved_node: Node,
25    pub assigned_name: String,
26}
27
28#[derive(Debug)]
29pub struct TypeParameter {
30    pub ty: Type,
31    pub debug_name: String,
32}
33
34#[derive(Clone, Debug)]
35pub enum Symbol {
36    Type(Type),
37    Module(ModuleRef),
38    PackageVersion(TinyVersion),
39    Constant(ConstantRef),
40    FunctionDefinition(FuncDef),
41    Alias(AliasType),
42    Blueprint(ParameterizedTypeBlueprint),
43}
44
45impl Symbol {
46    #[must_use]
47    pub const fn is_basic_type(&self) -> bool {
48        matches!(self, Self::Type(..) | Self::Alias(..))
49    }
50}
51
52#[derive(Debug, Clone)]
53pub struct SymbolTable {
54    symbols: SeqMap<String, Symbol>,
55    module_path: Vec<String>,
56}
57
58impl SymbolTable {
59    pub fn module_path(&self) -> Vec<String> {
60        self.module_path.clone()
61    }
62}
63
64pub type SymbolTableRef = Rc<SymbolTable>;
65
66impl SymbolTable {
67    #[must_use]
68    pub fn new(module_path: &[String]) -> Self {
69        Self {
70            symbols: SeqMap::default(),
71            module_path: module_path.to_vec(),
72        }
73    }
74
75    #[must_use]
76    pub fn is_empty(&self) -> bool {
77        self.symbols.is_empty()
78    }
79
80    #[must_use]
81    pub const fn symbols(&self) -> &SeqMap<String, Symbol> {
82        &self.symbols
83    }
84
85    pub fn structs(&self) -> SeqMap<String, NamedStructType> {
86        let mut structs = SeqMap::new();
87
88        for (name, symbol) in &self.symbols {
89            if let Symbol::Type(ty) = symbol {
90                if let Type::NamedStruct(struct_ref) = ty {
91                    structs
92                        .insert(name.to_string(), struct_ref.clone())
93                        .unwrap();
94                }
95            }
96        }
97
98        structs
99    }
100
101    /// # Errors
102    ///
103    pub fn extend_from(&mut self, symbol_table: &Self) -> Result<(), SemanticError> {
104        for (name, symbol) in symbol_table.symbols() {
105            self.add_symbol(name, symbol.clone())?;
106        }
107        Ok(())
108    }
109
110    /// # Errors
111    ///
112    pub fn extend_basic_from(&mut self, symbol_table: &Self) -> Result<(), SemanticError> {
113        for (name, symbol) in symbol_table.symbols() {
114            if symbol.is_basic_type() {
115                self.add_symbol(name, symbol.clone())?;
116            }
117        }
118        Ok(())
119    }
120
121    pub fn extend_intrinsic_functions_from(
122        &mut self,
123        symbol_table: &Self,
124    ) -> Result<(), SemanticError> {
125        for (name, symbol) in symbol_table.symbols() {
126            if let Symbol::FunctionDefinition(func_def) = symbol {
127                if let FuncDef::Intrinsic(_intrinsic_def) = func_def {
128                    self.add_symbol(name, symbol.clone())?;
129                }
130            }
131        }
132        Ok(())
133    }
134
135    #[must_use]
136    pub fn get_package_version(&self, name: &str) -> Option<String> {
137        match self.get_symbol(name)? {
138            Symbol::PackageVersion(name) => Some(name.to_string()),
139            _ => None,
140        }
141    }
142
143    /// # Errors
144    ///
145    pub fn add_constant(&mut self, constant: Constant) -> Result<ConstantRef, SemanticError> {
146        let constant_ref = Rc::new(constant);
147
148        self.add_constant_link(constant_ref.clone())?;
149
150        Ok(constant_ref)
151    }
152
153    /// # Errors
154    ///
155    pub fn add_constant_link(&mut self, constant_ref: ConstantRef) -> Result<(), SemanticError> {
156        let name = constant_ref.assigned_name.clone();
157
158        self.symbols
159            .insert(name.to_string(), Symbol::Constant(constant_ref))
160            .map_err(|_| SemanticError::DuplicateConstName(name.to_string()))?;
161
162        Ok(())
163    }
164
165    /// # Errors
166    ///
167    pub fn add_alias(&mut self, alias_type: AliasType) -> Result<AliasType, SemanticError> {
168        self.add_alias_link(alias_type.clone())?;
169        Ok(alias_type)
170    }
171
172    /// # Errors
173    ///
174    pub fn add_alias_link(&mut self, alias_type_ref: AliasType) -> Result<(), SemanticError> {
175        let name = alias_type_ref.assigned_name.clone();
176        self.symbols
177            .insert(name.clone(), Symbol::Alias(alias_type_ref.clone()))
178            .map_err(|_| SemanticError::DuplicateStructName(name))?;
179
180        Ok(())
181    }
182
183    /// # Errors
184    ///
185    pub fn add_blueprint(
186        &mut self,
187        blueprint: ParameterizedTypeBlueprint,
188    ) -> Result<ParameterizedTypeBlueprint, SemanticError> {
189        //let struct_ref = Rc::new(blueprint);
190        self.add_blueprint_link(blueprint.clone())?;
191        Ok(blueprint)
192    }
193
194    /// # Errors
195    ///
196    pub fn add_blueprint_link(
197        &mut self,
198        blueprint_ref: ParameterizedTypeBlueprint,
199    ) -> Result<(), SemanticError> {
200        let name = blueprint_ref.name().clone();
201        self.symbols
202            .insert(name.clone(), Symbol::Blueprint(blueprint_ref))
203            .map_err(|_| SemanticError::DuplicateStructName(name))?;
204        Ok(())
205    }
206
207    #[must_use]
208    pub fn get_blueprint(&self, name: &str) -> Option<&ParameterizedTypeBlueprint> {
209        if let Some(found_symbol) = self.get_symbol(name) {
210            if let Symbol::Blueprint(type_ref) = found_symbol {
211                return Some(type_ref);
212            }
213        }
214
215        None
216    }
217
218    pub fn add_external_type(
219        &mut self,
220        external: ExternalType,
221    ) -> Result<ExternalType, SemanticError> {
222        self.add_external_type_link(external.clone())?;
223        Ok(external)
224    }
225
226    /// # Errors
227    ///
228    pub fn add_external_type_link(
229        &mut self,
230        external_type_ref: ExternalType,
231    ) -> Result<(), SemanticError> {
232        let name = external_type_ref.type_name.clone();
233        self.symbols
234            .insert(
235                name.clone(),
236                Symbol::Type(Type::External(external_type_ref)),
237            )
238            .map_err(|_| SemanticError::DuplicateStructName(name))?;
239        Ok(())
240    }
241
242    /// # Errors
243    ///
244    pub fn add_struct(
245        &mut self,
246        struct_type: NamedStructType,
247    ) -> Result<NamedStructType, SemanticError> {
248        self.add_struct_link(struct_type.clone())?;
249        Ok(struct_type)
250    }
251
252    /// # Errors
253    ///
254    pub fn add_generated_struct(
255        &mut self,
256        name: &str,
257        fields: &[(&str, Type)],
258    ) -> Result<NamedStructType, SemanticError> {
259        let mut defined_fields = SeqMap::new();
260        for (name, field_type) in fields {
261            defined_fields
262                .insert(
263                    name.to_string(),
264                    StructTypeField {
265                        identifier: None,
266                        field_type: field_type.clone(),
267                    },
268                )
269                .unwrap();
270        }
271
272        let struct_type = NamedStructType {
273            name: Node::default(),
274            assigned_name: name.to_string(),
275            anon_struct_type: AnonymousStructType::new(defined_fields),
276            module_path: self.module_path.clone(),
277        };
278
279        self.add_struct_link(struct_type.clone())?;
280
281        Ok(struct_type)
282    }
283
284    /// # Errors
285    ///
286    pub fn add_struct_link(
287        &mut self,
288        struct_type_ref: NamedStructType,
289    ) -> Result<(), SemanticError> {
290        let name = struct_type_ref.assigned_name.clone();
291        self.symbols
292            .insert(
293                name.clone(),
294                Symbol::Type(Type::NamedStruct(struct_type_ref)),
295            )
296            .map_err(|_| SemanticError::DuplicateStructName(name))?;
297        Ok(())
298    }
299
300    pub fn add_enum_type(&mut self, enum_type: EnumType) -> Result<(), SemanticError> {
301        self.add_enum_type_link(enum_type.clone())?;
302        Ok(())
303    }
304
305    pub fn add_enum_type_link(&mut self, enum_type_ref: EnumType) -> Result<(), SemanticError> {
306        let ty = Type::Enum(enum_type_ref.clone());
307        self.symbols
308            .insert(enum_type_ref.assigned_name.clone(), Symbol::Type(ty))
309            .map_err(|_| SemanticError::DuplicateEnumType(enum_type_ref.assigned_name.clone()))?;
310
311        Ok(())
312    }
313
314    pub fn add_internal_function(
315        &mut self,
316        name: &str,
317        function: InternalFunctionDefinition,
318    ) -> Result<InternalFunctionDefinitionRef, SemanticError> {
319        let function_ref = Rc::new(function);
320        self.symbols
321            .insert(
322                name.to_string(),
323                Symbol::FunctionDefinition(FuncDef::Internal(function_ref.clone())),
324            )
325            .expect("todo: add seqmap error handling");
326        Ok(function_ref)
327    }
328
329    pub fn add_internal_function_link(
330        &mut self,
331        name: &str,
332        function_ref: InternalFunctionDefinitionRef,
333    ) -> Result<(), SemanticError> {
334        self.symbols
335            .insert(
336                name.to_string(),
337                Symbol::FunctionDefinition(FuncDef::Internal(function_ref.clone())),
338            )
339            .expect("todo: add seqmap error handling");
340        Ok(())
341    }
342
343    pub fn get_symbol(&self, name: &str) -> Option<&Symbol> {
344        self.symbols.get(&name.to_string())
345    }
346
347    pub fn add_symbol(&mut self, name: &str, symbol: Symbol) -> Result<(), SemanticError> {
348        self.symbols
349            .insert(name.to_string(), symbol)
350            .map_err(|_| SemanticError::DuplicateSymbolName(name.to_string()))
351    }
352
353    pub fn get_type(&self, name: &str) -> Option<&Type> {
354        if let Some(found_symbol) = self.get_symbol(name) {
355            if let Symbol::Type(type_ref) = found_symbol {
356                return Some(type_ref);
357            }
358        }
359
360        None
361    }
362
363    pub fn get_struct(&self, name: &str) -> Option<&NamedStructType> {
364        match self.get_type(name)? {
365            Type::NamedStruct(struct_ref) => Some(struct_ref),
366            _ => None,
367        }
368    }
369
370    pub fn get_enum(&self, name: &str) -> Option<&EnumType> {
371        match self.get_type(name)? {
372            Type::Enum(enum_type) => Some(enum_type),
373            _ => None,
374        }
375    }
376
377    #[must_use]
378    pub fn get_enum_variant_type(
379        &self,
380        enum_type_name: &str,
381        variant_name: &str,
382    ) -> Option<EnumVariantType> {
383        self.get_enum(enum_type_name).as_ref().map_or_else(
384            || None,
385            |found_enum| found_enum.variants.get(&variant_name.to_string()).cloned(),
386        )
387    }
388
389    pub fn get_constant(&self, name: &str) -> Option<&ConstantRef> {
390        match self.get_symbol(name)? {
391            Symbol::Constant(constant) => Some(constant),
392            _ => None,
393        }
394    }
395    #[must_use]
396    pub fn get_module_link(&self, name: &str) -> Option<&ModuleRef> {
397        match self.get_symbol(name)? {
398            Symbol::Module(module_ref) => Some(module_ref),
399            _ => None,
400        }
401    }
402
403    // Functions
404
405    #[must_use]
406    pub fn get_function(&self, name: &str) -> Option<&FuncDef> {
407        match self.get_symbol(name)? {
408            Symbol::FunctionDefinition(func_def) => Some(func_def),
409            _ => None,
410        }
411    }
412
413    #[must_use]
414    pub fn get_internal_function(&self, name: &str) -> Option<&InternalFunctionDefinitionRef> {
415        match self.get_function(name)? {
416            FuncDef::Internal(internal_fn) => Some(internal_fn),
417            FuncDef::External(_) => None,
418            FuncDef::Intrinsic(_) => None,
419        }
420    }
421
422    #[must_use]
423    pub fn get_intrinsic_function(&self, name: &str) -> Option<&IntrinsicFunctionDefinitionRef> {
424        match self.get_function(name)? {
425            FuncDef::Intrinsic(intrinsic_fn) => Some(intrinsic_fn),
426            _ => None,
427        }
428    }
429
430    #[must_use]
431    pub fn get_external_function_declaration(
432        &self,
433        name: &str,
434    ) -> Option<&ExternalFunctionDefinitionRef> {
435        match self.get_function(name)? {
436            FuncDef::External(external_def) => Some(external_def),
437            _ => None,
438        }
439    }
440
441    pub fn get_external_type(&self, name: &str) -> Option<&ExternalType> {
442        match self.get_type(name)? {
443            Type::External(ext_type) => Some(ext_type),
444            _ => None,
445        }
446    }
447
448    fn insert_symbol(&mut self, name: &str, symbol: Symbol) -> Result<(), SemanticError> {
449        self.symbols
450            .insert(name.to_string(), symbol)
451            .map_err(|_| SemanticError::DuplicateSymbolName(name.to_string()))
452    }
453
454    pub fn add_external_function_declaration(
455        &mut self,
456        decl: ExternalFunctionDefinition,
457    ) -> Result<ExternalFunctionDefinitionRef, SemanticError> {
458        let decl_ref = Rc::new(decl);
459
460        self.add_external_function_declaration_link(decl_ref.clone())?;
461
462        Ok(decl_ref)
463    }
464
465    pub fn add_external_function_declaration_link(
466        &mut self,
467        decl_ref: ExternalFunctionDefinitionRef,
468    ) -> Result<(), SemanticError> {
469        self.insert_symbol(
470            &decl_ref.assigned_name,
471            Symbol::FunctionDefinition(FuncDef::External(decl_ref.clone())),
472        )
473        .map_err(|_| {
474            SemanticError::DuplicateExternalFunction(decl_ref.assigned_name.to_string())
475        })?;
476        Ok(())
477    }
478
479    pub fn add_module_link(&mut self, name: &str, ns: ModuleRef) -> Result<(), SemanticError> {
480        self.insert_symbol(name, Symbol::Module(ns))
481            .map_err(|_| SemanticError::DuplicateNamespaceLink(name.to_string()))?;
482        Ok(())
483    }
484
485    pub fn add_package_version(
486        &mut self,
487        name: &str,
488        version: TinyVersion,
489    ) -> Result<(), SemanticError> {
490        self.insert_symbol(name, Symbol::PackageVersion(version))
491            .map_err(|_| SemanticError::DuplicateNamespaceLink(name.to_string()))?;
492        Ok(())
493    }
494
495    pub fn add_intrinsic_function(
496        &mut self,
497        function: IntrinsicFunctionDefinition,
498    ) -> Result<IntrinsicFunctionDefinitionRef, SemanticError> {
499        let function_ref = Rc::new(function);
500        self.symbols
501            .insert(
502                function_ref.name.clone(),
503                Symbol::FunctionDefinition(FuncDef::Intrinsic(function_ref.clone())),
504            )
505            .expect("todo: add seqmap error handling");
506        Ok(function_ref)
507    }
508}