swamp_modules/
symtbl.rs

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