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