swamp_script_analyzer/
call.rs1use crate::TypeContext;
7use crate::err::{Error, ErrorKind};
8use crate::{Analyzer, LocationSide, SPARSE_TYPE_ID};
9use std::rc::Rc;
10use swamp_script_semantic::{
11 ArgumentExpressionOrLocation, Expression, ExpressionKind, ExternalType,
12 MutOrImmutableExpression, Node, Type, TypeForParameter,
13};
14
15impl<'a> Analyzer<'a> {
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 pub fn analyze_and_verify_parameters(
48 &mut self,
49 node: &Node,
50 fn_parameters: &[TypeForParameter],
51 arguments: &[swamp_script_ast::MutableOrImmutableExpression],
52 ) -> Result<Vec<ArgumentExpressionOrLocation>, Error> {
53 if fn_parameters.len() != arguments.len() {
54 return Err(self.create_err_resolved(
55 ErrorKind::WrongNumberOfArguments(fn_parameters.len(), arguments.len()),
56 node,
57 ));
58 }
59
60 let mut resolved_arguments = Vec::new();
61 for (fn_parameter, argument_expr) in fn_parameters.iter().zip(arguments) {
62 let mut_or_immutable = self.analyze_argument(fn_parameter, argument_expr)?;
63 resolved_arguments.push(mut_or_immutable);
64 }
65
66 Ok(resolved_arguments)
69 }
70
71 pub(crate) fn check_for_internal_static_call(
72 &mut self,
73 type_name: &swamp_script_ast::QualifiedTypeIdentifier,
74 function_name: &swamp_script_ast::Node,
75 arguments: &[swamp_script_ast::MutableOrImmutableExpression],
76 ) -> Result<Option<Expression>, Error> {
77 let (type_name_text, function_name_text) = {
78 (
79 self.get_text(&type_name.name.0).to_string(),
80 self.get_text(function_name),
81 )
82 };
83
84 if type_name_text == "Sparse" && function_name_text == "new" {
85 if !arguments.is_empty() {
86 return Err(self.create_err(
87 ErrorKind::WrongNumberOfArguments(arguments.len(), 0),
88 function_name,
89 ));
90 }
91 let resolved_generic_type_parameters = self.analyze_types(&type_name.generic_params)?;
92 if resolved_generic_type_parameters.len() != 1 {
93 return Err(self.create_err(
94 ErrorKind::WrongNumberOfTypeArguments(
95 resolved_generic_type_parameters.len(),
96 1,
97 ),
98 function_name,
99 ));
100 }
101
102 let rust_type_ref = Rc::new(ExternalType {
103 type_name: type_name_text,
104 number: SPARSE_TYPE_ID, });
106
107 let rust_type_base = Type::External(rust_type_ref.clone());
108
109 let generic_specific_type = Type::Generic(
110 Box::from(rust_type_base.clone()),
111 resolved_generic_type_parameters.clone(),
112 );
113
114 let value_item_type = resolved_generic_type_parameters[0].clone();
115
116 let expr = self.create_expr(
117 ExpressionKind::SparseNew(rust_type_ref, value_item_type),
118 generic_specific_type,
119 &type_name.name.0,
120 );
121
122 return Ok(Some(expr));
123 }
124
125 Ok(None)
126 }
127
128 pub fn analyze_mut_or_immutable_expression(
129 &mut self,
130 expr: &swamp_script_ast::MutableOrImmutableExpression,
131 context: &TypeContext,
132 location_side: LocationSide,
133 ) -> Result<MutOrImmutableExpression, Error> {
134 let is_mutable = self.to_node_option(Option::from(&expr.is_mutable));
135 let expression_or_location = if is_mutable.is_some() {
136 ArgumentExpressionOrLocation::Location(self.analyze_to_location(
137 &expr.expression,
138 context,
139 location_side,
140 )?)
141 } else {
142 ArgumentExpressionOrLocation::Expression(
143 self.analyze_expression(&expr.expression, context)?,
144 )
145 };
146
147 Ok(MutOrImmutableExpression {
148 expression_or_location,
149 is_mutable,
150 })
151 }
152}