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