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