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