1use crate::ast::{
78 BinOp, CEStatement, DuTypeDef, Expr, Import, Literal, LoadDirective, MatchArm, ModuleDef,
79 ModuleItem, Pattern, Program, TypeDefinition, TypeExpr, VariantDef,
80};
81use crate::lexer::{Position, Token, TokenWithPos};
82use std::fmt;
83
84#[derive(Debug, Clone, PartialEq)]
86pub enum ParseError {
87 UnexpectedToken {
89 expected: String,
90 found: Token,
91 pos: Position,
92 },
93 UnexpectedEof { expected: String },
95 InvalidExpr { message: String, pos: Position },
97}
98
99impl fmt::Display for ParseError {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101 match self {
102 ParseError::UnexpectedToken {
103 expected,
104 found,
105 pos,
106 } => {
107 write!(
108 f,
109 "Parse error at {}: expected {}, found {}",
110 pos, expected, found
111 )
112 }
113 ParseError::UnexpectedEof { expected } => {
114 write!(
115 f,
116 "Parse error: unexpected end of file, expected {}",
117 expected
118 )
119 }
120 ParseError::InvalidExpr { message, pos } => {
121 write!(f, "Parse error at {}: {}", pos, message)
122 }
123 }
124 }
125}
126
127impl std::error::Error for ParseError {}
128
129type Result<T> = std::result::Result<T, ParseError>;
130
131enum LetResult {
133 Item(ModuleItem),
134 Expr(Expr),
135}
136
137pub struct Parser {
139 tokens: Vec<TokenWithPos>,
140 pos: usize,
141}
142
143impl Parser {
144 pub fn new(tokens: Vec<TokenWithPos>) -> Self {
146 Parser { tokens, pos: 0 }
147 }
148
149 pub fn parse(&mut self) -> Result<Expr> {
154 let expr = self.parse_expr()?;
155
156 if !self.is_at_end() {
158 let tok = self.current_token();
159 return Err(ParseError::UnexpectedToken {
160 expected: "end of input".to_string(),
161 found: tok.token.clone(),
162 pos: tok.pos,
163 });
164 }
165
166 Ok(expr)
167 }
168
169 pub fn parse_program(&mut self) -> Result<Program> {
173 let mut directives = vec![];
174 let mut imports = vec![];
175 let mut modules = vec![];
176 let mut items = vec![];
177 let mut main_expr = None;
178
179 while let Some(Token::LoadDirective(_)) = self.peek() {
181 directives.push(self.parse_load_directive()?);
182 }
183
184 while self.peek() == Some(&Token::Open) {
186 imports.push(self.parse_import()?);
187 }
188
189 while self.peek() == Some(&Token::Module) {
191 modules.push(self.parse_module()?);
192 }
193
194 while !self.is_at_end() {
196 let tok = self.current_token();
197 match tok.token {
198 Token::Let => {
199 let binding = self.parse_let_binding_or_expr()?;
202 match binding {
203 LetResult::Item(item) => items.push(item),
204 LetResult::Expr(expr) => {
205 main_expr = Some(expr);
206 break;
213 }
214 }
215 }
216 Token::Do => {
217 self.advance();
219 let expr = self.parse_expr()?;
220 items.push(ModuleItem::Let(None, expr));
221 }
222 Token::Type => {
223 let type_def = self.parse_type_def()?;
224 items.push(ModuleItem::TypeDef(type_def));
225 }
226 _ => {
227 let expr = self.parse_expr()?;
229 main_expr = Some(expr);
230 break;
231 }
232 }
233 }
234
235 Ok(Program {
236 directives,
237 modules,
238 imports,
239 items,
240 main_expr,
241 })
242 }
243
244 fn parse_module(&mut self) -> Result<ModuleDef> {
246 self.expect_token(Token::Module)?;
247 let name = self.expect_ident()?;
248 self.expect_token(Token::Eq)?;
249
250 let items = self.parse_module_items()?;
251
252 Ok(ModuleDef { name, items })
253 }
254
255 fn parse_module_items(&mut self) -> Result<Vec<ModuleItem>> {
257 let mut items = vec![];
258
259 while !self.is_at_end()
261 && self.peek() != Some(&Token::Module)
262 && self.peek() != Some(&Token::Open)
263 {
264 let tok = &self.current_token().token;
265
266 match tok {
267 Token::Let => {
268 let result = self.parse_let_binding_or_expr()?;
275 match result {
276 LetResult::Item(item) => items.push(item),
277 LetResult::Expr(_) => {
278 return Err(ParseError::UnexpectedToken {
279 expected: "module item".to_string(),
280 found: Token::In,
281 pos: self.current_token().pos,
282 });
283 }
284 }
285 }
286 Token::Do => {
287 self.advance();
289 let expr = self.parse_expr()?;
290 items.push(ModuleItem::Let(None, expr));
291 }
292 Token::Type => {
293 let type_def = self.parse_type_def()?;
294 items.push(ModuleItem::TypeDef(type_def));
295 }
296 _ => break,
297 }
298 }
299
300 Ok(items)
301 }
302
303 fn parse_let_binding_or_expr(&mut self) -> Result<LetResult> {
305 self.expect_token(Token::Let)?;
306
307 let is_rec = self.match_token(&Token::Rec);
309
310 if is_rec {
311 let first_name = self.expect_ident()?;
313 let mut params = vec![];
314 while let Token::Ident(_) = &self.current_token().token {
315 params.push(self.expect_ident()?);
316 }
317
318 self.expect_token(Token::Eq)?;
319 let mut first_value = self.parse_expr()?;
320
321 if !params.is_empty() {
323 first_value =
324 params
325 .into_iter()
326 .rev()
327 .fold(first_value, |acc, param| Expr::Lambda {
328 param,
329 body: Box::new(acc),
330 });
331 }
332
333 if self.match_token(&Token::AndKeyword) {
335 let mut bindings = vec![(first_name, first_value)];
336
337 loop {
338 let name = self.expect_ident()?;
339 let mut params = vec![];
340 while let Token::Ident(_) = &self.current_token().token {
341 params.push(self.expect_ident()?);
342 }
343 self.expect_token(Token::Eq)?;
344 let mut value = self.parse_expr()?;
345
346 if !params.is_empty() {
347 value = params
348 .into_iter()
349 .rev()
350 .fold(value, |acc, param| Expr::Lambda {
351 param,
352 body: Box::new(acc),
353 });
354 }
355 bindings.push((name, value));
356
357 if !self.match_token(&Token::AndKeyword) {
358 break;
359 }
360 }
361
362 if self.match_token(&Token::In) {
364 let body = self.parse_expr()?;
365 Ok(LetResult::Expr(Expr::LetRecMutual {
366 bindings,
367 body: Box::new(body),
368 }))
369 } else {
370 Ok(LetResult::Item(ModuleItem::LetRec(bindings)))
374 }
375 } else {
376 if self.match_token(&Token::In) {
380 let body = self.parse_expr()?;
381 Ok(LetResult::Expr(Expr::LetRec {
382 name: first_name,
383 value: Box::new(first_value),
384 body: Box::new(body),
385 }))
386 } else {
387 Ok(LetResult::Item(ModuleItem::LetRec(vec![(
388 first_name,
389 first_value,
390 )])))
391 }
392 }
393 } else {
394 let name = match &self.current_token().token {
397 Token::Underscore => {
398 self.advance();
399 None
400 }
401 Token::Ident(id) if id == "_" => {
402 self.advance();
403 None
404 }
405 _ => Some(self.expect_ident()?),
406 };
407
408 let mut params = vec![];
409 while let Token::Ident(_) = &self.current_token().token {
410 params.push(self.expect_ident()?);
411 }
412
413 self.expect_token(Token::Eq)?;
414 let mut value = self.parse_expr()?;
415
416 if !params.is_empty() {
417 value = params
418 .into_iter()
419 .rev()
420 .fold(value, |acc, param| Expr::Lambda {
421 param,
422 body: Box::new(acc),
423 });
424 }
425
426 if self.match_token(&Token::In) {
427 let body = self.parse_expr()?;
428 if name.is_none() {
430 return Err(ParseError::UnexpectedToken {
431 expected: "identifier".to_string(),
432 found: Token::Ident("_".to_string()),
433 pos: self.current_token().pos,
434 });
435 }
436 Ok(LetResult::Expr(Expr::Let {
437 name: name.unwrap(),
438 value: Box::new(value),
439 body: Box::new(body),
440 }))
441 } else {
442 Ok(LetResult::Item(ModuleItem::Let(name, value)))
443 }
444 }
445 }
446
447 fn parse_load_directive(&mut self) -> Result<LoadDirective> {
450 if let Some(Token::LoadDirective(path)) = self.peek() {
451 let path = path.clone();
452 self.advance();
453 Ok(LoadDirective { path })
454 } else {
455 let tok = self.current_token();
456 Err(ParseError::UnexpectedToken {
457 expected: "#load directive".to_string(),
458 found: tok.token.clone(),
459 pos: tok.pos,
460 })
461 }
462 }
463
464 fn parse_import(&mut self) -> Result<Import> {
465 self.expect_token(Token::Open)?;
466
467 let mut path = vec![self.expect_ident()?];
468
469 while self.check(&Token::Dot) {
471 self.advance();
472 path.push(self.expect_ident()?);
473 }
474
475 Ok(Import {
476 module_path: path,
477 is_qualified: false,
478 })
479 }
480
481 fn parse_type_def(&mut self) -> Result<TypeDefinition> {
483 let du_def = self.parse_du_type_def()?;
486 Ok(TypeDefinition::Du(du_def))
487 }
488
489 fn parse_expr(&mut self) -> Result<Expr> {
495 let tok = &self.current_token().token;
497 match tok {
498 Token::Let => self.parse_let(),
499 Token::If => self.parse_if(),
500 Token::Fun => self.parse_lambda(),
501 Token::Match => self.parse_match(),
502 Token::While => self.parse_while(),
503 Token::Break => {
504 self.advance();
505 Ok(Expr::Break)
506 }
507 Token::Continue => {
508 self.advance();
509 Ok(Expr::Continue)
510 }
511 _ => self.parse_pipeline_expr(), }
513 }
514
515 fn parse_let(&mut self) -> Result<Expr> {
517 self.expect_token(Token::Let)?;
518
519 if self.match_token(&Token::Rec) {
521 return self.parse_let_rec();
522 }
523
524 let name = self.expect_ident()?;
525
526 let mut params = vec![];
529 while let Token::Ident(_) = &self.current_token().token {
530 params.push(self.expect_ident()?);
531 }
532
533 self.expect_token(Token::Eq)?;
534 let mut value = self.parse_expr()?;
535
536 if !params.is_empty() {
539 value = params
540 .into_iter()
541 .rev()
542 .fold(value, |acc, param| Expr::Lambda {
543 param,
544 body: Box::new(acc),
545 });
546 }
547
548 self.expect_token(Token::In)?;
549 let body = self.parse_expr()?;
550
551 Ok(Expr::Let {
552 name,
553 value: Box::new(value),
554 body: Box::new(body),
555 })
556 }
557
558 fn parse_let_rec(&mut self) -> Result<Expr> {
560 let first_name = self.expect_ident()?;
562
563 let mut params = vec![];
565 while let Token::Ident(_) = &self.current_token().token {
566 params.push(self.expect_ident()?);
567 }
568
569 self.expect_token(Token::Eq)?;
570 let mut first_value = self.parse_expr()?;
571
572 if !params.is_empty() {
574 first_value = params
575 .into_iter()
576 .rev()
577 .fold(first_value, |acc, param| Expr::Lambda {
578 param,
579 body: Box::new(acc),
580 });
581 }
582
583 if self.match_token(&Token::AndKeyword) {
585 let mut bindings = vec![(first_name, first_value)];
586
587 loop {
588 let name = self.expect_ident()?;
589 let mut params = vec![];
590 while let Token::Ident(_) = &self.current_token().token {
591 params.push(self.expect_ident()?);
592 }
593 self.expect_token(Token::Eq)?;
594 let mut value = self.parse_expr()?;
595
596 if !params.is_empty() {
597 value = params
598 .into_iter()
599 .rev()
600 .fold(value, |acc, param| Expr::Lambda {
601 param,
602 body: Box::new(acc),
603 });
604 }
605 bindings.push((name, value));
606
607 if !self.match_token(&Token::AndKeyword) {
608 break;
609 }
610 }
611
612 self.expect_token(Token::In)?;
613 let body = self.parse_expr()?;
614
615 Ok(Expr::LetRecMutual {
616 bindings,
617 body: Box::new(body),
618 })
619 } else {
620 self.expect_token(Token::In)?;
622 let body = self.parse_expr()?;
623
624 Ok(Expr::LetRec {
625 name: first_name,
626 value: Box::new(first_value),
627 body: Box::new(body),
628 })
629 }
630 }
631
632 fn parse_if(&mut self) -> Result<Expr> {
634 self.expect_token(Token::If)?;
635
636 let cond = self.parse_expr()?;
637
638 self.expect_token(Token::Then)?;
639 let then_branch = self.parse_expr()?;
640
641 self.expect_token(Token::Else)?;
642 let else_branch = self.parse_expr()?;
643
644 Ok(Expr::If {
645 cond: Box::new(cond),
646 then_branch: Box::new(then_branch),
647 else_branch: Box::new(else_branch),
648 })
649 }
650
651 fn parse_lambda(&mut self) -> Result<Expr> {
653 self.expect_token(Token::Fun)?;
654
655 let mut params = vec![];
657 while let Token::Ident(_) = &self.current_token().token {
658 params.push(self.expect_ident()?);
659 }
660
661 if params.is_empty() {
662 let tok = self.current_token();
663 return Err(ParseError::UnexpectedToken {
664 expected: "parameter".to_string(),
665 found: tok.token.clone(),
666 pos: tok.pos,
667 });
668 }
669
670 self.expect_token(Token::Arrow)?;
671 let body = self.parse_expr()?;
672
673 Ok(params
676 .into_iter()
677 .rev()
678 .fold(body, |acc, param| Expr::Lambda {
679 param,
680 body: Box::new(acc),
681 }))
682 }
683
684 fn parse_match(&mut self) -> Result<Expr> {
686 self.expect_token(Token::Match)?;
687
688 let scrutinee = Box::new(self.parse_expr()?);
689
690 self.expect_token(Token::With)?;
691
692 let mut arms = vec![];
693
694 loop {
696 self.match_token(&Token::Pipe);
698
699 let pattern = self.parse_pattern()?;
700
701 self.expect_token(Token::Arrow)?;
702
703 let body = Box::new(self.parse_expr()?);
704
705 arms.push(MatchArm { pattern, body });
706
707 if !self.check(&Token::Pipe) {
709 break;
710 }
711 }
712
713 Ok(Expr::Match { scrutinee, arms })
714 }
715
716 fn parse_while(&mut self) -> Result<Expr> {
718 self.expect_token(Token::While)?;
719
720 let cond = Box::new(self.parse_expr()?);
721
722 self.expect_token(Token::Do)?;
723
724 let body = Box::new(self.parse_expr()?);
725
726 Ok(Expr::While { cond, body })
727 }
728
729 fn parse_pattern(&mut self) -> Result<Pattern> {
731 let tok = self.current_token();
732
733 match &tok.token {
734 Token::Underscore => {
735 self.advance();
736 Ok(Pattern::Wildcard)
737 }
738 Token::Ident(name) => {
739 let val = name.clone();
740 self.advance();
741
742 if Self::is_uppercase_ident(&val) {
744 if self.match_token(&Token::LParen) {
746 let mut patterns = vec![];
748
749 if !matches!(self.current_token().token, Token::RParen) {
750 loop {
751 patterns.push(self.parse_pattern()?);
752
753 if self.match_token(&Token::Comma) {
754 if matches!(self.current_token().token, Token::RParen) {
755 break;
756 }
757 } else {
758 break;
759 }
760 }
761 }
762
763 self.expect_token(Token::RParen)?;
764 Ok(Pattern::Variant {
765 variant: val,
766 patterns,
767 })
768 } else {
769 Ok(Pattern::Variant {
771 variant: val,
772 patterns: vec![],
773 })
774 }
775 } else {
776 Ok(Pattern::Var(val))
778 }
779 }
780 Token::Int(n) => {
781 let val = *n;
782 self.advance();
783 Ok(Pattern::Literal(Literal::Int(val)))
784 }
785 Token::Float(f) => {
786 let val = *f;
787 self.advance();
788 Ok(Pattern::Literal(Literal::Float(val)))
789 }
790 Token::Bool(b) => {
791 let val = *b;
792 self.advance();
793 Ok(Pattern::Literal(Literal::Bool(val)))
794 }
795 Token::String(s) => {
796 let val = s.clone();
797 self.advance();
798 Ok(Pattern::Literal(Literal::Str(val)))
799 }
800 Token::LParen => {
801 self.advance(); if self.match_token(&Token::RParen) {
805 return Ok(Pattern::Literal(Literal::Unit));
806 }
807
808 let first_pat = self.parse_pattern()?;
810
811 if self.match_token(&Token::Comma) {
813 let mut patterns = vec![first_pat];
815
816 if !matches!(self.current_token().token, Token::RParen) {
818 loop {
819 patterns.push(self.parse_pattern()?);
820
821 if self.match_token(&Token::Comma) {
822 if matches!(self.current_token().token, Token::RParen) {
824 break;
825 }
826 } else {
827 break;
828 }
829 }
830 }
831
832 self.expect_token(Token::RParen)?;
833 Ok(Pattern::Tuple(patterns))
834 } else {
835 self.expect_token(Token::RParen)?;
837 Ok(first_pat)
838 }
839 }
840 _ => Err(ParseError::UnexpectedToken {
841 expected: "pattern".to_string(),
842 found: tok.token.clone(),
843 pos: tok.pos,
844 }),
845 }
846 }
847
848 fn parse_or_expr(&mut self) -> Result<Expr> {
850 let mut left = self.parse_and_expr()?;
851
852 while self.match_token(&Token::Or) {
853 let right = self.parse_and_expr()?;
854 left = Expr::BinOp {
855 op: BinOp::Or,
856 left: Box::new(left),
857 right: Box::new(right),
858 };
859 }
860
861 Ok(left)
862 }
863
864 fn parse_and_expr(&mut self) -> Result<Expr> {
866 let mut left = self.parse_comp_expr()?;
867
868 while self.match_token(&Token::And) {
869 let right = self.parse_comp_expr()?;
870 left = Expr::BinOp {
871 op: BinOp::And,
872 left: Box::new(left),
873 right: Box::new(right),
874 };
875 }
876
877 Ok(left)
878 }
879
880 fn parse_comp_expr(&mut self) -> Result<Expr> {
882 let left = self.parse_cons_expr()?;
883
884 if let Some(op) = self.match_comparison_op() {
885 let right = self.parse_cons_expr()?;
886 Ok(Expr::BinOp {
887 op,
888 left: Box::new(left),
889 right: Box::new(right),
890 })
891 } else {
892 Ok(left)
893 }
894 }
895
896 fn parse_cons_expr(&mut self) -> Result<Expr> {
898 let left = self.parse_add_expr()?;
899
900 if self.match_token(&Token::ColonColon) {
901 let right = self.parse_cons_expr()?; Ok(Expr::Cons {
903 head: Box::new(left),
904 tail: Box::new(right),
905 })
906 } else {
907 Ok(left)
908 }
909 }
910
911 fn parse_add_expr(&mut self) -> Result<Expr> {
913 let mut left = self.parse_mul_expr()?;
914
915 while let Some(op) = self.match_add_op() {
916 let right = self.parse_mul_expr()?;
917 left = Expr::BinOp {
918 op,
919 left: Box::new(left),
920 right: Box::new(right),
921 };
922 }
923
924 Ok(left)
925 }
926
927 fn parse_mul_expr(&mut self) -> Result<Expr> {
929 let mut left = self.parse_unary_expr()?;
930
931 while let Some(op) = self.match_mul_op() {
932 let right = self.parse_unary_expr()?;
933 left = Expr::BinOp {
934 op,
935 left: Box::new(left),
936 right: Box::new(right),
937 };
938 }
939
940 Ok(left)
941 }
942
943 fn parse_unary_expr(&mut self) -> Result<Expr> {
945 if self.match_token(&Token::Minus) {
946 let expr = self.parse_unary_expr()?;
947 Ok(Expr::BinOp {
949 op: BinOp::Sub,
950 left: Box::new(Expr::Lit(Literal::Int(0))),
951 right: Box::new(expr),
952 })
953 } else {
954 self.parse_app_expr()
955 }
956 }
957
958 fn parse_pipeline_expr(&mut self) -> Result<Expr> {
960 let mut left = self.parse_or_expr()?;
961
962 while self.match_token(&Token::PipeRight) {
963 let func_expr = self.parse_app_expr()?; left = Expr::App {
965 func: Box::new(func_expr),
966 arg: Box::new(left),
967 };
968 }
969
970 Ok(left)
971 }
972
973 fn parse_app_expr(&mut self) -> Result<Expr> {
975 let mut func = self.parse_postfix_expr()?;
976
977 while self.is_primary_start() {
979 if self.current_token().pos.column == 1 {
982 break;
983 }
984
985 let arg = self.parse_postfix_expr()?;
986 func = Expr::App {
987 func: Box::new(func),
988 arg: Box::new(arg),
989 };
990 }
991
992 func = self.convert_variant_app_to_construct(func);
995
996 Ok(func)
997 }
998
999 fn convert_variant_app_to_construct(&self, expr: Expr) -> Expr {
1010 match expr {
1011 Expr::App { func, arg } => {
1012 let (variant_opt, mut args) = self.extract_variant_and_args(*func, vec![]);
1014 args.push(*arg);
1015
1016 if let Some((type_name, variant)) = variant_opt {
1017 Expr::VariantConstruct {
1019 type_name,
1020 variant,
1021 fields: args.into_iter().map(Box::new).collect(),
1022 }
1023 } else {
1024 self.rebuild_app_from_args(args)
1027 }
1028 }
1029 _ => expr,
1030 }
1031 }
1032 fn extract_variant_and_args(
1036 &self,
1037 func: Expr,
1038 mut current_args: Vec<Expr>,
1039 ) -> (Option<(String, String)>, Vec<Expr>) {
1040 match func {
1041 Expr::VariantConstruct {
1042 type_name,
1043 variant,
1044 fields,
1045 } => {
1046 let mut all_fields: Vec<Expr> = fields.into_iter().map(|b| *b).collect();
1049 all_fields.extend(current_args);
1050 (Some((type_name, variant)), all_fields)
1051 }
1052 Expr::App {
1053 func: inner_func,
1054 arg,
1055 } => {
1056 current_args.insert(0, *arg);
1058 self.extract_variant_and_args(*inner_func, current_args)
1059 }
1060 _ => {
1061 current_args.insert(0, func);
1063 (None, current_args)
1064 }
1065 }
1066 }
1067
1068 fn extract_app_chain(&self, expr: Expr) -> (Expr, Vec<Expr>) {
1070 match expr {
1071 Expr::App { func, arg } => {
1072 let (leftmost, mut args) = self.extract_app_chain(*func);
1073 args.push(*arg);
1074 (leftmost, args)
1075 }
1076 _ => (expr, vec![]),
1077 }
1078 }
1079
1080 fn rebuild_app_from_args(&self, mut exprs: Vec<Expr>) -> Expr {
1082 if exprs.is_empty() {
1083 return Expr::Lit(Literal::Unit); }
1085
1086 let mut result = exprs.remove(0);
1087 for arg in exprs {
1088 result = Expr::App {
1089 func: Box::new(result),
1090 arg: Box::new(arg),
1091 };
1092 }
1093 result
1094 }
1095
1096 fn parse_postfix_expr(&mut self) -> Result<Expr> {
1098 let mut expr = self.parse_primary()?;
1099
1100 loop {
1101 let tok = &self.current_token().token;
1102 match tok {
1103 Token::Dot => {
1105 self.advance(); if self.match_token(&Token::LBracket) {
1108 let index = Box::new(self.parse_expr()?);
1109 self.expect_token(Token::RBracket)?;
1110
1111 if self.match_token(&Token::LArrow) {
1113 let value = Box::new(self.parse_expr()?);
1114 expr = Expr::ArrayUpdate {
1115 array: Box::new(expr),
1116 index,
1117 value,
1118 };
1119 } else {
1120 expr = Expr::ArrayIndex {
1121 array: Box::new(expr),
1122 index,
1123 };
1124 }
1125 } else {
1126 let field = self.expect_ident()?;
1128
1129 let is_module =
1133 matches!(&expr, Expr::Var(name) if Self::is_uppercase_ident(name));
1134
1135 if self.current_token().token == Token::LParen && !is_module {
1138 self.advance(); let mut args = vec![];
1142
1143 if !matches!(self.current_token().token, Token::RParen) {
1145 loop {
1146 args.push(self.parse_expr()?);
1147
1148 if !self.match_token(&Token::Comma) {
1149 break;
1150 }
1151 }
1152 }
1153
1154 self.expect_token(Token::RParen)?;
1155
1156 expr = Expr::MethodCall {
1157 receiver: Box::new(expr),
1158 method_name: field,
1159 args,
1160 };
1161 } else {
1162 expr = Expr::RecordAccess {
1164 record: Box::new(expr),
1165 field,
1166 };
1167 }
1168 }
1169 }
1170 _ => break,
1171 }
1172 }
1173
1174 Ok(expr)
1175 }
1176
1177 fn parse_record_literal(&mut self) -> Result<Expr> {
1179 self.expect_token(Token::LBrace)?;
1180
1181 if self.match_token(&Token::RBrace) {
1183 return Ok(Expr::RecordLiteral {
1184 type_name: String::new(),
1185 fields: vec![],
1186 });
1187 }
1188
1189 let save_pos = self.pos;
1196
1197 if let Ok(_first_ident) = self.expect_ident() {
1199 if self.match_token(&Token::With) {
1201 self.pos = save_pos;
1204 let record = Box::new(self.parse_expr()?);
1205
1206 self.expect_token(Token::With)?;
1208
1209 let mut fields = vec![];
1211
1212 loop {
1213 let field_name = self.expect_ident()?;
1214 self.expect_token(Token::Eq)?;
1215 let value = self.parse_expr()?;
1216 fields.push((field_name, Box::new(value)));
1217
1218 if self.match_token(&Token::Semicolon) {
1220 if matches!(self.current_token().token, Token::RBrace) {
1222 break;
1223 }
1224 } else {
1225 break;
1226 }
1227 }
1228
1229 self.expect_token(Token::RBrace)?;
1230
1231 return Ok(Expr::RecordUpdate { record, fields });
1232 }
1233 }
1234
1235 self.pos = save_pos;
1237
1238 let mut fields = vec![];
1240
1241 loop {
1242 let field_name = self.expect_ident()?;
1243 self.expect_token(Token::Eq)?;
1244 let value = self.parse_expr()?;
1245 fields.push((field_name, Box::new(value)));
1246
1247 if self.match_token(&Token::Semicolon) {
1249 if matches!(self.current_token().token, Token::RBrace) {
1251 break;
1252 }
1253 } else {
1254 break;
1255 }
1256 }
1257
1258 self.expect_token(Token::RBrace)?;
1259
1260 Ok(Expr::RecordLiteral {
1261 type_name: String::new(),
1262 fields,
1263 })
1264 }
1265
1266 fn parse_anonymous_record_literal(&mut self) -> Result<Expr> {
1270 self.expect_token(Token::LBracePipe)?;
1271
1272 if self.match_token(&Token::PipeRBrace) {
1274 return Ok(Expr::RecordLiteral {
1275 type_name: String::new(),
1276 fields: vec![],
1277 });
1278 }
1279
1280 let mut fields = vec![];
1283
1284 loop {
1285 let field_name = self.expect_ident()?;
1286 self.expect_token(Token::Eq)?;
1287 let value = self.parse_expr()?;
1288 fields.push((field_name, Box::new(value)));
1289
1290 if self.match_token(&Token::Semicolon) {
1292 if matches!(self.current_token().token, Token::PipeRBrace) {
1294 break;
1295 }
1296 } else if matches!(self.current_token().token, Token::PipeRBrace) {
1297 break;
1299 } else {
1300 let tok = self.current_token();
1302 return Err(ParseError::UnexpectedToken {
1303 expected: "';' or '|}'".to_string(),
1304 found: tok.token.clone(),
1305 pos: tok.pos,
1306 });
1307 }
1308 }
1309
1310 self.expect_token(Token::PipeRBrace)?;
1311
1312 Ok(Expr::RecordLiteral {
1313 type_name: String::new(), fields,
1315 })
1316 }
1317
1318 fn parse_variant_construct(&mut self, variant_name: String) -> Result<Expr> {
1320 if self.match_token(&Token::LParen) {
1322 let mut fields = vec![];
1324
1325 if !matches!(self.current_token().token, Token::RParen) {
1327 loop {
1328 fields.push(Box::new(self.parse_expr()?));
1329
1330 if self.match_token(&Token::Comma) {
1331 if matches!(self.current_token().token, Token::RParen) {
1333 break;
1334 }
1335 } else {
1336 break;
1337 }
1338 }
1339 }
1340
1341 self.expect_token(Token::RParen)?;
1342 Ok(Expr::VariantConstruct {
1343 type_name: String::new(), variant: variant_name,
1345 fields,
1346 })
1347 } else {
1348 Ok(Expr::VariantConstruct {
1351 type_name: String::new(),
1352 variant: variant_name,
1353 fields: vec![],
1354 })
1355 }
1356 }
1357
1358 fn is_uppercase_ident(s: &str) -> bool {
1360 s.chars().next().is_some_and(|c| c.is_uppercase())
1361 }
1362
1363 fn parse_primary(&mut self) -> Result<Expr> {
1365 let tok = self.current_token();
1366
1367 match &tok.token {
1368 Token::Int(n) => {
1369 let val = *n;
1370 self.advance();
1371 Ok(Expr::Lit(Literal::Int(val)))
1372 }
1373 Token::Float(f) => {
1374 let val = *f;
1375 self.advance();
1376 Ok(Expr::Lit(Literal::Float(val)))
1377 }
1378 Token::Bool(b) => {
1379 let val = *b;
1380 self.advance();
1381 Ok(Expr::Lit(Literal::Bool(val)))
1382 }
1383 Token::String(s) => {
1384 let val = s.clone();
1385 self.advance();
1386 Ok(Expr::Lit(Literal::Str(val)))
1387 }
1388 Token::Ident(name) => {
1389 let val = name.clone();
1390 self.advance();
1391
1392 if val == "Array" && self.match_token(&Token::Dot) {
1394 let method = self.expect_ident()?;
1395 if method == "length" {
1396 let arr = Box::new(self.parse_postfix_expr()?);
1397 return Ok(Expr::ArrayLength(arr));
1398 } else {
1399 let record = Expr::Var("Array".to_string());
1401 return Ok(Expr::RecordAccess {
1402 record: Box::new(record),
1403 field: method,
1404 });
1405 }
1406 }
1407
1408 if (Self::is_uppercase_ident(&val) && !self.check(&Token::Dot))
1412 || matches!(self.current_token().token, Token::LParen)
1413 {
1414 self.parse_variant_construct(val)
1416 } else {
1417 Ok(Expr::Var(val))
1419 }
1420 }
1421 Token::LParen => {
1422 self.advance(); if self.match_token(&Token::RParen) {
1426 return Ok(Expr::Lit(Literal::Unit));
1427 }
1428
1429 let first_expr = self.parse_expr()?;
1431
1432 if self.match_token(&Token::Comma) {
1434 let mut elements = vec![first_expr];
1436
1437 if !matches!(self.current_token().token, Token::RParen) {
1439 loop {
1441 elements.push(self.parse_expr()?);
1442
1443 if self.match_token(&Token::Comma) {
1444 if matches!(self.current_token().token, Token::RParen) {
1446 break;
1447 }
1448 } else {
1450 break;
1451 }
1452 }
1453 }
1454
1455 self.expect_token(Token::RParen)?;
1456 Ok(Expr::Tuple(elements))
1457 } else {
1458 self.expect_token(Token::RParen)?;
1460 Ok(first_expr)
1461 }
1462 }
1463 Token::LBracket => self.parse_list(),
1464 Token::LBracketPipe => self.parse_array(),
1465 Token::LBracePipe => self.parse_anonymous_record_literal(),
1466 Token::LBrace => self.parse_record_literal(),
1467 Token::Async => self.parse_computation_expr(),
1468 _ => {
1469 let tok = self.current_token();
1470 Err(ParseError::UnexpectedToken {
1471 expected: "expression".to_string(),
1472 found: tok.token.clone(),
1473 pos: tok.pos,
1474 })
1475 }
1476 }
1477 }
1478
1479 fn parse_list(&mut self) -> Result<Expr> {
1484 self.expect_token(Token::LBracket)?;
1485
1486 if self.match_token(&Token::RBracket) {
1488 return Ok(Expr::List(vec![]));
1489 }
1490
1491 let mut elements = vec![];
1493
1494 loop {
1495 elements.push(self.parse_expr()?);
1496
1497 if self.match_token(&Token::Comma) || self.match_token(&Token::Semicolon) {
1499 if matches!(self.current_token().token, Token::RBracket) {
1501 break;
1502 }
1503 } else {
1505 break;
1506 }
1507 }
1508
1509 self.expect_token(Token::RBracket)?;
1510
1511 Ok(Expr::List(elements))
1512 }
1513
1514 fn parse_array(&mut self) -> Result<Expr> {
1516 self.expect_token(Token::LBracketPipe)?;
1517
1518 if self.match_token(&Token::PipeRBracket) {
1520 return Ok(Expr::Array(vec![]));
1521 }
1522
1523 let mut elements = vec![];
1525
1526 loop {
1527 elements.push(self.parse_expr()?);
1528
1529 if self.match_token(&Token::Semicolon) {
1531 if matches!(self.current_token().token, Token::PipeRBracket) {
1533 break;
1534 }
1535 } else {
1537 break;
1538 }
1539 }
1540
1541 self.expect_token(Token::PipeRBracket)?;
1542
1543 Ok(Expr::Array(elements))
1544 }
1545
1546 pub fn parse_du_type_def(&mut self) -> Result<DuTypeDef> {
1548 self.expect_token(Token::Type)?;
1549
1550 let type_name = self.expect_ident()?;
1551
1552 self.expect_token(Token::Eq)?;
1553
1554 let mut variants = vec![];
1556
1557 if self.match_token(&Token::Pipe) {
1559 let tok = self.current_token();
1562 if !matches!(&tok.token, Token::Ident(_)) {
1563 return Err(ParseError::UnexpectedToken {
1564 expected: "variant name".to_string(),
1565 found: tok.token.clone(),
1566 pos: tok.pos,
1567 });
1568 }
1569 }
1570
1571 loop {
1572 let variant_name = self.expect_ident()?;
1573
1574 let fields = if self.match_token(&Token::Of) {
1576 let mut field_types = vec![];
1577
1578 loop {
1579 let ty = self.parse_type_expr()?;
1580 field_types.push(ty);
1581
1582 if !self.match_token(&Token::Star) {
1584 break;
1585 }
1586 }
1587
1588 field_types
1589 } else {
1590 vec![]
1591 };
1592
1593 variants.push(VariantDef {
1594 name: variant_name,
1595 fields,
1596 });
1597
1598 if !self.match_token(&Token::Pipe) {
1600 break;
1601 }
1602 }
1603
1604 Ok(DuTypeDef {
1605 name: type_name,
1606 variants,
1607 })
1608 }
1609
1610 fn parse_type_expr(&mut self) -> Result<TypeExpr> {
1612 let left = self.parse_simple_type()?;
1616
1617 if self.match_token(&Token::Arrow) {
1619 let right = self.parse_type_expr()?; return Ok(TypeExpr::Function(Box::new(left), Box::new(right)));
1621 }
1622
1623 Ok(left)
1624 }
1625
1626 fn parse_simple_type(&mut self) -> Result<TypeExpr> {
1628 let name = self.expect_ident()?;
1629 Ok(TypeExpr::Named(name))
1630 }
1631
1632 fn parse_computation_expr(&mut self) -> Result<Expr> {
1643 let builder = match &self.current_token().token {
1645 Token::Async => {
1646 self.advance(); "async".to_string()
1648 }
1649 _ => {
1650 let tok = self.current_token();
1651 return Err(ParseError::UnexpectedToken {
1652 expected: "computation expression keyword".to_string(),
1653 found: tok.token.clone(),
1654 pos: tok.pos,
1655 });
1656 }
1657 };
1658
1659 self.expect_token(Token::LBrace)?;
1661
1662 let mut body = Vec::new();
1664 while !self.check(&Token::RBrace) && !self.is_at_end() {
1665 body.push(self.parse_ce_statement()?);
1666 self.match_token(&Token::Semicolon);
1668 }
1669
1670 self.expect_token(Token::RBrace)?;
1672
1673 Ok(Expr::ComputationExpr { builder, body })
1674 }
1675
1676 fn parse_ce_statement(&mut self) -> Result<CEStatement> {
1688 let tok = &self.current_token().token;
1689
1690 match tok {
1691 Token::LetBang => {
1692 self.advance(); let name = if self.match_token(&Token::Underscore) {
1694 "_".to_string()
1695 } else {
1696 self.expect_ident()?
1697 };
1698 self.expect_token(Token::Eq)?;
1699 let value = Box::new(self.parse_expr()?);
1700 Ok(CEStatement::LetBang { name, value })
1701 }
1702 Token::Let => {
1703 self.advance(); let name = if self.match_token(&Token::Underscore) {
1705 "_".to_string()
1706 } else {
1707 self.expect_ident()?
1708 };
1709 self.expect_token(Token::Eq)?;
1710 let value = Box::new(self.parse_expr()?);
1711 Ok(CEStatement::Let { name, value })
1712 }
1713 Token::DoBang => {
1714 self.advance(); let value = Box::new(self.parse_expr()?);
1716 Ok(CEStatement::DoBang { value })
1717 }
1718 Token::Return => {
1719 self.advance(); let value = Box::new(self.parse_expr()?);
1721 Ok(CEStatement::Return { value })
1722 }
1723 Token::ReturnBang => {
1724 self.advance(); let value = Box::new(self.parse_expr()?);
1726 Ok(CEStatement::ReturnBang { value })
1727 }
1728 Token::Yield => {
1729 self.advance(); let value = Box::new(self.parse_expr()?);
1731 Ok(CEStatement::Yield { value })
1732 }
1733 Token::YieldBang => {
1734 self.advance(); let value = Box::new(self.parse_expr()?);
1736 Ok(CEStatement::YieldBang { value })
1737 }
1738 _ => {
1739 let value = Box::new(self.parse_expr()?);
1741 Ok(CEStatement::Expr { value })
1742 }
1743 }
1744 }
1745
1746 fn current_token(&self) -> &TokenWithPos {
1752 if self.is_at_end() {
1753 static EOF_TOKEN: std::sync::OnceLock<TokenWithPos> = std::sync::OnceLock::new();
1755 EOF_TOKEN.get_or_init(|| TokenWithPos {
1756 token: Token::Eof,
1757 pos: Position::new(0, 0, 0),
1758 })
1759 } else {
1760 &self.tokens[self.pos]
1761 }
1762 }
1763
1764 fn peek(&self) -> Option<&Token> {
1766 if self.is_at_end() {
1767 None
1768 } else {
1769 Some(&self.tokens[self.pos].token)
1770 }
1771 }
1772
1773 fn check(&self, token: &Token) -> bool {
1775 !self.is_at_end() && &self.tokens[self.pos].token == token
1776 }
1777
1778 fn advance(&mut self) {
1780 if !self.is_at_end() {
1781 self.pos += 1;
1782 }
1783 }
1784
1785 fn is_at_end(&self) -> bool {
1787 self.pos >= self.tokens.len() || matches!(self.tokens[self.pos].token, Token::Eof)
1788 }
1789
1790 fn match_token(&mut self, token: &Token) -> bool {
1792 if self.check(token) {
1793 self.advance();
1794 true
1795 } else {
1796 false
1797 }
1798 }
1799
1800 fn expect_token(&mut self, expected: Token) -> Result<()> {
1802 if self.check(&expected) {
1803 self.advance();
1804 Ok(())
1805 } else {
1806 let tok = self.current_token();
1807 Err(ParseError::UnexpectedToken {
1808 expected: format!("{}", expected),
1809 found: tok.token.clone(),
1810 pos: tok.pos,
1811 })
1812 }
1813 }
1814
1815 fn expect_ident(&mut self) -> Result<String> {
1817 let tok = self.current_token();
1818 match &tok.token {
1819 Token::Ident(name) => {
1820 let val = name.clone();
1821 self.advance();
1822 Ok(val)
1823 }
1824 _ => Err(ParseError::UnexpectedToken {
1825 expected: "identifier".to_string(),
1826 found: tok.token.clone(),
1827 pos: tok.pos,
1828 }),
1829 }
1830 }
1831
1832 fn is_primary_start(&self) -> bool {
1834 if self.is_at_end() {
1835 return false;
1836 }
1837
1838 matches!(
1839 &self.current_token().token,
1840 Token::Int(_)
1841 | Token::Float(_)
1842 | Token::Bool(_)
1843 | Token::String(_)
1844 | Token::Ident(_)
1845 | Token::LParen
1846 | Token::LBracket
1847 | Token::LBracketPipe
1848 | Token::LBrace
1849 )
1850 }
1851
1852 fn match_comparison_op(&mut self) -> Option<BinOp> {
1854 let tok = &self.current_token().token;
1855 let op = match tok {
1856 Token::Eq => Some(BinOp::Eq),
1857 Token::EqEq => Some(BinOp::Eq),
1858 Token::Neq => Some(BinOp::Neq),
1859 Token::Lt => Some(BinOp::Lt),
1860 Token::Lte => Some(BinOp::Lte),
1861 Token::Gt => Some(BinOp::Gt),
1862 Token::Gte => Some(BinOp::Gte),
1863 _ => None,
1864 };
1865
1866 if op.is_some() {
1867 self.advance();
1868 }
1869
1870 op
1871 }
1872
1873 fn match_add_op(&mut self) -> Option<BinOp> {
1875 let tok = &self.current_token().token;
1876 let op = match tok {
1877 Token::Plus => Some(BinOp::Add),
1878 Token::Minus => Some(BinOp::Sub),
1879 Token::PlusPlus => Some(BinOp::Concat),
1880 _ => None,
1881 };
1882
1883 if op.is_some() {
1884 self.advance();
1885 }
1886
1887 op
1888 }
1889
1890 fn match_mul_op(&mut self) -> Option<BinOp> {
1892 let tok = &self.current_token().token;
1893 let op = match tok {
1894 Token::Star => Some(BinOp::Mul),
1895 Token::Slash => Some(BinOp::Div),
1896 _ => None,
1897 };
1898
1899 if op.is_some() {
1900 self.advance();
1901 }
1902
1903 op
1904 }
1905}
1906
1907#[cfg(test)]
1908mod tests {
1909 use super::*;
1910 use crate::lexer::Lexer;
1911
1912 fn parse_str(input: &str) -> Result<Expr> {
1913 let mut lexer = Lexer::new(input);
1914 let tokens = lexer.tokenize().unwrap();
1915 let mut parser = Parser::new(tokens);
1916 parser.parse()
1917 }
1918
1919 #[test]
1920 fn test_parse_int() {
1921 let expr = parse_str("42").unwrap();
1922 assert!(matches!(expr, Expr::Lit(Literal::Int(42))));
1923 }
1924
1925 #[test]
1926 fn test_parse_let() {
1927 let expr = parse_str("let x = 42 in x").unwrap();
1928 assert!(expr.is_let());
1929 }
1930
1931 #[test]
1932 fn test_parse_application() {
1933 let expr = parse_str("f x").unwrap();
1934 assert!(expr.is_app());
1935 }
1936
1937 #[test]
1938 fn test_parse_lambda() {
1939 let expr = parse_str("fun x -> x").unwrap();
1940 assert!(expr.is_lambda());
1941 }
1942
1943 #[test]
1944 fn test_parse_string_concat() {
1945 let expr = parse_str(r#""hello" ++ "world""#).unwrap();
1946 match expr {
1947 Expr::BinOp { op, left, right } => {
1948 assert_eq!(op, BinOp::Concat);
1949 assert!(matches!(*left, Expr::Lit(Literal::Str(_))));
1950 assert!(matches!(*right, Expr::Lit(Literal::Str(_))));
1951 }
1952 _ => panic!("Expected BinOp with Concat"),
1953 }
1954 }
1955
1956 #[test]
1957 fn test_parse_string_concat_chain() {
1958 let expr = parse_str(r#""a" ++ "b" ++ "c""#).unwrap();
1959 match expr {
1961 Expr::BinOp { op, left, right: _ } => {
1962 assert_eq!(op, BinOp::Concat);
1963 match *left {
1964 Expr::BinOp { op, .. } => {
1965 assert_eq!(op, BinOp::Concat);
1966 }
1967 _ => panic!("Expected nested BinOp"),
1968 }
1969 }
1970 _ => panic!("Expected BinOp"),
1971 }
1972 }
1973
1974 #[test]
1975 fn test_parse_concat_precedence() {
1976 let expr = parse_str(r#""http://" ++ host ++ ":" ++ port"#).unwrap();
1978 match expr {
1979 Expr::BinOp { op, .. } => {
1980 assert_eq!(op, BinOp::Concat);
1981 }
1982 _ => panic!("Expected BinOp"),
1983 }
1984 }
1985
1986 #[test]
1991 fn test_parse_async_block_empty() {
1992 let mut lexer = Lexer::new("async { }");
1993 let tokens = lexer.tokenize().unwrap();
1994 let mut parser = Parser::new(tokens);
1995 let expr = parser.parse().unwrap();
1996
1997 assert!(expr.is_computation_expr());
1998 match expr {
1999 Expr::ComputationExpr { builder, body } => {
2000 assert_eq!(builder, "async");
2001 assert_eq!(body.len(), 0);
2002 }
2003 _ => panic!("Expected ComputationExpr"),
2004 }
2005 }
2006
2007 #[test]
2008 fn test_parse_async_block_return() {
2009 let mut lexer = Lexer::new("async { return 42 }");
2010 let tokens = lexer.tokenize().unwrap();
2011 let mut parser = Parser::new(tokens);
2012 let expr = parser.parse().unwrap();
2013
2014 assert!(expr.is_computation_expr());
2015 match expr {
2016 Expr::ComputationExpr { builder, body } => {
2017 assert_eq!(builder, "async");
2018 assert_eq!(body.len(), 1);
2019 match &body[0] {
2020 CEStatement::Return { value } => {
2021 assert!(matches!(**value, Expr::Lit(Literal::Int(42))));
2022 }
2023 _ => panic!("Expected Return statement"),
2024 }
2025 }
2026 _ => panic!("Expected ComputationExpr"),
2027 }
2028 }
2029
2030 #[test]
2031 fn test_parse_let_bang() {
2032 let mut lexer = Lexer::new("async { let! x = op; return x }");
2033 let tokens = lexer.tokenize().unwrap();
2034 let mut parser = Parser::new(tokens);
2035 let expr = parser.parse().unwrap();
2036
2037 assert!(expr.is_computation_expr());
2038 match expr {
2039 Expr::ComputationExpr { builder, body } => {
2040 assert_eq!(builder, "async");
2041 assert_eq!(body.len(), 2);
2042
2043 match &body[0] {
2045 CEStatement::LetBang { name, value } => {
2046 assert_eq!(name, "x");
2047 assert!(matches!(**value, Expr::Var(_)));
2048 }
2049 _ => panic!("Expected LetBang statement"),
2050 }
2051
2052 match &body[1] {
2054 CEStatement::Return { value } => {
2055 assert!(matches!(**value, Expr::Var(_)));
2056 }
2057 _ => panic!("Expected Return statement"),
2058 }
2059 }
2060 _ => panic!("Expected ComputationExpr"),
2061 }
2062 }
2063
2064 #[test]
2065 fn test_parse_do_bang() {
2066 let mut lexer = Lexer::new("async { do! print 42 }");
2067 let tokens = lexer.tokenize().unwrap();
2068 let mut parser = Parser::new(tokens);
2069 let expr = parser.parse().unwrap();
2070
2071 match expr {
2072 Expr::ComputationExpr { builder, body } => {
2073 assert_eq!(builder, "async");
2074 assert_eq!(body.len(), 1);
2075 match &body[0] {
2076 CEStatement::DoBang { value } => {
2077 assert!(matches!(**value, Expr::App { .. }));
2078 }
2079 _ => panic!("Expected DoBang statement"),
2080 }
2081 }
2082 _ => panic!("Expected ComputationExpr"),
2083 }
2084 }
2085
2086 #[test]
2087 fn test_parse_regular_let_in_ce() {
2088 let mut lexer = Lexer::new("async { let x = 42; return x }");
2089 let tokens = lexer.tokenize().unwrap();
2090 let mut parser = Parser::new(tokens);
2091 let expr = parser.parse().unwrap();
2092
2093 match expr {
2094 Expr::ComputationExpr { builder, body } => {
2095 assert_eq!(builder, "async");
2096 assert_eq!(body.len(), 2);
2097
2098 match &body[0] {
2100 CEStatement::Let { name, value } => {
2101 assert_eq!(name, "x");
2102 assert!(matches!(**value, Expr::Lit(Literal::Int(42))));
2103 }
2104 _ => panic!("Expected Let statement"),
2105 }
2106 }
2107 _ => panic!("Expected ComputationExpr"),
2108 }
2109 }
2110
2111 #[test]
2112 fn test_parse_return_bang() {
2113 let mut lexer = Lexer::new("async { return! other }");
2114 let tokens = lexer.tokenize().unwrap();
2115 let mut parser = Parser::new(tokens);
2116 let expr = parser.parse().unwrap();
2117
2118 match expr {
2119 Expr::ComputationExpr { builder, body } => {
2120 assert_eq!(builder, "async");
2121 assert_eq!(body.len(), 1);
2122 match &body[0] {
2123 CEStatement::ReturnBang { value } => {
2124 assert!(matches!(**value, Expr::Var(_)));
2125 }
2126 _ => panic!("Expected ReturnBang statement"),
2127 }
2128 }
2129 _ => panic!("Expected ComputationExpr"),
2130 }
2131 }
2132
2133 #[test]
2134 fn test_parse_yield() {
2135 let mut lexer = Lexer::new("async { yield 1; yield 2 }");
2136 let tokens = lexer.tokenize().unwrap();
2137 let mut parser = Parser::new(tokens);
2138 let expr = parser.parse().unwrap();
2139
2140 match expr {
2141 Expr::ComputationExpr { builder, body } => {
2142 assert_eq!(builder, "async");
2143 assert_eq!(body.len(), 2);
2144 match &body[0] {
2145 CEStatement::Yield { value } => {
2146 assert!(matches!(**value, Expr::Lit(Literal::Int(1))));
2147 }
2148 _ => panic!("Expected Yield statement"),
2149 }
2150 }
2151 _ => panic!("Expected ComputationExpr"),
2152 }
2153 }
2154
2155 #[test]
2156 fn test_parse_yield_bang() {
2157 let mut lexer = Lexer::new("async { yield! sequence }");
2158 let tokens = lexer.tokenize().unwrap();
2159 let mut parser = Parser::new(tokens);
2160 let expr = parser.parse().unwrap();
2161
2162 match expr {
2163 Expr::ComputationExpr { builder, body } => {
2164 assert_eq!(builder, "async");
2165 assert_eq!(body.len(), 1);
2166 match &body[0] {
2167 CEStatement::YieldBang { value } => {
2168 assert!(matches!(**value, Expr::Var(_)));
2169 }
2170 _ => panic!("Expected YieldBang statement"),
2171 }
2172 }
2173 _ => panic!("Expected ComputationExpr"),
2174 }
2175 }
2176
2177 #[test]
2178 fn test_parse_plain_expr_in_ce() {
2179 let mut lexer = Lexer::new("async { 1 + 2 }");
2180 let tokens = lexer.tokenize().unwrap();
2181 let mut parser = Parser::new(tokens);
2182 let expr = parser.parse().unwrap();
2183
2184 match expr {
2185 Expr::ComputationExpr { builder, body } => {
2186 assert_eq!(builder, "async");
2187 assert_eq!(body.len(), 1);
2188 match &body[0] {
2189 CEStatement::Expr { value } => {
2190 assert!(matches!(**value, Expr::BinOp { .. }));
2191 }
2192 _ => panic!("Expected Expr statement"),
2193 }
2194 }
2195 _ => panic!("Expected ComputationExpr"),
2196 }
2197 }
2198
2199 #[test]
2200 fn test_parse_complex_async_block() {
2201 let input = r#"
2202 async {
2203 let! x = fetchData;
2204 let y = x + 1;
2205 do! printValue y;
2206 return y
2207 }
2208 "#;
2209 let mut lexer = Lexer::new(input);
2210 let tokens = lexer.tokenize().unwrap();
2211 let mut parser = Parser::new(tokens);
2212 let expr = parser.parse().unwrap();
2213
2214 match expr {
2215 Expr::ComputationExpr { builder, body } => {
2216 assert_eq!(builder, "async");
2217 assert_eq!(body.len(), 4);
2218
2219 assert!(matches!(body[0], CEStatement::LetBang { .. }));
2221 assert!(matches!(body[1], CEStatement::Let { .. }));
2222 assert!(matches!(body[2], CEStatement::DoBang { .. }));
2223 assert!(matches!(body[3], CEStatement::Return { .. }));
2224 }
2225 _ => panic!("Expected ComputationExpr"),
2226 }
2227 }
2228
2229 #[test]
2230 fn test_parse_nested_async_blocks() {
2231 let input = "async { let! x = async { return 42 }; return x }";
2232 let mut lexer = Lexer::new(input);
2233 let tokens = lexer.tokenize().unwrap();
2234 let mut parser = Parser::new(tokens);
2235 let expr = parser.parse().unwrap();
2236
2237 match expr {
2238 Expr::ComputationExpr { builder, body } => {
2239 assert_eq!(builder, "async");
2240 assert_eq!(body.len(), 2);
2241
2242 match &body[0] {
2244 CEStatement::LetBang { value, .. } => {
2245 assert!(matches!(**value, Expr::ComputationExpr { .. }));
2246 }
2247 _ => panic!("Expected LetBang"),
2248 }
2249 }
2250 _ => panic!("Expected ComputationExpr"),
2251 }
2252 }
2253
2254 #[test]
2255 fn test_parse_async_with_optional_semicolons() {
2256 let input = "async { let x = 1 let y = 2 return x }";
2258 let mut lexer = Lexer::new(input);
2259 let tokens = lexer.tokenize().unwrap();
2260 let mut parser = Parser::new(tokens);
2261 let expr = parser.parse().unwrap();
2262
2263 match expr {
2264 Expr::ComputationExpr { builder, body } => {
2265 assert_eq!(builder, "async");
2266 assert_eq!(body.len(), 3);
2267 }
2268 _ => panic!("Expected ComputationExpr"),
2269 }
2270 }
2271
2272 #[test]
2273 fn test_parse_async_with_trailing_semicolon() {
2274 let input = "async { return 42; }";
2275 let mut lexer = Lexer::new(input);
2276 let tokens = lexer.tokenize().unwrap();
2277 let mut parser = Parser::new(tokens);
2278 let expr = parser.parse().unwrap();
2279
2280 match expr {
2281 Expr::ComputationExpr { builder, body } => {
2282 assert_eq!(builder, "async");
2283 assert_eq!(body.len(), 1);
2284 }
2285 _ => panic!("Expected ComputationExpr"),
2286 }
2287 }
2288
2289 #[test]
2290 fn test_computation_expr_helpers() {
2291 let expr = Expr::ComputationExpr {
2292 builder: "async".to_string(),
2293 body: vec![],
2294 };
2295
2296 assert!(expr.is_computation_expr());
2297 assert!(!expr.is_let());
2298 assert!(!expr.is_if());
2299
2300 let result = expr.as_computation_expr();
2301 assert!(result.is_some());
2302 let (builder, body) = result.unwrap();
2303 assert_eq!(builder, "async");
2304 assert_eq!(body.len(), 0);
2305 }
2306}