swamp_script_analyzer/
constant.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 */
5
6use 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        // This extra storage of the constants in modules is to have them in analyze / dependency order
37        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        constant_identifier: &swamp_script_ast::ConstantIdentifier,
55    ) -> Result<Expression, Error> {
56        self.try_find_constant(constant_identifier).map_or_else(
57            || Err(self.create_err(ErrorKind::UnknownConstant, &constant_identifier.0)),
58            |constant_ref| {
59                let ty = constant_ref.resolved_type.clone();
60                Ok(self.create_expr(
61                    ExpressionKind::ConstantAccess(constant_ref.clone()),
62                    ty,
63                    &constant_identifier.0,
64                ))
65            },
66        )
67    }
68
69    #[must_use]
70    pub fn try_find_constant(
71        &self,
72        constant_identifier: &swamp_script_ast::ConstantIdentifier,
73    ) -> Option<&ConstantRef> {
74        let constant_name = self.get_text(&constant_identifier.0);
75        self.shared.lookup_table.get_constant(constant_name)
76    }
77}