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