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