1use crate::ast::{AssignTarget, Param, UnaryOp, *};
5use crate::errors::{CompileError, Result, Span};
6use crate::lexer::Token;
7
8pub struct Parser {
9 tokens: Vec<(Token, Span)>,
10 current: usize,
11 type_params_in_scope: Vec<String>,
13 current_token_cache: Option<(Token, Span)>,
15}
16
17impl Parser {
18 pub fn new(tokens: Vec<(Token, Span)>) -> Self {
19 let current_token_cache = if !tokens.is_empty() {
20 Some(tokens[0].clone())
21 } else {
22 None
23 };
24
25 Self {
26 tokens,
27 current: 0,
28 type_params_in_scope: Vec::new(),
29 current_token_cache,
30 }
31 }
32
33 #[allow(clippy::type_complexity)]
35 fn parse_generic_params(&mut self) -> Result<(Vec<String>, Vec<String>, Vec<(String, Type)>)> {
36 let mut lifetime_params = Vec::new();
37 let mut type_params = Vec::new();
38 let mut const_params = Vec::new();
39
40 if self.check(&Token::Lt) {
41 self.advance()?; loop {
44 if self.check(&Token::SingleQuote) {
46 self.advance()?; let lifetime_name = match self.advance()? {
48 (Token::Identifier(name), _) => format!("'{}", name),
49 (token, _) => {
50 return Err(CompileError::UnexpectedToken {
51 expected: "lifetime name".to_string(),
52 found: token.to_string(),
53 span: self.current_span(),
54 });
55 }
56 };
57 lifetime_params.push(lifetime_name);
58 } else if self.check(&Token::Const) {
59 self.advance()?; let param_name = match self.advance()? {
62 (Token::Identifier(name), _) => name,
63 (token, _) => {
64 return Err(CompileError::UnexpectedToken {
65 expected: "const parameter name".to_string(),
66 found: token.to_string(),
67 span: self.current_span(),
68 });
69 }
70 };
71 self.consume(Token::Colon, "Expected ':' after const parameter name")?;
72 let param_type = self.parse_type()?;
73 const_params.push((param_name, param_type));
74 } else {
75 let param_name = match self.advance()? {
77 (Token::Identifier(name), _) => name,
78 (token, _) => {
79 return Err(CompileError::UnexpectedToken {
80 expected: "type parameter name".to_string(),
81 found: token.to_string(),
82 span: self.current_span(),
83 });
84 }
85 };
86 type_params.push(param_name.clone());
87 }
88
89 if !self.check(&Token::Comma) {
90 break;
91 }
92 self.advance()?; }
94
95 self.consume(Token::Gt, "Expected '>' after generic parameters")?;
96 }
97
98 Ok((lifetime_params, type_params, const_params))
99 }
100
101 pub fn current_token(&self) -> &Token {
103 if let Some((ref token, _)) = self.current_token_cache {
104 token
105 } else {
106 &Token::Eof
107 }
108 }
109
110 fn update_cache(&mut self) {
112 self.current_token_cache = if self.current < self.tokens.len() {
113 Some(self.tokens[self.current].clone())
114 } else {
115 None
116 };
117 }
118
119 fn current_span(&self) -> Option<crate::errors::Span> {
121 if self.current < self.tokens.len() {
122 let span = &self.tokens[self.current].1;
123 Some(crate::errors::Span::new(
124 span.start,
125 span.end,
126 span.line,
127 span.column,
128 ))
129 } else if self.current > 0 && self.current - 1 < self.tokens.len() {
130 let span = &self.tokens[self.current - 1].1;
132 Some(crate::errors::Span::new(
133 span.start,
134 span.end,
135 span.line,
136 span.column,
137 ))
138 } else {
139 None
140 }
141 }
142
143 fn expr_span(expr: &Expr) -> Span {
145 match expr {
146 Expr::Integer(_) => Span::dummy(),
148 Expr::String(_) => Span::dummy(),
149 Expr::Bool(_) => Span::dummy(),
150 Expr::Ident(_) => Span::dummy(),
151 Expr::Binary { span, .. } => *span,
153 Expr::Unary { span, .. } => *span,
154 Expr::Call { span, .. } => *span,
155 Expr::Index { span, .. } => *span,
156 Expr::ArrayLiteral { span, .. } => *span,
157 Expr::ArrayRepeat { span, .. } => *span,
158 Expr::StructLiteral { span, .. } => *span,
159 Expr::FieldAccess { span, .. } => *span,
160 Expr::EnumConstructor { span, .. } => *span,
161 Expr::Range { span, .. } => *span,
162 Expr::Reference { span, .. } => *span,
163 Expr::Deref { span, .. } => *span,
164 Expr::Question { span, .. } => *span,
165 Expr::MacroInvocation { span, .. } => *span,
166 Expr::Await { span, .. } => *span,
167 }
168 }
169
170 pub fn parse(&mut self) -> Result<Program> {
172 let mut imports = Vec::new();
173 let mut items = Vec::new();
174
175 while self.check(&Token::Import) {
177 imports.push(self.parse_import()?);
178 }
179
180 while !self.is_at_end() {
182 items.push(self.parse_item()?);
183 }
184
185 Ok(Program { imports, items })
186 }
187
188 fn parse_import(&mut self) -> Result<crate::ast::Import> {
190 let start_span = self.consume(Token::Import, "Expected 'import'")?;
191
192 let mut path = Vec::new();
193 let mut items = None;
194
195 let first = match self.advance()? {
197 (Token::Identifier(name), _) => name,
198 (token, _) => {
199 return Err(CompileError::UnexpectedToken {
200 expected: "module name".to_string(),
201 found: token.to_string(),
202 span: self.current_span(),
203 });
204 }
205 };
206 path.push(first);
207
208 while self.check(&Token::DoubleColon) {
210 self.advance()?; if matches!(self.peek(), Ok(Token::Identifier(_))) {
214 let next_is_terminator = self
216 .tokens
217 .get(self.current + 1)
218 .map(|(t, _)| matches!(t, Token::Semicolon | Token::Comma | Token::LeftBrace))
219 .unwrap_or(false);
220
221 if next_is_terminator {
222 items = Some(self.parse_import_items()?);
224 break;
225 } else {
226 let segment = match self.advance()? {
228 (Token::Identifier(name), _) => name,
229 (token, _) => {
230 return Err(CompileError::UnexpectedToken {
231 expected: "module name".to_string(),
232 found: token.to_string(),
233 span: self.current_span(),
234 });
235 }
236 };
237 path.push(segment);
238 }
239 } else if self.check(&Token::Star) {
240 self.advance()?; items = None; break;
244 } else if self.check(&Token::LeftBrace) {
245 items = Some(self.parse_import_items()?);
247 break;
248 } else {
249 return Err(CompileError::UnexpectedToken {
250 expected: "module name, item name, or '*'".to_string(),
251 found: self.peek()?.to_string(),
252 span: self.current_span(),
253 });
254 }
255 }
256
257 let mut alias = None;
259 if self.check(&Token::As) {
260 self.advance()?; match self.advance()? {
262 (Token::Identifier(name), _) => {
263 alias = Some(name);
264 }
265 (token, _) => {
266 return Err(CompileError::UnexpectedToken {
267 expected: "alias name".to_string(),
268 found: token.to_string(),
269 span: self.current_span(),
270 });
271 }
272 }
273 }
274
275 let end_span = self.consume(Token::Semicolon, "Expected ';' after import")?;
276
277 Ok(crate::ast::Import {
278 path,
279 items,
280 alias,
281 span: Span::new(
282 start_span.start,
283 end_span.end,
284 start_span.line,
285 start_span.column,
286 ),
287 })
288 }
289
290 fn parse_import_items(&mut self) -> Result<Vec<String>> {
292 let mut items = Vec::new();
293
294 if self.check(&Token::LeftBrace) {
295 self.advance()?; loop {
299 match self.advance()? {
300 (Token::Identifier(name), _) => {
301 items.push(name);
302
303 if self.check(&Token::RightBrace) {
304 self.advance()?; break;
306 } else {
307 self.consume(Token::Comma, "Expected ',' or '}' after import item")?;
308 if self.check(&Token::RightBrace) {
310 self.advance()?; break;
312 }
313 }
314 }
315 (token, _) => {
316 return Err(CompileError::UnexpectedToken {
317 expected: "item name".to_string(),
318 found: token.to_string(),
319 span: self.current_span(),
320 });
321 }
322 }
323 }
324 } else {
325 match self.advance()? {
327 (Token::Identifier(name), _) => {
328 items.push(name);
329 }
330 (token, _) => {
331 return Err(CompileError::UnexpectedToken {
332 expected: "item name".to_string(),
333 found: token.to_string(),
334 span: self.current_span(),
335 });
336 }
337 }
338 }
339
340 Ok(items)
341 }
342
343 fn parse_item(&mut self) -> Result<Item> {
345 let visibility = if self.check(&Token::Pub) {
347 self.advance()?; crate::ast::Visibility::Public
349 } else {
350 crate::ast::Visibility::Private
351 };
352
353 let is_async = if self.check(&Token::Async) {
355 self.advance()?; true
357 } else {
358 false
359 };
360
361 match self.peek()? {
362 Token::Fn => {
363 let mut func = self.parse_function()?;
364 func.visibility = visibility;
365 func.is_async = is_async;
366 Ok(Item::Function(func))
367 }
368 Token::Struct => {
369 if is_async {
370 return Err(CompileError::SyntaxError {
371 message: "async can only be used with functions".to_string(),
372 span: self.current_span(),
373 });
374 }
375 let mut struct_def = self.parse_struct()?;
376 struct_def.visibility = visibility;
377 Ok(Item::Struct(struct_def))
378 }
379 Token::Enum => Ok(Item::Enum(self.parse_enum()?)),
380 Token::Trait => {
381 let mut trait_def = self.parse_trait()?;
382 trait_def.visibility = visibility;
383 Ok(Item::Trait(trait_def))
384 }
385 Token::Impl => Ok(Item::Impl(self.parse_impl()?)),
386 Token::Type => {
387 let mut type_alias = self.parse_type_alias()?;
388 type_alias.visibility = visibility;
389 Ok(Item::TypeAlias(type_alias))
390 }
391 Token::Macro => Ok(Item::Macro(self.parse_macro()?)),
392 _ => {
393 if is_async {
394 Err(CompileError::SyntaxError {
395 message: "async can only be used with function declarations".to_string(),
396 span: self.current_span(),
397 })
398 } else {
399 Err(CompileError::SyntaxError {
400 message: "Expected function, struct, enum, trait, type, impl, or macro declaration".to_string(),
401 span: self.current_span(),
402 })
403 }
404 }
405 }
406 }
407
408 fn parse_function(&mut self) -> Result<Function> {
410 let start_span = self.consume(Token::Fn, "Expected 'fn'")?;
411
412 let name = match self.advance()? {
413 (Token::Identifier(name), _) => name,
414 (token, _) => {
415 return Err(CompileError::UnexpectedToken {
416 expected: "function name".to_string(),
417 found: token.to_string(),
418 span: self.current_span(),
419 });
420 }
421 };
422
423 let (lifetime_params, type_params, const_params) = self.parse_generic_params()?;
425
426 self.type_params_in_scope = type_params.clone();
428
429 self.consume(Token::LeftParen, "Expected '('")?;
430
431 let mut params = Vec::new();
433
434 if !self.check(&Token::RightParen) {
435 loop {
436 let mutable = if self.check(&Token::Mut) {
438 self.advance()?; true
440 } else {
441 false
442 };
443
444 let param_name = match self.advance()? {
446 (Token::Identifier(name), _) => name,
447 (token, _) => {
448 return Err(CompileError::UnexpectedToken {
449 expected: "parameter name".to_string(),
450 found: token.to_string(),
451 span: self.current_span(),
452 });
453 }
454 };
455
456 self.consume(Token::Colon, "Expected ':' after parameter name")?;
458 let param_type = self.parse_type()?;
459
460 params.push(Param {
461 name: param_name,
462 ty: param_type,
463 mutable,
464 });
465
466 if !self.check(&Token::Comma) {
467 break;
468 }
469 self.advance()?; }
471 }
472
473 self.consume(Token::RightParen, "Expected ')'")?;
474
475 let return_type = if self.check(&Token::Arrow) {
477 self.advance()?; Some(self.parse_type()?)
479 } else {
480 None
481 };
482
483 self.consume(Token::LeftBrace, "Expected '{'")?;
484
485 let mut body = Vec::new();
486 while !self.check(&Token::RightBrace) && !self.is_at_end() {
487 body.push(self.parse_statement()?);
488 }
489
490 let end_span = self.consume(Token::RightBrace, "Expected '}'")?;
491
492 self.type_params_in_scope.clear();
494
495 Ok(Function {
496 visibility: crate::ast::Visibility::Private, is_async: false, name,
499 lifetime_params,
500 type_params,
501 const_params,
502 params,
503 return_type,
504 body,
505 span: Span::new(
506 start_span.start,
507 end_span.end,
508 start_span.line,
509 start_span.column,
510 ),
511 effects: None, })
513 }
514
515 fn parse_struct(&mut self) -> Result<StructDef> {
517 let start_span = self.consume(Token::Struct, "Expected 'struct'")?;
518
519 let name = match self.advance()? {
520 (Token::Identifier(name), _) => name,
521 (token, _) => {
522 return Err(CompileError::UnexpectedToken {
523 expected: "struct name".to_string(),
524 found: token.to_string(),
525 span: self.current_span(),
526 });
527 }
528 };
529
530 let (lifetime_params, type_params, const_params) = self.parse_generic_params()?;
532
533 self.consume(Token::LeftBrace, "Expected '{' after struct name")?;
534
535 let mut fields = Vec::new();
536
537 while !self.check(&Token::RightBrace) && !self.is_at_end() {
538 let field_name = match self.advance()? {
540 (Token::Identifier(name), _) => name,
541 (token, _) => {
542 return Err(CompileError::UnexpectedToken {
543 expected: "field name".to_string(),
544 found: token.to_string(),
545 span: self.current_span(),
546 });
547 }
548 };
549
550 self.consume(Token::Colon, "Expected ':' after field name")?;
551 let field_type = self.parse_type()?;
552
553 fields.push((field_name, field_type));
554
555 if !self.check(&Token::RightBrace) {
557 self.consume(Token::Comma, "Expected ',' after field")?;
558 }
559 }
560
561 let end_span = self.consume(Token::RightBrace, "Expected '}' after struct fields")?;
562
563 Ok(StructDef {
564 visibility: crate::ast::Visibility::Private, name,
566 lifetime_params,
567 type_params,
568 const_params,
569 fields,
570 span: Span::new(
571 start_span.start,
572 end_span.end,
573 start_span.line,
574 start_span.column,
575 ),
576 })
577 }
578
579 fn parse_enum(&mut self) -> Result<EnumDef> {
581 let start_span = self.consume(Token::Enum, "Expected 'enum'")?;
582
583 let name = match self.advance()? {
584 (Token::Identifier(name), _) => name,
585 (token, _) => {
586 return Err(CompileError::UnexpectedToken {
587 expected: "enum name".to_string(),
588 found: token.to_string(),
589 span: self.current_span(),
590 });
591 }
592 };
593
594 let (lifetime_params, type_params, const_params) = self.parse_generic_params()?;
596
597 self.consume(Token::LeftBrace, "Expected '{' after enum name")?;
598
599 let mut variants = Vec::new();
600
601 while !self.check(&Token::RightBrace) && !self.is_at_end() {
602 let variant_name = match self.advance()? {
604 (Token::Identifier(name), _) => name,
605 (token, _) => {
606 return Err(CompileError::UnexpectedToken {
607 expected: "variant name".to_string(),
608 found: token.to_string(),
609 span: self.current_span(),
610 });
611 }
612 };
613
614 let data = if self.check(&Token::LeftParen) {
616 self.advance()?; let mut types = Vec::new();
619
620 if !self.check(&Token::RightParen) {
621 loop {
622 types.push(self.parse_type()?);
623 if !self.check(&Token::Comma) {
624 break;
625 }
626 self.advance()?; }
628 }
629
630 self.consume(Token::RightParen, "Expected ')' after tuple variant types")?;
631 EnumVariantData::Tuple(types)
632 } else if self.check(&Token::LeftBrace) {
633 self.advance()?; let mut fields = Vec::new();
636
637 while !self.check(&Token::RightBrace) && !self.is_at_end() {
638 let field_name = match self.advance()? {
639 (Token::Identifier(name), _) => name,
640 (token, _) => {
641 return Err(CompileError::UnexpectedToken {
642 expected: "field name".to_string(),
643 found: token.to_string(),
644 span: self.current_span(),
645 });
646 }
647 };
648
649 self.consume(Token::Colon, "Expected ':' after field name")?;
650 let field_type = self.parse_type()?;
651
652 fields.push((field_name, field_type));
653
654 if !self.check(&Token::RightBrace) {
655 self.consume(Token::Comma, "Expected ',' after field")?;
656 }
657 }
658
659 self.consume(
660 Token::RightBrace,
661 "Expected '}' after struct variant fields",
662 )?;
663 EnumVariantData::Struct(fields)
664 } else {
665 EnumVariantData::Unit
667 };
668
669 variants.push(EnumVariant {
670 name: variant_name,
671 data,
672 });
673
674 if !self.check(&Token::RightBrace) {
676 self.consume(Token::Comma, "Expected ',' after variant")?;
677 }
678 }
679
680 let end_span = self.consume(Token::RightBrace, "Expected '}' after enum variants")?;
681
682 Ok(EnumDef {
683 name,
684 lifetime_params,
685 type_params,
686 const_params,
687 variants,
688 span: Span::new(
689 start_span.start,
690 end_span.end,
691 start_span.line,
692 start_span.column,
693 ),
694 })
695 }
696
697 fn parse_trait(&mut self) -> Result<TraitDef> {
699 let start_span = self.consume(Token::Trait, "Expected 'trait'")?;
700
701 let name = match self.advance()? {
702 (Token::Identifier(name), _) => name,
703 (token, _) => {
704 return Err(CompileError::UnexpectedToken {
705 expected: "trait name".to_string(),
706 found: token.to_string(),
707 span: self.current_span(),
708 });
709 }
710 };
711
712 let mut lifetime_params = Vec::new();
714 let mut type_params = Vec::new();
715
716 if self.check(&Token::Lt) {
717 self.advance()?; loop {
720 if self.check(&Token::SingleQuote) {
722 self.advance()?; let lifetime_name = match self.advance()? {
724 (Token::Identifier(name), _) => format!("'{}", name),
725 (token, _) => {
726 return Err(CompileError::UnexpectedToken {
727 expected: "lifetime name".to_string(),
728 found: token.to_string(),
729 span: self.current_span(),
730 });
731 }
732 };
733 lifetime_params.push(lifetime_name);
734 } else {
735 let param_name = match self.advance()? {
737 (Token::Identifier(name), _) => name,
738 (token, _) => {
739 return Err(CompileError::UnexpectedToken {
740 expected: "type parameter name".to_string(),
741 found: token.to_string(),
742 span: self.current_span(),
743 });
744 }
745 };
746 type_params.push(param_name);
747 }
748
749 if !self.check(&Token::Comma) {
750 break;
751 }
752 self.advance()?; }
754
755 self.consume(Token::Gt, "Expected '>' after generic parameters")?;
756 }
757
758 self.consume(Token::LeftBrace, "Expected '{' after trait name")?;
759
760 let mut methods = Vec::new();
761
762 while !self.check(&Token::RightBrace) && !self.is_at_end() {
763 let method_start = self.consume(Token::Fn, "Expected 'fn' for trait method")?;
765
766 let method_name = match self.advance()? {
767 (Token::Identifier(name), _) => name,
768 (token, _) => {
769 return Err(CompileError::UnexpectedToken {
770 expected: "method name".to_string(),
771 found: token.to_string(),
772 span: self.current_span(),
773 });
774 }
775 };
776
777 let mut method_lifetime_params = Vec::new();
779 let mut method_type_params = Vec::new();
780
781 if self.check(&Token::Lt) {
782 self.advance()?; loop {
785 if self.check(&Token::SingleQuote) {
786 self.advance()?;
787 let lifetime_name = match self.advance()? {
788 (Token::Identifier(name), _) => format!("'{}", name),
789 (token, _) => {
790 return Err(CompileError::UnexpectedToken {
791 expected: "lifetime name".to_string(),
792 found: token.to_string(),
793 span: self.current_span(),
794 });
795 }
796 };
797 method_lifetime_params.push(lifetime_name);
798 } else {
799 let param_name = match self.advance()? {
800 (Token::Identifier(name), _) => name,
801 (token, _) => {
802 return Err(CompileError::UnexpectedToken {
803 expected: "type parameter name".to_string(),
804 found: token.to_string(),
805 span: self.current_span(),
806 });
807 }
808 };
809 method_type_params.push(param_name);
810 }
811
812 if !self.check(&Token::Comma) {
813 break;
814 }
815 self.advance()?;
816 }
817
818 self.consume(Token::Gt, "Expected '>' after generic parameters")?;
819 }
820
821 self.consume(Token::LeftParen, "Expected '(' after method name")?;
823 let mut params = Vec::new();
824
825 if !self.check(&Token::RightParen) {
826 loop {
827 let mutable = if self.check(&Token::Mut) {
828 self.advance()?;
829 true
830 } else {
831 false
832 };
833
834 let param_name = match self.advance()? {
835 (Token::Identifier(name), _) => name,
836 (token, _) => {
837 return Err(CompileError::UnexpectedToken {
838 expected: "parameter name".to_string(),
839 found: token.to_string(),
840 span: self.current_span(),
841 });
842 }
843 };
844
845 self.consume(Token::Colon, "Expected ':' after parameter name")?;
846 let param_type = self.parse_type()?;
847
848 params.push(Param {
849 name: param_name,
850 ty: param_type,
851 mutable,
852 });
853
854 if !self.check(&Token::Comma) {
855 break;
856 }
857 self.advance()?;
858 }
859 }
860
861 self.consume(Token::RightParen, "Expected ')'")?;
862
863 let return_type = if self.check(&Token::Arrow) {
865 self.advance()?;
866 Some(self.parse_type()?)
867 } else {
868 None
869 };
870
871 let (has_body, body) = if self.check(&Token::LeftBrace) {
873 self.advance()?; let mut stmts = Vec::new();
875 while !self.check(&Token::RightBrace) && !self.is_at_end() {
876 stmts.push(self.parse_statement()?);
877 }
878 let _method_end = self.consume(Token::RightBrace, "Expected '}'")?;
879 (true, Some(stmts))
880 } else {
881 self.consume(
882 Token::Semicolon,
883 "Expected ';' after trait method signature",
884 )?;
885 (false, None)
886 };
887
888 methods.push(TraitMethod {
889 name: method_name,
890 lifetime_params: method_lifetime_params,
891 type_params: method_type_params,
892 params,
893 return_type,
894 has_body,
895 body,
896 span: Span::new(
897 method_start.start,
898 self.current_span()
899 .map(|s| s.end)
900 .unwrap_or(method_start.end),
901 method_start.line,
902 method_start.column,
903 ),
904 });
905 }
906
907 let end_span = self.consume(Token::RightBrace, "Expected '}' after trait methods")?;
908
909 Ok(TraitDef {
910 visibility: crate::ast::Visibility::Private, name,
912 lifetime_params,
913 type_params,
914 methods,
915 span: Span::new(
916 start_span.start,
917 end_span.end,
918 start_span.line,
919 start_span.column,
920 ),
921 })
922 }
923
924 fn parse_impl(&mut self) -> Result<ImplBlock> {
926 let start_span = self.consume(Token::Impl, "Expected 'impl'")?;
927
928 let mut lifetime_params = Vec::new();
930 let mut type_params = Vec::new();
931
932 if self.check(&Token::Lt) {
933 self.advance()?; loop {
936 if self.check(&Token::SingleQuote) {
937 self.advance()?;
938 let lifetime_name = match self.advance()? {
939 (Token::Identifier(name), _) => format!("'{}", name),
940 (token, _) => {
941 return Err(CompileError::UnexpectedToken {
942 expected: "lifetime name".to_string(),
943 found: token.to_string(),
944 span: self.current_span(),
945 });
946 }
947 };
948 lifetime_params.push(lifetime_name);
949 } else {
950 let param_name = match self.advance()? {
951 (Token::Identifier(name), _) => name,
952 (token, _) => {
953 return Err(CompileError::UnexpectedToken {
954 expected: "type parameter name".to_string(),
955 found: token.to_string(),
956 span: self.current_span(),
957 });
958 }
959 };
960 type_params.push(param_name);
961 }
962
963 if !self.check(&Token::Comma) {
964 break;
965 }
966 self.advance()?;
967 }
968
969 self.consume(Token::Gt, "Expected '>' after generic parameters")?;
970 }
971
972 let first_type = self.parse_type()?;
974
975 let (trait_type, for_type) = if self.check(&Token::For) {
977 self.advance()?; let impl_type = self.parse_type()?;
979 (Some(first_type), impl_type)
980 } else {
981 (None, first_type)
983 };
984
985 self.consume(Token::LeftBrace, "Expected '{' after impl type")?;
986
987 let mut methods = Vec::new();
988
989 while !self.check(&Token::RightBrace) && !self.is_at_end() {
990 if !self.check(&Token::Fn) {
992 return Err(CompileError::UnexpectedToken {
993 expected: "'fn' for method".to_string(),
994 found: self.peek()?.to_string(),
995 span: self.current_span(),
996 });
997 }
998 let method = self.parse_function()?;
999 methods.push(method);
1000 }
1001
1002 let end_span = self.consume(Token::RightBrace, "Expected '}' after impl methods")?;
1003
1004 Ok(ImplBlock {
1005 lifetime_params,
1006 type_params,
1007 trait_type,
1008 for_type,
1009 methods,
1010 span: Span::new(
1011 start_span.start,
1012 end_span.end,
1013 start_span.line,
1014 start_span.column,
1015 ),
1016 })
1017 }
1018
1019 fn parse_type_alias(&mut self) -> Result<TypeAlias> {
1021 let start_span = self.consume(Token::Type, "Expected 'type'")?;
1022
1023 let name = match self.advance()? {
1024 (Token::Identifier(name), _) => name,
1025 (token, _) => {
1026 return Err(CompileError::UnexpectedToken {
1027 expected: "type alias name".to_string(),
1028 found: token.to_string(),
1029 span: self.current_span(),
1030 });
1031 }
1032 };
1033
1034 let mut lifetime_params = Vec::new();
1036 let mut type_params = Vec::new();
1037
1038 if self.check(&Token::Lt) {
1039 self.advance()?; loop {
1042 if self.check(&Token::SingleQuote) {
1044 self.advance()?; let lifetime_name = match self.advance()? {
1046 (Token::Identifier(name), _) => format!("'{}", name),
1047 (token, _) => {
1048 return Err(CompileError::UnexpectedToken {
1049 expected: "lifetime name".to_string(),
1050 found: token.to_string(),
1051 span: self.current_span(),
1052 });
1053 }
1054 };
1055 lifetime_params.push(lifetime_name);
1056 } else {
1057 let param_name = match self.advance()? {
1059 (Token::Identifier(name), _) => name,
1060 (token, _) => {
1061 return Err(CompileError::UnexpectedToken {
1062 expected: "type parameter name".to_string(),
1063 found: token.to_string(),
1064 span: self.current_span(),
1065 });
1066 }
1067 };
1068 type_params.push(param_name);
1069 }
1070
1071 if !self.check(&Token::Comma) {
1072 break;
1073 }
1074 self.advance()?; }
1076
1077 self.consume(Token::Gt, "Expected '>' after generic parameters")?;
1078 }
1079
1080 self.consume(Token::Eq, "Expected '=' after type alias name")?;
1081
1082 let ty = self.parse_type()?;
1083
1084 let end_span = self.consume(Token::Semicolon, "Expected ';' after type alias")?;
1085
1086 Ok(TypeAlias {
1087 visibility: Visibility::Private, name,
1089 lifetime_params,
1090 type_params,
1091 ty,
1092 span: Span::new(
1093 start_span.start,
1094 end_span.end,
1095 start_span.line,
1096 start_span.column,
1097 ),
1098 })
1099 }
1100
1101 fn parse_macro(&mut self) -> Result<MacroDef> {
1103 let start_span = self.consume(Token::Macro, "Expected 'macro'")?;
1104
1105 let name = match self.advance()? {
1106 (Token::Identifier(name), _) => name,
1107 (token, _) => {
1108 return Err(CompileError::UnexpectedToken {
1109 expected: "macro name".to_string(),
1110 found: token.to_string(),
1111 span: self.current_span(),
1112 });
1113 }
1114 };
1115
1116 self.consume(Token::Not, "Expected '!' after macro name")?;
1118
1119 let params = if self.check(&Token::LeftParen) {
1121 self.advance()?; let mut params = Vec::new();
1123
1124 while !self.check(&Token::RightParen) && !self.is_at_end() {
1125 match self.advance()? {
1126 (Token::Identifier(param), _) => {
1127 params.push(param);
1128
1129 if self.check(&Token::Comma) {
1130 self.advance()?; } else if !self.check(&Token::RightParen) {
1132 return Err(CompileError::SyntaxError {
1133 message: "Expected ',' or ')' in macro parameters".to_string(),
1134 span: self.current_span(),
1135 });
1136 }
1137 }
1138 (token, _) => {
1139 return Err(CompileError::UnexpectedToken {
1140 expected: "parameter name".to_string(),
1141 found: token.to_string(),
1142 span: self.current_span(),
1143 });
1144 }
1145 }
1146 }
1147
1148 self.consume(Token::RightParen, "Expected ')' after macro parameters")?;
1149 params
1150 } else {
1151 Vec::new()
1152 };
1153
1154 self.consume(Token::LeftBrace, "Expected '{' to start macro body")?;
1156
1157 let mut body = Vec::new();
1158 let mut brace_depth = 1;
1159
1160 while brace_depth > 0 && !self.is_at_end() {
1161 let (token, _) = self.advance()?;
1162
1163 match &token {
1164 Token::LeftBrace => {
1165 brace_depth += 1;
1166 body.push(self.token_to_ast_token(token));
1167 }
1168 Token::RightBrace => {
1169 brace_depth -= 1;
1170 if brace_depth > 0 {
1171 body.push(self.token_to_ast_token(token));
1172 }
1173 }
1174 _ => {
1175 body.push(self.token_to_ast_token(token));
1176 }
1177 }
1178 }
1179
1180 let end_span = self.current_span().unwrap_or(start_span);
1181
1182 Ok(MacroDef {
1183 name,
1184 params,
1185 body,
1186 span: Span::new(
1187 start_span.start,
1188 end_span.end,
1189 start_span.line,
1190 start_span.column,
1191 ),
1192 })
1193 }
1194
1195 fn token_to_ast_token(&self, token: Token) -> crate::ast::Token {
1197 use crate::ast::Token as AstToken;
1198
1199 match token {
1200 Token::Identifier(s) => AstToken::Ident(s),
1201 Token::String(s) => AstToken::Literal(format!("\"{}\"", s)),
1202 Token::Integer(n) => AstToken::Literal(n.to_string()),
1203 Token::True => AstToken::Literal("true".to_string()),
1204 Token::False => AstToken::Literal("false".to_string()),
1205 Token::LeftParen => AstToken::Punct('('),
1206 Token::RightParen => AstToken::Punct(')'),
1207 Token::LeftBrace => AstToken::Punct('{'),
1208 Token::RightBrace => AstToken::Punct('}'),
1209 Token::LeftBracket => AstToken::Punct('['),
1210 Token::RightBracket => AstToken::Punct(']'),
1211 Token::Semicolon => AstToken::Punct(';'),
1212 Token::Comma => AstToken::Punct(','),
1213 Token::Dot => AstToken::Punct('.'),
1214 Token::Plus => AstToken::Punct('+'),
1215 Token::Minus => AstToken::Punct('-'),
1216 Token::Star => AstToken::Punct('*'),
1217 Token::Slash => AstToken::Punct('/'),
1218 Token::Not => AstToken::Punct('!'),
1219 Token::Eq => AstToken::Punct('='),
1220 _ => AstToken::Ident(format!("{:?}", token)), }
1222 }
1223
1224 pub fn parse_statement(&mut self) -> Result<Stmt> {
1226 match self.peek()? {
1227 Token::Let => self.parse_let(),
1228 Token::Return => self.parse_return(),
1229 Token::If => self.parse_if(),
1230 Token::While => self.parse_while(),
1231 Token::For => self.parse_for(),
1232 Token::Break => self.parse_break(),
1233 Token::Continue => self.parse_continue(),
1234 Token::Match => self.parse_match(),
1235 Token::Unsafe => self.parse_unsafe(),
1236 Token::Identifier(_) | Token::Star => {
1237 let checkpoint = self.current;
1240 let expr = self.parse_expression()?; if self.check(&Token::Eq) && !self.check_at(1, &Token::Eq) {
1244 let start_span = expr.span();
1246 self.advance()?; let value = self.parse_expression()?;
1248 let end_span =
1249 self.consume(Token::Semicolon, "Expected ';' after assignment")?;
1250
1251 let target = match expr {
1253 Expr::Ident(name) => AssignTarget::Ident(name),
1254 Expr::Index { array, index, .. } => AssignTarget::Index { array, index },
1255 Expr::FieldAccess { object, field, .. } => {
1256 AssignTarget::FieldAccess { object, field }
1257 }
1258 Expr::Deref { expr, .. } => AssignTarget::Deref { expr },
1259 _ => {
1260 return Err(CompileError::SyntaxError {
1261 message: "Invalid assignment target".to_string(),
1262 span: self.current_span(),
1263 });
1264 }
1265 };
1266
1267 return Ok(Stmt::Assign {
1268 target,
1269 value,
1270 span: Span::new(
1271 start_span.start,
1272 end_span.end,
1273 start_span.line,
1274 start_span.column,
1275 ),
1276 });
1277 }
1278
1279 self.current = checkpoint;
1281 let expr = self.parse_expression()?;
1282 self.consume(Token::Semicolon, "Expected ';' after expression")?;
1283 Ok(Stmt::Expr(expr))
1284 }
1285 _ => {
1286 let expr = self.parse_expression()?;
1288 self.consume(Token::Semicolon, "Expected ';' after expression")?;
1289 Ok(Stmt::Expr(expr))
1290 }
1291 }
1292 }
1293
1294 fn parse_return(&mut self) -> Result<Stmt> {
1296 self.consume(Token::Return, "Expected 'return'")?;
1297
1298 if self.check(&Token::Semicolon) {
1299 self.advance()?;
1300 Ok(Stmt::Return(None))
1301 } else {
1302 let expr = self.parse_expression()?;
1303 self.consume(Token::Semicolon, "Expected ';' after return value")?;
1304 Ok(Stmt::Return(Some(expr)))
1305 }
1306 }
1307
1308 fn parse_let(&mut self) -> Result<Stmt> {
1310 let start_span = self.consume(Token::Let, "Expected 'let'")?;
1311
1312 let mutable = if self.check(&Token::Mut) {
1314 self.advance()?; true
1316 } else {
1317 false
1318 };
1319
1320 let name = match self.advance()? {
1321 (Token::Identifier(name), _) => name,
1322 (token, _) => {
1323 return Err(CompileError::UnexpectedToken {
1324 expected: "variable name".to_string(),
1325 found: token.to_string(),
1326 span: self.current_span(),
1327 });
1328 }
1329 };
1330
1331 let ty = if self.check(&Token::Colon) {
1333 self.advance()?; Some(self.parse_type()?)
1335 } else {
1336 None
1337 };
1338
1339 self.consume(Token::Eq, "Expected '=' after variable name")?;
1340 let value = self.parse_expression()?;
1341 let end_span = self.consume(Token::Semicolon, "Expected ';' after let statement")?;
1342
1343 Ok(Stmt::Let {
1344 name,
1345 ty,
1346 value,
1347 mutable,
1348 span: Span::new(
1349 start_span.start,
1350 end_span.end,
1351 start_span.line,
1352 start_span.column,
1353 ),
1354 })
1355 }
1356
1357 fn parse_if(&mut self) -> Result<Stmt> {
1359 let start_span = self.consume(Token::If, "Expected 'if'")?;
1360
1361 let condition = self.parse_expression()?;
1362
1363 self.consume(Token::LeftBrace, "Expected '{' after if condition")?;
1364
1365 let mut then_branch = Vec::new();
1366 while !self.check(&Token::RightBrace) && !self.is_at_end() {
1367 then_branch.push(self.parse_statement()?);
1368 }
1369
1370 self.consume(Token::RightBrace, "Expected '}' after if body")?;
1371
1372 let else_branch = if self.check(&Token::Else) {
1373 self.advance()?; self.consume(Token::LeftBrace, "Expected '{' after else")?;
1375
1376 let mut else_stmts = Vec::new();
1377 while !self.check(&Token::RightBrace) && !self.is_at_end() {
1378 else_stmts.push(self.parse_statement()?);
1379 }
1380
1381 let _end_span = self.consume(Token::RightBrace, "Expected '}' after else body")?;
1382 Some(else_stmts)
1383 } else {
1384 None
1385 };
1386
1387 let end_span = self.tokens[self.current - 1].1;
1388
1389 Ok(Stmt::If {
1390 condition,
1391 then_branch,
1392 else_branch,
1393 span: Span::new(
1394 start_span.start,
1395 end_span.end,
1396 start_span.line,
1397 start_span.column,
1398 ),
1399 })
1400 }
1401
1402 fn parse_while(&mut self) -> Result<Stmt> {
1404 let start_span = self.consume(Token::While, "Expected 'while'")?;
1405
1406 let condition = self.parse_expression()?;
1407
1408 self.consume(Token::LeftBrace, "Expected '{' after while condition")?;
1409
1410 let mut body = Vec::new();
1411 while !self.check(&Token::RightBrace) && !self.is_at_end() {
1412 body.push(self.parse_statement()?);
1413 }
1414
1415 let end_span = self.consume(Token::RightBrace, "Expected '}' after while body")?;
1416
1417 Ok(Stmt::While {
1418 condition,
1419 body,
1420 span: Span::new(
1421 start_span.start,
1422 end_span.end,
1423 start_span.line,
1424 start_span.column,
1425 ),
1426 })
1427 }
1428
1429 fn parse_for(&mut self) -> Result<Stmt> {
1431 let start_span = self.consume(Token::For, "Expected 'for'")?;
1432
1433 let var = match self.advance()? {
1435 (Token::Identifier(name), _) => name,
1436 (token, _) => {
1437 return Err(CompileError::UnexpectedToken {
1438 expected: "variable name".to_string(),
1439 found: token.to_string(),
1440 span: self.current_span(),
1441 });
1442 }
1443 };
1444
1445 self.consume(Token::In, "Expected 'in' after for variable")?;
1446
1447 let iter = self.parse_expression()?;
1449
1450 self.consume(Token::LeftBrace, "Expected '{' after for header")?;
1451
1452 let mut body = Vec::new();
1453 while !self.check(&Token::RightBrace) && !self.is_at_end() {
1454 body.push(self.parse_statement()?);
1455 }
1456
1457 let end_span = self.consume(Token::RightBrace, "Expected '}' after for body")?;
1458
1459 Ok(Stmt::For {
1460 var,
1461 iter,
1462 body,
1463 span: Span::new(
1464 start_span.start,
1465 end_span.end,
1466 start_span.line,
1467 start_span.column,
1468 ),
1469 })
1470 }
1471
1472 fn parse_break(&mut self) -> Result<Stmt> {
1474 let start_span = self.consume(Token::Break, "Expected 'break'")?;
1475 let end_span = self.consume(Token::Semicolon, "Expected ';' after break")?;
1476
1477 Ok(Stmt::Break {
1478 span: Span::new(
1479 start_span.start,
1480 end_span.end,
1481 start_span.line,
1482 start_span.column,
1483 ),
1484 })
1485 }
1486
1487 fn parse_continue(&mut self) -> Result<Stmt> {
1489 let start_span = self.consume(Token::Continue, "Expected 'continue'")?;
1490 let end_span = self.consume(Token::Semicolon, "Expected ';' after continue")?;
1491
1492 Ok(Stmt::Continue {
1493 span: Span::new(
1494 start_span.start,
1495 end_span.end,
1496 start_span.line,
1497 start_span.column,
1498 ),
1499 })
1500 }
1501
1502 fn parse_match(&mut self) -> Result<Stmt> {
1504 let start_span = self.consume(Token::Match, "Expected 'match'")?;
1505
1506 let expr = self.parse_expression()?;
1507
1508 self.consume(Token::LeftBrace, "Expected '{' after match expression")?;
1509
1510 let mut arms = Vec::new();
1511
1512 while !self.check(&Token::RightBrace) && !self.is_at_end() {
1513 let pattern = self.parse_pattern()?;
1515
1516 self.consume(Token::FatArrow, "Expected '=>' after pattern")?;
1517
1518 let body = if self.check(&Token::LeftBrace) {
1520 self.advance()?; let mut stmts = Vec::new();
1523 while !self.check(&Token::RightBrace) && !self.is_at_end() {
1524 stmts.push(self.parse_statement()?);
1525 }
1526 self.consume(Token::RightBrace, "Expected '}' after match arm body")?;
1527 stmts
1528 } else {
1529 let expr = self.parse_expression()?;
1531 self.consume(Token::Comma, "Expected ',' after match arm expression")?;
1532 vec![Stmt::Expr(expr)]
1533 };
1534
1535 arms.push(MatchArm { pattern, body });
1536 }
1537
1538 let end_span = self.consume(Token::RightBrace, "Expected '}' after match arms")?;
1539
1540 Ok(Stmt::Match {
1541 expr,
1542 arms,
1543 span: Span::new(
1544 start_span.start,
1545 end_span.end,
1546 start_span.line,
1547 start_span.column,
1548 ),
1549 })
1550 }
1551
1552 fn parse_unsafe(&mut self) -> Result<Stmt> {
1554 let start_span = self.consume(Token::Unsafe, "Expected 'unsafe'")?;
1555
1556 self.consume(Token::LeftBrace, "Expected '{' after unsafe")?;
1557
1558 let mut body = Vec::new();
1559 while !self.check(&Token::RightBrace) && !self.is_at_end() {
1560 body.push(self.parse_statement()?);
1561 }
1562
1563 let end_span = self.consume(Token::RightBrace, "Expected '}' after unsafe block")?;
1564
1565 Ok(Stmt::Unsafe {
1566 body,
1567 span: Span::new(
1568 start_span.start,
1569 end_span.end,
1570 start_span.line,
1571 start_span.column,
1572 ),
1573 })
1574 }
1575
1576 fn parse_pattern(&mut self) -> Result<Pattern> {
1578 let token = self.peek()?.clone();
1580
1581 match token {
1582 Token::Underscore => {
1583 self.advance()?;
1584 Ok(Pattern::Wildcard)
1585 }
1586 Token::Identifier(name) => {
1587 self.advance()?;
1588
1589 if self.check(&Token::DoubleColon) {
1591 self.advance()?; let variant = match self.advance()? {
1594 (Token::Identifier(v), _) => v,
1595 (token, _) => {
1596 return Err(CompileError::UnexpectedToken {
1597 expected: "variant name".to_string(),
1598 found: token.to_string(),
1599 span: self.current_span(),
1600 });
1601 }
1602 };
1603
1604 let data = if self.check(&Token::LeftParen) {
1606 self.advance()?; let mut patterns = Vec::new();
1609
1610 if !self.check(&Token::RightParen) {
1611 loop {
1612 patterns.push(self.parse_pattern()?);
1613 if !self.check(&Token::Comma) {
1614 break;
1615 }
1616 self.advance()?; }
1618 }
1619
1620 self.consume(Token::RightParen, "Expected ')' after tuple pattern")?;
1621 Some(PatternData::Tuple(patterns))
1622 } else if self.check(&Token::LeftBrace) {
1623 self.advance()?; let mut fields = Vec::new();
1626
1627 while !self.check(&Token::RightBrace) && !self.is_at_end() {
1628 let field_name = match self.advance()? {
1629 (Token::Identifier(fname), _) => fname,
1630 (token, _) => {
1631 return Err(CompileError::UnexpectedToken {
1632 expected: "field name".to_string(),
1633 found: token.to_string(),
1634 span: self.current_span(),
1635 });
1636 }
1637 };
1638
1639 self.consume(Token::Colon, "Expected ':' after field name in pattern")?;
1640 let field_pattern = self.parse_pattern()?;
1641
1642 fields.push((field_name, field_pattern));
1643
1644 if !self.check(&Token::RightBrace) {
1645 self.consume(Token::Comma, "Expected ',' after field pattern")?;
1646 }
1647 }
1648
1649 self.consume(Token::RightBrace, "Expected '}' after struct pattern")?;
1650 Some(PatternData::Struct(fields))
1651 } else {
1652 None
1653 };
1654
1655 Ok(Pattern::EnumPattern {
1656 enum_name: name,
1657 variant,
1658 data,
1659 })
1660 } else {
1661 Ok(Pattern::Ident(name))
1663 }
1664 }
1665 _ => Err(CompileError::UnexpectedToken {
1666 expected: "pattern".to_string(),
1667 found: token.to_string(),
1668 span: self.current_span(),
1669 }),
1670 }
1671 }
1672
1673 pub fn parse_expression(&mut self) -> Result<Expr> {
1675 self.parse_range()
1676 }
1677
1678 fn parse_range(&mut self) -> Result<Expr> {
1680 let mut left = self.parse_logical_or()?;
1681
1682 while let Ok(token) = self.peek() {
1683 match token {
1684 Token::DotDot => {
1685 let left_span = Self::expr_span(&left);
1686 self.advance()?; let right = self.parse_logical_or()?;
1688 let right_span = Self::expr_span(&right);
1689 left = Expr::Range {
1690 start: Box::new(left),
1691 end: Box::new(right),
1692 span: Span::new(
1693 left_span.start,
1694 right_span.end,
1695 left_span.line,
1696 left_span.column,
1697 ),
1698 };
1699 }
1700 _ => break,
1701 }
1702 }
1703
1704 Ok(left)
1705 }
1706
1707 fn parse_logical_or(&mut self) -> Result<Expr> {
1709 let mut left = self.parse_logical_and()?;
1710
1711 while let Ok(token) = self.peek() {
1712 match token {
1713 Token::OrOr => {
1714 let left_span = Self::expr_span(&left);
1715 let _ = self.advance()?; let right = self.parse_logical_and()?;
1717 let right_span = Self::expr_span(&right);
1718 let span = Span::new(
1719 left_span.start,
1720 right_span.end,
1721 left_span.line,
1722 left_span.column,
1723 );
1724 left = Expr::Binary {
1725 left: Box::new(left),
1726 op: BinOp::Or,
1727 right: Box::new(right),
1728 span,
1729 };
1730 }
1731 _ => break,
1732 }
1733 }
1734
1735 Ok(left)
1736 }
1737
1738 fn parse_logical_and(&mut self) -> Result<Expr> {
1740 let mut left = self.parse_equality()?;
1741
1742 while let Ok(token) = self.peek() {
1743 match token {
1744 Token::AndAnd => {
1745 let left_span = Self::expr_span(&left);
1746 let _ = self.advance()?; let right = self.parse_equality()?;
1748 let right_span = Self::expr_span(&right);
1749 let span = Span::new(
1750 left_span.start,
1751 right_span.end,
1752 left_span.line,
1753 left_span.column,
1754 );
1755 left = Expr::Binary {
1756 left: Box::new(left),
1757 op: BinOp::And,
1758 right: Box::new(right),
1759 span,
1760 };
1761 }
1762 _ => break,
1763 }
1764 }
1765
1766 Ok(left)
1767 }
1768
1769 fn parse_equality(&mut self) -> Result<Expr> {
1771 let mut left = self.parse_comparison()?;
1772
1773 while let Ok(token) = self.peek() {
1774 match token {
1775 Token::EqEq | Token::Ne => {
1776 let left_span = Self::expr_span(&left);
1777 let op = match self.advance()?.0 {
1778 Token::EqEq => BinOp::Eq,
1779 Token::Ne => BinOp::Ne,
1780 _ => unreachable!(),
1781 };
1782 let right = self.parse_comparison()?;
1783 let right_span = Self::expr_span(&right);
1784 let span = Span::new(
1785 left_span.start,
1786 right_span.end,
1787 left_span.line,
1788 left_span.column,
1789 );
1790 left = Expr::Binary {
1791 left: Box::new(left),
1792 op,
1793 right: Box::new(right),
1794 span,
1795 };
1796 }
1797 _ => break,
1798 }
1799 }
1800
1801 Ok(left)
1802 }
1803
1804 fn parse_comparison(&mut self) -> Result<Expr> {
1806 let mut left = self.parse_addition()?;
1807
1808 while let Ok(token) = self.peek() {
1809 match token {
1810 Token::Lt | Token::Gt | Token::Le | Token::Ge => {
1811 let left_span = Self::expr_span(&left);
1812 let op = match self.advance()?.0 {
1813 Token::Lt => BinOp::Lt,
1814 Token::Gt => BinOp::Gt,
1815 Token::Le => BinOp::Le,
1816 Token::Ge => BinOp::Ge,
1817 _ => unreachable!(),
1818 };
1819 let right = self.parse_addition()?;
1820 let right_span = Self::expr_span(&right);
1821 let span = Span::new(
1822 left_span.start,
1823 right_span.end,
1824 left_span.line,
1825 left_span.column,
1826 );
1827 left = Expr::Binary {
1828 left: Box::new(left),
1829 op,
1830 right: Box::new(right),
1831 span,
1832 };
1833 }
1834 _ => break,
1835 }
1836 }
1837
1838 Ok(left)
1839 }
1840
1841 fn parse_addition(&mut self) -> Result<Expr> {
1843 let mut left = self.parse_multiplication()?;
1844
1845 while let Ok(token) = self.peek() {
1846 match token {
1847 Token::Plus | Token::Minus => {
1848 let left_span = Self::expr_span(&left);
1849 let op = match self.advance()?.0 {
1850 Token::Plus => BinOp::Add,
1851 Token::Minus => BinOp::Sub,
1852 _ => unreachable!(),
1853 };
1854 let right = self.parse_multiplication()?;
1855 let right_span = Self::expr_span(&right);
1856 let span = Span::new(
1857 left_span.start,
1858 right_span.end,
1859 left_span.line,
1860 left_span.column,
1861 );
1862 left = Expr::Binary {
1863 left: Box::new(left),
1864 op,
1865 right: Box::new(right),
1866 span,
1867 };
1868 }
1869 _ => break,
1870 }
1871 }
1872
1873 Ok(left)
1874 }
1875
1876 fn parse_multiplication(&mut self) -> Result<Expr> {
1878 let mut left = self.parse_unary()?;
1879
1880 while let Ok(token) = self.peek() {
1881 match token {
1882 Token::Star | Token::Slash | Token::Percent => {
1883 let left_span = Self::expr_span(&left);
1884 let op = match self.advance()?.0 {
1885 Token::Star => BinOp::Mul,
1886 Token::Slash => BinOp::Div,
1887 Token::Percent => BinOp::Mod,
1888 _ => unreachable!(),
1889 };
1890 let right = self.parse_postfix()?;
1891 let right_span = Self::expr_span(&right);
1892 let span = Span::new(
1893 left_span.start,
1894 right_span.end,
1895 left_span.line,
1896 left_span.column,
1897 );
1898 left = Expr::Binary {
1899 left: Box::new(left),
1900 op,
1901 right: Box::new(right),
1902 span,
1903 };
1904 }
1905 _ => break,
1906 }
1907 }
1908
1909 Ok(left)
1910 }
1911
1912 fn parse_type(&mut self) -> Result<Type> {
1914 match self.advance()? {
1915 (Token::SelfType, _) => {
1916 Ok(Type::Custom("Self".to_string()))
1918 }
1919 (Token::Ampersand, _) => {
1920 let mut lifetime = None;
1922 let mut mutable = false;
1923
1924 if matches!(self.peek()?, Token::SingleQuote) {
1926 self.advance()?; match self.advance()? {
1928 (Token::Identifier(lt), _) => {
1929 lifetime = Some(lt);
1930 }
1931 _ => {
1932 return Err(CompileError::UnexpectedToken {
1933 expected: "lifetime name".to_string(),
1934 found: self.peek()?.to_string(),
1935 span: self.current_span(),
1936 });
1937 }
1938 }
1939 }
1940
1941 if matches!(self.peek()?, Token::Mut) {
1943 self.advance()?;
1944 mutable = true;
1945 }
1946
1947 let inner = self.parse_type()?;
1949
1950 Ok(Type::Reference {
1951 lifetime,
1952 mutable,
1953 inner: Box::new(inner),
1954 })
1955 }
1956 (Token::Identifier(name), _) => {
1957 if self.type_params_in_scope.contains(&name) {
1959 return Ok(Type::TypeParam(name));
1960 }
1961
1962 let base_type = match name.as_str() {
1963 "i32" => Type::I32,
1964 "i64" | "int" => Type::I64, "u32" => Type::U32,
1966 "u64" => Type::U64,
1967 "bool" => Type::Bool,
1968 "String" => Type::String,
1969 _ => Type::Custom(name.clone()),
1970 };
1971
1972 if self.check(&Token::Lt) {
1974 match base_type {
1976 Type::Custom(type_name) => {
1977 self.advance()?; let mut args = Vec::new();
1979
1980 loop {
1981 if let Token::Integer(n) = self.peek()? {
1983 let n_val = *n;
1984 self.advance()?; args.push(GenericArg::Const(ConstValue::Integer(n_val)));
1986 } else {
1987 let ty = self.parse_type()?;
1989 match &ty {
1991 Type::Custom(name)
1992 if name
1993 .chars()
1994 .all(|c| c.is_uppercase() || c == '_') =>
1995 {
1996 args.push(GenericArg::Const(ConstValue::ConstParam(
1998 name.clone(),
1999 )));
2000 }
2001 _ => {
2002 args.push(GenericArg::Type(ty));
2003 }
2004 }
2005 }
2006
2007 if !self.check(&Token::Comma) {
2008 break;
2009 }
2010 self.advance()?; }
2012
2013 self.consume(Token::Gt, "Expected '>' after generic arguments")?;
2014 Ok(Type::Generic {
2015 name: type_name,
2016 args,
2017 })
2018 }
2019 _ => {
2020 Err(CompileError::SyntaxError {
2022 message: format!("Type '{}' cannot have generic arguments", name),
2023 span: self.current_span(),
2024 })
2025 }
2026 }
2027 } else {
2028 Ok(base_type)
2029 }
2030 }
2031 (Token::LeftParen, _) => {
2032 self.consume(Token::RightParen, "Expected ')' for unit type")?;
2033 Ok(Type::Unit)
2034 }
2035 (Token::LeftBracket, _) => {
2036 let elem_type = self.parse_type()?;
2038 self.consume(Token::Semicolon, "Expected ';' in array type")?;
2039
2040 let size = match self.peek()? {
2042 Token::Integer(n) => {
2043 let n_val = *n;
2044 self.advance()?; if n_val < 0 {
2046 return Err(CompileError::Generic(
2047 "Array size must be non-negative".to_string(),
2048 ));
2049 }
2050 ArraySize::Literal(n_val as usize)
2051 }
2052 Token::Identifier(name) => {
2053 let name_val = name.clone();
2054 self.advance()?; ArraySize::ConstParam(name_val)
2058 }
2059 token => {
2060 return Err(CompileError::UnexpectedToken {
2061 expected: "array size (integer or const parameter)".to_string(),
2062 found: token.to_string(),
2063 span: self.current_span(),
2064 });
2065 }
2066 };
2067
2068 self.consume(Token::RightBracket, "Expected ']' after array type")?;
2069 Ok(Type::Array(Box::new(elem_type), size))
2070 }
2071 (token, _) => Err(CompileError::UnexpectedToken {
2072 expected: "type".to_string(),
2073 found: token.to_string(),
2074 span: self.current_span(),
2075 }),
2076 }
2077 }
2078
2079 fn parse_primary(&mut self) -> Result<Expr> {
2081 match self.advance()? {
2082 (Token::String(s), _) => Ok(Expr::String(s)),
2083 (Token::Integer(n), _) => Ok(Expr::Integer(n)),
2084 (Token::True, _) => Ok(Expr::Bool(true)),
2085 (Token::False, _) => Ok(Expr::Bool(false)),
2086 (Token::Identifier(name), span) => {
2087 if self.check(&Token::LeftBrace) && self.check_struct_literal_pattern() {
2091 let start_span = span;
2092 self.advance()?; let mut fields = Vec::new();
2095
2096 while !self.check(&Token::RightBrace) && !self.is_at_end() {
2097 let field_name = match self.advance()? {
2099 (Token::Identifier(fname), _) => fname,
2100 (token, _) => {
2101 return Err(CompileError::UnexpectedToken {
2102 expected: "field name".to_string(),
2103 found: token.to_string(),
2104 span: self.current_span(),
2105 });
2106 }
2107 };
2108
2109 self.consume(Token::Colon, "Expected ':' after field name")?;
2110 let field_expr = self.parse_expression()?;
2111
2112 fields.push((field_name, field_expr));
2113
2114 if !self.check(&Token::RightBrace) {
2115 self.consume(Token::Comma, "Expected ',' after field")?;
2116 }
2117 }
2118
2119 let end_span =
2120 self.consume(Token::RightBrace, "Expected '}' after struct fields")?;
2121
2122 Ok(Expr::StructLiteral {
2123 name,
2124 fields,
2125 span: Span::new(
2126 start_span.start,
2127 end_span.end,
2128 start_span.line,
2129 start_span.column,
2130 ),
2131 })
2132 } else {
2133 Ok(Expr::Ident(name))
2134 }
2135 }
2136 (Token::LeftParen, _) => {
2137 let expr = self.parse_expression()?;
2139 self.consume(Token::RightParen, "Expected ')' after expression")?;
2140 Ok(expr)
2141 }
2142 (Token::LeftBracket, span) => {
2143 if self.check(&Token::RightBracket) {
2145 let end_span = self.advance()?.1;
2147 return Ok(Expr::ArrayLiteral {
2148 elements: Vec::new(),
2149 span: Span::new(span.start, end_span.end, span.line, span.column),
2150 });
2151 }
2152
2153 let first_elem = self.parse_expression()?;
2155
2156 if self.check(&Token::Semicolon) {
2158 self.advance()?; let count = self.parse_expression()?;
2160 let end_span =
2161 self.consume(Token::RightBracket, "Expected ']' after array repeat count")?;
2162
2163 Ok(Expr::ArrayRepeat {
2164 value: Box::new(first_elem),
2165 count: Box::new(count),
2166 span: Span::new(span.start, end_span.end, span.line, span.column),
2167 })
2168 } else {
2169 let mut elements = vec![first_elem];
2171
2172 while self.check(&Token::Comma) {
2173 self.advance()?; if self.check(&Token::RightBracket) {
2175 break;
2177 }
2178 elements.push(self.parse_expression()?);
2179 }
2180
2181 let end_span =
2182 self.consume(Token::RightBracket, "Expected ']' after array elements")?;
2183
2184 Ok(Expr::ArrayLiteral {
2185 elements,
2186 span: Span::new(span.start, end_span.end, span.line, span.column),
2187 })
2188 }
2189 }
2190 (token, _) => Err(CompileError::UnexpectedToken {
2191 expected: "expression".to_string(),
2192 found: token.to_string(),
2193 span: self.current_span(),
2194 }),
2195 }
2196 }
2197
2198 fn parse_unary(&mut self) -> Result<Expr> {
2200 match self.peek() {
2201 Ok(Token::Minus) => {
2202 let (_, start_span) = self.advance()?; let operand = self.parse_unary()?; let end_span = operand.span();
2205 Ok(Expr::Unary {
2206 op: UnaryOp::Neg,
2207 operand: Box::new(operand),
2208 span: Span::new(
2209 start_span.start,
2210 end_span.end,
2211 start_span.line,
2212 start_span.column,
2213 ),
2214 })
2215 }
2216 Ok(Token::Not) => {
2217 let (_, start_span) = self.advance()?; let operand = self.parse_unary()?; let end_span = operand.span();
2220 Ok(Expr::Unary {
2221 op: UnaryOp::Not,
2222 operand: Box::new(operand),
2223 span: Span::new(
2224 start_span.start,
2225 end_span.end,
2226 start_span.line,
2227 start_span.column,
2228 ),
2229 })
2230 }
2231 Ok(Token::Ampersand) => {
2232 let (_, start_span) = self.advance()?; let mutable = if matches!(self.peek()?, Token::Mut) {
2234 self.advance()?; true
2236 } else {
2237 false
2238 };
2239 let expr = self.parse_unary()?;
2240 let end_span = expr.span();
2241 Ok(Expr::Reference {
2242 mutable,
2243 expr: Box::new(expr),
2244 span: Span::new(
2245 start_span.start,
2246 end_span.end,
2247 start_span.line,
2248 start_span.column,
2249 ),
2250 })
2251 }
2252 Ok(Token::Star) => {
2253 let (_, start_span) = self.advance()?; let expr = self.parse_unary()?;
2255 let end_span = expr.span();
2256 Ok(Expr::Deref {
2257 expr: Box::new(expr),
2258 span: Span::new(
2259 start_span.start,
2260 end_span.end,
2261 start_span.line,
2262 start_span.column,
2263 ),
2264 })
2265 }
2266 _ => self.parse_postfix(),
2267 }
2268 }
2269
2270 fn parse_postfix(&mut self) -> Result<Expr> {
2272 let mut expr = self.parse_primary()?;
2273
2274 loop {
2275 match self.peek() {
2276 Ok(Token::LeftBracket) => {
2277 let start_span = self.advance()?.1; let index = self.parse_expression()?;
2279 let end_span =
2280 self.consume(Token::RightBracket, "Expected ']' after array index")?;
2281
2282 expr = Expr::Index {
2283 array: Box::new(expr),
2284 index: Box::new(index),
2285 span: Span::new(
2286 start_span.start,
2287 end_span.end,
2288 start_span.line,
2289 start_span.column,
2290 ),
2291 };
2292 }
2293 Ok(Token::LeftParen) => {
2294 let start_span = self.advance()?.1; let mut args = Vec::new();
2297
2298 if !self.check(&Token::RightParen) {
2299 loop {
2300 args.push(self.parse_expression()?);
2301
2302 if !self.check(&Token::Comma) {
2303 break;
2304 }
2305 self.advance()?; }
2307 }
2308
2309 let end_span = self.consume(Token::RightParen, "Expected ')'")?;
2310
2311 expr = Expr::Call {
2312 func: Box::new(expr),
2313 args,
2314 span: Span::new(
2315 start_span.start,
2316 end_span.end,
2317 start_span.line,
2318 start_span.column,
2319 ),
2320 };
2321 }
2322 Ok(Token::Dot) if self.check_at(1, &Token::Await) => {
2323 let start_span = Self::expr_span(&expr);
2324 self.advance()?; let end_span = self.consume(Token::Await, "Expected 'await'")?;
2326
2327 expr = Expr::Await {
2328 expr: Box::new(expr),
2329 span: Span::new(
2330 start_span.start,
2331 end_span.end,
2332 start_span.line,
2333 start_span.column,
2334 ),
2335 };
2336 }
2337 Ok(Token::Dot) => {
2338 let start_span = Self::expr_span(&expr);
2339
2340 self.advance()?; match self.advance()? {
2343 (Token::Identifier(name), span) => {
2344 let end_span = span;
2345 expr = Expr::FieldAccess {
2346 object: Box::new(expr),
2347 field: name,
2348 span: Span::new(
2349 start_span.start,
2350 end_span.end,
2351 start_span.line,
2352 start_span.column,
2353 ),
2354 };
2355 continue;
2356 }
2357 (token, _) => {
2358 return Err(CompileError::UnexpectedToken {
2359 expected: "field name".to_string(),
2360 found: token.to_string(),
2361 span: self.current_span(),
2362 });
2363 }
2364 };
2365 }
2366 Ok(Token::DoubleColon) => {
2367 if let Expr::Ident(enum_name) = expr {
2369 let start_span = self.tokens[self.current - 2].1; self.advance()?; let variant = match self.advance()? {
2373 (Token::Identifier(name), _) => name,
2374 (token, _) => {
2375 return Err(CompileError::UnexpectedToken {
2376 expected: "variant name".to_string(),
2377 found: token.to_string(),
2378 span: self.current_span(),
2379 });
2380 }
2381 };
2382
2383 if self.check(&Token::LeftParen) {
2385 self.advance()?; let mut args = Vec::new();
2388
2389 if !self.check(&Token::RightParen) {
2390 loop {
2391 args.push(self.parse_expression()?);
2392 if !self.check(&Token::Comma) {
2393 break;
2394 }
2395 self.advance()?; }
2397 }
2398
2399 let end_span = self.consume(Token::RightParen, "Expected ')'")?;
2400
2401 expr = Expr::EnumConstructor {
2403 enum_name,
2404 variant,
2405 data: Some(EnumConstructorData::Tuple(args)),
2406 span: Span::new(
2407 start_span.start,
2408 end_span.end,
2409 start_span.line,
2410 start_span.column,
2411 ),
2412 };
2413 continue;
2414 }
2415
2416 let data = if self.check(&Token::LeftBrace) {
2418 self.advance()?; let mut fields = Vec::new();
2421
2422 while !self.check(&Token::RightBrace) && !self.is_at_end() {
2423 let field_name = match self.advance()? {
2424 (Token::Identifier(fname), _) => fname,
2425 (token, _) => {
2426 return Err(CompileError::UnexpectedToken {
2427 expected: "field name".to_string(),
2428 found: token.to_string(),
2429 span: self.current_span(),
2430 });
2431 }
2432 };
2433
2434 self.consume(Token::Colon, "Expected ':' after field name")?;
2435 let field_expr = self.parse_expression()?;
2436
2437 fields.push((field_name, field_expr));
2438
2439 if !self.check(&Token::RightBrace) {
2440 self.consume(Token::Comma, "Expected ',' after field")?;
2441 }
2442 }
2443
2444 let _end_span = self.consume(Token::RightBrace, "Expected '}'")?;
2445 Some(EnumConstructorData::Struct(fields))
2446 } else {
2447 None
2448 };
2449
2450 let end_span = self.tokens[self.current - 1].1; expr = Expr::EnumConstructor {
2452 enum_name,
2453 variant,
2454 data,
2455 span: Span::new(
2456 start_span.start,
2457 end_span.end,
2458 start_span.line,
2459 start_span.column,
2460 ),
2461 };
2462 } else {
2463 return Err(CompileError::SyntaxError {
2464 message: "Double colon can only be used after an identifier"
2465 .to_string(),
2466 span: self.current_span(),
2467 });
2468 }
2469 }
2470 Ok(Token::Question) => {
2471 let start_span = Self::expr_span(&expr);
2472 let (_, end_span) = self.advance()?; expr = Expr::Question {
2475 expr: Box::new(expr),
2476 span: Span::new(
2477 start_span.start,
2478 end_span.end,
2479 start_span.line,
2480 start_span.column,
2481 ),
2482 };
2483 }
2484 Ok(Token::Not) => {
2485 if let Expr::Ident(name) = expr {
2487 let start_span = self.tokens[self.current - 1].1; self.advance()?; self.consume(Token::LeftParen, "Expected '(' after macro name!")?;
2492
2493 let mut args = Vec::new();
2494 let mut paren_depth = 1;
2495
2496 while paren_depth > 0 && !self.is_at_end() {
2497 let (token, _) = self.advance()?;
2498
2499 match &token {
2500 Token::LeftParen => {
2501 paren_depth += 1;
2502 args.push(self.token_to_ast_token(token));
2503 }
2504 Token::RightParen => {
2505 paren_depth -= 1;
2506 if paren_depth > 0 {
2507 args.push(self.token_to_ast_token(token));
2508 }
2509 }
2510 _ => {
2511 args.push(self.token_to_ast_token(token));
2512 }
2513 }
2514 }
2515
2516 let end_span = self.current_span().unwrap_or(start_span);
2517
2518 expr = Expr::MacroInvocation {
2519 name,
2520 args,
2521 span: Span::new(
2522 start_span.start,
2523 end_span.end,
2524 start_span.line,
2525 start_span.column,
2526 ),
2527 };
2528 } else {
2529 return Err(CompileError::SyntaxError {
2530 message: "Macro invocation '!' can only be used after an identifier"
2531 .to_string(),
2532 span: self.current_span(),
2533 });
2534 }
2535 }
2536 _ => break,
2537 }
2538 }
2539
2540 Ok(expr)
2541 }
2542
2543 fn check_struct_literal_pattern(&self) -> bool {
2548 if self.current + 1 >= self.tokens.len() {
2549 return false;
2550 }
2551
2552 match &self.tokens[self.current + 1].0 {
2554 Token::Identifier(_) => {
2555 if self.current + 2 < self.tokens.len() {
2557 matches!(&self.tokens[self.current + 2].0, Token::Colon)
2558 } else {
2559 false
2560 }
2561 }
2562 Token::RightBrace => true, _ => false,
2564 }
2565 }
2566
2567 fn is_at_end(&self) -> bool {
2569 self.current >= self.tokens.len()
2570 }
2571
2572 fn peek(&self) -> Result<&Token> {
2574 if self.is_at_end() {
2575 Err(CompileError::SyntaxError {
2576 message: "Unexpected end of file".to_string(),
2577 span: self.current_span(),
2578 })
2579 } else {
2580 Ok(&self.tokens[self.current].0)
2581 }
2582 }
2583
2584 fn check(&self, token: &Token) -> bool {
2586 if self.is_at_end() {
2587 false
2588 } else {
2589 std::mem::discriminant(&self.tokens[self.current].0) == std::mem::discriminant(token)
2590 }
2591 }
2592
2593 fn check_at(&self, offset: usize, token: &Token) -> bool {
2595 let index = self.current + offset;
2596 if index >= self.tokens.len() {
2597 false
2598 } else {
2599 std::mem::discriminant(&self.tokens[index].0) == std::mem::discriminant(token)
2600 }
2601 }
2602
2603 fn advance(&mut self) -> Result<(Token, Span)> {
2605 if self.is_at_end() {
2606 Err(CompileError::SyntaxError {
2607 message: "Unexpected end of file".to_string(),
2608 span: self.current_span(),
2609 })
2610 } else {
2611 let token = self.tokens[self.current].clone();
2612 self.current += 1;
2613 self.update_cache(); Ok(token)
2615 }
2616 }
2617
2618 fn consume(&mut self, expected: Token, message: &str) -> Result<Span> {
2620 let (token, span) = self.advance()?;
2621
2622 if std::mem::discriminant(&token) == std::mem::discriminant(&expected) {
2623 Ok(span)
2624 } else {
2625 Err(CompileError::UnexpectedToken {
2626 expected: format!("{} ({})", expected, message),
2627 found: token.to_string(),
2628 span: self.current_span(),
2629 })
2630 }
2631 }
2632}
2633
2634#[cfg(test)]
2635mod tests {
2636 use super::*;
2637 use crate::lexer::Lexer;
2638
2639 #[test]
2640 fn test_parse_hello_world() {
2641 let source = r#"
2642 fn main() {
2643 print("Hello, World!");
2644 }
2645 "#;
2646
2647 let mut lexer = Lexer::new(source);
2648 let tokens = lexer.collect_tokens().unwrap();
2649 let mut parser = Parser::new(tokens);
2650 let ast = parser.parse().unwrap();
2651
2652 assert_eq!(ast.items.len(), 1);
2653
2654 if let Item::Function(func) = &ast.items[0] {
2655 assert_eq!(func.name, "main");
2656 assert_eq!(func.params.len(), 0);
2657 assert_eq!(func.return_type, None);
2658 assert_eq!(func.body.len(), 1);
2659
2660 if let Stmt::Expr(Expr::Call { func: _, args, .. }) = &func.body[0] {
2661 assert_eq!(args.len(), 1);
2662 if let Expr::String(s) = &args[0] {
2663 assert_eq!(s, "Hello, World!");
2664 }
2665 }
2666 }
2667 }
2668
2669 #[test]
2670 fn test_parse_function_with_return_type() {
2671 let source = r#"
2672 fn main() -> i32 {
2673 return 0;
2674 }
2675 "#;
2676
2677 let mut lexer = Lexer::new(source);
2678 let tokens = lexer.collect_tokens().unwrap();
2679 let mut parser = Parser::new(tokens);
2680 let ast = parser.parse().unwrap();
2681
2682 assert_eq!(ast.items.len(), 1);
2683
2684 if let Item::Function(func) = &ast.items[0] {
2685 assert_eq!(func.name, "main");
2686 assert_eq!(func.params.len(), 0);
2687 assert_eq!(func.return_type, Some(Type::I32));
2688 assert_eq!(func.body.len(), 1);
2689
2690 if let Stmt::Return(Some(Expr::Integer(n))) = &func.body[0] {
2691 assert_eq!(*n, 0);
2692 } else {
2693 panic!("Expected return statement with integer");
2694 }
2695 }
2696 }
2697
2698 #[test]
2699 fn test_parse_for_loop() {
2700 let source = r#"
2701 fn main() {
2702 for i in arr {
2703 print_int(i);
2704 }
2705 }
2706 "#;
2707
2708 let mut lexer = Lexer::new(source);
2709 let tokens = lexer.collect_tokens().unwrap();
2710 let mut parser = Parser::new(tokens);
2711 let ast = parser.parse().unwrap();
2712
2713 assert_eq!(ast.items.len(), 1);
2714
2715 if let Item::Function(func) = &ast.items[0] {
2716 assert_eq!(func.name, "main");
2717 assert_eq!(func.body.len(), 1);
2718
2719 if let Stmt::For {
2720 var, iter, body, ..
2721 } = &func.body[0]
2722 {
2723 assert_eq!(var, "i");
2724 if let Expr::Ident(name) = iter {
2725 assert_eq!(name, "arr");
2726 }
2727 assert_eq!(body.len(), 1);
2728 } else {
2729 panic!("Expected for loop");
2730 }
2731 } else {
2732 panic!("Expected function");
2733 }
2734 }
2735
2736 #[test]
2737 fn test_parse_break_continue() {
2738 let source = r#"
2739 fn main() {
2740 while true {
2741 if x > 10 {
2742 break;
2743 }
2744 if x == 5 {
2745 continue;
2746 }
2747 }
2748 }
2749 "#;
2750
2751 let mut lexer = Lexer::new(source);
2752 let tokens = lexer.collect_tokens().unwrap();
2753 let mut parser = Parser::new(tokens);
2754 let ast = parser.parse().unwrap();
2755
2756 assert_eq!(ast.items.len(), 1);
2757
2758 if let Item::Function(func) = &ast.items[0] {
2759 assert_eq!(func.body.len(), 1);
2760
2761 if let Stmt::While { body, .. } = &func.body[0] {
2762 assert_eq!(body.len(), 2);
2763
2764 if let Stmt::If { then_branch, .. } = &body[0] {
2765 assert_eq!(then_branch.len(), 1);
2766 assert!(matches!(&then_branch[0], Stmt::Break { .. }));
2767 }
2768
2769 if let Stmt::If { then_branch, .. } = &body[1] {
2770 assert_eq!(then_branch.len(), 1);
2771 assert!(matches!(&then_branch[0], Stmt::Continue { .. }));
2772 }
2773 } else {
2774 panic!("Expected while loop");
2775 }
2776 } else {
2777 panic!("Expected function");
2778 }
2779 }
2780
2781 #[test]
2782 fn test_parse_for_loop_with_break_continue() {
2783 let source = r#"
2784 fn main() {
2785 for i in arr {
2786 if i == 0 {
2787 continue;
2788 }
2789 if i > 10 {
2790 break;
2791 }
2792 print_int(i);
2793 }
2794 }
2795 "#;
2796
2797 let mut lexer = Lexer::new(source);
2798 let tokens = lexer.collect_tokens().unwrap();
2799 let mut parser = Parser::new(tokens);
2800 let ast = parser.parse().unwrap();
2801
2802 assert_eq!(ast.items.len(), 1);
2803
2804 if let Item::Function(func) = &ast.items[0] {
2805 assert_eq!(func.body.len(), 1);
2806
2807 if let Stmt::For { var, body, .. } = &func.body[0] {
2808 assert_eq!(var, "i");
2809 assert_eq!(body.len(), 3);
2810
2811 if let Stmt::If { then_branch, .. } = &body[0] {
2813 assert_eq!(then_branch.len(), 1);
2814 assert!(matches!(&then_branch[0], Stmt::Continue { .. }));
2815 }
2816
2817 if let Stmt::If { then_branch, .. } = &body[1] {
2819 assert_eq!(then_branch.len(), 1);
2820 assert!(matches!(&then_branch[0], Stmt::Break { .. }));
2821 }
2822
2823 assert!(matches!(&body[2], Stmt::Expr(_)));
2825 } else {
2826 panic!("Expected for loop");
2827 }
2828 } else {
2829 panic!("Expected function");
2830 }
2831 }
2832
2833 #[test]
2834 fn test_parse_struct() {
2835 let source = r#"
2836 struct Point {
2837 x: i64,
2838 y: i64,
2839 }
2840
2841 fn main() {
2842 let p = Point { x: 10, y: 20 };
2843 print_int(p.x);
2844 p.y = 30;
2845 }
2846 "#;
2847
2848 let mut lexer = Lexer::new(source);
2849 let tokens = lexer.collect_tokens().unwrap();
2850 let mut parser = Parser::new(tokens);
2851 let ast = parser.parse().unwrap();
2852
2853 assert_eq!(ast.items.len(), 2);
2854
2855 if let Item::Struct(struct_def) = &ast.items[0] {
2857 assert_eq!(struct_def.name, "Point");
2858 assert_eq!(struct_def.fields.len(), 2);
2859 assert_eq!(struct_def.fields[0].0, "x");
2860 assert_eq!(struct_def.fields[0].1, Type::I64);
2861 assert_eq!(struct_def.fields[1].0, "y");
2862 assert_eq!(struct_def.fields[1].1, Type::I64);
2863 } else {
2864 panic!("Expected struct definition");
2865 }
2866
2867 if let Item::Function(func) = &ast.items[1] {
2869 assert_eq!(func.name, "main");
2870 assert_eq!(func.body.len(), 3);
2871
2872 if let Stmt::Let { name, value, .. } = &func.body[0] {
2874 assert_eq!(name, "p");
2875 if let Expr::StructLiteral { name, fields, .. } = value {
2876 assert_eq!(name, "Point");
2877 assert_eq!(fields.len(), 2);
2878 assert_eq!(fields[0].0, "x");
2879 assert_eq!(fields[1].0, "y");
2880 } else {
2881 panic!("Expected struct literal");
2882 }
2883 }
2884
2885 if let Stmt::Expr(Expr::Call { args, .. }) = &func.body[1] {
2887 assert_eq!(args.len(), 1);
2888 if let Expr::FieldAccess { field, .. } = &args[0] {
2889 assert_eq!(field, "x");
2890 } else {
2891 panic!("Expected field access");
2892 }
2893 }
2894
2895 if let Stmt::Assign { target, .. } = &func.body[2] {
2897 if let AssignTarget::FieldAccess { field, .. } = target {
2898 assert_eq!(field, "y");
2899 } else {
2900 panic!("Expected field assignment");
2901 }
2902 }
2903 } else {
2904 panic!("Expected function");
2905 }
2906 }
2907
2908 #[test]
2909 fn test_parse_range_syntax() {
2910 let source = r#"
2911 fn main() {
2912 for i in 0..10 {
2913 print_int(i);
2914 }
2915
2916 let start = 5;
2917 let end = 15;
2918 for j in start..end {
2919 print_int(j);
2920 }
2921
2922 for k in 0..n+1 {
2923 print_int(k);
2924 }
2925 }
2926 "#;
2927
2928 let mut lexer = Lexer::new(source);
2929 let tokens = lexer.collect_tokens().unwrap();
2930 let mut parser = Parser::new(tokens);
2931 let ast = parser.parse().unwrap();
2932
2933 assert_eq!(ast.items.len(), 1);
2934
2935 if let Item::Function(func) = &ast.items[0] {
2936 assert_eq!(func.name, "main");
2937 assert_eq!(func.body.len(), 5); if let Stmt::For { var, iter, .. } = &func.body[0] {
2941 assert_eq!(var, "i");
2942 if let Expr::Range { start, end, .. } = iter {
2943 assert!(matches!(start.as_ref(), Expr::Integer(0)));
2944 assert!(matches!(end.as_ref(), Expr::Integer(10)));
2945 } else {
2946 panic!("Expected range expression");
2947 }
2948 } else {
2949 panic!("Expected for loop");
2950 }
2951
2952 assert!(matches!(&func.body[1], Stmt::Let { name, .. } if name == "start"));
2954 assert!(matches!(&func.body[2], Stmt::Let { name, .. } if name == "end"));
2955
2956 if let Stmt::For { var, iter, .. } = &func.body[3] {
2958 assert_eq!(var, "j");
2959 if let Expr::Range { start, end, .. } = iter {
2960 assert!(matches!(start.as_ref(), Expr::Ident(s) if s == "start"));
2961 assert!(matches!(end.as_ref(), Expr::Ident(e) if e == "end"));
2962 } else {
2963 panic!("Expected range expression");
2964 }
2965 } else {
2966 panic!("Expected for loop");
2967 }
2968
2969 if let Stmt::For { var, iter, .. } = &func.body[4] {
2971 assert_eq!(var, "k");
2972 if let Expr::Range { start, end, .. } = iter {
2973 assert!(matches!(start.as_ref(), Expr::Integer(0)));
2974 assert!(matches!(end.as_ref(), Expr::Binary { .. }));
2976 } else {
2977 panic!("Expected range expression");
2978 }
2979 } else {
2980 panic!("Expected for loop");
2981 }
2982 } else {
2983 panic!("Expected function");
2984 }
2985 }
2986
2987 #[test]
2988 fn test_parse_enum() {
2989 let source = r#"
2990 enum Color {
2991 Red,
2992 Green,
2993 Blue,
2994 }
2995
2996 enum Option {
2997 Some(i64),
2998 None,
2999 }
3000
3001 enum Shape {
3002 Circle { radius: i64 },
3003 Rectangle { width: i64, height: i64 },
3004 Point,
3005 }
3006
3007 fn main() {
3008 let c = Color::Red;
3009 let opt = Option::Some(42);
3010 let shape = Shape::Circle { radius: 10 };
3011 }
3012 "#;
3013
3014 let mut lexer = Lexer::new(source);
3015 let tokens = lexer.collect_tokens().unwrap();
3016 let mut parser = Parser::new(tokens);
3017 let ast = parser.parse().unwrap();
3018
3019 assert_eq!(ast.items.len(), 4);
3020
3021 if let Item::Enum(enum_def) = &ast.items[0] {
3023 assert_eq!(enum_def.name, "Color");
3024 assert_eq!(enum_def.variants.len(), 3);
3025 assert_eq!(enum_def.variants[0].name, "Red");
3026 assert!(matches!(enum_def.variants[0].data, EnumVariantData::Unit));
3027 assert_eq!(enum_def.variants[1].name, "Green");
3028 assert!(matches!(enum_def.variants[1].data, EnumVariantData::Unit));
3029 assert_eq!(enum_def.variants[2].name, "Blue");
3030 assert!(matches!(enum_def.variants[2].data, EnumVariantData::Unit));
3031 } else {
3032 panic!("Expected enum definition");
3033 }
3034
3035 if let Item::Enum(enum_def) = &ast.items[1] {
3037 assert_eq!(enum_def.name, "Option");
3038 assert_eq!(enum_def.variants.len(), 2);
3039 assert_eq!(enum_def.variants[0].name, "Some");
3040 if let EnumVariantData::Tuple(types) = &enum_def.variants[0].data {
3041 assert_eq!(types.len(), 1);
3042 assert_eq!(types[0], Type::I64);
3043 } else {
3044 panic!("Expected tuple variant");
3045 }
3046 assert_eq!(enum_def.variants[1].name, "None");
3047 assert!(matches!(enum_def.variants[1].data, EnumVariantData::Unit));
3048 } else {
3049 panic!("Expected enum definition");
3050 }
3051
3052 if let Item::Enum(enum_def) = &ast.items[2] {
3054 assert_eq!(enum_def.name, "Shape");
3055 assert_eq!(enum_def.variants.len(), 3);
3056
3057 assert_eq!(enum_def.variants[0].name, "Circle");
3058 if let EnumVariantData::Struct(fields) = &enum_def.variants[0].data {
3059 assert_eq!(fields.len(), 1);
3060 assert_eq!(fields[0].0, "radius");
3061 assert_eq!(fields[0].1, Type::I64);
3062 } else {
3063 panic!("Expected struct variant");
3064 }
3065
3066 assert_eq!(enum_def.variants[1].name, "Rectangle");
3067 if let EnumVariantData::Struct(fields) = &enum_def.variants[1].data {
3068 assert_eq!(fields.len(), 2);
3069 assert_eq!(fields[0].0, "width");
3070 assert_eq!(fields[0].1, Type::I64);
3071 assert_eq!(fields[1].0, "height");
3072 assert_eq!(fields[1].1, Type::I64);
3073 } else {
3074 panic!("Expected struct variant");
3075 }
3076
3077 assert_eq!(enum_def.variants[2].name, "Point");
3078 assert!(matches!(enum_def.variants[2].data, EnumVariantData::Unit));
3079 } else {
3080 panic!("Expected enum definition");
3081 }
3082
3083 if let Item::Function(func) = &ast.items[3] {
3085 assert_eq!(func.name, "main");
3086 assert_eq!(func.body.len(), 3);
3087
3088 if let Stmt::Let { name, value, .. } = &func.body[0] {
3090 assert_eq!(name, "c");
3091 if let Expr::EnumConstructor {
3092 enum_name,
3093 variant,
3094 data,
3095 ..
3096 } = value
3097 {
3098 assert_eq!(enum_name, "Color");
3099 assert_eq!(variant, "Red");
3100 assert!(data.is_none());
3101 } else {
3102 panic!("Expected enum constructor");
3103 }
3104 }
3105
3106 if let Stmt::Let { name, value, .. } = &func.body[1] {
3108 assert_eq!(name, "opt");
3109 if let Expr::EnumConstructor {
3110 enum_name,
3111 variant,
3112 data,
3113 ..
3114 } = value
3115 {
3116 assert_eq!(enum_name, "Option");
3117 assert_eq!(variant, "Some");
3118 if let Some(EnumConstructorData::Tuple(args)) = data {
3119 assert_eq!(args.len(), 1);
3120 if let Expr::Integer(n) = &args[0] {
3121 assert_eq!(*n, 42);
3122 } else {
3123 panic!("Expected integer argument");
3124 }
3125 } else {
3126 panic!("Expected tuple constructor data");
3127 }
3128 } else {
3129 panic!("Expected enum constructor");
3130 }
3131 }
3132
3133 if let Stmt::Let { name, value, .. } = &func.body[2] {
3135 assert_eq!(name, "shape");
3136 if let Expr::EnumConstructor {
3137 enum_name,
3138 variant,
3139 data,
3140 ..
3141 } = value
3142 {
3143 assert_eq!(enum_name, "Shape");
3144 assert_eq!(variant, "Circle");
3145 if let Some(EnumConstructorData::Struct(fields)) = data {
3146 assert_eq!(fields.len(), 1);
3147 assert_eq!(fields[0].0, "radius");
3148 if let Expr::Integer(n) = &fields[0].1 {
3149 assert_eq!(*n, 10);
3150 } else {
3151 panic!("Expected integer field value");
3152 }
3153 } else {
3154 panic!("Expected struct constructor data");
3155 }
3156 } else {
3157 panic!("Expected enum constructor");
3158 }
3159 }
3160 } else {
3161 panic!("Expected function");
3162 }
3163 }
3164
3165 #[test]
3166 fn test_parse_match_wildcard() {
3167 let source = r#"
3168 fn main() {
3169 let x = 42;
3170 match x {
3171 _ => print("wildcard"),
3172 }
3173 }
3174 "#;
3175
3176 let mut lexer = Lexer::new(source);
3177 let tokens = lexer.collect_tokens().unwrap();
3178 let mut parser = Parser::new(tokens);
3179 let ast = parser.parse().unwrap();
3180
3181 if let Item::Function(func) = &ast.items[0] {
3182 assert_eq!(func.body.len(), 2);
3183 if let Stmt::Match { arms, .. } = &func.body[1] {
3184 assert_eq!(arms.len(), 1);
3185 match &arms[0].pattern {
3186 Pattern::Wildcard => {}
3187 _ => panic!("Expected wildcard pattern"),
3188 }
3189 assert_eq!(arms[0].body.len(), 1);
3190 } else {
3191 panic!("Expected match statement");
3192 }
3193 } else {
3194 panic!("Expected function");
3195 }
3196 }
3197
3198 #[test]
3199 fn test_parse_match_identifier() {
3200 let source = r#"
3201 fn main() {
3202 match x {
3203 value => print("bound"),
3204 }
3205 }
3206 "#;
3207
3208 let mut lexer = Lexer::new(source);
3209 let tokens = lexer.collect_tokens().unwrap();
3210 let mut parser = Parser::new(tokens);
3211 let ast = parser.parse().unwrap();
3212
3213 if let Item::Function(func) = &ast.items[0] {
3214 if let Stmt::Match { arms, .. } = &func.body[0] {
3215 match &arms[0].pattern {
3216 Pattern::Ident(name) => {
3217 assert_eq!(name, "value");
3218 }
3219 _ => panic!("Expected identifier pattern"),
3220 }
3221 }
3222 }
3223 }
3224
3225 #[test]
3226 fn test_parse_match_enum_patterns() {
3227 let source = r#"
3228 enum Option {
3229 Some(i64),
3230 None,
3231 }
3232
3233 fn main() {
3234 match opt {
3235 Option::Some(n) => print_int(n),
3236 Option::None => print("none"),
3237 }
3238 }
3239 "#;
3240
3241 let mut lexer = Lexer::new(source);
3242 let tokens = lexer.collect_tokens().unwrap();
3243 let mut parser = Parser::new(tokens);
3244 let ast = parser.parse().unwrap();
3245
3246 if let Item::Function(func) = &ast.items[1] {
3247 if let Stmt::Match { arms, .. } = &func.body[0] {
3248 assert_eq!(arms.len(), 2);
3249
3250 match &arms[0].pattern {
3252 Pattern::EnumPattern {
3253 enum_name,
3254 variant,
3255 data,
3256 } => {
3257 assert_eq!(enum_name, "Option");
3258 assert_eq!(variant, "Some");
3259 if let Some(PatternData::Tuple(patterns)) = data {
3260 assert_eq!(patterns.len(), 1);
3261 match &patterns[0] {
3262 Pattern::Ident(name) => assert_eq!(name, "n"),
3263 _ => panic!("Expected identifier pattern in tuple"),
3264 }
3265 } else {
3266 panic!("Expected tuple pattern data");
3267 }
3268 }
3269 _ => panic!("Expected enum pattern"),
3270 }
3271
3272 match &arms[1].pattern {
3274 Pattern::EnumPattern {
3275 enum_name,
3276 variant,
3277 data,
3278 } => {
3279 assert_eq!(enum_name, "Option");
3280 assert_eq!(variant, "None");
3281 assert!(data.is_none());
3282 }
3283 _ => panic!("Expected enum pattern"),
3284 }
3285 }
3286 }
3287 }
3288
3289 #[test]
3290 fn test_parse_match_block_body() {
3291 let source = r#"
3292 fn main() {
3293 match x {
3294 _ => {
3295 print("line 1");
3296 print("line 2");
3297 }
3298 }
3299 }
3300 "#;
3301
3302 let mut lexer = Lexer::new(source);
3303 let tokens = lexer.collect_tokens().unwrap();
3304 let mut parser = Parser::new(tokens);
3305 let ast = parser.parse().unwrap();
3306
3307 if let Item::Function(func) = &ast.items[0] {
3308 if let Stmt::Match { arms, .. } = &func.body[0] {
3309 assert_eq!(arms[0].body.len(), 2);
3310 }
3311 }
3312 }
3313
3314 #[test]
3315 fn test_parse_array_repeat() {
3316 let source = r#"
3317 fn main() {
3318 let arr = [0; 10];
3319 let arr2 = [42; 5];
3320 }
3321 "#;
3322
3323 let mut lexer = Lexer::new(source);
3324 let tokens = lexer.collect_tokens().unwrap();
3325 let mut parser = Parser::new(tokens);
3326 let ast = parser.parse().unwrap();
3327
3328 assert_eq!(ast.items.len(), 1);
3329
3330 if let Item::Function(func) = &ast.items[0] {
3331 assert_eq!(func.name, "main");
3332 assert_eq!(func.body.len(), 2);
3333
3334 if let Stmt::Let { name, value, .. } = &func.body[0] {
3336 assert_eq!(name, "arr");
3337 if let Expr::ArrayRepeat { value, count, .. } = value {
3338 if let Expr::Integer(n) = value.as_ref() {
3339 assert_eq!(*n, 0);
3340 } else {
3341 panic!("Expected integer value");
3342 }
3343 if let Expr::Integer(n) = count.as_ref() {
3344 assert_eq!(*n, 10);
3345 } else {
3346 panic!("Expected integer count");
3347 }
3348 } else {
3349 panic!("Expected array repeat expression");
3350 }
3351 }
3352
3353 if let Stmt::Let { name, value, .. } = &func.body[1] {
3355 assert_eq!(name, "arr2");
3356 if let Expr::ArrayRepeat { value, count, .. } = value {
3357 if let Expr::Integer(n) = value.as_ref() {
3358 assert_eq!(*n, 42);
3359 } else {
3360 panic!("Expected integer value");
3361 }
3362 if let Expr::Integer(n) = count.as_ref() {
3363 assert_eq!(*n, 5);
3364 } else {
3365 panic!("Expected integer count");
3366 }
3367 } else {
3368 panic!("Expected array repeat expression");
3369 }
3370 }
3371 } else {
3372 panic!("Expected function");
3373 }
3374 }
3375
3376 #[test]
3377 fn test_parse_struct_returns() {
3378 let source = r#"
3379 struct Point {
3380 x: i64,
3381 y: i64,
3382 }
3383
3384 fn make_point(x: i64, y: i64) -> Point {
3385 return Point { x: x, y: y };
3386 }
3387
3388 fn get_origin() -> Point {
3389 return Point { x: 0, y: 0 };
3390 }
3391
3392 fn main() {
3393 let p = make_point(10, 20);
3394 let origin = get_origin();
3395 }
3396 "#;
3397
3398 let mut lexer = Lexer::new(source);
3399 let tokens = lexer.collect_tokens().unwrap();
3400 let mut parser = Parser::new(tokens);
3401 let ast = parser.parse().unwrap();
3402
3403 assert_eq!(ast.items.len(), 4);
3404
3405 if let Item::Struct(struct_def) = &ast.items[0] {
3407 assert_eq!(struct_def.name, "Point");
3408 assert_eq!(struct_def.fields.len(), 2);
3409 } else {
3410 panic!("Expected struct definition");
3411 }
3412
3413 if let Item::Function(func) = &ast.items[1] {
3415 assert_eq!(func.name, "make_point");
3416 assert_eq!(func.params.len(), 2);
3417 assert_eq!(func.params[0].name, "x");
3418 assert_eq!(func.params[0].ty, Type::I64);
3419 assert_eq!(func.params[1].name, "y");
3420 assert_eq!(func.params[1].ty, Type::I64);
3421 assert_eq!(func.return_type, Some(Type::Custom("Point".to_string())));
3422
3423 assert_eq!(func.body.len(), 1);
3425 if let Stmt::Return(Some(Expr::StructLiteral { name, fields, .. })) = &func.body[0] {
3426 assert_eq!(name, "Point");
3427 assert_eq!(fields.len(), 2);
3428 assert_eq!(fields[0].0, "x");
3429 assert_eq!(fields[1].0, "y");
3430 } else {
3431 panic!("Expected return with struct literal");
3432 }
3433 } else {
3434 panic!("Expected function");
3435 }
3436
3437 if let Item::Function(func) = &ast.items[2] {
3439 assert_eq!(func.name, "get_origin");
3440 assert_eq!(func.params.len(), 0);
3441 assert_eq!(func.return_type, Some(Type::Custom("Point".to_string())));
3442
3443 assert_eq!(func.body.len(), 1);
3445 if let Stmt::Return(Some(Expr::StructLiteral { name, fields, .. })) = &func.body[0] {
3446 assert_eq!(name, "Point");
3447 assert_eq!(fields.len(), 2);
3448 if let Expr::Integer(n) = &fields[0].1 {
3449 assert_eq!(*n, 0);
3450 }
3451 if let Expr::Integer(n) = &fields[1].1 {
3452 assert_eq!(*n, 0);
3453 }
3454 } else {
3455 panic!("Expected return with struct literal");
3456 }
3457 } else {
3458 panic!("Expected function");
3459 }
3460
3461 if let Item::Function(func) = &ast.items[3] {
3463 assert_eq!(func.name, "main");
3464 assert_eq!(func.body.len(), 2);
3465
3466 if let Stmt::Let { name, value, .. } = &func.body[0] {
3468 assert_eq!(name, "p");
3469 if let Expr::Call { func, args, .. } = value {
3470 if let Expr::Ident(fname) = func.as_ref() {
3471 assert_eq!(fname, "make_point");
3472 }
3473 assert_eq!(args.len(), 2);
3474 } else {
3475 panic!("Expected function call");
3476 }
3477 }
3478
3479 if let Stmt::Let { name, value, .. } = &func.body[1] {
3481 assert_eq!(name, "origin");
3482 if let Expr::Call { func, args, .. } = value {
3483 if let Expr::Ident(fname) = func.as_ref() {
3484 assert_eq!(fname, "get_origin");
3485 }
3486 assert_eq!(args.len(), 0);
3487 } else {
3488 panic!("Expected function call");
3489 }
3490 }
3491 } else {
3492 panic!("Expected function");
3493 }
3494 }
3495
3496 #[test]
3497 fn test_parse_logical_operators() {
3498 let source = r#"
3499 fn main() {
3500 let a = true && false;
3501 let b = true || false;
3502 let c = x < 5 && y > 10;
3503 let d = (a && b) || (c && d);
3504
3505 if a && b || c {
3506 print("complex condition");
3507 }
3508
3509 while i < 10 && running {
3510 i = i + 1;
3511 }
3512 }
3513 "#;
3514
3515 let mut lexer = Lexer::new(source);
3516 let tokens = lexer.collect_tokens().unwrap();
3517 let mut parser = Parser::new(tokens);
3518 let ast = parser.parse().unwrap();
3519
3520 assert_eq!(ast.items.len(), 1);
3521
3522 if let Item::Function(func) = &ast.items[0] {
3523 assert_eq!(func.name, "main");
3524 assert_eq!(func.body.len(), 6);
3525
3526 if let Stmt::Let { name, value, .. } = &func.body[0] {
3528 assert_eq!(name, "a");
3529 if let Expr::Binary {
3530 op, left, right, ..
3531 } = value
3532 {
3533 assert_eq!(*op, BinOp::And);
3534 assert!(matches!(left.as_ref(), Expr::Bool(true)));
3535 assert!(matches!(right.as_ref(), Expr::Bool(false)));
3536 } else {
3537 panic!("Expected && expression");
3538 }
3539 }
3540
3541 if let Stmt::Let { name, value, .. } = &func.body[1] {
3543 assert_eq!(name, "b");
3544 if let Expr::Binary {
3545 op, left, right, ..
3546 } = value
3547 {
3548 assert_eq!(*op, BinOp::Or);
3549 assert!(matches!(left.as_ref(), Expr::Bool(true)));
3550 assert!(matches!(right.as_ref(), Expr::Bool(false)));
3551 } else {
3552 panic!("Expected || expression");
3553 }
3554 }
3555
3556 if let Stmt::Let { name, value, .. } = &func.body[2] {
3558 assert_eq!(name, "c");
3559 if let Expr::Binary {
3560 op, left, right, ..
3561 } = value
3562 {
3563 assert_eq!(*op, BinOp::And);
3564 if let Expr::Binary { op: left_op, .. } = left.as_ref() {
3566 assert_eq!(*left_op, BinOp::Lt);
3567 } else {
3568 panic!("Expected comparison on left side of &&");
3569 }
3570 if let Expr::Binary { op: right_op, .. } = right.as_ref() {
3572 assert_eq!(*right_op, BinOp::Gt);
3573 } else {
3574 panic!("Expected comparison on right side of &&");
3575 }
3576 } else {
3577 panic!("Expected && expression");
3578 }
3579 }
3580
3581 if let Stmt::Let { name, value, .. } = &func.body[3] {
3583 assert_eq!(name, "d");
3584 if let Expr::Binary { op, .. } = value {
3585 assert_eq!(*op, BinOp::Or);
3586 } else {
3587 panic!("Expected || at top level");
3588 }
3589 }
3590
3591 if let Stmt::If { condition, .. } = &func.body[4] {
3593 if let Expr::Binary { op, .. } = condition {
3594 assert_eq!(*op, BinOp::Or); } else {
3596 panic!("Expected logical expression in if condition");
3597 }
3598 }
3599
3600 if let Stmt::While { condition, .. } = &func.body[5] {
3602 if let Expr::Binary { op, .. } = condition {
3603 assert_eq!(*op, BinOp::And);
3604 } else {
3605 panic!("Expected && in while condition");
3606 }
3607 }
3608 } else {
3609 panic!("Expected function");
3610 }
3611 }
3612}