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