1pub mod access;
6mod attributes;
7pub mod call;
8pub mod constant;
9pub mod context;
10pub mod def;
11pub mod literal;
12pub mod operator;
13pub mod pattern;
14pub mod prelude;
15pub mod shared;
16mod structure;
17mod to_string;
18pub mod types;
19pub mod variable;
20
21use crate::call::MaybeBorrowMutRefExpression;
22use crate::context::TypeContext;
23use crate::shared::SharedState;
24use crate::to_string::create_expr_resolved;
25use seq_map::SeqMap;
26use source_map_cache::SourceMap;
27use source_map_node::{FileId, Node, Span};
28use std::mem::take;
29use std::num::{ParseFloatError, ParseIntError};
30use std::rc::Rc;
31use std::str::{FromStr, ParseBoolError};
32use swamp_ast::{GenericParameter, QualifiedTypeIdentifier};
33use swamp_modules::prelude::*;
34use swamp_modules::symtbl::SymbolTableRef;
35use swamp_semantic::prelude::*;
36use swamp_semantic::{
37 ArgumentExpression, BinaryOperatorKind, BlockScope, BlockScopeMode, FunctionScopeState,
38 GridType, InternalMainExpression, LocationAccess, LocationAccessKind, MapType,
39 MutableReferenceKind, NormalPattern, Postfix, PostfixKind, ScopeInfo, SingleLocationExpression,
40 SliceViewType, SparseType, TargetAssignmentLocation, TypeWithMut, VariableType, VecType,
41 WhenBinding,
42};
43use swamp_semantic::{StartOfChain, StartOfChainKind};
44use swamp_types::TypeKind;
45use swamp_types::prelude::*;
46use tracing::error;
47
48#[derive(Copy, Clone, Eq, PartialEq)]
49pub enum AssignmentMode {
50 OwnedValue,
51 CopyBlittable,
52 CopySharedPtr,
53}
54
55#[derive(Copy, Clone, Eq, PartialEq, Debug)]
56pub enum LocationSide {
57 Lhs,
58 Mutable,
59 Rhs,
60}
61
62#[derive(Debug)]
63pub enum StartOfChainBase {
64 FunctionReference(Function),
65 Variable(VariableRef),
66}
67#[derive(Debug)]
68pub struct Program {
69 pub state: ProgramState,
70 pub modules: Modules,
71 pub default_symbol_table: SymbolTable,
72}
73
74impl Default for Program {
75 fn default() -> Self {
76 Self::new(ProgramState::new(), Modules::new(), SymbolTable::new(&[]))
77 }
78}
79
80impl Program {
81 #[must_use]
82 pub const fn new(
83 state: ProgramState,
84 modules: Modules,
85 default_symbol_table: SymbolTable,
86 ) -> Self {
87 Self {
88 state,
89 modules,
90 default_symbol_table,
91 }
92 }
93}
94
95#[must_use]
96pub const fn convert_span(without: &swamp_ast::SpanWithoutFileId, file_id: FileId) -> Span {
97 Span {
98 file_id,
99 offset: without.offset,
100 length: without.length,
101 }
102}
103
104pub struct Analyzer<'a> {
105 pub shared: SharedState<'a>,
106 scope: ScopeInfo,
107 global: FunctionScopeState,
108 module_path: Vec<String>,
109}
110
111impl<'a> Analyzer<'a> {
112 pub fn new(
113 state: &'a mut ProgramState,
114 modules: &'a Modules,
115 core_symbol_table: SymbolTableRef,
116 source_map: &'a SourceMap,
117 module_path: &[String],
118 file_id: FileId,
119 ) -> Self {
120 let shared = SharedState {
121 state,
122 lookup_table: SymbolTable::new(&[]),
123 definition_table: SymbolTable::new(module_path),
124 modules,
125 core_symbol_table,
126 source_map,
127 file_id,
128 };
129 Self {
130 scope: ScopeInfo::default(),
131 global: FunctionScopeState::new(),
132 shared,
133 module_path: module_path.to_vec(),
134 }
135 }
136
137 fn start_function(&mut self) {
139 self.global.block_scope_stack = take(&mut self.scope.active_scope.block_scope_stack);
140 self.scope = ScopeInfo::default();
141 }
142
143 fn stop_function(&mut self) {
144 self.scope.active_scope.block_scope_stack = take(&mut self.global.block_scope_stack);
145 }
146
147 fn analyze_if_expression(
148 &mut self,
149 condition: &swamp_ast::Expression,
150 true_expression: &swamp_ast::Expression,
151 maybe_false_expression: Option<&swamp_ast::Expression>,
152 context: &TypeContext,
153 ) -> Expression {
154 let resolved_condition = self.analyze_bool_argument_expression(condition);
155
156 let branch_context = context;
157
158 let true_expr = self.analyze_expression(true_expression, branch_context);
159 let resolved_true = Box::new(true_expr);
160
161 let mut detected = context.expected_type.cloned();
162 if detected.is_none() {
163 detected = Some(resolved_true.ty.clone());
164 }
165
166 let else_statements = if let Some(false_expression) = maybe_false_expression {
168 let else_context =
169 branch_context.with_expected_type(detected.as_ref(), context.has_lvalue_target);
170 let else_expr = self.analyze_expression(false_expression, &else_context);
171 if detected.is_none() {
172 detected = Some(else_expr.ty.clone());
173 }
174
175 Some(Box::new(else_expr))
176 } else {
177 None
178 };
179
180 self.create_expr(
181 ExpressionKind::If(resolved_condition, resolved_true, else_statements),
182 detected.unwrap(),
183 &condition.node,
184 )
185 }
186
187 fn get_text(&self, ast_node: &swamp_ast::Node) -> &str {
188 let span = Span {
189 file_id: self.shared.file_id,
190 offset: ast_node.span.offset,
191 length: ast_node.span.length,
192 };
193 self.shared.source_map.get_span_source(
194 self.shared.file_id,
195 span.offset as usize,
196 span.length as usize,
197 )
198 }
199
200 fn get_text_resolved(&self, resolved_node: &Node) -> &str {
201 let span = Span {
202 file_id: self.shared.file_id,
203 offset: resolved_node.span.offset,
204 length: resolved_node.span.length,
205 };
206 self.shared.source_map.get_span_source(
207 self.shared.file_id,
208 span.offset as usize,
209 span.length as usize,
210 )
211 }
212
213 fn get_path(&self, ident: &swamp_ast::QualifiedTypeIdentifier) -> (Vec<String>, String) {
214 let path = ident
215 .module_path
216 .as_ref()
217 .map_or_else(Vec::new, |found_path| {
218 let mut v = Vec::new();
219 for p in &found_path.0 {
220 v.push(self.get_text(p).to_string());
221 }
222 v
223 });
224 (path, self.get_text(&ident.name.0).to_string())
225 }
226
227 fn analyze_return_type(&mut self, function: &swamp_ast::Function) -> TypeRef {
228 let ast_return_type = match function {
229 swamp_ast::Function::Internal(x) => &x.declaration.return_type,
230 swamp_ast::Function::External(_, x) => &x.return_type,
231 };
232
233 match ast_return_type {
234 None => self.shared.state.types.unit(),
235 Some(x) => self.analyze_type(x),
236 }
237 }
238
239 fn analyze_function_body_expression(
240 &mut self,
241 expression: &swamp_ast::Expression,
242 return_type: &TypeRef,
243 ) -> Expression {
244 let context = TypeContext::new_function(return_type);
245
246 self.analyze_expression(expression, &context)
247 }
248
249 fn analyze_maybe_type(&mut self, maybe_type: Option<&swamp_ast::Type>) -> TypeRef {
250 match maybe_type {
251 None => self.shared.state.types.unit(),
252 Some(ast_type) => self.analyze_type(ast_type),
253 }
254 }
255
256 fn analyze_for_pattern(
257 &mut self,
258 pattern: &swamp_ast::ForPattern,
259 key_type: Option<&TypeRef>,
260 value_type: &TypeRef,
261 ) -> ForPattern {
262 match pattern {
263 swamp_ast::ForPattern::Single(var) => {
264 let variable_ref = self.create_local_variable(
265 &var.identifier,
266 Option::from(&var.is_mut),
267 value_type,
268 false,
269 );
270 ForPattern::Single(variable_ref)
271 }
272 swamp_ast::ForPattern::Pair(first, second) => {
273 let found_key = key_type.unwrap();
274 let first_var_ref = self.create_local_variable(
275 &first.identifier,
276 Option::from(&first.is_mut),
277 found_key,
278 false,
279 );
280 let second_var_ref = self.create_local_variable(
281 &second.identifier,
282 Option::from(&second.is_mut),
283 value_type,
284 false,
285 );
286 ForPattern::Pair(first_var_ref, second_var_ref)
287 }
288 }
289 }
290 const MAX_PARAMETER_COUNT: usize = 6; fn analyze_parameters(
292 &mut self,
293 parameters: &Vec<swamp_ast::Parameter>,
294 ) -> Vec<TypeForParameter> {
295 let mut resolved_parameters = Vec::new();
296 if parameters.len() > Self::MAX_PARAMETER_COUNT {
297 self.add_err(
298 ErrorKind::TooManyParameters {
299 encountered: parameters.len(),
300 allowed: Self::MAX_PARAMETER_COUNT,
301 },
302 ¶meters[0].variable.name,
303 );
304 return vec![];
305 }
306 for parameter in parameters {
307 let param_type = self.analyze_type(¶meter.param_type);
308 if !param_type.allowed_as_parameter_type() {
309 self.add_err(
310 ErrorKind::ParameterTypeCanNotBeStorage(param_type),
311 ¶meter.variable.name,
312 );
313 continue;
314 }
315 resolved_parameters.push(TypeForParameter {
316 name: self.get_text(¶meter.variable.name).to_string(),
317 resolved_type: param_type,
318 is_mutable: parameter.variable.is_mutable.is_some(),
319 node: Some(ParameterNode {
320 is_mutable: self.to_node_option(Option::from(¶meter.variable.is_mutable)),
321 name: self.to_node(¶meter.variable.name),
322 }),
323 });
324 }
325 resolved_parameters
326 }
327
328 pub(crate) fn analyze_static_member_access(
329 &mut self,
330 named_type: &swamp_ast::QualifiedTypeIdentifier,
331 member_name_node: &swamp_ast::Node,
332 ) -> Option<Function> {
333 if let Some(found_function) = self.special_static_member(named_type, member_name_node) {
334 Some(found_function)
335 } else {
336 let some_type = self.analyze_named_type(named_type);
337
338 let member_name = self.get_text(member_name_node);
339 self.lookup_associated_function(&some_type, member_name)
340 }
341 }
342
343 pub fn analyze_local_function_access(
344 &mut self,
345 qualified_func_name: &swamp_ast::QualifiedIdentifier,
346 ) -> Option<Function> {
347 let path = self.get_module_path(qualified_func_name.module_path.as_ref());
348 let function_name = self.get_text(&qualified_func_name.name);
349
350 if let Some(found_table) = self.shared.get_symbol_table(&path) {
351 if let Some(found_func) = found_table.get_function(function_name) {
352 let (kind, signature) = match found_func {
353 FuncDef::Internal(internal_fn) => (
354 Function::Internal(internal_fn.clone()),
355 &internal_fn.signature,
356 ),
357 FuncDef::External(external_fn) => (
358 Function::External(external_fn.clone()),
359 &external_fn.signature,
360 ),
361 FuncDef::Intrinsic(intrinsic_fn) => (
363 Function::Intrinsic(intrinsic_fn.clone()),
364 &intrinsic_fn.signature,
365 ),
366 };
367
368 return Some(kind);
369 }
370 }
371
372 None
373 }
374
375 fn check_if_function_reference(
376 &mut self,
377 ast_expression: &swamp_ast::Expression,
378 ) -> Option<Function> {
379 match &ast_expression.kind {
380 swamp_ast::ExpressionKind::StaticMemberFunctionReference(
381 qualified_type_identifier,
382 node,
383 ) => self.analyze_static_member_access(qualified_type_identifier, node),
384 swamp_ast::ExpressionKind::IdentifierReference(qualified_identifier) => {
385 self.analyze_local_function_access(qualified_identifier)
386 }
387 _ => None,
388 }
389 }
390
391 pub fn analyze_start_chain_expression_get_mutability(
394 &mut self,
395 ast_expression: &swamp_ast::Expression,
396 ) -> Option<StartOfChainBase> {
397 self.check_if_function_reference(ast_expression)
398 .map_or_else(
399 || {
400 if let swamp_ast::ExpressionKind::IdentifierReference(
401 found_qualified_identifier,
402 ) = &ast_expression.kind
403 {
404 self.try_find_variable(&found_qualified_identifier.name)
405 .map(StartOfChainBase::Variable)
406 } else {
407 None
408 }
409 },
410 |found_func_def| Some(StartOfChainBase::FunctionReference(found_func_def)),
411 )
412 }
413
414 pub fn debug_expression(&self, expr: &swamp_ast::Expression, description: &str) {
415 self.debug_line(expr.node.span.offset as usize, description);
416 }
417
418 pub fn debug_line(&self, offset: usize, description: &str) {
419 let (line, col) = self
420 .shared
421 .source_map
422 .get_span_location_utf8(self.shared.file_id, offset);
423
424 let source_line = self
425 .shared
426 .source_map
427 .get_source_line(self.shared.file_id, line);
428
429 let source_path = self
430 .shared
431 .source_map
432 .fetch_relative_filename(self.shared.file_id);
433 let debug_line = format!("{source_path}:{line}:{col}> {}", source_line.unwrap());
434 }
437
438 pub fn analyze_main_expression(
441 &mut self,
442 ast_expression: &swamp_ast::Expression,
443 ) -> InternalMainExpression {
444 self.start_function();
445
446 let context = TypeContext::new_anything_argument(true); let analyzed_expr = self.analyze_expression(ast_expression, &context);
448 let main_expr = InternalMainExpression {
449 expression: analyzed_expr,
450 scopes: self.scope.total_scopes.clone(),
451 program_unique_id: self.shared.state.allocate_internal_function_id(),
452 };
453
454 self.stop_function();
455
456 main_expr
457 }
458
459 fn analyze_maybe_ref_expression(
460 &mut self,
461 ast_expr: &swamp_ast::Expression,
462 ) -> MaybeBorrowMutRefExpression {
463 if let swamp_ast::ExpressionKind::UnaryOp(found_unary, ast_inner_expression) =
464 &ast_expr.kind
465 {
466 if let swamp_ast::UnaryOperator::BorrowMutRef(node) = found_unary {
467 let resolved_node = self.to_node(node);
469 return MaybeBorrowMutRefExpression {
470 ast_expression: *ast_inner_expression.clone(),
471 has_borrow_mutable_reference: Some(resolved_node),
472 };
473 }
474 }
475
476 MaybeBorrowMutRefExpression {
477 ast_expression: ast_expr.clone(),
478 has_borrow_mutable_reference: None,
479 }
480 }
481
482 fn needs_storage_error(
484 &self,
485 expr: &Expression,
486 is_function_call: bool,
487 context: &TypeContext,
488 ast_node: &swamp_ast::Node,
489 ) -> bool {
490 let is_constant = matches!(expr.kind, ExpressionKind::ConstantAccess(_));
491 let is_variable = matches!(expr.kind, ExpressionKind::VariableAccess(_));
492
493 !context.has_lvalue_target
495 && expr.ty.collection_view_that_needs_explicit_storage()
496 && is_function_call
497 && !is_constant
498 && !is_variable
499 }
500
501 pub fn analyze_expression(
502 &mut self,
503 ast_expression: &swamp_ast::Expression,
504 context: &TypeContext,
505 ) -> Expression {
506 let expr = self.analyze_expression_internal(ast_expression, context);
509
510 if matches!(expr.kind, ExpressionKind::Error(_)) {
511 return expr;
512 }
513
514 let encountered_type = expr.ty.clone();
515
516 let expr = if let Some(found_expected_type) = context.expected_type {
518 let reduced_expected = found_expected_type;
519
520 let reduced_encountered_type = encountered_type;
521
522 if self
523 .shared
524 .state
525 .types
526 .compatible_with(reduced_expected, &reduced_encountered_type)
527 {
528 expr
529 } else {
530 self.types_did_not_match_try_late_coerce_expression(
531 expr,
532 reduced_expected,
533 &reduced_encountered_type,
534 &ast_expression.node,
535 )
536 }
537 } else {
538 expr
539 };
542
543 let is_function_call = Self::is_aggregate_function_call(ast_expression);
546
547 if self.needs_storage_error(&expr, is_function_call, context, &ast_expression.node) {
548 self.create_err(ErrorKind::NeedStorage, &ast_expression.node)
550 } else {
551 expr
552 }
553 }
554
555 #[allow(clippy::too_many_lines)]
558 pub fn analyze_expression_internal(
559 &mut self,
560 ast_expression: &swamp_ast::Expression,
561 context: &TypeContext,
562 ) -> Expression {
563 match &ast_expression.kind {
566 swamp_ast::ExpressionKind::PostfixChain(postfix_chain) => {
568 self.analyze_postfix_chain(postfix_chain, context)
569 }
570
571 swamp_ast::ExpressionKind::VariableDefinition(
572 variable,
573 maybe_annotation,
574 source_expression,
575 ) => self.analyze_create_variable(
576 variable,
577 Option::from(maybe_annotation),
578 source_expression,
579 ),
580
581 swamp_ast::ExpressionKind::VariableAssignment(variable, source_expression) => {
582 self.analyze_variable_assignment(variable, source_expression)
583 }
584
585 swamp_ast::ExpressionKind::DestructuringAssignment(variables, expression) => {
586 self.analyze_destructuring(&ast_expression.node, variables, expression)
587 }
588
589 swamp_ast::ExpressionKind::IdentifierReference(qualified_identifier) => {
590 self.analyze_identifier(qualified_identifier)
591 }
592
593 swamp_ast::ExpressionKind::VariableReference(variable) => {
594 self.analyze_variable_reference(&variable.name)
595 }
596
597 swamp_ast::ExpressionKind::ContextAccess => {
598 todo!("context access is not done yet")
599 }
600
601 swamp_ast::ExpressionKind::StaticMemberFunctionReference(
602 type_identifier,
603 member_name,
604 ) => {
605 let debug_name = self.get_text(member_name);
606 let type_name = self.get_text(&type_identifier.name.0);
607 panic!("can not have separate member func ref {type_name:?} {debug_name}")
608 }
609
610 swamp_ast::ExpressionKind::ConstantReference(constant_identifier) => {
611 self.analyze_constant_access(constant_identifier)
612 }
613
614 swamp_ast::ExpressionKind::Assignment(location, source) => {
615 self.analyze_assignment(location, source)
616 }
617
618 swamp_ast::ExpressionKind::CompoundAssignment(target, op, source) => {
619 self.analyze_assignment_compound(target, op, source)
620 }
621
622 swamp_ast::ExpressionKind::BinaryOp(resolved_a, operator, resolved_b) => {
624 let Some((resolved_op, result_type)) =
625 self.analyze_binary_op(resolved_a, operator, resolved_b)
626 else {
627 return self.create_err(ErrorKind::OperatorProblem, &operator.node);
628 };
629
630 self.create_expr(
631 ExpressionKind::BinaryOp(resolved_op),
632 result_type,
633 &ast_expression.node,
634 )
635 }
636
637 swamp_ast::ExpressionKind::UnaryOp(operator, expression) => {
638 if let swamp_ast::UnaryOperator::BorrowMutRef(_node) = operator {
639 let inner_expr =
640 self.analyze_to_location(expression, context, LocationSide::Rhs);
641 let ty = inner_expr.ty.clone();
642 self.create_expr(
643 ExpressionKind::BorrowMutRef(Box::from(inner_expr)),
644 ty,
645 &ast_expression.node,
646 )
647 } else {
648 let Some((resolved_op, result_type)) =
649 self.analyze_unary_op(operator, expression)
650 else {
651 return self.create_err(ErrorKind::OperatorProblem, &ast_expression.node);
652 };
653 self.create_expr(
654 ExpressionKind::UnaryOp(resolved_op),
655 result_type,
656 &ast_expression.node,
657 )
658 }
659 }
660
661 swamp_ast::ExpressionKind::Block(expressions) => {
662 let (block, resulting_type) =
663 self.analyze_block(&ast_expression.node, context, expressions);
664 self.create_expr(
665 ExpressionKind::Block(block),
666 resulting_type,
667 &ast_expression.node,
668 )
669 }
670
671 swamp_ast::ExpressionKind::With(variable_bindings, expression) => {
672 self.analyze_with_expr(context, variable_bindings, expression)
673 }
674
675 swamp_ast::ExpressionKind::When(variable_bindings, true_expr, else_expr) => {
676 self.analyze_when_expr(context, variable_bindings, true_expr, else_expr.as_deref())
677 }
678
679 swamp_ast::ExpressionKind::InterpolatedString(string_parts) => {
680 self.analyze_interpolated_string_lowering(&ast_expression.node, string_parts)
681 }
682
683 swamp_ast::ExpressionKind::NamedStructLiteral(struct_identifier, fields, has_rest) => {
685 self.analyze_named_struct_literal(struct_identifier, fields, *has_rest)
686 }
687
688 swamp_ast::ExpressionKind::AnonymousStructLiteral(fields, rest_was_specified) => self
689 .analyze_anonymous_struct_literal(
690 &ast_expression.node,
691 fields,
692 *rest_was_specified,
693 context,
694 ),
695
696 swamp_ast::ExpressionKind::ContextAccess => {
697 todo!("lone dot not implemented yet")
698 }
699
700 swamp_ast::ExpressionKind::Range(min_value, max_value, range_mode) => {
701 self.analyze_range(min_value, max_value, range_mode, &ast_expression.node)
702 }
703
704 swamp_ast::ExpressionKind::ForLoop(pattern, iterable_expression, statements) => {
705 if pattern.is_key_variable_mut() {
706 return self.create_err(
707 ErrorKind::KeyVariableNotAllowedToBeMutable,
708 &ast_expression.node,
709 );
710 }
711 let resolved_iterator =
712 self.analyze_iterable(pattern.is_value_mut(), &iterable_expression.expression);
713
714 self.push_block_scope("for_loop");
715 let pattern = self.analyze_for_pattern(
716 pattern,
717 resolved_iterator.key_type.as_ref(),
718 &resolved_iterator.value_type,
719 );
720 let resolved_statements = self.analyze_expression(statements, context);
721 self.pop_block_scope("for_loop");
722 let resolved_type = resolved_statements.ty.clone();
723 self.create_expr(
724 ExpressionKind::ForLoop(
725 pattern,
726 resolved_iterator,
727 Box::from(resolved_statements),
728 ),
729 resolved_type,
730 &ast_expression.node,
731 )
732 }
733
734 swamp_ast::ExpressionKind::WhileLoop(expression, statements) => {
735 let condition = self.analyze_bool_argument_expression(expression);
736 let resolved_statements = self.analyze_expression(statements, context);
738 let resolved_type = resolved_statements.ty.clone();
739 self.create_expr(
742 ExpressionKind::WhileLoop(condition, Box::from(resolved_statements)),
743 resolved_type,
744 &ast_expression.node,
745 )
746 }
747
748 swamp_ast::ExpressionKind::If(expression, true_expression, maybe_false_expression) => {
749 self.analyze_if_expression(
750 expression,
751 true_expression,
752 maybe_false_expression.as_deref(),
753 context,
754 )
755 }
756
757 swamp_ast::ExpressionKind::Match(expression, arms) => {
758 let (match_expr, return_type) = self.analyze_match(expression, context, arms);
759 self.create_expr(
760 ExpressionKind::Match(match_expr),
761 return_type,
762 &ast_expression.node,
763 )
764 }
765 swamp_ast::ExpressionKind::Guard(guard_expressions) => {
766 self.analyze_guard(&ast_expression.node, context, guard_expressions)
767 }
768
769 swamp_ast::ExpressionKind::Lambda(variables, expression) => {
770 self.analyze_lambda(&ast_expression.node, variables, expression, context)
771 }
772 swamp_ast::ExpressionKind::Error => {
773 self.create_err(ErrorKind::UnexpectedType, &ast_expression.node)
774 }
775 swamp_ast::ExpressionKind::Literal(literal) => {
776 self.analyze_complex_literal_to_expression(ast_expression, literal, context)
777 } }
779 }
780
781 fn get_struct_type(
782 &mut self,
783 qualified_type_identifier: &swamp_ast::QualifiedTypeIdentifier,
784 ) -> NamedStructType {
785 let maybe_struct_type = self.analyze_named_type(qualified_type_identifier);
786 if let TypeKind::NamedStruct(struct_type) = &*maybe_struct_type.kind {
787 struct_type.clone()
788 } else {
789 self.add_err(
790 ErrorKind::UnknownStructTypeReference,
792 &qualified_type_identifier.name.0,
793 );
794
795 NamedStructType {
796 name: Default::default(),
797 module_path: vec![],
798 assigned_name: String::new(),
799 anon_struct_type: self.types().unit(),
800 instantiated_type_parameters: vec![],
801 }
802 }
803 }
804
805 pub(crate) fn analyze_named_type(
806 &mut self,
807 type_name_to_find: &swamp_ast::QualifiedTypeIdentifier,
808 ) -> TypeRef {
809 let (path, name) = self.get_path(type_name_to_find);
810 let mut analyzed_type_parameters = Vec::new();
811
812 if let Some(found) =
813 self.analyze_special_named_type(&path, &name, &type_name_to_find.generic_params)
814 {
815 return found;
816 }
817
818 for analyzed_type in &type_name_to_find.generic_params {
819 let ty = self.analyze_type(analyzed_type.get_type());
820
821 analyzed_type_parameters.push(ty);
822 }
823
824 let symbol = {
825 if let Some(symbol_table) = self.shared.get_symbol_table(&path) {
826 if let Some(x) = symbol_table.get_symbol(&name) {
827 x
828 } else {
829 self.add_err(ErrorKind::UnknownSymbol, &type_name_to_find.name.0);
830 return self.types().unit();
831 }
832 } else {
833 self.add_err(ErrorKind::UnexpectedType, &type_name_to_find.name.0);
834 return self.types().unit();
835 }
836 };
837
838 if analyzed_type_parameters.is_empty() {
839 match &symbol {
840 Symbol::Type(base_type) => base_type.clone(),
841 Symbol::Alias(alias_type) => alias_type.ty.clone(),
842 _ => {
843 self.add_err(ErrorKind::UnexpectedType, &type_name_to_find.name.0);
844 self.types().unit()
845 }
846 }
847 } else {
848 panic!("unknown type")
849 }
850 }
851
852 fn create_default_value_for_type(
853 &mut self,
854 node: &swamp_ast::Node,
855 field_type: &TypeRef,
856 ) -> Option<Expression> {
857 let kind = match &*field_type.kind {
858 TypeKind::Tuple(tuple_type_ref) => {
859 let mut expressions = Vec::new();
860 for resolved_type in tuple_type_ref {
861 let expr = self.create_default_value_for_type(node, resolved_type)?;
862 expressions.push(expr);
863 }
864 ExpressionKind::TupleLiteral(expressions)
865 }
866
867 TypeKind::NamedStruct(_struct_ref) => {
868 if self
870 .shared
871 .state
872 .associated_impls
873 .get_member_function(field_type, "default")
874 .is_some()
875 {
876 self.create_default_static_call(node, field_type)
877 } else {
878 return None;
880 }
881 }
882
883 _ => {
884 return None;
886 }
887 };
888
889 Some(self.create_expr(kind, field_type.clone(), node))
890 }
891
892 fn create_static_member_call(
893 &mut self,
894 function_name: &str,
895 arguments: &[ArgumentExpression],
896 node: &swamp_ast::Node,
897 ty: &TypeRef,
898 ) -> ExpressionKind {
899 self.lookup_associated_function(ty, function_name)
900 .map_or_else(
901 || {
902 self.create_err(
903 ErrorKind::NoAssociatedFunction(ty.clone(), function_name.to_string()),
904 node,
905 )
906 .kind
907 },
908 |function| {
909 let Function::Internal(internal_function) = &function else {
910 panic!("only allowed for internal functions");
911 };
912
913 ExpressionKind::InternalCall(internal_function.clone(), arguments.to_vec())
914 },
915 )
916 }
917
918 fn create_static_member_intrinsic_call(
919 &mut self,
920 function_name: &str,
921 arguments: &[ArgumentExpression],
922 node: &swamp_ast::Node,
923 ty: &TypeRef,
924 ) -> ExpressionKind {
925 if let Some(function) = self.lookup_associated_function(ty, function_name) {
927 let Function::Internal(internal_function) = &function else {
928 panic!("only allowed for internal functions");
929 };
930
931 if let Some((intrinsic_fn, _)) =
932 Self::extract_single_intrinsic_call(&internal_function.body)
933 {
934 ExpressionKind::IntrinsicCallEx(intrinsic_fn, arguments.to_vec())
935 } else {
936 self.create_err(
937 ErrorKind::NoAssociatedFunction(ty.clone(), function_name.to_string()),
938 node,
939 )
940 .kind
941 }
942 } else {
943 self.create_err(
944 ErrorKind::NoAssociatedFunction(ty.clone(), function_name.to_string()),
945 node,
946 )
947 .kind
948 }
949 }
950
951 fn create_default_static_call(
952 &mut self,
953 node: &swamp_ast::Node,
954 ty: &TypeRef,
955 ) -> ExpressionKind {
956 self.create_static_member_call("default", &[], node, ty)
957 }
958
959 fn add_postfix(
960 &mut self,
961 vec: &mut Vec<Postfix>,
962 kind: PostfixKind,
963 ty: TypeRef,
964 node: &swamp_ast::Node,
965 ) {
966 let resolved_node = self.to_node(node);
967 let postfix = Postfix {
968 node: resolved_node,
969 ty,
970 kind,
971 };
972
973 vec.push(postfix);
974 }
975
976 pub fn analyze_struct_field(
981 &mut self,
982 field_name: &swamp_ast::Node,
983 tv: &TypeRef,
984 ) -> (AnonymousStructType, usize, TypeRef) {
985 let field_name_str = self.get_text(field_name).to_string();
986
987 let anon_struct_ref = match &*tv.kind {
988 TypeKind::NamedStruct(struct_type) => struct_type.anon_struct_type.clone(),
989 TypeKind::AnonymousStruct(anon_struct) => {
990 self.shared
992 .state
993 .types
994 .anonymous_struct(anon_struct.clone())
995 }
996 TypeKind::Range(range_struct_ref) => {
997 if let TypeKind::NamedStruct(named_struct) = &*range_struct_ref.kind {
999 named_struct.anon_struct_type.clone()
1000 } else {
1001 self.add_err(ErrorKind::UnknownStructField, field_name);
1002 return (
1004 AnonymousStructType::new(SeqMap::new()),
1005 0,
1006 self.shared.state.types.unit(),
1007 );
1008 }
1009 }
1010 _ => {
1011 self.add_err(ErrorKind::UnknownStructField, field_name);
1012 return (
1014 AnonymousStructType::new(SeqMap::new()),
1015 0,
1016 self.shared.state.types.unit(),
1017 );
1018 }
1019 };
1020
1021 if let TypeKind::AnonymousStruct(anon_struct) = &*anon_struct_ref.kind {
1023 if let Some(found_field) = anon_struct.field_name_sorted_fields.get(&field_name_str) {
1024 let index = anon_struct
1025 .field_name_sorted_fields
1026 .get_index(&field_name_str)
1027 .expect("checked earlier");
1028
1029 return (anon_struct.clone(), index, found_field.field_type.clone());
1030 }
1031 }
1032
1033 self.add_err(ErrorKind::UnknownStructField, field_name);
1034 (
1036 AnonymousStructType::new(SeqMap::new()),
1037 0,
1038 self.shared.state.types.unit(),
1039 )
1040 }
1041
1042 pub fn analyze_static_call(
1043 &mut self,
1044 ast_node: &swamp_ast::Node,
1045 maybe_associated_to_type: Option<TypeRef>,
1046 func_def: Function,
1047 maybe_generic_arguments: &Option<Vec<swamp_ast::GenericParameter>>,
1048 arguments: &[swamp_ast::Expression],
1049 context: &TypeContext,
1050 ) -> Expression {
1051 let signature = func_def.signature().clone();
1052
1053 let analyzed_arguments =
1054 self.analyze_and_verify_parameters(ast_node, &signature.parameters, arguments);
1055
1056 let expr_kind = match &func_def {
1057 Function::Internal(internal) => {
1058 ExpressionKind::InternalCall(internal.clone(), analyzed_arguments)
1059 }
1060 Function::External(host) => ExpressionKind::HostCall(host.clone(), analyzed_arguments),
1061 Function::Intrinsic(intrinsic) => {
1062 ExpressionKind::IntrinsicCallEx(intrinsic.intrinsic.clone(), analyzed_arguments)
1063 }
1064 };
1065
1066 let expr = self.create_expr(expr_kind, signature.return_type.clone(), ast_node);
1067
1068 if self.needs_storage_error(&expr, true, context, ast_node) {
1070 return self.create_err(ErrorKind::NeedStorage, ast_node);
1071 }
1072
1073 expr
1074 }
1075
1076 #[allow(clippy::too_many_lines)]
1077 fn analyze_postfix_chain(
1078 &mut self,
1079 chain: &swamp_ast::PostfixChain,
1080 context: &TypeContext,
1081 ) -> Expression {
1082 let maybe_start_of_chain_base =
1083 self.analyze_start_chain_expression_get_mutability(&chain.base);
1084
1085 let mut start_index = 0;
1086
1087 let start_of_chain_kind = if let Some(start_of_chain_base) = maybe_start_of_chain_base {
1088 match start_of_chain_base {
1090 StartOfChainBase::FunctionReference(func_def) => {
1091 if let swamp_ast::Postfix::FunctionCall(
1094 ast_node,
1095 maybe_generic_arguments,
1096 arguments,
1097 ) = &chain.postfixes[0]
1098 {
1099 start_index = 1;
1100 let call_expr = self.analyze_static_call(
1101 ast_node,
1102 None,
1103 func_def,
1104 maybe_generic_arguments,
1105 arguments,
1106 context,
1107 );
1108 if chain.postfixes.len() == 1 {
1109 return call_expr;
1110 }
1111 StartOfChainKind::Expression(Box::from(call_expr))
1112 } else {
1113 panic!("must be a normal function call")
1114 }
1115 }
1116 StartOfChainBase::Variable(var) => StartOfChainKind::Variable(var),
1117 }
1118 } else {
1119 let ctx = TypeContext::new_anything_argument(true); StartOfChainKind::Expression(Box::from(self.analyze_expression(&chain.base, &ctx)))
1121 };
1122
1123 let start_of_chain_node = self.to_node(&chain.base.node);
1124
1125 let start_of_chain = StartOfChain {
1126 kind: start_of_chain_kind.clone(),
1127 node: start_of_chain_node,
1128 };
1129
1130 let mut tv = TypeWithMut {
1131 resolved_type: start_of_chain_kind.ty(),
1132 is_mutable: start_of_chain_kind.is_mutable(),
1133 };
1134
1135 let mut uncertain = false;
1136
1137 let mut suffixes = Vec::new();
1138
1139 for (index, item) in chain.postfixes[start_index..].iter().enumerate() {
1140 let is_last = index == chain.postfixes[start_index..].len() - 1;
1142
1143 match item {
1144 swamp_ast::Postfix::FieldAccess(field_name) => {
1151 let (struct_type_ref, index, return_type) =
1152 self.analyze_struct_field(&field_name.clone(), &tv.resolved_type);
1153 let struct_type_type_ref = self
1154 .shared
1155 .state
1156 .types
1157 .anonymous_struct(struct_type_ref.clone());
1158 self.add_postfix(
1159 &mut suffixes,
1160 PostfixKind::StructField(struct_type_type_ref, index),
1161 return_type.clone(),
1162 field_name,
1163 );
1164
1165 tv.resolved_type = return_type.clone();
1166 }
1168
1169 swamp_ast::Postfix::SubscriptTuple(col_expr, row_expr) => {
1170 let collection_type = tv.resolved_type.clone();
1171 match &*collection_type.kind {
1172 TypeKind::GridStorage(element_type, x, _) => {
1173 let int_type = self.shared.state.types.int();
1174 let unsigned_int_x_context =
1175 TypeContext::new_argument(&int_type, false);
1176 let unsigned_int_x_expression =
1177 self.analyze_expression(col_expr, &unsigned_int_x_context);
1178
1179 let unsigned_int_y_context =
1180 TypeContext::new_argument(&int_type, false);
1181 let unsigned_int_y_expression =
1182 self.analyze_expression(row_expr, &unsigned_int_y_context);
1183
1184 let vec_type = GridType {
1185 element: element_type.clone(),
1186 };
1187
1188 self.add_postfix(
1189 &mut suffixes,
1190 PostfixKind::GridSubscript(
1191 vec_type,
1192 unsigned_int_x_expression,
1193 unsigned_int_y_expression,
1194 ),
1195 element_type.clone(),
1196 &col_expr.node,
1197 );
1198
1199 tv.resolved_type = element_type.clone();
1201 }
1202 _ => panic!("not a subscript tuple"),
1203 }
1204 }
1205
1206 swamp_ast::Postfix::Subscript(lookup_expr) => {
1207 let collection_type = tv.resolved_type.clone();
1208 match &*collection_type.kind {
1209 TypeKind::FixedCapacityAndLengthArray(element_type_in_slice, _) => {
1210 let int_type = self.shared.state.types.int();
1211 let unsigned_int_context = TypeContext::new_argument(&int_type, false);
1212 let unsigned_int_expression =
1213 self.analyze_expression(lookup_expr, &unsigned_int_context);
1214
1215 let slice_type = SliceViewType {
1216 element: element_type_in_slice.clone(),
1217 };
1218
1219 self.add_postfix(
1220 &mut suffixes,
1221 PostfixKind::SliceViewSubscript(
1222 slice_type,
1223 unsigned_int_expression,
1224 ),
1225 collection_type.clone(),
1226 &lookup_expr.node,
1227 );
1228
1229 tv.resolved_type = element_type_in_slice.clone();
1231 }
1232 TypeKind::QueueStorage(element_type, _)
1233 | TypeKind::StackStorage(element_type, _)
1234 | TypeKind::StackView(element_type)
1235 | TypeKind::VecStorage(element_type, _)
1236 | TypeKind::StringStorage(element_type, _, _)
1237 | TypeKind::String(element_type, _)
1238 | TypeKind::DynamicLengthVecView(element_type)
1239 | TypeKind::SliceView(element_type) => {
1240 let int_type = self.shared.state.types.int();
1241 let unsigned_int_context = TypeContext::new_argument(&int_type, false);
1242 let unsigned_int_expression =
1243 self.analyze_expression(lookup_expr, &unsigned_int_context);
1244
1245 let vec_type = VecType {
1246 element: element_type.clone(),
1247 };
1248
1249 self.add_postfix(
1250 &mut suffixes,
1251 PostfixKind::VecSubscript(vec_type, unsigned_int_expression),
1252 element_type.clone(),
1253 &lookup_expr.node,
1254 );
1255
1256 tv.resolved_type = element_type.clone();
1258 }
1259 TypeKind::SparseStorage(element_type, _)
1260 | TypeKind::SparseView(element_type) => {
1261 let int_type = self.shared.state.types.int();
1262 let unsigned_int_context = TypeContext::new_argument(&int_type, false);
1263 let unsigned_int_expression =
1264 self.analyze_expression(lookup_expr, &unsigned_int_context);
1265
1266 let vec_type = SparseType {
1267 element: element_type.clone(),
1268 };
1269
1270 self.add_postfix(
1271 &mut suffixes,
1272 PostfixKind::SparseSubscript(vec_type, unsigned_int_expression),
1273 element_type.clone(),
1274 &lookup_expr.node,
1275 );
1276
1277 tv.resolved_type = element_type.clone();
1279 }
1280 TypeKind::MapStorage(key_type, value_type, _)
1281 | TypeKind::DynamicLengthMapView(key_type, value_type) => {
1282 let key_context = TypeContext::new_argument(key_type, false);
1283 let key_expression = self.analyze_expression(lookup_expr, &key_context);
1284
1285 let map_type = MapType {
1286 key: key_type.clone(),
1287 value: value_type.clone(),
1288 };
1289
1290 self.add_postfix(
1291 &mut suffixes,
1292 PostfixKind::MapSubscript(map_type, key_expression),
1293 value_type.clone(),
1294 &lookup_expr.node,
1295 );
1296
1297 tv.resolved_type = value_type.clone();
1299 }
1300 _ => {
1301 eprintln!("xwhat is this: {collection_type:?}");
1302 return self
1303 .create_err(ErrorKind::MissingSubscriptMember, &lookup_expr.node);
1304 }
1305 }
1306 }
1307
1308 swamp_ast::Postfix::MemberCall(member_name, generic_arguments, ast_arguments) => {
1309 let member_name_str = self.get_text(member_name).to_string();
1310 let underlying_type = tv.resolved_type;
1311
1312 let (kind, return_type) = self.analyze_member_call(
1313 &underlying_type,
1314 &member_name_str,
1315 generic_arguments.clone(),
1316 ast_arguments,
1317 tv.is_mutable,
1318 member_name,
1319 );
1320
1321 self.add_postfix(&mut suffixes, kind, return_type.clone(), member_name);
1322 tv.resolved_type = return_type.clone();
1323 tv.is_mutable = false;
1324 }
1325 swamp_ast::Postfix::FunctionCall(node, _generic_arguments, arguments) => {
1326 panic!("can only have function call at the start of a postfix chain")
1327 }
1328
1329 swamp_ast::Postfix::NoneCoalescingOperator(default_expr) => {
1330 let unwrapped_type = if let TypeKind::Optional(unwrapped_type) =
1331 &*tv.resolved_type.kind
1332 {
1333 unwrapped_type
1334 } else if uncertain {
1335 &tv.resolved_type
1336 } else {
1337 return self.create_err(ErrorKind::CanNotNoneCoalesce, &default_expr.node);
1338 };
1339
1340 let unwrapped_type_context = TypeContext::new_argument(unwrapped_type, false);
1341 let resolved_default_expr =
1342 self.analyze_expression(default_expr, &unwrapped_type_context);
1343 self.add_postfix(
1344 &mut suffixes,
1345 PostfixKind::NoneCoalescingOperator(resolved_default_expr),
1346 (*unwrapped_type).clone(),
1347 &default_expr.node,
1348 );
1349 tv.resolved_type = (*unwrapped_type).clone();
1350 uncertain = false; }
1352
1353 swamp_ast::Postfix::OptionalChainingOperator(option_node) => {
1354 if is_last {
1355 return self.create_err(
1356 ErrorKind::OptionalChainingOperatorCanNotBePartOfChain,
1357 option_node,
1358 );
1359 }
1360
1361 if let TypeKind::Optional(unwrapped_type) = &*tv.resolved_type.kind {
1362 uncertain = true;
1363 self.add_postfix(
1364 &mut suffixes,
1365 PostfixKind::OptionalChainingOperator,
1366 (*unwrapped_type).clone(),
1367 option_node,
1368 );
1369 tv.resolved_type = (*unwrapped_type).clone();
1370 } else {
1371 return self.create_err(ErrorKind::ExpectedOptional, option_node);
1372 }
1373 }
1374 }
1375 }
1376
1377 if uncertain {
1378 if let TypeKind::Optional(_) = &*tv.resolved_type.kind {
1379 } else {
1380 tv.resolved_type = self.shared.state.types.optional(&tv.resolved_type.clone());
1381 }
1382 }
1383
1384 self.create_expr(
1385 ExpressionKind::PostfixChain(start_of_chain, suffixes),
1386 tv.resolved_type,
1387 &chain.base.node,
1388 )
1389 }
1390
1391 fn analyze_bool_argument_expression(
1392 &mut self,
1393 expression: &swamp_ast::Expression,
1394 ) -> BooleanExpression {
1395 let bool_type = self.shared.state.types.bool();
1396 let bool_context = TypeContext::new_argument(&bool_type, false);
1397 let resolved_expression = self.analyze_expression(expression, &bool_context);
1398 let expr_type = resolved_expression.ty.clone();
1399
1400 let bool_expression = match &*expr_type.kind {
1401 TypeKind::Bool => resolved_expression,
1402 TypeKind::Optional(_) => {
1403 let bool = self.types().bool();
1404 self.create_expr(
1405 ExpressionKind::CoerceOptionToBool(Box::new(resolved_expression)),
1406 bool,
1407 &expression.node,
1408 )
1409 }
1410 _ => self.create_err(ErrorKind::ExpectedBooleanExpression, &expression.node),
1411 };
1412
1413 BooleanExpression {
1414 expression: Box::from(bool_expression),
1415 }
1416 }
1417
1418 fn is_aggregate_function_call(expression: &swamp_ast::Expression) -> bool {
1420 match &expression.kind {
1421 swamp_ast::ExpressionKind::PostfixChain(chain) => {
1422 if chain.postfixes.is_empty() {
1423 return false;
1424 }
1425
1426 for postfix in &chain.postfixes {
1427 if let swamp_ast::Postfix::FunctionCall(_, _, _) = postfix {
1428 return true;
1429 }
1430 }
1431 false
1432 }
1433 _ => false, }
1435 }
1436
1437 fn analyze_iterable(
1438 &mut self,
1439 mut_requested_for_value_variable: Option<swamp_ast::Node>,
1440 expression: &swamp_ast::Expression,
1441 ) -> Iterable {
1442 let has_lvalue_target = !Self::is_aggregate_function_call(expression);
1445 let any_context = TypeContext::new_anything_argument(has_lvalue_target);
1446
1447 let resolved_expression = self.analyze_expression(expression, &any_context);
1448
1449 let resolved_type = &resolved_expression.ty.clone();
1450 let int_type = Some(self.types().int());
1451 let (key_type, value_type): (Option<TypeRef>, TypeRef) = match &*resolved_type.kind {
1452 TypeKind::String(_, char) => (int_type, char.clone()),
1453 TypeKind::SliceView(element_type) => (int_type, element_type.clone()),
1454 TypeKind::VecStorage(element_type, _fixed_size) => (int_type, element_type.clone()),
1455 TypeKind::SparseStorage(element_type, _fixed_size) => (int_type, element_type.clone()),
1456 TypeKind::StackStorage(element_type, _fixed_size) => (int_type, element_type.clone()),
1457 TypeKind::StackView(element_type) => (int_type, element_type.clone()),
1458 TypeKind::QueueStorage(element_type, _fixed_size) => (int_type, element_type.clone()),
1459 TypeKind::QueueView(element_type) => (int_type, element_type.clone()),
1460 TypeKind::DynamicLengthVecView(element_type) => (int_type, element_type.clone()),
1461 TypeKind::SparseView(element_type) => (int_type, element_type.clone()),
1462 TypeKind::DynamicLengthMapView(key_type, value_type)
1463 | TypeKind::MapStorage(key_type, value_type, _) => {
1464 (Some(key_type.clone()), value_type.clone())
1465 }
1466 TypeKind::Range(_) => (None, self.types().int()),
1467 _ => {
1468 error!(?resolved_type, "not an iterator");
1469 return Iterable {
1470 key_type: None,
1471 value_type: self.shared.state.types.unit(),
1472 resolved_expression: Box::new(
1473 self.create_err(ErrorKind::NotAnIterator, &expression.node),
1474 ),
1475 };
1476 }
1477 };
1478
1479 if mut_requested_for_value_variable.is_some() {
1480 let _resulting_location =
1482 self.analyze_to_location(expression, &any_context, LocationSide::Mutable);
1483 }
1486
1487 Iterable {
1488 key_type,
1489 value_type,
1490 resolved_expression: Box::new(resolved_expression),
1491 }
1492 }
1493
1494 fn analyze_argument_expressions(
1495 &mut self,
1496 expected_type: Option<&TypeRef>,
1497 context: &TypeContext,
1498 ast_expressions: &[swamp_ast::Expression],
1499 ) -> Vec<Expression> {
1500 let mut resolved_expressions = Vec::new();
1501 let argument_expressions_context = TypeContext::new_unsure_argument(expected_type, false);
1503
1504 for expression in ast_expressions {
1505 resolved_expressions
1506 .push(self.analyze_expression(expression, &argument_expressions_context));
1507 }
1508 resolved_expressions
1509 }
1510
1511 fn analyze_block(
1512 &mut self,
1513 _node: &swamp_ast::Node,
1514 context: &TypeContext,
1515 ast_expressions: &[swamp_ast::Expression],
1516 ) -> (Vec<Expression>, TypeRef) {
1517 if ast_expressions.is_empty() {
1518 return (vec![], self.shared.state.types.unit());
1519 }
1520
1521 self.push_block_scope("block");
1522
1523 let mut resolved_expressions = Vec::with_capacity(ast_expressions.len());
1524
1525 for expression in &ast_expressions[..ast_expressions.len() - 1] {
1526 let unit_type = self.shared.state.types.unit();
1527 let stmt_context =
1528 context.with_expected_type(Some(&unit_type), context.has_lvalue_target);
1529 let expr = self.analyze_expression(expression, &stmt_context);
1530
1531 resolved_expressions.push(expr);
1532 }
1533
1534 let last_expr =
1536 self.analyze_expression(&ast_expressions[ast_expressions.len() - 1], context);
1537 let last_type = last_expr.ty.clone();
1538 resolved_expressions.push(last_expr);
1539
1540 self.pop_block_scope("block");
1541
1542 (resolved_expressions, last_type)
1543 }
1544
1545 fn analyze_interpolated_string_lowering(
1546 &mut self,
1547 node: &swamp_ast::Node,
1548 string_parts: &[swamp_ast::StringPart],
1549 ) -> Expression {
1550 let mut last_expression: Option<Expression> = None;
1551 for part in string_parts {
1552 let created_expression = match part {
1553 swamp_ast::StringPart::Literal(string_node, processed_string) => {
1554 let string_literal =
1555 ExpressionKind::StringLiteral(processed_string.to_string());
1556 let basic_literal = string_literal;
1557 let string_type = self.shared.state.types.string();
1558 self.create_expr(basic_literal, string_type, string_node)
1559 }
1560 swamp_ast::StringPart::Interpolation(expression, format_specifier) => {
1561 let any_context = TypeContext::new_anything_argument(false); let expr = self.analyze_expression(expression, &any_context);
1564
1565 let tk = (*expr.ty.kind).clone();
1566
1567 let maybe_to_string = self
1568 .shared
1569 .state
1570 .associated_impls
1571 .get_internal_member_function(&expr.ty, "to_string");
1572
1573 if matches!(tk, TypeKind::String { .. }) {
1574 expr
1575 } else {
1576 let underlying = expr.ty.clone();
1577
1578 if self.needs_storage_error(&expr, true, &any_context, &expression.node) {
1580 return self.create_err(ErrorKind::NeedStorage, &expression.node);
1581 }
1582
1583 let call_expr_kind = if maybe_to_string.is_none() {
1584 let string_type = self.types().string();
1585
1586 ExpressionKind::StringLiteral(format!("missing {string_type}"))
1587 } else {
1596 let expr_as_param = ArgumentExpression::Expression(expr);
1597 self.create_static_member_call(
1598 "to_string",
1599 &[expr_as_param.clone()],
1600 &expression.node,
1601 &underlying,
1602 )
1603 };
1604
1605 let string_type = self.shared.state.types.string();
1613 self.create_expr(call_expr_kind, string_type, &expression.node)
1614 }
1615 }
1616 };
1617
1618 let x_last_expr = if let Some(last_expr) = last_expression.clone() {
1619 let op_kind = BinaryOperatorKind::Add;
1620 let node = created_expression.node.clone();
1621 let op = BinaryOperator {
1622 left: Box::new(last_expr),
1623 right: Box::new(created_expression),
1624 kind: op_kind,
1625 node: node.clone(),
1626 };
1627
1628 let string_type = self.shared.state.types.string();
1629 create_expr_resolved(ExpressionKind::BinaryOp(op), string_type, &node)
1630 } else {
1631 created_expression
1632 };
1633
1634 last_expression = Some(x_last_expr);
1635 }
1636
1637 if let Some(last) = last_expression {
1640 last
1641 } else {
1642 let string_type = self.shared.state.types.string();
1643 self.create_expr(
1644 ExpressionKind::StringLiteral(String::new()),
1645 string_type,
1646 node,
1647 )
1648 }
1649 }
1650
1651 pub(crate) fn analyze_identifier(
1652 &mut self,
1653 qualified_func_name: &swamp_ast::QualifiedIdentifier,
1654 ) -> Expression {
1655 if qualified_func_name.module_path.is_none()
1658 && qualified_func_name.generic_params.is_empty()
1659 {
1660 if let Some(found_variable) = self.try_find_variable(&qualified_func_name.name) {
1661 return self.create_expr(
1662 ExpressionKind::VariableAccess(found_variable.clone()),
1663 found_variable.resolved_type.clone(),
1664 &qualified_func_name.name,
1665 );
1666 }
1667 }
1668
1669 let text = self.get_text(&qualified_func_name.name);
1670 self.create_err(
1671 ErrorKind::UnknownIdentifier(text.to_string()),
1672 &qualified_func_name.name,
1673 )
1674 }
1675
1676 fn analyze_variable_reference(&mut self, var_node: &swamp_ast::Node) -> Expression {
1678 if let Some(found_variable) = self.try_find_variable(var_node) {
1679 return self.create_expr(
1680 ExpressionKind::VariableAccess(found_variable.clone()),
1681 found_variable.resolved_type.clone(),
1682 var_node,
1683 );
1684 }
1685 let text = self.get_text(var_node);
1686 self.create_err(ErrorKind::UnknownIdentifier(text.to_string()), var_node)
1687 }
1688
1689 fn analyze_internal_initializer_pair_list(
1690 &mut self,
1691 node: &swamp_ast::Node,
1692 items: &[(swamp_ast::Expression, swamp_ast::Expression)],
1693 context: &TypeContext,
1694 ) -> (TypeRef, Vec<(Expression, Expression)>) {
1695 let (collection_type, key_type, value_type) = if let Some(expected_type) =
1696 context.expected_type
1697 {
1698 match &*expected_type.kind {
1699 TypeKind::MapStorage(key, value, capacity) => {
1700 if items.len() > *capacity {
1701 self.add_err(
1702 ErrorKind::TooManyInitializerListElementsForStorage {
1703 capacity: *capacity,
1704 },
1705 node,
1706 );
1707 return (self.types().unit(), vec![]);
1708 }
1709 (expected_type.clone(), key.clone(), value.clone())
1710 }
1711 TypeKind::DynamicLengthMapView(key, value) => {
1712 (expected_type.clone(), key.clone(), value.clone())
1713 }
1714 _ => {
1715 self.add_err(ErrorKind::ExpectedSlice, node);
1716 return (self.types().unit(), vec![]);
1717 }
1718 }
1719 } else if items.is_empty() {
1720 self.add_err(ErrorKind::NoInferredTypeForEmptyInitializer, node);
1721 return (self.types().unit(), vec![]);
1722 } else {
1723 let maybe_key_context = TypeContext::new_anything_argument(true);
1725
1726 let first_key_expression = self.analyze_expression(&items[0].0, &maybe_key_context);
1727
1728 let maybe_value_context = TypeContext::new_anything_argument(true);
1729 let first_value_expression = self.analyze_expression(&items[0].1, &maybe_value_context);
1730
1731 let required_key_type = first_key_expression.ty;
1732 let required_value_type = first_value_expression.ty;
1733
1734 let inferred_type =
1735 self.types()
1736 .map_storage(&required_key_type, &required_value_type, items.len());
1737
1738 (inferred_type, required_key_type, required_value_type)
1739 };
1740
1741 assert!(!matches!(*key_type.kind, TypeKind::Unit));
1742 assert!(!matches!(*value_type.kind, TypeKind::Unit));
1743
1744 let required_key_context = TypeContext::new_argument(&key_type, true);
1745 let required_value_context = TypeContext::new_argument(&value_type, true);
1746
1747 let mut resolved_items = Vec::new();
1748
1749 for (key_expr, value_expr) in items {
1750 let analyzed_key_expr = self.analyze_expression(key_expr, &required_key_context);
1751 let analyzed_value_expr = self.analyze_expression(value_expr, &required_value_context);
1752 resolved_items.push((analyzed_key_expr, analyzed_value_expr));
1753 }
1754
1755 (collection_type, resolved_items)
1756 }
1757
1758 fn analyze_internal_initializer_list(
1759 &mut self,
1760 node: &swamp_ast::Node,
1761 items: &[swamp_ast::Expression],
1762 context: &TypeContext,
1763 ) -> (TypeRef, Vec<Expression>) {
1764 let (collection_type, element_type) = if let Some(expected_type) = context.expected_type {
1765 match &*expected_type.kind {
1766 TypeKind::GridStorage(element_type, width, height) => {
1767 let capacity = width * height;
1768 if items.len() > capacity {
1769 return (
1770 self.types().unit(),
1771 self.create_err_vec(
1772 ErrorKind::TooManyInitializerListElementsForStorage { capacity },
1773 node,
1774 ),
1775 );
1776 }
1777 (expected_type.clone(), element_type.clone())
1778 }
1779 TypeKind::StackStorage(element_type, capacity)
1780 | TypeKind::QueueStorage(element_type, capacity)
1781 | TypeKind::SparseStorage(element_type, capacity)
1782 | TypeKind::VecStorage(element_type, capacity) => {
1783 if items.len() > *capacity {
1784 return (
1785 self.types().unit(),
1786 self.create_err_vec(
1787 ErrorKind::TooManyInitializerListElementsForStorage {
1788 capacity: *capacity,
1789 },
1790 node,
1791 ),
1792 );
1793 }
1794 (expected_type.clone(), element_type.clone())
1795 }
1796 TypeKind::QueueView(element_type) => {
1797 let inferred_storage_type = self.types().queue_storage(element_type, items.len());
1799 let default_node = swamp_ast::Node::default();
1800 self.add_default_functions(&inferred_storage_type, &default_node);
1801 (inferred_storage_type, element_type.clone())
1802 }
1803 TypeKind::SparseView(element_type) => {
1804 let inferred_storage_type = self.types().sparse_storage(element_type, items.len());
1806 let default_node = swamp_ast::Node::default();
1807 self.add_default_functions(&inferred_storage_type, &default_node);
1808 (inferred_storage_type, element_type.clone())
1809 }
1810 TypeKind::StackView(element_type) => {
1811 let inferred_storage_type = self.types().stack_storage(element_type, items.len());
1813 let default_node = swamp_ast::Node::default();
1814 self.add_default_functions(&inferred_storage_type, &default_node);
1815 (inferred_storage_type, element_type.clone())
1816 }
1817 TypeKind::GridView(element_type) => {
1818 (expected_type.clone(), element_type.clone())
1820 }
1821 TypeKind::DynamicLengthVecView(element_type) => {
1822 let inferred_storage_type = self.types().vec_storage(element_type, items.len());
1824 let default_node = swamp_ast::Node::default();
1825 self.add_default_functions(&inferred_storage_type, &default_node);
1826 (inferred_storage_type, element_type.clone())
1827 }
1828 TypeKind::SliceView(element_type) => {
1829 let inferred_storage_type = self.types().vec_storage(element_type, items.len());
1831 let default_node = swamp_ast::Node::default();
1832 self.add_default_functions(&inferred_storage_type, &default_node);
1833 (inferred_storage_type, element_type.clone())
1834 }
1835 TypeKind::FixedCapacityAndLengthArray(element_type, _size) => {
1836 (expected_type.clone(), element_type.clone())
1837 }
1838 _ => {
1839 return (
1840 self.types().unit(),
1841 self.create_err_vec(
1842 ErrorKind::ExpectedInitializerTarget {
1843 destination_type: expected_type.clone(),
1844 },
1845 node,
1846 ),
1847 );
1848 }
1849 }
1850 } else if items.is_empty() {
1851 return (
1852 self.types().unit(),
1853 self.create_err_vec(ErrorKind::NoInferredTypeForEmptyInitializer, node),
1854 );
1855 } else {
1856 let maybe_context = TypeContext::new_anything_argument(true);
1858 let first = self.analyze_expression(&items[0], &maybe_context);
1859 let required_type = first.ty;
1860 let inferred_vec_storage_type = self.types().vec_storage(&required_type, items.len());
1861 let default_node = swamp_ast::Node::default();
1863 self.add_default_functions(&inferred_vec_storage_type, &default_node);
1864 (inferred_vec_storage_type, required_type)
1865 };
1866
1867 let required_context = TypeContext::new_argument(&element_type, true);
1868 let mut resolved_items = Vec::new();
1869 for item in items {
1870 let resolved_expr = self.analyze_expression(item, &required_context);
1871 resolved_items.push(resolved_expr);
1872 }
1873 (collection_type, resolved_items)
1874 }
1875
1876 fn push_block_scope(&mut self, debug_str: &str) {
1877 let register_watermark = self.scope.total_scopes.current_register;
1878
1879 self.scope.active_scope.block_scope_stack.push(BlockScope {
1880 mode: BlockScopeMode::Open,
1881 lookup: Default::default(),
1882 variables: SeqMap::default(),
1883 register_watermark,
1884 });
1885 }
1886
1887 fn push_lambda_scope(&mut self, debug_str: &str) {
1888 self.scope.active_scope.block_scope_stack.push(BlockScope {
1891 mode: BlockScopeMode::Lambda,
1892 lookup: SeqMap::default(),
1893 variables: SeqMap::default(),
1894 register_watermark: 0, });
1896 }
1897
1898 fn pop_block_scope(&mut self, debug_str: &str) {
1899 self.pop_any_block_scope();
1900 }
1901
1902 fn push_closed_block_scope(&mut self) {
1903 let register_watermark = self.scope.total_scopes.current_register;
1904 self.scope.active_scope.block_scope_stack.push(BlockScope {
1905 mode: BlockScopeMode::Closed,
1906 lookup: Default::default(),
1907 variables: SeqMap::default(),
1908 register_watermark,
1909 });
1910 }
1911
1912 fn pop_closed_block_scope(&mut self) {
1913 self.pop_any_block_scope();
1915 }
1916
1917 fn pop_any_block_scope(&mut self) {
1918 let scope = self.scope.active_scope.block_scope_stack.pop().unwrap();
1919
1920 self.scope.total_scopes.highest_virtual_register = self.scope.total_scopes.current_register;
1922
1923 let is_inside_lambda = self
1925 .scope
1926 .active_scope
1927 .block_scope_stack
1928 .iter()
1929 .any(|s| matches!(s.mode, BlockScopeMode::Lambda));
1930
1931 if matches!(scope.mode, BlockScopeMode::Lambda) {
1932 } else if is_inside_lambda {
1934 } else {
1936 self.scope.total_scopes.current_register = scope.register_watermark;
1938 }
1939 }
1940
1941 fn analyze_match(
1942 &mut self,
1943 scrutinee: &swamp_ast::Expression,
1944 default_context: &TypeContext,
1945 arms: &Vec<swamp_ast::MatchArm>,
1946 ) -> (Match, TypeRef) {
1947 let mut known_type = default_context.expected_type.cloned();
1948 let own_context = default_context.clone();
1949 let scrutinee_context = TypeContext::new_anything_argument(true); let resolved_scrutinee = self.analyze_expression(scrutinee, &scrutinee_context);
1952 let scrutinee_type = resolved_scrutinee.ty.clone();
1953
1954 let mut resolved_arms = Vec::with_capacity(arms.len());
1955
1956 if arms.is_empty() {
1958 let err_match = Match {
1959 expression: Box::new(
1960 self.create_err(ErrorKind::MatchMustHaveAtLeastOneArm, &scrutinee.node),
1961 ),
1962 arms: resolved_arms,
1963 };
1964 return (err_match, self.types().unit());
1965 }
1966
1967 for arm in arms {
1968 let (resolved_arm, _anyone_wants_mutable) = self.analyze_arm(
1969 arm,
1970 &resolved_scrutinee,
1971 &own_context.with_expected_type(known_type.as_ref(), false),
1972 &scrutinee_type,
1973 );
1974
1975 if known_type.is_none() {
1976 known_type = Some(resolved_arm.expression.ty.clone());
1977 }
1978 resolved_arms.push(resolved_arm);
1979 }
1980
1981 if let Some(encountered_type) = known_type {
1982 (
1983 Match {
1984 expression: Box::new(resolved_scrutinee),
1985 arms: resolved_arms,
1986 },
1987 encountered_type,
1988 )
1989 } else {
1990 let err_expr = self.create_err(ErrorKind::MatchArmsMustHaveTypes, &scrutinee.node);
1991
1992 (
1993 Match {
1994 expression: Box::new(err_expr),
1995 arms: resolved_arms.clone(),
1996 },
1997 self.types().unit(),
1998 )
1999 }
2000 }
2001
2002 fn analyze_arm(
2003 &mut self,
2004 arm: &swamp_ast::MatchArm,
2005 _expression: &Expression,
2006 type_context: &TypeContext,
2007 expected_condition_type: &TypeRef,
2008 ) -> (MatchArm, bool) {
2009 let (resolved_pattern, scope_was_pushed, anyone_wants_mutable) =
2010 self.analyze_pattern(&arm.pattern, expected_condition_type);
2011
2012 let resolved_expression = self.analyze_expression(&arm.expression, type_context);
2013 if scope_was_pushed {
2014 self.pop_block_scope("analyze_arm");
2015 }
2016
2017 let resolved_type = resolved_expression.ty.clone();
2018
2019 (
2020 MatchArm {
2021 pattern: resolved_pattern,
2022 expression: Box::from(resolved_expression),
2023 expression_type: resolved_type,
2024 },
2025 anyone_wants_mutable,
2026 )
2027 }
2028
2029 fn str_to_int(text: &str) -> Result<i32, ParseIntError> {
2030 let text = text.replace('_', "");
2031 text.strip_prefix("0x").map_or_else(
2032 || {
2033 text.strip_prefix("-0x").map_or_else(
2034 || text.parse::<i32>(),
2035 |rest| i32::from_str_radix(rest, 16).map(|x| -x),
2036 )
2037 },
2038 |rest| i32::from_str_radix(rest, 16),
2039 )
2040 }
2041
2042 fn str_to_unsigned_int(text: &str) -> Result<u32, ParseIntError> {
2043 let text = text.replace('_', "");
2044 text.strip_prefix("0x")
2045 .map_or_else(|| text.parse::<u32>(), |rest| u32::from_str_radix(rest, 16))
2046 }
2047
2048 fn str_to_float(text: &str) -> Result<f32, ParseFloatError> {
2049 text.parse::<f32>()
2050 }
2051
2052 fn str_to_bool(text: &str) -> Result<bool, ParseBoolError> {
2053 bool::from_str(text)
2054 }
2055
2056 fn analyze_pattern_literal(
2057 &mut self,
2058 node: &swamp_ast::Node,
2059 ast_literal: &swamp_ast::LiteralKind,
2060 expected_condition_type: &TypeRef,
2061 ) -> NormalPattern {
2062 let required_condition_type_context =
2063 TypeContext::new_argument(expected_condition_type, false);
2064 let literal = self.analyze_literal(node, ast_literal, &required_condition_type_context);
2065
2066 if !self
2067 .types()
2068 .compatible_with(&literal.ty, expected_condition_type)
2069 {
2070 return NormalPattern::Literal(self.create_err(
2071 ErrorKind::IncompatibleTypes {
2072 expected: expected_condition_type.clone(),
2073 found: literal.ty,
2074 },
2075 node,
2076 ));
2077 }
2078
2079 NormalPattern::Literal(literal)
2080 }
2081
2082 const fn to_node(&self, node: &swamp_ast::Node) -> Node {
2083 Node {
2084 span: Span {
2085 file_id: self.shared.file_id,
2086 offset: node.span.offset,
2087 length: node.span.length,
2088 },
2089 }
2090 }
2091
2092 fn get_module_path(&self, module_path: Option<&swamp_ast::ModulePath>) -> Vec<String> {
2093 module_path.as_ref().map_or_else(Vec::new, |found| {
2094 let mut strings = Vec::new();
2095 for path_item in &found.0 {
2096 strings.push(self.get_text(path_item).to_string());
2097 }
2098 strings
2099 })
2100 }
2101
2102 fn get_enum_variant_type(
2103 &mut self,
2104 qualified_type_identifier: &swamp_ast::QualifiedTypeIdentifier,
2105 variant_name: &str,
2106 ) -> EnumVariantType {
2107 let Some((symbol_table, enum_name)) =
2108 self.get_symbol_table_and_name(qualified_type_identifier)
2109 else {
2110 self.add_err(
2111 ErrorKind::UnknownEnumVariantType,
2112 &qualified_type_identifier.name.0,
2113 );
2114 return EnumVariantType {
2115 common: EnumVariantCommon {
2116 name: Default::default(),
2117 assigned_name: String::new(),
2118 container_index: 0,
2119 },
2120 payload_type: self.types().unit(),
2121 };
2122 };
2123
2124 if let Some(enum_name) = symbol_table.get_enum_variant_type(&enum_name, variant_name) {
2125 enum_name
2126 } else {
2127 self.add_err(
2128 ErrorKind::UnknownEnumVariantType,
2129 &qualified_type_identifier.name.0,
2130 );
2131 EnumVariantType {
2132 common: EnumVariantCommon {
2133 name: Default::default(),
2134 assigned_name: String::new(),
2135 container_index: 0,
2136 },
2137 payload_type: self.types().unit(),
2138 }
2139 }
2140 }
2141
2142 pub(crate) fn get_symbol_table_and_name(
2143 &self,
2144 type_identifier: &swamp_ast::QualifiedTypeIdentifier,
2145 ) -> Option<(&SymbolTable, String)> {
2146 let path = self.get_module_path(type_identifier.module_path.as_ref());
2147 let name = self.get_text(&type_identifier.name.0).to_string();
2148
2149 if let Some(found) = self.shared.get_symbol_table(&path) {
2150 Some((found, name))
2151 } else {
2152 None
2153 }
2154 }
2155
2156 const fn analyze_compound_operator(
2157 &self,
2158 ast_operator: &swamp_ast::CompoundOperator,
2159 ) -> CompoundOperator {
2160 let resolved_node = self.to_node(&ast_operator.node);
2161 let resolved_kind = match ast_operator.kind {
2162 swamp_ast::CompoundOperatorKind::Add => CompoundOperatorKind::Add,
2163 swamp_ast::CompoundOperatorKind::Sub => CompoundOperatorKind::Sub,
2164 swamp_ast::CompoundOperatorKind::Mul => CompoundOperatorKind::Mul,
2165 swamp_ast::CompoundOperatorKind::Div => CompoundOperatorKind::Div,
2166 swamp_ast::CompoundOperatorKind::Modulo => CompoundOperatorKind::Modulo,
2167 };
2168
2169 CompoundOperator {
2170 node: resolved_node,
2171 kind: resolved_kind,
2172 }
2173 }
2174
2175 const fn to_node_option(&self, maybe_node: Option<&swamp_ast::Node>) -> Option<Node> {
2176 match maybe_node {
2177 None => None,
2178 Some(node) => Some(self.to_node(node)),
2179 }
2180 }
2181
2182 const fn analyze_format_specifier(
2183 &self,
2184 ast_format_specifier: Option<&swamp_ast::FormatSpecifier>,
2185 ) -> Option<FormatSpecifier> {
2186 let f = match ast_format_specifier {
2187 None => return None,
2188 Some(ast_format) => match ast_format {
2189 swamp_ast::FormatSpecifier::LowerHex(node) => FormatSpecifier {
2190 node: self.to_node(node),
2191 kind: FormatSpecifierKind::LowerHex,
2192 },
2193 swamp_ast::FormatSpecifier::UpperHex(node) => FormatSpecifier {
2194 node: self.to_node(node),
2195 kind: FormatSpecifierKind::UpperHex,
2196 },
2197 swamp_ast::FormatSpecifier::Binary(node) => FormatSpecifier {
2198 node: self.to_node(node),
2199 kind: FormatSpecifierKind::Binary,
2200 },
2201 swamp_ast::FormatSpecifier::Float(node) => FormatSpecifier {
2202 node: self.to_node(node),
2203 kind: FormatSpecifierKind::Float,
2204 },
2205 swamp_ast::FormatSpecifier::Precision(value, node, x) => {
2206 let (precision_type, precision_node) = match x {
2207 swamp_ast::PrecisionType::Float(node) => {
2208 (PrecisionType::Float, self.to_node(node))
2209 }
2210 swamp_ast::PrecisionType::String(node) => {
2211 (PrecisionType::String, self.to_node(node))
2212 }
2213 };
2214 FormatSpecifier {
2215 node: self.to_node(node),
2216 kind: FormatSpecifierKind::Precision(
2217 *value,
2218 precision_node,
2219 precision_type,
2220 ),
2221 }
2222 }
2223 },
2224 };
2225
2226 Some(f)
2227 }
2228
2229 fn analyze_with_expr(
2230 &mut self,
2231 context: &TypeContext,
2232 variables: &[swamp_ast::VariableBinding],
2233 expression: &swamp_ast::Expression,
2234 ) -> Expression {
2235 let mut variable_expressions = Vec::new();
2236
2237 for variable in variables {
2238 let any_context = TypeContext::new_anything_argument(false);
2239 let must_have_expression = if let Some(x) = &variable.expression {
2240 x
2241 } else {
2242 &swamp_ast::Expression {
2243 kind: swamp_ast::ExpressionKind::VariableReference(variable.variable.clone()),
2244 node: variable.variable.name.clone(),
2245 }
2246 };
2247
2248 let location_side = if variable.variable.is_mutable.is_some() {
2250 if let Some(expr) = &variable.expression {
2252 let maybe_ref = self.analyze_maybe_ref_expression(expr);
2254 if maybe_ref.has_borrow_mutable_reference.is_some() {
2255 LocationSide::Mutable
2256 } else {
2257 LocationSide::Rhs
2258 }
2259 } else {
2260 LocationSide::Rhs
2262 }
2263 } else {
2264 LocationSide::Rhs
2266 };
2267
2268 let var = self.analyze_mut_or_immutable_expression(
2269 must_have_expression,
2270 &any_context,
2271 location_side,
2272 );
2273
2274 variable_expressions.push(var);
2275 }
2276
2277 self.push_closed_block_scope();
2278 let mut expressions = Vec::new();
2279 for (variable_binding, resolved_expression) in variables.iter().zip(variable_expressions) {
2280 let initialize_variable_expression = self
2281 .create_variable_binding_for_with(&variable_binding.variable, resolved_expression);
2282
2283 expressions.push(initialize_variable_expression);
2287 }
2288
2289 let resolved_expression = self.analyze_expression(expression, context);
2290 let block_type = self.types().unit();
2292 expressions.push(resolved_expression);
2293
2294 let block_expression_kind = ExpressionKind::Block(expressions);
2295 self.pop_closed_block_scope();
2296
2297 self.create_expr(block_expression_kind, block_type, &expression.node)
2298 }
2299
2300 fn analyze_when_expr(
2301 &mut self,
2302 context: &TypeContext,
2303 variables: &[swamp_ast::VariableBinding],
2304 true_expr: &swamp_ast::Expression,
2305 else_expr: Option<&swamp_ast::Expression>,
2306 ) -> Expression {
2307 self.push_block_scope("when");
2309 let mut bindings = Vec::new();
2310 for variable_binding in variables {
2311 let mut_expr = if let Some(found_expr) = &variable_binding.expression {
2312 let any_context = TypeContext::new_anything_argument(true); self.analyze_mut_or_immutable_expression(
2314 found_expr,
2315 &any_context,
2316 LocationSide::Rhs,
2317 )
2318 .expect_immutable()
2319 .unwrap()
2320 } else {
2321 let same_var = self.find_variable(&variable_binding.variable);
2322
2323 let generated_expr_kind = ExpressionKind::VariableAccess(same_var.clone());
2326 self.create_expr(
2327 generated_expr_kind,
2328 same_var.resolved_type.clone(),
2329 &variable_binding.variable.name,
2330 )
2331 };
2332
2333 let tk = &mut_expr.ty.kind;
2334
2335 if let TypeKind::Optional(found_ty) = &**tk {
2336 let variable_ref = self.create_variable(&variable_binding.variable, found_ty);
2337
2338 let binding = WhenBinding {
2339 variable: variable_ref,
2340 expr: mut_expr,
2341 };
2342 bindings.push(binding);
2343 } else {
2344 return self.create_err(ErrorKind::ExpectedOptional, &true_expr.node);
2345 }
2346 }
2347
2348 let resolved_true = self.analyze_expression(true_expr, context);
2349 let block_type = resolved_true.ty.clone();
2350
2351 self.pop_block_scope("when");
2352
2353 let maybe_resolved_else = if let Some(found_else) = else_expr {
2354 let block_type_for_true_context = context.we_know_expected_type(&block_type, false);
2355 Some(Box::new(self.analyze_expression(
2356 found_else,
2357 &block_type_for_true_context,
2358 )))
2359 } else {
2360 None
2361 };
2362
2363 let when_kind =
2364 ExpressionKind::When(bindings, Box::from(resolved_true), maybe_resolved_else);
2365
2366 self.create_expr(when_kind, block_type, &true_expr.node)
2367 }
2368
2369 fn analyze_guard(
2370 &mut self,
2371 node: &swamp_ast::Node,
2372 context: &TypeContext,
2373 guard_expressions: &Vec<swamp_ast::GuardExpr>,
2374 ) -> Expression {
2375 let mut guards = Vec::new();
2376 let mut found_wildcard = None;
2377 let mut detected_type = context.expected_type.cloned();
2378
2379 for guard in guard_expressions {
2380 let resolved_condition = match &guard.clause {
2381 swamp_ast::GuardClause::Wildcard(x) => {
2382 if found_wildcard.is_some() {
2383 return self.create_err(ErrorKind::GuardCanNotHaveMultipleWildcards, node);
2384 }
2385 found_wildcard = Some(x);
2386 None
2387 }
2388 swamp_ast::GuardClause::Expression(clause_expr) => {
2389 if found_wildcard.is_some() {
2390 return self.create_err(ErrorKind::WildcardMustBeLastInGuard, node);
2391 }
2392 Some(self.analyze_bool_argument_expression(clause_expr))
2393 }
2394 };
2395
2396 let resolved_result = self.analyze_expression(
2397 &guard.result,
2398 &context.with_expected_type(detected_type.as_ref(), false),
2399 );
2400 let ty = resolved_result.ty.clone();
2401 if detected_type.is_none() {
2402 detected_type = Some(ty.clone());
2403 }
2404
2405 guards.push(Guard {
2406 condition: resolved_condition,
2407 result: resolved_result,
2408 });
2409 }
2410
2411 if found_wildcard.is_none() {
2412 return self.create_err(ErrorKind::GuardMustHaveWildcard, node);
2413 }
2414
2415 let kind = ExpressionKind::Guard(guards);
2416
2417 if let Some(found_expecting_type) = detected_type {
2418 self.create_expr(kind, found_expecting_type, node)
2419 } else {
2420 self.create_err(ErrorKind::GuardHasNoType, node)
2421 }
2422 }
2423
2424 fn analyze_lambda(
2425 &mut self,
2426 node: &swamp_ast::Node,
2427 variables: &[swamp_ast::Variable],
2428 ast_expr: &swamp_ast::Expression,
2429 context: &TypeContext,
2430 ) -> Expression {
2431 let TypeKind::Function(signature) = &*context.expected_type.unwrap().kind else {
2432 return self.create_err(ErrorKind::ExpectedLambda, node);
2433 };
2434
2435 let return_block_type = TypeContext::new_argument(&signature.return_type, false);
2436
2437 self.push_lambda_scope("lambda");
2440
2441 let arity_required = signature.parameters.len();
2442 let variable_types_to_create = if variables.len() == arity_required {
2443 &signature.parameters
2444 } else if variables.len() + 1 == arity_required {
2445 &signature.parameters[1..].to_vec()
2446 } else {
2447 return self.create_err(ErrorKind::WrongNumberOfArguments(0, 0), node);
2448 };
2449
2450 let mut resolved_variables = Vec::new();
2451 for (variable, variable_type) in variables.iter().zip(variable_types_to_create) {
2452 let variable_ref = self.create_local_variable(
2453 &variable.name,
2454 variable.is_mutable.as_ref(),
2455 &variable_type.resolved_type,
2456 false,
2457 );
2458 resolved_variables.push(variable_ref);
2459 }
2460
2461 let analyzed_expression = self.analyze_expression(ast_expr, &return_block_type);
2464
2465 self.pop_block_scope("lambda");
2466
2467 let function_type = self.types().function(signature.clone());
2468 self.create_expr(
2469 ExpressionKind::Lambda(resolved_variables, Box::new(analyzed_expression)),
2470 function_type,
2471 node,
2472 )
2473 }
2474
2475 #[must_use]
2476 pub fn chain_is_owned_result(
2477 start_of_chain: &StartOfChain,
2478 chains: &Vec<Postfix>,
2479 ) -> (bool, bool) {
2480 let mut is_owned_result = matches!(start_of_chain.kind, StartOfChainKind::Expression(_));
2481 let mut is_mutable = if let StartOfChainKind::Variable(var) = &start_of_chain.kind {
2482 var.is_mutable()
2483 } else {
2484 false
2485 };
2486
2487 for chain in chains {
2488 match chain.kind {
2489 PostfixKind::StructField(_, _) => {
2490 is_owned_result = false;
2491 }
2492 PostfixKind::SliceViewSubscript(_, _) => {
2493 is_owned_result = false;
2494 }
2495 PostfixKind::MemberCall(_, _) => {
2496 is_owned_result = true;
2497 is_mutable = false;
2498 }
2499 PostfixKind::OptionalChainingOperator => {
2500 is_owned_result = true;
2501 is_mutable = false;
2502 }
2503 PostfixKind::NoneCoalescingOperator(_) => {
2504 is_owned_result = true;
2505 is_mutable = false;
2506 }
2507 PostfixKind::VecSubscript(_, _) => {}
2508 PostfixKind::SparseSubscript(_, _) => {}
2509 PostfixKind::GridSubscript(_, _, _) => {}
2510 PostfixKind::MapSubscript(_, _) => {}
2511 }
2512 }
2513
2514 (is_owned_result, is_mutable)
2515 }
2516
2517 pub fn check_assignment_mode(
2518 &mut self,
2519 lhs_is_mutable: bool,
2520 source_expression: &Expression,
2521 ty: &TypeRef,
2522 ) -> AssignmentMode {
2523 if matches!(
2524 &source_expression.kind,
2525 _ | ExpressionKind::IntrinsicCallEx(_, _)
2526 ) {
2527 return AssignmentMode::OwnedValue;
2528 }
2529
2530 if let ExpressionKind::PostfixChain(start_chain, postfix) = &source_expression.kind {
2538 let (chain_is_owned, chain_is_mutable) =
2539 Self::chain_is_owned_result(start_chain, postfix);
2540 if lhs_is_mutable {
2541 return if chain_is_mutable {
2542 AssignmentMode::CopyBlittable
2543 } else if lhs_is_mutable {
2544 if chain_is_owned {
2545 AssignmentMode::OwnedValue
2546 } else {
2547 AssignmentMode::CopyBlittable
2548 }
2549 } else {
2550 AssignmentMode::CopySharedPtr
2551 };
2552 }
2553 }
2555
2556 AssignmentMode::CopyBlittable
2557 }
2558
2559 pub const fn check_mutable_assignment(&mut self, assignment_mode: AssignmentMode, node: &Node) {
2560 }
2561
2562 pub const fn check_mutable_variable_assignment(
2563 &mut self,
2564 source_expression: &swamp_ast::Expression,
2565 ty: &TypeRef,
2566 variable: &swamp_ast::Variable,
2567 ) {
2568 }
2574
2575 pub fn analyze_variable_assignment(
2578 &mut self,
2579 variable: &swamp_ast::Variable,
2580 source_expression: &swamp_ast::Expression,
2581 ) -> Expression {
2582 let maybe_found_variable = self.try_find_variable(&variable.name);
2583
2584 let required_type = maybe_found_variable
2585 .as_ref()
2586 .map(|found_variable| found_variable.resolved_type.clone());
2587
2588 let source_expr = if let Some(target_type) = &required_type {
2589 self.analyze_expression_for_assignment_with_target_type(target_type, source_expression)
2590 } else {
2591 let any_type_context = TypeContext::new_anything_argument(true);
2592 self.analyze_expression(source_expression, &any_type_context)
2593 };
2594
2595 let target_type = if let Some(found_var) = &maybe_found_variable {
2598 &found_var.resolved_type
2599 } else {
2600 &source_expr.ty
2601 };
2602
2603 let should_check_blittable = if let Some(found_var) = &maybe_found_variable {
2605 !matches!(found_var.variable_type, VariableType::Parameter)
2606 } else {
2607 true };
2609
2610 if should_check_blittable && !target_type.is_blittable() {
2611 let debug_text = self.get_text(&variable.name);
2612 if !debug_text.starts_with('_') {
2613 return self.create_err(
2614 ErrorKind::VariableTypeMustBeBlittable(target_type.clone()),
2615 &variable.name,
2616 );
2617 }
2618 }
2619
2620 let kind: ExpressionKind = if let Some(found_var) = maybe_found_variable {
2621 if !found_var.is_mutable() {
2622 return self.create_err(ErrorKind::VariableIsNotMutable, &variable.name);
2623 }
2624 if !self
2625 .types()
2626 .compatible_with(&found_var.resolved_type, &source_expr.ty)
2627 {
2628 return self.create_err(
2629 ErrorKind::IncompatibleTypes {
2630 expected: source_expr.ty,
2631 found: found_var.resolved_type.clone(),
2632 },
2633 &variable.name,
2634 );
2635 }
2636 self.check_mutable_variable_assignment(source_expression, &source_expr.ty, variable);
2637 ExpressionKind::VariableReassignment(found_var, Box::from(source_expr))
2638 } else {
2639 if !source_expr.ty.is_blittable() {
2640 let text = self.get_text(&variable.name);
2641 error!(?text, ?required_type, ?source_expr, "variable is wrong");
2642 }
2643
2644 if variable.is_mutable.is_some() {
2647 self.check_mutable_variable_assignment(
2648 source_expression,
2649 &source_expr.ty,
2650 variable,
2651 );
2652 }
2653 let new_var = self.create_variable(variable, &source_expr.ty);
2654 ExpressionKind::VariableDefinition(new_var, Box::from(source_expr))
2655 };
2656
2657 let unit_type = self.shared.state.types.unit();
2658 self.create_expr(kind, unit_type, &variable.name)
2659 }
2660
2661 fn analyze_create_variable(
2662 &mut self,
2663 var: &swamp_ast::Variable,
2664 annotation_type: Option<&swamp_ast::Type>,
2665 source_expression: &swamp_ast::Expression,
2666 ) -> Expression {
2667 let maybe_annotated_type =
2668 annotation_type.map(|found_ast_type| self.analyze_type(found_ast_type));
2669
2670 let unsure_arg_context =
2671 TypeContext::new_unsure_argument(maybe_annotated_type.as_ref(), true);
2672
2673 let resolved_source = self.analyze_expression(source_expression, &unsure_arg_context);
2674
2675 let resulting_type = if let Some(annotated_type) = maybe_annotated_type {
2676 annotated_type
2677 } else {
2678 resolved_source.ty.clone()
2679 };
2680 let var_ref = self.create_local_variable(
2681 &var.name,
2682 Option::from(&var.is_mutable),
2683 &resulting_type,
2684 true,
2685 );
2686
2687 assert_ne!(&*resulting_type.kind, &TypeKind::Unit);
2688 let kind = ExpressionKind::VariableDefinition(var_ref, Box::from(resolved_source));
2689
2690 let unit_type = self.shared.state.types.unit();
2691
2692 self.create_expr(kind, unit_type, &var.name)
2693 }
2694
2695 fn add_location_item(
2696 &mut self,
2697 vec: &mut Vec<LocationAccess>,
2698 kind: LocationAccessKind,
2699 ty: TypeRef,
2700 ast_node: &swamp_ast::Node,
2701 ) {
2702 let resolved_node = self.to_node(ast_node);
2703 let postfix = LocationAccess {
2704 node: resolved_node,
2705 ty,
2706 kind,
2707 };
2708
2709 vec.push(postfix);
2710 }
2711
2712 fn extract_single_intrinsic_call(
2713 body: &Expression,
2714 ) -> Option<(IntrinsicFunction, Vec<ArgumentExpression>)> {
2715 if let ExpressionKind::Block(expressions) = &body.kind {
2716 let first_kind = &expressions[0].kind;
2717 if let ExpressionKind::IntrinsicCallEx(intrinsic_fn, args) = &first_kind {
2718 return Some((intrinsic_fn.clone(), args.clone()));
2719 }
2720 }
2721 None
2722 }
2723
2724 #[allow(clippy::too_many_lines)]
2725 fn analyze_chain_to_location(
2726 &mut self,
2727 chain: &swamp_ast::PostfixChain,
2728 context: &TypeContext,
2729 location_side: LocationSide,
2730 ) -> SingleLocationExpression {
2731 let mut items = Vec::new();
2732
2733 let nothing_context = TypeContext::new(None, true);
2734
2735 let base_expr = self.analyze_expression(&chain.base, ¬hing_context);
2736 let ExpressionKind::VariableAccess(start_variable) = base_expr.kind else {
2737 self.add_err(ErrorKind::NotValidLocationStartingPoint, &chain.base.node);
2738 let unit_type = self.types().unit();
2739 let err_variable = Variable {
2740 name: Default::default(),
2741 assigned_name: String::new(),
2742 resolved_type: unit_type,
2743 mutable_node: None,
2744 variable_type: VariableType::Local,
2745 scope_index: 0,
2746 variable_index: 0,
2747 unique_id_within_function: 0,
2748 virtual_register: 0,
2749 is_unused: false,
2750 };
2751 return SingleLocationExpression {
2752 kind: MutableReferenceKind::MutVariableRef,
2753 node: self.to_node(&chain.base.node),
2754 ty: self.shared.state.types.unit(),
2755 starting_variable: VariableRef::from(err_variable),
2756 access_chain: vec![],
2757 };
2758 };
2759
2760 if !start_variable.is_mutable() {
2761 self.add_err(ErrorKind::VariableIsNotMutable, &chain.base.node);
2762
2763 let unit_type = self.types().unit();
2764 let err_variable = Variable {
2765 name: Default::default(),
2766 assigned_name: String::new(),
2767 resolved_type: unit_type,
2768 mutable_node: None,
2769 variable_type: VariableType::Local,
2770 scope_index: 0,
2771 variable_index: 0,
2772 unique_id_within_function: 0,
2773 virtual_register: 0,
2774 is_unused: false,
2775 };
2776 return SingleLocationExpression {
2777 kind: MutableReferenceKind::MutVariableRef,
2778 node: self.to_node(&chain.base.node),
2779 ty: self.shared.state.types.unit(),
2780 starting_variable: VariableRef::from(err_variable),
2781 access_chain: vec![],
2782 };
2783 }
2784
2785 let mut ty = start_variable.resolved_type.clone();
2786 for (i, item) in chain.postfixes.iter().enumerate() {
2787 let is_absolute_last_in_chain = i == chain.postfixes.len() - 1;
2788 match &item {
2789 swamp_ast::Postfix::FieldAccess(field_name_node) => {
2790 let (struct_type_ref, index, return_type) =
2792 self.analyze_struct_field(field_name_node, &ty);
2793
2794 self.add_location_item(
2795 &mut items,
2796 LocationAccessKind::FieldIndex(struct_type_ref.clone(), index),
2797 return_type.clone(),
2798 field_name_node,
2799 );
2800
2801 ty = return_type.clone();
2802 }
2803 swamp_ast::Postfix::SubscriptTuple(x_expr, y_expr) => match &*ty.kind {
2804 TypeKind::GridView(element_type)
2805 | TypeKind::GridStorage(element_type, _, _) => {
2806 let int_type = self.types().int();
2807 let unsigned_int_context = TypeContext::new_argument(&int_type, true);
2808 let unsigned_int_x_expr =
2809 self.analyze_expression(x_expr, &unsigned_int_context);
2810
2811 let unsigned_int_y_expr =
2812 self.analyze_expression(y_expr, &unsigned_int_context);
2813
2814 let grid_type = GridType {
2815 element: element_type.clone(),
2816 };
2817
2818 self.add_location_item(
2819 &mut items,
2820 LocationAccessKind::GridSubscript(
2821 grid_type,
2822 unsigned_int_x_expr,
2823 unsigned_int_y_expr,
2824 ),
2825 element_type.clone(),
2826 &x_expr.node,
2827 );
2828
2829 ty = element_type.clone();
2830 }
2831 _ => panic!("not allowed"),
2832 },
2833 swamp_ast::Postfix::Subscript(ast_key_expression) => {
2834 let underlying = &ty.kind;
2835 match &**underlying {
2836 TypeKind::SliceView(element_type)
2837 | TypeKind::StackStorage(element_type, _)
2838 | TypeKind::StackView(element_type)
2839 | TypeKind::VecStorage(element_type, _)
2840 | TypeKind::DynamicLengthVecView(element_type)
2841 | TypeKind::FixedCapacityAndLengthArray(element_type, _) => {
2842 let int_type = self.types().int();
2843 let unsigned_int_context = TypeContext::new_argument(&int_type, false);
2844 let unsigned_int_expr =
2845 self.analyze_expression(ast_key_expression, &unsigned_int_context);
2846
2847 let slice_type = SliceViewType {
2848 element: element_type.clone(),
2849 };
2850
2851 self.add_location_item(
2852 &mut items,
2853 LocationAccessKind::SliceViewSubscript(
2854 slice_type,
2855 unsigned_int_expr,
2856 ),
2857 element_type.clone(),
2858 &ast_key_expression.node,
2859 );
2860
2861 ty = element_type.clone();
2862 }
2863 TypeKind::SparseView(element_type)
2864 | TypeKind::SparseStorage(element_type, _) => {
2865 let int_type = self.types().int();
2866 let unsigned_int_context = TypeContext::new_argument(&int_type, false);
2867 let unsigned_int_expr =
2868 self.analyze_expression(ast_key_expression, &unsigned_int_context);
2869
2870 let slice_type = SparseType {
2871 element: element_type.clone(),
2872 };
2873
2874 self.add_location_item(
2875 &mut items,
2876 LocationAccessKind::SparseSubscript(slice_type, unsigned_int_expr),
2877 element_type.clone(),
2878 &ast_key_expression.node,
2879 );
2880
2881 ty = element_type.clone();
2882 }
2883 TypeKind::MapStorage(key_type, value_type, ..)
2884 | TypeKind::DynamicLengthMapView(key_type, value_type) => {
2885 let key_index_context = TypeContext::new_argument(key_type, false);
2886 let key_expr =
2887 self.analyze_expression(ast_key_expression, &key_index_context);
2888
2889 let map_like_type = MapType {
2890 key: key_type.clone(),
2891 value: value_type.clone(),
2892 };
2893
2894 match location_side {
2895 LocationSide::Lhs => {
2896 let access_kind = if is_absolute_last_in_chain {
2900 LocationAccessKind::MapSubscriptCreateIfNeeded(
2901 map_like_type,
2902 key_expr,
2903 )
2904 } else {
2905 LocationAccessKind::MapSubscriptMustExist(
2906 map_like_type,
2907 key_expr,
2908 )
2909 };
2910
2911 self.add_location_item(
2912 &mut items,
2913 access_kind,
2914 value_type.clone(),
2915 &ast_key_expression.node,
2916 );
2917 }
2918 LocationSide::Mutable | LocationSide::Rhs => {
2919 self.add_location_item(
2920 &mut items,
2921 LocationAccessKind::MapSubscriptMustExist(
2922 map_like_type,
2923 key_expr,
2924 ),
2925 value_type.clone(),
2926 &ast_key_expression.node,
2927 );
2928 }
2929 }
2930 ty = value_type.clone();
2931 }
2932
2933 _ => {
2934 eprintln!("can not subscript with this type: {underlying}");
2935 todo!()
2936 }
2937 }
2938 }
2939
2940 swamp_ast::Postfix::MemberCall(node, _generic_arguments, _regular_args) => {
2941 return SingleLocationExpression {
2942 kind: MutableReferenceKind::MutVariableRef,
2943 node: self.to_node(node),
2944 ty: self.shared.state.types.unit(),
2945 starting_variable: start_variable,
2946 access_chain: vec![],
2947 };
2948 }
2949 swamp_ast::Postfix::FunctionCall(node, _generic_arguments, _regular_args) => {
2956 return SingleLocationExpression {
2957 kind: MutableReferenceKind::MutVariableRef,
2958 node: self.to_node(node),
2959 ty: self.shared.state.types.unit(),
2960 starting_variable: start_variable,
2961 access_chain: vec![],
2962 };
2963 }
2964 swamp_ast::Postfix::OptionalChainingOperator(node) => {
2965 return SingleLocationExpression {
2966 kind: MutableReferenceKind::MutVariableRef,
2967 node: self.to_node(node),
2968 ty: self.shared.state.types.unit(),
2969 starting_variable: start_variable,
2970 access_chain: vec![],
2971 };
2972 }
2973 swamp_ast::Postfix::NoneCoalescingOperator(expr) => {
2974 return SingleLocationExpression {
2975 kind: MutableReferenceKind::MutVariableRef,
2976 node: self.to_node(&expr.node),
2977 ty: self.shared.state.types.unit(),
2978 starting_variable: start_variable,
2979 access_chain: vec![],
2980 };
2981 }
2982 }
2983 }
2984
2985 if let Some(found_expected_type) = context.expected_type {
2986 if !self.types().compatible_with(found_expected_type, &ty) {
2987 self.add_err(
2988 ErrorKind::IncompatibleTypes {
2989 expected: found_expected_type.clone(),
2990 found: ty.clone(),
2991 },
2992 &chain.base.node,
2993 );
2994 }
2995 }
2996
2997 SingleLocationExpression {
2998 kind: MutableReferenceKind::MutVariableRef,
2999 node: self.to_node(&chain.base.node),
3000 ty,
3001 starting_variable: start_variable,
3002 access_chain: items,
3003 }
3004 }
3005
3006 fn analyze_to_location(
3007 &mut self,
3008 expr: &swamp_ast::Expression,
3009 context: &TypeContext,
3010 location_type: LocationSide,
3011 ) -> SingleLocationExpression {
3012 match &expr.kind {
3013 swamp_ast::ExpressionKind::PostfixChain(chain) => {
3014 self.analyze_chain_to_location(chain, context, location_type)
3015 }
3016 swamp_ast::ExpressionKind::VariableReference(variable) => {
3017 let var = self.find_variable(variable);
3018 if !var.is_mutable() {
3019 self.add_err(ErrorKind::VariableIsNotMutable, &expr.node);
3020 }
3021
3022 SingleLocationExpression {
3023 kind: MutableReferenceKind::MutVariableRef,
3024 node: self.to_node(&variable.name),
3025 ty: var.resolved_type.clone(),
3026 starting_variable: var,
3027 access_chain: vec![],
3028 }
3029 }
3030 swamp_ast::ExpressionKind::IdentifierReference(qualified_identifier) => {
3031 let generated_var = swamp_ast::Variable {
3032 name: qualified_identifier.name.clone(),
3033 is_mutable: None,
3034 };
3035 let var = self.find_variable(&generated_var);
3036 if !var.is_mutable() {
3037 self.add_err(ErrorKind::VariableIsNotMutable, &expr.node);
3038 }
3039 SingleLocationExpression {
3040 kind: MutableReferenceKind::MutVariableRef,
3041 node: self.to_node(&generated_var.name),
3042 ty: var.resolved_type.clone(),
3043 starting_variable: var,
3044 access_chain: vec![],
3045 }
3046 }
3047 _ => {
3048 self.add_err(ErrorKind::NotValidLocationStartingPoint, &expr.node);
3049 let unit_type = self.types().unit();
3050 SingleLocationExpression {
3051 kind: MutableReferenceKind::MutVariableRef,
3052 node: self.to_node(&expr.node),
3053 ty: unit_type.clone(),
3054 starting_variable: Rc::new(Variable {
3055 name: Default::default(),
3056 assigned_name: String::new(),
3057 resolved_type: unit_type,
3058 mutable_node: None,
3059 variable_type: VariableType::Local,
3060 scope_index: 0,
3061 variable_index: 0,
3062 unique_id_within_function: 0,
3063 virtual_register: 0,
3064 is_unused: false,
3065 }),
3066 access_chain: vec![],
3067 }
3068 }
3069 }
3070 }
3071
3072 fn analyze_expression_for_assignment_compound(
3073 &mut self,
3074 target_expression: &swamp_ast::Expression,
3075 ast_source_expression: &swamp_ast::Expression,
3076 ) -> (TargetAssignmentLocation, Expression) {
3077 let any_argument_context = TypeContext::new_anything_argument(true);
3078 let source_expr = self.analyze_expression(ast_source_expression, &any_argument_context);
3079 let source_expr_type_context = TypeContext::new_argument(&source_expr.ty, true);
3080
3081 let resolved_location = TargetAssignmentLocation(self.analyze_to_location(
3082 target_expression,
3083 &source_expr_type_context,
3084 LocationSide::Rhs,
3085 ));
3086
3087 (resolved_location, source_expr)
3088 }
3089
3090 fn analyze_expression_for_assignment_with_target_type(
3117 &mut self,
3118 target_type: &TypeRef,
3119 ast_source_expression: &swamp_ast::Expression,
3120 ) -> Expression {
3121 let base_context = TypeContext::new_argument(target_type, true);
3122 let source_expr = self.analyze_expression(ast_source_expression, &base_context);
3123
3124 let final_expr = if self.types().compatible_with(target_type, &source_expr.ty) {
3125 source_expr
3126 } else {
3127 let source_type = source_expr.ty.clone();
3128 self.types_did_not_match_try_late_coerce_expression(
3129 source_expr,
3130 target_type,
3131 &source_type,
3132 &ast_source_expression.node,
3133 )
3134 };
3135
3136 let assignment_mode = self.check_assignment_mode(true, &final_expr, target_type); self.check_mutable_assignment(assignment_mode, &final_expr.node);
3139
3140 final_expr
3141 }
3142
3143 fn analyze_expression_for_assignment(
3144 &mut self,
3145 ast_target_location_expression: &swamp_ast::Expression,
3146 ast_source_expression: &swamp_ast::Expression,
3147 ) -> (TargetAssignmentLocation, Expression) {
3148 let any_argument_context = TypeContext::new_anything_argument(true);
3149 let resolved_location = self.analyze_to_location(
3150 ast_target_location_expression,
3151 &any_argument_context,
3152 LocationSide::Lhs,
3153 );
3154
3155 let target_type = resolved_location.ty.clone();
3156 let mut_type = target_type; let mut_location = TargetAssignmentLocation(resolved_location);
3158
3159 let final_expr = self
3160 .analyze_expression_for_assignment_with_target_type(&mut_type, ast_source_expression);
3161
3162 (mut_location, final_expr)
3163 }
3164
3165 fn analyze_assignment_compound(
3166 &mut self,
3167 target_expression: &swamp_ast::Expression,
3168 ast_op: &swamp_ast::CompoundOperator,
3169 ast_source_expression: &swamp_ast::Expression,
3170 ) -> Expression {
3171 let resolved_op = self.analyze_compound_operator(ast_op);
3172
3173 let (resolved_location, source_expr) = self
3174 .analyze_expression_for_assignment_compound(target_expression, ast_source_expression);
3175
3176 let kind = ExpressionKind::CompoundAssignment(
3177 resolved_location,
3178 resolved_op.kind,
3179 Box::from(source_expr),
3180 );
3181
3182 let unit_type = self.shared.state.types.unit();
3183
3184 self.create_expr(kind, unit_type, &target_expression.node)
3185 }
3186
3187 fn analyze_assignment_mode(lhs: SingleLocationExpression) {}
3188
3189 fn analyze_assignment(
3190 &mut self,
3191 target_location: &swamp_ast::Expression,
3192 ast_source_expression: &swamp_ast::Expression,
3193 ) -> Expression {
3194 let (mut_location, source_expr) =
3195 self.analyze_expression_for_assignment(target_location, ast_source_expression);
3196 let kind = ExpressionKind::Assignment(Box::from(mut_location), Box::from(source_expr));
3197 let unit_type = self.shared.state.types.unit();
3198
3199 self.create_expr(kind, unit_type, &target_location.node)
3202 }
3203
3204 #[must_use]
3205 pub const fn create_expr(
3206 &self,
3207 kind: ExpressionKind,
3208 ty: TypeRef,
3209 ast_node: &swamp_ast::Node,
3210 ) -> Expression {
3211 Expression {
3213 kind,
3214 ty,
3215 node: self.to_node(ast_node),
3216 }
3217 }
3218
3219 fn analyze_destructuring(
3220 &mut self,
3221 node: &swamp_ast::Node,
3222 target_ast_variables: &[swamp_ast::Variable],
3223 tuple_expression: &swamp_ast::Expression,
3224 ) -> Expression {
3225 let any_context = TypeContext::new_anything_argument(true);
3226 let tuple_resolved = self.analyze_expression(tuple_expression, &any_context);
3227 let tuple_expr_type = &tuple_resolved.ty;
3228 let unit = self.types().unit();
3229
3230 let mut variable_refs = Vec::new();
3231 if let TypeKind::Tuple(tuple) = &*tuple_expr_type.kind {
3232 if target_ast_variables.len() > tuple.len() {
3233 return self.create_err(ErrorKind::TooManyDestructureVariables, node);
3234 }
3235 for (ast_variable, tuple_type) in target_ast_variables.iter().zip(tuple.clone()) {
3236 let variable_ref = self.create_local_variable(
3237 &ast_variable.name,
3238 ast_variable.is_mutable.as_ref(),
3239 &tuple_type,
3240 true,
3241 );
3242 variable_refs.push(variable_ref);
3243 }
3244 let expr_kind = ExpressionKind::TupleDestructuring(
3245 variable_refs,
3246 tuple_expr_type.clone(),
3247 Box::from(tuple_resolved),
3248 );
3249
3250 self.create_expr(expr_kind, unit, node)
3251 } else {
3252 self.create_err(ErrorKind::CanNotDestructure, node)
3253 }
3254 }
3255
3256 fn analyze_normal_member_call(
3257 &mut self,
3258 type_that_member_is_on: &TypeRef,
3259 found_function: &FunctionRef,
3260 generic_arguments: Vec<TypeRef>,
3261 ast_arguments: &[swamp_ast::Expression],
3262 is_mutable: bool,
3263 node: &swamp_ast::Node,
3264 ) -> Signature {
3265 let resolved_node = self.to_node(node);
3266 found_function.signature().clone()
3269 }
3270
3271 fn queue_member_signature(
3272 &mut self,
3273 self_type: &TypeRef,
3274 key_type: Option<&TypeRef>,
3275 element_type: &TypeRef,
3276 field_name_str: &str,
3277 lambda_variable_count: usize,
3278 node: &swamp_ast::Node,
3279 ) -> Option<(IntrinsicFunction, Signature)> {
3280 let self_type_param = TypeForParameter {
3281 name: "self".to_string(),
3282 resolved_type: self_type.clone(),
3283 is_mutable: false,
3284 node: None,
3285 };
3286 let self_mutable_type_param = TypeForParameter {
3287 name: "self".to_string(),
3288 resolved_type: self_type.clone(),
3289 is_mutable: true,
3290 node: None,
3291 };
3292 let intrinsic_and_signature = match field_name_str {
3293 "enqueue" => (
3294 IntrinsicFunction::VecPush,
3295 Signature {
3296 parameters: vec![
3297 self_mutable_type_param,
3298 TypeForParameter {
3299 name: "element".to_string(),
3300 resolved_type: element_type.clone(),
3301 is_mutable: false,
3302 node: None,
3303 },
3304 ],
3305 return_type: self.types().unit(),
3306 },
3307 ),
3308 "dequeue" => (
3309 IntrinsicFunction::VecRemoveFirstIndexGetValue,
3310 Signature {
3311 parameters: vec![self_mutable_type_param],
3312 return_type: element_type.clone(),
3313 },
3314 ),
3315 _ => {
3316 self.slice_member_signature(
3317 self_type,
3318 key_type,
3319 element_type,
3320 field_name_str,
3321 lambda_variable_count,
3322 node,
3323 )
3324 }?,
3325 };
3326
3327 Some(intrinsic_and_signature)
3328 }
3329
3330 fn sparse_member_signature(
3331 &mut self,
3332 self_type: &TypeRef,
3333 element_type: &TypeRef,
3334 field_name_str: &str,
3335 lambda_variable_count: usize,
3336 node: &swamp_ast::Node,
3337 ) -> Option<(IntrinsicFunction, Signature)> {
3338 let key_type = self.types().int(); let self_type_param = TypeForParameter {
3341 name: "self".to_string(),
3342 resolved_type: self_type.clone(),
3343 is_mutable: false,
3344 node: None,
3345 };
3346 let self_mutable_type_param = TypeForParameter {
3347 name: "self".to_string(),
3348 resolved_type: self_type.clone(),
3349 is_mutable: true,
3350 node: None,
3351 };
3352 let intrinsic_and_signature = match field_name_str {
3353 "add" => (
3354 IntrinsicFunction::SparseAdd,
3355 Signature {
3356 parameters: vec![
3357 self_mutable_type_param,
3358 TypeForParameter {
3359 name: "element".to_string(),
3360 resolved_type: element_type.clone(),
3361 is_mutable: false,
3362 node: None,
3363 },
3364 ],
3365 return_type: self.types().int(),
3366 },
3367 ),
3368 "remove" => (
3369 IntrinsicFunction::SparseRemove,
3370 Signature {
3371 parameters: vec![
3372 self_mutable_type_param,
3373 TypeForParameter {
3374 name: "key".to_string(),
3375 resolved_type: key_type,
3376 is_mutable: false,
3377 node: None,
3378 },
3379 ],
3380 return_type: self.types().unit(),
3381 },
3382 ),
3383 "is_alive" => (
3384 IntrinsicFunction::SparseIsAlive,
3385 Signature {
3386 parameters: vec![
3387 self_type_param,
3388 TypeForParameter {
3389 name: "element".to_string(),
3390 resolved_type: element_type.clone(),
3391 is_mutable: false,
3392 node: None,
3393 },
3394 ],
3395 return_type: self.types().bool(),
3396 },
3397 ),
3398
3399 _ => {
3400 self.slice_member_signature(
3401 self_type,
3402 Option::from(key_type).as_ref(),
3403 element_type,
3404 field_name_str,
3405 lambda_variable_count,
3406 node,
3407 )
3408 }?,
3409 };
3410 Some(intrinsic_and_signature)
3411 }
3412
3413 fn vec_member_signature(
3414 &mut self,
3415 self_type: &TypeRef,
3416 element_type: &TypeRef,
3417 field_name_str: &str,
3418 lambda_variable_count: usize,
3419 node: &swamp_ast::Node,
3420 ) -> Option<(IntrinsicFunction, Signature)> {
3421 let key_type = self.types().int();
3422 let self_type_param = TypeForParameter {
3423 name: "self".to_string(),
3424 resolved_type: self_type.clone(),
3425 is_mutable: false,
3426 node: None,
3427 };
3428 let self_mutable_type_param = TypeForParameter {
3429 name: "self".to_string(),
3430 resolved_type: self_type.clone(),
3431 is_mutable: true,
3432 node: None,
3433 };
3434 let intrinsic_and_signature = match field_name_str {
3435 "prepend" => (
3436 IntrinsicFunction::VecPush,
3437 Signature {
3438 parameters: vec![
3439 self_mutable_type_param,
3440 TypeForParameter {
3441 name: "element".to_string(),
3442 resolved_type: element_type.clone(),
3443 is_mutable: false,
3444 node: None,
3445 },
3446 ],
3447 return_type: self.types().unit(),
3448 },
3449 ),
3450 "push" => (
3451 IntrinsicFunction::VecPush,
3452 Signature {
3453 parameters: vec![
3454 self_mutable_type_param,
3455 TypeForParameter {
3456 name: "element".to_string(),
3457 resolved_type: element_type.clone(),
3458 is_mutable: false,
3459 node: None,
3460 },
3461 ],
3462 return_type: self.types().unit(),
3463 },
3464 ),
3465 "pop" => (
3466 IntrinsicFunction::VecPop,
3467 Signature {
3468 parameters: vec![self_mutable_type_param],
3469 return_type: element_type.clone(),
3470 },
3471 ),
3472
3473 _ => {
3474 self.slice_member_signature(
3475 self_type,
3476 Option::from(key_type).as_ref(),
3477 element_type,
3478 field_name_str,
3479 lambda_variable_count,
3480 node,
3481 )
3482 }?,
3483 };
3484 Some(intrinsic_and_signature)
3485 }
3486
3487 #[allow(clippy::unnecessary_wraps)]
3488 fn grid_member_signature(
3489 &mut self,
3490 self_type: &TypeRef,
3491 element_type: &TypeRef,
3492 field_name_str: &str,
3493 node: &swamp_ast::Node,
3494 ) -> Option<(IntrinsicFunction, Signature)> {
3495 let self_type_param = TypeForParameter {
3496 name: "self".to_string(),
3497 resolved_type: self_type.clone(),
3498 is_mutable: false,
3499 node: None,
3500 };
3501 let self_mutable_type_param = TypeForParameter {
3502 name: "self".to_string(),
3503 resolved_type: self_type.clone(),
3504 is_mutable: true,
3505 node: None,
3506 };
3507 let element_param = TypeForParameter {
3508 name: "element".to_string(),
3509 resolved_type: element_type.clone(),
3510 is_mutable: false,
3511 node: None,
3512 };
3513 let int_type = self.types().int();
3514
3515 let int_param = TypeForParameter {
3516 name: "x_or_y".to_string(),
3517 resolved_type: int_type.clone(),
3518 is_mutable: false,
3519 node: None,
3520 };
3521 let intrinsic_and_signature = match field_name_str {
3522 "set" => (
3523 IntrinsicFunction::GridSet,
3524 Signature {
3525 parameters: vec![self_type_param, int_param.clone(), int_param, element_param],
3526 return_type: self.types().unit(),
3527 },
3528 ),
3529
3530 "get" => (
3531 IntrinsicFunction::GridGet,
3532 Signature {
3533 parameters: vec![self_type_param, int_param.clone(), int_param],
3534 return_type: element_type.clone(),
3535 },
3536 ),
3537
3538 "width" => (
3539 IntrinsicFunction::GridWidth,
3540 Signature {
3541 parameters: vec![self_type_param],
3542 return_type: int_type,
3543 },
3544 ),
3545
3546 "height" => (
3547 IntrinsicFunction::GridHeight,
3548 Signature {
3549 parameters: vec![self_type_param],
3550 return_type: int_type,
3551 },
3552 ),
3553
3554 _ => panic!("unknown grid method {field_name_str}"),
3555 };
3556
3557 Some(intrinsic_and_signature)
3558 }
3559
3560 fn basic_collection_member_signature(
3561 &mut self,
3562 self_type: &TypeRef,
3563 field_name_str: &str,
3564 node: &swamp_ast::Node,
3565 ) -> Option<(IntrinsicFunction, Signature)> {
3566 let self_type_param = TypeForParameter {
3567 name: "self".to_string(),
3568 resolved_type: self_type.clone(),
3569 is_mutable: false,
3570 node: None,
3571 };
3572 let self_mut_type_param = TypeForParameter {
3573 name: "self".to_string(),
3574 resolved_type: self_type.clone(),
3575 is_mutable: true,
3576 node: None,
3577 };
3578 let intrinsic_and_signature = match field_name_str {
3579 "len" => {
3580 let signature = Signature {
3581 parameters: vec![self_type_param],
3582 return_type: self.types().int(),
3583 };
3584 (IntrinsicFunction::VecLen, signature)
3585 }
3586 "is_empty" => (
3587 IntrinsicFunction::VecIsEmpty,
3588 Signature {
3589 parameters: vec![self_type_param],
3590 return_type: self.types().bool(),
3591 },
3592 ),
3593 "capacity" => {
3594 let signature = Signature {
3595 parameters: vec![self_type_param],
3596 return_type: self.types().int(),
3597 };
3598 (IntrinsicFunction::VecCapacity, signature)
3599 }
3600 _ => {
3601 self.add_err(ErrorKind::UnknownMemberFunction(self_type.clone()), node);
3602
3603 return None;
3604 }
3605 };
3606 Some(intrinsic_and_signature)
3607 }
3608 #[allow(clippy::too_many_lines)]
3609 fn codepoint_member_signature(
3610 &mut self,
3611 self_type: &TypeRef,
3612 key_type: Option<&TypeRef>,
3613 element_type: &TypeRef,
3614 field_name_str: &str,
3615 lambda_variable_count: usize,
3616 node: &swamp_ast::Node,
3617 ) -> Option<(IntrinsicFunction, Signature)> {
3618 let self_type_param = TypeForParameter {
3619 name: "self".to_string(),
3620 resolved_type: self_type.clone(),
3621 is_mutable: false,
3622 node: None,
3623 };
3624
3625 match field_name_str {
3626 "to_int" => Some((
3627 IntrinsicFunction::CodepointToInt,
3628 Signature {
3629 parameters: vec![self_type_param],
3630 return_type: self.types().int(),
3631 },
3632 )),
3633 _ => None,
3634 }
3635 }
3636
3637 #[allow(clippy::too_many_lines)]
3638 fn byte_member_signature(
3639 &mut self,
3640 self_type: &TypeRef,
3641 key_type: Option<&TypeRef>,
3642 element_type: &TypeRef,
3643 field_name_str: &str,
3644 lambda_variable_count: usize,
3645 node: &swamp_ast::Node,
3646 ) -> Option<(IntrinsicFunction, Signature)> {
3647 let self_type_param = TypeForParameter {
3648 name: "self".to_string(),
3649 resolved_type: self_type.clone(),
3650 is_mutable: false,
3651 node: None,
3652 };
3653
3654 match field_name_str {
3655 "to_int" => Some((
3656 IntrinsicFunction::ByteToInt,
3657 Signature {
3658 parameters: vec![self_type_param],
3659 return_type: self.types().int(),
3660 },
3661 )),
3662 _ => None,
3663 }
3664 }
3665
3666 #[allow(clippy::too_many_lines)]
3667 fn string_member_signature(
3668 &mut self,
3669 self_type: &TypeRef,
3670 key_type: Option<&TypeRef>,
3671 element_type: &TypeRef,
3672 field_name_str: &str,
3673 lambda_variable_count: usize,
3674 node: &swamp_ast::Node,
3675 ) -> Option<(IntrinsicFunction, Signature)> {
3676 self.vec_member_signature(
3677 self_type,
3678 element_type,
3679 field_name_str,
3680 lambda_variable_count,
3681 node,
3682 )
3683 }
3684
3685 #[allow(clippy::too_many_lines)]
3686 fn slice_member_signature(
3687 &mut self,
3688 self_type: &TypeRef,
3689 key_type: Option<&TypeRef>,
3690 element_type: &TypeRef,
3691 field_name_str: &str,
3692 lambda_variable_count: usize,
3693 node: &swamp_ast::Node,
3694 ) -> Option<(IntrinsicFunction, Signature)> {
3695 let slice_view_type = self.types().slice_view(&element_type.clone());
3696 let int_type = self.types().int();
3697 let self_type_param = TypeForParameter {
3698 name: "self".to_string(),
3699 resolved_type: slice_view_type.clone(),
3700 is_mutable: false,
3701 node: None,
3702 };
3703 let self_mut_type_param = TypeForParameter {
3704 name: "self".to_string(),
3705 resolved_type: slice_view_type,
3706 is_mutable: true,
3707 node: None,
3708 };
3709 let intrinsic_and_signature = match field_name_str {
3710 "for" => {
3711 let parameters = if lambda_variable_count == 2 {
3712 vec![
3713 TypeForParameter {
3714 name: "key".to_string(),
3715 resolved_type: key_type.unwrap().clone(),
3716 is_mutable: false,
3717 node: None,
3718 },
3719 TypeForParameter {
3720 name: "element".to_string(),
3721 resolved_type: element_type.clone(),
3722 is_mutable: false,
3723 node: None,
3724 },
3725 ]
3726 } else {
3727 vec![TypeForParameter {
3728 name: "element".to_string(),
3729 resolved_type: element_type.clone(),
3730 is_mutable: false,
3731 node: None,
3732 }]
3733 };
3734 let lambda_signature = Signature {
3735 parameters,
3736 return_type: self.types().unit(),
3737 };
3738 let lambda_function_type = self.types().function(lambda_signature);
3739 (
3740 IntrinsicFunction::TransformerFor,
3741 Signature {
3742 parameters: vec![
3743 self_type_param,
3744 TypeForParameter {
3745 name: "lambda".to_string(),
3746 resolved_type: lambda_function_type,
3747 is_mutable: false,
3748 node: None,
3749 },
3750 ],
3751 return_type: self.types().unit(), },
3753 )
3754 }
3755 "while" => {
3756 let parameters = if lambda_variable_count == 2 {
3757 vec![
3758 TypeForParameter {
3759 name: "key".to_string(),
3760 resolved_type: key_type.unwrap().clone(),
3761 is_mutable: false,
3762 node: None,
3763 },
3764 TypeForParameter {
3765 name: "element".to_string(),
3766 resolved_type: element_type.clone(),
3767 is_mutable: false,
3768 node: None,
3769 },
3770 ]
3771 } else {
3772 vec![TypeForParameter {
3773 name: "element".to_string(),
3774 resolved_type: element_type.clone(),
3775 is_mutable: false,
3776 node: None,
3777 }]
3778 };
3779 let lambda_signature = Signature {
3780 parameters,
3781 return_type: self.types().bool(), };
3783 let lambda_function_type = self.types().function(lambda_signature);
3784 (
3785 IntrinsicFunction::TransformerWhile,
3786 Signature {
3787 parameters: vec![
3788 self_type_param,
3789 TypeForParameter {
3790 name: "lambda".to_string(),
3791 resolved_type: lambda_function_type,
3792 is_mutable: false,
3793 node: None,
3794 },
3795 ],
3796 return_type: self.types().unit(), },
3798 )
3799 }
3800 "filter" => {
3801 let lambda_signature = Signature {
3802 parameters: vec![TypeForParameter {
3803 name: "element".to_string(),
3804 resolved_type: element_type.clone(),
3805 is_mutable: false,
3806 node: None,
3807 }],
3808 return_type: self.types().bool(),
3809 };
3810 let lambda_function_type = self.types().function(lambda_signature);
3811 (
3812 IntrinsicFunction::TransformerFilter,
3813 Signature {
3814 parameters: vec![
3815 self_type_param,
3816 TypeForParameter {
3817 name: "lambda".to_string(),
3818 resolved_type: lambda_function_type,
3819 is_mutable: false,
3820 node: None,
3821 },
3822 ],
3823 return_type: self.shared.state.types.slice_view(&element_type.clone()),
3824 },
3825 )
3826 }
3827 "find" => {
3828 let lambda_signature = Signature {
3829 parameters: vec![TypeForParameter {
3830 name: "element".to_string(),
3831 resolved_type: element_type.clone(),
3832 is_mutable: false,
3833 node: None,
3834 }],
3835 return_type: self.types().bool(),
3836 };
3837 let lambda_function_type = self.types().function(lambda_signature);
3838 (
3839 IntrinsicFunction::TransformerFind,
3840 Signature {
3841 parameters: vec![
3842 self_type_param,
3843 TypeForParameter {
3844 name: "lambda".to_string(),
3845 resolved_type: lambda_function_type,
3846 is_mutable: false,
3847 node: None,
3848 },
3849 ],
3850 return_type: self.shared.state.types.optional(&element_type.clone()),
3851 },
3852 )
3853 }
3854
3855 "remove" => {
3856 let signature = Signature {
3857 parameters: vec![
3858 self_mut_type_param,
3859 TypeForParameter {
3860 name: "index".to_string(),
3861 resolved_type: int_type,
3862 is_mutable: false,
3863 node: None,
3864 },
3865 ],
3866 return_type: self.types().unit(),
3867 };
3868 (IntrinsicFunction::VecRemoveIndex, signature)
3869 }
3870 _ => return self.basic_collection_member_signature(self_type, field_name_str, node),
3871 };
3872 Some(intrinsic_and_signature)
3873 }
3874
3875 #[allow(clippy::unnecessary_wraps, clippy::result_large_err)]
3876 fn map_member_signature(
3877 &mut self,
3878 self_type: &TypeRef,
3879 key_type: &TypeRef,
3880 value_type: &TypeRef,
3881 field_name_str: &str,
3882 node: &swamp_ast::Node,
3883 ) -> Option<(IntrinsicFunction, Signature)> {
3884 let self_type_param = TypeForParameter {
3885 name: "self".to_string(),
3886 resolved_type: self_type.clone(),
3887 is_mutable: false,
3888 node: None,
3889 };
3890
3891 let mutable_self_type_param = TypeForParameter {
3892 name: "self".to_string(),
3893 resolved_type: self_type.clone(),
3894 is_mutable: true,
3895 node: None,
3896 };
3897
3898 let intrinsic_and_signature = match field_name_str {
3899 "has" => (
3900 IntrinsicFunction::MapHas,
3901 Signature {
3902 parameters: vec![
3903 self_type_param,
3904 TypeForParameter {
3905 name: "key".to_string(),
3906 resolved_type: key_type.clone(),
3907 is_mutable: false,
3908 node: None,
3909 },
3910 ],
3911 return_type: self.types().bool(),
3912 },
3913 ),
3914 "remove" => (
3915 IntrinsicFunction::MapRemove,
3916 Signature {
3917 parameters: vec![
3918 mutable_self_type_param,
3919 TypeForParameter {
3920 name: "key".to_string(),
3921 resolved_type: key_type.clone(),
3922 is_mutable: false,
3923 node: None,
3924 },
3925 ],
3926 return_type: self.types().unit(),
3927 },
3928 ),
3929 "len" => (
3930 IntrinsicFunction::MapLen,
3931 Signature {
3932 parameters: vec![self_type_param],
3933 return_type: self.types().int(),
3934 },
3935 ),
3936 "capacity" => (
3937 IntrinsicFunction::MapCapacity,
3938 Signature {
3939 parameters: vec![self_type_param],
3940 return_type: self.types().int(),
3941 },
3942 ),
3943 "is_empty" => (
3944 IntrinsicFunction::MapIsEmpty,
3945 Signature {
3946 parameters: vec![self_type_param],
3947 return_type: self.types().bool(),
3948 },
3949 ),
3950 _ => todo!("unknown map member"),
3951 };
3952
3953 Some(intrinsic_and_signature)
3954 }
3955
3956 fn check_intrinsic_member_signature(
3957 &mut self,
3958 type_that_member_is_on: &TypeRef,
3959 field_name_str: &str,
3960 lambda_variables_count: usize,
3961 node: &swamp_ast::Node,
3962 ) -> Option<(IntrinsicFunction, Signature)> {
3963 let ty = type_that_member_is_on;
3964 let int_type = self.types().int();
3965 match &*ty.kind {
3966 TypeKind::GridStorage(element_type, ..) | TypeKind::GridView(element_type) => self
3967 .grid_member_signature(type_that_member_is_on, element_type, field_name_str, node),
3968 TypeKind::SparseStorage(element_type, ..) | TypeKind::SparseView(element_type) => self
3969 .sparse_member_signature(
3970 type_that_member_is_on,
3971 element_type,
3972 field_name_str,
3973 lambda_variables_count,
3974 node,
3975 ),
3976 TypeKind::QueueStorage(element_type, ..) => self.queue_member_signature(
3977 type_that_member_is_on,
3978 None,
3979 element_type,
3980 field_name_str,
3981 lambda_variables_count,
3982 node,
3983 ),
3984 TypeKind::StackStorage(element_type, ..)
3985 | TypeKind::QueueStorage(element_type, ..)
3986 | TypeKind::VecStorage(element_type, ..)
3987 | TypeKind::DynamicLengthVecView(element_type) => self.vec_member_signature(
3988 type_that_member_is_on,
3989 element_type,
3990 field_name_str,
3991 lambda_variables_count,
3992 node,
3993 ),
3994 TypeKind::SliceView(element_type) => self.slice_member_signature(
3995 type_that_member_is_on,
3996 Some(&int_type),
3997 element_type,
3998 field_name_str,
3999 lambda_variables_count,
4000 node,
4001 ),
4002 TypeKind::Byte => {
4003 let element_type = self.shared.state.types.byte();
4004 self.byte_member_signature(
4005 type_that_member_is_on,
4006 Some(&int_type),
4007 &element_type,
4008 field_name_str,
4009 lambda_variables_count,
4010 node,
4011 )
4012 }
4013 TypeKind::Codepoint => {
4014 let element_type = self.shared.state.types.codepoint();
4015 self.codepoint_member_signature(
4016 type_that_member_is_on,
4017 Some(&int_type),
4018 &element_type,
4019 field_name_str,
4020 lambda_variables_count,
4021 node,
4022 )
4023 }
4024 TypeKind::String { .. } | TypeKind::StringStorage(..) => {
4025 let element_type = self.shared.state.types.byte();
4026 self.string_member_signature(
4027 type_that_member_is_on,
4028 Some(&int_type),
4029 &element_type,
4030 field_name_str,
4031 lambda_variables_count,
4032 node,
4033 )
4034 }
4035 TypeKind::DynamicLengthMapView(key, value) | TypeKind::MapStorage(key, value, _) => {
4036 self.map_member_signature(type_that_member_is_on, key, value, field_name_str, node)
4037 }
4038
4039 TypeKind::FixedCapacityAndLengthArray(element_type, _) => self.slice_member_signature(
4040 type_that_member_is_on,
4041 Some(&int_type),
4042 element_type,
4043 field_name_str,
4044 lambda_variables_count,
4045 node,
4046 ),
4047 _ => {
4048 self.add_err(
4049 ErrorKind::UnknownMemberFunction(type_that_member_is_on.clone()),
4050 node,
4051 );
4052
4053 None
4054 }
4055 }
4056 }
4057
4058 fn analyze_member_call(
4059 &mut self,
4060 type_that_member_is_on: &TypeRef,
4061 field_name_str: &str,
4062 ast_maybe_generic_arguments: Option<Vec<swamp_ast::GenericParameter>>,
4063 ast_arguments: &[swamp_ast::Expression],
4064 chain_self_is_mutable: bool,
4065 node: &swamp_ast::Node,
4066 ) -> (PostfixKind, TypeRef) {
4067 let generic_arguments = if let Some(ast_generic_arguments) = ast_maybe_generic_arguments {
4068 let mut resolved_types = Vec::new();
4069 for ast_type in ast_generic_arguments {
4070 resolved_types.push(self.analyze_type(ast_type.get_type()));
4071 }
4072 resolved_types
4073 } else {
4074 vec![]
4075 };
4076
4077 let maybe_function = self
4078 .shared
4079 .state
4080 .associated_impls
4081 .get_member_function(type_that_member_is_on, field_name_str)
4082 .cloned();
4083
4084 let (function_ref, instantiated_signature) = if let Some(found_function) = maybe_function {
4085 let signature = self.analyze_normal_member_call(
4086 type_that_member_is_on,
4087 &found_function,
4088 generic_arguments,
4089 ast_arguments,
4090 chain_self_is_mutable,
4091 node,
4092 );
4093 (found_function, signature)
4094 } else {
4095 let lambda_variables_count = if ast_arguments.is_empty() {
4096 0
4097 } else if let swamp_ast::ExpressionKind::Lambda(variables, ..) = &ast_arguments[0].kind
4098 {
4099 variables.len()
4100 } else {
4101 0
4102 };
4103 let Some((intrinsic_fn, signature)) = self.check_intrinsic_member_signature(
4104 type_that_member_is_on,
4105 field_name_str,
4106 lambda_variables_count,
4107 node,
4108 ) else {
4109 return (PostfixKind::OptionalChainingOperator, self.types().unit());
4110 };
4111 let def = IntrinsicFunctionDefinition {
4112 name: field_name_str.to_string(),
4113 signature,
4114 intrinsic: intrinsic_fn,
4115 };
4116 let function_ref = FunctionRef::from(Function::Intrinsic(
4117 IntrinsicFunctionDefinitionRef::from(def.clone()),
4118 ));
4119 (function_ref, def.signature)
4120 };
4121
4122 let self_type_in_signature = &instantiated_signature.parameters[0];
4123
4124 if self_type_in_signature.is_mutable && !chain_self_is_mutable {
4125 self.add_err(ErrorKind::SelfNotCorrectMutableState, node);
4126 }
4127
4128 let resolved_arguments = self.analyze_and_verify_parameters(
4129 node,
4130 &instantiated_signature.parameters[1..],
4131 ast_arguments,
4132 );
4133
4134 (
4135 PostfixKind::MemberCall(function_ref, resolved_arguments),
4136 TypeRef::from(instantiated_signature.return_type.clone()),
4137 )
4138 }
4139
4140 fn analyze_postfix_member_call(
4141 &mut self,
4142 type_that_member_is_on: &TypeRef,
4143 is_mutable: bool,
4144 member_name: &swamp_ast::Node,
4145 ast_maybe_generic_arguments: Option<Vec<swamp_ast::GenericParameter>>,
4146 ast_arguments: &[swamp_ast::Expression],
4147 suffixes: &mut Vec<Postfix>,
4148 ) -> TypeRef {
4149 let field_name_str = self.get_text(member_name).to_string();
4150
4151 let resolved_node = self.to_node(member_name);
4152
4153 let (kind, return_type) = self.analyze_member_call(
4154 type_that_member_is_on,
4155 &field_name_str,
4156 ast_maybe_generic_arguments,
4157 ast_arguments,
4158 is_mutable,
4159 member_name,
4160 );
4161 let postfix = Postfix {
4162 node: resolved_node,
4163 ty: return_type,
4164 kind,
4165 };
4166
4167 let last_type = postfix.ty.clone();
4168 suffixes.push(postfix);
4169
4170 last_type
4171 }
4172
4173 fn is_compatible_initializer_list_target(
4174 &mut self,
4175 target_type: &TypeRef,
4176 initializer_element_type: &TypeRef,
4177 ) -> bool {
4178 match &*target_type.kind {
4179 TypeKind::VecStorage(vec_element_type, _vec_capacity) => self
4180 .types()
4181 .compatible_with(vec_element_type, initializer_element_type),
4182 TypeKind::FixedCapacityAndLengthArray(array_element_type, _array_capacity) => self
4183 .types()
4184 .compatible_with(array_element_type, initializer_element_type),
4185 _ => false,
4186 }
4187 }
4188
4189 fn is_compatible_initializer_pair_list_target(
4190 &mut self,
4191 target_type: &TypeRef,
4192 initializer_key_type: &TypeRef,
4193 initializer_value_type: &TypeRef,
4194 ) -> bool {
4195 match &*target_type.kind {
4196 TypeKind::MapStorage(storage_key, storage_value, _) => {
4197 self.types()
4198 .compatible_with(initializer_key_type, storage_key)
4199 && self
4200 .types()
4201 .compatible_with(initializer_value_type, storage_value)
4202 }
4203 _ => false,
4204 }
4205 }
4206
4207 fn types_did_not_match_try_late_coerce_expression(
4208 &mut self,
4209 expr: Expression,
4210 special_expected_type: &TypeRef,
4211 special_encountered_type: &TypeRef,
4212 node: &swamp_ast::Node,
4213 ) -> Expression {
4214 let expected_type = special_expected_type;
4215 let encountered_type = special_encountered_type;
4216 let encountered_is_optional = matches!(&*encountered_type.kind, TypeKind::Optional(_));
4217 if let TypeKind::Optional(expected_inner_type) = &*expected_type.kind {
4218 let inner_is_also_optional =
4219 matches!(&*expected_inner_type.kind, TypeKind::Optional(_));
4220 assert!(!inner_is_also_optional);
4223
4224 if !encountered_is_optional {
4227 if self
4229 .types()
4230 .compatible_with(expected_inner_type, encountered_type)
4231 {
4232 let wrapped = self.create_expr(
4234 ExpressionKind::Option(Option::from(Box::new(expr))),
4235 expected_type.clone(),
4236 node,
4237 );
4238 return wrapped;
4239 }
4240 }
4241 }
4242
4243 if matches!(&*expected_type.kind, &TypeKind::Bool) {
4244 if encountered_is_optional {
4246 let bool_type = self.types().bool();
4247 let wrapped = self.create_expr(
4248 ExpressionKind::CoerceOptionToBool(Box::from(expr)),
4249 bool_type,
4250 node,
4251 );
4252 return wrapped;
4253 }
4254 }
4255
4256 if matches!(
4257 (&*expected_type.kind, &*encountered_type.kind),
4258 (TypeKind::Codepoint, TypeKind::Int)
4259 ) {
4260 let coerced = self.create_expr(
4261 ExpressionKind::CoerceIntToChar(Box::new(expr)),
4262 expected_type.clone(),
4263 node,
4264 );
4265 return coerced;
4266 }
4267
4268 error!(?expected_type, ?encountered_type, "incompatible");
4269 self.create_err(
4270 ErrorKind::IncompatibleTypes {
4271 expected: expected_type.clone(),
4272 found: encountered_type.clone(),
4273 },
4274 node,
4275 )
4276 }
4277
4278 #[must_use]
4279 pub fn analyze_generic_parameter_usize(&self, generic_parameter: &GenericParameter) -> usize {
4280 let usize_node = generic_parameter.get_unsigned_int_node();
4281 let usize_str = self.get_text(usize_node);
4282 Self::str_to_unsigned_int(usize_str).unwrap() as usize
4283 }
4284
4285 #[must_use]
4286 pub fn analyze_generic_parameter_usize_tuple(
4287 &self,
4288 generic_parameter: &GenericParameter,
4289 ) -> (usize, usize) {
4290 let (first, second) = generic_parameter.get_unsigned_int_tuple_nodes();
4291 let first_str = self.get_text(first);
4292 let second_str = self.get_text(second);
4293 let first_value = Self::str_to_unsigned_int(first_str).unwrap() as usize;
4294 let second_value = Self::str_to_unsigned_int(second_str).unwrap() as usize;
4295
4296 (first_value, second_value)
4297 }
4298
4299 pub fn analyze_special_named_type(
4300 &mut self,
4301 path: &[String],
4302 name: &str,
4303 ast_generic_parameters: &[GenericParameter],
4304 ) -> Option<TypeRef> {
4305 let converted_type = match name {
4306 "String" => {
4307 if ast_generic_parameters.len() == 1 {
4308 let fixed_size =
4309 self.analyze_generic_parameter_usize(&ast_generic_parameters[0]);
4310 let new_type = self.shared.state.types.string_storage(fixed_size);
4311 let default_node = swamp_ast::Node::default();
4312 self.add_default_functions(&new_type, &default_node);
4313 new_type
4314 } else {
4315 return None;
4316 }
4317 }
4318 "Vec" => {
4319 if ast_generic_parameters.len() == 1 {
4320 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4321 let vec_type = self.shared.state.types.dynamic_vec_view(&element_type);
4322 let default_node = swamp_ast::Node::default();
4324 self.add_default_functions(&vec_type, &default_node);
4325 vec_type
4326 } else if ast_generic_parameters.len() == 2 {
4327 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4328 let fixed_size =
4329 self.analyze_generic_parameter_usize(&ast_generic_parameters[1]);
4330 let vec_storage_type = self
4331 .shared
4332 .state
4333 .types
4334 .vec_storage(&element_type, fixed_size);
4335 let default_node = swamp_ast::Node::default();
4337 self.add_default_functions(&vec_storage_type, &default_node);
4338 vec_storage_type
4339 } else {
4340 panic!("todo: make this into an error")
4341 }
4342 }
4343 "Stack" => {
4344 if ast_generic_parameters.len() == 1 {
4345 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4346 let stack_view_type = self.shared.state.types.stack_view(&element_type);
4347 let default_node = swamp_ast::Node::default();
4349 self.add_default_functions(&stack_view_type, &default_node);
4350 stack_view_type
4351 } else if ast_generic_parameters.len() == 2 {
4352 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4353 let fixed_size =
4354 self.analyze_generic_parameter_usize(&ast_generic_parameters[1]);
4355 let stack_storage_type = self
4356 .shared
4357 .state
4358 .types
4359 .stack_storage(&element_type, fixed_size);
4360 let default_node = swamp_ast::Node::default();
4362 self.add_default_functions(&stack_storage_type, &default_node);
4363 stack_storage_type
4364 } else {
4365 panic!("todo: make this into an error")
4366 }
4367 }
4368 "Queue" => {
4369 if ast_generic_parameters.len() == 1 {
4370 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4371 let queue_view_type = self.shared.state.types.queue_view(&element_type);
4372 let default_node = swamp_ast::Node::default();
4374 self.add_default_functions(&queue_view_type, &default_node);
4375 queue_view_type
4376 } else if ast_generic_parameters.len() == 2 {
4377 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4378 let fixed_size =
4379 self.analyze_generic_parameter_usize(&ast_generic_parameters[1]);
4380 let queue_storage_type = self
4381 .shared
4382 .state
4383 .types
4384 .queue_storage(&element_type, fixed_size);
4385 let default_node = swamp_ast::Node::default();
4387 self.add_default_functions(&queue_storage_type, &default_node);
4388 queue_storage_type
4389 } else {
4390 panic!("todo: make this into an error")
4391 }
4392 }
4393 "Sparse" => {
4394 if ast_generic_parameters.len() == 1 {
4395 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4396 let sparse_view_type = self.shared.state.types.sparse_view(&element_type);
4397 let default_node = swamp_ast::Node::default();
4399 self.add_default_functions(&sparse_view_type, &default_node);
4400 sparse_view_type
4401 } else if ast_generic_parameters.len() == 2 {
4402 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4403 let fixed_size =
4404 self.analyze_generic_parameter_usize(&ast_generic_parameters[1]);
4405 let sparse_storage_type = self
4406 .shared
4407 .state
4408 .types
4409 .sparse_storage(&element_type, fixed_size);
4410 let default_node = swamp_ast::Node::default();
4412 self.add_default_functions(&sparse_storage_type, &default_node);
4413 sparse_storage_type
4414 } else {
4415 panic!("todo: make this into an error")
4416 }
4417 }
4418
4419 "Grid" => {
4420 if ast_generic_parameters.len() == 1 {
4421 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4422 let grid_view_type = self.shared.state.types.grid_view(&element_type);
4423 let default_node = swamp_ast::Node::default();
4425 self.add_default_functions(&grid_view_type, &default_node);
4426 grid_view_type
4427 } else if ast_generic_parameters.len() == 2 {
4428 let element_type = self.analyze_type(ast_generic_parameters[0].get_type());
4429 let (width, height) =
4430 self.analyze_generic_parameter_usize_tuple(&ast_generic_parameters[1]);
4431 let grid_storage_type =
4432 self.shared
4433 .state
4434 .types
4435 .grid_storage(&element_type, width, height);
4436 let default_node = swamp_ast::Node::default();
4438 self.add_default_functions(&grid_storage_type, &default_node);
4439 grid_storage_type
4440 } else {
4441 panic!("todo: make this into an error")
4442 }
4443 }
4444
4445 _ => return None,
4446 };
4447
4448 Some(converted_type)
4449 }
4450
4451 fn special_static_member(
4452 &self,
4453 type_identifier: &QualifiedTypeIdentifier,
4454 member_name_node: &swamp_ast::Node,
4455 ) -> Option<Function> {
4456 if type_identifier.generic_params.is_empty() {
4457 return None;
4458 }
4459
4460 if type_identifier.module_path.is_some() {
4461 return None;
4462 }
4463
4464 let member_name = self.get_text(member_name_node);
4465 let name = self.get_text(&type_identifier.name.0);
4466
4467 match name {
4468 "Stack" => None,
4469 _ => None,
4470 }
4471 }
4472}