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