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(&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(&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(&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(&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(&TokenKind::Star)
1112 || self.check(&TokenKind::Slash)
1113 || self.check(&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(&TokenKind::Dot) || self.check(&TokenKind::QuestionDot) {
1170 let optional = self.check(&TokenKind::QuestionDot);
1171 let start = expr.span;
1172 self.advance();
1173 let member = self.consume_identifier_or_keyword("member name")?;
1174 if self.check(&TokenKind::LParen) {
1175 self.advance();
1176 let args = self.parse_arg_list()?;
1177 self.consume(&TokenKind::RParen, ")")?;
1178 if optional {
1179 expr = spanned(
1180 Node::OptionalMethodCall {
1181 object: Box::new(expr),
1182 method: member,
1183 args,
1184 },
1185 Span::merge(start, self.prev_span()),
1186 );
1187 } else {
1188 expr = spanned(
1189 Node::MethodCall {
1190 object: Box::new(expr),
1191 method: member,
1192 args,
1193 },
1194 Span::merge(start, self.prev_span()),
1195 );
1196 }
1197 } else if optional {
1198 expr = spanned(
1199 Node::OptionalPropertyAccess {
1200 object: Box::new(expr),
1201 property: member,
1202 },
1203 Span::merge(start, self.prev_span()),
1204 );
1205 } else {
1206 expr = spanned(
1207 Node::PropertyAccess {
1208 object: Box::new(expr),
1209 property: member,
1210 },
1211 Span::merge(start, self.prev_span()),
1212 );
1213 }
1214 } else if self.check(&TokenKind::LBracket) {
1215 let start = expr.span;
1216 self.advance();
1217
1218 if self.check(&TokenKind::Colon) {
1223 self.advance(); let end_expr = if self.check(&TokenKind::RBracket) {
1226 None
1227 } else {
1228 Some(Box::new(self.parse_expression()?))
1229 };
1230 self.consume(&TokenKind::RBracket, "]")?;
1231 expr = spanned(
1232 Node::SliceAccess {
1233 object: Box::new(expr),
1234 start: None,
1235 end: end_expr,
1236 },
1237 Span::merge(start, self.prev_span()),
1238 );
1239 } else {
1240 let index = self.parse_expression()?;
1241 if self.check(&TokenKind::Colon) {
1242 self.advance(); let end_expr = if self.check(&TokenKind::RBracket) {
1245 None
1246 } else {
1247 Some(Box::new(self.parse_expression()?))
1248 };
1249 self.consume(&TokenKind::RBracket, "]")?;
1250 expr = spanned(
1251 Node::SliceAccess {
1252 object: Box::new(expr),
1253 start: Some(Box::new(index)),
1254 end: end_expr,
1255 },
1256 Span::merge(start, self.prev_span()),
1257 );
1258 } else {
1259 self.consume(&TokenKind::RBracket, "]")?;
1260 expr = spanned(
1261 Node::SubscriptAccess {
1262 object: Box::new(expr),
1263 index: Box::new(index),
1264 },
1265 Span::merge(start, self.prev_span()),
1266 );
1267 }
1268 }
1269 } else if self.check(&TokenKind::LParen) && matches!(expr.node, Node::Identifier(_)) {
1270 let start = expr.span;
1271 self.advance();
1272 let args = self.parse_arg_list()?;
1273 self.consume(&TokenKind::RParen, ")")?;
1274 if let Node::Identifier(name) = expr.node {
1275 expr = spanned(
1276 Node::FunctionCall { name, args },
1277 Span::merge(start, self.prev_span()),
1278 );
1279 }
1280 } else {
1281 break;
1282 }
1283 }
1284
1285 Ok(expr)
1286 }
1287
1288 fn parse_primary(&mut self) -> Result<SNode, ParserError> {
1289 let tok = self.current().ok_or_else(|| ParserError::UnexpectedEof {
1290 expected: "expression".into(),
1291 })?;
1292 let start = self.current_span();
1293
1294 match &tok.kind {
1295 TokenKind::StringLiteral(s) => {
1296 let s = s.clone();
1297 self.advance();
1298 Ok(spanned(
1299 Node::StringLiteral(s),
1300 Span::merge(start, self.prev_span()),
1301 ))
1302 }
1303 TokenKind::InterpolatedString(segments) => {
1304 let segments = segments.clone();
1305 self.advance();
1306 Ok(spanned(
1307 Node::InterpolatedString(segments),
1308 Span::merge(start, self.prev_span()),
1309 ))
1310 }
1311 TokenKind::IntLiteral(n) => {
1312 let n = *n;
1313 self.advance();
1314 Ok(spanned(
1315 Node::IntLiteral(n),
1316 Span::merge(start, self.prev_span()),
1317 ))
1318 }
1319 TokenKind::FloatLiteral(n) => {
1320 let n = *n;
1321 self.advance();
1322 Ok(spanned(
1323 Node::FloatLiteral(n),
1324 Span::merge(start, self.prev_span()),
1325 ))
1326 }
1327 TokenKind::True => {
1328 self.advance();
1329 Ok(spanned(
1330 Node::BoolLiteral(true),
1331 Span::merge(start, self.prev_span()),
1332 ))
1333 }
1334 TokenKind::False => {
1335 self.advance();
1336 Ok(spanned(
1337 Node::BoolLiteral(false),
1338 Span::merge(start, self.prev_span()),
1339 ))
1340 }
1341 TokenKind::Nil => {
1342 self.advance();
1343 Ok(spanned(
1344 Node::NilLiteral,
1345 Span::merge(start, self.prev_span()),
1346 ))
1347 }
1348 TokenKind::Identifier(name) => {
1349 let name = name.clone();
1350 self.advance();
1351 Ok(spanned(
1352 Node::Identifier(name),
1353 Span::merge(start, self.prev_span()),
1354 ))
1355 }
1356 TokenKind::LParen => {
1357 self.advance();
1358 let expr = self.parse_expression()?;
1359 self.consume(&TokenKind::RParen, ")")?;
1360 Ok(expr)
1361 }
1362 TokenKind::LBracket => self.parse_list_literal(),
1363 TokenKind::LBrace => self.parse_dict_or_closure(),
1364 TokenKind::Parallel => self.parse_parallel(),
1365 TokenKind::ParallelMap => self.parse_parallel_map(),
1366 TokenKind::Retry => self.parse_retry(),
1367 TokenKind::If => self.parse_if_else(),
1368 TokenKind::Spawn => self.parse_spawn_expr(),
1369 TokenKind::DurationLiteral(ms) => {
1370 let ms = *ms;
1371 self.advance();
1372 Ok(spanned(
1373 Node::DurationLiteral(ms),
1374 Span::merge(start, self.prev_span()),
1375 ))
1376 }
1377 TokenKind::Ask => self.parse_ask_expr(),
1378 TokenKind::Deadline => self.parse_deadline(),
1379 _ => Err(self.error("expression")),
1380 }
1381 }
1382
1383 fn parse_spawn_expr(&mut self) -> Result<SNode, ParserError> {
1384 let start = self.current_span();
1385 self.consume(&TokenKind::Spawn, "spawn")?;
1386 self.consume(&TokenKind::LBrace, "{")?;
1387 let body = self.parse_block()?;
1388 self.consume(&TokenKind::RBrace, "}")?;
1389 Ok(spanned(
1390 Node::SpawnExpr { body },
1391 Span::merge(start, self.prev_span()),
1392 ))
1393 }
1394
1395 fn parse_list_literal(&mut self) -> Result<SNode, ParserError> {
1396 let start = self.current_span();
1397 self.consume(&TokenKind::LBracket, "[")?;
1398 let mut elements = Vec::new();
1399 self.skip_newlines();
1400
1401 while !self.is_at_end() && !self.check(&TokenKind::RBracket) {
1402 elements.push(self.parse_expression()?);
1403 self.skip_newlines();
1404 if self.check(&TokenKind::Comma) {
1405 self.advance();
1406 self.skip_newlines();
1407 }
1408 }
1409
1410 self.consume(&TokenKind::RBracket, "]")?;
1411 Ok(spanned(
1412 Node::ListLiteral(elements),
1413 Span::merge(start, self.prev_span()),
1414 ))
1415 }
1416
1417 fn parse_dict_or_closure(&mut self) -> Result<SNode, ParserError> {
1418 let start = self.current_span();
1419 self.consume(&TokenKind::LBrace, "{")?;
1420 self.skip_newlines();
1421
1422 if self.check(&TokenKind::RBrace) {
1424 self.advance();
1425 return Ok(spanned(
1426 Node::DictLiteral(Vec::new()),
1427 Span::merge(start, self.prev_span()),
1428 ));
1429 }
1430
1431 let saved = self.pos;
1433 if self.is_closure_lookahead() {
1434 self.pos = saved;
1435 return self.parse_closure_body(start);
1436 }
1437 self.pos = saved;
1438 self.parse_dict_literal(start)
1439 }
1440
1441 fn is_closure_lookahead(&mut self) -> bool {
1444 let mut depth = 0;
1445 while !self.is_at_end() {
1446 if let Some(tok) = self.current() {
1447 match &tok.kind {
1448 TokenKind::Arrow if depth == 0 => return true,
1449 TokenKind::LBrace | TokenKind::LParen | TokenKind::LBracket => depth += 1,
1450 TokenKind::RBrace if depth == 0 => return false,
1451 TokenKind::RBrace => depth -= 1,
1452 TokenKind::RParen | TokenKind::RBracket => {
1453 if depth > 0 {
1454 depth -= 1;
1455 }
1456 }
1457 _ => {}
1458 }
1459 self.advance();
1460 } else {
1461 return false;
1462 }
1463 }
1464 false
1465 }
1466
1467 fn parse_closure_body(&mut self, start: Span) -> Result<SNode, ParserError> {
1469 let params = self.parse_typed_param_list_until_arrow()?;
1470 self.consume(&TokenKind::Arrow, "->")?;
1471 let body = self.parse_block()?;
1472 self.consume(&TokenKind::RBrace, "}")?;
1473 Ok(spanned(
1474 Node::Closure { params, body },
1475 Span::merge(start, self.prev_span()),
1476 ))
1477 }
1478
1479 fn parse_typed_param_list_until_arrow(&mut self) -> Result<Vec<TypedParam>, ParserError> {
1481 let mut params = Vec::new();
1482 self.skip_newlines();
1483 while !self.is_at_end() && !self.check(&TokenKind::Arrow) {
1484 let name = self.consume_identifier("parameter name")?;
1485 let type_expr = self.try_parse_type_annotation()?;
1486 params.push(TypedParam { name, type_expr });
1487 if self.check(&TokenKind::Comma) {
1488 self.advance();
1489 self.skip_newlines();
1490 }
1491 }
1492 Ok(params)
1493 }
1494
1495 fn parse_dict_literal(&mut self, start: Span) -> Result<SNode, ParserError> {
1496 let mut entries = Vec::new();
1497 self.skip_newlines();
1498
1499 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1500 let key = if self.check(&TokenKind::LBracket) {
1501 self.advance();
1503 let k = self.parse_expression()?;
1504 self.consume(&TokenKind::RBracket, "]")?;
1505 k
1506 } else if matches!(
1507 self.current().map(|t| &t.kind),
1508 Some(TokenKind::StringLiteral(_))
1509 ) {
1510 let key_span = self.current_span();
1512 let name =
1513 if let Some(TokenKind::StringLiteral(s)) = self.current().map(|t| &t.kind) {
1514 s.clone()
1515 } else {
1516 unreachable!()
1517 };
1518 self.advance();
1519 spanned(Node::StringLiteral(name), key_span)
1520 } else {
1521 let key_span = self.current_span();
1523 let name = self.consume_identifier_or_keyword("dict key")?;
1524 spanned(Node::StringLiteral(name), key_span)
1525 };
1526 self.consume(&TokenKind::Colon, ":")?;
1527 let value = self.parse_expression()?;
1528 entries.push(DictEntry { key, value });
1529 self.skip_newlines();
1530 if self.check(&TokenKind::Comma) {
1531 self.advance();
1532 self.skip_newlines();
1533 }
1534 }
1535
1536 self.consume(&TokenKind::RBrace, "}")?;
1537 Ok(spanned(
1538 Node::DictLiteral(entries),
1539 Span::merge(start, self.prev_span()),
1540 ))
1541 }
1542
1543 fn parse_param_list(&mut self) -> Result<Vec<String>, ParserError> {
1547 let mut params = Vec::new();
1548 self.skip_newlines();
1549
1550 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
1551 params.push(self.consume_identifier("parameter name")?);
1552 if self.check(&TokenKind::Comma) {
1553 self.advance();
1554 self.skip_newlines();
1555 }
1556 }
1557 Ok(params)
1558 }
1559
1560 fn parse_typed_param_list(&mut self) -> Result<Vec<TypedParam>, ParserError> {
1562 let mut params = Vec::new();
1563 self.skip_newlines();
1564
1565 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
1566 let name = self.consume_identifier("parameter name")?;
1567 let type_expr = self.try_parse_type_annotation()?;
1568 params.push(TypedParam { name, type_expr });
1569 if self.check(&TokenKind::Comma) {
1570 self.advance();
1571 self.skip_newlines();
1572 }
1573 }
1574 Ok(params)
1575 }
1576
1577 fn try_parse_type_annotation(&mut self) -> Result<Option<TypeExpr>, ParserError> {
1580 if !self.check(&TokenKind::Colon) {
1581 return Ok(None);
1582 }
1583 self.advance(); Ok(Some(self.parse_type_expr()?))
1585 }
1586
1587 fn parse_type_expr(&mut self) -> Result<TypeExpr, ParserError> {
1589 self.skip_newlines();
1590 let first = self.parse_type_primary()?;
1591
1592 if self.check(&TokenKind::Bar) {
1594 let mut types = vec![first];
1595 while self.check(&TokenKind::Bar) {
1596 self.advance(); types.push(self.parse_type_primary()?);
1598 }
1599 return Ok(TypeExpr::Union(types));
1600 }
1601
1602 Ok(first)
1603 }
1604
1605 fn parse_type_primary(&mut self) -> Result<TypeExpr, ParserError> {
1608 self.skip_newlines();
1609 if self.check(&TokenKind::LBrace) {
1610 return self.parse_shape_type();
1611 }
1612 if let Some(tok) = self.current() {
1614 let type_name = match &tok.kind {
1615 TokenKind::Nil => {
1616 self.advance();
1617 return Ok(TypeExpr::Named("nil".to_string()));
1618 }
1619 TokenKind::True | TokenKind::False => {
1620 self.advance();
1621 return Ok(TypeExpr::Named("bool".to_string()));
1622 }
1623 _ => None,
1624 };
1625 if let Some(name) = type_name {
1626 return Ok(TypeExpr::Named(name));
1627 }
1628 }
1629 let name = self.consume_identifier("type name")?;
1630 if self.check(&TokenKind::LBracket) {
1632 self.advance(); let first_param = self.parse_type_expr()?;
1634 if name == "list" {
1635 self.consume(&TokenKind::RBracket, "]")?;
1636 return Ok(TypeExpr::List(Box::new(first_param)));
1637 } else if name == "dict" {
1638 self.consume(&TokenKind::Comma, ",")?;
1639 let second_param = self.parse_type_expr()?;
1640 self.consume(&TokenKind::RBracket, "]")?;
1641 return Ok(TypeExpr::DictType(
1642 Box::new(first_param),
1643 Box::new(second_param),
1644 ));
1645 }
1646 self.consume(&TokenKind::RBracket, "]")?;
1648 }
1649 Ok(TypeExpr::Named(name))
1650 }
1651
1652 fn parse_shape_type(&mut self) -> Result<TypeExpr, ParserError> {
1654 self.consume(&TokenKind::LBrace, "{")?;
1655 let mut fields = Vec::new();
1656 self.skip_newlines();
1657
1658 while !self.is_at_end() && !self.check(&TokenKind::RBrace) {
1659 let name = self.consume_identifier("field name")?;
1660 let optional = if self.check(&TokenKind::Question) {
1661 self.advance();
1662 true
1663 } else {
1664 false
1665 };
1666 self.consume(&TokenKind::Colon, ":")?;
1667 let type_expr = self.parse_type_expr()?;
1668 fields.push(ShapeField {
1669 name,
1670 type_expr,
1671 optional,
1672 });
1673 self.skip_newlines();
1674 if self.check(&TokenKind::Comma) {
1675 self.advance();
1676 self.skip_newlines();
1677 }
1678 }
1679
1680 self.consume(&TokenKind::RBrace, "}")?;
1681 Ok(TypeExpr::Shape(fields))
1682 }
1683
1684 fn parse_arg_list(&mut self) -> Result<Vec<SNode>, ParserError> {
1685 let mut args = Vec::new();
1686 self.skip_newlines();
1687
1688 while !self.is_at_end() && !self.check(&TokenKind::RParen) {
1689 args.push(self.parse_expression()?);
1690 self.skip_newlines();
1691 if self.check(&TokenKind::Comma) {
1692 self.advance();
1693 self.skip_newlines();
1694 }
1695 }
1696 Ok(args)
1697 }
1698
1699 fn is_at_end(&self) -> bool {
1700 self.pos >= self.tokens.len()
1701 || matches!(self.tokens.get(self.pos), Some(t) if t.kind == TokenKind::Eof)
1702 }
1703
1704 fn current(&self) -> Option<&Token> {
1705 self.tokens.get(self.pos)
1706 }
1707
1708 fn peek_kind(&self) -> Option<&TokenKind> {
1709 self.tokens.get(self.pos + 1).map(|t| &t.kind)
1710 }
1711
1712 fn check(&self, kind: &TokenKind) -> bool {
1713 self.current()
1714 .map(|t| std::mem::discriminant(&t.kind) == std::mem::discriminant(kind))
1715 .unwrap_or(false)
1716 }
1717
1718 fn advance(&mut self) {
1719 if self.pos < self.tokens.len() {
1720 self.pos += 1;
1721 }
1722 }
1723
1724 fn consume(&mut self, kind: &TokenKind, expected: &str) -> Result<Token, ParserError> {
1725 self.skip_newlines();
1726 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
1727 if std::mem::discriminant(&tok.kind) != std::mem::discriminant(kind) {
1728 return Err(self.make_error(expected));
1729 }
1730 let tok = tok.clone();
1731 self.advance();
1732 Ok(tok)
1733 }
1734
1735 fn consume_identifier(&mut self, expected: &str) -> Result<String, ParserError> {
1736 self.skip_newlines();
1737 let tok = self.current().ok_or_else(|| self.make_error(expected))?;
1738 if let TokenKind::Identifier(name) = &tok.kind {
1739 let name = name.clone();
1740 self.advance();
1741 Ok(name)
1742 } else {
1743 Err(self.make_error(expected))
1744 }
1745 }
1746
1747 fn consume_identifier_or_keyword(&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 return Ok(name);
1757 }
1758 let name = match &tok.kind {
1760 TokenKind::Pipeline => "pipeline",
1761 TokenKind::Extends => "extends",
1762 TokenKind::Override => "override",
1763 TokenKind::Let => "let",
1764 TokenKind::Var => "var",
1765 TokenKind::If => "if",
1766 TokenKind::Else => "else",
1767 TokenKind::For => "for",
1768 TokenKind::In => "in",
1769 TokenKind::Match => "match",
1770 TokenKind::Retry => "retry",
1771 TokenKind::Parallel => "parallel",
1772 TokenKind::ParallelMap => "parallel_map",
1773 TokenKind::Return => "return",
1774 TokenKind::Import => "import",
1775 TokenKind::True => "true",
1776 TokenKind::False => "false",
1777 TokenKind::Nil => "nil",
1778 TokenKind::Try => "try",
1779 TokenKind::Catch => "catch",
1780 TokenKind::Throw => "throw",
1781 TokenKind::Fn => "fn",
1782 TokenKind::Spawn => "spawn",
1783 TokenKind::While => "while",
1784 TokenKind::TypeKw => "type",
1785 TokenKind::Enum => "enum",
1786 TokenKind::Struct => "struct",
1787 TokenKind::Interface => "interface",
1788 TokenKind::Pub => "pub",
1789 TokenKind::From => "from",
1790 TokenKind::Thru => "thru",
1791 TokenKind::Upto => "upto",
1792 TokenKind::Guard => "guard",
1793 TokenKind::Ask => "ask",
1794 TokenKind::Deadline => "deadline",
1795 TokenKind::Yield => "yield",
1796 TokenKind::Mutex => "mutex",
1797 TokenKind::Break => "break",
1798 TokenKind::Continue => "continue",
1799 _ => return Err(self.make_error(expected)),
1800 };
1801 let name = name.to_string();
1802 self.advance();
1803 Ok(name)
1804 }
1805
1806 fn skip_newlines(&mut self) {
1807 while self.pos < self.tokens.len() && self.tokens[self.pos].kind == TokenKind::Newline {
1808 self.pos += 1;
1809 }
1810 }
1811
1812 fn make_error(&self, expected: &str) -> ParserError {
1813 if let Some(tok) = self.tokens.get(self.pos) {
1814 if tok.kind == TokenKind::Eof {
1815 return ParserError::UnexpectedEof {
1816 expected: expected.into(),
1817 };
1818 }
1819 ParserError::Unexpected {
1820 got: tok.kind.to_string(),
1821 expected: expected.into(),
1822 span: tok.span,
1823 }
1824 } else {
1825 ParserError::UnexpectedEof {
1826 expected: expected.into(),
1827 }
1828 }
1829 }
1830
1831 fn error(&self, expected: &str) -> ParserError {
1832 self.make_error(expected)
1833 }
1834}