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