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