1use crate::ast::*;
2use crate::error::IonError;
3use crate::token::{SpannedToken, Token};
4
5pub struct ParseOutput {
7 pub program: Program,
8 pub errors: Vec<IonError>,
9}
10
11pub struct Parser {
12 tokens: Vec<SpannedToken>,
13 pos: usize,
14 errors: Vec<IonError>,
15}
16
17impl Parser {
18 pub fn new(tokens: Vec<SpannedToken>) -> Self {
19 Self {
20 tokens,
21 pos: 0,
22 errors: Vec::new(),
23 }
24 }
25
26 pub fn parse_program_recovering(&mut self) -> ParseOutput {
29 let mut stmts = Vec::new();
30 while !self.is_at_end() {
31 let before = self.pos;
32 match self.parse_stmt() {
33 Ok(stmt) => stmts.push(stmt),
34 Err(e) => {
35 self.errors.push(e);
36 self.synchronize();
37 if self.pos == before {
39 self.advance();
40 }
41 }
42 }
43 }
44 ParseOutput {
45 program: Program { stmts },
46 errors: std::mem::take(&mut self.errors),
47 }
48 }
49
50 pub fn parse_program(&mut self) -> Result<Program, IonError> {
53 let output = self.parse_program_recovering();
54 if output.errors.is_empty() {
55 Ok(output.program)
56 } else {
57 let mut errors = output.errors;
58 let mut first = errors.remove(0);
59 first.additional = errors;
60 Err(first)
61 }
62 }
63
64 fn synchronize(&mut self) {
67 let mut brace_depth = 0i32;
68 while !self.is_at_end() {
69 if self.pos > 0 && brace_depth == 0 {
71 if let Token::Semicolon = &self.tokens[self.pos - 1].token {
72 return;
73 }
74 }
75 match self.peek() {
76 Token::LBrace => {
78 brace_depth += 1;
79 self.advance();
80 }
81 Token::RBrace => {
82 if brace_depth > 0 {
83 brace_depth -= 1;
84 self.advance();
85 } else {
86 return;
88 }
89 }
90 Token::Let
92 | Token::Fn
93 | Token::For
94 | Token::While
95 | Token::If
96 | Token::Return
97 | Token::Match
98 | Token::Loop
99 | Token::Try
100 | Token::Break
101 | Token::Continue
102 | Token::Use
103 if brace_depth == 0 =>
104 {
105 return;
106 }
107 _ => {
108 self.advance();
109 }
110 }
111 }
112 }
113
114 fn peek(&self) -> &Token {
117 &self.tokens[self.pos].token
118 }
119
120 fn span(&self) -> Span {
121 let t = &self.tokens[self.pos];
122 Span {
123 line: t.line,
124 col: t.col,
125 }
126 }
127
128 fn prev_span(&self) -> Span {
129 if self.pos > 0 {
130 let t = &self.tokens[self.pos - 1];
131 Span {
132 line: t.line,
133 col: t.col,
134 }
135 } else {
136 self.span()
137 }
138 }
139
140 fn advance(&mut self) -> &SpannedToken {
141 let tok = &self.tokens[self.pos];
142 if !self.is_at_end() {
143 self.pos += 1;
144 }
145 tok
146 }
147
148 fn is_at_end(&self) -> bool {
149 matches!(self.peek(), Token::Eof)
150 }
151
152 fn check(&self, token: &Token) -> bool {
153 std::mem::discriminant(self.peek()) == std::mem::discriminant(token)
154 }
155
156 fn eat(&mut self, expected: &Token) -> Result<(), IonError> {
157 if self.check(expected) {
158 self.advance();
159 Ok(())
160 } else {
161 let s = self.span();
162 Err(IonError::parse(
163 format!(
164 "{}{:?}{}{:?}",
165 ion_str!("expected "),
166 expected,
167 ion_str!(", found "),
168 self.peek()
169 ),
170 s.line,
171 s.col,
172 ))
173 }
174 }
175
176 fn eat_ident(&mut self) -> Result<String, IonError> {
177 if let Token::Ident(name) = self.peek().clone() {
178 self.advance();
179 Ok(name)
180 } else {
181 let s = self.span();
182 Err(IonError::parse(
183 format!(
184 "{}{:?}",
185 ion_str!("expected identifier, found "),
186 self.peek()
187 ),
188 s.line,
189 s.col,
190 ))
191 }
192 }
193
194 fn parse_stmt(&mut self) -> Result<Stmt, IonError> {
197 let span = self.span();
198 match self.peek().clone() {
199 Token::Let => self.parse_let_stmt(),
200 Token::Fn => self.parse_fn_decl(),
201 Token::For => self.parse_for_stmt(None),
202 Token::While => self.parse_while_stmt(None),
203 Token::Loop => self.parse_loop_stmt(None),
204 Token::Label(name) => {
205 self.advance();
206 self.eat(&Token::Colon)?;
207 match self.peek() {
208 Token::For => self.parse_for_stmt(Some(name)),
209 Token::While => self.parse_while_stmt(Some(name)),
210 Token::Loop => self.parse_loop_stmt(Some(name)),
211 other => {
212 let s = self.span();
213 Err(IonError::parse(
214 format!(
215 "{}{:?}",
216 ion_str!("expected loop after label, found "),
217 other,
218 ),
219 s.line,
220 s.col,
221 ))
222 }
223 }
224 }
225 Token::Break => self.parse_break_stmt(),
226 Token::Continue => self.parse_continue_stmt(span),
227 Token::Return => self.parse_return_stmt(),
228 Token::Use => self.parse_use_stmt(),
229 _ => self.parse_expr_or_assign_stmt(),
230 }
231 }
232
233 fn parse_optional_label(&mut self) -> Option<String> {
234 if let Token::Label(name) = self.peek().clone() {
235 self.advance();
236 Some(name)
237 } else {
238 None
239 }
240 }
241
242 fn parse_continue_stmt(&mut self, span: Span) -> Result<Stmt, IonError> {
243 self.eat(&Token::Continue)?;
244 let label = self.parse_optional_label();
245 self.eat(&Token::Semicolon)?;
246 Ok(Stmt {
247 kind: StmtKind::Continue { label },
248 span,
249 })
250 }
251
252 fn parse_let_stmt(&mut self) -> Result<Stmt, IonError> {
253 let span = self.span();
254 self.eat(&Token::Let)?;
255 let mutable = if self.check(&Token::Mut) {
256 self.advance();
257 true
258 } else {
259 false
260 };
261 let pattern = self.parse_pattern()?;
262 let type_ann = if self.check(&Token::Colon) {
263 self.advance();
264 Some(self.parse_type_ann()?)
265 } else {
266 None
267 };
268 self.eat(&Token::Eq)?;
269 let value = self.parse_expr()?;
270 self.eat(&Token::Semicolon)?;
271 Ok(Stmt {
272 kind: StmtKind::Let {
273 mutable,
274 pattern,
275 type_ann,
276 value,
277 },
278 span,
279 })
280 }
281
282 fn parse_type_ann(&mut self) -> Result<TypeAnn, IonError> {
283 if self.check(&Token::Fn) {
285 self.advance();
286 return Ok(TypeAnn::Simple("fn".to_string()));
287 }
288 let name = self.eat_ident()?;
289 match name.as_str() {
290 "Option" => {
291 self.eat(&Token::Lt)?;
292 let inner = self.parse_type_ann()?;
293 self.eat(&Token::Gt)?;
294 Ok(TypeAnn::Option(Box::new(inner)))
295 }
296 "Result" => {
297 self.eat(&Token::Lt)?;
298 let ok = self.parse_type_ann()?;
299 self.eat(&Token::Comma)?;
300 let err = self.parse_type_ann()?;
301 self.eat(&Token::Gt)?;
302 Ok(TypeAnn::Result(Box::new(ok), Box::new(err)))
303 }
304 "list" => {
305 if self.check(&Token::Lt) {
306 self.advance();
307 let inner = self.parse_type_ann()?;
308 self.eat(&Token::Gt)?;
309 Ok(TypeAnn::List(Box::new(inner)))
310 } else {
311 Ok(TypeAnn::Simple(name))
312 }
313 }
314 "dict" => {
315 if self.check(&Token::Lt) {
316 self.advance();
317 let key = self.parse_type_ann()?;
318 self.eat(&Token::Comma)?;
319 let val = self.parse_type_ann()?;
320 self.eat(&Token::Gt)?;
321 Ok(TypeAnn::Dict(Box::new(key), Box::new(val)))
322 } else {
323 Ok(TypeAnn::Simple(name))
324 }
325 }
326 _ => Ok(TypeAnn::Simple(name)),
327 }
328 }
329
330 fn parse_fn_decl(&mut self) -> Result<Stmt, IonError> {
331 let span = self.span();
332 self.eat(&Token::Fn)?;
333 let name = self.eat_ident()?;
334 self.eat(&Token::LParen)?;
335 let params = self.parse_params()?;
336 self.eat(&Token::RParen)?;
337 self.eat(&Token::LBrace)?;
338 let body = self.parse_block_stmts()?;
339 self.eat(&Token::RBrace)?;
340 Ok(Stmt {
341 kind: StmtKind::FnDecl { name, params, body },
342 span,
343 })
344 }
345
346 fn parse_params(&mut self) -> Result<Vec<Param>, IonError> {
347 let mut params = Vec::new();
348 while !self.check(&Token::RParen) {
349 let name = self.eat_ident()?;
350 let default = if self.check(&Token::Eq) {
351 self.advance();
352 Some(self.parse_expr()?)
353 } else {
354 None
355 };
356 params.push(Param { name, default });
357 if !self.check(&Token::RParen) {
358 self.eat(&Token::Comma)?;
359 }
360 }
361 Ok(params)
362 }
363
364 fn parse_for_stmt(&mut self, label: Option<String>) -> Result<Stmt, IonError> {
365 let span = self.span();
366 self.eat(&Token::For)?;
367 let pattern = self.parse_pattern()?;
368 self.eat(&Token::In)?;
369 let iter = self.parse_expr()?;
370 self.eat(&Token::LBrace)?;
371 let body = self.parse_block_stmts()?;
372 self.eat(&Token::RBrace)?;
373 Ok(Stmt {
374 kind: StmtKind::For {
375 label,
376 pattern,
377 iter,
378 body,
379 },
380 span,
381 })
382 }
383
384 fn parse_while_stmt(&mut self, label: Option<String>) -> Result<Stmt, IonError> {
385 let span = self.span();
386 self.eat(&Token::While)?;
387 if self.check(&Token::Let) {
389 self.advance();
390 let pattern = self.parse_pattern()?;
391 self.eat(&Token::Eq)?;
392 let expr = self.parse_expr()?;
393 self.eat(&Token::LBrace)?;
394 let body = self.parse_block_stmts()?;
395 self.eat(&Token::RBrace)?;
396 return Ok(Stmt {
397 kind: StmtKind::WhileLet {
398 label,
399 pattern,
400 expr,
401 body,
402 },
403 span,
404 });
405 }
406 let cond = self.parse_expr()?;
407 self.eat(&Token::LBrace)?;
408 let body = self.parse_block_stmts()?;
409 self.eat(&Token::RBrace)?;
410 Ok(Stmt {
411 kind: StmtKind::While { label, cond, body },
412 span,
413 })
414 }
415
416 fn parse_loop_stmt(&mut self, label: Option<String>) -> Result<Stmt, IonError> {
417 let span = self.span();
418 self.eat(&Token::Loop)?;
419 self.eat(&Token::LBrace)?;
420 let body = self.parse_block_stmts()?;
421 self.eat(&Token::RBrace)?;
422 Ok(Stmt {
423 kind: StmtKind::Loop { label, body },
424 span,
425 })
426 }
427
428 fn parse_break_stmt(&mut self) -> Result<Stmt, IonError> {
429 let span = self.span();
430 self.eat(&Token::Break)?;
431 let label = self.parse_optional_label();
432 let value = if self.check(&Token::Semicolon) {
433 None
434 } else {
435 Some(self.parse_expr()?)
436 };
437 self.eat(&Token::Semicolon)?;
438 Ok(Stmt {
439 kind: StmtKind::Break { label, value },
440 span,
441 })
442 }
443
444 fn parse_return_stmt(&mut self) -> Result<Stmt, IonError> {
445 let span = self.span();
446 self.eat(&Token::Return)?;
447 let value = if self.check(&Token::Semicolon) {
448 None
449 } else {
450 Some(self.parse_expr()?)
451 };
452 self.eat(&Token::Semicolon)?;
453 Ok(Stmt {
454 kind: StmtKind::Return { value },
455 span,
456 })
457 }
458
459 fn parse_use_stmt(&mut self) -> Result<Stmt, IonError> {
461 let span = self.span();
462 self.eat(&Token::Use)?;
463
464 let mut path = Vec::new();
466 path.push(self.eat_ident()?);
467 while self.check(&Token::ColonColon) {
468 self.advance();
469 if self.check(&Token::Star) {
471 self.advance();
473 self.eat(&Token::Semicolon)?;
474 return Ok(Stmt {
475 kind: StmtKind::Use {
476 path,
477 imports: UseImports::Glob,
478 },
479 span,
480 });
481 } else if self.check(&Token::LBrace) {
482 self.advance();
484 let mut names = Vec::new();
485 while !self.check(&Token::RBrace) && !self.is_at_end() {
486 names.push(self.eat_ident()?);
487 if !self.check(&Token::RBrace) {
488 self.eat(&Token::Comma)?;
489 }
490 }
491 self.eat(&Token::RBrace)?;
492 self.eat(&Token::Semicolon)?;
493 return Ok(Stmt {
494 kind: StmtKind::Use {
495 path,
496 imports: UseImports::Names(names),
497 },
498 span,
499 });
500 } else {
501 path.push(self.eat_ident()?);
503 }
504 }
505
506 self.eat(&Token::Semicolon)?;
508 if path.len() < 2 {
509 return Err(IonError::parse(
510 ion_str!("use statement requires at least module::name"),
511 span.line,
512 span.col,
513 ));
514 }
515 let name = path.pop().unwrap();
516 Ok(Stmt {
517 kind: StmtKind::Use {
518 path,
519 imports: UseImports::Single(name),
520 },
521 span,
522 })
523 }
524
525 fn parse_expr_or_assign_stmt(&mut self) -> Result<Stmt, IonError> {
526 let span = self.span();
527 let expr = self.parse_expr()?;
528
529 let assign_op = match self.peek() {
531 Token::Eq => Some(AssignOp::Eq),
532 Token::PlusEq => Some(AssignOp::PlusEq),
533 Token::MinusEq => Some(AssignOp::MinusEq),
534 Token::StarEq => Some(AssignOp::StarEq),
535 Token::SlashEq => Some(AssignOp::SlashEq),
536 _ => None,
537 };
538
539 if let Some(op) = assign_op {
540 self.advance();
541 let target = self.expr_to_assign_target(&expr)?;
542 let value = self.parse_expr()?;
543 self.eat(&Token::Semicolon)?;
544 Ok(Stmt {
545 kind: StmtKind::Assign { target, op, value },
546 span,
547 })
548 } else {
549 let has_semi = self.check(&Token::Semicolon);
550 if has_semi {
551 self.advance();
552 }
553 Ok(Stmt {
554 kind: StmtKind::ExprStmt { expr, has_semi },
555 span,
556 })
557 }
558 }
559
560 fn expr_to_assign_target(&self, expr: &Expr) -> Result<AssignTarget, IonError> {
561 match &expr.kind {
562 ExprKind::Ident(name) => Ok(AssignTarget::Ident(name.clone())),
563 ExprKind::Index { expr, index } => Ok(AssignTarget::Index(expr.clone(), index.clone())),
564 ExprKind::FieldAccess { expr, field } => {
565 Ok(AssignTarget::Field(expr.clone(), field.clone()))
566 }
567 _ => Err(IonError::parse(
568 ion_str!("invalid assignment target").to_string(),
569 expr.span.line,
570 expr.span.col,
571 )),
572 }
573 }
574
575 fn parse_block_stmts(&mut self) -> Result<Vec<Stmt>, IonError> {
576 let mut stmts = Vec::new();
577 while !self.check(&Token::RBrace) && !self.is_at_end() {
578 let before = self.pos;
579 match self.parse_stmt() {
580 Ok(stmt) => stmts.push(stmt),
581 Err(e) => {
582 self.errors.push(e);
583 self.synchronize();
584 if self.pos == before {
586 self.advance();
587 }
588 }
589 }
590 }
591 Ok(stmts)
592 }
593
594 fn parse_expr(&mut self) -> Result<Expr, IonError> {
597 self.parse_pipe()
598 }
599
600 fn parse_pipe(&mut self) -> Result<Expr, IonError> {
601 let mut left = self.parse_or()?;
602 while self.check(&Token::Pipe) {
603 self.advance();
604 let right = self.parse_or()?;
605 let span = left.span;
606 left = Expr {
607 kind: ExprKind::PipeOp {
608 left: Box::new(left),
609 right: Box::new(right),
610 },
611 span,
612 };
613 }
614 Ok(left)
615 }
616
617 fn parse_or(&mut self) -> Result<Expr, IonError> {
618 let mut left = self.parse_and()?;
619 while self.check(&Token::Or) {
620 self.advance();
621 let right = self.parse_and()?;
622 let span = left.span;
623 left = Expr {
624 kind: ExprKind::BinOp {
625 left: Box::new(left),
626 op: BinOp::Or,
627 right: Box::new(right),
628 },
629 span,
630 };
631 }
632 Ok(left)
633 }
634
635 fn parse_and(&mut self) -> Result<Expr, IonError> {
636 let mut left = self.parse_bitwise_or()?;
637 while self.check(&Token::And) {
638 self.advance();
639 let right = self.parse_bitwise_or()?;
640 let span = left.span;
641 left = Expr {
642 kind: ExprKind::BinOp {
643 left: Box::new(left),
644 op: BinOp::And,
645 right: Box::new(right),
646 },
647 span,
648 };
649 }
650 Ok(left)
651 }
652
653 fn parse_bitwise_or(&mut self) -> Result<Expr, IonError> {
654 let mut left = self.parse_bitwise_xor()?;
655 while self.check(&Token::PipeSym) {
656 self.advance();
657 let right = self.parse_bitwise_xor()?;
658 let span = left.span;
659 left = Expr {
660 kind: ExprKind::BinOp {
661 left: Box::new(left),
662 op: BinOp::BitOr,
663 right: Box::new(right),
664 },
665 span,
666 };
667 }
668 Ok(left)
669 }
670
671 fn parse_bitwise_xor(&mut self) -> Result<Expr, IonError> {
672 let mut left = self.parse_bitwise_and()?;
673 while self.check(&Token::Caret) {
674 self.advance();
675 let right = self.parse_bitwise_and()?;
676 let span = left.span;
677 left = Expr {
678 kind: ExprKind::BinOp {
679 left: Box::new(left),
680 op: BinOp::BitXor,
681 right: Box::new(right),
682 },
683 span,
684 };
685 }
686 Ok(left)
687 }
688
689 fn parse_bitwise_and(&mut self) -> Result<Expr, IonError> {
690 let mut left = self.parse_equality()?;
691 while self.check(&Token::Ampersand) {
692 self.advance();
693 let right = self.parse_equality()?;
694 let span = left.span;
695 left = Expr {
696 kind: ExprKind::BinOp {
697 left: Box::new(left),
698 op: BinOp::BitAnd,
699 right: Box::new(right),
700 },
701 span,
702 };
703 }
704 Ok(left)
705 }
706
707 fn parse_equality(&mut self) -> Result<Expr, IonError> {
708 let mut left = self.parse_comparison()?;
709 loop {
710 let op = match self.peek() {
711 Token::EqEq => BinOp::Eq,
712 Token::BangEq => BinOp::Ne,
713 _ => break,
714 };
715 self.advance();
716 let right = self.parse_comparison()?;
717 let span = left.span;
718 left = Expr {
719 kind: ExprKind::BinOp {
720 left: Box::new(left),
721 op,
722 right: Box::new(right),
723 },
724 span,
725 };
726 }
727 Ok(left)
728 }
729
730 fn parse_comparison(&mut self) -> Result<Expr, IonError> {
731 let mut left = self.parse_shift()?;
732 loop {
733 let op = match self.peek() {
734 Token::Lt => BinOp::Lt,
735 Token::Gt => BinOp::Gt,
736 Token::LtEq => BinOp::Le,
737 Token::GtEq => BinOp::Ge,
738 _ => break,
739 };
740 self.advance();
741 let right = self.parse_shift()?;
742 let span = left.span;
743 left = Expr {
744 kind: ExprKind::BinOp {
745 left: Box::new(left),
746 op,
747 right: Box::new(right),
748 },
749 span,
750 };
751 }
752 Ok(left)
753 }
754
755 fn parse_shift(&mut self) -> Result<Expr, IonError> {
756 let mut left = self.parse_range()?;
757 loop {
758 let op = match self.peek() {
759 Token::Shl => BinOp::Shl,
760 Token::Shr => BinOp::Shr,
761 _ => break,
762 };
763 self.advance();
764 let right = self.parse_range()?;
765 let span = left.span;
766 left = Expr {
767 kind: ExprKind::BinOp {
768 left: Box::new(left),
769 op,
770 right: Box::new(right),
771 },
772 span,
773 };
774 }
775 Ok(left)
776 }
777
778 fn parse_range(&mut self) -> Result<Expr, IonError> {
779 let left = self.parse_addition()?;
780 match self.peek() {
781 Token::DotDot => {
782 self.advance();
783 let right = self.parse_addition()?;
784 let span = left.span;
785 Ok(Expr {
786 kind: ExprKind::Range {
787 start: Box::new(left),
788 end: Box::new(right),
789 inclusive: false,
790 },
791 span,
792 })
793 }
794 Token::DotDotEq => {
795 self.advance();
796 let right = self.parse_addition()?;
797 let span = left.span;
798 Ok(Expr {
799 kind: ExprKind::Range {
800 start: Box::new(left),
801 end: Box::new(right),
802 inclusive: true,
803 },
804 span,
805 })
806 }
807 _ => Ok(left),
808 }
809 }
810
811 fn parse_addition(&mut self) -> Result<Expr, IonError> {
812 let mut left = self.parse_multiplication()?;
813 loop {
814 let op = match self.peek() {
815 Token::Plus => BinOp::Add,
816 Token::Minus => BinOp::Sub,
817 _ => break,
818 };
819 self.advance();
820 let right = self.parse_multiplication()?;
821 let span = left.span;
822 left = Expr {
823 kind: ExprKind::BinOp {
824 left: Box::new(left),
825 op,
826 right: Box::new(right),
827 },
828 span,
829 };
830 }
831 Ok(left)
832 }
833
834 fn parse_multiplication(&mut self) -> Result<Expr, IonError> {
835 let mut left = self.parse_unary()?;
836 loop {
837 let op = match self.peek() {
838 Token::Star => BinOp::Mul,
839 Token::Slash => BinOp::Div,
840 Token::Percent => BinOp::Mod,
841 _ => break,
842 };
843 self.advance();
844 let right = self.parse_unary()?;
845 let span = left.span;
846 left = Expr {
847 kind: ExprKind::BinOp {
848 left: Box::new(left),
849 op,
850 right: Box::new(right),
851 },
852 span,
853 };
854 }
855 Ok(left)
856 }
857
858 fn parse_unary(&mut self) -> Result<Expr, IonError> {
859 let span = self.span();
860 match self.peek() {
861 Token::Minus => {
862 self.advance();
863 let expr = self.parse_unary()?;
864 Ok(Expr {
865 kind: ExprKind::UnaryOp {
866 op: UnaryOp::Neg,
867 expr: Box::new(expr),
868 },
869 span,
870 })
871 }
872 Token::Bang => {
873 self.advance();
874 let expr = self.parse_unary()?;
875 Ok(Expr {
876 kind: ExprKind::UnaryOp {
877 op: UnaryOp::Not,
878 expr: Box::new(expr),
879 },
880 span,
881 })
882 }
883 _ => self.parse_postfix(),
884 }
885 }
886
887 fn parse_postfix(&mut self) -> Result<Expr, IonError> {
888 let mut expr = self.parse_primary()?;
889
890 loop {
891 match self.peek() {
892 Token::Question => {
893 self.advance();
894 let span = expr.span;
895 expr = Expr {
896 kind: ExprKind::Try(Box::new(expr)),
897 span,
898 };
899 }
900 Token::Dot => {
901 self.advance();
902 if self.check(&Token::Await) {
904 self.advance();
905 let span = expr.span;
906 expr = Expr {
907 kind: ExprKind::AwaitExpr(Box::new(expr)),
908 span,
909 };
910 continue;
911 }
912 let field = self.eat_ident()?;
913 if self.check(&Token::LParen) {
914 self.advance();
916 let args = self.parse_call_args()?;
917 self.eat(&Token::RParen)?;
918 let span = expr.span;
919 expr = Expr {
920 kind: ExprKind::MethodCall {
921 expr: Box::new(expr),
922 method: field,
923 args,
924 },
925 span,
926 };
927 } else {
928 let span = expr.span;
929 expr = Expr {
930 kind: ExprKind::FieldAccess {
931 expr: Box::new(expr),
932 field,
933 },
934 span,
935 };
936 }
937 }
938 Token::LBracket => {
939 self.advance();
940 let span = expr.span;
941 if self.check(&Token::DotDot) || self.check(&Token::DotDotEq) {
943 let inclusive = self.check(&Token::DotDotEq);
944 self.advance();
945 let end = if self.check(&Token::RBracket) {
946 None
947 } else {
948 Some(Box::new(self.parse_expr()?))
949 };
950 self.eat(&Token::RBracket)?;
951 expr = Expr {
952 kind: ExprKind::Slice {
953 expr: Box::new(expr),
954 start: None,
955 end,
956 inclusive,
957 },
958 span,
959 };
960 continue;
961 }
962 let first = self.parse_addition()?;
964 if self.check(&Token::DotDot) || self.check(&Token::DotDotEq) {
965 let inclusive = self.check(&Token::DotDotEq);
966 self.advance();
967 let end = if self.check(&Token::RBracket) {
968 None
969 } else {
970 Some(Box::new(self.parse_expr()?))
971 };
972 self.eat(&Token::RBracket)?;
973 expr = Expr {
974 kind: ExprKind::Slice {
975 expr: Box::new(expr),
976 start: Some(Box::new(first)),
977 end,
978 inclusive,
979 },
980 span,
981 };
982 } else {
983 self.eat(&Token::RBracket)?;
984 expr = Expr {
985 kind: ExprKind::Index {
986 expr: Box::new(expr),
987 index: Box::new(first),
988 },
989 span,
990 };
991 }
992 }
993 Token::LParen => {
994 self.advance();
996 let args = self.parse_call_args()?;
997 self.eat(&Token::RParen)?;
998 let span = expr.span;
999 expr = Expr {
1000 kind: ExprKind::Call {
1001 func: Box::new(expr),
1002 args,
1003 },
1004 span,
1005 };
1006 }
1007 _ => break,
1008 }
1009 }
1010 Ok(expr)
1011 }
1012
1013 fn parse_call_args(&mut self) -> Result<Vec<CallArg>, IonError> {
1014 let mut args = Vec::new();
1015 while !self.check(&Token::RParen) && !self.is_at_end() {
1016 let arg = if let Token::Ident(name) = self.peek().clone() {
1018 if self.tokens.get(self.pos + 1).map(|t| &t.token) == Some(&Token::Colon) {
1019 let name = name.clone();
1020 self.advance(); self.advance(); let value = self.parse_expr()?;
1023 CallArg {
1024 name: Some(name),
1025 value,
1026 }
1027 } else {
1028 let value = self.parse_expr()?;
1029 CallArg { name: None, value }
1030 }
1031 } else {
1032 let value = self.parse_expr()?;
1033 CallArg { name: None, value }
1034 };
1035 args.push(arg);
1036 if !self.check(&Token::RParen) {
1037 self.eat(&Token::Comma)?;
1038 }
1039 }
1040 Ok(args)
1041 }
1042
1043 fn parse_primary(&mut self) -> Result<Expr, IonError> {
1044 let span = self.span();
1045 match self.peek().clone() {
1046 Token::Int(n) => {
1047 self.advance();
1048 Ok(Expr {
1049 kind: ExprKind::Int(n),
1050 span,
1051 })
1052 }
1053 Token::Float(n) => {
1054 self.advance();
1055 Ok(Expr {
1056 kind: ExprKind::Float(n),
1057 span,
1058 })
1059 }
1060 Token::True => {
1061 self.advance();
1062 Ok(Expr {
1063 kind: ExprKind::Bool(true),
1064 span,
1065 })
1066 }
1067 Token::False => {
1068 self.advance();
1069 Ok(Expr {
1070 kind: ExprKind::Bool(false),
1071 span,
1072 })
1073 }
1074 Token::Str(s) => {
1075 self.advance();
1076 Ok(Expr {
1077 kind: ExprKind::Str(s),
1078 span,
1079 })
1080 }
1081 Token::Bytes(b) => {
1082 self.advance();
1083 Ok(Expr {
1084 kind: ExprKind::Bytes(b),
1085 span,
1086 })
1087 }
1088 Token::FStr(template) => {
1089 self.advance();
1090 let parts = self.parse_fstr_parts(&template, span)?;
1091 Ok(Expr {
1092 kind: ExprKind::FStr(parts),
1093 span,
1094 })
1095 }
1096 Token::None => {
1097 self.advance();
1098 Ok(Expr {
1099 kind: ExprKind::None,
1100 span,
1101 })
1102 }
1103 Token::Some => {
1104 self.advance();
1105 self.eat(&Token::LParen)?;
1106 let expr = self.parse_expr()?;
1107 self.eat(&Token::RParen)?;
1108 Ok(Expr {
1109 kind: ExprKind::SomeExpr(Box::new(expr)),
1110 span,
1111 })
1112 }
1113 Token::Ok => {
1114 self.advance();
1115 self.eat(&Token::LParen)?;
1116 let expr = self.parse_expr()?;
1117 self.eat(&Token::RParen)?;
1118 Ok(Expr {
1119 kind: ExprKind::OkExpr(Box::new(expr)),
1120 span,
1121 })
1122 }
1123 Token::Err => {
1124 self.advance();
1125 self.eat(&Token::LParen)?;
1126 let expr = self.parse_expr()?;
1127 self.eat(&Token::RParen)?;
1128 Ok(Expr {
1129 kind: ExprKind::ErrExpr(Box::new(expr)),
1130 span,
1131 })
1132 }
1133 Token::LParen => {
1134 self.advance();
1135 if self.check(&Token::RParen) {
1139 self.advance();
1140 return Ok(Expr {
1141 kind: ExprKind::Unit,
1142 span,
1143 });
1144 }
1145 let first = self.parse_expr()?;
1146 if self.check(&Token::Comma) {
1147 let mut items = vec![first];
1149 while self.check(&Token::Comma) {
1150 self.advance();
1151 if self.check(&Token::RParen) {
1152 break;
1153 }
1154 items.push(self.parse_expr()?);
1155 }
1156 self.eat(&Token::RParen)?;
1157 Ok(Expr {
1158 kind: ExprKind::Tuple(items),
1159 span,
1160 })
1161 } else {
1162 self.eat(&Token::RParen)?;
1163 Ok(first) }
1165 }
1166 Token::LBracket => {
1167 self.advance();
1168 if self.check(&Token::RBracket) {
1169 self.advance();
1170 return Ok(Expr {
1171 kind: ExprKind::List(vec![]),
1172 span,
1173 });
1174 }
1175 let first_entry = if self.check(&Token::DotDotDot) {
1177 self.advance();
1178 ListEntry::Spread(self.parse_expr()?)
1179 } else {
1180 ListEntry::Elem(self.parse_expr()?)
1181 };
1182 if let ListEntry::Elem(ref first) = first_entry {
1184 if self.check(&Token::For) {
1185 self.advance();
1186 let pattern = self.parse_pattern()?;
1187 self.eat(&Token::In)?;
1188 let iter = self.parse_expr()?;
1189 let cond = if self.check(&Token::If) {
1190 self.advance();
1191 Some(Box::new(self.parse_expr()?))
1192 } else {
1193 None
1194 };
1195 self.eat(&Token::RBracket)?;
1196 return Ok(Expr {
1197 kind: ExprKind::ListComp {
1198 expr: Box::new(first.clone()),
1199 pattern,
1200 iter: Box::new(iter),
1201 cond,
1202 },
1203 span,
1204 });
1205 }
1206 }
1207 let mut items = vec![first_entry];
1208 while self.check(&Token::Comma) {
1209 self.advance();
1210 if self.check(&Token::RBracket) {
1211 break;
1212 }
1213 if self.check(&Token::DotDotDot) {
1214 self.advance();
1215 items.push(ListEntry::Spread(self.parse_expr()?));
1216 } else {
1217 items.push(ListEntry::Elem(self.parse_expr()?));
1218 }
1219 }
1220 self.eat(&Token::RBracket)?;
1221 Ok(Expr {
1222 kind: ExprKind::List(items),
1223 span,
1224 })
1225 }
1226 Token::HashBrace => {
1227 self.advance();
1228 if self.check(&Token::RBrace) {
1229 self.advance();
1230 return Ok(Expr {
1231 kind: ExprKind::Dict(vec![]),
1232 span,
1233 });
1234 }
1235 if self.check(&Token::DotDotDot) {
1237 return self.parse_dict_entries(span);
1238 }
1239 let first_key = self.parse_dict_key()?;
1240 self.eat(&Token::Colon)?;
1241 let first_val = self.parse_expr()?;
1242 if self.check(&Token::For) {
1244 self.advance();
1245 let pattern = self.parse_pattern()?;
1246 self.eat(&Token::In)?;
1247 let iter = self.parse_expr()?;
1248 let cond = if self.check(&Token::If) {
1249 self.advance();
1250 Some(Box::new(self.parse_expr()?))
1251 } else {
1252 None
1253 };
1254 self.eat(&Token::RBrace)?;
1255 return Ok(Expr {
1256 kind: ExprKind::DictComp {
1257 key: Box::new(first_key),
1258 value: Box::new(first_val),
1259 pattern,
1260 iter: Box::new(iter),
1261 cond,
1262 },
1263 span,
1264 });
1265 }
1266 let mut entries = vec![DictEntry::KeyValue(first_key, first_val)];
1267 while self.check(&Token::Comma) {
1268 self.advance();
1269 if self.check(&Token::RBrace) {
1270 break;
1271 }
1272 if self.check(&Token::DotDotDot) {
1273 self.advance();
1274 entries.push(DictEntry::Spread(self.parse_expr()?));
1275 } else {
1276 let key = self.parse_dict_key()?;
1277 self.eat(&Token::Colon)?;
1278 let value = self.parse_expr()?;
1279 entries.push(DictEntry::KeyValue(key, value));
1280 }
1281 }
1282 self.eat(&Token::RBrace)?;
1283 Ok(Expr {
1284 kind: ExprKind::Dict(entries),
1285 span,
1286 })
1287 }
1288 Token::PipeSym => {
1289 self.advance();
1291 let mut params = Vec::new();
1292 if !self.check(&Token::PipeSym) {
1293 params.push(self.eat_ident()?);
1294 while self.check(&Token::Comma) {
1295 self.advance();
1296 params.push(self.eat_ident()?);
1297 }
1298 }
1299 self.eat(&Token::PipeSym)?;
1300 let body = if self.check(&Token::LBrace) {
1301 self.advance();
1302 let stmts = self.parse_block_stmts()?;
1303 self.eat(&Token::RBrace)?;
1304 Expr {
1305 kind: ExprKind::Block(stmts),
1306 span,
1307 }
1308 } else {
1309 self.parse_expr()?
1310 };
1311 Ok(Expr {
1312 kind: ExprKind::Lambda {
1313 params,
1314 body: Box::new(body),
1315 },
1316 span,
1317 })
1318 }
1319 Token::Or => {
1320 self.advance();
1322 let body = if self.check(&Token::LBrace) {
1323 self.advance();
1324 let stmts = self.parse_block_stmts()?;
1325 self.eat(&Token::RBrace)?;
1326 Expr {
1327 kind: ExprKind::Block(stmts),
1328 span,
1329 }
1330 } else {
1331 self.parse_expr()?
1332 };
1333 Ok(Expr {
1334 kind: ExprKind::Lambda {
1335 params: Vec::new(),
1336 body: Box::new(body),
1337 },
1338 span,
1339 })
1340 }
1341 Token::If => self.parse_if_expr(),
1342 Token::Match => self.parse_match_expr(),
1343 Token::Loop => {
1344 self.advance();
1345 self.eat(&Token::LBrace)?;
1346 let body = self.parse_block_stmts()?;
1347 self.eat(&Token::RBrace)?;
1348 Ok(Expr {
1349 kind: ExprKind::LoopExpr(body),
1350 span,
1351 })
1352 }
1353 Token::Try => {
1354 self.advance();
1355 self.eat(&Token::LBrace)?;
1356 let body = self.parse_block_stmts()?;
1357 self.eat(&Token::RBrace)?;
1358 self.eat(&Token::Catch)?;
1359 let var = match self.peek() {
1360 Token::Ident(name) => {
1361 let name = name.clone();
1362 self.advance();
1363 name
1364 }
1365 _ => {
1366 return Err(IonError::parse(
1367 ion_str!("expected identifier after 'catch'").to_string(),
1368 self.span().line,
1369 self.span().col,
1370 ));
1371 }
1372 };
1373 self.eat(&Token::LBrace)?;
1374 let handler = self.parse_block_stmts()?;
1375 self.eat(&Token::RBrace)?;
1376 Ok(Expr {
1377 kind: ExprKind::TryCatch { body, var, handler },
1378 span,
1379 })
1380 }
1381 Token::Async => {
1382 self.advance();
1383 self.eat(&Token::LBrace)?;
1384 let body = self.parse_block_stmts()?;
1385 self.eat(&Token::RBrace)?;
1386 Ok(Expr {
1387 kind: ExprKind::AsyncBlock(body),
1388 span,
1389 })
1390 }
1391 Token::Spawn => {
1392 self.advance();
1393 let expr = self.parse_expr()?;
1394 Ok(Expr {
1395 kind: ExprKind::SpawnExpr(Box::new(expr)),
1396 span,
1397 })
1398 }
1399 Token::Select => {
1400 self.advance();
1401 self.eat(&Token::LBrace)?;
1402 let mut branches = Vec::new();
1403 while !self.check(&Token::RBrace) {
1404 let pattern = self.parse_pattern()?;
1405 self.eat(&Token::Eq)?;
1406 let future_expr = self.parse_expr()?;
1407 self.eat(&Token::Arrow)?;
1408 let body = self.parse_expr()?;
1409 branches.push(SelectBranch {
1410 pattern,
1411 future_expr,
1412 body,
1413 });
1414 if self.check(&Token::Comma) {
1415 self.advance();
1416 }
1417 }
1418 self.eat(&Token::RBrace)?;
1419 Ok(Expr {
1420 kind: ExprKind::SelectExpr(branches),
1421 span,
1422 })
1423 }
1424 Token::LBrace => {
1425 self.advance();
1426 let stmts = self.parse_block_stmts()?;
1427 self.eat(&Token::RBrace)?;
1428 Ok(Expr {
1429 kind: ExprKind::Block(stmts),
1430 span,
1431 })
1432 }
1433 Token::Ident(name) => {
1434 self.advance();
1435 if self.check(&Token::ColonColon) {
1437 self.advance();
1438 let second = self.eat_ident()?;
1439 if self.check(&Token::ColonColon) {
1441 let mut segments = vec![name, second];
1442 while self.check(&Token::ColonColon) {
1443 self.advance();
1444 segments.push(self.eat_ident()?);
1445 }
1446 Ok(Expr {
1447 kind: ExprKind::ModulePath(segments),
1448 span,
1449 })
1450 }
1451 else if name.chars().next().is_some_and(|c| c.is_uppercase()) {
1454 if self.check(&Token::LParen) {
1456 self.advance();
1457 let mut args = Vec::new();
1458 while !self.check(&Token::RParen) && !self.is_at_end() {
1459 args.push(self.parse_expr()?);
1460 if !self.check(&Token::RParen) {
1461 self.eat(&Token::Comma)?;
1462 }
1463 }
1464 self.eat(&Token::RParen)?;
1465 Ok(Expr {
1466 kind: ExprKind::EnumVariantCall {
1467 enum_name: name,
1468 variant: second,
1469 args,
1470 },
1471 span,
1472 })
1473 } else {
1474 Ok(Expr {
1475 kind: ExprKind::EnumVariant {
1476 enum_name: name,
1477 variant: second,
1478 },
1479 span,
1480 })
1481 }
1482 }
1483 else {
1485 Ok(Expr {
1486 kind: ExprKind::ModulePath(vec![name, second]),
1487 span,
1488 })
1489 }
1490 }
1491 else if self.check(&Token::LBrace)
1493 && name.chars().next().is_some_and(|c| c.is_uppercase())
1494 {
1495 self.advance();
1496 let mut fields = Vec::new();
1497 let mut spread = None;
1498 while !self.check(&Token::RBrace) && !self.is_at_end() {
1499 if self.check(&Token::DotDotDot) {
1500 self.advance();
1501 spread = Some(Box::new(self.parse_expr()?));
1502 if !self.check(&Token::RBrace) {
1503 self.eat(&Token::Comma)?;
1504 }
1505 continue;
1506 }
1507 let field_name = self.eat_ident()?;
1508 self.eat(&Token::Colon)?;
1509 let field_value = self.parse_expr()?;
1510 fields.push((field_name, field_value));
1511 if !self.check(&Token::RBrace) {
1512 self.eat(&Token::Comma)?;
1513 }
1514 }
1515 self.eat(&Token::RBrace)?;
1516 Ok(Expr {
1517 kind: ExprKind::StructConstruct {
1518 name,
1519 fields,
1520 spread,
1521 },
1522 span,
1523 })
1524 } else {
1525 Ok(Expr {
1526 kind: ExprKind::Ident(name),
1527 span,
1528 })
1529 }
1530 }
1531 _ => {
1532 let s = self.span();
1533 Err(IonError::parse(
1534 format!("{}{:?}", ion_str!("unexpected token: "), self.peek()),
1535 s.line,
1536 s.col,
1537 ))
1538 }
1539 }
1540 }
1541
1542 fn parse_dict_key(&mut self) -> Result<Expr, IonError> {
1545 let span = self.span();
1546 if let Token::Ident(name) = self.peek().clone() {
1547 if self.tokens.get(self.pos + 1).map(|t| &t.token) == Some(&Token::Colon) {
1549 self.advance(); return Ok(Expr {
1551 kind: ExprKind::Str(name),
1552 span,
1553 });
1554 }
1555 }
1556 self.parse_expr()
1557 }
1558
1559 fn parse_dict_entries(&mut self, span: Span) -> Result<Expr, IonError> {
1560 let mut entries = Vec::new();
1561 self.advance(); entries.push(DictEntry::Spread(self.parse_expr()?));
1564 while self.check(&Token::Comma) {
1565 self.advance();
1566 if self.check(&Token::RBrace) {
1567 break;
1568 }
1569 if self.check(&Token::DotDotDot) {
1570 self.advance();
1571 entries.push(DictEntry::Spread(self.parse_expr()?));
1572 } else {
1573 let key = self.parse_dict_key()?;
1574 self.eat(&Token::Colon)?;
1575 let value = self.parse_expr()?;
1576 entries.push(DictEntry::KeyValue(key, value));
1577 }
1578 }
1579 self.eat(&Token::RBrace)?;
1580 Ok(Expr {
1581 kind: ExprKind::Dict(entries),
1582 span,
1583 })
1584 }
1585
1586 fn parse_if_expr(&mut self) -> Result<Expr, IonError> {
1587 let span = self.span();
1588 self.eat(&Token::If)?;
1589
1590 if self.check(&Token::Let) {
1592 self.advance();
1593 let pattern = self.parse_pattern()?;
1594 self.eat(&Token::Eq)?;
1595 let expr = self.parse_expr()?;
1596 self.eat(&Token::LBrace)?;
1597 let then_body = self.parse_block_stmts()?;
1598 self.eat(&Token::RBrace)?;
1599 let else_body = if self.check(&Token::Else) {
1600 self.advance();
1601 self.eat(&Token::LBrace)?;
1602 let stmts = self.parse_block_stmts()?;
1603 self.eat(&Token::RBrace)?;
1604 Some(stmts)
1605 } else {
1606 None
1607 };
1608 return Ok(Expr {
1609 kind: ExprKind::IfLet {
1610 pattern,
1611 expr: Box::new(expr),
1612 then_body,
1613 else_body,
1614 },
1615 span,
1616 });
1617 }
1618
1619 let cond = self.parse_expr()?;
1620 self.eat(&Token::LBrace)?;
1621 let then_body = self.parse_block_stmts()?;
1622 self.eat(&Token::RBrace)?;
1623 let else_body = if self.check(&Token::Else) {
1624 self.advance();
1625 if self.check(&Token::If) {
1626 let else_if = self.parse_if_expr()?;
1628 Some(vec![Stmt {
1629 kind: StmtKind::ExprStmt {
1630 expr: else_if,
1631 has_semi: false,
1632 },
1633 span: self.prev_span(),
1634 }])
1635 } else {
1636 self.eat(&Token::LBrace)?;
1637 let stmts = self.parse_block_stmts()?;
1638 self.eat(&Token::RBrace)?;
1639 Some(stmts)
1640 }
1641 } else {
1642 None
1643 };
1644 Ok(Expr {
1645 kind: ExprKind::If {
1646 cond: Box::new(cond),
1647 then_body,
1648 else_body,
1649 },
1650 span,
1651 })
1652 }
1653
1654 fn parse_match_expr(&mut self) -> Result<Expr, IonError> {
1655 let span = self.span();
1656 self.eat(&Token::Match)?;
1657 let expr = self.parse_expr()?;
1658 self.eat(&Token::LBrace)?;
1659 let mut arms = Vec::new();
1660 while !self.check(&Token::RBrace) && !self.is_at_end() {
1661 let pattern = self.parse_pattern()?;
1662 let guard = if self.check(&Token::If) {
1663 self.advance();
1664 Some(self.parse_expr()?)
1665 } else {
1666 None
1667 };
1668 self.eat(&Token::Arrow)?;
1669 let body = self.parse_expr()?;
1670 arms.push(MatchArm {
1671 pattern,
1672 guard,
1673 body,
1674 });
1675 if !self.check(&Token::RBrace) {
1676 self.eat(&Token::Comma)?;
1677 }
1678 }
1679 self.eat(&Token::RBrace)?;
1680 Ok(Expr {
1681 kind: ExprKind::Match {
1682 expr: Box::new(expr),
1683 arms,
1684 },
1685 span,
1686 })
1687 }
1688
1689 fn parse_pattern(&mut self) -> Result<Pattern, IonError> {
1692 match self.peek().clone() {
1693 Token::Ident(name) if name == "_" => {
1694 self.advance();
1695 Ok(Pattern::Wildcard)
1696 }
1697 Token::Ident(name) => {
1698 self.advance();
1699 if self.check(&Token::ColonColon) {
1701 self.advance();
1702 let variant = self.eat_ident()?;
1703 let fields = if self.check(&Token::LParen) {
1704 self.advance();
1705 let mut pats = Vec::new();
1706 while !self.check(&Token::RParen) && !self.is_at_end() {
1707 pats.push(self.parse_pattern()?);
1708 if !self.check(&Token::RParen) {
1709 self.eat(&Token::Comma)?;
1710 }
1711 }
1712 self.eat(&Token::RParen)?;
1713 EnumPatternFields::Positional(pats)
1714 } else if self.check(&Token::LBrace) {
1715 self.advance();
1716 let mut fields = Vec::new();
1717 while !self.check(&Token::RBrace) && !self.is_at_end() {
1718 let field_name = self.eat_ident()?;
1719 let pat = if self.check(&Token::Colon) {
1720 self.advance();
1721 Some(self.parse_pattern()?)
1722 } else {
1723 None
1724 };
1725 fields.push((field_name, pat));
1726 if !self.check(&Token::RBrace) {
1727 self.eat(&Token::Comma)?;
1728 }
1729 }
1730 self.eat(&Token::RBrace)?;
1731 EnumPatternFields::Named(fields)
1732 } else {
1733 EnumPatternFields::None
1734 };
1735 Ok(Pattern::EnumVariant {
1736 enum_name: name,
1737 variant,
1738 fields,
1739 })
1740 }
1741 else if self.check(&Token::LBrace)
1743 && name.chars().next().is_some_and(|c| c.is_uppercase())
1744 {
1745 self.advance();
1746 let mut fields = Vec::new();
1747 while !self.check(&Token::RBrace) && !self.is_at_end() {
1748 let field_name = self.eat_ident()?;
1749 let pat = if self.check(&Token::Colon) {
1750 self.advance();
1751 Some(self.parse_pattern()?)
1752 } else {
1753 None
1754 };
1755 fields.push((field_name, pat));
1756 if !self.check(&Token::RBrace) {
1757 self.eat(&Token::Comma)?;
1758 }
1759 }
1760 self.eat(&Token::RBrace)?;
1761 Ok(Pattern::Struct { name, fields })
1762 } else {
1763 Ok(Pattern::Ident(name))
1764 }
1765 }
1766 Token::Int(n) => {
1767 self.advance();
1768 Ok(Pattern::Int(n))
1769 }
1770 Token::Float(n) => {
1771 self.advance();
1772 Ok(Pattern::Float(n))
1773 }
1774 Token::True => {
1775 self.advance();
1776 Ok(Pattern::Bool(true))
1777 }
1778 Token::False => {
1779 self.advance();
1780 Ok(Pattern::Bool(false))
1781 }
1782 Token::Str(s) => {
1783 self.advance();
1784 Ok(Pattern::Str(s))
1785 }
1786 Token::Bytes(b) => {
1787 self.advance();
1788 Ok(Pattern::Bytes(b))
1789 }
1790 Token::None => {
1791 self.advance();
1792 Ok(Pattern::None)
1793 }
1794 Token::Some => {
1795 self.advance();
1796 self.eat(&Token::LParen)?;
1797 let inner = self.parse_pattern()?;
1798 self.eat(&Token::RParen)?;
1799 Ok(Pattern::Some(Box::new(inner)))
1800 }
1801 Token::Ok => {
1802 self.advance();
1803 self.eat(&Token::LParen)?;
1804 let inner = self.parse_pattern()?;
1805 self.eat(&Token::RParen)?;
1806 Ok(Pattern::Ok(Box::new(inner)))
1807 }
1808 Token::Err => {
1809 self.advance();
1810 self.eat(&Token::LParen)?;
1811 let inner = self.parse_pattern()?;
1812 self.eat(&Token::RParen)?;
1813 Ok(Pattern::Err(Box::new(inner)))
1814 }
1815 Token::LParen => {
1816 self.advance();
1817 let mut pats = Vec::new();
1818 while !self.check(&Token::RParen) && !self.is_at_end() {
1819 pats.push(self.parse_pattern()?);
1820 if !self.check(&Token::RParen) {
1821 self.eat(&Token::Comma)?;
1822 }
1823 }
1824 self.eat(&Token::RParen)?;
1825 Ok(Pattern::Tuple(pats))
1826 }
1827 Token::LBracket => {
1828 self.advance();
1829 let mut pats = Vec::new();
1830 let mut rest = None;
1831 while !self.check(&Token::RBracket) && !self.is_at_end() {
1832 if self.check(&Token::DotDotDot) {
1833 self.advance();
1834 let rest_name = self.eat_ident()?;
1835 rest = Some(Box::new(Pattern::Ident(rest_name)));
1836 if !self.check(&Token::RBracket) {
1837 self.eat(&Token::Comma)?;
1838 }
1839 continue;
1840 }
1841 pats.push(self.parse_pattern()?);
1842 if !self.check(&Token::RBracket) {
1843 self.eat(&Token::Comma)?;
1844 }
1845 }
1846 self.eat(&Token::RBracket)?;
1847 Ok(Pattern::List(pats, rest))
1848 }
1849 _ => {
1850 let s = self.span();
1851 Err(IonError::parse(
1852 format!(
1853 "{}{:?}",
1854 ion_str!("unexpected token in pattern: "),
1855 self.peek()
1856 ),
1857 s.line,
1858 s.col,
1859 ))
1860 }
1861 }
1862 }
1863
1864 fn parse_fstr_parts(&self, template: &str, span: Span) -> Result<Vec<FStrPart>, IonError> {
1867 let mut parts = Vec::new();
1868 let mut chars = template.chars().peekable();
1869 let mut current = String::new();
1870
1871 while let Some(ch) = chars.next() {
1872 if ch == '{' {
1873 if !current.is_empty() {
1874 parts.push(FStrPart::Literal(std::mem::take(&mut current)));
1875 }
1876 let mut expr_str = String::new();
1877 let mut depth = 1;
1878 for inner in chars.by_ref() {
1879 if inner == '{' {
1880 depth += 1;
1881 } else if inner == '}' {
1882 depth -= 1;
1883 if depth == 0 {
1884 break;
1885 }
1886 }
1887 expr_str.push(inner);
1888 }
1889 if depth != 0 {
1890 return Err(IonError::parse(
1891 ion_str!("unterminated expression in f-string").to_string(),
1892 span.line,
1893 span.col,
1894 ));
1895 }
1896 let mut lexer = crate::lexer::Lexer::new(&expr_str);
1897 let tokens = lexer.tokenize()?;
1898 let mut parser = Parser::new(tokens);
1899 let expr = parser.parse_expr()?;
1900 if !parser.is_at_end() {
1901 let s = parser.span();
1902 return Err(IonError::parse(
1903 format!(
1904 "{}{:?}",
1905 ion_str!("unexpected token in f-string expression: "),
1906 parser.peek()
1907 ),
1908 span.line,
1909 span.col + s.col.saturating_sub(1),
1910 ));
1911 }
1912 parts.push(FStrPart::Expr(expr));
1913 } else {
1914 current.push(ch);
1915 }
1916 }
1917 if !current.is_empty() {
1918 parts.push(FStrPart::Literal(current));
1919 }
1920 Ok(parts)
1921 }
1922}
1923
1924#[cfg(test)]
1925mod tests {
1926 use super::*;
1927 use crate::lexer::Lexer;
1928
1929 fn parse(src: &str) -> Program {
1930 let tokens = Lexer::new(src).tokenize().unwrap();
1931 Parser::new(tokens).parse_program().unwrap()
1932 }
1933
1934 #[test]
1935 fn test_let_stmt() {
1936 let prog = parse("let x = 42;");
1937 assert_eq!(prog.stmts.len(), 1);
1938 assert!(matches!(
1939 &prog.stmts[0].kind,
1940 StmtKind::Let { mutable: false, .. }
1941 ));
1942 }
1943
1944 #[test]
1945 fn test_let_mut() {
1946 let prog = parse("let mut x = 42;");
1947 assert!(matches!(
1948 &prog.stmts[0].kind,
1949 StmtKind::Let { mutable: true, .. }
1950 ));
1951 }
1952
1953 #[test]
1954 fn test_fn_decl() {
1955 let prog = parse("fn add(a, b) { a + b }");
1956 assert!(matches!(&prog.stmts[0].kind, StmtKind::FnDecl { .. }));
1957 }
1958
1959 #[test]
1960 fn test_if_expr() {
1961 let prog = parse("let x = if true { 1 } else { 2 };");
1962 assert!(matches!(&prog.stmts[0].kind, StmtKind::Let { .. }));
1963 }
1964
1965 #[test]
1966 fn test_match_expr() {
1967 let prog = parse(r#"let x = match y { 1 => "one", _ => "other" };"#);
1968 assert!(matches!(&prog.stmts[0].kind, StmtKind::Let { .. }));
1969 }
1970
1971 #[test]
1972 fn test_lambda() {
1973 let prog = parse("let f = |x| x + 1;");
1974 assert!(matches!(&prog.stmts[0].kind, StmtKind::Let { .. }));
1975 }
1976
1977 #[test]
1978 fn test_dict() {
1979 let prog = parse(r#"let d = #{ "a": 1, "b": 2 };"#);
1980 assert!(matches!(&prog.stmts[0].kind, StmtKind::Let { .. }));
1981 }
1982
1983 #[test]
1984 fn test_for_loop() {
1985 let prog = parse("for x in items { x; }");
1986 assert!(matches!(&prog.stmts[0].kind, StmtKind::For { .. }));
1987 }
1988}