swamp_script_analyzer/
constant.rs1use crate::err::{Error, ErrorKind};
7use crate::{Analyzer, TypeContext};
8use swamp_script_semantic::{Constant, ConstantRef, Expression, ExpressionKind};
9
10impl Analyzer<'_> {
11 fn analyze_constant(&mut self, constant: &swamp_script_ast::ConstantInfo) -> Result<(), Error> {
12 let context = TypeContext::new_anything_argument();
13 let resolved_expr = self.analyze_expression(&constant.expression, &context)?;
14 let resolved_type = resolved_expr.ty.clone();
15 let name_node = self.to_node(&constant.constant_identifier.0);
16 let name_text = self.get_text_resolved(&name_node).to_string();
17 let constant = Constant {
18 name: name_node.clone(),
19 assigned_name: name_text,
20 id: self.shared.state.constants_in_dependency_order.len() as u32,
21 expr: resolved_expr,
22 resolved_type,
23 };
24
25 let const_ref = self
26 .shared
27 .definition_table
28 .add_constant(constant)
29 .map_err(|s| self.create_err_resolved(ErrorKind::SemanticError(s), &name_node))?;
30
31 self.shared
32 .lookup_table
33 .add_constant_link(const_ref.clone())
34 .map_err(|s| self.create_err_resolved(ErrorKind::SemanticError(s), &name_node))?;
35
36 self.shared
38 .state
39 .constants_in_dependency_order
40 .push(const_ref);
41
42 Ok(())
43 }
44
45 pub(crate) fn analyze_constant_definition(
46 &mut self,
47 constant: &swamp_script_ast::ConstantInfo,
48 ) -> Result<(), Error> {
49 self.analyze_constant(constant)
50 }
51
52 pub(crate) fn analyze_constant_access(
53 &self,
54 qualified_constant_identifier: &swamp_script_ast::QualifiedConstantIdentifier,
55 ) -> Result<Expression, Error> {
56 self.try_find_constant(qualified_constant_identifier)
57 .map_or_else(
58 || {
59 Err(self.create_err(
60 ErrorKind::UnknownConstant,
61 &qualified_constant_identifier.name,
62 ))
63 },
64 |constant_ref| {
65 let ty = constant_ref.resolved_type.clone();
66 Ok(self.create_expr(
67 ExpressionKind::ConstantAccess(constant_ref.clone()),
68 ty,
69 &qualified_constant_identifier.name,
70 ))
71 },
72 )
73 }
74
75 #[must_use]
76 pub fn try_find_constant(
77 &self,
78 qualified_constant_identifier: &swamp_script_ast::QualifiedConstantIdentifier,
79 ) -> Option<&ConstantRef> {
80 let path = self.get_module_path(qualified_constant_identifier.module_path.as_ref());
81 let constant_name = self.get_text(&qualified_constant_identifier.name);
82
83 let maybe_symbol_table = self.shared.get_symbol_table(&path);
84 maybe_symbol_table.map_or_else(
85 || None,
86 |symbol_table| Some(symbol_table.get_constant(constant_name)),
87 )?
88 }
89}