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