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();
681 let name = self.consume_identifier("error variable")?;
682 let ty = self.try_parse_type_annotation()?;
683 self.consume(&TokenKind::RParen, ")")?;
684 (Some(name), ty)
685 } else {
686 (None, None)
687 };
688 self.consume(&TokenKind::LBrace, "{")?;
689 let cb = self.parse_block()?;
690 self.consume(&TokenKind::RBrace, "}")?;
691 (ev, et, cb)
692 } else {
693 (None, None, Vec::new())
694 };
695
696 self.skip_newlines();
697
698 let finally_body = if self.check(&TokenKind::Finally) {
700 self.advance();
701 self.consume(&TokenKind::LBrace, "{")?;
702 let fb = self.parse_block()?;
703 self.consume(&TokenKind::RBrace, "}")?;
704 Some(fb)
705 } else {
706 None
707 };
708
709 if !has_catch && finally_body.is_none() {
711 return Err(self.error("catch or finally block after try"));
712 }
713
714 Ok(spanned(
715 Node::TryCatch {
716 body,
717 error_var,
718 error_type,
719 catch_body,
720 finally_body,
721 },
722 Span::merge(start, self.prev_span()),
723 ))
724 }
725
726 fn parse_select(&mut self) -> Result<SNode, ParserError> {
727 let start = self.current_span();
728 self.consume(&TokenKind::Select, "select")?;
729 self.consume(&TokenKind::LBrace, "{")?;
730 self.skip_newlines();
731
732 let mut cases = Vec::new();
733 let mut timeout = None;
734 let mut default_body = None;
735
736 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
737 self.skip_newlines();
738 if let Some(tok) = self.current() {
740 if let TokenKind::Identifier(ref id) = tok.kind {
741 if id == "timeout" {
742 self.advance();
743 let duration = self.parse_expression()?;
744 self.consume(&TokenKind::LBrace, "{")?;
745 let body = self.parse_block()?;
746 self.consume(&TokenKind::RBrace, "}")?;
747 timeout = Some((Box::new(duration), body));
748 self.skip_newlines();
749 continue;
750 }
751 if id == "default" {
752 self.advance();
753 self.consume(&TokenKind::LBrace, "{")?;
754 let body = self.parse_block()?;
755 self.consume(&TokenKind::RBrace, "}")?;
756 default_body = Some(body);
757 self.skip_newlines();
758 continue;
759 }
760 }
761 }
762 let variable = self.consume_identifier("select case variable")?;
764 self.consume(&TokenKind::From, "from")?;
765 let channel = self.parse_expression()?;
766 self.consume(&TokenKind::LBrace, "{")?;
767 let body = self.parse_block()?;
768 self.consume(&TokenKind::RBrace, "}")?;
769 cases.push(SelectCase {
770 variable,
771 channel: Box::new(channel),
772 body,
773 });
774 self.skip_newlines();
775 }
776
777 self.consume(&TokenKind::RBrace, "}")?;
778
779 if cases.is_empty() && timeout.is_none() && default_body.is_none() {
780 return Err(self.error("at least one select case"));
781 }
782 if timeout.is_some() && default_body.is_some() {
783 return Err(self.error("select cannot have both timeout and default"));
784 }
785
786 Ok(spanned(
787 Node::SelectExpr {
788 cases,
789 timeout,
790 default_body,
791 },
792 Span::merge(start, self.prev_span()),
793 ))
794 }
795
796 fn parse_fn_decl_with_pub(&mut self, is_pub: bool) -> Result<SNode, ParserError> {
797 let start = self.current_span();
798 self.consume(&TokenKind::Fn, "fn")?;
799 let name = self.consume_identifier("function name")?;
800
801 let type_params = if self.check(&TokenKind::Lt) {
803 self.advance(); self.parse_type_param_list()?
805 } else {
806 Vec::new()
807 };
808
809 self.consume(&TokenKind::LParen, "(")?;
810 let params = self.parse_typed_param_list()?;
811 self.consume(&TokenKind::RParen, ")")?;
812 let return_type = if self.check(&TokenKind::Arrow) {
814 self.advance();
815 Some(self.parse_type_expr()?)
816 } else {
817 None
818 };
819
820 let where_clauses = self.parse_where_clauses()?;
822
823 self.consume(&TokenKind::LBrace, "{")?;
824 let body = self.parse_block()?;
825 self.consume(&TokenKind::RBrace, "}")?;
826 Ok(spanned(
827 Node::FnDecl {
828 name,
829 type_params,
830 params,
831 return_type,
832 where_clauses,
833 body,
834 is_pub,
835 },
836 Span::merge(start, self.prev_span()),
837 ))
838 }
839
840 fn parse_type_decl(&mut self) -> Result<SNode, ParserError> {
841 let start = self.current_span();
842 self.consume(&TokenKind::TypeKw, "type")?;
843 let name = self.consume_identifier("type name")?;
844 self.consume(&TokenKind::Assign, "=")?;
845 let type_expr = self.parse_type_expr()?;
846 Ok(spanned(
847 Node::TypeDecl { name, type_expr },
848 Span::merge(start, self.prev_span()),
849 ))
850 }
851
852 fn parse_enum_decl(&mut self) -> Result<SNode, ParserError> {
853 let start = self.current_span();
854 self.consume(&TokenKind::Enum, "enum")?;
855 let name = self.consume_identifier("enum name")?;
856 self.consume(&TokenKind::LBrace, "{")?;
857 self.skip_newlines();
858
859 let mut variants = Vec::new();
860 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
861 let variant_name = self.consume_identifier("variant name")?;
862 let fields = if self.check(&TokenKind::LParen) {
863 self.advance();
864 let params = self.parse_typed_param_list()?;
865 self.consume(&TokenKind::RParen, ")")?;
866 params
867 } else {
868 Vec::new()
869 };
870 variants.push(EnumVariant {
871 name: variant_name,
872 fields,
873 });
874 self.skip_newlines();
875 if self.check(&TokenKind::Comma) {
876 self.advance();
877 self.skip_newlines();
878 }
879 }
880
881 self.consume(&TokenKind::RBrace, "}")?;
882 Ok(spanned(
883 Node::EnumDecl { name, variants },
884 Span::merge(start, self.prev_span()),
885 ))
886 }
887
888 fn parse_struct_decl(&mut self) -> Result<SNode, ParserError> {
889 let start = self.current_span();
890 self.consume(&TokenKind::Struct, "struct")?;
891 let name = self.consume_identifier("struct name")?;
892 self.consume(&TokenKind::LBrace, "{")?;
893 self.skip_newlines();
894
895 let mut fields = Vec::new();
896 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
897 let field_name = self.consume_identifier("field name")?;
898 let optional = if self.check(&TokenKind::Question) {
899 self.advance();
900 true
901 } else {
902 false
903 };
904 let type_expr = self.try_parse_type_annotation()?;
905 fields.push(StructField {
906 name: field_name,
907 type_expr,
908 optional,
909 });
910 self.skip_newlines();
911 if self.check(&TokenKind::Comma) {
912 self.advance();
913 self.skip_newlines();
914 }
915 }
916
917 self.consume(&TokenKind::RBrace, "}")?;
918 Ok(spanned(
919 Node::StructDecl { name, fields },
920 Span::merge(start, self.prev_span()),
921 ))
922 }
923
924 fn parse_interface_decl(&mut self) -> Result<SNode, ParserError> {
925 let start = self.current_span();
926 self.consume(&TokenKind::Interface, "interface")?;
927 let name = self.consume_identifier("interface name")?;
928 self.consume(&TokenKind::LBrace, "{")?;
929 self.skip_newlines();
930
931 let mut methods = Vec::new();
932 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
933 self.consume(&TokenKind::Fn, "fn")?;
934 let method_name = self.consume_identifier("method name")?;
935 self.consume(&TokenKind::LParen, "(")?;
936 let params = self.parse_typed_param_list()?;
937 self.consume(&TokenKind::RParen, ")")?;
938 let return_type = if self.check(&TokenKind::Arrow) {
940 self.advance();
941 Some(self.parse_type_expr()?)
942 } else {
943 None
944 };
945 methods.push(InterfaceMethod {
946 name: method_name,
947 params,
948 return_type,
949 });
950 self.skip_newlines();
951 }
952
953 self.consume(&TokenKind::RBrace, "}")?;
954 Ok(spanned(
955 Node::InterfaceDecl { name, methods },
956 Span::merge(start, self.prev_span()),
957 ))
958 }
959
960 fn parse_impl_block(&mut self) -> Result<SNode, ParserError> {
961 let start = self.current_span();
962 self.consume(&TokenKind::Impl, "impl")?;
963 let type_name = self.consume_identifier("type name")?;
964 self.consume(&TokenKind::LBrace, "{")?;
965 self.skip_newlines();
966
967 let mut methods = Vec::new();
968 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
969 let is_pub = self.check(&TokenKind::Pub);
970 if is_pub {
971 self.advance();
972 }
973 let method = self.parse_fn_decl_with_pub(is_pub)?;
974 methods.push(method);
975 self.skip_newlines();
976 }
977
978 self.consume(&TokenKind::RBrace, "}")?;
979 Ok(spanned(
980 Node::ImplBlock { type_name, methods },
981 Span::merge(start, self.prev_span()),
982 ))
983 }
984
985 fn parse_guard(&mut self) -> Result<SNode, ParserError> {
986 let start = self.current_span();
987 self.consume(&TokenKind::Guard, "guard")?;
988 let condition = self.parse_expression()?;
989 self.consume(&TokenKind::Else, "else")?;
991 self.consume(&TokenKind::LBrace, "{")?;
992 let else_body = self.parse_block()?;
993 self.consume(&TokenKind::RBrace, "}")?;
994 Ok(spanned(
995 Node::GuardStmt {
996 condition: Box::new(condition),
997 else_body,
998 },
999 Span::merge(start, self.prev_span()),
1000 ))
1001 }
1002
1003 fn parse_deadline(&mut self) -> Result<SNode, ParserError> {
1004 let start = self.current_span();
1005 self.consume(&TokenKind::Deadline, "deadline")?;
1006 let duration = self.parse_primary()?;
1007 self.consume(&TokenKind::LBrace, "{")?;
1008 let body = self.parse_block()?;
1009 self.consume(&TokenKind::RBrace, "}")?;
1010 Ok(spanned(
1011 Node::DeadlineBlock {
1012 duration: Box::new(duration),
1013 body,
1014 },
1015 Span::merge(start, self.prev_span()),
1016 ))
1017 }
1018
1019 fn parse_yield(&mut self) -> Result<SNode, ParserError> {
1020 let start = self.current_span();
1021 self.consume(&TokenKind::Yield, "yield")?;
1022 if self.is_at_end() || self.check(&TokenKind::Newline) || self.check(&TokenKind::RBrace) {
1023 return Ok(spanned(
1024 Node::YieldExpr { value: None },
1025 Span::merge(start, self.prev_span()),
1026 ));
1027 }
1028 let value = self.parse_expression()?;
1029 Ok(spanned(
1030 Node::YieldExpr {
1031 value: Some(Box::new(value)),
1032 },
1033 Span::merge(start, self.prev_span()),
1034 ))
1035 }
1036
1037 fn parse_mutex(&mut self) -> Result<SNode, ParserError> {
1038 let start = self.current_span();
1039 self.consume(&TokenKind::Mutex, "mutex")?;
1040 self.consume(&TokenKind::LBrace, "{")?;
1041 let body = self.parse_block()?;
1042 self.consume(&TokenKind::RBrace, "}")?;
1043 Ok(spanned(
1044 Node::MutexBlock { body },
1045 Span::merge(start, self.prev_span()),
1046 ))
1047 }
1048
1049 fn parse_ask_expr(&mut self) -> Result<SNode, ParserError> {
1050 let start = self.current_span();
1051 self.consume(&TokenKind::Ask, "ask")?;
1052 self.consume(&TokenKind::LBrace, "{")?;
1053 let mut entries = Vec::new();
1055 self.skip_newlines();
1056 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1057 let key_span = self.current_span();
1058 let name = self.consume_identifier("ask field")?;
1059 let key = spanned(Node::StringLiteral(name), key_span);
1060 self.consume(&TokenKind::Colon, ":")?;
1061 let value = self.parse_expression()?;
1062 entries.push(DictEntry { key, value });
1063 self.skip_newlines();
1064 if self.check(&TokenKind::Comma) {
1065 self.advance();
1066 self.skip_newlines();
1067 }
1068 }
1069 self.consume(&TokenKind::RBrace, "}")?;
1070 Ok(spanned(
1071 Node::AskExpr { fields: entries },
1072 Span::merge(start, self.prev_span()),
1073 ))
1074 }
1075
1076 fn parse_expression_statement(&mut self) -> Result<SNode, ParserError> {
1079 let start = self.current_span();
1080 let expr = self.parse_expression()?;
1081
1082 let is_assignable = matches!(
1085 expr.node,
1086 Node::Identifier(_) | Node::PropertyAccess { .. } | Node::SubscriptAccess { .. }
1087 );
1088 if is_assignable {
1089 if self.check(&TokenKind::Assign) {
1090 self.advance();
1091 let value = self.parse_expression()?;
1092 return Ok(spanned(
1093 Node::Assignment {
1094 target: Box::new(expr),
1095 value: Box::new(value),
1096 op: None,
1097 },
1098 Span::merge(start, self.prev_span()),
1099 ));
1100 }
1101 let compound_op = if self.check(&TokenKind::PlusAssign) {
1102 Some("+")
1103 } else if self.check(&TokenKind::MinusAssign) {
1104 Some("-")
1105 } else if self.check(&TokenKind::StarAssign) {
1106 Some("*")
1107 } else if self.check(&TokenKind::SlashAssign) {
1108 Some("/")
1109 } else if self.check(&TokenKind::PercentAssign) {
1110 Some("%")
1111 } else {
1112 None
1113 };
1114 if let Some(op) = compound_op {
1115 self.advance();
1116 let value = self.parse_expression()?;
1117 return Ok(spanned(
1118 Node::Assignment {
1119 target: Box::new(expr),
1120 value: Box::new(value),
1121 op: Some(op.into()),
1122 },
1123 Span::merge(start, self.prev_span()),
1124 ));
1125 }
1126 }
1127
1128 Ok(expr)
1129 }
1130
1131 fn parse_expression(&mut self) -> Result<SNode, ParserError> {
1132 self.skip_newlines();
1133 self.parse_pipe()
1134 }
1135
1136 fn parse_pipe(&mut self) -> Result<SNode, ParserError> {
1137 let mut left = self.parse_range()?;
1138 while self.check_skip_newlines(&TokenKind::Pipe) {
1139 let start = left.span;
1140 self.advance();
1141 let right = self.parse_range()?;
1142 left = spanned(
1143 Node::BinaryOp {
1144 op: "|>".into(),
1145 left: Box::new(left),
1146 right: Box::new(right),
1147 },
1148 Span::merge(start, self.prev_span()),
1149 );
1150 }
1151 Ok(left)
1152 }
1153
1154 fn parse_range(&mut self) -> Result<SNode, ParserError> {
1155 let left = self.parse_ternary()?;
1156 if self.check(&TokenKind::Thru) {
1157 let start = left.span;
1158 self.advance();
1159 let right = self.parse_ternary()?;
1160 return Ok(spanned(
1161 Node::RangeExpr {
1162 start: Box::new(left),
1163 end: Box::new(right),
1164 inclusive: true,
1165 },
1166 Span::merge(start, self.prev_span()),
1167 ));
1168 }
1169 if self.check(&TokenKind::Upto) {
1170 let start = left.span;
1171 self.advance();
1172 let right = self.parse_ternary()?;
1173 return Ok(spanned(
1174 Node::RangeExpr {
1175 start: Box::new(left),
1176 end: Box::new(right),
1177 inclusive: false,
1178 },
1179 Span::merge(start, self.prev_span()),
1180 ));
1181 }
1182 Ok(left)
1183 }
1184
1185 fn parse_ternary(&mut self) -> Result<SNode, ParserError> {
1186 let condition = self.parse_nil_coalescing()?;
1187 if !self.check(&TokenKind::Question) {
1188 return Ok(condition);
1189 }
1190 let start = condition.span;
1191 self.advance(); let true_val = self.parse_nil_coalescing()?;
1193 self.consume(&TokenKind::Colon, ":")?;
1194 let false_val = self.parse_nil_coalescing()?;
1195 Ok(spanned(
1196 Node::Ternary {
1197 condition: Box::new(condition),
1198 true_expr: Box::new(true_val),
1199 false_expr: Box::new(false_val),
1200 },
1201 Span::merge(start, self.prev_span()),
1202 ))
1203 }
1204
1205 fn parse_nil_coalescing(&mut self) -> Result<SNode, ParserError> {
1206 let mut left = self.parse_logical_or()?;
1207 while self.check(&TokenKind::NilCoal) {
1208 let start = left.span;
1209 self.advance();
1210 let right = self.parse_logical_or()?;
1211 left = spanned(
1212 Node::BinaryOp {
1213 op: "??".into(),
1214 left: Box::new(left),
1215 right: Box::new(right),
1216 },
1217 Span::merge(start, self.prev_span()),
1218 );
1219 }
1220 Ok(left)
1221 }
1222
1223 fn parse_logical_or(&mut self) -> Result<SNode, ParserError> {
1224 let mut left = self.parse_logical_and()?;
1225 while self.check_skip_newlines(&TokenKind::Or) {
1226 let start = left.span;
1227 self.advance();
1228 let right = self.parse_logical_and()?;
1229 left = spanned(
1230 Node::BinaryOp {
1231 op: "||".into(),
1232 left: Box::new(left),
1233 right: Box::new(right),
1234 },
1235 Span::merge(start, self.prev_span()),
1236 );
1237 }
1238 Ok(left)
1239 }
1240
1241 fn parse_logical_and(&mut self) -> Result<SNode, ParserError> {
1242 let mut left = self.parse_equality()?;
1243 while self.check_skip_newlines(&TokenKind::And) {
1244 let start = left.span;
1245 self.advance();
1246 let right = self.parse_equality()?;
1247 left = spanned(
1248 Node::BinaryOp {
1249 op: "&&".into(),
1250 left: Box::new(left),
1251 right: Box::new(right),
1252 },
1253 Span::merge(start, self.prev_span()),
1254 );
1255 }
1256 Ok(left)
1257 }
1258
1259 fn parse_equality(&mut self) -> Result<SNode, ParserError> {
1260 let mut left = self.parse_comparison()?;
1261 while self.check(&TokenKind::Eq) || self.check(&TokenKind::Neq) {
1262 let start = left.span;
1263 let op = if self.check(&TokenKind::Eq) {
1264 "=="
1265 } else {
1266 "!="
1267 };
1268 self.advance();
1269 let right = self.parse_comparison()?;
1270 left = spanned(
1271 Node::BinaryOp {
1272 op: op.into(),
1273 left: Box::new(left),
1274 right: Box::new(right),
1275 },
1276 Span::merge(start, self.prev_span()),
1277 );
1278 }
1279 Ok(left)
1280 }
1281
1282 fn parse_comparison(&mut self) -> Result<SNode, ParserError> {
1283 let mut left = self.parse_additive()?;
1284 while self.check(&TokenKind::Lt)
1285 || self.check(&TokenKind::Gt)
1286 || self.check(&TokenKind::Lte)
1287 || self.check(&TokenKind::Gte)
1288 {
1289 let start = left.span;
1290 let op = match self.current().map(|t| &t.kind) {
1291 Some(TokenKind::Lt) => "<",
1292 Some(TokenKind::Gt) => ">",
1293 Some(TokenKind::Lte) => "<=",
1294 Some(TokenKind::Gte) => ">=",
1295 _ => "<",
1296 };
1297 self.advance();
1298 let right = self.parse_additive()?;
1299 left = spanned(
1300 Node::BinaryOp {
1301 op: op.into(),
1302 left: Box::new(left),
1303 right: Box::new(right),
1304 },
1305 Span::merge(start, self.prev_span()),
1306 );
1307 }
1308 Ok(left)
1309 }
1310
1311 fn parse_additive(&mut self) -> Result<SNode, ParserError> {
1312 let mut left = self.parse_multiplicative()?;
1313 while self.check_skip_newlines(&TokenKind::Plus) || self.check(&TokenKind::Minus) {
1314 let start = left.span;
1315 let op = if self.check(&TokenKind::Plus) {
1316 "+"
1317 } else {
1318 "-"
1319 };
1320 self.advance();
1321 let right = self.parse_multiplicative()?;
1322 left = spanned(
1323 Node::BinaryOp {
1324 op: op.into(),
1325 left: Box::new(left),
1326 right: Box::new(right),
1327 },
1328 Span::merge(start, self.prev_span()),
1329 );
1330 }
1331 Ok(left)
1332 }
1333
1334 fn parse_multiplicative(&mut self) -> Result<SNode, ParserError> {
1335 let mut left = self.parse_unary()?;
1336 while self.check_skip_newlines(&TokenKind::Star)
1337 || self.check_skip_newlines(&TokenKind::Slash)
1338 || self.check_skip_newlines(&TokenKind::Percent)
1339 {
1340 let start = left.span;
1341 let op = if self.check(&TokenKind::Star) {
1342 "*"
1343 } else if self.check(&TokenKind::Slash) {
1344 "/"
1345 } else {
1346 "%"
1347 };
1348 self.advance();
1349 let right = self.parse_unary()?;
1350 left = spanned(
1351 Node::BinaryOp {
1352 op: op.into(),
1353 left: Box::new(left),
1354 right: Box::new(right),
1355 },
1356 Span::merge(start, self.prev_span()),
1357 );
1358 }
1359 Ok(left)
1360 }
1361
1362 fn parse_unary(&mut self) -> Result<SNode, ParserError> {
1363 if self.check(&TokenKind::Not) {
1364 let start = self.current_span();
1365 self.advance();
1366 let operand = self.parse_unary()?;
1367 return Ok(spanned(
1368 Node::UnaryOp {
1369 op: "!".into(),
1370 operand: Box::new(operand),
1371 },
1372 Span::merge(start, self.prev_span()),
1373 ));
1374 }
1375 if self.check(&TokenKind::Minus) {
1376 let start = self.current_span();
1377 self.advance();
1378 let operand = self.parse_unary()?;
1379 return Ok(spanned(
1380 Node::UnaryOp {
1381 op: "-".into(),
1382 operand: Box::new(operand),
1383 },
1384 Span::merge(start, self.prev_span()),
1385 ));
1386 }
1387 self.parse_postfix()
1388 }
1389
1390 fn parse_postfix(&mut self) -> Result<SNode, ParserError> {
1391 let mut expr = self.parse_primary()?;
1392
1393 loop {
1394 if self.check_skip_newlines(&TokenKind::Dot)
1395 || self.check_skip_newlines(&TokenKind::QuestionDot)
1396 {
1397 let optional = self.check(&TokenKind::QuestionDot);
1398 let start = expr.span;
1399 self.advance();
1400 let member = self.consume_identifier_or_keyword("member name")?;
1401 if self.check(&TokenKind::LParen) {
1402 self.advance();
1403 let args = self.parse_arg_list()?;
1404 self.consume(&TokenKind::RParen, ")")?;
1405 if optional {
1406 expr = spanned(
1407 Node::OptionalMethodCall {
1408 object: Box::new(expr),
1409 method: member,
1410 args,
1411 },
1412 Span::merge(start, self.prev_span()),
1413 );
1414 } else {
1415 expr = spanned(
1416 Node::MethodCall {
1417 object: Box::new(expr),
1418 method: member,
1419 args,
1420 },
1421 Span::merge(start, self.prev_span()),
1422 );
1423 }
1424 } else if optional {
1425 expr = spanned(
1426 Node::OptionalPropertyAccess {
1427 object: Box::new(expr),
1428 property: member,
1429 },
1430 Span::merge(start, self.prev_span()),
1431 );
1432 } else {
1433 expr = spanned(
1434 Node::PropertyAccess {
1435 object: Box::new(expr),
1436 property: member,
1437 },
1438 Span::merge(start, self.prev_span()),
1439 );
1440 }
1441 } else if self.check(&TokenKind::LBracket) {
1442 let start = expr.span;
1443 self.advance();
1444
1445 if self.check(&TokenKind::Colon) {
1450 self.advance(); let end_expr = if self.check(&TokenKind::RBracket) {
1453 None
1454 } else {
1455 Some(Box::new(self.parse_expression()?))
1456 };
1457 self.consume(&TokenKind::RBracket, "]")?;
1458 expr = spanned(
1459 Node::SliceAccess {
1460 object: Box::new(expr),
1461 start: None,
1462 end: end_expr,
1463 },
1464 Span::merge(start, self.prev_span()),
1465 );
1466 } else {
1467 let index = self.parse_expression()?;
1468 if self.check(&TokenKind::Colon) {
1469 self.advance(); let end_expr = if self.check(&TokenKind::RBracket) {
1472 None
1473 } else {
1474 Some(Box::new(self.parse_expression()?))
1475 };
1476 self.consume(&TokenKind::RBracket, "]")?;
1477 expr = spanned(
1478 Node::SliceAccess {
1479 object: Box::new(expr),
1480 start: Some(Box::new(index)),
1481 end: end_expr,
1482 },
1483 Span::merge(start, self.prev_span()),
1484 );
1485 } else {
1486 self.consume(&TokenKind::RBracket, "]")?;
1487 expr = spanned(
1488 Node::SubscriptAccess {
1489 object: Box::new(expr),
1490 index: Box::new(index),
1491 },
1492 Span::merge(start, self.prev_span()),
1493 );
1494 }
1495 }
1496 } else if self.check(&TokenKind::LParen) && matches!(expr.node, Node::Identifier(_)) {
1497 let start = expr.span;
1498 self.advance();
1499 let args = self.parse_arg_list()?;
1500 self.consume(&TokenKind::RParen, ")")?;
1501 if let Node::Identifier(name) = expr.node {
1502 expr = spanned(
1503 Node::FunctionCall { name, args },
1504 Span::merge(start, self.prev_span()),
1505 );
1506 }
1507 } else if self.check(&TokenKind::Question) {
1508 let next_pos = self.pos + 1;
1511 let is_ternary = self.tokens.get(next_pos).is_some_and(|t| {
1512 matches!(
1513 t.kind,
1514 TokenKind::Identifier(_)
1515 | TokenKind::IntLiteral(_)
1516 | TokenKind::FloatLiteral(_)
1517 | TokenKind::StringLiteral(_)
1518 | TokenKind::InterpolatedString(_)
1519 | TokenKind::True
1520 | TokenKind::False
1521 | TokenKind::Nil
1522 | TokenKind::LParen
1523 | TokenKind::LBracket
1524 | TokenKind::LBrace
1525 | TokenKind::Not
1526 | TokenKind::Minus
1527 | TokenKind::Fn
1528 )
1529 });
1530 if is_ternary {
1531 break;
1532 }
1533 let start = expr.span;
1534 self.advance(); expr = spanned(
1536 Node::TryOperator {
1537 operand: Box::new(expr),
1538 },
1539 Span::merge(start, self.prev_span()),
1540 );
1541 } else {
1542 break;
1543 }
1544 }
1545
1546 Ok(expr)
1547 }
1548
1549 fn parse_primary(&mut self) -> Result<SNode, ParserError> {
1550 let tok = self.current().ok_or_else(|| ParserError::UnexpectedEof {
1551 expected: "expression".into(),
1552 })?;
1553 let start = self.current_span();
1554
1555 match &tok.kind {
1556 TokenKind::StringLiteral(s) => {
1557 let s = s.clone();
1558 self.advance();
1559 Ok(spanned(
1560 Node::StringLiteral(s),
1561 Span::merge(start, self.prev_span()),
1562 ))
1563 }
1564 TokenKind::InterpolatedString(segments) => {
1565 let segments = segments.clone();
1566 self.advance();
1567 Ok(spanned(
1568 Node::InterpolatedString(segments),
1569 Span::merge(start, self.prev_span()),
1570 ))
1571 }
1572 TokenKind::IntLiteral(n) => {
1573 let n = *n;
1574 self.advance();
1575 Ok(spanned(
1576 Node::IntLiteral(n),
1577 Span::merge(start, self.prev_span()),
1578 ))
1579 }
1580 TokenKind::FloatLiteral(n) => {
1581 let n = *n;
1582 self.advance();
1583 Ok(spanned(
1584 Node::FloatLiteral(n),
1585 Span::merge(start, self.prev_span()),
1586 ))
1587 }
1588 TokenKind::True => {
1589 self.advance();
1590 Ok(spanned(
1591 Node::BoolLiteral(true),
1592 Span::merge(start, self.prev_span()),
1593 ))
1594 }
1595 TokenKind::False => {
1596 self.advance();
1597 Ok(spanned(
1598 Node::BoolLiteral(false),
1599 Span::merge(start, self.prev_span()),
1600 ))
1601 }
1602 TokenKind::Nil => {
1603 self.advance();
1604 Ok(spanned(
1605 Node::NilLiteral,
1606 Span::merge(start, self.prev_span()),
1607 ))
1608 }
1609 TokenKind::Identifier(name) => {
1610 let name = name.clone();
1611 self.advance();
1612 Ok(spanned(
1613 Node::Identifier(name),
1614 Span::merge(start, self.prev_span()),
1615 ))
1616 }
1617 TokenKind::LParen => {
1618 self.advance();
1619 let expr = self.parse_expression()?;
1620 self.consume(&TokenKind::RParen, ")")?;
1621 Ok(expr)
1622 }
1623 TokenKind::LBracket => self.parse_list_literal(),
1624 TokenKind::LBrace => self.parse_dict_or_closure(),
1625 TokenKind::Parallel => self.parse_parallel(),
1626 TokenKind::ParallelMap => self.parse_parallel_map(),
1627 TokenKind::Retry => self.parse_retry(),
1628 TokenKind::If => self.parse_if_else(),
1629 TokenKind::Spawn => self.parse_spawn_expr(),
1630 TokenKind::DurationLiteral(ms) => {
1631 let ms = *ms;
1632 self.advance();
1633 Ok(spanned(
1634 Node::DurationLiteral(ms),
1635 Span::merge(start, self.prev_span()),
1636 ))
1637 }
1638 TokenKind::Ask => self.parse_ask_expr(),
1639 TokenKind::Deadline => self.parse_deadline(),
1640 _ => Err(self.error("expression")),
1641 }
1642 }
1643
1644 fn parse_spawn_expr(&mut self) -> Result<SNode, ParserError> {
1645 let start = self.current_span();
1646 self.consume(&TokenKind::Spawn, "spawn")?;
1647 self.consume(&TokenKind::LBrace, "{")?;
1648 let body = self.parse_block()?;
1649 self.consume(&TokenKind::RBrace, "}")?;
1650 Ok(spanned(
1651 Node::SpawnExpr { body },
1652 Span::merge(start, self.prev_span()),
1653 ))
1654 }
1655
1656 fn parse_list_literal(&mut self) -> Result<SNode, ParserError> {
1657 let start = self.current_span();
1658 self.consume(&TokenKind::LBracket, "[")?;
1659 let mut elements = Vec::new();
1660 self.skip_newlines();
1661
1662 while !self.is_at_end() && !self.check(&TokenKind::RBracket) {
1663 if self.check(&TokenKind::Dot) {
1665 let saved_pos = self.pos;
1666 self.advance(); if self.check(&TokenKind::Dot) {
1668 self.advance(); self.consume(&TokenKind::Dot, ".")?; let spread_start = self.tokens[saved_pos].span;
1671 let expr = self.parse_expression()?;
1672 elements.push(spanned(
1673 Node::Spread(Box::new(expr)),
1674 Span::merge(spread_start, self.prev_span()),
1675 ));
1676 } else {
1677 self.pos = saved_pos;
1679 elements.push(self.parse_expression()?);
1680 }
1681 } else {
1682 elements.push(self.parse_expression()?);
1683 }
1684 self.skip_newlines();
1685 if self.check(&TokenKind::Comma) {
1686 self.advance();
1687 self.skip_newlines();
1688 }
1689 }
1690
1691 self.consume(&TokenKind::RBracket, "]")?;
1692 Ok(spanned(
1693 Node::ListLiteral(elements),
1694 Span::merge(start, self.prev_span()),
1695 ))
1696 }
1697
1698 fn parse_dict_or_closure(&mut self) -> Result<SNode, ParserError> {
1699 let start = self.current_span();
1700 self.consume(&TokenKind::LBrace, "{")?;
1701 self.skip_newlines();
1702
1703 if self.check(&TokenKind::RBrace) {
1705 self.advance();
1706 return Ok(spanned(
1707 Node::DictLiteral(Vec::new()),
1708 Span::merge(start, self.prev_span()),
1709 ));
1710 }
1711
1712 let saved = self.pos;
1714 if self.is_closure_lookahead() {
1715 self.pos = saved;
1716 return self.parse_closure_body(start);
1717 }
1718 self.pos = saved;
1719 self.parse_dict_literal(start)
1720 }
1721
1722 fn is_closure_lookahead(&mut self) -> bool {
1725 let mut depth = 0;
1726 while !self.is_at_end() {
1727 if let Some(tok) = self.current() {
1728 match &tok.kind {
1729 TokenKind::Arrow if depth == 0 => return true,
1730 TokenKind::LBrace | TokenKind::LParen | TokenKind::LBracket => depth += 1,
1731 TokenKind::RBrace if depth == 0 => return false,
1732 TokenKind::RBrace => depth -= 1,
1733 TokenKind::RParen | TokenKind::RBracket => {
1734 if depth > 0 {
1735 depth -= 1;
1736 }
1737 }
1738 _ => {}
1739 }
1740 self.advance();
1741 } else {
1742 return false;
1743 }
1744 }
1745 false
1746 }
1747
1748 fn parse_closure_body(&mut self, start: Span) -> Result<SNode, ParserError> {
1750 let params = self.parse_typed_param_list_until_arrow()?;
1751 self.consume(&TokenKind::Arrow, "->")?;
1752 let body = self.parse_block()?;
1753 self.consume(&TokenKind::RBrace, "}")?;
1754 Ok(spanned(
1755 Node::Closure { params, body },
1756 Span::merge(start, self.prev_span()),
1757 ))
1758 }
1759
1760 fn parse_typed_param_list_until_arrow(&mut self) -> Result<Vec<TypedParam>, ParserError> {
1762 self.parse_typed_params_until(|tok| tok == &TokenKind::Arrow)
1763 }
1764
1765 fn parse_dict_literal(&mut self, start: Span) -> Result<SNode, ParserError> {
1766 let mut entries = Vec::new();
1767 self.skip_newlines();
1768
1769 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1770 if self.check(&TokenKind::Dot) {
1772 let saved_pos = self.pos;
1773 self.advance(); if self.check(&TokenKind::Dot) {
1775 self.advance(); if self.check(&TokenKind::Dot) {
1777 self.advance(); let spread_start = self.tokens[saved_pos].span;
1779 let expr = self.parse_expression()?;
1780 entries.push(DictEntry {
1781 key: spanned(Node::NilLiteral, spread_start),
1782 value: spanned(
1783 Node::Spread(Box::new(expr)),
1784 Span::merge(spread_start, self.prev_span()),
1785 ),
1786 });
1787 self.skip_newlines();
1788 if self.check(&TokenKind::Comma) {
1789 self.advance();
1790 self.skip_newlines();
1791 }
1792 continue;
1793 }
1794 self.pos = saved_pos;
1796 } else {
1797 self.pos = saved_pos;
1798 }
1799 }
1800 let key = if self.check(&TokenKind::LBracket) {
1801 self.advance();
1803 let k = self.parse_expression()?;
1804 self.consume(&TokenKind::RBracket, "]")?;
1805 k
1806 } else if matches!(
1807 self.current().map(|t| &t.kind),
1808 Some(TokenKind::StringLiteral(_))
1809 ) {
1810 let key_span = self.current_span();
1812 let name =
1813 if let Some(TokenKind::StringLiteral(s)) = self.current().map(|t| &t.kind) {
1814 s.clone()
1815 } else {
1816 unreachable!()
1817 };
1818 self.advance();
1819 spanned(Node::StringLiteral(name), key_span)
1820 } else {
1821 let key_span = self.current_span();
1823 let name = self.consume_identifier_or_keyword("dict key")?;
1824 spanned(Node::StringLiteral(name), key_span)
1825 };
1826 self.consume(&TokenKind::Colon, ":")?;
1827 let value = self.parse_expression()?;
1828 entries.push(DictEntry { key, value });
1829 self.skip_newlines();
1830 if self.check(&TokenKind::Comma) {
1831 self.advance();
1832 self.skip_newlines();
1833 }
1834 }
1835
1836 self.consume(&TokenKind::RBrace, "}")?;
1837 Ok(spanned(
1838 Node::DictLiteral(entries),
1839 Span::merge(start, self.prev_span()),
1840 ))
1841 }
1842
1843 fn parse_param_list(&mut self) -> Result<Vec<String>, ParserError> {
1847 let mut params = Vec::new();
1848 self.skip_newlines();
1849
1850 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
1851 params.push(self.consume_identifier("parameter name")?);
1852 if self.check(&TokenKind::Comma) {
1853 self.advance();
1854 self.skip_newlines();
1855 }
1856 }
1857 Ok(params)
1858 }
1859
1860 fn parse_typed_param_list(&mut self) -> Result<Vec<TypedParam>, ParserError> {
1862 self.parse_typed_params_until(|tok| tok == &TokenKind::RParen)
1863 }
1864
1865 fn parse_typed_params_until(
1868 &mut self,
1869 is_terminator: impl Fn(&TokenKind) -> bool,
1870 ) -> Result<Vec<TypedParam>, ParserError> {
1871 let mut params = Vec::new();
1872 let mut seen_default = false;
1873 self.skip_newlines();
1874
1875 while !self.is_at_end() {
1876 if let Some(tok) = self.current() {
1877 if is_terminator(&tok.kind) {
1878 break;
1879 }
1880 } else {
1881 break;
1882 }
1883 let name = self.consume_identifier("parameter name")?;
1884 let type_expr = self.try_parse_type_annotation()?;
1885 let default_value = if self.check(&TokenKind::Assign) {
1886 self.advance();
1887 seen_default = true;
1888 Some(Box::new(self.parse_expression()?))
1889 } else {
1890 if seen_default {
1891 return Err(self.error(
1892 "Required parameter cannot follow a parameter with a default value",
1893 ));
1894 }
1895 None
1896 };
1897 params.push(TypedParam {
1898 name,
1899 type_expr,
1900 default_value,
1901 });
1902 if self.check(&TokenKind::Comma) {
1903 self.advance();
1904 self.skip_newlines();
1905 }
1906 }
1907 Ok(params)
1908 }
1909
1910 fn parse_type_param_list(&mut self) -> Result<Vec<TypeParam>, ParserError> {
1912 let mut params = Vec::new();
1913 self.skip_newlines();
1914 while !self.is_at_end() && !self.check(&TokenKind::Gt) {
1915 let name = self.consume_identifier("type parameter name")?;
1916 params.push(TypeParam { name });
1917 if self.check(&TokenKind::Comma) {
1918 self.advance();
1919 self.skip_newlines();
1920 }
1921 }
1922 self.consume(&TokenKind::Gt, ">")?;
1923 Ok(params)
1924 }
1925
1926 fn parse_where_clauses(&mut self) -> Result<Vec<WhereClause>, ParserError> {
1929 if let Some(tok) = self.current() {
1931 if let TokenKind::Identifier(ref id) = tok.kind {
1932 if id == "where" {
1933 self.advance(); let mut clauses = Vec::new();
1935 loop {
1936 self.skip_newlines();
1937 if self.check(&TokenKind::LBrace) || self.is_at_end() {
1939 break;
1940 }
1941 let type_name = self.consume_identifier("type parameter name")?;
1942 self.consume(&TokenKind::Colon, ":")?;
1943 let bound = self.consume_identifier("type bound")?;
1944 clauses.push(WhereClause { type_name, bound });
1945 if self.check(&TokenKind::Comma) {
1946 self.advance();
1947 } else {
1948 break;
1949 }
1950 }
1951 return Ok(clauses);
1952 }
1953 }
1954 }
1955 Ok(Vec::new())
1956 }
1957
1958 fn try_parse_type_annotation(&mut self) -> Result<Option<TypeExpr>, ParserError> {
1961 if !self.check(&TokenKind::Colon) {
1962 return Ok(None);
1963 }
1964 self.advance(); Ok(Some(self.parse_type_expr()?))
1966 }
1967
1968 fn parse_type_expr(&mut self) -> Result<TypeExpr, ParserError> {
1970 self.skip_newlines();
1971 let first = self.parse_type_primary()?;
1972
1973 if self.check(&TokenKind::Bar) {
1975 let mut types = vec![first];
1976 while self.check(&TokenKind::Bar) {
1977 self.advance(); types.push(self.parse_type_primary()?);
1979 }
1980 return Ok(TypeExpr::Union(types));
1981 }
1982
1983 Ok(first)
1984 }
1985
1986 fn parse_type_primary(&mut self) -> Result<TypeExpr, ParserError> {
1989 self.skip_newlines();
1990 if self.check(&TokenKind::LBrace) {
1991 return self.parse_shape_type();
1992 }
1993 if let Some(tok) = self.current() {
1995 let type_name = match &tok.kind {
1996 TokenKind::Nil => {
1997 self.advance();
1998 return Ok(TypeExpr::Named("nil".to_string()));
1999 }
2000 TokenKind::True | TokenKind::False => {
2001 self.advance();
2002 return Ok(TypeExpr::Named("bool".to_string()));
2003 }
2004 _ => None,
2005 };
2006 if let Some(name) = type_name {
2007 return Ok(TypeExpr::Named(name));
2008 }
2009 }
2010 if self.check(&TokenKind::Fn) {
2012 self.advance(); self.consume(&TokenKind::LParen, "(")?;
2014 let mut params = Vec::new();
2015 self.skip_newlines();
2016 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
2017 params.push(self.parse_type_expr()?);
2018 self.skip_newlines();
2019 if self.check(&TokenKind::Comma) {
2020 self.advance();
2021 self.skip_newlines();
2022 }
2023 }
2024 self.consume(&TokenKind::RParen, ")")?;
2025 self.consume(&TokenKind::Arrow, "->")?;
2026 let return_type = self.parse_type_expr()?;
2027 return Ok(TypeExpr::FnType {
2028 params,
2029 return_type: Box::new(return_type),
2030 });
2031 }
2032 let name = self.consume_identifier("type name")?;
2033 if self.check(&TokenKind::Lt) {
2035 self.advance(); let first_param = self.parse_type_expr()?;
2037 if name == "list" {
2038 self.consume(&TokenKind::Gt, ">")?;
2039 return Ok(TypeExpr::List(Box::new(first_param)));
2040 } else if name == "dict" {
2041 self.consume(&TokenKind::Comma, ",")?;
2042 let second_param = self.parse_type_expr()?;
2043 self.consume(&TokenKind::Gt, ">")?;
2044 return Ok(TypeExpr::DictType(
2045 Box::new(first_param),
2046 Box::new(second_param),
2047 ));
2048 }
2049 self.consume(&TokenKind::Gt, ">")?;
2051 }
2052 Ok(TypeExpr::Named(name))
2053 }
2054
2055 fn parse_shape_type(&mut self) -> Result<TypeExpr, ParserError> {
2057 self.consume(&TokenKind::LBrace, "{")?;
2058 let mut fields = Vec::new();
2059 self.skip_newlines();
2060
2061 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
2062 let name = self.consume_identifier("field name")?;
2063 let optional = if self.check(&TokenKind::Question) {
2064 self.advance();
2065 true
2066 } else {
2067 false
2068 };
2069 self.consume(&TokenKind::Colon, ":")?;
2070 let type_expr = self.parse_type_expr()?;
2071 fields.push(ShapeField {
2072 name,
2073 type_expr,
2074 optional,
2075 });
2076 self.skip_newlines();
2077 if self.check(&TokenKind::Comma) {
2078 self.advance();
2079 self.skip_newlines();
2080 }
2081 }
2082
2083 self.consume(&TokenKind::RBrace, "}")?;
2084 Ok(TypeExpr::Shape(fields))
2085 }
2086
2087 fn parse_arg_list(&mut self) -> Result<Vec<SNode>, ParserError> {
2088 let mut args = Vec::new();
2089 self.skip_newlines();
2090
2091 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
2092 args.push(self.parse_expression()?);
2093 self.skip_newlines();
2094 if self.check(&TokenKind::Comma) {
2095 self.advance();
2096 self.skip_newlines();
2097 }
2098 }
2099 Ok(args)
2100 }
2101
2102 fn is_at_end(&self) -> bool {
2103 self.pos >= self.tokens.len()
2104 || matches!(self.tokens.get(self.pos), Some(t) if t.kind == TokenKind::Eof)
2105 }
2106
2107 fn current(&self) -> Option<&Token> {
2108 self.tokens.get(self.pos)
2109 }
2110
2111 fn peek_kind(&self) -> Option<&TokenKind> {
2112 self.tokens.get(self.pos + 1).map(|t| &t.kind)
2113 }
2114
2115 fn check(&self, kind: &TokenKind) -> bool {
2116 self.current()
2117 .map(|t| std::mem::discriminant(&t.kind) == std::mem::discriminant(kind))
2118 .unwrap_or(false)
2119 }
2120
2121 fn check_skip_newlines(&mut self, kind: &TokenKind) -> bool {
2124 let saved = self.pos;
2125 self.skip_newlines();
2126 if self.check(kind) {
2127 true
2128 } else {
2129 self.pos = saved;
2130 false
2131 }
2132 }
2133
2134 fn advance(&mut self) {
2135 if self.pos < self.tokens.len() {
2136 self.pos += 1;
2137 }
2138 }
2139
2140 fn consume(&mut self, kind: &TokenKind, expected: &str) -> Result<Token, ParserError> {
2141 self.skip_newlines();
2142 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
2143 if std::mem::discriminant(&tok.kind) != std::mem::discriminant(kind) {
2144 return Err(self.make_error(expected));
2145 }
2146 let tok = tok.clone();
2147 self.advance();
2148 Ok(tok)
2149 }
2150
2151 fn consume_identifier(&mut self, expected: &str) -> Result<String, ParserError> {
2152 self.skip_newlines();
2153 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
2154 if let TokenKind::Identifier(name) = &tok.kind {
2155 let name = name.clone();
2156 self.advance();
2157 Ok(name)
2158 } else {
2159 Err(self.make_error(expected))
2160 }
2161 }
2162
2163 fn consume_identifier_or_keyword(&mut self, expected: &str) -> Result<String, ParserError> {
2167 self.skip_newlines();
2168 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
2169 if let TokenKind::Identifier(name) = &tok.kind {
2170 let name = name.clone();
2171 self.advance();
2172 return Ok(name);
2173 }
2174 let name = match &tok.kind {
2176 TokenKind::Pipeline => "pipeline",
2177 TokenKind::Extends => "extends",
2178 TokenKind::Override => "override",
2179 TokenKind::Let => "let",
2180 TokenKind::Var => "var",
2181 TokenKind::If => "if",
2182 TokenKind::Else => "else",
2183 TokenKind::For => "for",
2184 TokenKind::In => "in",
2185 TokenKind::Match => "match",
2186 TokenKind::Retry => "retry",
2187 TokenKind::Parallel => "parallel",
2188 TokenKind::ParallelMap => "parallel_map",
2189 TokenKind::Return => "return",
2190 TokenKind::Import => "import",
2191 TokenKind::True => "true",
2192 TokenKind::False => "false",
2193 TokenKind::Nil => "nil",
2194 TokenKind::Try => "try",
2195 TokenKind::Catch => "catch",
2196 TokenKind::Throw => "throw",
2197 TokenKind::Fn => "fn",
2198 TokenKind::Spawn => "spawn",
2199 TokenKind::While => "while",
2200 TokenKind::TypeKw => "type",
2201 TokenKind::Enum => "enum",
2202 TokenKind::Struct => "struct",
2203 TokenKind::Interface => "interface",
2204 TokenKind::Pub => "pub",
2205 TokenKind::From => "from",
2206 TokenKind::Thru => "thru",
2207 TokenKind::Upto => "upto",
2208 TokenKind::Guard => "guard",
2209 TokenKind::Ask => "ask",
2210 TokenKind::Deadline => "deadline",
2211 TokenKind::Yield => "yield",
2212 TokenKind::Mutex => "mutex",
2213 TokenKind::Break => "break",
2214 TokenKind::Continue => "continue",
2215 TokenKind::Impl => "impl",
2216 _ => return Err(self.make_error(expected)),
2217 };
2218 let name = name.to_string();
2219 self.advance();
2220 Ok(name)
2221 }
2222
2223 fn skip_newlines(&mut self) {
2224 while self.pos < self.tokens.len() && self.tokens[self.pos].kind == TokenKind::Newline {
2225 self.pos += 1;
2226 }
2227 }
2228
2229 fn make_error(&self, expected: &str) -> ParserError {
2230 if let Some(tok) = self.tokens.get(self.pos) {
2231 if tok.kind == TokenKind::Eof {
2232 return ParserError::UnexpectedEof {
2233 expected: expected.into(),
2234 };
2235 }
2236 ParserError::Unexpected {
2237 got: tok.kind.to_string(),
2238 expected: expected.into(),
2239 span: tok.span,
2240 }
2241 } else {
2242 ParserError::UnexpectedEof {
2243 expected: expected.into(),
2244 }
2245 }
2246 }
2247
2248 fn error(&self, expected: &str) -> ParserError {
2249 self.make_error(expected)
2250 }
2251}