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