swamp_script_analyzer/
access.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::Analyzer;
6use crate::TypeContext;
7use crate::err::{Error, ErrorKind};
8use swamp_script_semantic::{
9    ArrayTypeRef, Expression, ExpressionKind, Function, FunctionRef, Range, RangeMode, Type,
10};
11
12impl<'a> Analyzer<'a> {
13    fn convert_to_function_access(function: &FunctionRef) -> Expression {
14        match &**function {
15            Function::Internal(x) => Expression {
16                ty: Type::Function(x.signature.clone()),
17                node: function.node(),
18                kind: ExpressionKind::InternalFunctionAccess(x.clone()),
19            },
20            Function::External(y) => Expression {
21                ty: Type::Function(y.signature.clone()),
22                node: function.node(),
23                kind: ExpressionKind::ExternalFunctionAccess(y.clone()),
24            },
25        }
26    }
27
28    pub(crate) fn analyze_static_member_access(
29        &mut self,
30        struct_reference: &swamp_script_ast::QualifiedTypeIdentifier,
31        member_name_node: &swamp_script_ast::Node,
32    ) -> Result<Expression, Error> {
33        let struct_type = self.get_struct_type(struct_reference)?;
34        let member_name = self.get_text(member_name_node);
35        let binding = struct_type.borrow();
36        let member_function = binding
37            .functions
38            .get(&member_name.to_string())
39            .ok_or_else(|| self.create_err(ErrorKind::UnknownMemberFunction, member_name_node))?;
40
41        let expr = Self::convert_to_function_access(member_function);
42
43        Ok(expr)
44    }
45
46    pub(crate) fn analyze_min_max_expr(
47        &mut self,
48        min_expr: &swamp_script_ast::Expression,
49        max_expr: &swamp_script_ast::Expression,
50    ) -> Result<(Expression, Expression), Error> {
51        let context = TypeContext::new_argument(&Type::Int);
52
53        let resolved_min = self.analyze_expression(min_expr, &context)?;
54        let resolved_max = self.analyze_expression(max_expr, &context)?;
55
56        Ok((resolved_min, resolved_max))
57    }
58
59    pub fn analyze_range(
60        &mut self,
61        min_expr: &swamp_script_ast::Expression,
62        max_expr: &swamp_script_ast::Expression,
63        mode: &swamp_script_ast::RangeMode,
64    ) -> Result<Range, Error> {
65        let (min, max) = self.analyze_min_max_expr(min_expr, max_expr)?;
66
67        let resolved_range_mode = match mode {
68            swamp_script_ast::RangeMode::Inclusive => RangeMode::Inclusive,
69            swamp_script_ast::RangeMode::Exclusive => RangeMode::Exclusive,
70        };
71        Ok(Range {
72            min,
73            max,
74            mode: resolved_range_mode,
75        })
76    }
77
78    /// # Errors
79    ///
80    pub fn analyze_array_range_access(
81        &mut self,
82        base_expression: Expression,
83        array_type_ref: &ArrayTypeRef,
84        range: Range,
85    ) -> Result<Expression, Error> {
86        let node = &base_expression.node.clone();
87
88        Ok(self.create_expr_resolved(
89            ExpressionKind::ArrayRangeAccess(Box::from(base_expression), Box::from(range)),
90            Type::Array(array_type_ref.clone()),
91            &node,
92        ))
93    }
94
95    /// # Errors
96    ///
97    pub fn analyze_string_range_access(
98        &mut self,
99        base_expr: Expression,
100        range: Range,
101    ) -> Result<Expression, Error> {
102        let ty = base_expr.ty.clone();
103        let node = base_expr.node.clone();
104        Ok(self.create_expr_resolved(
105            ExpressionKind::StringRangeAccess(Box::from(base_expr), Box::from(range)),
106            ty,
107            &node,
108        ))
109    }
110}