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