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