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