swamp_script_analyzer/
call.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::TypeContext;
7use crate::err::{Error, ErrorKind};
8use crate::{Analyzer, LocationSide};
9use swamp_script_node::Node;
10use swamp_script_semantic::{ArgumentExpressionOrLocation, MutOrImmutableExpression};
11use swamp_script_types::prelude::*;
12
13impl Analyzer<'_> {
14    /// # Errors
15    ///
16    pub fn analyze_argument(
17        &mut self,
18        fn_parameter: &TypeForParameter,
19        argument_expr: &swamp_script_ast::MutableOrImmutableExpression,
20    ) -> Result<ArgumentExpressionOrLocation, Error> {
21        let context = TypeContext::new_argument(&fn_parameter.resolved_type);
22
23        let mut_or_immutable = if fn_parameter.is_mutable {
24            if argument_expr.is_mutable.is_none() {
25                return Err(self.create_err(
26                    ErrorKind::ArgumentIsNotMutable,
27                    &argument_expr.expression.node,
28                ));
29            }
30            let mut_location =
31                self.analyze_to_location(&argument_expr.expression, &context, LocationSide::Rhs)?;
32            ArgumentExpressionOrLocation::Location(mut_location)
33        } else {
34            if argument_expr.is_mutable.is_some() {
35                return Err(self.create_err(
36                    ErrorKind::ParameterIsNotMutable,
37                    &argument_expr.expression.node,
38                ));
39            }
40            let resolved_expr = self.analyze_expression(&argument_expr.expression, &context)?;
41            ArgumentExpressionOrLocation::Expression(resolved_expr)
42        };
43
44        Ok(mut_or_immutable)
45    }
46
47    /// # Errors
48    ///
49    pub fn analyze_and_verify_parameters(
50        &mut self,
51        node: &Node,
52        fn_parameters: &[TypeForParameter],
53        arguments: &[swamp_script_ast::MutableOrImmutableExpression],
54    ) -> Result<Vec<ArgumentExpressionOrLocation>, Error> {
55        if fn_parameters.len() != arguments.len() {
56            return Err(self.create_err_resolved(
57                ErrorKind::WrongNumberOfArguments(fn_parameters.len(), arguments.len()),
58                node,
59            ));
60        }
61
62        let mut resolved_arguments = Vec::new();
63        for (fn_parameter, argument_expr) in fn_parameters.iter().zip(arguments) {
64            let mut_or_immutable = self.analyze_argument(fn_parameter, argument_expr)?;
65            resolved_arguments.push(mut_or_immutable);
66        }
67
68        Ok(resolved_arguments)
69    }
70
71    /// # Errors
72    ///
73    pub fn analyze_mut_or_immutable_expression(
74        &mut self,
75        expr: &swamp_script_ast::MutableOrImmutableExpression,
76        context: &TypeContext,
77        location_side: LocationSide,
78    ) -> Result<MutOrImmutableExpression, Error> {
79        let is_mutable = self.to_node_option(Option::from(&expr.is_mutable));
80        let expression_or_location = if is_mutable.is_some() {
81            ArgumentExpressionOrLocation::Location(self.analyze_to_location(
82                &expr.expression,
83                context,
84                location_side,
85            )?)
86        } else {
87            ArgumentExpressionOrLocation::Expression(
88                self.analyze_expression(&expr.expression, context)?,
89            )
90        };
91
92        Ok(MutOrImmutableExpression {
93            expression_or_location,
94            is_mutable,
95        })
96    }
97}