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 Analyzer<'_> {
16 pub fn analyze_argument(
19 &mut self,
20 fn_parameter: &TypeForParameter,
21 argument_expr: &swamp_script_ast::MutableOrImmutableExpression,
22 ) -> Result<ArgumentExpressionOrLocation, Error> {
23 let context = TypeContext::new_argument(&fn_parameter.resolved_type);
24
25 let mut_or_immutable = if fn_parameter.is_mutable {
26 if argument_expr.is_mutable.is_none() {
27 return Err(self.create_err(
28 ErrorKind::ArgumentIsNotMutable,
29 &argument_expr.expression.node,
30 ));
31 }
32 let mut_location =
33 self.analyze_to_location(&argument_expr.expression, &context, LocationSide::Rhs)?;
34 ArgumentExpressionOrLocation::Location(mut_location)
35 } else {
36 if argument_expr.is_mutable.is_some() {
37 return Err(self.create_err(
38 ErrorKind::ParameterIsNotMutable,
39 &argument_expr.expression.node,
40 ));
41 }
42 let resolved_expr = self.analyze_expression(&argument_expr.expression, &context)?;
43 ArgumentExpressionOrLocation::Expression(resolved_expr)
44 };
45
46 Ok(mut_or_immutable)
47 }
48
49 pub fn analyze_and_verify_parameters(
52 &mut self,
53 node: &Node,
54 fn_parameters: &[TypeForParameter],
55 arguments: &[swamp_script_ast::MutableOrImmutableExpression],
56 ) -> Result<Vec<ArgumentExpressionOrLocation>, Error> {
57 if fn_parameters.len() != arguments.len() {
58 return Err(self.create_err_resolved(
59 ErrorKind::WrongNumberOfArguments(fn_parameters.len(), arguments.len()),
60 node,
61 ));
62 }
63
64 let mut resolved_arguments = Vec::new();
65 for (fn_parameter, argument_expr) in fn_parameters.iter().zip(arguments) {
66 let mut_or_immutable = self.analyze_argument(fn_parameter, argument_expr)?;
67 resolved_arguments.push(mut_or_immutable);
68 }
69
70 Ok(resolved_arguments)
71 }
72
73 pub(crate) fn check_for_internal_static_call(
74 &mut self,
75 type_name: &swamp_script_ast::QualifiedTypeIdentifier,
76 function_name: &swamp_script_ast::Node,
77 arguments: &[swamp_script_ast::MutableOrImmutableExpression],
78 ) -> Result<Option<Expression>, Error> {
79 let (type_name_text, function_name_text) = {
80 (
81 self.get_text(&type_name.name.0).to_string(),
82 self.get_text(function_name),
83 )
84 };
85
86 if type_name_text == "Sparse" && function_name_text == "new" {
87 if !arguments.is_empty() {
88 return Err(self.create_err(
89 ErrorKind::WrongNumberOfArguments(arguments.len(), 0),
90 function_name,
91 ));
92 }
93 let resolved_generic_type_parameters = self.analyze_types(&type_name.generic_params)?;
94 if resolved_generic_type_parameters.len() != 1 {
95 return Err(self.create_err(
96 ErrorKind::WrongNumberOfTypeArguments(
97 resolved_generic_type_parameters.len(),
98 1,
99 ),
100 function_name,
101 ));
102 }
103
104 let rust_type_ref = Rc::new(ExternalType {
105 type_name: type_name_text,
106 number: SPARSE_TYPE_ID, });
108
109 let rust_type_base = Type::External(rust_type_ref.clone());
110
111 let generic_specific_type = Type::Generic(
112 Box::from(rust_type_base.clone()),
113 resolved_generic_type_parameters.clone(),
114 );
115
116 let value_item_type = resolved_generic_type_parameters[0].clone();
117
118 let expr = self.create_expr(
119 ExpressionKind::SparseNew(rust_type_ref, value_item_type),
120 generic_specific_type,
121 &type_name.name.0,
122 );
123
124 return Ok(Some(expr));
125 }
126
127 Ok(None)
128 }
129
130 pub fn analyze_mut_or_immutable_expression(
133 &mut self,
134 expr: &swamp_script_ast::MutableOrImmutableExpression,
135 context: &TypeContext,
136 location_side: LocationSide,
137 ) -> Result<MutOrImmutableExpression, Error> {
138 let is_mutable = self.to_node_option(Option::from(&expr.is_mutable));
139 let expression_or_location = if is_mutable.is_some() {
140 ArgumentExpressionOrLocation::Location(self.analyze_to_location(
141 &expr.expression,
142 context,
143 location_side,
144 )?)
145 } else {
146 ArgumentExpressionOrLocation::Expression(
147 self.analyze_expression(&expr.expression, context)?,
148 )
149 };
150
151 Ok(MutOrImmutableExpression {
152 expression_or_location,
153 is_mutable,
154 })
155 }
156}