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 if self.check(&TokenKind::Dot) {
1492 let saved_pos = self.pos;
1493 self.advance(); if self.check(&TokenKind::Dot) {
1495 self.advance(); self.consume(&TokenKind::Dot, ".")?; let spread_start = self.tokens[saved_pos].span;
1498 let expr = self.parse_expression()?;
1499 elements.push(spanned(
1500 Node::Spread(Box::new(expr)),
1501 Span::merge(spread_start, self.prev_span()),
1502 ));
1503 } else {
1504 self.pos = saved_pos;
1506 elements.push(self.parse_expression()?);
1507 }
1508 } else {
1509 elements.push(self.parse_expression()?);
1510 }
1511 self.skip_newlines();
1512 if self.check(&TokenKind::Comma) {
1513 self.advance();
1514 self.skip_newlines();
1515 }
1516 }
1517
1518 self.consume(&TokenKind::RBracket, "]")?;
1519 Ok(spanned(
1520 Node::ListLiteral(elements),
1521 Span::merge(start, self.prev_span()),
1522 ))
1523 }
1524
1525 fn parse_dict_or_closure(&mut self) -> Result<SNode, ParserError> {
1526 let start = self.current_span();
1527 self.consume(&TokenKind::LBrace, "{")?;
1528 self.skip_newlines();
1529
1530 if self.check(&TokenKind::RBrace) {
1532 self.advance();
1533 return Ok(spanned(
1534 Node::DictLiteral(Vec::new()),
1535 Span::merge(start, self.prev_span()),
1536 ));
1537 }
1538
1539 let saved = self.pos;
1541 if self.is_closure_lookahead() {
1542 self.pos = saved;
1543 return self.parse_closure_body(start);
1544 }
1545 self.pos = saved;
1546 self.parse_dict_literal(start)
1547 }
1548
1549 fn is_closure_lookahead(&mut self) -> bool {
1552 let mut depth = 0;
1553 while !self.is_at_end() {
1554 if let Some(tok) = self.current() {
1555 match &tok.kind {
1556 TokenKind::Arrow if depth == 0 => return true,
1557 TokenKind::LBrace | TokenKind::LParen | TokenKind::LBracket => depth += 1,
1558 TokenKind::RBrace if depth == 0 => return false,
1559 TokenKind::RBrace => depth -= 1,
1560 TokenKind::RParen | TokenKind::RBracket => {
1561 if depth > 0 {
1562 depth -= 1;
1563 }
1564 }
1565 _ => {}
1566 }
1567 self.advance();
1568 } else {
1569 return false;
1570 }
1571 }
1572 false
1573 }
1574
1575 fn parse_closure_body(&mut self, start: Span) -> Result<SNode, ParserError> {
1577 let params = self.parse_typed_param_list_until_arrow()?;
1578 self.consume(&TokenKind::Arrow, "->")?;
1579 let body = self.parse_block()?;
1580 self.consume(&TokenKind::RBrace, "}")?;
1581 Ok(spanned(
1582 Node::Closure { params, body },
1583 Span::merge(start, self.prev_span()),
1584 ))
1585 }
1586
1587 fn parse_typed_param_list_until_arrow(&mut self) -> Result<Vec<TypedParam>, ParserError> {
1589 let mut params = Vec::new();
1590 self.skip_newlines();
1591 while !self.is_at_end() && !self.check(&TokenKind::Arrow) {
1592 let name = self.consume_identifier("parameter name")?;
1593 let type_expr = self.try_parse_type_annotation()?;
1594 params.push(TypedParam { name, type_expr });
1595 if self.check(&TokenKind::Comma) {
1596 self.advance();
1597 self.skip_newlines();
1598 }
1599 }
1600 Ok(params)
1601 }
1602
1603 fn parse_dict_literal(&mut self, start: Span) -> Result<SNode, ParserError> {
1604 let mut entries = Vec::new();
1605 self.skip_newlines();
1606
1607 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1608 if self.check(&TokenKind::Dot) {
1610 let saved_pos = self.pos;
1611 self.advance(); if self.check(&TokenKind::Dot) {
1613 self.advance(); if self.check(&TokenKind::Dot) {
1615 self.advance(); let spread_start = self.tokens[saved_pos].span;
1617 let expr = self.parse_expression()?;
1618 entries.push(DictEntry {
1619 key: spanned(Node::NilLiteral, spread_start),
1620 value: spanned(
1621 Node::Spread(Box::new(expr)),
1622 Span::merge(spread_start, self.prev_span()),
1623 ),
1624 });
1625 self.skip_newlines();
1626 if self.check(&TokenKind::Comma) {
1627 self.advance();
1628 self.skip_newlines();
1629 }
1630 continue;
1631 }
1632 self.pos = saved_pos;
1634 } else {
1635 self.pos = saved_pos;
1636 }
1637 }
1638 let key = if self.check(&TokenKind::LBracket) {
1639 self.advance();
1641 let k = self.parse_expression()?;
1642 self.consume(&TokenKind::RBracket, "]")?;
1643 k
1644 } else if matches!(
1645 self.current().map(|t| &t.kind),
1646 Some(TokenKind::StringLiteral(_))
1647 ) {
1648 let key_span = self.current_span();
1650 let name =
1651 if let Some(TokenKind::StringLiteral(s)) = self.current().map(|t| &t.kind) {
1652 s.clone()
1653 } else {
1654 unreachable!()
1655 };
1656 self.advance();
1657 spanned(Node::StringLiteral(name), key_span)
1658 } else {
1659 let key_span = self.current_span();
1661 let name = self.consume_identifier_or_keyword("dict key")?;
1662 spanned(Node::StringLiteral(name), key_span)
1663 };
1664 self.consume(&TokenKind::Colon, ":")?;
1665 let value = self.parse_expression()?;
1666 entries.push(DictEntry { key, value });
1667 self.skip_newlines();
1668 if self.check(&TokenKind::Comma) {
1669 self.advance();
1670 self.skip_newlines();
1671 }
1672 }
1673
1674 self.consume(&TokenKind::RBrace, "}")?;
1675 Ok(spanned(
1676 Node::DictLiteral(entries),
1677 Span::merge(start, self.prev_span()),
1678 ))
1679 }
1680
1681 fn parse_param_list(&mut self) -> Result<Vec<String>, ParserError> {
1685 let mut params = Vec::new();
1686 self.skip_newlines();
1687
1688 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
1689 params.push(self.consume_identifier("parameter name")?);
1690 if self.check(&TokenKind::Comma) {
1691 self.advance();
1692 self.skip_newlines();
1693 }
1694 }
1695 Ok(params)
1696 }
1697
1698 fn parse_typed_param_list(&mut self) -> Result<Vec<TypedParam>, ParserError> {
1700 let mut params = Vec::new();
1701 self.skip_newlines();
1702
1703 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
1704 let name = self.consume_identifier("parameter name")?;
1705 let type_expr = self.try_parse_type_annotation()?;
1706 params.push(TypedParam { name, type_expr });
1707 if self.check(&TokenKind::Comma) {
1708 self.advance();
1709 self.skip_newlines();
1710 }
1711 }
1712 Ok(params)
1713 }
1714
1715 fn try_parse_type_annotation(&mut self) -> Result<Option<TypeExpr>, ParserError> {
1718 if !self.check(&TokenKind::Colon) {
1719 return Ok(None);
1720 }
1721 self.advance(); Ok(Some(self.parse_type_expr()?))
1723 }
1724
1725 fn parse_type_expr(&mut self) -> Result<TypeExpr, ParserError> {
1727 self.skip_newlines();
1728 let first = self.parse_type_primary()?;
1729
1730 if self.check(&TokenKind::Bar) {
1732 let mut types = vec![first];
1733 while self.check(&TokenKind::Bar) {
1734 self.advance(); types.push(self.parse_type_primary()?);
1736 }
1737 return Ok(TypeExpr::Union(types));
1738 }
1739
1740 Ok(first)
1741 }
1742
1743 fn parse_type_primary(&mut self) -> Result<TypeExpr, ParserError> {
1746 self.skip_newlines();
1747 if self.check(&TokenKind::LBrace) {
1748 return self.parse_shape_type();
1749 }
1750 if let Some(tok) = self.current() {
1752 let type_name = match &tok.kind {
1753 TokenKind::Nil => {
1754 self.advance();
1755 return Ok(TypeExpr::Named("nil".to_string()));
1756 }
1757 TokenKind::True | TokenKind::False => {
1758 self.advance();
1759 return Ok(TypeExpr::Named("bool".to_string()));
1760 }
1761 _ => None,
1762 };
1763 if let Some(name) = type_name {
1764 return Ok(TypeExpr::Named(name));
1765 }
1766 }
1767 let name = self.consume_identifier("type name")?;
1768 if self.check(&TokenKind::LBracket) {
1770 self.advance(); let first_param = self.parse_type_expr()?;
1772 if name == "list" {
1773 self.consume(&TokenKind::RBracket, "]")?;
1774 return Ok(TypeExpr::List(Box::new(first_param)));
1775 } else if name == "dict" {
1776 self.consume(&TokenKind::Comma, ",")?;
1777 let second_param = self.parse_type_expr()?;
1778 self.consume(&TokenKind::RBracket, "]")?;
1779 return Ok(TypeExpr::DictType(
1780 Box::new(first_param),
1781 Box::new(second_param),
1782 ));
1783 }
1784 self.consume(&TokenKind::RBracket, "]")?;
1786 }
1787 Ok(TypeExpr::Named(name))
1788 }
1789
1790 fn parse_shape_type(&mut self) -> Result<TypeExpr, ParserError> {
1792 self.consume(&TokenKind::LBrace, "{")?;
1793 let mut fields = Vec::new();
1794 self.skip_newlines();
1795
1796 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1797 let name = self.consume_identifier("field name")?;
1798 let optional = if self.check(&TokenKind::Question) {
1799 self.advance();
1800 true
1801 } else {
1802 false
1803 };
1804 self.consume(&TokenKind::Colon, ":")?;
1805 let type_expr = self.parse_type_expr()?;
1806 fields.push(ShapeField {
1807 name,
1808 type_expr,
1809 optional,
1810 });
1811 self.skip_newlines();
1812 if self.check(&TokenKind::Comma) {
1813 self.advance();
1814 self.skip_newlines();
1815 }
1816 }
1817
1818 self.consume(&TokenKind::RBrace, "}")?;
1819 Ok(TypeExpr::Shape(fields))
1820 }
1821
1822 fn parse_arg_list(&mut self) -> Result<Vec<SNode>, ParserError> {
1823 let mut args = Vec::new();
1824 self.skip_newlines();
1825
1826 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
1827 args.push(self.parse_expression()?);
1828 self.skip_newlines();
1829 if self.check(&TokenKind::Comma) {
1830 self.advance();
1831 self.skip_newlines();
1832 }
1833 }
1834 Ok(args)
1835 }
1836
1837 fn is_at_end(&self) -> bool {
1838 self.pos >= self.tokens.len()
1839 || matches!(self.tokens.get(self.pos), Some(t) if t.kind == TokenKind::Eof)
1840 }
1841
1842 fn current(&self) -> Option<&Token> {
1843 self.tokens.get(self.pos)
1844 }
1845
1846 fn peek_kind(&self) -> Option<&TokenKind> {
1847 self.tokens.get(self.pos + 1).map(|t| &t.kind)
1848 }
1849
1850 fn check(&self, kind: &TokenKind) -> bool {
1851 self.current()
1852 .map(|t| std::mem::discriminant(&t.kind) == std::mem::discriminant(kind))
1853 .unwrap_or(false)
1854 }
1855
1856 fn check_skip_newlines(&mut self, kind: &TokenKind) -> bool {
1859 let saved = self.pos;
1860 self.skip_newlines();
1861 if self.check(kind) {
1862 true
1863 } else {
1864 self.pos = saved;
1865 false
1866 }
1867 }
1868
1869 fn advance(&mut self) {
1870 if self.pos < self.tokens.len() {
1871 self.pos += 1;
1872 }
1873 }
1874
1875 fn consume(&mut self, kind: &TokenKind, expected: &str) -> Result<Token, ParserError> {
1876 self.skip_newlines();
1877 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
1878 if std::mem::discriminant(&tok.kind) != std::mem::discriminant(kind) {
1879 return Err(self.make_error(expected));
1880 }
1881 let tok = tok.clone();
1882 self.advance();
1883 Ok(tok)
1884 }
1885
1886 fn consume_identifier(&mut self, expected: &str) -> Result<String, ParserError> {
1887 self.skip_newlines();
1888 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
1889 if let TokenKind::Identifier(name) = &tok.kind {
1890 let name = name.clone();
1891 self.advance();
1892 Ok(name)
1893 } else {
1894 Err(self.make_error(expected))
1895 }
1896 }
1897
1898 fn consume_identifier_or_keyword(&mut self, expected: &str) -> Result<String, ParserError> {
1902 self.skip_newlines();
1903 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
1904 if let TokenKind::Identifier(name) = &tok.kind {
1905 let name = name.clone();
1906 self.advance();
1907 return Ok(name);
1908 }
1909 let name = match &tok.kind {
1911 TokenKind::Pipeline => "pipeline",
1912 TokenKind::Extends => "extends",
1913 TokenKind::Override => "override",
1914 TokenKind::Let => "let",
1915 TokenKind::Var => "var",
1916 TokenKind::If => "if",
1917 TokenKind::Else => "else",
1918 TokenKind::For => "for",
1919 TokenKind::In => "in",
1920 TokenKind::Match => "match",
1921 TokenKind::Retry => "retry",
1922 TokenKind::Parallel => "parallel",
1923 TokenKind::ParallelMap => "parallel_map",
1924 TokenKind::Return => "return",
1925 TokenKind::Import => "import",
1926 TokenKind::True => "true",
1927 TokenKind::False => "false",
1928 TokenKind::Nil => "nil",
1929 TokenKind::Try => "try",
1930 TokenKind::Catch => "catch",
1931 TokenKind::Throw => "throw",
1932 TokenKind::Fn => "fn",
1933 TokenKind::Spawn => "spawn",
1934 TokenKind::While => "while",
1935 TokenKind::TypeKw => "type",
1936 TokenKind::Enum => "enum",
1937 TokenKind::Struct => "struct",
1938 TokenKind::Interface => "interface",
1939 TokenKind::Pub => "pub",
1940 TokenKind::From => "from",
1941 TokenKind::Thru => "thru",
1942 TokenKind::Upto => "upto",
1943 TokenKind::Guard => "guard",
1944 TokenKind::Ask => "ask",
1945 TokenKind::Deadline => "deadline",
1946 TokenKind::Yield => "yield",
1947 TokenKind::Mutex => "mutex",
1948 TokenKind::Break => "break",
1949 TokenKind::Continue => "continue",
1950 _ => return Err(self.make_error(expected)),
1951 };
1952 let name = name.to_string();
1953 self.advance();
1954 Ok(name)
1955 }
1956
1957 fn skip_newlines(&mut self) {
1958 while self.pos < self.tokens.len() && self.tokens[self.pos].kind == TokenKind::Newline {
1959 self.pos += 1;
1960 }
1961 }
1962
1963 fn make_error(&self, expected: &str) -> ParserError {
1964 if let Some(tok) = self.tokens.get(self.pos) {
1965 if tok.kind == TokenKind::Eof {
1966 return ParserError::UnexpectedEof {
1967 expected: expected.into(),
1968 };
1969 }
1970 ParserError::Unexpected {
1971 got: tok.kind.to_string(),
1972 expected: expected.into(),
1973 span: tok.span,
1974 }
1975 } else {
1976 ParserError::UnexpectedEof {
1977 expected: expected.into(),
1978 }
1979 }
1980 }
1981
1982 fn error(&self, expected: &str) -> ParserError {
1983 self.make_error(expected)
1984 }
1985}