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