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