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