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