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,
11    NamedStructType, Node, SemanticError, StructTypeField, StructTypeRef, Type, TypeNumber,
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::NamedStruct(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(
203        &mut self,
204        struct_type: NamedStructType,
205    ) -> Result<StructTypeRef, SemanticError> {
206        let struct_ref = Rc::new(RefCell::new(struct_type));
207        self.add_struct_link(struct_ref.clone())?;
208        Ok(struct_ref)
209    }
210
211    /// # Errors
212    ///
213    pub fn add_generated_struct(
214        &mut self,
215        name: &str,
216        fields: &[(&str, Type)],
217        type_id: TypeNumber,
218    ) -> Result<StructTypeRef, SemanticError> {
219        let mut defined_fields = SeqMap::new();
220        for (name, field_type) in fields {
221            defined_fields
222                .insert(
223                    name.to_string(),
224                    StructTypeField {
225                        identifier: None,
226                        field_type: field_type.clone(),
227                    },
228                )
229                .unwrap();
230        }
231
232        let struct_type = NamedStructType {
233            name: Node::default(),
234            assigned_name: name.to_string(),
235            anon_struct_type: AnonymousStructType::new(defined_fields),
236            type_id,
237        };
238
239        let struct_ref = Rc::new(RefCell::new(struct_type));
240
241        self.add_struct_link(struct_ref.clone())?;
242
243        Ok(struct_ref)
244    }
245
246    /// # Errors
247    ///
248    pub fn add_struct_link(&mut self, struct_type_ref: StructTypeRef) -> Result<(), SemanticError> {
249        let name = struct_type_ref.borrow().assigned_name.clone();
250        self.symbols
251            .insert(
252                name.clone(),
253                Symbol::Type(Type::NamedStruct(struct_type_ref)),
254            )
255            .map_err(|_| SemanticError::DuplicateStructName(name))?;
256        Ok(())
257    }
258
259    pub fn add_enum_type(&mut self, enum_type: EnumType) -> Result<EnumTypeRef, SemanticError> {
260        let enum_type_ref = Rc::new(RefCell::new(enum_type));
261        self.add_enum_type_link(enum_type_ref.clone())?;
262        Ok(enum_type_ref)
263    }
264
265    pub fn add_enum_type_link(&mut self, enum_type_ref: EnumTypeRef) -> Result<(), SemanticError> {
266        let ty = Type::Enum(enum_type_ref.clone());
267        self.symbols
268            .insert(
269                enum_type_ref.borrow().assigned_name.clone(),
270                Symbol::Type(ty),
271            )
272            .map_err(|_| {
273                SemanticError::DuplicateEnumType(enum_type_ref.borrow().assigned_name.clone())
274            })?;
275
276        Ok(())
277    }
278
279    pub fn add_enum_variant(
280        &mut self,
281        enum_type_name: EnumTypeRef,
282        enum_variant: EnumVariantType,
283    ) -> Result<EnumVariantTypeRef, SemanticError> {
284        let enum_variant_ref = Rc::new(enum_variant);
285        enum_type_name
286            .borrow_mut()
287            .variants
288            .insert(
289                enum_variant_ref.common().assigned_name.clone(),
290                enum_variant_ref.clone(),
291            )
292            .map_err(|_err| {
293                SemanticError::DuplicateEnumVariantType(
294                    enum_type_name.borrow().assigned_name.clone(),
295                    enum_variant_ref.common().assigned_name.clone(),
296                )
297            })?;
298
299        Ok(enum_variant_ref)
300    }
301
302    pub fn add_internal_function(
303        &mut self,
304        name: &str,
305        function: InternalFunctionDefinition,
306    ) -> Result<InternalFunctionDefinitionRef, SemanticError> {
307        let function_ref = Rc::new(function);
308        self.symbols
309            .insert(
310                name.to_string(),
311                Symbol::FunctionDefinition(FuncDef::Internal(function_ref.clone())),
312            )
313            .expect("todo: add seqmap error handling");
314        Ok(function_ref)
315    }
316
317    pub fn add_internal_function_link(
318        &mut self,
319        name: &str,
320        function_ref: InternalFunctionDefinitionRef,
321    ) -> Result<(), SemanticError> {
322        self.symbols
323            .insert(
324                name.to_string(),
325                Symbol::FunctionDefinition(FuncDef::Internal(function_ref.clone())),
326            )
327            .expect("todo: add seqmap error handling");
328        Ok(())
329    }
330
331    pub fn get_symbol(&self, name: &str) -> Option<&Symbol> {
332        self.symbols.get(&name.to_string())
333    }
334
335    pub fn add_symbol(&mut self, name: &str, symbol: Symbol) -> Result<(), SemanticError> {
336        self.symbols
337            .insert(name.to_string(), symbol)
338            .map_err(|_| SemanticError::DuplicateSymbolName)
339    }
340
341    pub fn get_type(&self, name: &str) -> Option<&Type> {
342        if let Some(found_symbol) = self.get_symbol(name) {
343            if let Symbol::Type(type_ref) = found_symbol {
344                return Some(type_ref);
345            }
346        }
347
348        None
349    }
350
351    pub fn get_struct(&self, name: &str) -> Option<&StructTypeRef> {
352        match self.get_type(name)? {
353            Type::NamedStruct(struct_ref) => Some(struct_ref),
354            _ => None,
355        }
356    }
357
358    pub fn get_enum(&self, name: &str) -> Option<&EnumTypeRef> {
359        match self.get_type(name)? {
360            Type::Enum(enum_type) => Some(enum_type),
361            _ => None,
362        }
363    }
364
365    #[must_use]
366    pub fn get_enum_variant_type(
367        &self,
368        enum_type_name: &str,
369        variant_name: &str,
370    ) -> Option<EnumVariantTypeRef> {
371        self.get_enum(enum_type_name).as_ref().map_or_else(
372            || None,
373            |found_enum| {
374                found_enum
375                    .borrow()
376                    .variants
377                    .get(&variant_name.to_string())
378                    .cloned()
379            },
380        )
381    }
382
383    pub fn get_constant(&self, name: &str) -> Option<&ConstantRef> {
384        match self.get_symbol(name)? {
385            Symbol::Constant(constant) => Some(constant),
386            _ => None,
387        }
388    }
389    #[must_use]
390    pub fn get_module_link(&self, name: &str) -> Option<&ModuleRef> {
391        match self.get_symbol(name)? {
392            Symbol::Module(module_ref) => Some(module_ref),
393            _ => None,
394        }
395    }
396
397    // Functions
398
399    #[must_use]
400    pub fn get_function(&self, name: &str) -> Option<&FuncDef> {
401        match self.get_symbol(name)? {
402            Symbol::FunctionDefinition(func_def) => Some(func_def),
403            _ => None,
404        }
405    }
406
407    #[must_use]
408    pub fn get_internal_function(&self, name: &str) -> Option<&InternalFunctionDefinitionRef> {
409        match self.get_function(name)? {
410            FuncDef::Internal(internal_fn) => Some(internal_fn),
411            FuncDef::External(_) => None,
412            FuncDef::Intrinsic(_) => None,
413        }
414    }
415
416    #[must_use]
417    pub fn get_intrinsic_function(&self, name: &str) -> Option<&IntrinsicFunctionDefinitionRef> {
418        match self.get_function(name)? {
419            FuncDef::Intrinsic(intrinsic_fn) => Some(intrinsic_fn),
420            _ => None,
421        }
422    }
423
424    #[must_use]
425    pub fn get_external_function_declaration(
426        &self,
427        name: &str,
428    ) -> Option<&ExternalFunctionDefinitionRef> {
429        match self.get_function(name)? {
430            FuncDef::External(external_def) => Some(external_def),
431            _ => None,
432        }
433    }
434
435    pub fn get_external_type(&self, name: &str) -> Option<&ExternalTypeRef> {
436        match self.get_type(name)? {
437            Type::External(ext_type) => Some(ext_type),
438            _ => None,
439        }
440    }
441
442    fn insert_symbol(&mut self, name: &str, symbol: Symbol) -> Result<(), SemanticError> {
443        self.symbols
444            .insert(name.to_string(), symbol)
445            .map_err(|_| SemanticError::DuplicateSymbolName)
446    }
447
448    pub fn add_external_function_declaration(
449        &mut self,
450        decl: ExternalFunctionDefinition,
451    ) -> Result<ExternalFunctionDefinitionRef, SemanticError> {
452        let decl_ref = Rc::new(decl);
453
454        self.add_external_function_declaration_link(decl_ref.clone())?;
455
456        Ok(decl_ref)
457    }
458
459    pub fn add_external_function_declaration_link(
460        &mut self,
461        decl_ref: ExternalFunctionDefinitionRef,
462    ) -> Result<(), SemanticError> {
463        self.insert_symbol(
464            &decl_ref.assigned_name,
465            Symbol::FunctionDefinition(FuncDef::External(decl_ref.clone())),
466        )
467        .map_err(|_| {
468            SemanticError::DuplicateExternalFunction(decl_ref.assigned_name.to_string())
469        })?;
470        Ok(())
471    }
472
473    pub fn add_module_link(&mut self, name: &str, ns: ModuleRef) -> Result<(), SemanticError> {
474        self.insert_symbol(name, Symbol::Module(ns))
475            .map_err(|_| SemanticError::DuplicateNamespaceLink(name.to_string()))?;
476        Ok(())
477    }
478}