1use crate::err::{Error, ErrorKind};
6use crate::{Analyzer, TypeContext};
7use swamp_script_node::Node;
8use swamp_script_semantic::ExpressionKind;
9use swamp_script_semantic::{
10 ArgumentExpressionOrLocation, EnumLiteralData, Expression, Fp, Literal,
11};
12use swamp_script_types::prelude::*;
13use tracing::error;
14use tracing::info;
15
16impl Analyzer<'_> {
17 #[allow(clippy::too_many_lines)]
20 pub fn analyze_complex_literal_to_expression(
21 &mut self,
22 ast_node: &swamp_script_ast::Node,
23 ast_literal_kind: &swamp_script_ast::LiteralKind,
24 context: &TypeContext,
25 ) -> Result<Expression, Error> {
26 let expression = match &ast_literal_kind {
27 swamp_script_ast::LiteralKind::Slice(items) => {
28 let (encountered_element_type, resolved_items) =
29 self.analyze_slice_type_helper(ast_node, items)?;
30
31 let slice_type = Type::Slice(Box::new(encountered_element_type.clone()));
32
33 let found_expected_type = if let Some(inner_type) = context.expected_type {
34 inner_type.clone()
35 } else {
36 let vec_blueprint = self
37 .shared
38 .core_symbol_table
39 .get_blueprint("Vec")
40 .unwrap()
41 .clone();
42 self.shared
43 .state
44 .instantiator
45 .instantiate_blueprint_and_members(
46 &vec_blueprint,
47 &[encountered_element_type.clone()],
48 )?
49 };
50
51 if let Some(found) = self
52 .shared
53 .state
54 .instantiator
55 .associated_impls
56 .get_internal_member_function(&found_expected_type, "new_from_slice")
57 {
58 let required_type = &found.signature.signature.parameters[0].resolved_type;
59 if resolved_items.is_empty() || slice_type.compatible_with(required_type) {
60 let slice_literal =
61 Literal::Slice(slice_type.clone(), resolved_items.clone());
62
63 let expr = self.create_expr(
64 ExpressionKind::Literal(slice_literal),
65 slice_type.clone(),
66 ast_node,
67 );
68 let return_type = *found.signature.signature.return_type.clone();
69 let arg = ArgumentExpressionOrLocation::Expression(expr);
70 let call_kind = self.create_static_call(
71 "new_from_slice",
72 &[arg],
73 ast_node,
74 &found_expected_type.clone(),
75 )?;
76
77 self.create_expr(call_kind, return_type, ast_node)
78 } else {
79 error!(
80 ?slice_type,
81 ?required_type,
82 "incompatible types new_from_slice"
83 );
84 return Err(self.create_err(
85 ErrorKind::IncompatibleTypes {
86 expected: required_type.clone(),
87 found: slice_type,
88 },
89 ast_node,
90 ));
91 }
92 } else {
93 return Err(self.create_err(
94 ErrorKind::MissingMemberFunction("new_from_slice".to_string()),
95 ast_node,
96 ));
97 }
98 }
99
100 swamp_script_ast::LiteralKind::SlicePair(entries) => {
101 let (resolved_items, encountered_key_type, encountered_value_type) =
102 self.analyze_slice_pair_literal(ast_node, entries)?;
103
104 let slice_pair_type = Type::SlicePair(
105 Box::new(encountered_key_type.clone()),
106 Box::new(encountered_value_type.clone()),
107 );
108
109 let found_expected_type = if let Some(inner_type) = context.expected_type {
110 inner_type.clone()
111 } else {
112 let map_blueprint = self
113 .shared
114 .core_symbol_table
115 .get_blueprint("Map")
116 .unwrap()
117 .clone();
118 self.shared
119 .state
120 .instantiator
121 .instantiate_blueprint_and_members(
122 &map_blueprint,
123 &[encountered_key_type.clone(), encountered_value_type.clone()],
124 )?
125 };
126
127 if let Some(found) = self
128 .shared
129 .state
130 .instantiator
131 .associated_impls
132 .get_internal_member_function(&found_expected_type, "new_from_slice_pair")
133 {
134 let required_type = &found.signature.signature.parameters[0].resolved_type;
135 if resolved_items.is_empty() || slice_pair_type.compatible_with(required_type) {
136 let slice_literal =
137 Literal::SlicePair(slice_pair_type.clone(), resolved_items.clone());
138
139 let expr = self.create_expr(
140 ExpressionKind::Literal(slice_literal),
141 slice_pair_type.clone(),
142 ast_node,
143 );
144 let return_type = *found.signature.signature.return_type.clone();
145 let arg = ArgumentExpressionOrLocation::Expression(expr);
146 let call_kind = self.create_static_call(
147 "new_from_slice_pair",
148 &[arg],
149 ast_node,
150 &found_expected_type.clone(),
151 )?;
152
153 self.create_expr(call_kind, return_type, ast_node)
154 } else {
155 return Err(self.create_err(
156 ErrorKind::IncompatibleTypes {
157 expected: required_type.clone(),
158 found: slice_pair_type,
159 },
160 ast_node,
161 ));
162 }
163 } else {
164 return Err(self.create_err(
165 ErrorKind::MissingMemberFunction("new_from_slice_pair".to_string()),
166 ast_node,
167 ));
168 }
169 }
170
171 _ => {
172 let (lit_kind, literal_type) =
173 self.analyze_literal(ast_node, ast_literal_kind, context)?;
174 self.create_expr(ExpressionKind::Literal(lit_kind), literal_type, ast_node)
175 }
176 };
177
178 Ok(expression)
179 }
180
181 #[allow(clippy::too_many_lines)]
182 pub(crate) fn analyze_literal(
183 &mut self,
184 ast_node: &swamp_script_ast::Node,
185 ast_literal_kind: &swamp_script_ast::LiteralKind,
186 context: &TypeContext,
187 ) -> Result<(Literal, Type), Error> {
188 let node_text = self.get_text(ast_node);
189 let resolved_literal = match &ast_literal_kind {
190 swamp_script_ast::LiteralKind::Int => (
191 Literal::IntLiteral(Self::str_to_int(node_text).map_err(|int_conversion_err| {
192 self.create_err(ErrorKind::IntConversionError(int_conversion_err), ast_node)
193 })?),
194 Type::Int,
195 ),
196 swamp_script_ast::LiteralKind::Float => {
197 let float = Self::str_to_float(node_text).map_err(|float_conversion_err| {
198 self.create_err(
199 ErrorKind::FloatConversionError(float_conversion_err),
200 ast_node,
201 )
202 })?;
203 (Literal::FloatLiteral(Fp::from(float)), Type::Float)
204 }
205 swamp_script_ast::LiteralKind::String(processed_string) => (
206 Literal::StringLiteral(processed_string.to_string()),
207 Type::String,
208 ),
209 swamp_script_ast::LiteralKind::Bool => {
210 let bool_val = if node_text == "false" {
211 false
212 } else if node_text == "true" {
213 true
214 } else {
215 return Err(self.create_err(ErrorKind::BoolConversionError, ast_node));
216 };
217 (Literal::BoolLiteral(bool_val), Type::Bool)
218 }
219 swamp_script_ast::LiteralKind::EnumVariant(enum_literal) => {
220 let (enum_name, variant_name) = match enum_literal {
221 swamp_script_ast::EnumVariantLiteral::Simple(enum_name, variant_name) => {
222 (enum_name, variant_name)
223 }
224 swamp_script_ast::EnumVariantLiteral::Tuple(enum_name, variant_name, _) => {
225 (enum_name, variant_name)
226 }
227 swamp_script_ast::EnumVariantLiteral::Struct(enum_name, variant_name, _, _) => {
228 (enum_name, variant_name)
229 }
230 };
231
232 let (symbol_table, name) = self.get_symbol_table_and_name(enum_name)?;
233 if let Some(enum_type_ref) = symbol_table.get_enum(&name) {
234 let enum_type_clone = enum_type_ref.clone();
235 let enum_type = Type::Enum(enum_type_ref.clone());
236
237 let variant_ref = self.analyze_enum_variant_ref(enum_name, variant_name)?;
239
240 let resolved_data = match enum_literal {
241 swamp_script_ast::EnumVariantLiteral::Simple(_, _) => {
242 EnumLiteralData::Nothing
243 }
244 swamp_script_ast::EnumVariantLiteral::Tuple(
245 _node,
246 _variant,
247 ast_expressions,
248 ) => {
249 let EnumVariantType::Tuple(tuple_data) = &variant_ref else {
250 return Err(self.create_err(
251 ErrorKind::WrongEnumVariantContainer(variant_ref),
252 &ast_node,
253 ));
254 };
255
256 let resolved = self.analyze_tuple_type(
257 &enum_literal.node(),
258 &tuple_data.fields_in_order,
259 ast_expressions,
260 )?;
261 EnumLiteralData::Tuple(resolved)
262 }
263 swamp_script_ast::EnumVariantLiteral::Struct(
264 _qualified_type_identifier,
265 variant,
266 anonym_struct_field_and_expressions,
267 detected_rest,
268 ) => {
269 if let EnumVariantType::Struct(ref resolved_variant_struct_ref) =
270 variant_ref
271 {
272 if anonym_struct_field_and_expressions.len()
273 != resolved_variant_struct_ref
274 .anon_struct
275 .field_name_sorted_fields
276 .len()
277 {
278 return Err(self.create_err(
279 ErrorKind::WrongNumberOfArguments(
280 anonym_struct_field_and_expressions.len(),
281 resolved_variant_struct_ref
282 .anon_struct
283 .field_name_sorted_fields
284 .len(),
285 ),
286 &variant.0,
287 ));
288 }
289
290 let resolved = self.analyze_anon_struct_instantiation(
291 &variant.0.clone(),
292 &resolved_variant_struct_ref.anon_struct,
293 anonym_struct_field_and_expressions,
294 *detected_rest,
295 )?;
296
297 EnumLiteralData::Struct(resolved)
298 } else {
299 return Err(self.create_err(
300 ErrorKind::WrongEnumVariantContainer(variant_ref.clone()),
301 &variant.0,
302 ));
303 }
304 }
305 };
306
307 return Ok((
308 Literal::EnumVariantLiteral(enum_type_clone, variant_ref, resolved_data),
309 enum_type,
310 ));
311 }
312 return Err(self.create_err(ErrorKind::UnknownEnumType, ast_node));
313 }
314
315 swamp_script_ast::LiteralKind::Tuple(expressions) => {
316 let (tuple_type_ref, resolved_items) = self.analyze_tuple_literal(expressions)?;
317 (
318 Literal::TupleLiteral(tuple_type_ref.clone(), resolved_items),
319 Type::Tuple(tuple_type_ref),
320 )
321 }
322 swamp_script_ast::LiteralKind::None => {
323 if let Some(found_expected_type) = context.expected_type {
324 if let Type::Optional(_some_type) = found_expected_type {
325 return Ok((Literal::NoneLiteral, found_expected_type.clone()));
326 }
327 }
328 return Err(self.create_err(ErrorKind::NoneNeedsExpectedTypeHint, &ast_node));
329 }
330 &&swamp_script_ast::LiteralKind::Slice(_)
331 | &swamp_script_ast::LiteralKind::SlicePair(_) => todo!(),
332 };
333
334 Ok(resolved_literal)
335 }
336
337 fn analyze_tuple_literal(
338 &mut self,
339 items: &[swamp_script_ast::Expression],
340 ) -> Result<(Vec<Type>, Vec<Expression>), Error> {
341 let expressions = self.analyze_argument_expressions(None, items)?;
342 let mut tuple_types = Vec::new();
343 for expr in &expressions {
344 let item_type = expr.ty.clone();
345 tuple_types.push(item_type);
346 }
347
348 Ok((tuple_types, expressions))
349 }
350
351 fn analyze_tuple_type(
352 &mut self,
353 node: &swamp_script_ast::Node,
354 expected_types: &Vec<Type>,
355 ast_expressions: &Vec<swamp_script_ast::Expression>,
356 ) -> Result<Vec<Expression>, Error> {
357 if ast_expressions.len() != expected_types.len() {
358 return Err(self.create_err(ErrorKind::WrongNumberOfArguments(0, 0), node));
359 }
360
361 let mut expressions = Vec::new();
362 for (expected_type, expr) in expected_types.iter().zip(ast_expressions) {
363 let context = TypeContext::new_argument(expected_type);
364 let resolved_expr = self.analyze_expression(expr, &context)?;
365 expressions.push(resolved_expr);
366 }
367
368 Ok(expressions)
369 }
370
371 fn analyze_slice_pair_literal(
372 &mut self,
373 node: &swamp_script_ast::Node,
374 entries: &[(swamp_script_ast::Expression, swamp_script_ast::Expression)],
375 ) -> Result<(Vec<(Expression, Expression)>, Type, Type), Error> {
376 if entries.is_empty() {
377 return Ok((vec![], Type::Unit, Type::Unit));
378 }
379
380 let (first_key, first_value) = &entries[0];
382 let anything_context = TypeContext::new_anything_argument();
383 let resolved_first_key = self.analyze_expression(first_key, &anything_context)?;
384 let resolved_first_value = self.analyze_expression(first_value, &anything_context)?;
385 let key_type = resolved_first_key.ty.clone();
386 let value_type = resolved_first_value.ty.clone();
387
388 let key_context = TypeContext::new_argument(&key_type);
389 let value_context = TypeContext::new_argument(&value_type);
390
391 let mut resolved_entries = Vec::new();
393 resolved_entries.push((resolved_first_key, resolved_first_value));
394
395 for (key, value) in entries.iter().skip(1) {
396 let resolved_key = self.analyze_expression(key, &key_context)?;
397 let resolved_value = self.analyze_expression(value, &value_context)?;
398
399 if !resolved_key.ty.compatible_with(&key_type) {
400 return Err(self.create_err(
401 ErrorKind::MapKeyTypeMismatch {
402 expected: key_type,
403 found: resolved_key.ty,
404 },
405 node,
406 ));
407 }
408
409 if !resolved_value.ty.compatible_with(&value_type) {
410 return Err(self.create_err(
411 ErrorKind::MapValueTypeMismatch {
412 expected: value_type,
413 found: resolved_value.ty,
414 },
415 node,
416 ));
417 }
418
419 resolved_entries.push((resolved_key, resolved_value));
420 }
421
422 Ok((resolved_entries, key_type, value_type))
423 }
424
425 #[must_use]
426 pub fn create_err(&self, kind: ErrorKind, ast_node: &swamp_script_ast::Node) -> Error {
427 error!(?kind, "error created");
428 Error {
429 node: self.to_node(ast_node),
430 kind,
431 }
432 }
433
434 #[must_use]
435 pub fn create_err_resolved(&self, kind: ErrorKind, resolved_node: &Node) -> Error {
436 Error {
437 node: resolved_node.clone(),
438 kind,
439 }
440 }
441}