1use crate::ast::*;
2use harn_lexer::{Span, Token, TokenKind};
3use std::fmt;
4
5#[derive(Debug, Clone, PartialEq)]
7pub enum ParserError {
8 Unexpected {
9 got: String,
10 expected: String,
11 span: Span,
12 },
13 UnexpectedEof {
14 expected: String,
15 },
16}
17
18impl fmt::Display for ParserError {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 match self {
21 ParserError::Unexpected {
22 got,
23 expected,
24 span,
25 } => write!(
26 f,
27 "Expected {expected}, got {got} at {}:{}",
28 span.line, span.column
29 ),
30 ParserError::UnexpectedEof { expected } => {
31 write!(f, "Unexpected end of file, expected {expected}")
32 }
33 }
34 }
35}
36
37impl std::error::Error for ParserError {}
38
39pub struct Parser {
41 tokens: Vec<Token>,
42 pos: usize,
43 errors: Vec<ParserError>,
44}
45
46impl Parser {
47 pub fn new(tokens: Vec<Token>) -> Self {
48 Self {
49 tokens,
50 pos: 0,
51 errors: Vec::new(),
52 }
53 }
54
55 fn current_span(&self) -> Span {
56 self.tokens
57 .get(self.pos)
58 .map(|t| t.span)
59 .unwrap_or(Span::dummy())
60 }
61
62 fn current_kind(&self) -> Option<&TokenKind> {
63 self.tokens.get(self.pos).map(|t| &t.kind)
64 }
65
66 fn prev_span(&self) -> Span {
67 if self.pos > 0 {
68 self.tokens[self.pos - 1].span
69 } else {
70 Span::dummy()
71 }
72 }
73
74 pub fn parse(&mut self) -> Result<Vec<SNode>, ParserError> {
76 let mut nodes = Vec::new();
77 self.skip_newlines();
78
79 while !self.is_at_end() {
80 if self.check(&TokenKind::RBrace) {
82 self.advance();
83 self.skip_newlines();
84 continue;
85 }
86
87 let result = if self.check(&TokenKind::Import) {
88 self.parse_import()
89 } else if self.check(&TokenKind::Pipeline) {
90 self.parse_pipeline()
91 } else {
92 self.parse_statement()
93 };
94
95 match result {
96 Ok(node) => nodes.push(node),
97 Err(err) => {
98 self.errors.push(err);
99 self.synchronize();
100 }
101 }
102 self.skip_newlines();
103 }
104
105 if let Some(first) = self.errors.first() {
106 return Err(first.clone());
107 }
108 Ok(nodes)
109 }
110
111 pub fn all_errors(&self) -> &[ParserError] {
113 &self.errors
114 }
115
116 fn is_statement_start(&self) -> bool {
118 matches!(
119 self.current_kind(),
120 Some(
121 TokenKind::Let
122 | TokenKind::Var
123 | TokenKind::If
124 | TokenKind::For
125 | TokenKind::While
126 | TokenKind::Match
127 | TokenKind::Retry
128 | TokenKind::Return
129 | TokenKind::Throw
130 | TokenKind::Fn
131 | TokenKind::Pub
132 | TokenKind::Try
133 | TokenKind::Select
134 | TokenKind::Pipeline
135 | TokenKind::Import
136 | TokenKind::Parallel
137 | TokenKind::ParallelMap
138 | TokenKind::ParallelSettle
139 | TokenKind::Enum
140 | TokenKind::Struct
141 | TokenKind::Interface
142 | TokenKind::Guard
143 | TokenKind::Require
144 | TokenKind::Deadline
145 | TokenKind::Yield
146 | TokenKind::Mutex
147 )
148 )
149 }
150
151 fn synchronize(&mut self) {
153 while !self.is_at_end() {
154 if self.check(&TokenKind::Newline) {
155 self.advance();
156 if self.is_at_end() || self.is_statement_start() {
157 return;
158 }
159 continue;
160 }
161 if self.check(&TokenKind::RBrace) {
162 return;
163 }
164 self.advance();
165 }
166 }
167
168 pub fn parse_single_expression(&mut self) -> Result<SNode, ParserError> {
170 self.skip_newlines();
171 self.parse_expression()
172 }
173
174 fn parse_pipeline(&mut self) -> Result<SNode, ParserError> {
177 let start = self.current_span();
178 self.consume(&TokenKind::Pipeline, "pipeline")?;
179 let name = self.consume_identifier("pipeline name")?;
180
181 self.consume(&TokenKind::LParen, "(")?;
182 let params = self.parse_param_list()?;
183 self.consume(&TokenKind::RParen, ")")?;
184
185 let extends = if self.check(&TokenKind::Extends) {
186 self.advance();
187 Some(self.consume_identifier("parent pipeline name")?)
188 } else {
189 None
190 };
191
192 self.consume(&TokenKind::LBrace, "{")?;
193 let body = self.parse_block()?;
194 self.consume(&TokenKind::RBrace, "}")?;
195
196 Ok(spanned(
197 Node::Pipeline {
198 name,
199 params,
200 body,
201 extends,
202 },
203 Span::merge(start, self.prev_span()),
204 ))
205 }
206
207 fn parse_import(&mut self) -> Result<SNode, ParserError> {
208 let start = self.current_span();
209 self.consume(&TokenKind::Import, "import")?;
210
211 if self.check(&TokenKind::LBrace) {
213 self.advance(); let mut names = Vec::new();
215 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
216 let name = self.consume_identifier("import name")?;
217 names.push(name);
218 if self.check(&TokenKind::Comma) {
219 self.advance();
220 }
221 }
222 self.consume(&TokenKind::RBrace, "}")?;
223 self.consume(&TokenKind::From, "from")?;
224 if let Some(tok) = self.current() {
225 if let TokenKind::StringLiteral(path) = &tok.kind {
226 let path = path.clone();
227 self.advance();
228 return Ok(spanned(
229 Node::SelectiveImport { names, path },
230 Span::merge(start, self.prev_span()),
231 ));
232 }
233 }
234 return Err(self.error("import path string"));
235 }
236
237 if let Some(tok) = self.current() {
238 if let TokenKind::StringLiteral(path) = &tok.kind {
239 let path = path.clone();
240 self.advance();
241 return Ok(spanned(
242 Node::ImportDecl { path },
243 Span::merge(start, self.prev_span()),
244 ));
245 }
246 }
247 Err(self.error("import path string"))
248 }
249
250 fn parse_block(&mut self) -> Result<Vec<SNode>, ParserError> {
253 let mut stmts = Vec::new();
254 self.skip_newlines();
255
256 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
257 stmts.push(self.parse_statement()?);
258 self.skip_newlines();
259 }
260 Ok(stmts)
261 }
262
263 fn parse_statement(&mut self) -> Result<SNode, ParserError> {
264 self.skip_newlines();
265
266 let tok = self.current().ok_or_else(|| ParserError::UnexpectedEof {
267 expected: "statement".into(),
268 })?;
269
270 match &tok.kind {
271 TokenKind::Let => self.parse_let_binding(),
272 TokenKind::Var => self.parse_var_binding(),
273 TokenKind::If => self.parse_if_else(),
274 TokenKind::For => self.parse_for_in(),
275 TokenKind::Match => self.parse_match(),
276 TokenKind::Retry => self.parse_retry(),
277 TokenKind::While => self.parse_while_loop(),
278 TokenKind::Parallel => self.parse_parallel(),
279 TokenKind::ParallelMap => self.parse_parallel_map(),
280 TokenKind::ParallelSettle => self.parse_parallel_settle(),
281 TokenKind::Return => self.parse_return(),
282 TokenKind::Throw => self.parse_throw(),
283 TokenKind::Override => self.parse_override(),
284 TokenKind::Try => self.parse_try_catch(),
285 TokenKind::Select => self.parse_select(),
286 TokenKind::Fn => self.parse_fn_decl_with_pub(false),
287 TokenKind::Pub => {
288 self.advance(); let tok = self.current().ok_or_else(|| ParserError::UnexpectedEof {
290 expected: "fn, struct, enum, or pipeline after pub".into(),
291 })?;
292 match &tok.kind {
293 TokenKind::Fn => self.parse_fn_decl_with_pub(true),
294 _ => Err(self.error("fn, struct, enum, or pipeline after pub")),
295 }
296 }
297 TokenKind::TypeKw => self.parse_type_decl(),
298 TokenKind::Enum => self.parse_enum_decl(),
299 TokenKind::Struct => self.parse_struct_decl(),
300 TokenKind::Interface => self.parse_interface_decl(),
301 TokenKind::Impl => self.parse_impl_block(),
302 TokenKind::Guard => self.parse_guard(),
303 TokenKind::Require => self.parse_require(),
304 TokenKind::Deadline => self.parse_deadline(),
305 TokenKind::Yield => self.parse_yield(),
306 TokenKind::Mutex => self.parse_mutex(),
307 TokenKind::Break => {
308 let span = self.current_span();
309 self.advance();
310 Ok(spanned(Node::BreakStmt, span))
311 }
312 TokenKind::Continue => {
313 let span = self.current_span();
314 self.advance();
315 Ok(spanned(Node::ContinueStmt, span))
316 }
317 _ => self.parse_expression_statement(),
318 }
319 }
320
321 fn parse_let_binding(&mut self) -> Result<SNode, ParserError> {
322 let start = self.current_span();
323 self.consume(&TokenKind::Let, "let")?;
324 let pattern = self.parse_binding_pattern()?;
325 let type_ann = if matches!(pattern, BindingPattern::Identifier(_)) {
326 self.try_parse_type_annotation()?
327 } else {
328 None
329 };
330 self.consume(&TokenKind::Assign, "=")?;
331 let value = self.parse_expression()?;
332 Ok(spanned(
333 Node::LetBinding {
334 pattern,
335 type_ann,
336 value: Box::new(value),
337 },
338 Span::merge(start, self.prev_span()),
339 ))
340 }
341
342 fn parse_var_binding(&mut self) -> Result<SNode, ParserError> {
343 let start = self.current_span();
344 self.consume(&TokenKind::Var, "var")?;
345 let pattern = self.parse_binding_pattern()?;
346 let type_ann = if matches!(pattern, BindingPattern::Identifier(_)) {
347 self.try_parse_type_annotation()?
348 } else {
349 None
350 };
351 self.consume(&TokenKind::Assign, "=")?;
352 let value = self.parse_expression()?;
353 Ok(spanned(
354 Node::VarBinding {
355 pattern,
356 type_ann,
357 value: Box::new(value),
358 },
359 Span::merge(start, self.prev_span()),
360 ))
361 }
362
363 fn parse_if_else(&mut self) -> Result<SNode, ParserError> {
364 let start = self.current_span();
365 self.consume(&TokenKind::If, "if")?;
366 let condition = self.parse_expression()?;
367 self.consume(&TokenKind::LBrace, "{")?;
368 let then_body = self.parse_block()?;
369 self.consume(&TokenKind::RBrace, "}")?;
370 self.skip_newlines();
371
372 let else_body = if self.check(&TokenKind::Else) {
373 self.advance();
374 if self.check(&TokenKind::If) {
375 Some(vec![self.parse_if_else()?])
376 } else {
377 self.consume(&TokenKind::LBrace, "{")?;
378 let body = self.parse_block()?;
379 self.consume(&TokenKind::RBrace, "}")?;
380 Some(body)
381 }
382 } else {
383 None
384 };
385
386 Ok(spanned(
387 Node::IfElse {
388 condition: Box::new(condition),
389 then_body,
390 else_body,
391 },
392 Span::merge(start, self.prev_span()),
393 ))
394 }
395
396 fn parse_for_in(&mut self) -> Result<SNode, ParserError> {
397 let start = self.current_span();
398 self.consume(&TokenKind::For, "for")?;
399 let pattern = self.parse_binding_pattern()?;
400 self.consume(&TokenKind::In, "in")?;
401 let iterable = self.parse_expression()?;
402 self.consume(&TokenKind::LBrace, "{")?;
403 let body = self.parse_block()?;
404 self.consume(&TokenKind::RBrace, "}")?;
405 Ok(spanned(
406 Node::ForIn {
407 pattern,
408 iterable: Box::new(iterable),
409 body,
410 },
411 Span::merge(start, self.prev_span()),
412 ))
413 }
414
415 fn parse_binding_pattern(&mut self) -> Result<BindingPattern, ParserError> {
418 self.skip_newlines();
419 if self.check(&TokenKind::LBrace) {
420 self.advance(); let mut fields = Vec::new();
423 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
424 if self.check(&TokenKind::Dot) {
426 self.advance(); self.consume(&TokenKind::Dot, ".")?;
429 self.consume(&TokenKind::Dot, ".")?;
430 let name = self.consume_identifier("rest variable name")?;
431 fields.push(DictPatternField {
432 key: name,
433 alias: None,
434 is_rest: true,
435 });
436 break;
438 }
439 let key = self.consume_identifier("field name")?;
440 let alias = if self.check(&TokenKind::Colon) {
441 self.advance(); Some(self.consume_identifier("alias name")?)
443 } else {
444 None
445 };
446 fields.push(DictPatternField {
447 key,
448 alias,
449 is_rest: false,
450 });
451 if self.check(&TokenKind::Comma) {
452 self.advance();
453 }
454 }
455 self.consume(&TokenKind::RBrace, "}")?;
456 Ok(BindingPattern::Dict(fields))
457 } else if self.check(&TokenKind::LBracket) {
458 self.advance(); let mut elements = Vec::new();
461 while !self.is_at_end() && !self.check(&TokenKind::RBracket) {
462 if self.check(&TokenKind::Dot) {
464 self.advance(); self.consume(&TokenKind::Dot, ".")?;
466 self.consume(&TokenKind::Dot, ".")?;
467 let name = self.consume_identifier("rest variable name")?;
468 elements.push(ListPatternElement {
469 name,
470 is_rest: true,
471 });
472 break;
474 }
475 let name = self.consume_identifier("element name")?;
476 elements.push(ListPatternElement {
477 name,
478 is_rest: false,
479 });
480 if self.check(&TokenKind::Comma) {
481 self.advance();
482 }
483 }
484 self.consume(&TokenKind::RBracket, "]")?;
485 Ok(BindingPattern::List(elements))
486 } else {
487 let name = self.consume_identifier("variable name or destructuring pattern")?;
489 Ok(BindingPattern::Identifier(name))
490 }
491 }
492
493 fn parse_match(&mut self) -> Result<SNode, ParserError> {
494 let start = self.current_span();
495 self.consume(&TokenKind::Match, "match")?;
496 let value = self.parse_expression()?;
497 self.consume(&TokenKind::LBrace, "{")?;
498 self.skip_newlines();
499
500 let mut arms = Vec::new();
501 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
502 let pattern = self.parse_expression()?;
503 self.consume(&TokenKind::Arrow, "->")?;
504 self.consume(&TokenKind::LBrace, "{")?;
505 let body = self.parse_block()?;
506 self.consume(&TokenKind::RBrace, "}")?;
507 arms.push(MatchArm { pattern, body });
508 self.skip_newlines();
509 }
510
511 self.consume(&TokenKind::RBrace, "}")?;
512 Ok(spanned(
513 Node::MatchExpr {
514 value: Box::new(value),
515 arms,
516 },
517 Span::merge(start, self.prev_span()),
518 ))
519 }
520
521 fn parse_while_loop(&mut self) -> Result<SNode, ParserError> {
522 let start = self.current_span();
523 self.consume(&TokenKind::While, "while")?;
524 let condition = if self.check(&TokenKind::LParen) {
525 self.advance();
526 let c = self.parse_expression()?;
527 self.consume(&TokenKind::RParen, ")")?;
528 c
529 } else {
530 self.parse_expression()?
531 };
532 self.consume(&TokenKind::LBrace, "{")?;
533 let body = self.parse_block()?;
534 self.consume(&TokenKind::RBrace, "}")?;
535 Ok(spanned(
536 Node::WhileLoop {
537 condition: Box::new(condition),
538 body,
539 },
540 Span::merge(start, self.prev_span()),
541 ))
542 }
543
544 fn parse_retry(&mut self) -> Result<SNode, ParserError> {
545 let start = self.current_span();
546 self.consume(&TokenKind::Retry, "retry")?;
547 let count = if self.check(&TokenKind::LParen) {
548 self.advance();
549 let c = self.parse_expression()?;
550 self.consume(&TokenKind::RParen, ")")?;
551 c
552 } else {
553 self.parse_primary()?
554 };
555 self.consume(&TokenKind::LBrace, "{")?;
556 let body = self.parse_block()?;
557 self.consume(&TokenKind::RBrace, "}")?;
558 Ok(spanned(
559 Node::Retry {
560 count: Box::new(count),
561 body,
562 },
563 Span::merge(start, self.prev_span()),
564 ))
565 }
566
567 fn parse_parallel(&mut self) -> Result<SNode, ParserError> {
568 let start = self.current_span();
569 self.consume(&TokenKind::Parallel, "parallel")?;
570 self.consume(&TokenKind::LParen, "(")?;
571 let count = self.parse_expression()?;
572 self.consume(&TokenKind::RParen, ")")?;
573 self.consume(&TokenKind::LBrace, "{")?;
574
575 let mut variable = None;
577 self.skip_newlines();
578 if let Some(tok) = self.current() {
579 if let TokenKind::Identifier(name) = &tok.kind {
580 if self.peek_kind() == Some(&TokenKind::Arrow) {
581 let name = name.clone();
582 self.advance(); self.advance(); variable = Some(name);
585 }
586 }
587 }
588
589 let body = self.parse_block()?;
590 self.consume(&TokenKind::RBrace, "}")?;
591 Ok(spanned(
592 Node::Parallel {
593 count: Box::new(count),
594 variable,
595 body,
596 },
597 Span::merge(start, self.prev_span()),
598 ))
599 }
600
601 fn parse_parallel_map(&mut self) -> Result<SNode, ParserError> {
602 let start = self.current_span();
603 self.consume(&TokenKind::ParallelMap, "parallel_map")?;
604 self.consume(&TokenKind::LParen, "(")?;
605 let list = self.parse_expression()?;
606 self.consume(&TokenKind::RParen, ")")?;
607 self.consume(&TokenKind::LBrace, "{")?;
608
609 self.skip_newlines();
610 let variable = self.consume_identifier("map variable")?;
611 self.consume(&TokenKind::Arrow, "->")?;
612
613 let body = self.parse_block()?;
614 self.consume(&TokenKind::RBrace, "}")?;
615 Ok(spanned(
616 Node::ParallelMap {
617 list: Box::new(list),
618 variable,
619 body,
620 },
621 Span::merge(start, self.prev_span()),
622 ))
623 }
624
625 fn parse_parallel_settle(&mut self) -> Result<SNode, ParserError> {
626 let start = self.current_span();
627 self.consume(&TokenKind::ParallelSettle, "parallel_settle")?;
628 self.consume(&TokenKind::LParen, "(")?;
629 let list = self.parse_expression()?;
630 self.consume(&TokenKind::RParen, ")")?;
631 self.consume(&TokenKind::LBrace, "{")?;
632
633 self.skip_newlines();
634 let variable = self.consume_identifier("settle variable")?;
635 self.consume(&TokenKind::Arrow, "->")?;
636
637 let body = self.parse_block()?;
638 self.consume(&TokenKind::RBrace, "}")?;
639 Ok(spanned(
640 Node::ParallelSettle {
641 list: Box::new(list),
642 variable,
643 body,
644 },
645 Span::merge(start, self.prev_span()),
646 ))
647 }
648
649 fn parse_return(&mut self) -> Result<SNode, ParserError> {
650 let start = self.current_span();
651 self.consume(&TokenKind::Return, "return")?;
652 if self.is_at_end() || self.check(&TokenKind::Newline) || self.check(&TokenKind::RBrace) {
653 return Ok(spanned(
654 Node::ReturnStmt { value: None },
655 Span::merge(start, self.prev_span()),
656 ));
657 }
658 let value = self.parse_expression()?;
659 Ok(spanned(
660 Node::ReturnStmt {
661 value: Some(Box::new(value)),
662 },
663 Span::merge(start, self.prev_span()),
664 ))
665 }
666
667 fn parse_throw(&mut self) -> Result<SNode, ParserError> {
668 let start = self.current_span();
669 self.consume(&TokenKind::Throw, "throw")?;
670 let value = self.parse_expression()?;
671 Ok(spanned(
672 Node::ThrowStmt {
673 value: Box::new(value),
674 },
675 Span::merge(start, self.prev_span()),
676 ))
677 }
678
679 fn parse_override(&mut self) -> Result<SNode, ParserError> {
680 let start = self.current_span();
681 self.consume(&TokenKind::Override, "override")?;
682 let name = self.consume_identifier("override name")?;
683 self.consume(&TokenKind::LParen, "(")?;
684 let params = self.parse_param_list()?;
685 self.consume(&TokenKind::RParen, ")")?;
686 self.consume(&TokenKind::LBrace, "{")?;
687 let body = self.parse_block()?;
688 self.consume(&TokenKind::RBrace, "}")?;
689 Ok(spanned(
690 Node::OverrideDecl { name, params, body },
691 Span::merge(start, self.prev_span()),
692 ))
693 }
694
695 fn parse_try_catch(&mut self) -> Result<SNode, ParserError> {
696 let start = self.current_span();
697 self.consume(&TokenKind::Try, "try")?;
698 self.consume(&TokenKind::LBrace, "{")?;
699 let body = self.parse_block()?;
700 self.consume(&TokenKind::RBrace, "}")?;
701 self.skip_newlines();
702
703 let has_catch = self.check(&TokenKind::Catch);
705 let (error_var, error_type, catch_body) = if has_catch {
706 self.advance();
707 let (ev, et) = if self.check(&TokenKind::LParen) {
708 self.advance();
710 let name = self.consume_identifier("error variable")?;
711 let ty = self.try_parse_type_annotation()?;
712 self.consume(&TokenKind::RParen, ")")?;
713 (Some(name), ty)
714 } else if matches!(
715 self.current().map(|t| &t.kind),
716 Some(TokenKind::Identifier(_))
717 ) {
718 let name = self.consume_identifier("error variable")?;
720 (Some(name), None)
721 } else {
722 (None, None)
723 };
724 self.consume(&TokenKind::LBrace, "{")?;
725 let cb = self.parse_block()?;
726 self.consume(&TokenKind::RBrace, "}")?;
727 (ev, et, cb)
728 } else {
729 (None, None, Vec::new())
730 };
731
732 self.skip_newlines();
733
734 let finally_body = if self.check(&TokenKind::Finally) {
736 self.advance();
737 self.consume(&TokenKind::LBrace, "{")?;
738 let fb = self.parse_block()?;
739 self.consume(&TokenKind::RBrace, "}")?;
740 Some(fb)
741 } else {
742 None
743 };
744
745 if !has_catch && finally_body.is_none() {
747 return Ok(spanned(
748 Node::TryExpr { body },
749 Span::merge(start, self.prev_span()),
750 ));
751 }
752
753 Ok(spanned(
754 Node::TryCatch {
755 body,
756 error_var,
757 error_type,
758 catch_body,
759 finally_body,
760 },
761 Span::merge(start, self.prev_span()),
762 ))
763 }
764
765 fn parse_select(&mut self) -> Result<SNode, ParserError> {
766 let start = self.current_span();
767 self.consume(&TokenKind::Select, "select")?;
768 self.consume(&TokenKind::LBrace, "{")?;
769 self.skip_newlines();
770
771 let mut cases = Vec::new();
772 let mut timeout = None;
773 let mut default_body = None;
774
775 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
776 self.skip_newlines();
777 if let Some(tok) = self.current() {
779 if let TokenKind::Identifier(ref id) = tok.kind {
780 if id == "timeout" {
781 self.advance();
782 let duration = self.parse_expression()?;
783 self.consume(&TokenKind::LBrace, "{")?;
784 let body = self.parse_block()?;
785 self.consume(&TokenKind::RBrace, "}")?;
786 timeout = Some((Box::new(duration), body));
787 self.skip_newlines();
788 continue;
789 }
790 if id == "default" {
791 self.advance();
792 self.consume(&TokenKind::LBrace, "{")?;
793 let body = self.parse_block()?;
794 self.consume(&TokenKind::RBrace, "}")?;
795 default_body = Some(body);
796 self.skip_newlines();
797 continue;
798 }
799 }
800 }
801 let variable = self.consume_identifier("select case variable")?;
803 self.consume(&TokenKind::From, "from")?;
804 let channel = self.parse_expression()?;
805 self.consume(&TokenKind::LBrace, "{")?;
806 let body = self.parse_block()?;
807 self.consume(&TokenKind::RBrace, "}")?;
808 cases.push(SelectCase {
809 variable,
810 channel: Box::new(channel),
811 body,
812 });
813 self.skip_newlines();
814 }
815
816 self.consume(&TokenKind::RBrace, "}")?;
817
818 if cases.is_empty() && timeout.is_none() && default_body.is_none() {
819 return Err(self.error("at least one select case"));
820 }
821 if timeout.is_some() && default_body.is_some() {
822 return Err(self.error("select cannot have both timeout and default"));
823 }
824
825 Ok(spanned(
826 Node::SelectExpr {
827 cases,
828 timeout,
829 default_body,
830 },
831 Span::merge(start, self.prev_span()),
832 ))
833 }
834
835 fn parse_fn_decl_with_pub(&mut self, is_pub: bool) -> Result<SNode, ParserError> {
836 let start = self.current_span();
837 self.consume(&TokenKind::Fn, "fn")?;
838 let name = self.consume_identifier("function name")?;
839
840 let type_params = if self.check(&TokenKind::Lt) {
842 self.advance(); self.parse_type_param_list()?
844 } else {
845 Vec::new()
846 };
847
848 self.consume(&TokenKind::LParen, "(")?;
849 let params = self.parse_typed_param_list()?;
850 self.consume(&TokenKind::RParen, ")")?;
851 let return_type = if self.check(&TokenKind::Arrow) {
853 self.advance();
854 Some(self.parse_type_expr()?)
855 } else {
856 None
857 };
858
859 let where_clauses = self.parse_where_clauses()?;
861
862 self.consume(&TokenKind::LBrace, "{")?;
863 let body = self.parse_block()?;
864 self.consume(&TokenKind::RBrace, "}")?;
865 Ok(spanned(
866 Node::FnDecl {
867 name,
868 type_params,
869 params,
870 return_type,
871 where_clauses,
872 body,
873 is_pub,
874 },
875 Span::merge(start, self.prev_span()),
876 ))
877 }
878
879 fn parse_type_decl(&mut self) -> Result<SNode, ParserError> {
880 let start = self.current_span();
881 self.consume(&TokenKind::TypeKw, "type")?;
882 let name = self.consume_identifier("type name")?;
883 self.consume(&TokenKind::Assign, "=")?;
884 let type_expr = self.parse_type_expr()?;
885 Ok(spanned(
886 Node::TypeDecl { name, type_expr },
887 Span::merge(start, self.prev_span()),
888 ))
889 }
890
891 fn parse_enum_decl(&mut self) -> Result<SNode, ParserError> {
892 let start = self.current_span();
893 self.consume(&TokenKind::Enum, "enum")?;
894 let name = self.consume_identifier("enum name")?;
895 self.consume(&TokenKind::LBrace, "{")?;
896 self.skip_newlines();
897
898 let mut variants = Vec::new();
899 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
900 let variant_name = self.consume_identifier("variant name")?;
901 let fields = if self.check(&TokenKind::LParen) {
902 self.advance();
903 let params = self.parse_typed_param_list()?;
904 self.consume(&TokenKind::RParen, ")")?;
905 params
906 } else {
907 Vec::new()
908 };
909 variants.push(EnumVariant {
910 name: variant_name,
911 fields,
912 });
913 self.skip_newlines();
914 if self.check(&TokenKind::Comma) {
915 self.advance();
916 self.skip_newlines();
917 }
918 }
919
920 self.consume(&TokenKind::RBrace, "}")?;
921 Ok(spanned(
922 Node::EnumDecl { name, variants },
923 Span::merge(start, self.prev_span()),
924 ))
925 }
926
927 fn parse_struct_decl(&mut self) -> Result<SNode, ParserError> {
928 let start = self.current_span();
929 self.consume(&TokenKind::Struct, "struct")?;
930 let name = self.consume_identifier("struct name")?;
931 self.consume(&TokenKind::LBrace, "{")?;
932 self.skip_newlines();
933
934 let mut fields = Vec::new();
935 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
936 let field_name = self.consume_identifier("field name")?;
937 let optional = if self.check(&TokenKind::Question) {
938 self.advance();
939 true
940 } else {
941 false
942 };
943 let type_expr = self.try_parse_type_annotation()?;
944 fields.push(StructField {
945 name: field_name,
946 type_expr,
947 optional,
948 });
949 self.skip_newlines();
950 if self.check(&TokenKind::Comma) {
951 self.advance();
952 self.skip_newlines();
953 }
954 }
955
956 self.consume(&TokenKind::RBrace, "}")?;
957 Ok(spanned(
958 Node::StructDecl { name, fields },
959 Span::merge(start, self.prev_span()),
960 ))
961 }
962
963 fn parse_interface_decl(&mut self) -> Result<SNode, ParserError> {
964 let start = self.current_span();
965 self.consume(&TokenKind::Interface, "interface")?;
966 let name = self.consume_identifier("interface name")?;
967 self.consume(&TokenKind::LBrace, "{")?;
968 self.skip_newlines();
969
970 let mut methods = Vec::new();
971 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
972 self.consume(&TokenKind::Fn, "fn")?;
973 let method_name = self.consume_identifier("method name")?;
974 self.consume(&TokenKind::LParen, "(")?;
975 let params = self.parse_typed_param_list()?;
976 self.consume(&TokenKind::RParen, ")")?;
977 let return_type = if self.check(&TokenKind::Arrow) {
979 self.advance();
980 Some(self.parse_type_expr()?)
981 } else {
982 None
983 };
984 methods.push(InterfaceMethod {
985 name: method_name,
986 params,
987 return_type,
988 });
989 self.skip_newlines();
990 }
991
992 self.consume(&TokenKind::RBrace, "}")?;
993 Ok(spanned(
994 Node::InterfaceDecl { name, methods },
995 Span::merge(start, self.prev_span()),
996 ))
997 }
998
999 fn parse_impl_block(&mut self) -> Result<SNode, ParserError> {
1000 let start = self.current_span();
1001 self.consume(&TokenKind::Impl, "impl")?;
1002 let type_name = self.consume_identifier("type name")?;
1003 self.consume(&TokenKind::LBrace, "{")?;
1004 self.skip_newlines();
1005
1006 let mut methods = Vec::new();
1007 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1008 let is_pub = self.check(&TokenKind::Pub);
1009 if is_pub {
1010 self.advance();
1011 }
1012 let method = self.parse_fn_decl_with_pub(is_pub)?;
1013 methods.push(method);
1014 self.skip_newlines();
1015 }
1016
1017 self.consume(&TokenKind::RBrace, "}")?;
1018 Ok(spanned(
1019 Node::ImplBlock { type_name, methods },
1020 Span::merge(start, self.prev_span()),
1021 ))
1022 }
1023
1024 fn parse_guard(&mut self) -> Result<SNode, ParserError> {
1025 let start = self.current_span();
1026 self.consume(&TokenKind::Guard, "guard")?;
1027 let condition = self.parse_expression()?;
1028 self.consume(&TokenKind::Else, "else")?;
1030 self.consume(&TokenKind::LBrace, "{")?;
1031 let else_body = self.parse_block()?;
1032 self.consume(&TokenKind::RBrace, "}")?;
1033 Ok(spanned(
1034 Node::GuardStmt {
1035 condition: Box::new(condition),
1036 else_body,
1037 },
1038 Span::merge(start, self.prev_span()),
1039 ))
1040 }
1041
1042 fn parse_require(&mut self) -> Result<SNode, ParserError> {
1043 let start = self.current_span();
1044 self.consume(&TokenKind::Require, "require")?;
1045 let condition = self.parse_expression()?;
1046 let message = if self.check(&TokenKind::Comma) {
1047 self.advance();
1048 Some(Box::new(self.parse_expression()?))
1049 } else {
1050 None
1051 };
1052 Ok(spanned(
1053 Node::RequireStmt {
1054 condition: Box::new(condition),
1055 message,
1056 },
1057 Span::merge(start, self.prev_span()),
1058 ))
1059 }
1060
1061 fn parse_deadline(&mut self) -> Result<SNode, ParserError> {
1062 let start = self.current_span();
1063 self.consume(&TokenKind::Deadline, "deadline")?;
1064 let duration = self.parse_primary()?;
1065 self.consume(&TokenKind::LBrace, "{")?;
1066 let body = self.parse_block()?;
1067 self.consume(&TokenKind::RBrace, "}")?;
1068 Ok(spanned(
1069 Node::DeadlineBlock {
1070 duration: Box::new(duration),
1071 body,
1072 },
1073 Span::merge(start, self.prev_span()),
1074 ))
1075 }
1076
1077 fn parse_yield(&mut self) -> Result<SNode, ParserError> {
1078 let start = self.current_span();
1079 self.consume(&TokenKind::Yield, "yield")?;
1080 if self.is_at_end() || self.check(&TokenKind::Newline) || self.check(&TokenKind::RBrace) {
1081 return Ok(spanned(
1082 Node::YieldExpr { value: None },
1083 Span::merge(start, self.prev_span()),
1084 ));
1085 }
1086 let value = self.parse_expression()?;
1087 Ok(spanned(
1088 Node::YieldExpr {
1089 value: Some(Box::new(value)),
1090 },
1091 Span::merge(start, self.prev_span()),
1092 ))
1093 }
1094
1095 fn parse_mutex(&mut self) -> Result<SNode, ParserError> {
1096 let start = self.current_span();
1097 self.consume(&TokenKind::Mutex, "mutex")?;
1098 self.consume(&TokenKind::LBrace, "{")?;
1099 let body = self.parse_block()?;
1100 self.consume(&TokenKind::RBrace, "}")?;
1101 Ok(spanned(
1102 Node::MutexBlock { body },
1103 Span::merge(start, self.prev_span()),
1104 ))
1105 }
1106
1107 fn parse_ask_expr(&mut self) -> Result<SNode, ParserError> {
1108 let start = self.current_span();
1109 self.consume(&TokenKind::Ask, "ask")?;
1110 self.consume(&TokenKind::LBrace, "{")?;
1111 let mut entries = Vec::new();
1113 self.skip_newlines();
1114 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1115 let key_span = self.current_span();
1116 let name = self.consume_identifier("ask field")?;
1117 let key = spanned(Node::StringLiteral(name), key_span);
1118 self.consume(&TokenKind::Colon, ":")?;
1119 let value = self.parse_expression()?;
1120 entries.push(DictEntry { key, value });
1121 self.skip_newlines();
1122 if self.check(&TokenKind::Comma) {
1123 self.advance();
1124 self.skip_newlines();
1125 }
1126 }
1127 self.consume(&TokenKind::RBrace, "}")?;
1128 Ok(spanned(
1129 Node::AskExpr { fields: entries },
1130 Span::merge(start, self.prev_span()),
1131 ))
1132 }
1133
1134 fn parse_expression_statement(&mut self) -> Result<SNode, ParserError> {
1137 let start = self.current_span();
1138 let expr = self.parse_expression()?;
1139
1140 let is_assignable = matches!(
1143 expr.node,
1144 Node::Identifier(_) | Node::PropertyAccess { .. } | Node::SubscriptAccess { .. }
1145 );
1146 if is_assignable {
1147 if self.check(&TokenKind::Assign) {
1148 self.advance();
1149 let value = self.parse_expression()?;
1150 return Ok(spanned(
1151 Node::Assignment {
1152 target: Box::new(expr),
1153 value: Box::new(value),
1154 op: None,
1155 },
1156 Span::merge(start, self.prev_span()),
1157 ));
1158 }
1159 let compound_op = if self.check(&TokenKind::PlusAssign) {
1160 Some("+")
1161 } else if self.check(&TokenKind::MinusAssign) {
1162 Some("-")
1163 } else if self.check(&TokenKind::StarAssign) {
1164 Some("*")
1165 } else if self.check(&TokenKind::SlashAssign) {
1166 Some("/")
1167 } else if self.check(&TokenKind::PercentAssign) {
1168 Some("%")
1169 } else {
1170 None
1171 };
1172 if let Some(op) = compound_op {
1173 self.advance();
1174 let value = self.parse_expression()?;
1175 return Ok(spanned(
1176 Node::Assignment {
1177 target: Box::new(expr),
1178 value: Box::new(value),
1179 op: Some(op.into()),
1180 },
1181 Span::merge(start, self.prev_span()),
1182 ));
1183 }
1184 }
1185
1186 Ok(expr)
1187 }
1188
1189 fn parse_expression(&mut self) -> Result<SNode, ParserError> {
1190 self.skip_newlines();
1191 self.parse_pipe()
1192 }
1193
1194 fn parse_pipe(&mut self) -> Result<SNode, ParserError> {
1195 let mut left = self.parse_range()?;
1196 while self.check_skip_newlines(&TokenKind::Pipe) {
1197 let start = left.span;
1198 self.advance();
1199 let right = self.parse_range()?;
1200 left = spanned(
1201 Node::BinaryOp {
1202 op: "|>".into(),
1203 left: Box::new(left),
1204 right: Box::new(right),
1205 },
1206 Span::merge(start, self.prev_span()),
1207 );
1208 }
1209 Ok(left)
1210 }
1211
1212 fn parse_range(&mut self) -> Result<SNode, ParserError> {
1213 let left = self.parse_ternary()?;
1214 if self.check(&TokenKind::Thru) {
1215 let start = left.span;
1216 self.advance();
1217 let right = self.parse_ternary()?;
1218 return Ok(spanned(
1219 Node::RangeExpr {
1220 start: Box::new(left),
1221 end: Box::new(right),
1222 inclusive: true,
1223 },
1224 Span::merge(start, self.prev_span()),
1225 ));
1226 }
1227 if self.check(&TokenKind::Upto) {
1228 let start = left.span;
1229 self.advance();
1230 let right = self.parse_ternary()?;
1231 return Ok(spanned(
1232 Node::RangeExpr {
1233 start: Box::new(left),
1234 end: Box::new(right),
1235 inclusive: false,
1236 },
1237 Span::merge(start, self.prev_span()),
1238 ));
1239 }
1240 Ok(left)
1241 }
1242
1243 fn parse_ternary(&mut self) -> Result<SNode, ParserError> {
1244 let condition = self.parse_nil_coalescing()?;
1245 if !self.check(&TokenKind::Question) {
1246 return Ok(condition);
1247 }
1248 let start = condition.span;
1249 self.advance(); let true_val = self.parse_nil_coalescing()?;
1251 self.consume(&TokenKind::Colon, ":")?;
1252 let false_val = self.parse_nil_coalescing()?;
1253 Ok(spanned(
1254 Node::Ternary {
1255 condition: Box::new(condition),
1256 true_expr: Box::new(true_val),
1257 false_expr: Box::new(false_val),
1258 },
1259 Span::merge(start, self.prev_span()),
1260 ))
1261 }
1262
1263 fn parse_nil_coalescing(&mut self) -> Result<SNode, ParserError> {
1264 let mut left = self.parse_logical_or()?;
1265 while self.check(&TokenKind::NilCoal) {
1266 let start = left.span;
1267 self.advance();
1268 let right = self.parse_logical_or()?;
1269 left = spanned(
1270 Node::BinaryOp {
1271 op: "??".into(),
1272 left: Box::new(left),
1273 right: Box::new(right),
1274 },
1275 Span::merge(start, self.prev_span()),
1276 );
1277 }
1278 Ok(left)
1279 }
1280
1281 fn parse_logical_or(&mut self) -> Result<SNode, ParserError> {
1282 let mut left = self.parse_logical_and()?;
1283 while self.check_skip_newlines(&TokenKind::Or) {
1284 let start = left.span;
1285 self.advance();
1286 let right = self.parse_logical_and()?;
1287 left = spanned(
1288 Node::BinaryOp {
1289 op: "||".into(),
1290 left: Box::new(left),
1291 right: Box::new(right),
1292 },
1293 Span::merge(start, self.prev_span()),
1294 );
1295 }
1296 Ok(left)
1297 }
1298
1299 fn parse_logical_and(&mut self) -> Result<SNode, ParserError> {
1300 let mut left = self.parse_equality()?;
1301 while self.check_skip_newlines(&TokenKind::And) {
1302 let start = left.span;
1303 self.advance();
1304 let right = self.parse_equality()?;
1305 left = spanned(
1306 Node::BinaryOp {
1307 op: "&&".into(),
1308 left: Box::new(left),
1309 right: Box::new(right),
1310 },
1311 Span::merge(start, self.prev_span()),
1312 );
1313 }
1314 Ok(left)
1315 }
1316
1317 fn parse_equality(&mut self) -> Result<SNode, ParserError> {
1318 let mut left = self.parse_comparison()?;
1319 while self.check(&TokenKind::Eq) || self.check(&TokenKind::Neq) {
1320 let start = left.span;
1321 let op = if self.check(&TokenKind::Eq) {
1322 "=="
1323 } else {
1324 "!="
1325 };
1326 self.advance();
1327 let right = self.parse_comparison()?;
1328 left = spanned(
1329 Node::BinaryOp {
1330 op: op.into(),
1331 left: Box::new(left),
1332 right: Box::new(right),
1333 },
1334 Span::merge(start, self.prev_span()),
1335 );
1336 }
1337 Ok(left)
1338 }
1339
1340 fn parse_comparison(&mut self) -> Result<SNode, ParserError> {
1341 let mut left = self.parse_additive()?;
1342 loop {
1343 if self.check(&TokenKind::Lt)
1344 || self.check(&TokenKind::Gt)
1345 || self.check(&TokenKind::Lte)
1346 || self.check(&TokenKind::Gte)
1347 {
1348 let start = left.span;
1349 let op = match self.current().map(|t| &t.kind) {
1350 Some(TokenKind::Lt) => "<",
1351 Some(TokenKind::Gt) => ">",
1352 Some(TokenKind::Lte) => "<=",
1353 Some(TokenKind::Gte) => ">=",
1354 _ => "<",
1355 };
1356 self.advance();
1357 let right = self.parse_additive()?;
1358 left = spanned(
1359 Node::BinaryOp {
1360 op: op.into(),
1361 left: Box::new(left),
1362 right: Box::new(right),
1363 },
1364 Span::merge(start, self.prev_span()),
1365 );
1366 } else if self.check(&TokenKind::In) {
1367 let start = left.span;
1368 self.advance();
1369 let right = self.parse_additive()?;
1370 left = spanned(
1371 Node::BinaryOp {
1372 op: "in".into(),
1373 left: Box::new(left),
1374 right: Box::new(right),
1375 },
1376 Span::merge(start, self.prev_span()),
1377 );
1378 } else if self.check_identifier("not") {
1379 let saved = self.pos;
1381 self.advance(); if self.check(&TokenKind::In) {
1383 let start = left.span;
1384 self.advance(); let right = self.parse_additive()?;
1386 left = spanned(
1387 Node::BinaryOp {
1388 op: "not_in".into(),
1389 left: Box::new(left),
1390 right: Box::new(right),
1391 },
1392 Span::merge(start, self.prev_span()),
1393 );
1394 } else {
1395 self.pos = saved;
1396 break;
1397 }
1398 } else {
1399 break;
1400 }
1401 }
1402 Ok(left)
1403 }
1404
1405 fn parse_additive(&mut self) -> Result<SNode, ParserError> {
1406 let mut left = self.parse_multiplicative()?;
1407 while self.check_skip_newlines(&TokenKind::Plus) || self.check(&TokenKind::Minus) {
1408 let start = left.span;
1409 let op = if self.check(&TokenKind::Plus) {
1410 "+"
1411 } else {
1412 "-"
1413 };
1414 self.advance();
1415 let right = self.parse_multiplicative()?;
1416 left = spanned(
1417 Node::BinaryOp {
1418 op: op.into(),
1419 left: Box::new(left),
1420 right: Box::new(right),
1421 },
1422 Span::merge(start, self.prev_span()),
1423 );
1424 }
1425 Ok(left)
1426 }
1427
1428 fn parse_multiplicative(&mut self) -> Result<SNode, ParserError> {
1429 let mut left = self.parse_unary()?;
1430 while self.check_skip_newlines(&TokenKind::Star)
1431 || self.check_skip_newlines(&TokenKind::Slash)
1432 || self.check_skip_newlines(&TokenKind::Percent)
1433 {
1434 let start = left.span;
1435 let op = if self.check(&TokenKind::Star) {
1436 "*"
1437 } else if self.check(&TokenKind::Slash) {
1438 "/"
1439 } else {
1440 "%"
1441 };
1442 self.advance();
1443 let right = self.parse_unary()?;
1444 left = spanned(
1445 Node::BinaryOp {
1446 op: op.into(),
1447 left: Box::new(left),
1448 right: Box::new(right),
1449 },
1450 Span::merge(start, self.prev_span()),
1451 );
1452 }
1453 Ok(left)
1454 }
1455
1456 fn parse_unary(&mut self) -> Result<SNode, ParserError> {
1457 if self.check(&TokenKind::Not) {
1458 let start = self.current_span();
1459 self.advance();
1460 let operand = self.parse_unary()?;
1461 return Ok(spanned(
1462 Node::UnaryOp {
1463 op: "!".into(),
1464 operand: Box::new(operand),
1465 },
1466 Span::merge(start, self.prev_span()),
1467 ));
1468 }
1469 if self.check(&TokenKind::Minus) {
1470 let start = self.current_span();
1471 self.advance();
1472 let operand = self.parse_unary()?;
1473 return Ok(spanned(
1474 Node::UnaryOp {
1475 op: "-".into(),
1476 operand: Box::new(operand),
1477 },
1478 Span::merge(start, self.prev_span()),
1479 ));
1480 }
1481 self.parse_postfix()
1482 }
1483
1484 fn parse_postfix(&mut self) -> Result<SNode, ParserError> {
1485 let mut expr = self.parse_primary()?;
1486
1487 loop {
1488 if self.check_skip_newlines(&TokenKind::Dot)
1489 || self.check_skip_newlines(&TokenKind::QuestionDot)
1490 {
1491 let optional = self.check(&TokenKind::QuestionDot);
1492 let start = expr.span;
1493 self.advance();
1494 let member = self.consume_identifier_or_keyword("member name")?;
1495 if self.check(&TokenKind::LParen) {
1496 self.advance();
1497 let args = self.parse_arg_list()?;
1498 self.consume(&TokenKind::RParen, ")")?;
1499 if optional {
1500 expr = spanned(
1501 Node::OptionalMethodCall {
1502 object: Box::new(expr),
1503 method: member,
1504 args,
1505 },
1506 Span::merge(start, self.prev_span()),
1507 );
1508 } else {
1509 expr = spanned(
1510 Node::MethodCall {
1511 object: Box::new(expr),
1512 method: member,
1513 args,
1514 },
1515 Span::merge(start, self.prev_span()),
1516 );
1517 }
1518 } else if optional {
1519 expr = spanned(
1520 Node::OptionalPropertyAccess {
1521 object: Box::new(expr),
1522 property: member,
1523 },
1524 Span::merge(start, self.prev_span()),
1525 );
1526 } else {
1527 expr = spanned(
1528 Node::PropertyAccess {
1529 object: Box::new(expr),
1530 property: member,
1531 },
1532 Span::merge(start, self.prev_span()),
1533 );
1534 }
1535 } else if self.check(&TokenKind::LBracket) {
1536 let start = expr.span;
1537 self.advance();
1538
1539 if self.check(&TokenKind::Colon) {
1544 self.advance(); let end_expr = if self.check(&TokenKind::RBracket) {
1547 None
1548 } else {
1549 Some(Box::new(self.parse_expression()?))
1550 };
1551 self.consume(&TokenKind::RBracket, "]")?;
1552 expr = spanned(
1553 Node::SliceAccess {
1554 object: Box::new(expr),
1555 start: None,
1556 end: end_expr,
1557 },
1558 Span::merge(start, self.prev_span()),
1559 );
1560 } else {
1561 let index = self.parse_expression()?;
1562 if self.check(&TokenKind::Colon) {
1563 self.advance(); let end_expr = if self.check(&TokenKind::RBracket) {
1566 None
1567 } else {
1568 Some(Box::new(self.parse_expression()?))
1569 };
1570 self.consume(&TokenKind::RBracket, "]")?;
1571 expr = spanned(
1572 Node::SliceAccess {
1573 object: Box::new(expr),
1574 start: Some(Box::new(index)),
1575 end: end_expr,
1576 },
1577 Span::merge(start, self.prev_span()),
1578 );
1579 } else {
1580 self.consume(&TokenKind::RBracket, "]")?;
1581 expr = spanned(
1582 Node::SubscriptAccess {
1583 object: Box::new(expr),
1584 index: Box::new(index),
1585 },
1586 Span::merge(start, self.prev_span()),
1587 );
1588 }
1589 }
1590 } else if self.check(&TokenKind::LParen) && matches!(expr.node, Node::Identifier(_)) {
1591 let start = expr.span;
1592 self.advance();
1593 let args = self.parse_arg_list()?;
1594 self.consume(&TokenKind::RParen, ")")?;
1595 if let Node::Identifier(name) = expr.node {
1596 expr = spanned(
1597 Node::FunctionCall { name, args },
1598 Span::merge(start, self.prev_span()),
1599 );
1600 }
1601 } else if self.check(&TokenKind::Question) {
1602 let next_pos = self.pos + 1;
1605 let is_ternary = self.tokens.get(next_pos).is_some_and(|t| {
1606 matches!(
1607 t.kind,
1608 TokenKind::Identifier(_)
1609 | TokenKind::IntLiteral(_)
1610 | TokenKind::FloatLiteral(_)
1611 | TokenKind::StringLiteral(_)
1612 | TokenKind::InterpolatedString(_)
1613 | TokenKind::True
1614 | TokenKind::False
1615 | TokenKind::Nil
1616 | TokenKind::LParen
1617 | TokenKind::LBracket
1618 | TokenKind::LBrace
1619 | TokenKind::Not
1620 | TokenKind::Minus
1621 | TokenKind::Fn
1622 )
1623 });
1624 if is_ternary {
1625 break;
1626 }
1627 let start = expr.span;
1628 self.advance(); expr = spanned(
1630 Node::TryOperator {
1631 operand: Box::new(expr),
1632 },
1633 Span::merge(start, self.prev_span()),
1634 );
1635 } else {
1636 break;
1637 }
1638 }
1639
1640 Ok(expr)
1641 }
1642
1643 fn parse_primary(&mut self) -> Result<SNode, ParserError> {
1644 let tok = self.current().ok_or_else(|| ParserError::UnexpectedEof {
1645 expected: "expression".into(),
1646 })?;
1647 let start = self.current_span();
1648
1649 match &tok.kind {
1650 TokenKind::StringLiteral(s) => {
1651 let s = s.clone();
1652 self.advance();
1653 Ok(spanned(
1654 Node::StringLiteral(s),
1655 Span::merge(start, self.prev_span()),
1656 ))
1657 }
1658 TokenKind::InterpolatedString(segments) => {
1659 let segments = segments.clone();
1660 self.advance();
1661 Ok(spanned(
1662 Node::InterpolatedString(segments),
1663 Span::merge(start, self.prev_span()),
1664 ))
1665 }
1666 TokenKind::IntLiteral(n) => {
1667 let n = *n;
1668 self.advance();
1669 Ok(spanned(
1670 Node::IntLiteral(n),
1671 Span::merge(start, self.prev_span()),
1672 ))
1673 }
1674 TokenKind::FloatLiteral(n) => {
1675 let n = *n;
1676 self.advance();
1677 Ok(spanned(
1678 Node::FloatLiteral(n),
1679 Span::merge(start, self.prev_span()),
1680 ))
1681 }
1682 TokenKind::True => {
1683 self.advance();
1684 Ok(spanned(
1685 Node::BoolLiteral(true),
1686 Span::merge(start, self.prev_span()),
1687 ))
1688 }
1689 TokenKind::False => {
1690 self.advance();
1691 Ok(spanned(
1692 Node::BoolLiteral(false),
1693 Span::merge(start, self.prev_span()),
1694 ))
1695 }
1696 TokenKind::Nil => {
1697 self.advance();
1698 Ok(spanned(
1699 Node::NilLiteral,
1700 Span::merge(start, self.prev_span()),
1701 ))
1702 }
1703 TokenKind::Identifier(name) => {
1704 let name = name.clone();
1705 self.advance();
1706 Ok(spanned(
1707 Node::Identifier(name),
1708 Span::merge(start, self.prev_span()),
1709 ))
1710 }
1711 TokenKind::LParen => {
1712 self.advance();
1713 let expr = self.parse_expression()?;
1714 self.consume(&TokenKind::RParen, ")")?;
1715 Ok(expr)
1716 }
1717 TokenKind::LBracket => self.parse_list_literal(),
1718 TokenKind::LBrace => self.parse_dict_or_closure(),
1719 TokenKind::Parallel => self.parse_parallel(),
1720 TokenKind::ParallelMap => self.parse_parallel_map(),
1721 TokenKind::ParallelSettle => self.parse_parallel_settle(),
1722 TokenKind::Retry => self.parse_retry(),
1723 TokenKind::If => self.parse_if_else(),
1724 TokenKind::Spawn => self.parse_spawn_expr(),
1725 TokenKind::DurationLiteral(ms) => {
1726 let ms = *ms;
1727 self.advance();
1728 Ok(spanned(
1729 Node::DurationLiteral(ms),
1730 Span::merge(start, self.prev_span()),
1731 ))
1732 }
1733 TokenKind::Ask => self.parse_ask_expr(),
1734 TokenKind::Deadline => self.parse_deadline(),
1735 TokenKind::Try => self.parse_try_catch(),
1736 TokenKind::Fn => self.parse_fn_expr(),
1737 _ => Err(self.error("expression")),
1738 }
1739 }
1740
1741 fn parse_fn_expr(&mut self) -> Result<SNode, ParserError> {
1745 let start = self.current_span();
1746 self.consume(&TokenKind::Fn, "fn")?;
1747 self.consume(&TokenKind::LParen, "(")?;
1748 let params = self.parse_typed_param_list()?;
1749 self.consume(&TokenKind::RParen, ")")?;
1750 self.consume(&TokenKind::LBrace, "{")?;
1751 let body = self.parse_block()?;
1752 self.consume(&TokenKind::RBrace, "}")?;
1753 Ok(spanned(
1754 Node::Closure {
1755 params,
1756 body,
1757 fn_syntax: true,
1758 },
1759 Span::merge(start, self.prev_span()),
1760 ))
1761 }
1762
1763 fn parse_spawn_expr(&mut self) -> Result<SNode, ParserError> {
1764 let start = self.current_span();
1765 self.consume(&TokenKind::Spawn, "spawn")?;
1766 self.consume(&TokenKind::LBrace, "{")?;
1767 let body = self.parse_block()?;
1768 self.consume(&TokenKind::RBrace, "}")?;
1769 Ok(spanned(
1770 Node::SpawnExpr { body },
1771 Span::merge(start, self.prev_span()),
1772 ))
1773 }
1774
1775 fn parse_list_literal(&mut self) -> Result<SNode, ParserError> {
1776 let start = self.current_span();
1777 self.consume(&TokenKind::LBracket, "[")?;
1778 let mut elements = Vec::new();
1779 self.skip_newlines();
1780
1781 while !self.is_at_end() && !self.check(&TokenKind::RBracket) {
1782 if self.check(&TokenKind::Dot) {
1784 let saved_pos = self.pos;
1785 self.advance(); if self.check(&TokenKind::Dot) {
1787 self.advance(); self.consume(&TokenKind::Dot, ".")?; let spread_start = self.tokens[saved_pos].span;
1790 let expr = self.parse_expression()?;
1791 elements.push(spanned(
1792 Node::Spread(Box::new(expr)),
1793 Span::merge(spread_start, self.prev_span()),
1794 ));
1795 } else {
1796 self.pos = saved_pos;
1798 elements.push(self.parse_expression()?);
1799 }
1800 } else {
1801 elements.push(self.parse_expression()?);
1802 }
1803 self.skip_newlines();
1804 if self.check(&TokenKind::Comma) {
1805 self.advance();
1806 self.skip_newlines();
1807 }
1808 }
1809
1810 self.consume(&TokenKind::RBracket, "]")?;
1811 Ok(spanned(
1812 Node::ListLiteral(elements),
1813 Span::merge(start, self.prev_span()),
1814 ))
1815 }
1816
1817 fn parse_dict_or_closure(&mut self) -> Result<SNode, ParserError> {
1818 let start = self.current_span();
1819 self.consume(&TokenKind::LBrace, "{")?;
1820 self.skip_newlines();
1821
1822 if self.check(&TokenKind::RBrace) {
1824 self.advance();
1825 return Ok(spanned(
1826 Node::DictLiteral(Vec::new()),
1827 Span::merge(start, self.prev_span()),
1828 ));
1829 }
1830
1831 let saved = self.pos;
1833 if self.is_closure_lookahead() {
1834 self.pos = saved;
1835 return self.parse_closure_body(start);
1836 }
1837 self.pos = saved;
1838 self.parse_dict_literal(start)
1839 }
1840
1841 fn is_closure_lookahead(&mut self) -> bool {
1844 let mut depth = 0;
1845 while !self.is_at_end() {
1846 if let Some(tok) = self.current() {
1847 match &tok.kind {
1848 TokenKind::Arrow if depth == 0 => return true,
1849 TokenKind::LBrace | TokenKind::LParen | TokenKind::LBracket => depth += 1,
1850 TokenKind::RBrace if depth == 0 => return false,
1851 TokenKind::RBrace => depth -= 1,
1852 TokenKind::RParen | TokenKind::RBracket => {
1853 if depth > 0 {
1854 depth -= 1;
1855 }
1856 }
1857 _ => {}
1858 }
1859 self.advance();
1860 } else {
1861 return false;
1862 }
1863 }
1864 false
1865 }
1866
1867 fn parse_closure_body(&mut self, start: Span) -> Result<SNode, ParserError> {
1869 let params = self.parse_typed_param_list_until_arrow()?;
1870 self.consume(&TokenKind::Arrow, "->")?;
1871 let body = self.parse_block()?;
1872 self.consume(&TokenKind::RBrace, "}")?;
1873 Ok(spanned(
1874 Node::Closure {
1875 params,
1876 body,
1877 fn_syntax: false,
1878 },
1879 Span::merge(start, self.prev_span()),
1880 ))
1881 }
1882
1883 fn parse_typed_param_list_until_arrow(&mut self) -> Result<Vec<TypedParam>, ParserError> {
1885 self.parse_typed_params_until(|tok| tok == &TokenKind::Arrow)
1886 }
1887
1888 fn parse_dict_literal(&mut self, start: Span) -> Result<SNode, ParserError> {
1889 let mut entries = Vec::new();
1890 self.skip_newlines();
1891
1892 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1893 if self.check(&TokenKind::Dot) {
1895 let saved_pos = self.pos;
1896 self.advance(); if self.check(&TokenKind::Dot) {
1898 self.advance(); if self.check(&TokenKind::Dot) {
1900 self.advance(); let spread_start = self.tokens[saved_pos].span;
1902 let expr = self.parse_expression()?;
1903 entries.push(DictEntry {
1904 key: spanned(Node::NilLiteral, spread_start),
1905 value: spanned(
1906 Node::Spread(Box::new(expr)),
1907 Span::merge(spread_start, self.prev_span()),
1908 ),
1909 });
1910 self.skip_newlines();
1911 if self.check(&TokenKind::Comma) {
1912 self.advance();
1913 self.skip_newlines();
1914 }
1915 continue;
1916 }
1917 self.pos = saved_pos;
1919 } else {
1920 self.pos = saved_pos;
1921 }
1922 }
1923 let key = if self.check(&TokenKind::LBracket) {
1924 self.advance();
1926 let k = self.parse_expression()?;
1927 self.consume(&TokenKind::RBracket, "]")?;
1928 k
1929 } else if matches!(
1930 self.current().map(|t| &t.kind),
1931 Some(TokenKind::StringLiteral(_))
1932 ) {
1933 let key_span = self.current_span();
1935 let name =
1936 if let Some(TokenKind::StringLiteral(s)) = self.current().map(|t| &t.kind) {
1937 s.clone()
1938 } else {
1939 unreachable!()
1940 };
1941 self.advance();
1942 spanned(Node::StringLiteral(name), key_span)
1943 } else {
1944 let key_span = self.current_span();
1946 let name = self.consume_identifier_or_keyword("dict key")?;
1947 spanned(Node::StringLiteral(name), key_span)
1948 };
1949 self.consume(&TokenKind::Colon, ":")?;
1950 let value = self.parse_expression()?;
1951 entries.push(DictEntry { key, value });
1952 self.skip_newlines();
1953 if self.check(&TokenKind::Comma) {
1954 self.advance();
1955 self.skip_newlines();
1956 }
1957 }
1958
1959 self.consume(&TokenKind::RBrace, "}")?;
1960 Ok(spanned(
1961 Node::DictLiteral(entries),
1962 Span::merge(start, self.prev_span()),
1963 ))
1964 }
1965
1966 fn parse_param_list(&mut self) -> Result<Vec<String>, ParserError> {
1970 let mut params = Vec::new();
1971 self.skip_newlines();
1972
1973 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
1974 params.push(self.consume_identifier("parameter name")?);
1975 if self.check(&TokenKind::Comma) {
1976 self.advance();
1977 self.skip_newlines();
1978 }
1979 }
1980 Ok(params)
1981 }
1982
1983 fn parse_typed_param_list(&mut self) -> Result<Vec<TypedParam>, ParserError> {
1985 self.parse_typed_params_until(|tok| tok == &TokenKind::RParen)
1986 }
1987
1988 fn parse_typed_params_until(
1991 &mut self,
1992 is_terminator: impl Fn(&TokenKind) -> bool,
1993 ) -> Result<Vec<TypedParam>, ParserError> {
1994 let mut params = Vec::new();
1995 let mut seen_default = false;
1996 self.skip_newlines();
1997
1998 while !self.is_at_end() {
1999 if let Some(tok) = self.current() {
2000 if is_terminator(&tok.kind) {
2001 break;
2002 }
2003 } else {
2004 break;
2005 }
2006 let name = self.consume_identifier("parameter name")?;
2007 let type_expr = self.try_parse_type_annotation()?;
2008 let default_value = if self.check(&TokenKind::Assign) {
2009 self.advance();
2010 seen_default = true;
2011 Some(Box::new(self.parse_expression()?))
2012 } else {
2013 if seen_default {
2014 return Err(self.error(
2015 "Required parameter cannot follow a parameter with a default value",
2016 ));
2017 }
2018 None
2019 };
2020 params.push(TypedParam {
2021 name,
2022 type_expr,
2023 default_value,
2024 });
2025 if self.check(&TokenKind::Comma) {
2026 self.advance();
2027 self.skip_newlines();
2028 }
2029 }
2030 Ok(params)
2031 }
2032
2033 fn parse_type_param_list(&mut self) -> Result<Vec<TypeParam>, ParserError> {
2035 let mut params = Vec::new();
2036 self.skip_newlines();
2037 while !self.is_at_end() && !self.check(&TokenKind::Gt) {
2038 let name = self.consume_identifier("type parameter name")?;
2039 params.push(TypeParam { name });
2040 if self.check(&TokenKind::Comma) {
2041 self.advance();
2042 self.skip_newlines();
2043 }
2044 }
2045 self.consume(&TokenKind::Gt, ">")?;
2046 Ok(params)
2047 }
2048
2049 fn parse_where_clauses(&mut self) -> Result<Vec<WhereClause>, ParserError> {
2052 if let Some(tok) = self.current() {
2054 if let TokenKind::Identifier(ref id) = tok.kind {
2055 if id == "where" {
2056 self.advance(); let mut clauses = Vec::new();
2058 loop {
2059 self.skip_newlines();
2060 if self.check(&TokenKind::LBrace) || self.is_at_end() {
2062 break;
2063 }
2064 let type_name = self.consume_identifier("type parameter name")?;
2065 self.consume(&TokenKind::Colon, ":")?;
2066 let bound = self.consume_identifier("type bound")?;
2067 clauses.push(WhereClause { type_name, bound });
2068 if self.check(&TokenKind::Comma) {
2069 self.advance();
2070 } else {
2071 break;
2072 }
2073 }
2074 return Ok(clauses);
2075 }
2076 }
2077 }
2078 Ok(Vec::new())
2079 }
2080
2081 fn try_parse_type_annotation(&mut self) -> Result<Option<TypeExpr>, ParserError> {
2084 if !self.check(&TokenKind::Colon) {
2085 return Ok(None);
2086 }
2087 self.advance(); Ok(Some(self.parse_type_expr()?))
2089 }
2090
2091 fn parse_type_expr(&mut self) -> Result<TypeExpr, ParserError> {
2093 self.skip_newlines();
2094 let first = self.parse_type_primary()?;
2095
2096 if self.check(&TokenKind::Bar) {
2098 let mut types = vec![first];
2099 while self.check(&TokenKind::Bar) {
2100 self.advance(); types.push(self.parse_type_primary()?);
2102 }
2103 return Ok(TypeExpr::Union(types));
2104 }
2105
2106 Ok(first)
2107 }
2108
2109 fn parse_type_primary(&mut self) -> Result<TypeExpr, ParserError> {
2112 self.skip_newlines();
2113 if self.check(&TokenKind::LBrace) {
2114 return self.parse_shape_type();
2115 }
2116 if let Some(tok) = self.current() {
2118 let type_name = match &tok.kind {
2119 TokenKind::Nil => {
2120 self.advance();
2121 return Ok(TypeExpr::Named("nil".to_string()));
2122 }
2123 TokenKind::True | TokenKind::False => {
2124 self.advance();
2125 return Ok(TypeExpr::Named("bool".to_string()));
2126 }
2127 _ => None,
2128 };
2129 if let Some(name) = type_name {
2130 return Ok(TypeExpr::Named(name));
2131 }
2132 }
2133 if self.check(&TokenKind::Fn) {
2135 self.advance(); self.consume(&TokenKind::LParen, "(")?;
2137 let mut params = Vec::new();
2138 self.skip_newlines();
2139 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
2140 params.push(self.parse_type_expr()?);
2141 self.skip_newlines();
2142 if self.check(&TokenKind::Comma) {
2143 self.advance();
2144 self.skip_newlines();
2145 }
2146 }
2147 self.consume(&TokenKind::RParen, ")")?;
2148 self.consume(&TokenKind::Arrow, "->")?;
2149 let return_type = self.parse_type_expr()?;
2150 return Ok(TypeExpr::FnType {
2151 params,
2152 return_type: Box::new(return_type),
2153 });
2154 }
2155 let name = self.consume_identifier("type name")?;
2156 if self.check(&TokenKind::Lt) {
2158 self.advance(); let first_param = self.parse_type_expr()?;
2160 if name == "list" {
2161 self.consume(&TokenKind::Gt, ">")?;
2162 return Ok(TypeExpr::List(Box::new(first_param)));
2163 } else if name == "dict" {
2164 self.consume(&TokenKind::Comma, ",")?;
2165 let second_param = self.parse_type_expr()?;
2166 self.consume(&TokenKind::Gt, ">")?;
2167 return Ok(TypeExpr::DictType(
2168 Box::new(first_param),
2169 Box::new(second_param),
2170 ));
2171 }
2172 self.consume(&TokenKind::Gt, ">")?;
2174 }
2175 Ok(TypeExpr::Named(name))
2176 }
2177
2178 fn parse_shape_type(&mut self) -> Result<TypeExpr, ParserError> {
2180 self.consume(&TokenKind::LBrace, "{")?;
2181 let mut fields = Vec::new();
2182 self.skip_newlines();
2183
2184 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
2185 let name = self.consume_identifier("field name")?;
2186 let optional = if self.check(&TokenKind::Question) {
2187 self.advance();
2188 true
2189 } else {
2190 false
2191 };
2192 self.consume(&TokenKind::Colon, ":")?;
2193 let type_expr = self.parse_type_expr()?;
2194 fields.push(ShapeField {
2195 name,
2196 type_expr,
2197 optional,
2198 });
2199 self.skip_newlines();
2200 if self.check(&TokenKind::Comma) {
2201 self.advance();
2202 self.skip_newlines();
2203 }
2204 }
2205
2206 self.consume(&TokenKind::RBrace, "}")?;
2207 Ok(TypeExpr::Shape(fields))
2208 }
2209
2210 fn parse_arg_list(&mut self) -> Result<Vec<SNode>, ParserError> {
2211 let mut args = Vec::new();
2212 self.skip_newlines();
2213
2214 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
2215 if self.check(&TokenKind::Dot) {
2217 let saved_pos = self.pos;
2218 self.advance(); if self.check(&TokenKind::Dot) {
2220 self.advance(); self.consume(&TokenKind::Dot, ".")?; let spread_start = self.tokens[saved_pos].span;
2223 let expr = self.parse_expression()?;
2224 args.push(spanned(
2225 Node::Spread(Box::new(expr)),
2226 Span::merge(spread_start, self.prev_span()),
2227 ));
2228 } else {
2229 self.pos = saved_pos;
2231 args.push(self.parse_expression()?);
2232 }
2233 } else {
2234 args.push(self.parse_expression()?);
2235 }
2236 self.skip_newlines();
2237 if self.check(&TokenKind::Comma) {
2238 self.advance();
2239 self.skip_newlines();
2240 }
2241 }
2242 Ok(args)
2243 }
2244
2245 fn is_at_end(&self) -> bool {
2246 self.pos >= self.tokens.len()
2247 || matches!(self.tokens.get(self.pos), Some(t) if t.kind == TokenKind::Eof)
2248 }
2249
2250 fn current(&self) -> Option<&Token> {
2251 self.tokens.get(self.pos)
2252 }
2253
2254 fn peek_kind(&self) -> Option<&TokenKind> {
2255 self.tokens.get(self.pos + 1).map(|t| &t.kind)
2256 }
2257
2258 fn check(&self, kind: &TokenKind) -> bool {
2259 self.current()
2260 .map(|t| std::mem::discriminant(&t.kind) == std::mem::discriminant(kind))
2261 .unwrap_or(false)
2262 }
2263
2264 fn check_skip_newlines(&mut self, kind: &TokenKind) -> bool {
2267 let saved = self.pos;
2268 self.skip_newlines();
2269 if self.check(kind) {
2270 true
2271 } else {
2272 self.pos = saved;
2273 false
2274 }
2275 }
2276
2277 fn check_identifier(&self, name: &str) -> bool {
2279 matches!(self.current().map(|t| &t.kind), Some(TokenKind::Identifier(s)) if s == name)
2280 }
2281
2282 fn advance(&mut self) {
2283 if self.pos < self.tokens.len() {
2284 self.pos += 1;
2285 }
2286 }
2287
2288 fn consume(&mut self, kind: &TokenKind, expected: &str) -> Result<Token, ParserError> {
2289 self.skip_newlines();
2290 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
2291 if std::mem::discriminant(&tok.kind) != std::mem::discriminant(kind) {
2292 return Err(self.make_error(expected));
2293 }
2294 let tok = tok.clone();
2295 self.advance();
2296 Ok(tok)
2297 }
2298
2299 fn consume_identifier(&mut self, expected: &str) -> Result<String, ParserError> {
2300 self.skip_newlines();
2301 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
2302 if let TokenKind::Identifier(name) = &tok.kind {
2303 let name = name.clone();
2304 self.advance();
2305 Ok(name)
2306 } else {
2307 Err(self.make_error(expected))
2308 }
2309 }
2310
2311 fn consume_identifier_or_keyword(&mut self, expected: &str) -> Result<String, ParserError> {
2315 self.skip_newlines();
2316 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
2317 if let TokenKind::Identifier(name) = &tok.kind {
2318 let name = name.clone();
2319 self.advance();
2320 return Ok(name);
2321 }
2322 let name = match &tok.kind {
2324 TokenKind::Pipeline => "pipeline",
2325 TokenKind::Extends => "extends",
2326 TokenKind::Override => "override",
2327 TokenKind::Let => "let",
2328 TokenKind::Var => "var",
2329 TokenKind::If => "if",
2330 TokenKind::Else => "else",
2331 TokenKind::For => "for",
2332 TokenKind::In => "in",
2333 TokenKind::Match => "match",
2334 TokenKind::Retry => "retry",
2335 TokenKind::Parallel => "parallel",
2336 TokenKind::ParallelMap => "parallel_map",
2337 TokenKind::ParallelSettle => "parallel_settle",
2338 TokenKind::Return => "return",
2339 TokenKind::Import => "import",
2340 TokenKind::True => "true",
2341 TokenKind::False => "false",
2342 TokenKind::Nil => "nil",
2343 TokenKind::Try => "try",
2344 TokenKind::Catch => "catch",
2345 TokenKind::Throw => "throw",
2346 TokenKind::Fn => "fn",
2347 TokenKind::Spawn => "spawn",
2348 TokenKind::While => "while",
2349 TokenKind::TypeKw => "type",
2350 TokenKind::Enum => "enum",
2351 TokenKind::Struct => "struct",
2352 TokenKind::Interface => "interface",
2353 TokenKind::Pub => "pub",
2354 TokenKind::From => "from",
2355 TokenKind::Thru => "thru",
2356 TokenKind::Upto => "upto",
2357 TokenKind::Guard => "guard",
2358 TokenKind::Ask => "ask",
2359 TokenKind::Deadline => "deadline",
2360 TokenKind::Yield => "yield",
2361 TokenKind::Mutex => "mutex",
2362 TokenKind::Break => "break",
2363 TokenKind::Continue => "continue",
2364 TokenKind::Impl => "impl",
2365 _ => return Err(self.make_error(expected)),
2366 };
2367 let name = name.to_string();
2368 self.advance();
2369 Ok(name)
2370 }
2371
2372 fn skip_newlines(&mut self) {
2373 while self.pos < self.tokens.len() && self.tokens[self.pos].kind == TokenKind::Newline {
2374 self.pos += 1;
2375 }
2376 }
2377
2378 fn make_error(&self, expected: &str) -> ParserError {
2379 if let Some(tok) = self.tokens.get(self.pos) {
2380 if tok.kind == TokenKind::Eof {
2381 return ParserError::UnexpectedEof {
2382 expected: expected.into(),
2383 };
2384 }
2385 ParserError::Unexpected {
2386 got: tok.kind.to_string(),
2387 expected: expected.into(),
2388 span: tok.span,
2389 }
2390 } else {
2391 ParserError::UnexpectedEof {
2392 expected: expected.into(),
2393 }
2394 }
2395 }
2396
2397 fn error(&self, expected: &str) -> ParserError {
2398 self.make_error(expected)
2399 }
2400}