1use cjc_ast::{
40 self, BinOp, Block, CallArg, ClassDecl, ConstDecl, Decl, DeclKind, ElseBranch, EnumDecl,
41 Expr, ExprKind, FieldDecl, FieldInit, FnDecl, FnSig, ForIter, ForStmt, Ident, IfStmt,
42 ImplDecl, ImportDecl, LetStmt, MatchArm, Param, Pattern, PatternField, PatternKind, Program,
43 RecordDecl, ShapeDim, Stmt, StmtKind, StructDecl, TraitDecl, TypeArg, TypeExpr, TypeExprKind,
44 TypeParam, UnaryOp, VariantDecl, Visibility, WhileStmt,
45};
46use cjc_diag::{Diagnostic, DiagnosticBag};
47use cjc_lexer::{Token, TokenKind};
48
49fn to_ast_span(s: cjc_diag::Span) -> cjc_ast::Span {
53 cjc_ast::Span::new(s.start, s.end)
54}
55
56fn to_diag_span(s: cjc_ast::Span) -> cjc_diag::Span {
58 cjc_diag::Span::new(s.start, s.end)
59}
60
61fn merge_spans(a: cjc_ast::Span, b: cjc_ast::Span) -> cjc_ast::Span {
63 cjc_ast::Span::new(a.start.min(b.start), a.end.max(b.end))
64}
65
66mod prec {
76 pub const ASSIGN: u8 = 2;
78 pub const PIPE: u8 = 4;
80 pub const OR: u8 = 6;
82 pub const AND: u8 = 8;
84 pub const BIT_OR: u8 = 9;
86 pub const BIT_XOR: u8 = 10;
88 pub const BIT_AND: u8 = 11;
90 pub const EQ: u8 = 12;
92 pub const CMP: u8 = 14;
94 pub const SHIFT: u8 = 16;
96 pub const ADD: u8 = 18;
98 pub const MUL: u8 = 20;
100 pub const POW: u8 = 22;
102 pub const AS_CAST: u8 = 23;
104 pub const UNARY: u8 = 24;
106 pub const POSTFIX: u8 = 26;
108}
109
110pub struct Parser {
130 tokens: Vec<Token>,
131 pos: usize,
132 pub diagnostics: DiagnosticBag,
138 allow_struct_lit: bool,
142 allow_pipe_in_type: bool,
146 loop_depth: usize,
148}
149
150type PResult<T> = Result<T, ()>;
153
154impl Parser {
155 pub fn new(tokens: Vec<Token>) -> Self {
170 Self {
171 tokens,
172 pos: 0,
173 diagnostics: DiagnosticBag::new(),
174 allow_struct_lit: true,
175 allow_pipe_in_type: true,
176 loop_depth: 0,
177 }
178 }
179
180 fn peek(&self) -> &Token {
183 self.tokens.get(self.pos).unwrap_or_else(|| self.tokens.last().unwrap())
184 }
185
186 fn peek_kind(&self) -> TokenKind {
187 self.peek().kind
188 }
189
190 fn at(&self, kind: TokenKind) -> bool {
191 self.peek_kind() == kind
192 }
193
194 fn at_eof(&self) -> bool {
195 self.at(TokenKind::Eof)
196 }
197
198 fn advance(&mut self) -> &Token {
199 let tok = &self.tokens[self.pos];
200 if self.pos + 1 < self.tokens.len() {
201 self.pos += 1;
202 }
203 tok
204 }
205
206 fn expect(&mut self, kind: TokenKind) -> PResult<Token> {
207 if self.at(kind) {
208 Ok(self.advance().clone())
209 } else {
210 let tok = self.peek().clone();
211 self.error_expected(kind.describe(), &tok);
212 Err(())
213 }
214 }
215
216 fn eat(&mut self, kind: TokenKind) -> Option<Token> {
217 if self.at(kind) {
218 Some(self.advance().clone())
219 } else {
220 None
221 }
222 }
223
224 fn current_span(&self) -> cjc_diag::Span {
225 self.peek().span
226 }
227
228 fn previous_span(&self) -> cjc_diag::Span {
229 if self.pos > 0 {
230 self.tokens[self.pos - 1].span
231 } else {
232 self.current_span()
233 }
234 }
235
236 fn error(&mut self, message: impl Into<String>, span: cjc_diag::Span) {
239 self.diagnostics
240 .emit(Diagnostic::error("E1000", message, span));
241 }
242
243 fn error_expected(&mut self, expected: &str, found: &Token) {
244 let msg = format!(
245 "expected {}, found {}",
246 expected,
247 found.kind.describe()
248 );
249 self.diagnostics.emit(
250 Diagnostic::error("E1001", msg, found.span)
251 .with_label(found.span, format!("expected {} here", expected)),
252 );
253 }
254
255 fn error_with_hint(
256 &mut self,
257 message: impl Into<String>,
258 span: cjc_diag::Span,
259 hint: impl Into<String>,
260 ) {
261 self.diagnostics.emit(
262 Diagnostic::error("E1002", message, span).with_hint(hint),
263 );
264 }
265
266 fn synchronize(&mut self) {
271 loop {
272 match self.peek_kind() {
273 TokenKind::Eof => return,
274 TokenKind::Semicolon => {
275 self.advance();
276 return;
277 }
278 TokenKind::RBrace => return,
279 TokenKind::Struct
280 | TokenKind::Class
281 | TokenKind::Record
282 | TokenKind::Fn
283 | TokenKind::Trait
284 | TokenKind::Impl
285 | TokenKind::Let
286 | TokenKind::Import
287 | TokenKind::Mod
288 | TokenKind::NoGc
289 | TokenKind::If
290 | TokenKind::While
291 | TokenKind::For
292 | TokenKind::Return => return,
293 _ => {
294 self.advance();
295 }
296 }
297 }
298 }
299
300 pub fn parse_program(mut self) -> (Program, DiagnosticBag) {
323 let mut declarations = Vec::new();
324 while !self.at_eof() {
325 let before = self.pos;
326 match self.parse_decl() {
327 Ok(decl) => declarations.push(decl),
328 Err(()) => {
329 self.synchronize();
330 if self.pos == before && !self.at_eof() {
335 self.advance();
336 }
337 }
338 }
339 }
340 (Program { declarations }, self.diagnostics)
341 }
342
343 fn parse_decl(&mut self) -> PResult<Decl> {
346 if self.peek_kind() == TokenKind::Pub {
348 return self.parse_pub_decl();
349 }
350 self.parse_decl_with_vis(Visibility::Private)
351 }
352
353 fn parse_pub_decl(&mut self) -> PResult<Decl> {
355 self.advance(); self.parse_decl_with_vis(Visibility::Public)
357 }
358
359 fn parse_decl_with_vis(&mut self, vis: Visibility) -> PResult<Decl> {
360 match self.peek_kind() {
361 TokenKind::Struct => self.parse_struct_decl_with_vis(vis),
362 TokenKind::Class => self.parse_class_decl_with_vis(vis),
363 TokenKind::Record => self.parse_record_decl_with_vis(vis),
364 TokenKind::Enum => self.parse_enum_decl(),
365 TokenKind::At => {
366 let decorators = self.parse_decorator_list()?;
367 if self.peek_kind() == TokenKind::NoGc && self.peek_ahead(1) == TokenKind::Fn {
368 self.advance(); self.parse_fn_decl_with_vis(true, decorators, vis)
370 } else {
371 self.parse_fn_decl_with_vis(false, decorators, vis)
372 }
373 }
374 TokenKind::Fn => self.parse_fn_decl_with_vis(false, vec![], vis),
375 TokenKind::NoGc if self.peek_ahead(1) == TokenKind::Fn => self.parse_nogc_fn_decl_with_vis(vis),
376 TokenKind::Trait => self.parse_trait_decl(),
377 TokenKind::Impl => self.parse_impl_decl(),
378 TokenKind::Import => self.parse_import_decl(),
379 TokenKind::Mod => self.parse_mod_decl(),
380 TokenKind::Let => self.parse_let_decl(),
381 TokenKind::Const => self.parse_const_decl(),
382 TokenKind::If => {
384 let start_span = to_ast_span(self.current_span());
385 let if_stmt = self.parse_if_stmt()?;
386 let end_span = if_stmt.then_block.span;
387 let span = merge_spans(start_span, end_span);
388 Ok(Decl {
389 kind: DeclKind::Stmt(Stmt {
390 kind: StmtKind::If(if_stmt),
391 span,
392 }),
393 span,
394 })
395 }
396 TokenKind::While => {
397 let while_stmt = self.parse_while_stmt()?;
398 let span = while_stmt.body.span;
399 Ok(Decl {
400 kind: DeclKind::Stmt(Stmt {
401 kind: StmtKind::While(while_stmt),
402 span,
403 }),
404 span,
405 })
406 }
407 TokenKind::For => {
408 let start_span = to_ast_span(self.current_span());
409 let for_stmt = self.parse_for_stmt()?;
410 let span = merge_spans(start_span, for_stmt.body.span);
411 Ok(Decl {
412 kind: DeclKind::Stmt(Stmt {
413 kind: StmtKind::For(for_stmt),
414 span,
415 }),
416 span,
417 })
418 }
419 TokenKind::NoGc if self.peek_ahead(1) == TokenKind::LBrace => {
420 let nogc_start = self.advance().span;
421 let block = self.parse_block()?;
422 let span = merge_spans(to_ast_span(nogc_start), block.span);
423 Ok(Decl {
424 kind: DeclKind::Stmt(Stmt {
425 kind: StmtKind::NoGcBlock(block),
426 span,
427 }),
428 span,
429 })
430 }
431 _ => {
432 let expr = self.parse_expr()?;
434 let span = expr.span;
435 self.expect(TokenKind::Semicolon)?;
436 Ok(Decl {
437 kind: DeclKind::Stmt(Stmt {
438 kind: StmtKind::Expr(expr),
439 span,
440 }),
441 span,
442 })
443 }
444 }
445 }
446
447 fn peek_ahead(&self, offset: usize) -> TokenKind {
448 self.tokens
449 .get(self.pos + offset)
450 .map(|t| t.kind)
451 .unwrap_or(TokenKind::Eof)
452 }
453
454 fn parse_struct_decl_with_vis(&mut self, vis: Visibility) -> PResult<Decl> {
457 let start = self.expect(TokenKind::Struct)?.span;
458 let name = self.parse_ident()?;
459 let type_params = self.parse_optional_type_params()?;
460 self.expect(TokenKind::LBrace)?;
461 let fields = self.parse_field_list()?;
462 let end = self.expect(TokenKind::RBrace)?.span;
463 Ok(Decl {
464 kind: DeclKind::Struct(StructDecl {
465 name,
466 type_params,
467 fields,
468 vis,
469 }),
470 span: to_ast_span(start.merge(end)),
471 })
472 }
473
474 fn parse_class_decl_with_vis(&mut self, vis: Visibility) -> PResult<Decl> {
477 let start = self.expect(TokenKind::Class)?.span;
478 let name = self.parse_ident()?;
479 let type_params = self.parse_optional_type_params()?;
480 self.expect(TokenKind::LBrace)?;
481 let fields = self.parse_field_list()?;
482 let end = self.expect(TokenKind::RBrace)?.span;
483 Ok(Decl {
484 kind: DeclKind::Class(ClassDecl {
485 name,
486 type_params,
487 fields,
488 vis,
489 }),
490 span: to_ast_span(start.merge(end)),
491 })
492 }
493
494 fn parse_record_decl_with_vis(&mut self, vis: Visibility) -> PResult<Decl> {
497 let start = self.expect(TokenKind::Record)?.span;
498 let name = self.parse_ident()?;
499 let type_params = self.parse_optional_type_params()?;
500 self.expect(TokenKind::LBrace)?;
501 let fields = self.parse_field_list()?;
502 let end = self.expect(TokenKind::RBrace)?.span;
503 Ok(Decl {
504 kind: DeclKind::Record(RecordDecl {
505 name,
506 type_params,
507 fields,
508 vis,
509 }),
510 span: to_ast_span(start.merge(end)),
511 })
512 }
513
514 fn parse_enum_decl(&mut self) -> PResult<Decl> {
517 let start = self.expect(TokenKind::Enum)?.span;
518 let name = self.parse_ident()?;
519 let type_params = self.parse_optional_type_params()?;
520 self.expect(TokenKind::LBrace)?;
521 let mut variants = Vec::new();
522 while !self.at(TokenKind::RBrace) && !self.at_eof() {
523 let variant = self.parse_variant_decl()?;
524 variants.push(variant);
525 self.eat(TokenKind::Comma);
527 }
528 let end = self.expect(TokenKind::RBrace)?.span;
529 Ok(Decl {
530 kind: DeclKind::Enum(EnumDecl {
531 name,
532 type_params,
533 variants,
534 }),
535 span: to_ast_span(start.merge(end)),
536 })
537 }
538
539 fn parse_variant_decl(&mut self) -> PResult<VariantDecl> {
540 let name = self.parse_ident()?;
541 let start_span = name.span;
542 let mut fields = Vec::new();
543 let end_span;
544 if self.eat(TokenKind::LParen).is_some() {
545 if !self.at(TokenKind::RParen) {
547 loop {
548 fields.push(self.parse_type_expr()?);
549 if self.eat(TokenKind::Comma).is_none() {
550 break;
551 }
552 if self.at(TokenKind::RParen) {
553 break;
554 }
555 }
556 }
557 let rparen = self.expect(TokenKind::RParen)?;
558 end_span = to_ast_span(rparen.span);
559 } else {
560 end_span = start_span;
562 }
563 Ok(VariantDecl {
564 name,
565 fields,
566 span: merge_spans(start_span, end_span),
567 })
568 }
569
570 fn parse_field_list(&mut self) -> PResult<Vec<FieldDecl>> {
573 let mut fields = Vec::new();
574 while !self.at(TokenKind::RBrace) && !self.at_eof() {
575 let field = self.parse_field_decl()?;
576 fields.push(field);
577 self.eat(TokenKind::Comma);
579 }
580 Ok(fields)
581 }
582
583 fn parse_field_decl(&mut self) -> PResult<FieldDecl> {
584 let vis = if self.eat(TokenKind::Pub).is_some() {
586 Visibility::Public
587 } else {
588 Visibility::Private
589 };
590 let name = self.parse_ident()?;
591 self.expect(TokenKind::Colon)?;
592 let ty = self.parse_type_expr()?;
593 let default = if self.eat(TokenKind::Eq).is_some() {
594 Some(self.parse_expr()?)
595 } else {
596 None
597 };
598 let span = merge_spans(name.span, if let Some(ref d) = default { d.span } else { ty.span });
599 Ok(FieldDecl {
600 name,
601 ty,
602 default,
603 vis,
604 span,
605 })
606 }
607
608 fn parse_fn_decl_with_vis(&mut self, is_nogc: bool, decorators: Vec<cjc_ast::Decorator>, vis: Visibility) -> PResult<Decl> {
611 let start = self.expect(TokenKind::Fn)?.span;
612 let name = self.parse_ident()?;
613 let type_params = self.parse_optional_type_params()?;
614 self.expect(TokenKind::LParen)?;
615 let params = self.parse_param_list()?;
616 self.expect(TokenKind::RParen)?;
617 let return_type = if self.eat(TokenKind::Arrow).is_some() {
618 Some(self.parse_type_expr()?)
619 } else {
620 None
621 };
622 let effect_annotation = self.parse_effect_annotation()?;
623 let body = self.parse_block()?;
624 let span = merge_spans(to_ast_span(start), body.span);
625 Ok(Decl {
626 kind: DeclKind::Fn(FnDecl {
627 name,
628 type_params,
629 params,
630 return_type,
631 body,
632 is_nogc,
633 effect_annotation,
634 decorators,
635 vis,
636 }),
637 span,
638 })
639 }
640
641 fn parse_nogc_fn_decl_with_vis(&mut self, vis: Visibility) -> PResult<Decl> {
642 self.advance(); self.parse_fn_decl_with_vis(true, vec![], vis)
644 }
645
646 fn parse_decorator_list(&mut self) -> PResult<Vec<cjc_ast::Decorator>> {
648 let mut decorators = Vec::new();
649 while self.at(TokenKind::At) {
650 let at_span = self.expect(TokenKind::At)?.span;
651 let name = self.parse_ident()?;
652 let args = if self.eat(TokenKind::LParen).is_some() {
653 let mut args = Vec::new();
654 while !self.at(TokenKind::RParen) && !self.at(TokenKind::Eof) {
655 args.push(self.parse_expr()?);
656 if !self.at(TokenKind::RParen) {
657 self.expect(TokenKind::Comma)?;
658 }
659 }
660 self.expect(TokenKind::RParen)?;
661 args
662 } else {
663 vec![]
664 };
665 let span = merge_spans(to_ast_span(at_span), name.span);
666 decorators.push(cjc_ast::Decorator { name, args, span });
667 }
668 Ok(decorators)
669 }
670
671 fn parse_effect_annotation(&mut self) -> PResult<Option<Vec<String>>> {
676 if self.eat(TokenKind::Slash).is_none() {
677 return Ok(None);
678 }
679 let mut effects = Vec::new();
680 let ident = self.parse_ident()?;
682 effects.push(ident.name);
683 while self.eat(TokenKind::Plus).is_some() {
685 let ident = self.parse_ident()?;
686 effects.push(ident.name);
687 }
688 Ok(Some(effects))
689 }
690
691 fn parse_param_list(&mut self) -> PResult<Vec<Param>> {
692 let mut params = Vec::new();
693 if self.at(TokenKind::RParen) {
694 return Ok(params);
695 }
696 loop {
697 let param = self.parse_param()?;
698 let is_variadic = param.is_variadic;
699 params.push(param);
700 if is_variadic {
701 break;
703 }
704 if self.eat(TokenKind::Comma).is_none() {
705 break;
706 }
707 if self.at(TokenKind::RParen) {
709 break;
710 }
711 }
712 Ok(params)
713 }
714
715 fn parse_param(&mut self) -> PResult<Param> {
716 let is_variadic = self.eat(TokenKind::DotDotDot).is_some();
718 let name = self.parse_ident()?;
719 self.expect(TokenKind::Colon)?;
720 let ty = self.parse_type_expr()?;
721 let default = if self.eat(TokenKind::Eq).is_some() {
723 if is_variadic {
724 self.error("variadic parameters cannot have default values", self.current_span());
725 return Err(());
726 }
727 Some(self.parse_expr()?)
728 } else {
729 None
730 };
731 let end_span = default.as_ref().map(|d| d.span).unwrap_or(ty.span);
732 let span = merge_spans(name.span, end_span);
733 Ok(Param { name, ty, default, is_variadic, span })
734 }
735
736 fn parse_trait_decl(&mut self) -> PResult<Decl> {
739 let start = self.expect(TokenKind::Trait)?.span;
740 let name = self.parse_ident()?;
741 let type_params = self.parse_optional_type_params()?;
742 let super_traits = if self.eat(TokenKind::Colon).is_some() {
743 self.parse_trait_bound_list()?
744 } else {
745 Vec::new()
746 };
747 self.expect(TokenKind::LBrace)?;
748 let mut methods = Vec::new();
749 while !self.at(TokenKind::RBrace) && !self.at_eof() {
750 let sig = self.parse_fn_sig()?;
751 self.expect(TokenKind::Semicolon)?;
752 methods.push(sig);
753 }
754 let end = self.expect(TokenKind::RBrace)?.span;
755 Ok(Decl {
756 kind: DeclKind::Trait(TraitDecl {
757 name,
758 type_params,
759 super_traits,
760 methods,
761 }),
762 span: to_ast_span(start.merge(end)),
763 })
764 }
765
766 fn parse_fn_sig(&mut self) -> PResult<FnSig> {
767 let start = self.expect(TokenKind::Fn)?.span;
768 let name = self.parse_ident()?;
769 let type_params = self.parse_optional_type_params()?;
770 self.expect(TokenKind::LParen)?;
771 let params = self.parse_param_list()?;
772 let end_paren = self.expect(TokenKind::RParen)?.span;
773 let return_type = if self.eat(TokenKind::Arrow).is_some() {
774 Some(self.parse_type_expr()?)
775 } else {
776 None
777 };
778 let end = return_type
779 .as_ref()
780 .map(|t| to_diag_span(t.span))
781 .unwrap_or(end_paren);
782 Ok(FnSig {
783 name,
784 type_params,
785 params,
786 return_type,
787 span: to_ast_span(start.merge(end)),
788 })
789 }
790
791 fn parse_trait_bound_list(&mut self) -> PResult<Vec<TypeExpr>> {
792 let mut bounds = Vec::new();
793 bounds.push(self.parse_type_expr()?);
794 while self.eat(TokenKind::Plus).is_some() {
795 bounds.push(self.parse_type_expr()?);
796 }
797 Ok(bounds)
798 }
799
800 fn parse_impl_decl(&mut self) -> PResult<Decl> {
803 let start = self.expect(TokenKind::Impl)?.span;
804 let type_params = self.parse_optional_type_params()?;
805 let first_type = self.parse_type_expr()?;
806
807 let (target, trait_ref) = if self.eat(TokenKind::For).is_some() {
811 let concrete = self.parse_type_expr()?;
813 (concrete, Some(first_type))
814 } else if self.eat(TokenKind::Colon).is_some() {
815 (first_type, Some(self.parse_type_expr()?))
817 } else {
818 (first_type, None)
820 };
821 self.expect(TokenKind::LBrace)?;
822 let mut methods = Vec::new();
823 while !self.at(TokenKind::RBrace) && !self.at_eof() {
824 let is_nogc = if self.at(TokenKind::NoGc) && self.peek_ahead(1) == TokenKind::Fn {
825 self.advance();
826 true
827 } else {
828 false
829 };
830 let fn_start = self.expect(TokenKind::Fn)?.span;
831 let name = self.parse_ident()?;
832 let fn_type_params = self.parse_optional_type_params()?;
833 self.expect(TokenKind::LParen)?;
834 let params = self.parse_param_list()?;
835 self.expect(TokenKind::RParen)?;
836 let return_type = if self.eat(TokenKind::Arrow).is_some() {
837 Some(self.parse_type_expr()?)
838 } else {
839 None
840 };
841 let effect_annotation = self.parse_effect_annotation()?;
842 let body = self.parse_block()?;
843 let fn_span = merge_spans(to_ast_span(fn_start), body.span);
844 methods.push(FnDecl {
845 name,
846 type_params: fn_type_params,
847 params,
848 return_type,
849 body,
850 is_nogc,
851 effect_annotation,
852 decorators: vec![],
853 vis: Visibility::Private,
854 });
855 let _ = fn_span; }
857 let end = self.expect(TokenKind::RBrace)?.span;
858 Ok(Decl {
859 kind: DeclKind::Impl(ImplDecl {
860 type_params,
861 target,
862 trait_ref,
863 methods,
864 span: to_ast_span(start.merge(end)),
865 }),
866 span: to_ast_span(start.merge(end)),
867 })
868 }
869
870 fn parse_import_decl(&mut self) -> PResult<Decl> {
873 let start = self.expect(TokenKind::Import)?.span;
874 let mut path = Vec::new();
875 path.push(self.parse_ident()?);
876 while self.eat(TokenKind::Dot).is_some() {
877 path.push(self.parse_ident()?);
878 }
879 let alias = if self.eat(TokenKind::As).is_some() {
880 Some(self.parse_ident()?)
881 } else {
882 None
883 };
884 let end_span = alias
885 .as_ref()
886 .map(|a| to_diag_span(a.span))
887 .or_else(|| path.last().map(|p| to_diag_span(p.span)))
888 .unwrap_or(start);
889 Ok(Decl {
890 kind: DeclKind::Import(ImportDecl { path, alias }),
891 span: to_ast_span(start.merge(end_span)),
892 })
893 }
894
895 fn parse_mod_decl(&mut self) -> PResult<Decl> {
897 let start = self.expect(TokenKind::Mod)?.span;
898 let name = self.parse_ident()?;
899 let end_span = to_diag_span(name.span);
900 Ok(Decl {
902 kind: DeclKind::Import(ImportDecl {
903 path: vec![name],
904 alias: None,
905 }),
906 span: to_ast_span(start.merge(end_span)),
907 })
908 }
909
910 fn parse_let_decl(&mut self) -> PResult<Decl> {
913 let start = self.current_span();
914 let let_stmt = self.parse_let_stmt()?;
915 self.expect(TokenKind::Semicolon)?;
916 let end = self.previous_span();
917 Ok(Decl {
918 kind: DeclKind::Let(let_stmt),
919 span: to_ast_span(start.merge(end)),
920 })
921 }
922
923 fn parse_const_decl(&mut self) -> PResult<Decl> {
925 let start = self.expect(TokenKind::Const)?.span;
926 let name = self.parse_ident()?;
927 self.expect(TokenKind::Colon)?;
928 let ty = self.parse_type_expr()?;
929 self.expect(TokenKind::Eq)?;
930 let value = self.parse_expr()?;
931 let end = self.expect(TokenKind::Semicolon)?.span;
932 let span = to_ast_span(start.merge(end));
933 Ok(Decl {
934 kind: DeclKind::Const(ConstDecl {
935 name,
936 ty,
937 value: Box::new(value),
938 span,
939 }),
940 span,
941 })
942 }
943
944 fn parse_fstring_segments(
950 &self,
951 raw: &str,
952 _span: cjc_ast::Span,
953 ) -> PResult<Vec<(String, Option<Box<Expr>>)>> {
954 let mut segments: Vec<(String, Option<Box<Expr>>)> = Vec::new();
955 let bytes = raw.as_bytes();
956 let mut i = 0;
957 let mut literal = String::new();
958
959 while i < bytes.len() {
960 if bytes[i] == b'{' {
961 let mut depth = 1usize;
963 let hole_start = i + 1;
964 let mut j = hole_start;
965 while j < bytes.len() && depth > 0 {
966 if bytes[j] == b'{' {
967 depth += 1;
968 } else if bytes[j] == b'}' {
969 depth -= 1;
970 }
971 j += 1;
972 }
973 let hole_end = j - 1; let expr_src = &raw[hole_start..hole_end];
975
976 let lexer = cjc_lexer::Lexer::new(expr_src);
978 let (tokens, _lex_diags) = lexer.tokenize();
979 let mut sub_parser = Parser::new(tokens);
980 let interp_expr = sub_parser.parse_expr().map_err(|_| ())?;
981 segments.push((literal.clone(), Some(Box::new(interp_expr))));
982 literal.clear();
983 i = j; } else {
985 literal.push(bytes[i] as char);
986 i += 1;
987 }
988 }
989
990 segments.push((literal, None));
992 Ok(segments)
993 }
994
995 fn parse_let_stmt(&mut self) -> PResult<LetStmt> {
996 self.expect(TokenKind::Let)?;
997 let mutable = self.eat(TokenKind::Mut).is_some();
998 let name = self.parse_ident()?;
999 let ty = if self.eat(TokenKind::Colon).is_some() {
1000 Some(self.parse_type_expr()?)
1001 } else {
1002 None
1003 };
1004 self.expect(TokenKind::Eq)?;
1005 let init = self.parse_expr()?;
1006 Ok(LetStmt {
1007 name,
1008 mutable,
1009 ty,
1010 init: Box::new(init),
1011 })
1012 }
1013
1014 fn parse_type_expr(&mut self) -> PResult<TypeExpr> {
1017 let base = match self.peek_kind() {
1018 TokenKind::Ident => self.parse_named_type()?,
1019 TokenKind::LParen => self.parse_tuple_type()?,
1020 TokenKind::LBracket => self.parse_array_or_shape_type()?,
1021 TokenKind::Fn => self.parse_fn_type()?,
1022 _ => {
1023 let tok = self.peek().clone();
1024 self.error(
1025 format!("expected type, found {}", tok.kind.describe()),
1026 tok.span,
1027 );
1028 return Err(());
1029 }
1030 };
1031
1032 if self.allow_pipe_in_type && self.at(TokenKind::Pipe) {
1035 let pipe_span = self.advance().span;
1036 if self.at(TokenKind::Null) {
1037 let null_tok = self.advance();
1038 let base_span = base.span;
1039 let end_span = to_ast_span(null_tok.span);
1040 let option_name = cjc_ast::Ident::new("Option", base_span);
1041 return Ok(TypeExpr {
1042 kind: TypeExprKind::Named {
1043 name: option_name,
1044 args: vec![TypeArg::Type(base)],
1045 },
1046 span: merge_spans(base_span, end_span),
1047 });
1048 } else {
1049 let tok = self.peek().clone();
1050 self.error(
1051 format!(
1052 "expected `null` after `|` in type expression (full union types are not yet supported), found {}",
1053 tok.kind.describe()
1054 ),
1055 pipe_span,
1056 );
1057 return Err(());
1058 }
1059 }
1060
1061 Ok(base)
1062 }
1063
1064 fn parse_named_type(&mut self) -> PResult<TypeExpr> {
1065 let name = self.parse_ident()?;
1066 let start_span = name.span;
1067 let args = if self.at(TokenKind::Lt) {
1068 self.parse_type_arg_list()?
1069 } else {
1070 Vec::new()
1071 };
1072 let end_span = if args.is_empty() {
1073 start_span
1074 } else {
1075 to_ast_span(self.previous_span())
1077 };
1078 Ok(TypeExpr {
1079 kind: TypeExprKind::Named { name, args },
1080 span: merge_spans(start_span, end_span),
1081 })
1082 }
1083
1084 fn parse_type_arg_list(&mut self) -> PResult<Vec<TypeArg>> {
1085 self.expect(TokenKind::Lt)?;
1086 let mut args = Vec::new();
1087 if !self.at(TokenKind::Gt) {
1088 loop {
1089 let arg = self.parse_type_arg()?;
1090 args.push(arg);
1091 if self.eat(TokenKind::Comma).is_none() {
1092 break;
1093 }
1094 if self.at(TokenKind::Gt) {
1095 break;
1096 }
1097 }
1098 }
1099 self.expect(TokenKind::Gt)?;
1100 Ok(args)
1101 }
1102
1103 fn parse_type_arg(&mut self) -> PResult<TypeArg> {
1104 match self.peek_kind() {
1107 TokenKind::LBracket => {
1108 let dims = self.parse_shape_dims()?;
1109 Ok(TypeArg::Shape(dims))
1110 }
1111 TokenKind::IntLit => {
1112 let expr = self.parse_expr()?;
1113 Ok(TypeArg::Expr(expr))
1114 }
1115 _ => {
1116 let ty = self.parse_type_expr()?;
1117 Ok(TypeArg::Type(ty))
1118 }
1119 }
1120 }
1121
1122 fn parse_shape_dims(&mut self) -> PResult<Vec<ShapeDim>> {
1123 self.expect(TokenKind::LBracket)?;
1124 let mut dims = Vec::new();
1125 if !self.at(TokenKind::RBracket) {
1126 loop {
1127 let dim = match self.peek_kind() {
1128 TokenKind::IntLit => {
1129 let tok = self.advance().clone();
1130 ShapeDim::Lit(tok.int_value())
1131 }
1132 TokenKind::Ident => {
1133 let ident = self.parse_ident()?;
1134 ShapeDim::Name(ident)
1135 }
1136 _ => {
1137 let tok = self.peek().clone();
1138 self.error(
1139 format!(
1140 "expected shape dimension (integer or name), found {}",
1141 tok.kind.describe()
1142 ),
1143 tok.span,
1144 );
1145 return Err(());
1146 }
1147 };
1148 dims.push(dim);
1149 if self.eat(TokenKind::Comma).is_none() {
1150 break;
1151 }
1152 }
1153 }
1154 self.expect(TokenKind::RBracket)?;
1155 Ok(dims)
1156 }
1157
1158 fn parse_tuple_type(&mut self) -> PResult<TypeExpr> {
1159 let start = self.expect(TokenKind::LParen)?.span;
1160 let mut elems = Vec::new();
1161 if !self.at(TokenKind::RParen) {
1162 loop {
1163 elems.push(self.parse_type_expr()?);
1164 if self.eat(TokenKind::Comma).is_none() {
1165 break;
1166 }
1167 if self.at(TokenKind::RParen) {
1168 break;
1169 }
1170 }
1171 }
1172 let end = self.expect(TokenKind::RParen)?.span;
1173 Ok(TypeExpr {
1174 kind: TypeExprKind::Tuple(elems),
1175 span: to_ast_span(start.merge(end)),
1176 })
1177 }
1178
1179 fn parse_array_or_shape_type(&mut self) -> PResult<TypeExpr> {
1180 let start = self.expect(TokenKind::LBracket)?.span;
1184
1185 let saved_pos = self.pos;
1188 let saved_diag_len = self.diagnostics.diagnostics.len();
1189
1190 if let Ok(elem_ty) = self.parse_type_expr() {
1191 if self.eat(TokenKind::Semicolon).is_some() {
1192 let size = self.parse_expr()?;
1194 let end = self.expect(TokenKind::RBracket)?.span;
1195 return Ok(TypeExpr {
1196 kind: TypeExprKind::Array {
1197 elem: Box::new(elem_ty),
1198 size: Box::new(size),
1199 },
1200 span: to_ast_span(start.merge(end)),
1201 });
1202 }
1203 }
1204
1205 self.pos = saved_pos;
1207 self.diagnostics.diagnostics.truncate(saved_diag_len);
1208
1209 let mut dims = Vec::new();
1210 if !self.at(TokenKind::RBracket) {
1211 loop {
1212 let dim = match self.peek_kind() {
1213 TokenKind::IntLit => {
1214 let tok = self.advance().clone();
1215 ShapeDim::Lit(tok.int_value())
1216 }
1217 TokenKind::Ident => {
1218 let ident = self.parse_ident()?;
1219 ShapeDim::Name(ident)
1220 }
1221 _ => {
1222 let tok = self.peek().clone();
1223 self.error(
1224 format!(
1225 "expected shape dimension, found {}",
1226 tok.kind.describe()
1227 ),
1228 tok.span,
1229 );
1230 return Err(());
1231 }
1232 };
1233 dims.push(dim);
1234 if self.eat(TokenKind::Comma).is_none() {
1235 break;
1236 }
1237 }
1238 }
1239 let end = self.expect(TokenKind::RBracket)?.span;
1240 Ok(TypeExpr {
1241 kind: TypeExprKind::ShapeLit(dims),
1242 span: to_ast_span(start.merge(end)),
1243 })
1244 }
1245
1246 fn parse_fn_type(&mut self) -> PResult<TypeExpr> {
1247 let start = self.expect(TokenKind::Fn)?.span;
1248 self.expect(TokenKind::LParen)?;
1249 let mut params = Vec::new();
1250 if !self.at(TokenKind::RParen) {
1251 loop {
1252 params.push(self.parse_type_expr()?);
1253 if self.eat(TokenKind::Comma).is_none() {
1254 break;
1255 }
1256 if self.at(TokenKind::RParen) {
1257 break;
1258 }
1259 }
1260 }
1261 self.expect(TokenKind::RParen)?;
1262 self.expect(TokenKind::Arrow)?;
1263 let ret = self.parse_type_expr()?;
1264 let end_span = ret.span;
1265 Ok(TypeExpr {
1266 kind: TypeExprKind::Fn {
1267 params,
1268 ret: Box::new(ret),
1269 },
1270 span: merge_spans(to_ast_span(start), end_span),
1271 })
1272 }
1273
1274 fn parse_optional_type_params(&mut self) -> PResult<Vec<TypeParam>> {
1277 if !self.at(TokenKind::Lt) {
1278 return Ok(Vec::new());
1279 }
1280 self.expect(TokenKind::Lt)?;
1281 let mut params = Vec::new();
1282 if !self.at(TokenKind::Gt) {
1283 loop {
1284 let param = self.parse_type_param()?;
1285 params.push(param);
1286 if self.eat(TokenKind::Comma).is_none() {
1287 break;
1288 }
1289 if self.at(TokenKind::Gt) {
1290 break;
1291 }
1292 }
1293 }
1294 self.expect(TokenKind::Gt)?;
1295 Ok(params)
1296 }
1297
1298 fn parse_type_param(&mut self) -> PResult<TypeParam> {
1299 let name = self.parse_ident()?;
1300 let start_span = name.span;
1301 let bounds = if self.eat(TokenKind::Colon).is_some() {
1302 self.parse_trait_bound_list()?
1303 } else {
1304 Vec::new()
1305 };
1306 let end_span = bounds
1307 .last()
1308 .map(|b| b.span)
1309 .unwrap_or(start_span);
1310 Ok(TypeParam {
1311 name,
1312 bounds,
1313 span: merge_spans(start_span, end_span),
1314 })
1315 }
1316
1317 fn parse_block(&mut self) -> PResult<Block> {
1320 let start = self.expect(TokenKind::LBrace)?.span;
1321 let mut stmts = Vec::new();
1322 let mut tail_expr: Option<Box<Expr>> = None;
1323
1324 while !self.at(TokenKind::RBrace) && !self.at_eof() {
1325 match self.peek_kind() {
1329 TokenKind::Let => {
1330 let let_stmt = self.parse_let_stmt()?;
1331 self.expect(TokenKind::Semicolon)?;
1332 let span = merge_spans(
1333 let_stmt.name.span,
1334 let_stmt.init.span,
1335 );
1336 stmts.push(Stmt {
1337 kind: StmtKind::Let(let_stmt),
1338 span,
1339 });
1340 }
1341 TokenKind::Return => {
1342 let ret_start = self.advance().span;
1343 let value = if !self.at(TokenKind::Semicolon)
1344 && !self.at(TokenKind::RBrace)
1345 && !self.at_eof()
1346 {
1347 Some(self.parse_expr()?)
1348 } else {
1349 None
1350 };
1351 let end = self.expect(TokenKind::Semicolon)?.span;
1352 stmts.push(Stmt {
1353 kind: StmtKind::Return(value),
1354 span: to_ast_span(ret_start.merge(end)),
1355 });
1356 }
1357 TokenKind::Break => {
1358 let brk_start = self.advance().span;
1359 if self.loop_depth == 0 {
1360 self.diagnostics.emit(Diagnostic::error(
1361 "E0400",
1362 "`break` outside of loop",
1363 brk_start,
1364 ));
1365 }
1366 let end = self.expect(TokenKind::Semicolon)?.span;
1367 stmts.push(Stmt {
1368 kind: StmtKind::Break,
1369 span: to_ast_span(brk_start.merge(end)),
1370 });
1371 }
1372 TokenKind::Continue => {
1373 let cont_start = self.advance().span;
1374 if self.loop_depth == 0 {
1375 self.diagnostics.emit(Diagnostic::error(
1376 "E0401",
1377 "`continue` outside of loop",
1378 cont_start,
1379 ));
1380 }
1381 let end = self.expect(TokenKind::Semicolon)?.span;
1382 stmts.push(Stmt {
1383 kind: StmtKind::Continue,
1384 span: to_ast_span(cont_start.merge(end)),
1385 });
1386 }
1387 TokenKind::If => {
1388 let if_start_span = to_ast_span(self.current_span());
1389 let if_stmt = self.parse_if_stmt()?;
1390 let if_end_span = if_stmt.then_block.span;
1391 stmts.push(Stmt {
1392 kind: StmtKind::If(if_stmt),
1393 span: merge_spans(if_start_span, if_end_span),
1394 });
1395 }
1396 TokenKind::While => {
1397 let while_stmt = self.parse_while_stmt()?;
1398 let span = while_stmt.body.span;
1399 stmts.push(Stmt {
1400 kind: StmtKind::While(while_stmt),
1401 span,
1402 });
1403 }
1404 TokenKind::For => {
1405 let for_start_span = to_ast_span(self.current_span());
1406 let for_stmt = self.parse_for_stmt()?;
1407 let span = merge_spans(for_start_span, for_stmt.body.span);
1408 stmts.push(Stmt {
1409 kind: StmtKind::For(for_stmt),
1410 span,
1411 });
1412 }
1413 TokenKind::NoGc if self.peek_ahead(1) == TokenKind::LBrace => {
1414 let nogc_start = self.advance().span;
1415 let block = self.parse_block()?;
1416 let span = merge_spans(to_ast_span(nogc_start), block.span);
1417 stmts.push(Stmt {
1418 kind: StmtKind::NoGcBlock(block),
1419 span,
1420 });
1421 }
1422 _ => {
1423 let expr = self.parse_expr()?;
1425 if self.eat(TokenKind::Semicolon).is_some() {
1426 let span = expr.span;
1427 stmts.push(Stmt {
1428 kind: StmtKind::Expr(expr),
1429 span,
1430 });
1431 } else if self.at(TokenKind::RBrace) {
1432 tail_expr = Some(Box::new(expr));
1434 } else {
1435 let span = expr.span;
1437 self.error_with_hint(
1438 "expected `;` after expression statement",
1439 to_diag_span(span),
1440 "add a `;` here",
1441 );
1442 stmts.push(Stmt {
1443 kind: StmtKind::Expr(expr),
1444 span,
1445 });
1446 }
1447 }
1448 }
1449 }
1450 let end = self.expect(TokenKind::RBrace)?.span;
1451 Ok(Block {
1452 stmts,
1453 expr: tail_expr,
1454 span: to_ast_span(start.merge(end)),
1455 })
1456 }
1457
1458 fn parse_if_stmt(&mut self) -> PResult<IfStmt> {
1461 self.expect(TokenKind::If)?;
1462 let prev = self.allow_struct_lit;
1465 self.allow_struct_lit = false;
1466 let condition = self.parse_expr();
1467 self.allow_struct_lit = prev;
1468 let condition = condition?;
1469 let then_block = self.parse_block()?;
1470 let else_branch = if self.eat(TokenKind::Else).is_some() {
1471 if self.at(TokenKind::If) {
1472 Some(ElseBranch::ElseIf(Box::new(self.parse_if_stmt()?)))
1473 } else {
1474 Some(ElseBranch::Else(self.parse_block()?))
1475 }
1476 } else {
1477 None
1478 };
1479 Ok(IfStmt {
1480 condition,
1481 then_block,
1482 else_branch,
1483 })
1484 }
1485
1486 fn parse_while_stmt(&mut self) -> PResult<WhileStmt> {
1487 self.expect(TokenKind::While)?;
1488 let prev = self.allow_struct_lit;
1491 self.allow_struct_lit = false;
1492 let condition = self.parse_expr();
1493 self.allow_struct_lit = prev;
1494 let condition = condition?;
1495 self.loop_depth += 1;
1496 let body = self.parse_block()?;
1497 self.loop_depth -= 1;
1498 Ok(WhileStmt { condition, body })
1499 }
1500
1501 fn parse_for_stmt(&mut self) -> PResult<ForStmt> {
1502 self.expect(TokenKind::For)?;
1503 let ident = self.parse_ident()?;
1504 self.expect(TokenKind::In)?;
1505
1506 let prev = self.allow_struct_lit;
1513 self.allow_struct_lit = false;
1514 let start_expr = self.parse_expr_bp(prec::CMP + 1)?;
1515 let iter = if self.eat(TokenKind::DotDot).is_some() {
1516 let end_expr = self.parse_expr_bp(prec::CMP + 1)?;
1517 ForIter::Range {
1518 start: Box::new(start_expr),
1519 end: Box::new(end_expr),
1520 }
1521 } else {
1522 ForIter::Expr(Box::new(start_expr))
1523 };
1524 self.allow_struct_lit = prev;
1525
1526 self.loop_depth += 1;
1527 let body = self.parse_block()?;
1528 self.loop_depth -= 1;
1529 Ok(ForStmt { ident, iter, body })
1530 }
1531
1532 fn parse_expr(&mut self) -> PResult<Expr> {
1535 self.parse_expr_bp(0)
1536 }
1537
1538 fn parse_expr_bp(&mut self, min_bp: u8) -> PResult<Expr> {
1540 let mut lhs = self.parse_prefix()?;
1542
1543 loop {
1545 let (op_info, is_postfix) = match self.peek_kind() {
1546 TokenKind::Dot => (Some((prec::POSTFIX, prec::POSTFIX + 1)), true),
1548 TokenKind::LParen => (Some((prec::POSTFIX, prec::POSTFIX + 1)), true),
1549 TokenKind::LBracket => (Some((prec::POSTFIX, prec::POSTFIX + 1)), true),
1550 TokenKind::Question => (Some((prec::POSTFIX, prec::POSTFIX + 1)), true),
1551
1552 TokenKind::LBrace => {
1558 if self.allow_struct_lit && matches!(lhs.kind, ExprKind::Ident(_)) {
1564 (Some((prec::POSTFIX, prec::POSTFIX + 1)), true)
1565 } else {
1566 break;
1567 }
1568 }
1569
1570 TokenKind::Eq => {
1572 let (l_bp, r_bp) = (prec::ASSIGN, prec::ASSIGN);
1573 (Some((l_bp, r_bp)), false)
1574 }
1575
1576 TokenKind::PlusEq | TokenKind::MinusEq | TokenKind::StarEq
1578 | TokenKind::SlashEq | TokenKind::PercentEq | TokenKind::StarStarEq
1579 | TokenKind::AmpEq | TokenKind::PipeEq | TokenKind::CaretEq
1580 | TokenKind::LtLtEq | TokenKind::GtGtEq => {
1581 (Some((prec::ASSIGN, prec::ASSIGN)), false)
1582 }
1583
1584 TokenKind::PipeGt => {
1586 let (l_bp, r_bp) = (prec::PIPE, prec::PIPE + 1);
1587 (Some((l_bp, r_bp)), false)
1588 }
1589
1590 TokenKind::PipePipe => (Some((prec::OR, prec::OR + 1)), false),
1592 TokenKind::AmpAmp => (Some((prec::AND, prec::AND + 1)), false),
1593 TokenKind::Pipe => (Some((prec::BIT_OR, prec::BIT_OR + 1)), false),
1595 TokenKind::Caret => (Some((prec::BIT_XOR, prec::BIT_XOR + 1)), false),
1596 TokenKind::Amp => (Some((prec::BIT_AND, prec::BIT_AND + 1)), false),
1597 TokenKind::EqEq | TokenKind::BangEq => (Some((prec::EQ, prec::EQ + 1)), false),
1598 TokenKind::TildeEq | TokenKind::BangTilde => (Some((prec::EQ, prec::EQ + 1)), false),
1599 TokenKind::Lt | TokenKind::Gt | TokenKind::LtEq | TokenKind::GtEq => {
1600 (Some((prec::CMP, prec::CMP + 1)), false)
1601 }
1602 TokenKind::LtLt | TokenKind::GtGt => (Some((prec::SHIFT, prec::SHIFT + 1)), false),
1604 TokenKind::Plus | TokenKind::Minus => (Some((prec::ADD, prec::ADD + 1)), false),
1605 TokenKind::Star | TokenKind::Slash | TokenKind::Percent => {
1606 (Some((prec::MUL, prec::MUL + 1)), false)
1607 }
1608 TokenKind::StarStar => (Some((prec::POW, prec::POW)), false),
1610
1611 TokenKind::As => (Some((prec::AS_CAST, prec::AS_CAST + 1)), false),
1613
1614 _ => break,
1615 };
1616
1617 let (l_bp, r_bp) = match op_info {
1618 Some(bp) => bp,
1619 None => break,
1620 };
1621
1622 if l_bp < min_bp {
1623 break;
1624 }
1625
1626 if is_postfix {
1627 lhs = self.parse_postfix(lhs)?;
1628 } else {
1629 lhs = self.parse_infix(lhs, r_bp)?;
1630 }
1631 }
1632
1633 Ok(lhs)
1634 }
1635
1636 fn parse_prefix(&mut self) -> PResult<Expr> {
1638 match self.peek_kind() {
1639 TokenKind::Minus => {
1641 let op_tok = self.advance().clone();
1642 let operand = self.parse_expr_bp(prec::UNARY)?;
1643 let span = merge_spans(to_ast_span(op_tok.span), operand.span);
1644 Ok(Expr {
1645 kind: ExprKind::Unary {
1646 op: UnaryOp::Neg,
1647 operand: Box::new(operand),
1648 },
1649 span,
1650 })
1651 }
1652 TokenKind::Bang => {
1654 let op_tok = self.advance().clone();
1655 let operand = self.parse_expr_bp(prec::UNARY)?;
1656 let span = merge_spans(to_ast_span(op_tok.span), operand.span);
1657 Ok(Expr {
1658 kind: ExprKind::Unary {
1659 op: UnaryOp::Not,
1660 operand: Box::new(operand),
1661 },
1662 span,
1663 })
1664 }
1665 TokenKind::Tilde => {
1667 let op_tok = self.advance().clone();
1668 let operand = self.parse_expr_bp(prec::UNARY)?;
1669 let span = merge_spans(to_ast_span(op_tok.span), operand.span);
1670 Ok(Expr {
1671 kind: ExprKind::Unary {
1672 op: UnaryOp::BitNot,
1673 operand: Box::new(operand),
1674 },
1675 span,
1676 })
1677 }
1678 TokenKind::If => {
1680 let start_span = to_ast_span(self.current_span());
1681 let if_stmt = self.parse_if_stmt()?;
1682 let end_span = if_stmt.then_block.span;
1683 let span = merge_spans(start_span, end_span);
1684 Ok(Expr {
1685 kind: ExprKind::IfExpr {
1686 condition: Box::new(if_stmt.condition),
1687 then_block: if_stmt.then_block,
1688 else_branch: if_stmt.else_branch,
1689 },
1690 span,
1691 })
1692 }
1693 _ => self.parse_atom(),
1694 }
1695 }
1696
1697 fn parse_atom(&mut self) -> PResult<Expr> {
1699 match self.peek_kind() {
1700 TokenKind::IntLit => {
1701 let tok = self.advance().clone();
1702 Ok(Expr {
1703 kind: ExprKind::IntLit(tok.int_value()),
1704 span: to_ast_span(tok.span),
1705 })
1706 }
1707 TokenKind::FloatLit => {
1708 let tok = self.advance().clone();
1709 Ok(Expr {
1710 kind: ExprKind::FloatLit(tok.float_value()),
1711 span: to_ast_span(tok.span),
1712 })
1713 }
1714 TokenKind::StringLit => {
1715 let tok = self.advance().clone();
1716 Ok(Expr {
1717 kind: ExprKind::StringLit(tok.text.clone()),
1718 span: to_ast_span(tok.span),
1719 })
1720 }
1721 TokenKind::ByteStringLit => {
1722 let tok = self.advance().clone();
1723 let bytes: Vec<u8> = tok.text.chars().map(|c| c as u8).collect();
1724 Ok(Expr {
1725 kind: ExprKind::ByteStringLit(bytes),
1726 span: to_ast_span(tok.span),
1727 })
1728 }
1729 TokenKind::ByteCharLit => {
1730 let tok = self.advance().clone();
1731 let byte_val: u8 = tok.text.parse().unwrap_or(0);
1732 Ok(Expr {
1733 kind: ExprKind::ByteCharLit(byte_val),
1734 span: to_ast_span(tok.span),
1735 })
1736 }
1737 TokenKind::RawStringLit => {
1738 let tok = self.advance().clone();
1739 Ok(Expr {
1740 kind: ExprKind::RawStringLit(tok.text.clone()),
1741 span: to_ast_span(tok.span),
1742 })
1743 }
1744 TokenKind::RawByteStringLit => {
1745 let tok = self.advance().clone();
1746 let bytes: Vec<u8> = tok.text.bytes().collect();
1747 Ok(Expr {
1748 kind: ExprKind::RawByteStringLit(bytes),
1749 span: to_ast_span(tok.span),
1750 })
1751 }
1752 TokenKind::FStringLit => {
1753 let tok = self.advance().clone();
1754 let span = to_ast_span(tok.span);
1755 let segments = self.parse_fstring_segments(&tok.text, span)?;
1758 Ok(Expr {
1759 kind: ExprKind::FStringLit(segments),
1760 span,
1761 })
1762 }
1763 TokenKind::RegexLit => {
1764 let tok = self.advance().clone();
1765 let (pattern, flags) = if let Some(idx) = tok.text.find('\0') {
1767 (tok.text[..idx].to_string(), tok.text[idx + 1..].to_string())
1768 } else {
1769 (tok.text.clone(), String::new())
1770 };
1771 Ok(Expr {
1772 kind: ExprKind::RegexLit { pattern, flags },
1773 span: to_ast_span(tok.span),
1774 })
1775 }
1776 TokenKind::True => {
1777 let tok = self.advance().clone();
1778 Ok(Expr {
1779 kind: ExprKind::BoolLit(true),
1780 span: to_ast_span(tok.span),
1781 })
1782 }
1783 TokenKind::False => {
1784 let tok = self.advance().clone();
1785 Ok(Expr {
1786 kind: ExprKind::BoolLit(false),
1787 span: to_ast_span(tok.span),
1788 })
1789 }
1790 TokenKind::Na => {
1791 let tok = self.advance().clone();
1792 Ok(Expr {
1793 kind: ExprKind::NaLit,
1794 span: to_ast_span(tok.span),
1795 })
1796 }
1797 TokenKind::Ident => {
1798 let ident = self.parse_ident()?;
1799 Ok(Expr {
1800 kind: ExprKind::Ident(ident.clone()),
1801 span: ident.span,
1802 })
1803 }
1804 TokenKind::Col => self.parse_col_expr(),
1805 TokenKind::LParen => self.parse_paren_expr(),
1806 TokenKind::LBracket => self.parse_array_lit(),
1807 TokenKind::LBracketPipe => self.parse_tensor_lit(),
1808 TokenKind::Pipe => self.parse_lambda(),
1809 TokenKind::PipePipe => self.parse_lambda_no_params(),
1810 TokenKind::Match => self.parse_match_expr(),
1811 TokenKind::LBrace => {
1812 let block = self.parse_block()?;
1813 let span = block.span;
1814 Ok(Expr {
1815 kind: ExprKind::Block(block),
1816 span,
1817 })
1818 }
1819 _ => {
1820 let tok = self.peek().clone();
1821 self.error(
1822 format!("expected expression, found {}", tok.kind.describe()),
1823 tok.span,
1824 );
1825 Err(())
1826 }
1827 }
1828 }
1829
1830 fn parse_col_expr(&mut self) -> PResult<Expr> {
1831 let start = self.expect(TokenKind::Col)?.span;
1832 self.expect(TokenKind::LParen)?;
1833 let name_tok = self.expect(TokenKind::StringLit)?;
1834 let end = self.expect(TokenKind::RParen)?.span;
1835 Ok(Expr {
1836 kind: ExprKind::Col(name_tok.text.clone()),
1837 span: to_ast_span(start.merge(end)),
1838 })
1839 }
1840
1841 fn parse_paren_expr(&mut self) -> PResult<Expr> {
1842 let start = self.expect(TokenKind::LParen)?.span;
1843 if self.at(TokenKind::RParen) {
1845 let end = self.advance().span;
1846 return Ok(Expr {
1847 kind: ExprKind::TupleLit(vec![]),
1848 span: to_ast_span(start.merge(end)),
1849 });
1850 }
1851 let first = self.parse_expr()?;
1852 if self.at(TokenKind::Comma) {
1854 let mut elems = vec![first];
1855 while self.eat(TokenKind::Comma).is_some() {
1856 if self.at(TokenKind::RParen) {
1857 break; }
1859 elems.push(self.parse_expr()?);
1860 }
1861 let end = self.expect(TokenKind::RParen)?.span;
1862 return Ok(Expr {
1863 kind: ExprKind::TupleLit(elems),
1864 span: to_ast_span(start.merge(end)),
1865 });
1866 }
1867 let end = self.expect(TokenKind::RParen)?.span;
1868 Ok(Expr {
1870 kind: first.kind,
1871 span: to_ast_span(start.merge(end)),
1872 })
1873 }
1874
1875 fn parse_array_lit(&mut self) -> PResult<Expr> {
1876 let start = self.expect(TokenKind::LBracket)?.span;
1877 let mut elems = Vec::new();
1878 if !self.at(TokenKind::RBracket) {
1879 loop {
1880 elems.push(self.parse_expr()?);
1881 if self.eat(TokenKind::Comma).is_none() {
1882 break;
1883 }
1884 if self.at(TokenKind::RBracket) {
1885 break;
1886 }
1887 }
1888 }
1889 let end = self.expect(TokenKind::RBracket)?.span;
1890 Ok(Expr {
1891 kind: ExprKind::ArrayLit(elems),
1892 span: to_ast_span(start.merge(end)),
1893 })
1894 }
1895
1896 fn parse_tensor_lit(&mut self) -> PResult<Expr> {
1904 let start = self.expect(TokenKind::LBracketPipe)?.span;
1905 let mut rows: Vec<Vec<Expr>> = Vec::new();
1906
1907 if !self.at(TokenKind::PipeRBracket) {
1908 loop {
1909 let mut row = Vec::new();
1911 loop {
1912 row.push(self.parse_expr()?);
1913 if self.eat(TokenKind::Comma).is_none() {
1914 break;
1915 }
1916 if self.at(TokenKind::Semicolon) || self.at(TokenKind::PipeRBracket) {
1918 break;
1919 }
1920 }
1921 rows.push(row);
1922 if self.eat(TokenKind::Semicolon).is_none() {
1924 break;
1925 }
1926 if self.at(TokenKind::PipeRBracket) {
1928 break;
1929 }
1930 }
1931 }
1932
1933 let end = self.expect(TokenKind::PipeRBracket)?.span;
1934 Ok(Expr {
1935 kind: ExprKind::TensorLit { rows },
1936 span: to_ast_span(start.merge(end)),
1937 })
1938 }
1939
1940 fn parse_lambda_no_params(&mut self) -> PResult<Expr> {
1943 let start = to_ast_span(self.expect(TokenKind::PipePipe)?.span);
1944 let body = self.parse_expr()?;
1945 let span = merge_spans(start, body.span);
1946 Ok(Expr {
1947 kind: ExprKind::Lambda {
1948 params: vec![],
1949 body: Box::new(body),
1950 },
1951 span,
1952 })
1953 }
1954
1955 fn parse_lambda(&mut self) -> PResult<Expr> {
1957 let start = to_ast_span(self.expect(TokenKind::Pipe)?.span);
1958
1959 let prev_pipe = self.allow_pipe_in_type;
1962 self.allow_pipe_in_type = false;
1963
1964 let mut params = Vec::new();
1966 if !self.at(TokenKind::Pipe) {
1967 loop {
1968 let param = self.parse_param()?;
1969 params.push(param);
1970 if self.eat(TokenKind::Comma).is_none() {
1971 break;
1972 }
1973 if self.at(TokenKind::Pipe) {
1975 break;
1976 }
1977 }
1978 }
1979
1980 self.allow_pipe_in_type = prev_pipe;
1981 self.expect(TokenKind::Pipe)?;
1982
1983 let body = self.parse_expr()?;
1985 let span = merge_spans(start, body.span);
1986
1987 Ok(Expr {
1988 kind: ExprKind::Lambda {
1989 params,
1990 body: Box::new(body),
1991 },
1992 span,
1993 })
1994 }
1995
1996 fn parse_match_expr(&mut self) -> PResult<Expr> {
1998 let start = self.expect(TokenKind::Match)?.span;
1999 let old_allow = self.allow_struct_lit;
2002 self.allow_struct_lit = false;
2003 let scrutinee = self.parse_expr()?;
2004 self.allow_struct_lit = old_allow;
2005
2006 self.expect(TokenKind::LBrace)?;
2007 let mut arms = Vec::new();
2008 while !self.at(TokenKind::RBrace) && !self.at_eof() {
2009 let arm = self.parse_match_arm()?;
2010 arms.push(arm);
2011 if self.eat(TokenKind::Comma).is_none() {
2013 break;
2014 }
2015 }
2016 let end = self.expect(TokenKind::RBrace)?.span;
2017 Ok(Expr {
2018 kind: ExprKind::Match {
2019 scrutinee: Box::new(scrutinee),
2020 arms,
2021 },
2022 span: to_ast_span(start.merge(end)),
2023 })
2024 }
2025
2026 fn parse_match_arm(&mut self) -> PResult<MatchArm> {
2028 let pattern = self.parse_pattern()?;
2029 self.expect(TokenKind::FatArrow)?;
2030 let body = self.parse_expr()?;
2031 let span = merge_spans(pattern.span, body.span);
2032 Ok(MatchArm {
2033 pattern,
2034 body,
2035 span,
2036 })
2037 }
2038
2039 fn parse_pattern(&mut self) -> PResult<Pattern> {
2041 match self.peek_kind() {
2042 TokenKind::Underscore => {
2044 let tok = self.advance().clone();
2045 Ok(Pattern {
2046 kind: PatternKind::Wildcard,
2047 span: to_ast_span(tok.span),
2048 })
2049 }
2050 TokenKind::True => {
2052 let tok = self.advance().clone();
2053 Ok(Pattern {
2054 kind: PatternKind::LitBool(true),
2055 span: to_ast_span(tok.span),
2056 })
2057 }
2058 TokenKind::False => {
2059 let tok = self.advance().clone();
2060 Ok(Pattern {
2061 kind: PatternKind::LitBool(false),
2062 span: to_ast_span(tok.span),
2063 })
2064 }
2065 TokenKind::StringLit => {
2067 let tok = self.advance().clone();
2068 Ok(Pattern {
2069 kind: PatternKind::LitString(tok.text.clone()),
2070 span: to_ast_span(tok.span),
2071 })
2072 }
2073 TokenKind::IntLit => {
2075 let tok = self.advance().clone();
2076 Ok(Pattern {
2077 kind: PatternKind::LitInt(tok.int_value()),
2078 span: to_ast_span(tok.span),
2079 })
2080 }
2081 TokenKind::FloatLit => {
2083 let tok = self.advance().clone();
2084 Ok(Pattern {
2085 kind: PatternKind::LitFloat(tok.float_value()),
2086 span: to_ast_span(tok.span),
2087 })
2088 }
2089 TokenKind::Minus => {
2091 let start = self.advance().span;
2092 match self.peek_kind() {
2093 TokenKind::IntLit => {
2094 let tok = self.advance().clone();
2095 Ok(Pattern {
2096 kind: PatternKind::LitInt(-tok.int_value()),
2097 span: to_ast_span(start.merge(tok.span)),
2098 })
2099 }
2100 TokenKind::FloatLit => {
2101 let tok = self.advance().clone();
2102 Ok(Pattern {
2103 kind: PatternKind::LitFloat(-tok.float_value()),
2104 span: to_ast_span(start.merge(tok.span)),
2105 })
2106 }
2107 _ => {
2108 let tok = self.peek().clone();
2109 self.error(
2110 format!(
2111 "expected numeric literal after `-` in pattern, found {}",
2112 tok.kind.describe()
2113 ),
2114 tok.span,
2115 );
2116 Err(())
2117 }
2118 }
2119 }
2120 TokenKind::LParen => {
2122 let start = self.advance().span;
2123 let mut pats = Vec::new();
2124 if !self.at(TokenKind::RParen) {
2125 loop {
2126 pats.push(self.parse_pattern()?);
2127 if self.eat(TokenKind::Comma).is_none() {
2128 break;
2129 }
2130 if self.at(TokenKind::RParen) {
2131 break;
2132 }
2133 }
2134 }
2135 let end = self.expect(TokenKind::RParen)?.span;
2136 Ok(Pattern {
2137 kind: PatternKind::Tuple(pats),
2138 span: to_ast_span(start.merge(end)),
2139 })
2140 }
2141 TokenKind::Ident => {
2143 let ident = self.parse_ident()?;
2144 if self.at(TokenKind::LBrace) {
2145 self.advance(); let mut fields = Vec::new();
2148 while !self.at(TokenKind::RBrace) && !self.at_eof() {
2149 let field = self.parse_pattern_field()?;
2150 fields.push(field);
2151 if self.eat(TokenKind::Comma).is_none() {
2152 break;
2153 }
2154 }
2155 let end = self.expect(TokenKind::RBrace)?.span;
2156 Ok(Pattern {
2157 kind: PatternKind::Struct {
2158 name: ident.clone(),
2159 fields,
2160 },
2161 span: merge_spans(ident.span, to_ast_span(end)),
2162 })
2163 } else if self.at(TokenKind::LParen) {
2164 self.advance(); let mut sub_pats = Vec::new();
2167 if !self.at(TokenKind::RParen) {
2168 loop {
2169 sub_pats.push(self.parse_pattern()?);
2170 if self.eat(TokenKind::Comma).is_none() {
2171 break;
2172 }
2173 if self.at(TokenKind::RParen) {
2174 break;
2175 }
2176 }
2177 }
2178 let end = self.expect(TokenKind::RParen)?.span;
2179 Ok(Pattern {
2180 kind: PatternKind::Variant {
2181 enum_name: None,
2182 variant: ident.clone(),
2183 fields: sub_pats,
2184 },
2185 span: merge_spans(ident.span, to_ast_span(end)),
2186 })
2187 } else {
2188 Ok(Pattern {
2190 kind: PatternKind::Binding(ident.clone()),
2191 span: ident.span,
2192 })
2193 }
2194 }
2195 _ => {
2196 let tok = self.peek().clone();
2197 self.error(
2198 format!("expected pattern, found {}", tok.kind.describe()),
2199 tok.span,
2200 );
2201 Err(())
2202 }
2203 }
2204 }
2205
2206 fn parse_pattern_field(&mut self) -> PResult<PatternField> {
2208 let name = self.parse_ident()?;
2209 let start = name.span;
2210 if self.eat(TokenKind::Colon).is_some() {
2211 let pattern = self.parse_pattern()?;
2212 let span = merge_spans(start, pattern.span);
2213 Ok(PatternField {
2214 name,
2215 pattern: Some(pattern),
2216 span,
2217 })
2218 } else {
2219 Ok(PatternField {
2221 name: name.clone(),
2222 pattern: None,
2223 span: start,
2224 })
2225 }
2226 }
2227
2228 fn parse_postfix(&mut self, lhs: Expr) -> PResult<Expr> {
2230 match self.peek_kind() {
2231 TokenKind::Dot => {
2232 self.advance(); if let TokenKind::IntLit = self.peek_kind() {
2235 let tok = self.advance();
2236 let idx_str = tok.text.clone();
2237 let idx_span = to_ast_span(tok.span);
2238 let name = Ident { name: idx_str, span: idx_span };
2239 let span = merge_spans(lhs.span, idx_span);
2240 return Ok(Expr {
2241 kind: ExprKind::Field {
2242 object: Box::new(lhs),
2243 name,
2244 },
2245 span,
2246 });
2247 }
2248 let name = self.parse_ident()?;
2249 let span = merge_spans(lhs.span, name.span);
2250 Ok(Expr {
2251 kind: ExprKind::Field {
2252 object: Box::new(lhs),
2253 name,
2254 },
2255 span,
2256 })
2257 }
2258 TokenKind::LParen => {
2259 self.advance(); let args = self.parse_call_args()?;
2261 let end = self.expect(TokenKind::RParen)?.span;
2262 let span = merge_spans(lhs.span, to_ast_span(end));
2263 Ok(Expr {
2264 kind: ExprKind::Call {
2265 callee: Box::new(lhs),
2266 args,
2267 },
2268 span,
2269 })
2270 }
2271 TokenKind::LBracket => {
2272 self.advance(); let mut indices = Vec::new();
2274 if !self.at(TokenKind::RBracket) {
2275 loop {
2276 indices.push(self.parse_expr()?);
2277 if self.eat(TokenKind::Comma).is_none() {
2278 break;
2279 }
2280 if self.at(TokenKind::RBracket) {
2281 break;
2282 }
2283 }
2284 }
2285 let end = self.expect(TokenKind::RBracket)?.span;
2286 let span = merge_spans(lhs.span, to_ast_span(end));
2287 if indices.len() == 1 {
2288 Ok(Expr {
2289 kind: ExprKind::Index {
2290 object: Box::new(lhs),
2291 index: Box::new(indices.into_iter().next().unwrap()),
2292 },
2293 span,
2294 })
2295 } else {
2296 Ok(Expr {
2297 kind: ExprKind::MultiIndex {
2298 object: Box::new(lhs),
2299 indices,
2300 },
2301 span,
2302 })
2303 }
2304 }
2305 TokenKind::LBrace => {
2306 let name = match lhs.kind {
2309 ExprKind::Ident(ref id) => id.clone(),
2310 _ => unreachable!("struct literal postfix should only apply to identifiers"),
2311 };
2312 self.advance(); let mut fields = Vec::new();
2314 while !self.at(TokenKind::RBrace) && !self.at_eof() {
2315 let field_name = self.parse_ident()?;
2316 self.expect(TokenKind::Colon)?;
2317 let value = self.parse_expr()?;
2318 let field_span = merge_spans(field_name.span, value.span);
2319 fields.push(FieldInit {
2320 name: field_name,
2321 value,
2322 span: field_span,
2323 });
2324 if self.eat(TokenKind::Comma).is_none() {
2325 break;
2326 }
2327 }
2328 let end = self.expect(TokenKind::RBrace)?.span;
2329 let span = merge_spans(lhs.span, to_ast_span(end));
2330 Ok(Expr {
2331 kind: ExprKind::StructLit { name, fields },
2332 span,
2333 })
2334 }
2335 TokenKind::Question => {
2336 let tok = self.advance().clone();
2337 let span = merge_spans(lhs.span, to_ast_span(tok.span));
2338 Ok(Expr {
2339 kind: ExprKind::Try(Box::new(lhs)),
2340 span,
2341 })
2342 }
2343 _ => unreachable!("parse_postfix called with non-postfix token"),
2344 }
2345 }
2346
2347 fn parse_call_args(&mut self) -> PResult<Vec<CallArg>> {
2348 let mut args = Vec::new();
2349 if self.at(TokenKind::RParen) {
2350 return Ok(args);
2351 }
2352 loop {
2353 let arg = self.parse_call_arg()?;
2354 args.push(arg);
2355 if self.eat(TokenKind::Comma).is_none() {
2356 break;
2357 }
2358 if self.at(TokenKind::RParen) {
2359 break;
2360 }
2361 }
2362 Ok(args)
2363 }
2364
2365 fn parse_call_arg(&mut self) -> PResult<CallArg> {
2366 let start_span = to_ast_span(self.current_span());
2369 if self.at(TokenKind::Ident) && self.peek_ahead(1) == TokenKind::Colon {
2370 let name = self.parse_ident()?;
2371 self.advance(); let value = self.parse_expr()?;
2373 let span = merge_spans(name.span, value.span);
2374 return Ok(CallArg {
2375 name: Some(name),
2376 value,
2377 span,
2378 });
2379 }
2380 let value = self.parse_expr()?;
2381 let span = merge_spans(start_span, value.span);
2382 Ok(CallArg {
2383 name: None,
2384 value,
2385 span,
2386 })
2387 }
2388
2389 fn parse_infix(&mut self, lhs: Expr, r_bp: u8) -> PResult<Expr> {
2391 let op_tok = self.advance().clone();
2392
2393 match op_tok.kind {
2394 TokenKind::Eq => {
2395 let rhs = self.parse_expr_bp(r_bp)?;
2396 let span = merge_spans(lhs.span, rhs.span);
2397 Ok(Expr {
2398 kind: ExprKind::Assign {
2399 target: Box::new(lhs),
2400 value: Box::new(rhs),
2401 },
2402 span,
2403 })
2404 }
2405 TokenKind::PlusEq | TokenKind::MinusEq | TokenKind::StarEq
2407 | TokenKind::SlashEq | TokenKind::PercentEq | TokenKind::StarStarEq
2408 | TokenKind::AmpEq | TokenKind::PipeEq | TokenKind::CaretEq
2409 | TokenKind::LtLtEq | TokenKind::GtGtEq => {
2410 let op = compound_assign_to_binop(op_tok.kind);
2411 let rhs = self.parse_expr_bp(r_bp)?;
2412 let span = merge_spans(lhs.span, rhs.span);
2413 Ok(Expr {
2414 kind: ExprKind::CompoundAssign {
2415 op,
2416 target: Box::new(lhs),
2417 value: Box::new(rhs),
2418 },
2419 span,
2420 })
2421 }
2422 TokenKind::PipeGt => {
2423 let rhs = self.parse_expr_bp(r_bp)?;
2424 let span = merge_spans(lhs.span, rhs.span);
2425 Ok(Expr {
2426 kind: ExprKind::Pipe {
2427 left: Box::new(lhs),
2428 right: Box::new(rhs),
2429 },
2430 span,
2431 })
2432 }
2433 TokenKind::As => {
2434 let target = self.parse_ident()?;
2436 let span = merge_spans(lhs.span, target.span);
2437 Ok(Expr {
2438 kind: ExprKind::Cast {
2439 expr: Box::new(lhs),
2440 target_type: target,
2441 },
2442 span,
2443 })
2444 }
2445 _ => {
2446 let op = token_to_binop(op_tok.kind);
2447 let rhs = self.parse_expr_bp(r_bp)?;
2448 let span = merge_spans(lhs.span, rhs.span);
2449 Ok(Expr {
2450 kind: ExprKind::Binary {
2451 op,
2452 left: Box::new(lhs),
2453 right: Box::new(rhs),
2454 },
2455 span,
2456 })
2457 }
2458 }
2459 }
2460
2461 fn parse_ident(&mut self) -> PResult<Ident> {
2464 let tok = self.expect(TokenKind::Ident)?;
2465 Ok(Ident {
2466 name: tok.text.clone(),
2467 span: to_ast_span(tok.span),
2468 })
2469 }
2470}
2471
2472fn token_to_binop(kind: TokenKind) -> BinOp {
2475 match kind {
2476 TokenKind::Plus => BinOp::Add,
2477 TokenKind::Minus => BinOp::Sub,
2478 TokenKind::Star => BinOp::Mul,
2479 TokenKind::Slash => BinOp::Div,
2480 TokenKind::Percent => BinOp::Mod,
2481 TokenKind::StarStar => BinOp::Pow,
2482 TokenKind::EqEq => BinOp::Eq,
2483 TokenKind::BangEq => BinOp::Ne,
2484 TokenKind::Lt => BinOp::Lt,
2485 TokenKind::Gt => BinOp::Gt,
2486 TokenKind::LtEq => BinOp::Le,
2487 TokenKind::GtEq => BinOp::Ge,
2488 TokenKind::AmpAmp => BinOp::And,
2489 TokenKind::PipePipe => BinOp::Or,
2490 TokenKind::TildeEq => BinOp::Match,
2491 TokenKind::BangTilde => BinOp::NotMatch,
2492 TokenKind::Amp => BinOp::BitAnd,
2494 TokenKind::Pipe => BinOp::BitOr,
2495 TokenKind::Caret => BinOp::BitXor,
2496 TokenKind::LtLt => BinOp::Shl,
2497 TokenKind::GtGt => BinOp::Shr,
2498 _ => unreachable!("token_to_binop called with non-operator token {:?}", kind),
2499 }
2500}
2501
2502fn compound_assign_to_binop(kind: TokenKind) -> BinOp {
2503 match kind {
2504 TokenKind::PlusEq => BinOp::Add,
2505 TokenKind::MinusEq => BinOp::Sub,
2506 TokenKind::StarEq => BinOp::Mul,
2507 TokenKind::SlashEq => BinOp::Div,
2508 TokenKind::PercentEq => BinOp::Mod,
2509 TokenKind::StarStarEq => BinOp::Pow,
2510 TokenKind::AmpEq => BinOp::BitAnd,
2511 TokenKind::PipeEq => BinOp::BitOr,
2512 TokenKind::CaretEq => BinOp::BitXor,
2513 TokenKind::LtLtEq => BinOp::Shl,
2514 TokenKind::GtGtEq => BinOp::Shr,
2515 _ => unreachable!("compound_assign_to_binop called with {:?}", kind),
2516 }
2517}
2518
2519pub fn parse_source(source: &str) -> (Program, DiagnosticBag) {
2546 let lexer = cjc_lexer::Lexer::new(source);
2547 let (tokens, mut lex_diags) = lexer.tokenize();
2548 let parser = Parser::new(tokens);
2549 let (program, parse_diags) = parser.parse_program();
2550 for d in parse_diags.diagnostics {
2552 lex_diags.emit(d);
2553 }
2554 (program, lex_diags)
2555}
2556
2557#[cfg(test)]
2560mod tests {
2561 use super::*;
2562
2563 fn parse_ok(source: &str) -> Program {
2565 let (program, diags) = parse_source(source);
2566 if diags.has_errors() {
2567 let rendered = diags.render_all(source, "<test>");
2568 panic!("unexpected parse errors:\n{}", rendered);
2569 }
2570 program
2571 }
2572
2573 fn parse_err(source: &str) -> DiagnosticBag {
2575 let (_, diags) = parse_source(source);
2576 assert!(
2577 diags.has_errors(),
2578 "expected parse error but got none for: {}",
2579 source
2580 );
2581 diags
2582 }
2583
2584 #[test]
2587 fn test_parse_struct_simple() {
2588 let prog = parse_ok("struct Point { x: f64, y: f64 }");
2589 assert_eq!(prog.declarations.len(), 1);
2590 match &prog.declarations[0].kind {
2591 DeclKind::Struct(s) => {
2592 assert_eq!(s.name.name, "Point");
2593 assert_eq!(s.fields.len(), 2);
2594 assert_eq!(s.fields[0].name.name, "x");
2595 assert_eq!(s.fields[1].name.name, "y");
2596 }
2597 _ => panic!("expected struct"),
2598 }
2599 }
2600
2601 #[test]
2602 fn test_parse_struct_generic() {
2603 let prog = parse_ok("struct Pair<T: Clone, U> { first: T, second: U }");
2604 match &prog.declarations[0].kind {
2605 DeclKind::Struct(s) => {
2606 assert_eq!(s.type_params.len(), 2);
2607 assert_eq!(s.type_params[0].name.name, "T");
2608 assert_eq!(s.type_params[0].bounds.len(), 1);
2609 assert_eq!(s.type_params[1].name.name, "U");
2610 assert!(s.type_params[1].bounds.is_empty());
2611 }
2612 _ => panic!("expected struct"),
2613 }
2614 }
2615
2616 #[test]
2619 fn test_parse_class() {
2620 let prog = parse_ok("class Node<T> { value: T, next: Node<T> }");
2621 match &prog.declarations[0].kind {
2622 DeclKind::Class(c) => {
2623 assert_eq!(c.name.name, "Node");
2624 assert_eq!(c.type_params.len(), 1);
2625 assert_eq!(c.fields.len(), 2);
2626 }
2627 _ => panic!("expected class"),
2628 }
2629 }
2630
2631 #[test]
2634 fn test_parse_fn_simple() {
2635 let prog = parse_ok("fn add(a: i64, b: i64) -> i64 { a + b }");
2636 match &prog.declarations[0].kind {
2637 DeclKind::Fn(f) => {
2638 assert_eq!(f.name.name, "add");
2639 assert_eq!(f.params.len(), 2);
2640 assert!(f.return_type.is_some());
2641 assert!(!f.is_nogc);
2642 assert!(f.body.expr.is_some());
2644 }
2645 _ => panic!("expected fn"),
2646 }
2647 }
2648
2649 #[test]
2650 fn test_parse_fn_nogc() {
2651 let prog = parse_ok("nogc fn fast(x: f64) -> f64 { x }");
2652 match &prog.declarations[0].kind {
2653 DeclKind::Fn(f) => {
2654 assert!(f.is_nogc);
2655 assert_eq!(f.name.name, "fast");
2656 }
2657 _ => panic!("expected fn"),
2658 }
2659 }
2660
2661 #[test]
2662 fn test_parse_fn_no_return_type() {
2663 let prog = parse_ok("fn greet(name: String) { name }");
2664 match &prog.declarations[0].kind {
2665 DeclKind::Fn(f) => {
2666 assert!(f.return_type.is_none());
2667 }
2668 _ => panic!("expected fn"),
2669 }
2670 }
2671
2672 #[test]
2675 fn test_parse_trait() {
2676 let prog = parse_ok(
2677 "trait Numeric: Add + Mul { fn zero() -> Self; fn one() -> Self; }",
2678 );
2679 match &prog.declarations[0].kind {
2680 DeclKind::Trait(t) => {
2681 assert_eq!(t.name.name, "Numeric");
2682 assert_eq!(t.super_traits.len(), 2);
2683 assert_eq!(t.methods.len(), 2);
2684 assert_eq!(t.methods[0].name.name, "zero");
2685 }
2686 _ => panic!("expected trait"),
2687 }
2688 }
2689
2690 #[test]
2693 fn test_parse_impl() {
2694 let prog = parse_ok(
2695 "impl<T> Vec<T> : Iterable { fn len(self: Vec<T>) -> i64 { 0 } }",
2696 );
2697 match &prog.declarations[0].kind {
2698 DeclKind::Impl(i) => {
2699 assert_eq!(i.type_params.len(), 1);
2700 assert!(i.trait_ref.is_some());
2701 assert_eq!(i.methods.len(), 1);
2702 }
2703 _ => panic!("expected impl"),
2704 }
2705 }
2706
2707 #[test]
2710 fn test_parse_import() {
2711 let prog = parse_ok("import std.io.File as F");
2712 match &prog.declarations[0].kind {
2713 DeclKind::Import(i) => {
2714 assert_eq!(i.path.len(), 3);
2715 assert_eq!(i.path[0].name, "std");
2716 assert_eq!(i.path[1].name, "io");
2717 assert_eq!(i.path[2].name, "File");
2718 assert_eq!(i.alias.as_ref().unwrap().name, "F");
2719 }
2720 _ => panic!("expected import"),
2721 }
2722 }
2723
2724 #[test]
2725 fn test_parse_import_no_alias() {
2726 let prog = parse_ok("import math.linalg");
2727 match &prog.declarations[0].kind {
2728 DeclKind::Import(i) => {
2729 assert_eq!(i.path.len(), 2);
2730 assert!(i.alias.is_none());
2731 }
2732 _ => panic!("expected import"),
2733 }
2734 }
2735
2736 #[test]
2739 fn test_parse_let() {
2740 let prog = parse_ok("let x: i64 = 42;");
2741 match &prog.declarations[0].kind {
2742 DeclKind::Let(l) => {
2743 assert_eq!(l.name.name, "x");
2744 assert!(!l.mutable);
2745 assert!(l.ty.is_some());
2746 }
2747 _ => panic!("expected let"),
2748 }
2749 }
2750
2751 #[test]
2752 fn test_parse_let_mut() {
2753 let prog = parse_ok("let mut count = 0;");
2754 match &prog.declarations[0].kind {
2755 DeclKind::Let(l) => {
2756 assert!(l.mutable);
2757 assert!(l.ty.is_none());
2758 }
2759 _ => panic!("expected let"),
2760 }
2761 }
2762
2763 #[test]
2766 fn test_parse_binary_precedence() {
2767 let prog = parse_ok("fn main() { 1 + 2 * 3 }");
2769 match &prog.declarations[0].kind {
2770 DeclKind::Fn(f) => {
2771 let tail = f.body.expr.as_ref().unwrap();
2772 match &tail.kind {
2773 ExprKind::Binary { op, left, right } => {
2774 assert_eq!(*op, BinOp::Add);
2775 assert!(matches!(left.kind, ExprKind::IntLit(1)));
2777 match &right.kind {
2779 ExprKind::Binary { op, .. } => assert_eq!(*op, BinOp::Mul),
2780 _ => panic!("expected binary mul"),
2781 }
2782 }
2783 _ => panic!("expected binary add"),
2784 }
2785 }
2786 _ => panic!("expected fn"),
2787 }
2788 }
2789
2790 #[test]
2791 fn test_parse_unary() {
2792 let prog = parse_ok("fn f() { -x }");
2793 match &prog.declarations[0].kind {
2794 DeclKind::Fn(f) => {
2795 let tail = f.body.expr.as_ref().unwrap();
2796 match &tail.kind {
2797 ExprKind::Unary { op, .. } => assert_eq!(*op, UnaryOp::Neg),
2798 _ => panic!("expected unary"),
2799 }
2800 }
2801 _ => panic!("expected fn"),
2802 }
2803 }
2804
2805 #[test]
2806 fn test_parse_call_with_named_args() {
2807 let prog = parse_ok("fn f() { create(width: 10, height: 20) }");
2808 match &prog.declarations[0].kind {
2809 DeclKind::Fn(f) => {
2810 let tail = f.body.expr.as_ref().unwrap();
2811 match &tail.kind {
2812 ExprKind::Call { args, .. } => {
2813 assert_eq!(args.len(), 2);
2814 assert_eq!(args[0].name.as_ref().unwrap().name, "width");
2815 assert_eq!(args[1].name.as_ref().unwrap().name, "height");
2816 }
2817 _ => panic!("expected call"),
2818 }
2819 }
2820 _ => panic!("expected fn"),
2821 }
2822 }
2823
2824 #[test]
2825 fn test_parse_field_access_and_method_call() {
2826 let prog = parse_ok("fn f() { obj.field.method(x) }");
2827 match &prog.declarations[0].kind {
2828 DeclKind::Fn(f) => {
2829 let tail = f.body.expr.as_ref().unwrap();
2830 match &tail.kind {
2832 ExprKind::Call { callee, args } => {
2833 assert_eq!(args.len(), 1);
2834 match &callee.kind {
2835 ExprKind::Field { name, .. } => {
2836 assert_eq!(name.name, "method");
2837 }
2838 _ => panic!("expected field access"),
2839 }
2840 }
2841 _ => panic!("expected call"),
2842 }
2843 }
2844 _ => panic!("expected fn"),
2845 }
2846 }
2847
2848 #[test]
2849 fn test_parse_index_and_multi_index() {
2850 let prog = parse_ok("fn f() { a[0]; b[1, 2] }");
2851 match &prog.declarations[0].kind {
2852 DeclKind::Fn(f) => {
2853 match &f.body.stmts[0].kind {
2855 StmtKind::Expr(e) => match &e.kind {
2856 ExprKind::Index { .. } => {}
2857 _ => panic!("expected index"),
2858 },
2859 _ => panic!("expected expr stmt"),
2860 }
2861 let tail = f.body.expr.as_ref().unwrap();
2863 match &tail.kind {
2864 ExprKind::MultiIndex { indices, .. } => {
2865 assert_eq!(indices.len(), 2);
2866 }
2867 _ => panic!("expected multi-index"),
2868 }
2869 }
2870 _ => panic!("expected fn"),
2871 }
2872 }
2873
2874 #[test]
2875 fn test_parse_pipe() {
2876 let prog = parse_ok("fn f() { data |> filter(x) |> map(y) }");
2877 match &prog.declarations[0].kind {
2878 DeclKind::Fn(f) => {
2879 let tail = f.body.expr.as_ref().unwrap();
2880 match &tail.kind {
2882 ExprKind::Pipe { right, .. } => {
2883 match &right.kind {
2884 ExprKind::Call { callee, .. } => match &callee.kind {
2885 ExprKind::Ident(id) => assert_eq!(id.name, "map"),
2886 _ => panic!("expected ident"),
2887 },
2888 _ => panic!("expected call"),
2889 }
2890 }
2891 _ => panic!("expected pipe"),
2892 }
2893 }
2894 _ => panic!("expected fn"),
2895 }
2896 }
2897
2898 #[test]
2899 fn test_parse_assignment() {
2900 let prog = parse_ok("fn f() { x = 10; }");
2901 match &prog.declarations[0].kind {
2902 DeclKind::Fn(f) => match &f.body.stmts[0].kind {
2903 StmtKind::Expr(e) => match &e.kind {
2904 ExprKind::Assign { .. } => {}
2905 _ => panic!("expected assign"),
2906 },
2907 _ => panic!("expected expr stmt"),
2908 },
2909 _ => panic!("expected fn"),
2910 }
2911 }
2912
2913 #[test]
2914 fn test_parse_struct_literal() {
2915 let prog = parse_ok("fn f() { Point { x: 1, y: 2 } }");
2916 match &prog.declarations[0].kind {
2917 DeclKind::Fn(f) => {
2918 let tail = f.body.expr.as_ref().unwrap();
2919 match &tail.kind {
2920 ExprKind::StructLit { name, fields } => {
2921 assert_eq!(name.name, "Point");
2922 assert_eq!(fields.len(), 2);
2923 }
2924 _ => panic!("expected struct lit"),
2925 }
2926 }
2927 _ => panic!("expected fn"),
2928 }
2929 }
2930
2931 #[test]
2932 fn test_parse_array_literal() {
2933 let prog = parse_ok("fn f() { [1, 2, 3] }");
2934 match &prog.declarations[0].kind {
2935 DeclKind::Fn(f) => {
2936 let tail = f.body.expr.as_ref().unwrap();
2937 match &tail.kind {
2938 ExprKind::ArrayLit(elems) => assert_eq!(elems.len(), 3),
2939 _ => panic!("expected array lit"),
2940 }
2941 }
2942 _ => panic!("expected fn"),
2943 }
2944 }
2945
2946 #[test]
2947 fn test_parse_col() {
2948 let prog = parse_ok(r#"fn f() { col("price") }"#);
2949 match &prog.declarations[0].kind {
2950 DeclKind::Fn(f) => {
2951 let tail = f.body.expr.as_ref().unwrap();
2952 match &tail.kind {
2953 ExprKind::Col(name) => assert_eq!(name, "price"),
2954 _ => panic!("expected col"),
2955 }
2956 }
2957 _ => panic!("expected fn"),
2958 }
2959 }
2960
2961 #[test]
2964 fn test_parse_if_else_if_else() {
2965 let prog = parse_ok(
2966 "fn f() { if x { 1; } else if y { 2; } else { 3; } }",
2967 );
2968 match &prog.declarations[0].kind {
2969 DeclKind::Fn(f) => {
2970 assert_eq!(f.body.stmts.len(), 1);
2971 match &f.body.stmts[0].kind {
2972 StmtKind::If(if_stmt) => {
2973 assert!(if_stmt.else_branch.is_some());
2974 match if_stmt.else_branch.as_ref().unwrap() {
2975 ElseBranch::ElseIf(elif) => {
2976 assert!(elif.else_branch.is_some());
2977 match elif.else_branch.as_ref().unwrap() {
2978 ElseBranch::Else(_) => {}
2979 _ => panic!("expected else block"),
2980 }
2981 }
2982 _ => panic!("expected else-if"),
2983 }
2984 }
2985 _ => panic!("expected if"),
2986 }
2987 }
2988 _ => panic!("expected fn"),
2989 }
2990 }
2991
2992 #[test]
2993 fn test_parse_while() {
2994 let prog = parse_ok("fn f() { while x > 0 { x = x - 1; } }");
2995 match &prog.declarations[0].kind {
2996 DeclKind::Fn(f) => match &f.body.stmts[0].kind {
2997 StmtKind::While(w) => {
2998 assert!(!w.body.stmts.is_empty());
2999 }
3000 _ => panic!("expected while"),
3001 },
3002 _ => panic!("expected fn"),
3003 }
3004 }
3005
3006 #[test]
3007 fn test_parse_return() {
3008 let prog = parse_ok("fn f() { return 42; }");
3009 match &prog.declarations[0].kind {
3010 DeclKind::Fn(f) => match &f.body.stmts[0].kind {
3011 StmtKind::Return(Some(e)) => {
3012 assert!(matches!(e.kind, ExprKind::IntLit(42)));
3013 }
3014 _ => panic!("expected return"),
3015 },
3016 _ => panic!("expected fn"),
3017 }
3018 }
3019
3020 #[test]
3021 fn test_parse_nogc_block() {
3022 let prog = parse_ok("fn f() { nogc { x + y; } }");
3023 match &prog.declarations[0].kind {
3024 DeclKind::Fn(f) => match &f.body.stmts[0].kind {
3025 StmtKind::NoGcBlock(block) => {
3026 assert_eq!(block.stmts.len(), 1);
3027 }
3028 _ => panic!("expected nogc block"),
3029 },
3030 _ => panic!("expected fn"),
3031 }
3032 }
3033
3034 #[test]
3037 fn test_error_recovery_missing_semicolon() {
3038 let (prog, diags) = parse_source("let x = 1\nfn f() { 0 }");
3041 assert!(diags.has_errors());
3042 assert!(prog.declarations.iter().any(|d| matches!(&d.kind, DeclKind::Fn(_))));
3044 }
3045
3046 #[test]
3047 fn test_error_recovery_unexpected_token() {
3048 let diags = parse_err("@@@ fn f() { 0 }");
3049 assert!(diags.has_errors());
3050 }
3051
3052 #[test]
3053 fn test_error_expected_expression() {
3054 let diags = parse_err("fn f() { let x = ; }");
3055 assert!(diags.has_errors());
3056 }
3057
3058 #[test]
3061 fn test_parse_full_program() {
3062 let source = r#"
3063 import std.math as m
3064
3065 struct Vec2 {
3066 x: f64,
3067 y: f64
3068 }
3069
3070 fn dot(a: Vec2, b: Vec2) -> f64 {
3071 a.x * b.x + a.y * b.y
3072 }
3073
3074 trait Shape {
3075 fn area(self: Self) -> f64;
3076 }
3077
3078 impl Vec2 : Shape {
3079 fn area(self: Vec2) -> f64 {
3080 self.x * self.y
3081 }
3082 }
3083
3084 let result: f64 = dot(Vec2 { x: 1.0, y: 2.0 }, Vec2 { x: 3.0, y: 4.0 });
3085 "#;
3086 let prog = parse_ok(source);
3087 assert_eq!(prog.declarations.len(), 6);
3088 }
3089
3090 #[test]
3091 fn test_parse_pipe_chain() {
3092 let source = r#"
3093 fn pipeline(data: DataFrame) -> DataFrame {
3094 data
3095 |> filter(col("age") > 18)
3096 |> group_by(col("city"))
3097 }
3098 "#;
3099 let prog = parse_ok(source);
3102 match &prog.declarations[0].kind {
3103 DeclKind::Fn(f) => {
3104 assert!(f.body.expr.is_some());
3105 }
3106 _ => panic!("expected fn"),
3107 }
3108 }
3109
3110 #[test]
3113 fn test_parse_logical_operators() {
3114 let prog = parse_ok("fn f() { a && b || c }");
3115 match &prog.declarations[0].kind {
3116 DeclKind::Fn(f) => {
3117 let tail = f.body.expr.as_ref().unwrap();
3118 match &tail.kind {
3120 ExprKind::Binary { op, .. } => assert_eq!(*op, BinOp::Or),
3121 _ => panic!("expected binary or"),
3122 }
3123 }
3124 _ => panic!("expected fn"),
3125 }
3126 }
3127
3128 #[test]
3129 fn test_parse_comparison_chain() {
3130 let prog = parse_ok("fn f() { x == 1 && y != 2 }");
3131 match &prog.declarations[0].kind {
3132 DeclKind::Fn(f) => {
3133 let tail = f.body.expr.as_ref().unwrap();
3134 match &tail.kind {
3135 ExprKind::Binary { op, .. } => assert_eq!(*op, BinOp::And),
3136 _ => panic!("expected and"),
3137 }
3138 }
3139 _ => panic!("expected fn"),
3140 }
3141 }
3142}