1use crate::call_type::CallType;
2use crate::inferred_type::DefaultType;
3use crate::parser::block::block;
4use crate::parser::type_name::TypeName;
5use crate::rib_source_span::SourceSpan;
6use crate::rib_type_error::RibTypeErrorInternal;
7use crate::type_inference as ti;
8use crate::wit_type::WitType;
9use crate::{
10 from_string, text, type_checker, type_inference, ComponentDependency, ComponentDependencyKey,
11 CustomInstanceSpec, DynamicParsedFunctionName, GlobalVariableTypeSpec, InferredType,
12 InstanceIdentifier, VariableId,
13};
14use crate::{IntoValueAndType, ValueAndType};
15use bigdecimal::{BigDecimal, ToPrimitive};
16use combine::parser::char::spaces;
17use combine::stream::position;
18use combine::Parser;
19use combine::{eof, EasyParser};
20use serde::{Deserialize, Serialize, Serializer};
21use serde_json::Value;
22use std::collections::VecDeque;
23use std::fmt::Display;
24use std::ops::Deref;
25use std::sync::Arc;
26
27#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
28pub enum Expr {
29 Let {
30 variable_id: VariableId,
31 type_annotation: Option<TypeName>,
32 expr: Box<Expr>,
33 inferred_type: InferredType,
34 source_span: SourceSpan,
35 },
36 SelectField {
37 expr: Box<Expr>,
38 field: String,
39 type_annotation: Option<TypeName>,
40 inferred_type: InferredType,
41 source_span: SourceSpan,
42 },
43 SelectIndex {
44 expr: Box<Expr>,
45 index: Box<Expr>,
46 type_annotation: Option<TypeName>,
47 inferred_type: InferredType,
48 source_span: SourceSpan,
49 },
50 Sequence {
51 exprs: Vec<Expr>,
52 type_annotation: Option<TypeName>,
53 inferred_type: InferredType,
54 source_span: SourceSpan,
55 },
56 Range {
57 range: Range,
58 type_annotation: Option<TypeName>,
59 inferred_type: InferredType,
60 source_span: SourceSpan,
61 },
62 Record {
63 exprs: Vec<(String, Box<Expr>)>,
64 type_annotation: Option<TypeName>,
65 inferred_type: InferredType,
66 source_span: SourceSpan,
67 },
68 Tuple {
69 exprs: Vec<Expr>,
70 type_annotation: Option<TypeName>,
71 inferred_type: InferredType,
72 source_span: SourceSpan,
73 },
74 Literal {
75 value: String,
76 type_annotation: Option<TypeName>,
77 inferred_type: InferredType,
78 source_span: SourceSpan,
79 },
80 Number {
81 number: Number,
82 type_annotation: Option<TypeName>,
83 inferred_type: InferredType,
84 source_span: SourceSpan,
85 },
86 Flags {
87 flags: Vec<String>,
88 type_annotation: Option<TypeName>,
89 inferred_type: InferredType,
90 source_span: SourceSpan,
91 },
92 Identifier {
93 variable_id: VariableId,
94 type_annotation: Option<TypeName>,
95 inferred_type: InferredType,
96 source_span: SourceSpan,
97 },
98 Boolean {
99 value: bool,
100 type_annotation: Option<TypeName>,
101 inferred_type: InferredType,
102 source_span: SourceSpan,
103 },
104 Concat {
105 exprs: Vec<Expr>,
106 type_annotation: Option<TypeName>,
107 inferred_type: InferredType,
108 source_span: SourceSpan,
109 },
110 ExprBlock {
111 exprs: Vec<Expr>,
112 type_annotation: Option<TypeName>,
113 inferred_type: InferredType,
114 source_span: SourceSpan,
115 },
116 Not {
117 expr: Box<Expr>,
118 inferred_type: InferredType,
119 type_annotation: Option<TypeName>,
120 source_span: SourceSpan,
121 },
122 GreaterThan {
123 lhs: Box<Expr>,
124 rhs: Box<Expr>,
125 type_annotation: Option<TypeName>,
126 inferred_type: InferredType,
127 source_span: SourceSpan,
128 },
129 And {
130 lhs: Box<Expr>,
131 rhs: Box<Expr>,
132 type_annotation: Option<TypeName>,
133 inferred_type: InferredType,
134 source_span: SourceSpan,
135 },
136 Or {
137 lhs: Box<Expr>,
138 rhs: Box<Expr>,
139 type_annotation: Option<TypeName>,
140 inferred_type: InferredType,
141 source_span: SourceSpan,
142 },
143 GreaterThanOrEqualTo {
144 lhs: Box<Expr>,
145 rhs: Box<Expr>,
146 type_annotation: Option<TypeName>,
147 inferred_type: InferredType,
148 source_span: SourceSpan,
149 },
150 LessThanOrEqualTo {
151 lhs: Box<Expr>,
152 rhs: Box<Expr>,
153 type_annotation: Option<TypeName>,
154 inferred_type: InferredType,
155 source_span: SourceSpan,
156 },
157 Plus {
158 lhs: Box<Expr>,
159 rhs: Box<Expr>,
160 type_annotation: Option<TypeName>,
161 inferred_type: InferredType,
162 source_span: SourceSpan,
163 },
164 Multiply {
165 lhs: Box<Expr>,
166 rhs: Box<Expr>,
167 type_annotation: Option<TypeName>,
168 inferred_type: InferredType,
169 source_span: SourceSpan,
170 },
171 Minus {
172 lhs: Box<Expr>,
173 rhs: Box<Expr>,
174 type_annotation: Option<TypeName>,
175 inferred_type: InferredType,
176 source_span: SourceSpan,
177 },
178 Divide {
179 lhs: Box<Expr>,
180 rhs: Box<Expr>,
181 type_annotation: Option<TypeName>,
182 inferred_type: InferredType,
183 source_span: SourceSpan,
184 },
185 EqualTo {
186 lhs: Box<Expr>,
187 rhs: Box<Expr>,
188 type_annotation: Option<TypeName>,
189 inferred_type: InferredType,
190 source_span: SourceSpan,
191 },
192 LessThan {
193 lhs: Box<Expr>,
194 rhs: Box<Expr>,
195 type_annotation: Option<TypeName>,
196 inferred_type: InferredType,
197 source_span: SourceSpan,
198 },
199 Cond {
200 cond: Box<Expr>,
201 lhs: Box<Expr>,
202 rhs: Box<Expr>,
203 type_annotation: Option<TypeName>,
204 inferred_type: InferredType,
205 source_span: SourceSpan,
206 },
207 PatternMatch {
208 predicate: Box<Expr>,
209 match_arms: Vec<MatchArm>,
210 type_annotation: Option<TypeName>,
211 inferred_type: InferredType,
212 source_span: SourceSpan,
213 },
214 Option {
215 expr: Option<Box<Expr>>,
216 type_annotation: Option<TypeName>,
217 inferred_type: InferredType,
218 source_span: SourceSpan,
219 },
220 Result {
221 expr: Result<Box<Expr>, Box<Expr>>,
222 type_annotation: Option<TypeName>,
223 inferred_type: InferredType,
224 source_span: SourceSpan,
225 },
226 Call {
231 call_type: CallType,
232 args: Vec<Expr>,
233 type_annotation: Option<TypeName>,
234 inferred_type: InferredType,
235 source_span: SourceSpan,
236 },
237 InvokeMethodLazy {
243 lhs: Box<Expr>,
244 method: String,
245 args: Vec<Expr>,
246 type_annotation: Option<TypeName>,
247 inferred_type: InferredType,
248 source_span: SourceSpan,
249 },
250 Unwrap {
251 expr: Box<Expr>,
252 inferred_type: InferredType,
253 type_annotation: Option<TypeName>,
254 source_span: SourceSpan,
255 },
256 Throw {
257 message: String,
258 inferred_type: InferredType,
259 type_annotation: Option<TypeName>,
260 source_span: SourceSpan,
261 },
262 GetTag {
263 expr: Box<Expr>,
264 inferred_type: InferredType,
265 type_annotation: Option<TypeName>,
266 source_span: SourceSpan,
267 },
268 ListComprehension {
269 iterated_variable: VariableId,
270 iterable_expr: Box<Expr>,
271 yield_expr: Box<Expr>,
272 type_annotation: Option<TypeName>,
273 inferred_type: InferredType,
274 source_span: SourceSpan,
275 },
276 ListReduce {
277 reduce_variable: VariableId,
278 iterated_variable: VariableId,
279 iterable_expr: Box<Expr>,
280 type_annotation: Option<TypeName>,
281 yield_expr: Box<Expr>,
282 init_value_expr: Box<Expr>,
283 inferred_type: InferredType,
284 source_span: SourceSpan,
285 },
286 Length {
287 expr: Box<Expr>,
288 inferred_type: InferredType,
289 type_annotation: Option<TypeName>,
290 source_span: SourceSpan,
291 },
292
293 GenerateWorkerName {
294 inferred_type: InferredType,
295 type_annotation: Option<TypeName>,
296 source_span: SourceSpan,
297 variable_id: Option<VariableId>,
298 },
299}
300
301impl Expr {
302 pub fn as_record(&self) -> Option<Vec<(String, Expr)>> {
303 match self {
304 Expr::Record { exprs: fields, .. } => Some(
305 fields
306 .iter()
307 .map(|(k, v)| (k.clone(), v.deref().clone()))
308 .collect::<Vec<_>>(),
309 ),
310 _ => None,
311 }
312 }
313 pub fn from_text(input: &str) -> Result<Expr, String> {
330 if input.trim().ends_with(';') {
331 return Err("unexpected `;` at the end of rib expression. \nnote: `;` is used to separate expressions, but it should not appear after the last expression (which is the return value)".to_string());
332 }
333
334 spaces()
335 .with(block().skip(eof()))
336 .easy_parse(position::Stream::new(input))
337 .map(|t| t.0)
338 .map_err(|err| format!("{err}"))
339 }
340
341 pub fn lookup(&self, source_span: &SourceSpan) -> Option<Expr> {
342 let mut expr = self.clone();
343 find_expr(&mut expr, source_span)
344 }
345
346 pub fn is_literal(&self) -> bool {
347 matches!(self, Expr::Literal { .. })
348 }
349
350 pub fn is_block(&self) -> bool {
351 matches!(self, Expr::ExprBlock { .. })
352 }
353
354 pub fn is_number(&self) -> bool {
355 matches!(self, Expr::Number { .. })
356 }
357
358 pub fn is_record(&self) -> bool {
359 matches!(self, Expr::Record { .. })
360 }
361
362 pub fn is_result(&self) -> bool {
363 matches!(self, Expr::Result { .. })
364 }
365
366 pub fn is_option(&self) -> bool {
367 matches!(self, Expr::Option { .. })
368 }
369
370 pub fn is_tuple(&self) -> bool {
371 matches!(self, Expr::Tuple { .. })
372 }
373
374 pub fn is_list(&self) -> bool {
375 matches!(self, Expr::Sequence { .. })
376 }
377
378 pub fn is_flags(&self) -> bool {
379 matches!(self, Expr::Flags { .. })
380 }
381
382 pub fn is_identifier(&self) -> bool {
383 matches!(self, Expr::Identifier { .. })
384 }
385
386 pub fn is_select_field(&self) -> bool {
387 matches!(self, Expr::SelectField { .. })
388 }
389
390 pub fn is_if_else(&self) -> bool {
391 matches!(self, Expr::Cond { .. })
392 }
393
394 pub fn is_function_call(&self) -> bool {
395 matches!(self, Expr::Call { .. })
396 }
397
398 pub fn is_match_expr(&self) -> bool {
399 matches!(self, Expr::PatternMatch { .. })
400 }
401
402 pub fn is_boolean(&self) -> bool {
403 matches!(self, Expr::Boolean { .. })
404 }
405
406 pub fn is_comparison(&self) -> bool {
407 matches!(
408 self,
409 Expr::GreaterThan { .. }
410 | Expr::GreaterThanOrEqualTo { .. }
411 | Expr::LessThanOrEqualTo { .. }
412 | Expr::EqualTo { .. }
413 | Expr::LessThan { .. }
414 )
415 }
416
417 pub fn is_concat(&self) -> bool {
418 matches!(self, Expr::Concat { .. })
419 }
420
421 pub fn is_multiple(&self) -> bool {
422 matches!(self, Expr::ExprBlock { .. })
423 }
424
425 pub fn inbuilt_variant(&self) -> Option<(String, Option<Expr>)> {
426 match self {
427 Expr::Option {
428 expr: Some(expr), ..
429 } => Some(("some".to_string(), Some(expr.deref().clone()))),
430 Expr::Option { expr: None, .. } => Some(("some".to_string(), None)),
431 Expr::Result { expr: Ok(expr), .. } => {
432 Some(("ok".to_string(), Some(expr.deref().clone())))
433 }
434 Expr::Result {
435 expr: Err(expr), ..
436 } => Some(("err".to_string(), Some(expr.deref().clone()))),
437 _ => None,
438 }
439 }
440 pub fn unwrap(&self) -> Self {
441 Expr::Unwrap {
442 expr: Box::new(self.clone()),
443 inferred_type: InferredType::unknown(),
444 source_span: SourceSpan::default(),
445 type_annotation: None,
446 }
447 }
448
449 pub fn length(expr: Expr) -> Self {
450 Expr::Length {
451 expr: Box::new(expr),
452 inferred_type: InferredType::u64(),
453 source_span: SourceSpan::default(),
454 type_annotation: None,
455 }
456 }
457
458 pub fn boolean(value: bool) -> Self {
459 Expr::Boolean {
460 value,
461 inferred_type: InferredType::bool(),
462 source_span: SourceSpan::default(),
463 type_annotation: None,
464 }
465 }
466
467 pub fn and(left: Expr, right: Expr) -> Self {
468 Expr::And {
469 lhs: Box::new(left),
470 rhs: Box::new(right),
471 inferred_type: InferredType::bool(),
472 source_span: SourceSpan::default(),
473 type_annotation: None,
474 }
475 }
476
477 pub fn throw(message: impl AsRef<str>) -> Self {
478 Expr::Throw {
479 message: message.as_ref().to_string(),
480 inferred_type: InferredType::unknown(),
481 source_span: SourceSpan::default(),
482 type_annotation: None,
483 }
484 }
485
486 pub fn generate_worker_name(variable_id: Option<VariableId>) -> Self {
487 Expr::GenerateWorkerName {
488 inferred_type: InferredType::string(),
489 type_annotation: None,
490 source_span: SourceSpan::default(),
491 variable_id,
492 }
493 }
494
495 pub fn plus(left: Expr, right: Expr) -> Self {
496 Expr::Plus {
497 lhs: Box::new(left),
498 rhs: Box::new(right),
499 inferred_type: InferredType::unknown(),
500 source_span: SourceSpan::default(),
501 type_annotation: None,
502 }
503 }
504
505 pub fn minus(left: Expr, right: Expr) -> Self {
506 Expr::Minus {
507 lhs: Box::new(left),
508 rhs: Box::new(right),
509 inferred_type: InferredType::unknown(),
510 source_span: SourceSpan::default(),
511 type_annotation: None,
512 }
513 }
514
515 pub fn divide(left: Expr, right: Expr) -> Self {
516 Expr::Divide {
517 lhs: Box::new(left),
518 rhs: Box::new(right),
519 inferred_type: InferredType::unknown(),
520 source_span: SourceSpan::default(),
521 type_annotation: None,
522 }
523 }
524
525 pub fn multiply(left: Expr, right: Expr) -> Self {
526 Expr::Multiply {
527 lhs: Box::new(left),
528 rhs: Box::new(right),
529 inferred_type: InferredType::unknown(),
530 source_span: SourceSpan::default(),
531 type_annotation: None,
532 }
533 }
534
535 pub fn and_combine(conditions: Vec<Expr>) -> Option<Expr> {
536 let mut cond: Option<Expr> = None;
537
538 for i in conditions {
539 let left = Box::new(cond.clone().unwrap_or(Expr::boolean(true)));
540 cond = Some(Expr::And {
541 lhs: left,
542 rhs: Box::new(i),
543 inferred_type: InferredType::bool(),
544 source_span: SourceSpan::default(),
545 type_annotation: None,
546 });
547 }
548
549 cond
550 }
551
552 pub fn call_worker_function(
553 dynamic_parsed_fn_name: DynamicParsedFunctionName,
554 module_identifier: Option<InstanceIdentifier>,
555 args: Vec<Expr>,
556 component_info: Option<ComponentDependencyKey>,
557 ) -> Self {
558 Expr::Call {
559 call_type: CallType::Function {
560 function_name: dynamic_parsed_fn_name,
561 instance_identifier: module_identifier.map(Box::new),
562 component_info,
563 },
564 args,
565 inferred_type: InferredType::unknown(),
566 source_span: SourceSpan::default(),
567 type_annotation: None,
568 }
569 }
570
571 pub fn call(call_type: CallType, args: Vec<Expr>) -> Self {
572 Expr::Call {
573 call_type,
574 args,
575 inferred_type: InferredType::unknown(),
576 source_span: SourceSpan::default(),
577 type_annotation: None,
578 }
579 }
580
581 pub fn invoke_worker_function(lhs: Expr, function_name: String, args: Vec<Expr>) -> Self {
582 Expr::InvokeMethodLazy {
583 lhs: Box::new(lhs),
584 method: function_name,
585 args,
586 inferred_type: InferredType::unknown(),
587 source_span: SourceSpan::default(),
588 type_annotation: None,
589 }
590 }
591
592 pub fn concat(expressions: Vec<Expr>) -> Self {
593 Expr::Concat {
594 exprs: expressions,
595 inferred_type: InferredType::string(),
596 source_span: SourceSpan::default(),
597 type_annotation: None,
598 }
599 }
600
601 pub fn cond(cond: Expr, lhs: Expr, rhs: Expr) -> Self {
602 Expr::Cond {
603 cond: Box::new(cond),
604 lhs: Box::new(lhs),
605 rhs: Box::new(rhs),
606 inferred_type: InferredType::unknown(),
607 source_span: SourceSpan::default(),
608 type_annotation: None,
609 }
610 }
611
612 pub fn equal_to(left: Expr, right: Expr) -> Self {
613 Expr::EqualTo {
614 lhs: Box::new(left),
615 rhs: Box::new(right),
616 inferred_type: InferredType::bool(),
617 source_span: SourceSpan::default(),
618 type_annotation: None,
619 }
620 }
621
622 pub fn err(expr: Expr, type_annotation: Option<TypeName>) -> Self {
623 let inferred_type = expr.inferred_type();
624 Expr::Result {
625 expr: Err(Box::new(expr)),
626 type_annotation,
627 inferred_type: InferredType::result(Some(InferredType::unknown()), Some(inferred_type)),
628 source_span: SourceSpan::default(),
629 }
630 }
631
632 pub fn flags(flags: Vec<String>) -> Self {
633 Expr::Flags {
634 flags: flags.clone(),
635 inferred_type: InferredType::flags(flags),
636 source_span: SourceSpan::default(),
637 type_annotation: None,
638 }
639 }
640
641 pub fn greater_than(left: Expr, right: Expr) -> Self {
642 Expr::GreaterThan {
643 lhs: Box::new(left),
644 rhs: Box::new(right),
645 inferred_type: InferredType::bool(),
646 source_span: SourceSpan::default(),
647 type_annotation: None,
648 }
649 }
650
651 pub fn greater_than_or_equal_to(left: Expr, right: Expr) -> Self {
652 Expr::GreaterThanOrEqualTo {
653 lhs: Box::new(left),
654 rhs: Box::new(right),
655 inferred_type: InferredType::bool(),
656 source_span: SourceSpan::default(),
657 type_annotation: None,
658 }
659 }
660
661 pub fn identifier_global(name: impl AsRef<str>, type_annotation: Option<TypeName>) -> Self {
663 Expr::Identifier {
664 variable_id: VariableId::global(name.as_ref().to_string()),
665 type_annotation,
666 inferred_type: InferredType::unknown(),
667 source_span: SourceSpan::default(),
668 }
669 }
670
671 pub fn identifier_local(
672 name: impl AsRef<str>,
673 id: u32,
674 type_annotation: Option<TypeName>,
675 ) -> Self {
676 Expr::Identifier {
677 variable_id: VariableId::local(name.as_ref(), id),
678 type_annotation,
679 inferred_type: InferredType::unknown(),
680 source_span: SourceSpan::default(),
681 }
682 }
683
684 pub fn identifier_with_variable_id(
685 variable_id: VariableId,
686 type_annotation: Option<TypeName>,
687 ) -> Self {
688 Expr::Identifier {
689 variable_id,
690 type_annotation,
691 inferred_type: InferredType::unknown(),
692 source_span: SourceSpan::default(),
693 }
694 }
695
696 pub fn less_than(left: Expr, right: Expr) -> Self {
697 Expr::LessThan {
698 lhs: Box::new(left),
699 rhs: Box::new(right),
700 inferred_type: InferredType::bool(),
701 source_span: SourceSpan::default(),
702 type_annotation: None,
703 }
704 }
705
706 pub fn less_than_or_equal_to(left: Expr, right: Expr) -> Self {
707 Expr::LessThanOrEqualTo {
708 lhs: Box::new(left),
709 rhs: Box::new(right),
710 inferred_type: InferredType::bool(),
711 source_span: SourceSpan::default(),
712 type_annotation: None,
713 }
714 }
715
716 pub fn range(from: Expr, to: Expr) -> Self {
717 Expr::Range {
718 range: Range::Range {
719 from: Box::new(from.clone()),
720 to: Box::new(to.clone()),
721 },
722 inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
723 source_span: SourceSpan::default(),
724 type_annotation: None,
725 }
726 }
727
728 pub fn range_from(from: Expr) -> Self {
729 Expr::Range {
730 range: Range::RangeFrom {
731 from: Box::new(from.clone()),
732 },
733 inferred_type: InferredType::range(from.inferred_type(), None),
734 source_span: SourceSpan::default(),
735 type_annotation: None,
736 }
737 }
738
739 pub fn range_inclusive(from: Expr, to: Expr) -> Self {
740 Expr::Range {
741 range: Range::RangeInclusive {
742 from: Box::new(from.clone()),
743 to: Box::new(to.clone()),
744 },
745 inferred_type: InferredType::range(from.inferred_type(), Some(to.inferred_type())),
746 source_span: SourceSpan::default(),
747 type_annotation: None,
748 }
749 }
750
751 pub fn let_binding(
752 name: impl AsRef<str>,
753 expr: Expr,
754 type_annotation: Option<TypeName>,
755 ) -> Self {
756 Expr::Let {
757 variable_id: VariableId::global(name.as_ref().to_string()),
758 type_annotation,
759 expr: Box::new(expr),
760 source_span: SourceSpan::default(),
761 inferred_type: InferredType::tuple(vec![]),
762 }
763 }
764
765 pub fn let_binding_with_variable_id(
766 variable_id: VariableId,
767 expr: Expr,
768 type_annotation: Option<TypeName>,
769 ) -> Self {
770 Expr::Let {
771 variable_id,
772 type_annotation,
773 expr: Box::new(expr),
774 source_span: SourceSpan::default(),
775 inferred_type: InferredType::tuple(vec![]),
776 }
777 }
778
779 pub fn typed_list_reduce(
780 reduce_variable: VariableId,
781 iterated_variable: VariableId,
782 iterable_expr: Expr,
783 init_value_expr: Expr,
784 yield_expr: Expr,
785 inferred_type: InferredType,
786 ) -> Self {
787 Expr::ListReduce {
788 reduce_variable,
789 iterated_variable,
790 iterable_expr: Box::new(iterable_expr),
791 yield_expr: Box::new(yield_expr),
792 init_value_expr: Box::new(init_value_expr),
793 inferred_type,
794 source_span: SourceSpan::default(),
795 type_annotation: None,
796 }
797 }
798
799 pub fn list_reduce(
800 reduce_variable: VariableId,
801 iterated_variable: VariableId,
802 iterable_expr: Expr,
803 init_value_expr: Expr,
804 yield_expr: Expr,
805 ) -> Self {
806 Expr::typed_list_reduce(
807 reduce_variable,
808 iterated_variable,
809 iterable_expr,
810 init_value_expr,
811 yield_expr,
812 InferredType::unknown(),
813 )
814 }
815
816 pub fn list_comprehension_typed(
817 iterated_variable: VariableId,
818 iterable_expr: Expr,
819 yield_expr: Expr,
820 inferred_type: InferredType,
821 ) -> Self {
822 Expr::ListComprehension {
823 iterated_variable,
824 iterable_expr: Box::new(iterable_expr),
825 yield_expr: Box::new(yield_expr),
826 inferred_type,
827 source_span: SourceSpan::default(),
828 type_annotation: None,
829 }
830 }
831
832 pub fn list_comprehension(
833 variable_id: VariableId,
834 iterable_expr: Expr,
835 yield_expr: Expr,
836 ) -> Self {
837 Expr::list_comprehension_typed(
838 variable_id,
839 iterable_expr,
840 yield_expr,
841 InferredType::list(InferredType::unknown()),
842 )
843 }
844
845 pub fn literal(value: impl AsRef<str>) -> Self {
846 let default_type = DefaultType::String;
847
848 Expr::Literal {
849 value: value.as_ref().to_string(),
850 inferred_type: InferredType::from(&default_type),
851 source_span: SourceSpan::default(),
852 type_annotation: None,
853 }
854 }
855
856 pub fn empty_expr() -> Self {
857 Expr::literal("")
858 }
859
860 pub fn expr_block(expressions: Vec<Expr>) -> Self {
861 let inferred_type = expressions
862 .last()
863 .map_or(InferredType::unknown(), |e| e.inferred_type());
864
865 Expr::ExprBlock {
866 exprs: expressions,
867 inferred_type,
868 source_span: SourceSpan::default(),
869 type_annotation: None,
870 }
871 }
872
873 #[allow(clippy::should_implement_trait)]
874 pub fn not(expr: Expr) -> Self {
875 Expr::Not {
876 expr: Box::new(expr),
877 inferred_type: InferredType::bool(),
878 source_span: SourceSpan::default(),
879 type_annotation: None,
880 }
881 }
882
883 pub fn ok(expr: Expr, type_annotation: Option<TypeName>) -> Self {
884 let inferred_type = expr.inferred_type();
885
886 Expr::Result {
887 expr: Ok(Box::new(expr)),
888 type_annotation,
889 inferred_type: InferredType::result(Some(inferred_type), Some(InferredType::unknown())),
890 source_span: SourceSpan::default(),
891 }
892 }
893
894 pub fn option(expr: Option<Expr>) -> Self {
895 let inferred_type = match &expr {
896 Some(expr) => expr.inferred_type(),
897 None => InferredType::unknown(),
898 };
899
900 Expr::Option {
901 expr: expr.map(Box::new),
902 type_annotation: None,
903 inferred_type: InferredType::option(inferred_type),
904 source_span: SourceSpan::default(),
905 }
906 }
907
908 pub fn or(left: Expr, right: Expr) -> Self {
909 Expr::Or {
910 lhs: Box::new(left),
911 rhs: Box::new(right),
912 inferred_type: InferredType::bool(),
913 source_span: SourceSpan::default(),
914 type_annotation: None,
915 }
916 }
917
918 pub fn pattern_match(expr: Expr, match_arms: Vec<MatchArm>) -> Self {
919 Expr::PatternMatch {
920 predicate: Box::new(expr),
921 match_arms,
922 inferred_type: InferredType::unknown(),
923 source_span: SourceSpan::default(),
924 type_annotation: None,
925 }
926 }
927
928 pub fn record(expressions: Vec<(String, Expr)>) -> Self {
929 let inferred_type = InferredType::record(
930 expressions
931 .iter()
932 .map(|(field_name, expr)| (field_name.to_string(), expr.inferred_type()))
933 .collect(),
934 );
935
936 Expr::Record {
937 exprs: expressions
938 .into_iter()
939 .map(|(field_name, expr)| (field_name, Box::new(expr)))
940 .collect(),
941 inferred_type,
942 source_span: SourceSpan::default(),
943 type_annotation: None,
944 }
945 }
946
947 pub fn select_field(
948 expr: Expr,
949 field: impl AsRef<str>,
950 type_annotation: Option<TypeName>,
951 ) -> Self {
952 Expr::SelectField {
953 expr: Box::new(expr),
954 field: field.as_ref().to_string(),
955 type_annotation,
956 inferred_type: InferredType::unknown(),
957 source_span: SourceSpan::default(),
958 }
959 }
960
961 pub fn select_index(expr: Expr, index: Expr) -> Self {
962 Expr::SelectIndex {
963 expr: Box::new(expr),
964 index: Box::new(index),
965 type_annotation: None,
966 inferred_type: InferredType::unknown(),
967 source_span: SourceSpan::default(),
968 }
969 }
970
971 pub fn get_tag(expr: Expr) -> Self {
972 Expr::GetTag {
973 expr: Box::new(expr),
974 inferred_type: InferredType::unknown(),
975 source_span: SourceSpan::default(),
976 type_annotation: None,
977 }
978 }
979
980 pub fn tuple(expressions: Vec<Expr>) -> Self {
981 let inferred_type = InferredType::tuple(
982 expressions
983 .iter()
984 .map(|expr| expr.inferred_type())
985 .collect(),
986 );
987
988 Expr::Tuple {
989 exprs: expressions,
990 inferred_type,
991 source_span: SourceSpan::default(),
992 type_annotation: None,
993 }
994 }
995
996 pub fn sequence(expressions: Vec<Expr>, type_annotation: Option<TypeName>) -> Self {
997 let inferred_type = InferredType::list(
998 expressions
999 .first()
1000 .map_or(InferredType::unknown(), |x| x.inferred_type()),
1001 );
1002
1003 Expr::Sequence {
1004 exprs: expressions,
1005 type_annotation,
1006 inferred_type,
1007 source_span: SourceSpan::default(),
1008 }
1009 }
1010
1011 pub fn inferred_type_mut(&mut self) -> &mut InferredType {
1012 match self {
1013 Expr::Let { inferred_type, .. }
1014 | Expr::SelectField { inferred_type, .. }
1015 | Expr::SelectIndex { inferred_type, .. }
1016 | Expr::Sequence { inferred_type, .. }
1017 | Expr::Record { inferred_type, .. }
1018 | Expr::Tuple { inferred_type, .. }
1019 | Expr::Literal { inferred_type, .. }
1020 | Expr::Number { inferred_type, .. }
1021 | Expr::Flags { inferred_type, .. }
1022 | Expr::Identifier { inferred_type, .. }
1023 | Expr::Boolean { inferred_type, .. }
1024 | Expr::Concat { inferred_type, .. }
1025 | Expr::ExprBlock { inferred_type, .. }
1026 | Expr::Not { inferred_type, .. }
1027 | Expr::GreaterThan { inferred_type, .. }
1028 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1029 | Expr::LessThanOrEqualTo { inferred_type, .. }
1030 | Expr::EqualTo { inferred_type, .. }
1031 | Expr::Plus { inferred_type, .. }
1032 | Expr::Minus { inferred_type, .. }
1033 | Expr::Divide { inferred_type, .. }
1034 | Expr::Multiply { inferred_type, .. }
1035 | Expr::LessThan { inferred_type, .. }
1036 | Expr::Cond { inferred_type, .. }
1037 | Expr::PatternMatch { inferred_type, .. }
1038 | Expr::Option { inferred_type, .. }
1039 | Expr::Result { inferred_type, .. }
1040 | Expr::Unwrap { inferred_type, .. }
1041 | Expr::Throw { inferred_type, .. }
1042 | Expr::GetTag { inferred_type, .. }
1043 | Expr::And { inferred_type, .. }
1044 | Expr::Or { inferred_type, .. }
1045 | Expr::ListComprehension { inferred_type, .. }
1046 | Expr::ListReduce { inferred_type, .. }
1047 | Expr::Call { inferred_type, .. }
1048 | Expr::Range { inferred_type, .. }
1049 | Expr::InvokeMethodLazy { inferred_type, .. }
1050 | Expr::Length { inferred_type, .. }
1051 | Expr::GenerateWorkerName { inferred_type, .. } => &mut *inferred_type,
1052 }
1053 }
1054
1055 pub fn inferred_type(&self) -> InferredType {
1056 match self {
1057 Expr::Let { inferred_type, .. }
1058 | Expr::SelectField { inferred_type, .. }
1059 | Expr::SelectIndex { inferred_type, .. }
1060 | Expr::Sequence { inferred_type, .. }
1061 | Expr::Record { inferred_type, .. }
1062 | Expr::Tuple { inferred_type, .. }
1063 | Expr::Literal { inferred_type, .. }
1064 | Expr::Number { inferred_type, .. }
1065 | Expr::Flags { inferred_type, .. }
1066 | Expr::Identifier { inferred_type, .. }
1067 | Expr::Boolean { inferred_type, .. }
1068 | Expr::Concat { inferred_type, .. }
1069 | Expr::ExprBlock { inferred_type, .. }
1070 | Expr::Not { inferred_type, .. }
1071 | Expr::GreaterThan { inferred_type, .. }
1072 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1073 | Expr::LessThanOrEqualTo { inferred_type, .. }
1074 | Expr::EqualTo { inferred_type, .. }
1075 | Expr::Plus { inferred_type, .. }
1076 | Expr::Minus { inferred_type, .. }
1077 | Expr::Divide { inferred_type, .. }
1078 | Expr::Multiply { inferred_type, .. }
1079 | Expr::LessThan { inferred_type, .. }
1080 | Expr::Cond { inferred_type, .. }
1081 | Expr::PatternMatch { inferred_type, .. }
1082 | Expr::Option { inferred_type, .. }
1083 | Expr::Result { inferred_type, .. }
1084 | Expr::Unwrap { inferred_type, .. }
1085 | Expr::Throw { inferred_type, .. }
1086 | Expr::GetTag { inferred_type, .. }
1087 | Expr::And { inferred_type, .. }
1088 | Expr::Or { inferred_type, .. }
1089 | Expr::ListComprehension { inferred_type, .. }
1090 | Expr::ListReduce { inferred_type, .. }
1091 | Expr::Call { inferred_type, .. }
1092 | Expr::Range { inferred_type, .. }
1093 | Expr::InvokeMethodLazy { inferred_type, .. }
1094 | Expr::Length { inferred_type, .. }
1095 | Expr::GenerateWorkerName { inferred_type, .. } => inferred_type.clone(),
1096 }
1097 }
1098
1099 pub fn infer_types(
1100 &mut self,
1101 component_dependency: &ComponentDependency,
1102 global_variable_type_spec: &Vec<GlobalVariableTypeSpec>,
1103 custom_instance_spec: &[CustomInstanceSpec],
1104 ) -> Result<(), RibTypeErrorInternal> {
1105 let component = Arc::new(component_dependency.clone());
1106
1107 let (mut arena, mut types, root) = {
1108 let _p = crate::profile::Scope::new("type inference: lower to expr arena");
1109
1110 crate::expr_arena::lower(self)
1111 };
1112
1113 {
1114 let _p = crate::profile::Scope::new(
1115 "type inference: run_initial_binding_and_instance_phases",
1116 );
1117 ti::run_initial_binding_and_instance_phases(
1118 root,
1119 &mut arena,
1120 &mut types,
1121 component.clone(),
1122 global_variable_type_spec.as_slice(),
1123 custom_instance_spec,
1124 )?;
1125
1126 ti::infer_variants_lowered(root, &mut arena, &mut types, component.as_ref());
1127 ti::infer_enums(root, &mut arena, &mut types, component.as_ref());
1128 ti::bind_instance_types(root, &arena, &mut types);
1129 }
1130
1131 {
1132 let _p = crate::profile::Scope::new(
1133 "type inference: fixpoint - resolve function calls and instance bindings",
1134 );
1135
1136 ti::type_inference_fix_point(
1137 |root, arena, types| -> Result<(), RibTypeErrorInternal> {
1138 ti::bind_instance_types(root, arena, types);
1139 ti::infer_function_invokes(root, arena, types, component.as_ref())
1140 },
1141 root,
1142 &mut arena,
1143 &mut types,
1144 )?;
1145 }
1146
1147 {
1148 let _p = crate::profile::Scope::new("type inference: infer_function_call_types");
1149
1150 ti::infer_function_call_types(
1151 root,
1152 &arena,
1153 &mut types,
1154 component.as_ref(),
1155 custom_instance_spec,
1156 )
1157 .map_err(RibTypeErrorInternal::from)?;
1158 }
1159
1160 {
1161 let _p = crate::profile::Scope::new(
1162 "type inference: fixpoint - main scan for type inference",
1163 );
1164
1165 ti::type_inference_fix_point(
1166 |root, arena, types| -> Result<(), RibTypeErrorInternal> {
1167 ti::infer_all_identifiers(root, arena, types);
1168 ti::push_types_down(root, arena, types)?;
1169 ti::infer_all_identifiers(root, arena, types);
1170 ti::pull_types_up(root, arena, types, component.as_ref())?;
1171 ti::infer_global_inputs(root, arena, types);
1172 ti::infer_function_call_types(
1173 root,
1174 arena,
1175 types,
1176 component.as_ref(),
1177 custom_instance_spec,
1178 )
1179 .map_err(RibTypeErrorInternal::from)?;
1180 Ok(())
1181 },
1182 root,
1183 &mut arena,
1184 &mut types,
1185 )?;
1186 }
1187
1188 {
1189 let _p = crate::profile::Scope::new(
1190 "type inference: sync_embedded_worker_exprs_from_calls + bind_instance_types",
1191 );
1192
1193 ti::sync_embedded_worker_exprs_from_calls(root, &arena, &mut types);
1194 ti::bind_instance_types(root, &arena, &mut types);
1195 }
1196
1197 {
1198 let _p = crate::profile::Scope::new("type inference: type check");
1199 type_checker::checker::type_check(root, &arena, &mut types, component.as_ref())?;
1200 }
1201
1202 {
1203 let _p = crate::profile::Scope::new("type inference: unify types");
1204 type_inference::unify_types(root, &arena, &mut types)?;
1205 }
1206
1207 {
1208 let _p = crate::profile::Scope::new("type inference: rebuild_expr");
1209 *self = crate::expr_arena::rebuild_expr(root, &arena, &types);
1210 }
1211
1212 Ok(())
1213 }
1214
1215 pub fn merge_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1216 let mut expr_copied = self.clone();
1217 expr_copied.add_infer_type_mut(new_inferred_type);
1218 expr_copied
1219 }
1220
1221 pub fn add_infer_type_mut(&mut self, new_inferred_type: InferredType) {
1222 match self {
1223 Expr::Identifier { inferred_type, .. }
1224 | Expr::Let { inferred_type, .. }
1225 | Expr::SelectField { inferred_type, .. }
1226 | Expr::SelectIndex { inferred_type, .. }
1227 | Expr::Sequence { inferred_type, .. }
1228 | Expr::Record { inferred_type, .. }
1229 | Expr::Tuple { inferred_type, .. }
1230 | Expr::Literal { inferred_type, .. }
1231 | Expr::Number { inferred_type, .. }
1232 | Expr::Flags { inferred_type, .. }
1233 | Expr::Boolean { inferred_type, .. }
1234 | Expr::Concat { inferred_type, .. }
1235 | Expr::ExprBlock { inferred_type, .. }
1236 | Expr::Not { inferred_type, .. }
1237 | Expr::GreaterThan { inferred_type, .. }
1238 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1239 | Expr::LessThanOrEqualTo { inferred_type, .. }
1240 | Expr::EqualTo { inferred_type, .. }
1241 | Expr::Plus { inferred_type, .. }
1242 | Expr::Minus { inferred_type, .. }
1243 | Expr::Divide { inferred_type, .. }
1244 | Expr::Multiply { inferred_type, .. }
1245 | Expr::LessThan { inferred_type, .. }
1246 | Expr::Cond { inferred_type, .. }
1247 | Expr::PatternMatch { inferred_type, .. }
1248 | Expr::Option { inferred_type, .. }
1249 | Expr::Result { inferred_type, .. }
1250 | Expr::Unwrap { inferred_type, .. }
1251 | Expr::Throw { inferred_type, .. }
1252 | Expr::GetTag { inferred_type, .. }
1253 | Expr::And { inferred_type, .. }
1254 | Expr::Or { inferred_type, .. }
1255 | Expr::ListComprehension { inferred_type, .. }
1256 | Expr::ListReduce { inferred_type, .. }
1257 | Expr::InvokeMethodLazy { inferred_type, .. }
1258 | Expr::Range { inferred_type, .. }
1259 | Expr::Length { inferred_type, .. }
1260 | Expr::GenerateWorkerName { inferred_type, .. }
1261 | Expr::Call { inferred_type, .. } => {
1262 if !new_inferred_type.is_unknown() {
1263 *inferred_type = inferred_type.merge(new_inferred_type);
1264 }
1265 }
1266 }
1267 }
1268
1269 pub fn reset_type(&mut self) {
1270 type_inference::reset_type_info(self);
1271 }
1272
1273 pub fn source_span(&self) -> SourceSpan {
1274 match self {
1275 Expr::Identifier { source_span, .. }
1276 | Expr::Let { source_span, .. }
1277 | Expr::SelectField { source_span, .. }
1278 | Expr::SelectIndex { source_span, .. }
1279 | Expr::Sequence { source_span, .. }
1280 | Expr::Record { source_span, .. }
1281 | Expr::Tuple { source_span, .. }
1282 | Expr::Literal { source_span, .. }
1283 | Expr::Number { source_span, .. }
1284 | Expr::Flags { source_span, .. }
1285 | Expr::Boolean { source_span, .. }
1286 | Expr::Concat { source_span, .. }
1287 | Expr::ExprBlock { source_span, .. }
1288 | Expr::Not { source_span, .. }
1289 | Expr::GreaterThan { source_span, .. }
1290 | Expr::GreaterThanOrEqualTo { source_span, .. }
1291 | Expr::LessThanOrEqualTo { source_span, .. }
1292 | Expr::EqualTo { source_span, .. }
1293 | Expr::LessThan { source_span, .. }
1294 | Expr::Plus { source_span, .. }
1295 | Expr::Minus { source_span, .. }
1296 | Expr::Divide { source_span, .. }
1297 | Expr::Multiply { source_span, .. }
1298 | Expr::Cond { source_span, .. }
1299 | Expr::PatternMatch { source_span, .. }
1300 | Expr::Option { source_span, .. }
1301 | Expr::Result { source_span, .. }
1302 | Expr::Unwrap { source_span, .. }
1303 | Expr::Throw { source_span, .. }
1304 | Expr::And { source_span, .. }
1305 | Expr::Or { source_span, .. }
1306 | Expr::GetTag { source_span, .. }
1307 | Expr::ListComprehension { source_span, .. }
1308 | Expr::ListReduce { source_span, .. }
1309 | Expr::InvokeMethodLazy { source_span, .. }
1310 | Expr::Range { source_span, .. }
1311 | Expr::Length { source_span, .. }
1312 | Expr::Call { source_span, .. }
1313 | Expr::GenerateWorkerName { source_span, .. } => source_span.clone(),
1314 }
1315 }
1316
1317 pub fn type_annotation(&self) -> &Option<TypeName> {
1318 match self {
1319 Expr::Identifier {
1320 type_annotation, ..
1321 }
1322 | Expr::Let {
1323 type_annotation, ..
1324 }
1325 | Expr::SelectField {
1326 type_annotation, ..
1327 }
1328 | Expr::SelectIndex {
1329 type_annotation, ..
1330 }
1331 | Expr::Sequence {
1332 type_annotation, ..
1333 }
1334 | Expr::Record {
1335 type_annotation, ..
1336 }
1337 | Expr::Tuple {
1338 type_annotation, ..
1339 }
1340 | Expr::Literal {
1341 type_annotation, ..
1342 }
1343 | Expr::Number {
1344 type_annotation, ..
1345 }
1346 | Expr::Flags {
1347 type_annotation, ..
1348 }
1349 | Expr::Boolean {
1350 type_annotation, ..
1351 }
1352 | Expr::Concat {
1353 type_annotation, ..
1354 }
1355 | Expr::ExprBlock {
1356 type_annotation, ..
1357 }
1358 | Expr::Not {
1359 type_annotation, ..
1360 }
1361 | Expr::GreaterThan {
1362 type_annotation, ..
1363 }
1364 | Expr::GreaterThanOrEqualTo {
1365 type_annotation, ..
1366 }
1367 | Expr::LessThanOrEqualTo {
1368 type_annotation, ..
1369 }
1370 | Expr::EqualTo {
1371 type_annotation, ..
1372 }
1373 | Expr::LessThan {
1374 type_annotation, ..
1375 }
1376 | Expr::Plus {
1377 type_annotation, ..
1378 }
1379 | Expr::Minus {
1380 type_annotation, ..
1381 }
1382 | Expr::Divide {
1383 type_annotation, ..
1384 }
1385 | Expr::Multiply {
1386 type_annotation, ..
1387 }
1388 | Expr::Cond {
1389 type_annotation, ..
1390 }
1391 | Expr::PatternMatch {
1392 type_annotation, ..
1393 }
1394 | Expr::Option {
1395 type_annotation, ..
1396 }
1397 | Expr::Result {
1398 type_annotation, ..
1399 }
1400 | Expr::Unwrap {
1401 type_annotation, ..
1402 }
1403 | Expr::Throw {
1404 type_annotation, ..
1405 }
1406 | Expr::And {
1407 type_annotation, ..
1408 }
1409 | Expr::Or {
1410 type_annotation, ..
1411 }
1412 | Expr::GetTag {
1413 type_annotation, ..
1414 }
1415 | Expr::ListComprehension {
1416 type_annotation, ..
1417 }
1418 | Expr::ListReduce {
1419 type_annotation, ..
1420 }
1421 | Expr::InvokeMethodLazy {
1422 type_annotation, ..
1423 }
1424 | Expr::Range {
1425 type_annotation, ..
1426 }
1427 | Expr::Length {
1428 type_annotation, ..
1429 }
1430 | Expr::GenerateWorkerName {
1431 type_annotation, ..
1432 }
1433 | Expr::Call {
1434 type_annotation, ..
1435 } => type_annotation,
1436 }
1437 }
1438
1439 pub fn with_type_annotation_opt(&self, type_annotation: Option<TypeName>) -> Expr {
1440 if let Some(type_annotation) = type_annotation {
1441 self.with_type_annotation(type_annotation)
1442 } else {
1443 self.clone()
1444 }
1445 }
1446
1447 pub fn with_type_annotation(&self, type_annotation: TypeName) -> Expr {
1448 let mut expr_copied = self.clone();
1449 expr_copied.with_type_annotation_mut(type_annotation);
1450 expr_copied
1451 }
1452
1453 pub fn with_type_annotation_mut(&mut self, type_annotation: TypeName) {
1454 let new_type_annotation = type_annotation;
1455
1456 match self {
1457 Expr::Identifier {
1458 type_annotation, ..
1459 }
1460 | Expr::Let {
1461 type_annotation, ..
1462 }
1463 | Expr::SelectField {
1464 type_annotation, ..
1465 }
1466 | Expr::SelectIndex {
1467 type_annotation, ..
1468 }
1469 | Expr::Sequence {
1470 type_annotation, ..
1471 }
1472 | Expr::Record {
1473 type_annotation, ..
1474 }
1475 | Expr::Tuple {
1476 type_annotation, ..
1477 }
1478 | Expr::Literal {
1479 type_annotation, ..
1480 }
1481 | Expr::Number {
1482 type_annotation, ..
1483 }
1484 | Expr::Flags {
1485 type_annotation, ..
1486 }
1487 | Expr::Boolean {
1488 type_annotation, ..
1489 }
1490 | Expr::Concat {
1491 type_annotation, ..
1492 }
1493 | Expr::ExprBlock {
1494 type_annotation, ..
1495 }
1496 | Expr::Not {
1497 type_annotation, ..
1498 }
1499 | Expr::GreaterThan {
1500 type_annotation, ..
1501 }
1502 | Expr::GreaterThanOrEqualTo {
1503 type_annotation, ..
1504 }
1505 | Expr::LessThanOrEqualTo {
1506 type_annotation, ..
1507 }
1508 | Expr::EqualTo {
1509 type_annotation, ..
1510 }
1511 | Expr::LessThan {
1512 type_annotation, ..
1513 }
1514 | Expr::Plus {
1515 type_annotation, ..
1516 }
1517 | Expr::Minus {
1518 type_annotation, ..
1519 }
1520 | Expr::Divide {
1521 type_annotation, ..
1522 }
1523 | Expr::Multiply {
1524 type_annotation, ..
1525 }
1526 | Expr::Cond {
1527 type_annotation, ..
1528 }
1529 | Expr::PatternMatch {
1530 type_annotation, ..
1531 }
1532 | Expr::Option {
1533 type_annotation, ..
1534 }
1535 | Expr::Result {
1536 type_annotation, ..
1537 }
1538 | Expr::Unwrap {
1539 type_annotation, ..
1540 }
1541 | Expr::Throw {
1542 type_annotation, ..
1543 }
1544 | Expr::And {
1545 type_annotation, ..
1546 }
1547 | Expr::Or {
1548 type_annotation, ..
1549 }
1550 | Expr::GetTag {
1551 type_annotation, ..
1552 }
1553 | Expr::Range {
1554 type_annotation, ..
1555 }
1556 | Expr::ListComprehension {
1557 type_annotation, ..
1558 }
1559 | Expr::ListReduce {
1560 type_annotation, ..
1561 }
1562 | Expr::InvokeMethodLazy {
1563 type_annotation, ..
1564 }
1565 | Expr::Length {
1566 type_annotation, ..
1567 }
1568 | Expr::GenerateWorkerName {
1569 type_annotation, ..
1570 }
1571 | Expr::Call {
1572 type_annotation, ..
1573 } => {
1574 *type_annotation = Some(new_type_annotation);
1575 }
1576 }
1577 }
1578
1579 pub fn with_source_span(&self, new_source_span: SourceSpan) -> Expr {
1580 let mut expr_copied = self.clone();
1581 expr_copied.with_source_span_mut(new_source_span);
1582 expr_copied
1583 }
1584
1585 pub fn with_source_span_mut(&mut self, new_source_span: SourceSpan) {
1586 match self {
1587 Expr::Identifier { source_span, .. }
1588 | Expr::Let { source_span, .. }
1589 | Expr::SelectField { source_span, .. }
1590 | Expr::SelectIndex { source_span, .. }
1591 | Expr::Sequence { source_span, .. }
1592 | Expr::Number { source_span, .. }
1593 | Expr::Record { source_span, .. }
1594 | Expr::Tuple { source_span, .. }
1595 | Expr::Literal { source_span, .. }
1596 | Expr::Flags { source_span, .. }
1597 | Expr::Boolean { source_span, .. }
1598 | Expr::Concat { source_span, .. }
1599 | Expr::ExprBlock { source_span, .. }
1600 | Expr::Not { source_span, .. }
1601 | Expr::GreaterThan { source_span, .. }
1602 | Expr::GreaterThanOrEqualTo { source_span, .. }
1603 | Expr::LessThanOrEqualTo { source_span, .. }
1604 | Expr::EqualTo { source_span, .. }
1605 | Expr::LessThan { source_span, .. }
1606 | Expr::Plus { source_span, .. }
1607 | Expr::Minus { source_span, .. }
1608 | Expr::Divide { source_span, .. }
1609 | Expr::Multiply { source_span, .. }
1610 | Expr::Cond { source_span, .. }
1611 | Expr::PatternMatch { source_span, .. }
1612 | Expr::Option { source_span, .. }
1613 | Expr::Result { source_span, .. }
1614 | Expr::Unwrap { source_span, .. }
1615 | Expr::Throw { source_span, .. }
1616 | Expr::And { source_span, .. }
1617 | Expr::Or { source_span, .. }
1618 | Expr::GetTag { source_span, .. }
1619 | Expr::Range { source_span, .. }
1620 | Expr::ListComprehension { source_span, .. }
1621 | Expr::ListReduce { source_span, .. }
1622 | Expr::InvokeMethodLazy { source_span, .. }
1623 | Expr::Length { source_span, .. }
1624 | Expr::GenerateWorkerName { source_span, .. }
1625 | Expr::Call { source_span, .. } => {
1626 *source_span = new_source_span;
1627 }
1628 }
1629 }
1630
1631 pub fn with_inferred_type(&self, new_inferred_type: InferredType) -> Expr {
1632 let mut expr_copied = self.clone();
1633 expr_copied.with_inferred_type_mut(new_inferred_type);
1634 expr_copied
1635 }
1636
1637 pub fn with_inferred_type_mut(&mut self, new_inferred_type: InferredType) {
1640 match self {
1641 Expr::Identifier { inferred_type, .. }
1642 | Expr::Let { inferred_type, .. }
1643 | Expr::SelectField { inferred_type, .. }
1644 | Expr::SelectIndex { inferred_type, .. }
1645 | Expr::Sequence { inferred_type, .. }
1646 | Expr::Record { inferred_type, .. }
1647 | Expr::Tuple { inferred_type, .. }
1648 | Expr::Literal { inferred_type, .. }
1649 | Expr::Number { inferred_type, .. }
1650 | Expr::Flags { inferred_type, .. }
1651 | Expr::Boolean { inferred_type, .. }
1652 | Expr::Concat { inferred_type, .. }
1653 | Expr::ExprBlock { inferred_type, .. }
1654 | Expr::Not { inferred_type, .. }
1655 | Expr::GreaterThan { inferred_type, .. }
1656 | Expr::GreaterThanOrEqualTo { inferred_type, .. }
1657 | Expr::LessThanOrEqualTo { inferred_type, .. }
1658 | Expr::EqualTo { inferred_type, .. }
1659 | Expr::LessThan { inferred_type, .. }
1660 | Expr::Plus { inferred_type, .. }
1661 | Expr::Minus { inferred_type, .. }
1662 | Expr::Divide { inferred_type, .. }
1663 | Expr::Multiply { inferred_type, .. }
1664 | Expr::Cond { inferred_type, .. }
1665 | Expr::PatternMatch { inferred_type, .. }
1666 | Expr::Option { inferred_type, .. }
1667 | Expr::Result { inferred_type, .. }
1668 | Expr::Unwrap { inferred_type, .. }
1669 | Expr::Throw { inferred_type, .. }
1670 | Expr::And { inferred_type, .. }
1671 | Expr::Or { inferred_type, .. }
1672 | Expr::GetTag { inferred_type, .. }
1673 | Expr::ListComprehension { inferred_type, .. }
1674 | Expr::ListReduce { inferred_type, .. }
1675 | Expr::InvokeMethodLazy { inferred_type, .. }
1676 | Expr::Range { inferred_type, .. }
1677 | Expr::Length { inferred_type, .. }
1678 | Expr::GenerateWorkerName { inferred_type, .. }
1679 | Expr::Call { inferred_type, .. } => {
1680 *inferred_type = new_inferred_type;
1681 }
1682 }
1683 }
1684
1685 pub fn visit_expr_nodes_lazy<'a>(&'a mut self, queue: &mut VecDeque<&'a mut Expr>) {
1686 type_inference::collect_children_mut(self, queue);
1687 }
1688
1689 pub fn number_inferred(
1690 big_decimal: BigDecimal,
1691 type_annotation: Option<TypeName>,
1692 inferred_type: InferredType,
1693 ) -> Expr {
1694 Expr::Number {
1695 number: Number { value: big_decimal },
1696 type_annotation,
1697 inferred_type,
1698 source_span: SourceSpan::default(),
1699 }
1700 }
1701
1702 pub fn number(big_decimal: BigDecimal) -> Expr {
1703 let default_type = DefaultType::from(&big_decimal);
1704 let inferred_type = InferredType::from(&default_type);
1705
1706 Expr::number_inferred(big_decimal, None, inferred_type)
1707 }
1708}
1709
1710#[derive(Debug, Hash, Clone, PartialEq, Eq, PartialOrd, Ord)]
1711pub enum Range {
1712 Range { from: Box<Expr>, to: Box<Expr> },
1713 RangeInclusive { from: Box<Expr>, to: Box<Expr> },
1714 RangeFrom { from: Box<Expr> },
1715}
1716
1717impl Range {
1718 pub fn from(&self) -> Option<&Expr> {
1719 match self {
1720 Range::Range { from, .. } => Some(from),
1721 Range::RangeInclusive { from, .. } => Some(from),
1722 Range::RangeFrom { from } => Some(from),
1723 }
1724 }
1725
1726 pub fn to(&self) -> Option<&Expr> {
1727 match self {
1728 Range::Range { to, .. } => Some(to),
1729 Range::RangeInclusive { to, .. } => Some(to),
1730 Range::RangeFrom { .. } => None,
1731 }
1732 }
1733
1734 pub fn inclusive(&self) -> bool {
1735 matches!(self, Range::RangeInclusive { .. })
1736 }
1737
1738 pub fn get_exprs_mut(&mut self) -> Vec<&mut Box<Expr>> {
1739 match self {
1740 Range::Range { from, to } => vec![from, to],
1741 Range::RangeInclusive { from, to } => vec![from, to],
1742 Range::RangeFrom { from } => vec![from],
1743 }
1744 }
1745
1746 pub fn get_exprs(&self) -> Vec<&Expr> {
1747 match self {
1748 Range::Range { from, to } => vec![from.as_ref(), to.as_ref()],
1749 Range::RangeInclusive { from, to } => vec![from.as_ref(), to.as_ref()],
1750 Range::RangeFrom { from } => vec![from.as_ref()],
1751 }
1752 }
1753}
1754
1755#[derive(Debug, Hash, Clone, PartialEq, Ord, PartialOrd)]
1756pub struct Number {
1757 pub value: BigDecimal,
1758}
1759
1760impl Eq for Number {}
1761
1762impl Number {
1763 pub fn to_val(&self, analysed_type: &WitType) -> Option<ValueAndType> {
1764 match analysed_type {
1765 WitType::F64(_) => self.value.to_f64().map(|v| v.into_value_and_type()),
1766 WitType::U64(_) => self.value.to_u64().map(|v| v.into_value_and_type()),
1767 WitType::F32(_) => self.value.to_f32().map(|v| v.into_value_and_type()),
1768 WitType::U32(_) => self.value.to_u32().map(|v| v.into_value_and_type()),
1769 WitType::S32(_) => self.value.to_i32().map(|v| v.into_value_and_type()),
1770 WitType::S64(_) => self.value.to_i64().map(|v| v.into_value_and_type()),
1771 WitType::U8(_) => self.value.to_u8().map(|v| v.into_value_and_type()),
1772 WitType::S8(_) => self.value.to_i8().map(|v| v.into_value_and_type()),
1773 WitType::U16(_) => self.value.to_u16().map(|v| v.into_value_and_type()),
1774 WitType::S16(_) => self.value.to_i16().map(|v| v.into_value_and_type()),
1775 _ => None,
1776 }
1777 }
1778}
1779
1780impl Display for Number {
1781 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1782 write!(f, "{}", self.value)
1783 }
1784}
1785
1786#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1787pub struct MatchArm {
1788 pub arm_pattern: ArmPattern,
1789 pub arm_resolution_expr: Box<Expr>,
1790}
1791
1792impl MatchArm {
1793 pub fn new(arm_pattern: ArmPattern, arm_resolution: Expr) -> MatchArm {
1794 MatchArm {
1795 arm_pattern,
1796 arm_resolution_expr: Box::new(arm_resolution),
1797 }
1798 }
1799}
1800
1801#[derive(Debug, Hash, Clone, PartialEq, Eq, Ord, PartialOrd)]
1802pub enum ArmPattern {
1803 WildCard,
1804 As(String, Box<ArmPattern>),
1805 Constructor(String, Vec<ArmPattern>),
1806 TupleConstructor(Vec<ArmPattern>),
1807 RecordConstructor(Vec<(String, ArmPattern)>),
1808 ListConstructor(Vec<ArmPattern>),
1809 Literal(Box<Expr>),
1810}
1811
1812impl ArmPattern {
1813 pub fn is_wildcard(&self) -> bool {
1814 matches!(self, ArmPattern::WildCard)
1815 }
1816
1817 pub fn is_literal_identifier(&self) -> bool {
1818 matches!(self, ArmPattern::Literal(expr) if expr.is_identifier())
1819 }
1820
1821 pub fn constructor(name: &str, patterns: Vec<ArmPattern>) -> ArmPattern {
1822 ArmPattern::Constructor(name.to_string(), patterns)
1823 }
1824
1825 pub fn literal(expr: Expr) -> ArmPattern {
1826 ArmPattern::Literal(Box::new(expr))
1827 }
1828
1829 pub fn get_expr_literals_mut(&mut self) -> Vec<&mut Box<Expr>> {
1830 match self {
1831 ArmPattern::Literal(expr) => vec![expr],
1832 ArmPattern::As(_, pattern) => pattern.get_expr_literals_mut(),
1833 ArmPattern::Constructor(_, patterns) => {
1834 let mut result = vec![];
1835 for pattern in patterns {
1836 result.extend(pattern.get_expr_literals_mut());
1837 }
1838 result
1839 }
1840 ArmPattern::TupleConstructor(patterns) => {
1841 let mut result = vec![];
1842 for pattern in patterns {
1843 result.extend(pattern.get_expr_literals_mut());
1844 }
1845 result
1846 }
1847 ArmPattern::RecordConstructor(patterns) => {
1848 let mut result = vec![];
1849 for (_, pattern) in patterns {
1850 result.extend(pattern.get_expr_literals_mut());
1851 }
1852 result
1853 }
1854 ArmPattern::ListConstructor(patterns) => {
1855 let mut result = vec![];
1856 for pattern in patterns {
1857 result.extend(pattern.get_expr_literals_mut());
1858 }
1859 result
1860 }
1861 ArmPattern::WildCard => vec![],
1862 }
1863 }
1864
1865 pub fn get_expr_literals(&self) -> Vec<&Expr> {
1866 match self {
1867 ArmPattern::Literal(expr) => vec![expr.as_ref()],
1868 ArmPattern::As(_, pattern) => pattern.get_expr_literals(),
1869 ArmPattern::Constructor(_, patterns) => {
1870 let mut result = vec![];
1871 for pattern in patterns {
1872 result.extend(pattern.get_expr_literals());
1873 }
1874 result
1875 }
1876 ArmPattern::TupleConstructor(patterns) => {
1877 let mut result = vec![];
1878 for pattern in patterns {
1879 result.extend(pattern.get_expr_literals());
1880 }
1881 result
1882 }
1883 ArmPattern::RecordConstructor(patterns) => {
1884 let mut result = vec![];
1885 for (_, pattern) in patterns {
1886 result.extend(pattern.get_expr_literals());
1887 }
1888 result
1889 }
1890 ArmPattern::ListConstructor(patterns) => {
1891 let mut result = vec![];
1892 for pattern in patterns {
1893 result.extend(pattern.get_expr_literals());
1894 }
1895 result
1896 }
1897 ArmPattern::WildCard => vec![],
1898 }
1899 }
1900 pub fn ok(binding_variable: &str) -> ArmPattern {
1902 ArmPattern::Literal(Box::new(Expr::Result {
1903 expr: Ok(Box::new(Expr::Identifier {
1904 variable_id: VariableId::global(binding_variable.to_string()),
1905 type_annotation: None,
1906 inferred_type: InferredType::unknown(),
1907 source_span: SourceSpan::default(),
1908 })),
1909 type_annotation: None,
1910 inferred_type: InferredType::result(
1911 Some(InferredType::unknown()),
1912 Some(InferredType::unknown()),
1913 ),
1914 source_span: SourceSpan::default(),
1915 }))
1916 }
1917
1918 pub fn err(binding_variable: &str) -> ArmPattern {
1920 ArmPattern::Literal(Box::new(Expr::Result {
1921 expr: Err(Box::new(Expr::Identifier {
1922 variable_id: VariableId::global(binding_variable.to_string()),
1923 type_annotation: None,
1924 inferred_type: InferredType::unknown(),
1925 source_span: SourceSpan::default(),
1926 })),
1927 type_annotation: None,
1928 inferred_type: InferredType::result(
1929 Some(InferredType::unknown()),
1930 Some(InferredType::unknown()),
1931 ),
1932 source_span: SourceSpan::default(),
1933 }))
1934 }
1935
1936 pub fn some(binding_variable: &str) -> ArmPattern {
1938 ArmPattern::Literal(Box::new(Expr::Option {
1939 expr: Some(Box::new(Expr::Identifier {
1940 variable_id: VariableId::local_with_no_id(binding_variable),
1941 type_annotation: None,
1942 inferred_type: InferredType::unknown(),
1943 source_span: SourceSpan::default(),
1944 })),
1945 type_annotation: None,
1946 inferred_type: InferredType::unknown(),
1947 source_span: SourceSpan::default(),
1948 }))
1949 }
1950
1951 pub fn none() -> ArmPattern {
1952 ArmPattern::Literal(Box::new(Expr::Option {
1953 expr: None,
1954 type_annotation: None,
1955 inferred_type: InferredType::unknown(),
1956 source_span: SourceSpan::default(),
1957 }))
1958 }
1959
1960 pub fn identifier(binding_variable: &str) -> ArmPattern {
1961 ArmPattern::Literal(Box::new(Expr::Identifier {
1962 variable_id: VariableId::global(binding_variable.to_string()),
1963 type_annotation: None,
1964 inferred_type: InferredType::unknown(),
1965 source_span: SourceSpan::default(),
1966 }))
1967 }
1968 pub fn custom_constructor(name: &str, args: Vec<ArmPattern>) -> ArmPattern {
1969 ArmPattern::Constructor(name.to_string(), args)
1970 }
1971}
1972
1973impl Display for Expr {
1974 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1975 write!(f, "{}", text::to_string(self).unwrap())
1976 }
1977}
1978
1979impl Display for ArmPattern {
1980 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1981 write!(f, "{}", text::to_string_arm_pattern(self).unwrap())
1982 }
1983}
1984
1985impl<'de> Deserialize<'de> for Expr {
1986 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1987 where
1988 D: serde::Deserializer<'de>,
1989 {
1990 let value = Value::deserialize(deserializer)?;
1991 match value {
1992 Value::String(expr_string) => match from_string(expr_string.as_str()) {
1993 Ok(expr) => Ok(expr),
1994 Err(message) => Err(serde::de::Error::custom(message.to_string())),
1995 },
1996
1997 e => Err(serde::de::Error::custom(format!(
1998 "Failed to deserialize expression {e}"
1999 ))),
2000 }
2001 }
2002}
2003
2004impl Serialize for Expr {
2005 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2006 where
2007 S: Serializer,
2008 {
2009 match text::to_string(self) {
2010 Ok(value) => Value::serialize(&Value::String(value), serializer),
2011 Err(error) => Err(serde::ser::Error::custom(error.to_string())),
2012 }
2013 }
2014}
2015
2016fn find_expr(expr: &mut Expr, source_span: &SourceSpan) -> Option<Expr> {
2017 let mut expr = expr.clone();
2018 let mut found = None;
2019
2020 type_inference::visit_post_order_rev_mut(&mut expr, &mut |current| {
2021 if found.is_none() {
2022 let span = current.source_span();
2023 if source_span.eq(&span) {
2024 found = Some(current.clone());
2025 }
2026 }
2027 });
2028
2029 found
2030}