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