1use crate::ast::*;
6use crate::lexer::{Lexer, Token};
7use crate::span::{Span, Spanned};
8use thiserror::Error;
9
10#[derive(Error, Debug)]
11pub enum ParseError {
12 #[error("Unexpected token: expected {expected}, found {found:?} at {span}")]
13 UnexpectedToken {
14 expected: String,
15 found: Token,
16 span: Span,
17 },
18 #[error("Unexpected end of file")]
19 UnexpectedEof,
20 #[error("Invalid number literal: {0}")]
21 InvalidNumber(String),
22 #[error("Parse error: {0}")]
23 Custom(String),
24}
25
26pub type ParseResult<T> = Result<T, ParseError>;
27
28pub struct Parser<'a> {
30 lexer: Lexer<'a>,
31 current: Option<(Token, Span)>,
32 in_condition: bool,
34 pending_gt: Option<Span>,
36}
37
38impl<'a> Parser<'a> {
39 pub fn new(source: &'a str) -> Self {
40 let mut lexer = Lexer::new(source);
41 let current = lexer.next_token();
42 Self {
43 lexer,
44 current,
45 in_condition: false,
46 pending_gt: None,
47 }
48 }
49
50 pub fn parse_file(&mut self) -> ParseResult<SourceFile> {
52 let mut attrs = Vec::new();
54 while matches!(self.current_token(), Some(Token::HashBang)) {
55 attrs.push(self.parse_inner_attribute()?);
56 }
57
58 let config = self.build_crate_config(&attrs);
60
61 let mut items = Vec::new();
62 while !self.is_eof() {
63 while matches!(
65 self.current_token(),
66 Some(
67 Token::LineComment(_)
68 | Token::TildeComment(_)
69 | Token::BlockComment(_)
70 | Token::DocComment(_)
71 )
72 ) {
73 self.advance();
74 }
75 if self.is_eof() {
76 break;
77 }
78 items.push(self.parse_item()?);
79 }
80 Ok(SourceFile {
81 attrs,
82 config,
83 items,
84 })
85 }
86
87 fn parse_inner_attribute(&mut self) -> ParseResult<Attribute> {
89 self.expect(Token::HashBang)?;
90 self.expect(Token::LBracket)?;
91
92 let name = self.parse_ident()?;
93 let args = self.parse_attr_args()?;
94
95 self.expect(Token::RBracket)?;
96
97 Ok(Attribute {
98 name,
99 args,
100 is_inner: true,
101 })
102 }
103
104 fn parse_outer_attribute(&mut self) -> ParseResult<Attribute> {
108 let is_at_syntax = self.check(&Token::At);
110 if is_at_syntax {
111 self.advance();
112 } else {
113 self.expect(Token::Hash)?;
114 }
115 self.expect(Token::LBracket)?;
116
117 let name = self.parse_attr_name()?;
118
119 if is_at_syntax && self.check(&Token::Comma) && !self.check(&Token::LParen) {
122 let mut args = vec![AttrArg::Ident(name)];
124 while self.consume_if(&Token::Comma) {
125 if self.check(&Token::RBracket) {
126 break; }
128 args.push(AttrArg::Ident(self.parse_attr_name()?));
129 }
130 self.expect(Token::RBracket)?;
131
132 Ok(Attribute {
134 name: Ident {
135 name: "derive".to_string(),
136 evidentiality: None,
137 affect: None,
138 span: self.current_span(),
139 },
140 args: Some(AttrArgs::Paren(args)),
141 is_inner: false,
142 })
143 } else {
144 let args = self.parse_attr_args()?;
145 self.expect(Token::RBracket)?;
146
147 Ok(Attribute {
148 name,
149 args,
150 is_inner: false,
151 })
152 }
153 }
154
155 fn parse_attr_name(&mut self) -> ParseResult<Ident> {
157 let span = self.current_span();
158 let first_name = match self.current_token().cloned() {
159 Some(Token::Ident(name)) => {
160 self.advance();
161 name
162 }
163 Some(Token::Naked) => {
165 self.advance();
166 "naked".to_string()
167 }
168 Some(Token::Unsafe) => {
169 self.advance();
170 "unsafe".to_string()
171 }
172 Some(Token::Asm) => {
173 self.advance();
174 "asm".to_string()
175 }
176 Some(Token::Volatile) => {
177 self.advance();
178 "volatile".to_string()
179 }
180 Some(Token::Derive) => {
181 self.advance();
182 "derive".to_string()
183 }
184 Some(Token::Simd) => {
185 self.advance();
186 "simd".to_string()
187 }
188 Some(Token::Atomic) => {
189 self.advance();
190 "atomic".to_string()
191 }
192 Some(Token::Macro) => {
193 self.advance();
194 "macro".to_string()
195 }
196 Some(t) => {
197 return Err(ParseError::UnexpectedToken {
198 expected: "attribute name".to_string(),
199 found: t,
200 span,
201 })
202 }
203 None => return Err(ParseError::UnexpectedEof),
204 };
205
206 let mut full_name = first_name;
208 while self.consume_if(&Token::ColonColon) {
209 let segment = match self.current_token().cloned() {
210 Some(Token::Ident(name)) => {
211 self.advance();
212 name
213 }
214 Some(t) => {
215 return Err(ParseError::UnexpectedToken {
216 expected: "identifier after ::".to_string(),
217 found: t,
218 span: self.current_span(),
219 })
220 }
221 None => return Err(ParseError::UnexpectedEof),
222 };
223 full_name = format!("{}::{}", full_name, segment);
224 }
225
226 Ok(Ident {
227 name: full_name,
228 evidentiality: None,
229 affect: None,
230 span,
231 })
232 }
233
234 fn parse_attr_args(&mut self) -> ParseResult<Option<AttrArgs>> {
236 if self.consume_if(&Token::LParen) {
237 let mut args = Vec::new();
238
239 while !self.check(&Token::RParen) {
240 args.push(self.parse_attr_arg()?);
241 if !self.consume_if(&Token::Comma) {
242 break;
243 }
244 }
245
246 self.expect(Token::RParen)?;
247 Ok(Some(AttrArgs::Paren(args)))
248 } else if self.consume_if(&Token::Eq) {
249 let expr = self.parse_expr()?;
250 Ok(Some(AttrArgs::Eq(Box::new(expr))))
251 } else {
252 Ok(None)
253 }
254 }
255
256 fn parse_attr_arg(&mut self) -> ParseResult<AttrArg> {
258 match self.current_token().cloned() {
259 Some(Token::StringLit(s)) => {
260 self.advance();
261 Ok(AttrArg::Literal(Literal::String(s)))
262 }
263 Some(Token::IntLit(s)) => {
264 self.advance();
265 Ok(AttrArg::Literal(Literal::Int {
266 value: s,
267 base: NumBase::Decimal,
268 suffix: None,
269 }))
270 }
271 Some(Token::HexLit(s)) => {
272 self.advance();
273 Ok(AttrArg::Literal(Literal::Int {
274 value: s,
275 base: NumBase::Hex,
276 suffix: None,
277 }))
278 }
279 Some(Token::BinaryLit(s)) => {
280 self.advance();
281 Ok(AttrArg::Literal(Literal::Int {
282 value: s,
283 base: NumBase::Binary,
284 suffix: None,
285 }))
286 }
287 Some(Token::OctalLit(s)) => {
288 self.advance();
289 Ok(AttrArg::Literal(Literal::Int {
290 value: s,
291 base: NumBase::Octal,
292 suffix: None,
293 }))
294 }
295 Some(Token::Ident(_)) => {
296 let ident = self.parse_ident()?;
297 self.parse_attr_arg_after_ident(ident)
298 }
299 Some(Token::Asm) => {
301 let span = self.current_span();
302 self.advance();
303 let ident = Ident {
304 name: "asm".to_string(),
305 evidentiality: None,
306 affect: None,
307 span,
308 };
309 self.parse_attr_arg_after_ident(ident)
310 }
311 Some(Token::Volatile) => {
312 let span = self.current_span();
313 self.advance();
314 let ident = Ident {
315 name: "volatile".to_string(),
316 evidentiality: None,
317 affect: None,
318 span,
319 };
320 self.parse_attr_arg_after_ident(ident)
321 }
322 Some(Token::Naked) => {
323 let span = self.current_span();
324 self.advance();
325 let ident = Ident {
326 name: "naked".to_string(),
327 evidentiality: None,
328 affect: None,
329 span,
330 };
331 self.parse_attr_arg_after_ident(ident)
332 }
333 Some(Token::Packed) => {
334 let span = self.current_span();
335 self.advance();
336 let ident = Ident {
337 name: "packed".to_string(),
338 evidentiality: None,
339 affect: None,
340 span,
341 };
342 self.parse_attr_arg_after_ident(ident)
343 }
344 Some(Token::Unsafe) => {
345 let span = self.current_span();
346 self.advance();
347 let ident = Ident {
348 name: "unsafe".to_string(),
349 evidentiality: None,
350 affect: None,
351 span,
352 };
353 self.parse_attr_arg_after_ident(ident)
354 }
355 Some(t) => Err(ParseError::UnexpectedToken {
356 expected: "attribute argument".to_string(),
357 found: t,
358 span: self.current_span(),
359 }),
360 None => Err(ParseError::UnexpectedEof),
361 }
362 }
363
364 fn parse_attr_arg_after_ident(&mut self, ident: Ident) -> ParseResult<AttrArg> {
366 if self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
368 let mut path_parts = vec![ident.name.clone()];
369 loop {
370 let part = self.parse_ident()?;
371 path_parts.push(part.name);
372 if !self.consume_if(&Token::ColonColon) && !self.consume_if(&Token::MiddleDot) {
373 break;
374 }
375 }
376 let full_path = path_parts.join("::");
378 return Ok(AttrArg::Ident(Ident {
379 name: full_path,
380 evidentiality: None,
381 affect: None,
382 span: ident.span.clone(),
383 }));
384 }
385 if self.consume_if(&Token::Eq) {
387 let value = self.parse_expr()?;
388 Ok(AttrArg::KeyValue {
389 key: ident,
390 value: Box::new(value),
391 })
392 }
393 else if self.check(&Token::LParen) {
395 let args = self.parse_attr_args()?;
396 Ok(AttrArg::Nested(Attribute {
397 name: ident,
398 args,
399 is_inner: false,
400 }))
401 }
402 else {
404 Ok(AttrArg::Ident(ident))
405 }
406 }
407
408 fn parse_interpolation_parts(&mut self, s: &str) -> ParseResult<Vec<InterpolationPart>> {
411 let mut parts = Vec::new();
412 let mut current_text = String::new();
413 let mut chars = s.chars().peekable();
414 let mut brace_depth = 0;
415 let mut expr_content = String::new();
416 let mut in_expr = false;
417
418 while let Some(c) = chars.next() {
419 if in_expr {
420 if c == '{' {
421 brace_depth += 1;
422 expr_content.push(c);
423 } else if c == '}' {
424 if brace_depth > 0 {
425 brace_depth -= 1;
426 expr_content.push(c);
427 } else {
428 in_expr = false;
430 if !expr_content.is_empty() {
431 let mut expr_parser = Parser::new(&expr_content);
433 match expr_parser.parse_expr() {
434 Ok(expr) => {
435 parts.push(InterpolationPart::Expr(Box::new(expr)));
436 }
437 Err(_) => {
438 parts.push(InterpolationPart::Text(format!(
440 "{{{}}}",
441 expr_content
442 )));
443 }
444 }
445 }
446 expr_content.clear();
447 }
448 } else {
449 expr_content.push(c);
450 }
451 } else if c == '{' {
452 if chars.peek() == Some(&'{') {
453 chars.next();
455 current_text.push('{');
456 } else {
457 if !current_text.is_empty() {
459 parts.push(InterpolationPart::Text(current_text.clone()));
460 current_text.clear();
461 }
462 in_expr = true;
463 }
464 } else if c == '}' {
465 if chars.peek() == Some(&'}') {
466 chars.next();
468 current_text.push('}');
469 } else {
470 current_text.push(c);
471 }
472 } else {
473 current_text.push(c);
474 }
475 }
476
477 if !current_text.is_empty() {
479 parts.push(InterpolationPart::Text(current_text));
480 }
481
482 if parts.is_empty() {
484 parts.push(InterpolationPart::Text(String::new()));
485 }
486
487 Ok(parts)
488 }
489
490 fn build_crate_config(&self, attrs: &[Attribute]) -> CrateConfig {
492 let mut config = CrateConfig::default();
493 let mut linker = LinkerConfig::default();
494 let mut has_linker_config = false;
495
496 for attr in attrs {
497 match attr.name.name.as_str() {
498 "no_std" => config.no_std = true,
499 "no_main" => config.no_main = true,
500 "feature" => {
501 if let Some(AttrArgs::Paren(args)) = &attr.args {
502 for arg in args {
503 if let AttrArg::Ident(ident) = arg {
504 config.features.push(ident.name.clone());
505 }
506 }
507 }
508 }
509 "target" => {
510 let mut target = TargetConfig::default();
511 if let Some(AttrArgs::Paren(args)) = &attr.args {
512 for arg in args {
513 if let AttrArg::KeyValue { key, value } = arg {
514 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
515 match key.name.as_str() {
516 "arch" => target.arch = Some(s.clone()),
517 "os" => target.os = Some(s.clone()),
518 "abi" => target.abi = Some(s.clone()),
519 _ => {}
520 }
521 }
522 }
523 }
524 }
525 config.target = Some(target);
526 }
527 "linker_script" => {
529 if let Some(AttrArgs::Eq(value)) = &attr.args {
530 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
531 linker.script = Some(s.clone());
532 has_linker_config = true;
533 }
534 }
535 }
536 "entry_point" => {
537 if let Some(AttrArgs::Eq(value)) = &attr.args {
538 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
539 linker.entry_point = Some(s.clone());
540 has_linker_config = true;
541 }
542 }
543 }
544 "base_address" => {
545 if let Some(AttrArgs::Eq(value)) = &attr.args {
546 if let Expr::Literal(Literal::Int { value: s, base, .. }) = value.as_ref() {
547 let addr = Self::parse_int_value(s, *base);
548 linker.base_address = Some(addr);
549 has_linker_config = true;
550 }
551 }
552 }
553 "stack_size" => {
554 if let Some(AttrArgs::Eq(value)) = &attr.args {
555 if let Expr::Literal(Literal::Int { value: s, base, .. }) = value.as_ref() {
556 let size = Self::parse_int_value(s, *base);
557 linker.stack_size = Some(size);
558 has_linker_config = true;
559 }
560 }
561 }
562 "link" => {
563 if let Some(AttrArgs::Paren(args)) = &attr.args {
565 for arg in args {
566 if let AttrArg::KeyValue { key, value } = arg {
567 if key.name == "flag" {
568 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
569 linker.flags.push(s.clone());
570 has_linker_config = true;
571 }
572 }
573 }
574 }
575 }
576 }
577 _ => {}
578 }
579 }
580
581 if has_linker_config {
582 config.linker = Some(linker);
583 }
584
585 config
586 }
587
588 fn parse_int_value(s: &str, base: NumBase) -> u64 {
590 let (stripped, radix) = match base {
592 NumBase::Binary => (
593 s.strip_prefix("0b").or(s.strip_prefix("0B")).unwrap_or(s),
594 2,
595 ),
596 NumBase::Octal => (
597 s.strip_prefix("0o").or(s.strip_prefix("0O")).unwrap_or(s),
598 8,
599 ),
600 NumBase::Decimal => (s, 10),
601 NumBase::Hex => (
602 s.strip_prefix("0x").or(s.strip_prefix("0X")).unwrap_or(s),
603 16,
604 ),
605 NumBase::Vigesimal => (
606 s.strip_prefix("0v").or(s.strip_prefix("0V")).unwrap_or(s),
607 20,
608 ),
609 NumBase::Duodecimal => (
610 s.strip_prefix("0d").or(s.strip_prefix("0D")).unwrap_or(s),
611 12,
612 ),
613 NumBase::Sexagesimal => (
614 s.strip_prefix("0s").or(s.strip_prefix("0S")).unwrap_or(s),
615 60,
616 ),
617 NumBase::Explicit(r) => (s, r as u32),
618 };
619 let clean: String = stripped.chars().filter(|c| *c != '_').collect();
621 u64::from_str_radix(&clean, radix).unwrap_or(0)
622 }
623
624 pub(crate) fn current_token(&self) -> Option<&Token> {
627 self.current.as_ref().map(|(t, _)| t)
628 }
629
630 pub(crate) fn current_span(&self) -> Span {
631 self.current.as_ref().map(|(_, s)| *s).unwrap_or_default()
632 }
633
634 pub(crate) fn advance(&mut self) -> Option<(Token, Span)> {
635 let prev = self.current.take();
636 self.current = self.lexer.next_token();
637 prev
638 }
639
640 pub(crate) fn is_eof(&self) -> bool {
641 self.current.is_none()
642 }
643
644 pub(crate) fn expect(&mut self, expected: Token) -> ParseResult<Span> {
645 match &self.current {
646 Some((token, span))
647 if std::mem::discriminant(token) == std::mem::discriminant(&expected) =>
648 {
649 let span = *span;
650 self.advance();
651 Ok(span)
652 }
653 Some((token, span)) => Err(ParseError::UnexpectedToken {
654 expected: format!("{:?}", expected),
655 found: token.clone(),
656 span: *span,
657 }),
658 None => Err(ParseError::UnexpectedEof),
659 }
660 }
661
662 pub(crate) fn check(&self, expected: &Token) -> bool {
663 matches!(&self.current, Some((token, _)) if std::mem::discriminant(token) == std::mem::discriminant(expected))
664 }
665
666 pub(crate) fn peek_next(&mut self) -> Option<&Token> {
668 self.lexer.peek().map(|(t, _)| t)
669 }
670
671 pub(crate) fn peek_n(&mut self, n: usize) -> Option<&Token> {
673 self.lexer.peek_n(n).map(|(t, _)| t)
674 }
675
676 pub(crate) fn consume_if(&mut self, expected: &Token) -> bool {
677 if self.check(expected) {
678 self.advance();
679 true
680 } else {
681 false
682 }
683 }
684
685 pub(crate) fn skip_comments(&mut self) {
687 while matches!(
688 self.current_token(),
689 Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
690 | Some(Token::DocComment(_))
691 ) {
692 self.advance();
693 }
694 }
695
696 pub(crate) fn check_gt(&self) -> bool {
698 self.pending_gt.is_some() || self.check(&Token::Gt)
699 }
700
701 pub(crate) fn expect_gt(&mut self) -> ParseResult<Span> {
704 if let Some(span) = self.pending_gt.take() {
706 return Ok(span);
707 }
708
709 match &self.current {
710 Some((Token::Gt, span)) => {
711 let span = *span;
712 self.advance();
713 Ok(span)
714 }
715 Some((Token::Shr, span)) => {
716 let span = *span;
719 self.pending_gt = Some(span);
720 self.advance();
721 Ok(span)
722 }
723 Some((token, span)) => Err(ParseError::UnexpectedToken {
724 expected: "Gt".to_string(),
725 found: token.clone(),
726 span: *span,
727 }),
728 None => Err(ParseError::UnexpectedEof),
729 }
730 }
731
732 fn consume_gt(&mut self) -> bool {
734 if self.pending_gt.is_some() {
735 self.pending_gt = None;
736 return true;
737 }
738 if self.check(&Token::Gt) {
739 self.advance();
740 return true;
741 }
742 if self.check(&Token::Shr) {
744 let span = self.current_span();
745 self.pending_gt = Some(span);
746 self.advance();
747 return true;
748 }
749 false
750 }
751
752 fn can_start_item(&self) -> bool {
755 matches!(
756 self.current_token(),
757 Some(
758 Token::Pub
759 | Token::Fn
760 | Token::Async
761 | Token::Struct
762 | Token::Enum
763 | Token::Trait
764 | Token::Impl
765 | Token::Type
766 | Token::Mod
767 | Token::Use
768 | Token::Const
769 | Token::Static
770 | Token::Actor
771 | Token::Extern
772 | Token::Hash
773 | Token::At
774 | Token::Naked
775 | Token::Packed
776 | Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
777 | Token::DocComment(_)
778 | Token::Alter
780 | Token::Headspace
781 | Token::Reality
782 | Token::CoCon
783 )
784 ) || (matches!(self.current_token(), Some(Token::On)) && self.peek_next_is_trigger())
785 }
786
787 fn peek_next_is_trigger(&self) -> bool {
789 false }
792
793 fn can_start_stmt(&self) -> bool {
796 if let Some(token) = self.current_token() {
798 if Self::keyword_as_ident(token).is_some() {
799 return true;
800 }
801 }
802 matches!(
803 self.current_token(),
804 Some(
805 Token::Let
806 | Token::If
807 | Token::Match
808 | Token::Loop
809 | Token::While
810 | Token::For
811 | Token::Return
812 | Token::Break
813 | Token::Continue
814 | Token::Ident(_)
815 | Token::SelfLower
816 | Token::SelfUpper
817 | Token::LParen
818 | Token::LBracket
819 | Token::LBrace
820 | Token::StringLit(_)
822 | Token::IntLit(_)
823 | Token::FloatLit(_)
824 | Token::True
825 | Token::False
826 | Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
827 | Token::DocComment(_)
828 )
829 ) || self.can_start_item()
830 }
831
832 fn expect_semi_or_item_start(&mut self) -> ParseResult<()> {
835 if self.consume_if(&Token::Semi) {
836 return Ok(());
837 }
838 if self.can_start_item() || self.is_eof() || self.check(&Token::RBrace) {
839 return Ok(());
841 }
842 let span = self.current_span();
843 Err(ParseError::UnexpectedToken {
844 expected: "`;` or new item".to_string(),
845 found: self.current_token().cloned().unwrap_or(Token::Semi),
846 span,
847 })
848 }
849
850 fn parse_item(&mut self) -> ParseResult<Spanned<Item>> {
853 let start_span = self.current_span();
854
855 let mut outer_attrs = Vec::new();
857 while self.check(&Token::Hash) || self.check(&Token::At) {
858 outer_attrs.push(self.parse_outer_attribute()?);
859 }
860
861 let visibility = self.parse_visibility()?;
862
863 let item = match self.current_token() {
864 Some(Token::Fn) | Some(Token::Async) => {
865 Item::Function(self.parse_function_with_attrs(visibility, outer_attrs)?)
866 }
867 Some(Token::Struct) => {
868 Item::Struct(self.parse_struct_with_attrs(visibility, outer_attrs)?)
869 }
870 Some(Token::Enum) => Item::Enum(self.parse_enum(visibility)?),
871 Some(Token::Trait) => Item::Trait(self.parse_trait(visibility)?),
872 Some(Token::Impl) => Item::Impl(self.parse_impl()?),
873 Some(Token::Unsafe) => {
874 self.advance(); match self.current_token() {
877 Some(Token::Impl) => Item::Impl(self.parse_impl()?),
878 Some(Token::Fn) | Some(Token::Async) => {
879 Item::Function(self.parse_function_with_attrs(visibility, outer_attrs)?)
880 }
881 Some(Token::Trait) => Item::Trait(self.parse_trait(visibility)?),
882 Some(t) => {
883 return Err(ParseError::UnexpectedToken {
884 expected: "impl, fn, or trait after unsafe".to_string(),
885 found: t.clone(),
886 span: self.current_span(),
887 })
888 }
889 None => return Err(ParseError::UnexpectedEof),
890 }
891 }
892 Some(Token::Type) => Item::TypeAlias(self.parse_type_alias(visibility)?),
893 Some(Token::Mod) => Item::Module(self.parse_module(visibility)?),
894 Some(Token::Use) => Item::Use(self.parse_use(visibility)?),
895 Some(Token::Const) => {
896 if self
898 .peek_next()
899 .map(|t| matches!(t, Token::Fn | Token::Async))
900 == Some(true)
901 {
902 Item::Function(self.parse_function_with_attrs(visibility, outer_attrs)?)
903 } else {
904 Item::Const(self.parse_const(visibility)?)
905 }
906 }
907 Some(Token::Static) => Item::Static(self.parse_static(visibility)?),
908 Some(Token::Actor) => Item::Actor(self.parse_actor(visibility)?),
909 Some(Token::Extern) => Item::ExternBlock(self.parse_extern_block()?),
910 Some(Token::Macro) | Some(Token::MacroRules) => {
911 Item::Macro(self.parse_macro_def(visibility)?)
912 }
913 Some(Token::Naked) => {
914 Item::Function(self.parse_function_with_attrs(visibility, outer_attrs)?)
916 }
917 Some(Token::Packed) => {
918 Item::Struct(self.parse_struct_with_attrs(visibility, outer_attrs)?)
920 }
921 Some(Token::Alter) => {
923 use crate::plurality::PluralityParser;
924 Item::Plurality(crate::plurality::PluralityItem::Alter(
925 self.parse_alter_def(visibility)?,
926 ))
927 }
928 Some(Token::Headspace) => {
929 use crate::plurality::PluralityParser;
930 Item::Plurality(crate::plurality::PluralityItem::Headspace(
931 self.parse_headspace_def(visibility)?,
932 ))
933 }
934 Some(Token::Reality) => {
935 use crate::plurality::PluralityParser;
936 Item::Plurality(crate::plurality::PluralityItem::Reality(
937 self.parse_reality_def(visibility)?,
938 ))
939 }
940 Some(Token::CoCon) => {
941 use crate::plurality::PluralityParser;
942 Item::Plurality(crate::plurality::PluralityItem::CoConChannel(
943 self.parse_cocon_channel()?,
944 ))
945 }
946 Some(Token::On) => {
947 if self.peek_next() == Some(&Token::Trigger) {
949 use crate::plurality::PluralityParser;
950 Item::Plurality(crate::plurality::PluralityItem::TriggerHandler(
951 self.parse_trigger_handler()?,
952 ))
953 } else {
954 return Err(ParseError::UnexpectedToken {
955 expected: "item".to_string(),
956 found: Token::On,
957 span: self.current_span(),
958 });
959 }
960 }
961 Some(Token::Ident(_)) => {
963 if self.looks_like_macro_invocation() {
965 Item::MacroInvocation(self.parse_macro_invocation()?)
966 } else {
967 return Err(ParseError::UnexpectedToken {
968 expected: "item".to_string(),
969 found: self.current_token().unwrap().clone(),
970 span: self.current_span(),
971 });
972 }
973 }
974 Some(token) => {
975 return Err(ParseError::UnexpectedToken {
976 expected: "item".to_string(),
977 found: token.clone(),
978 span: self.current_span(),
979 });
980 }
981 None => return Err(ParseError::UnexpectedEof),
982 };
983
984 let end_span = self.current_span();
985 Ok(Spanned::new(item, start_span.merge(end_span)))
986 }
987
988 pub(crate) fn parse_visibility(&mut self) -> ParseResult<Visibility> {
989 if self.consume_if(&Token::Pub) {
990 Ok(Visibility::Public)
991 } else {
992 Ok(Visibility::Private)
993 }
994 }
995
996 fn parse_function(&mut self, visibility: Visibility) -> ParseResult<Function> {
997 self.parse_function_with_attrs(visibility, Vec::new())
998 }
999
1000 fn parse_function_with_attrs(
1001 &mut self,
1002 visibility: Visibility,
1003 outer_attrs: Vec<Attribute>,
1004 ) -> ParseResult<Function> {
1005 let mut attrs = self.process_function_attrs(&outer_attrs);
1007
1008 if self.consume_if(&Token::Naked) {
1010 attrs.naked = true;
1011 }
1012
1013 let is_unsafe = self.consume_if(&Token::Unsafe);
1015
1016 let is_const = self.consume_if(&Token::Const);
1018
1019 let is_async = self.consume_if(&Token::Async);
1020 self.expect(Token::Fn)?;
1021
1022 let mut name = self.parse_ident()?;
1023
1024 if let Some(ev) = self.parse_evidentiality_opt() {
1027 if name.evidentiality.is_none() {
1029 name.evidentiality = Some(ev);
1030 }
1031 }
1032
1033 let aspect = match self.current_token() {
1035 Some(Token::AspectProgressive) => {
1036 self.advance();
1037 Some(Aspect::Progressive)
1038 }
1039 Some(Token::AspectPerfective) => {
1040 self.advance();
1041 Some(Aspect::Perfective)
1042 }
1043 Some(Token::AspectPotential) => {
1044 self.advance();
1045 Some(Aspect::Potential)
1046 }
1047 Some(Token::AspectResultative) => {
1048 self.advance();
1049 Some(Aspect::Resultative)
1050 }
1051 _ => None,
1052 };
1053
1054 let generics = self.parse_generics_opt()?;
1055
1056 self.expect(Token::LParen)?;
1057 let params = self.parse_params()?;
1058 self.expect(Token::RParen)?;
1059
1060 let return_type = if self.consume_if(&Token::Arrow) {
1061 Some(self.parse_type()?)
1062 } else {
1063 None
1064 };
1065
1066 let is_async = is_async || self.consume_if(&Token::Hourglass);
1069
1070 let where_clause = self.parse_where_clause_opt()?;
1071
1072 let body = if self.check(&Token::LBrace) {
1073 Some(self.parse_block()?)
1074 } else {
1075 if !self.consume_if(&Token::Semi) {
1078 let valid_terminator = matches!(
1084 self.current_token(),
1085 Some(Token::Fn)
1086 | Some(Token::Async)
1087 | Some(Token::Unsafe)
1088 | Some(Token::Const)
1089 | Some(Token::Type)
1090 | Some(Token::Pub)
1091 | Some(Token::DocComment(_))
1092 | Some(Token::LineComment(_))
1093 | Some(Token::BlockComment(_))
1094 | Some(Token::TildeComment(_))
1095 | Some(Token::RBrace)
1096 | Some(Token::Hash)
1097 );
1098 if !valid_terminator {
1099 return match self.current_token().cloned() {
1100 Some(token) => Err(ParseError::UnexpectedToken {
1101 expected: "Semi".to_string(),
1102 found: token,
1103 span: self.current_span(),
1104 }),
1105 None => Err(ParseError::UnexpectedEof),
1106 };
1107 }
1108 }
1109 None
1110 };
1111
1112 Ok(Function {
1113 visibility,
1114 is_async,
1115 is_const,
1116 is_unsafe,
1117 attrs,
1118 name,
1119 aspect,
1120 generics,
1121 params,
1122 return_type,
1123 where_clause,
1124 body,
1125 })
1126 }
1127
1128 fn process_function_attrs(&self, attrs: &[Attribute]) -> FunctionAttrs {
1130 let mut func_attrs = FunctionAttrs::default();
1131
1132 for attr in attrs {
1133 match attr.name.name.as_str() {
1134 "panic_handler" => func_attrs.panic_handler = true,
1135 "entry" => func_attrs.entry = true,
1136 "no_mangle" => func_attrs.no_mangle = true,
1137 "export" => func_attrs.export = true,
1138 "cold" => func_attrs.cold = true,
1139 "hot" => func_attrs.hot = true,
1140 "test" => func_attrs.test = true,
1141 "naked" => func_attrs.naked = true,
1142 "inline" => {
1143 func_attrs.inline = Some(match &attr.args {
1144 Some(AttrArgs::Paren(args)) => {
1145 if let Some(AttrArg::Ident(ident)) = args.first() {
1146 match ident.name.as_str() {
1147 "always" => InlineHint::Always,
1148 "never" => InlineHint::Never,
1149 _ => InlineHint::Hint,
1150 }
1151 } else {
1152 InlineHint::Hint
1153 }
1154 }
1155 _ => InlineHint::Hint,
1156 });
1157 }
1158 "link_section" => {
1159 if let Some(AttrArgs::Eq(value)) = &attr.args {
1160 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
1161 func_attrs.link_section = Some(s.clone());
1162 }
1163 }
1164 }
1165 "interrupt" => {
1166 if let Some(AttrArgs::Paren(args)) = &attr.args {
1167 if let Some(AttrArg::Literal(Literal::Int { value, base, .. })) =
1168 args.first()
1169 {
1170 let num = Self::parse_int_value(value, *base) as u32;
1171 func_attrs.interrupt = Some(num);
1172 }
1173 }
1174 }
1175 "align" => {
1176 if let Some(AttrArgs::Paren(args)) = &attr.args {
1177 if let Some(AttrArg::Literal(Literal::Int { value, base, .. })) =
1178 args.first()
1179 {
1180 let align = Self::parse_int_value(value, *base) as usize;
1181 func_attrs.align = Some(align);
1182 }
1183 }
1184 }
1185 _ => {
1186 func_attrs.outer_attrs.push(attr.clone());
1188 }
1189 }
1190 }
1191
1192 func_attrs
1193 }
1194
1195 fn parse_struct_with_attrs(
1196 &mut self,
1197 visibility: Visibility,
1198 outer_attrs: Vec<Attribute>,
1199 ) -> ParseResult<StructDef> {
1200 let mut attrs = StructAttrs::default();
1202 attrs.outer_attrs = outer_attrs.clone();
1203
1204 for attr in &outer_attrs {
1206 if attr.name.name == "derive" {
1207 if let Some(AttrArgs::Paren(args)) = &attr.args {
1208 for arg in args {
1209 if let AttrArg::Ident(ident) = arg {
1210 let derive = Self::parse_derive_trait(&ident.name)?;
1211 attrs.derives.push(derive);
1212 }
1213 }
1214 }
1215 } else if attr.name.name == "simd" {
1216 attrs.simd = true;
1217 } else if attr.name.name == "repr" {
1218 if let Some(AttrArgs::Paren(args)) = &attr.args {
1219 for arg in args {
1220 if let AttrArg::Ident(ident) = arg {
1221 attrs.repr = Some(match ident.name.as_str() {
1222 "C" => StructRepr::C,
1223 "transparent" => StructRepr::Transparent,
1224 "packed" => {
1225 attrs.packed = true;
1226 StructRepr::C }
1228 other => StructRepr::Int(other.to_string()),
1229 });
1230 } else if let AttrArg::Nested(nested) = arg {
1231 if nested.name.name == "align" {
1232 if let Some(AttrArgs::Paren(align_args)) = &nested.args {
1233 if let Some(AttrArg::Literal(Literal::Int { value, .. })) =
1234 align_args.first()
1235 {
1236 if let Ok(n) = value.parse::<usize>() {
1237 attrs.align = Some(n);
1238 }
1239 }
1240 }
1241 }
1242 }
1243 }
1244 }
1245 }
1246 }
1247
1248 if self.consume_if(&Token::Packed) {
1250 attrs.packed = true;
1251 }
1252
1253 self.expect(Token::Struct)?;
1254 let name = self.parse_ident()?;
1255
1256 let _evidentiality_before = self.parse_evidentiality_opt();
1262
1263 let generics = self.parse_generics_opt()?;
1264
1265 let _evidentiality_after = self.parse_evidentiality_opt();
1267
1268 let _ = self.parse_where_clause_opt()?;
1270
1271 let fields = if self.check(&Token::LBrace) {
1272 self.expect(Token::LBrace)?;
1273 let fields = self.parse_field_defs()?;
1274 self.expect(Token::RBrace)?;
1275 StructFields::Named(fields)
1276 } else if self.check(&Token::LParen) {
1277 self.expect(Token::LParen)?;
1278 let types = self.parse_tuple_struct_fields()?;
1279 self.expect(Token::RParen)?;
1280 self.expect_semi_or_item_start()?;
1282 StructFields::Tuple(types)
1283 } else {
1284 self.expect_semi_or_item_start()?;
1286 StructFields::Unit
1287 };
1288
1289 Ok(StructDef {
1290 visibility,
1291 attrs,
1292 name,
1293 generics,
1294 fields,
1295 })
1296 }
1297
1298 fn parse_derive_trait(name: &str) -> ParseResult<DeriveTrait> {
1299 match name {
1300 "Debug" => Ok(DeriveTrait::Debug),
1301 "Clone" => Ok(DeriveTrait::Clone),
1302 "Copy" => Ok(DeriveTrait::Copy),
1303 "Default" => Ok(DeriveTrait::Default),
1304 "PartialEq" => Ok(DeriveTrait::PartialEq),
1305 "Eq" => Ok(DeriveTrait::Eq),
1306 "PartialOrd" => Ok(DeriveTrait::PartialOrd),
1307 "Ord" => Ok(DeriveTrait::Ord),
1308 "Hash" => Ok(DeriveTrait::Hash),
1309 "Component" => Ok(DeriveTrait::Component),
1311 "Resource" => Ok(DeriveTrait::Resource),
1312 "Bundle" => Ok(DeriveTrait::Bundle),
1313 "Serialize" => Ok(DeriveTrait::Serialize),
1315 "Deserialize" => Ok(DeriveTrait::Deserialize),
1316 _ => Ok(DeriveTrait::Custom(name.to_string())),
1318 }
1319 }
1320
1321 fn parse_enum(&mut self, visibility: Visibility) -> ParseResult<EnumDef> {
1322 self.expect(Token::Enum)?;
1323 let name = self.parse_ident()?;
1324 let generics = self.parse_generics_opt()?;
1325
1326 self.expect(Token::LBrace)?;
1327 let mut variants = Vec::new();
1328 while !self.check(&Token::RBrace) && !self.is_eof() {
1329 while matches!(
1331 self.current_token(),
1332 Some(Token::DocComment(_))
1333 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1334 ) {
1335 self.advance();
1336 }
1337 while self.check(&Token::Hash) || self.check(&Token::At) {
1339 self.parse_outer_attribute()?;
1340 }
1341 while matches!(
1343 self.current_token(),
1344 Some(Token::DocComment(_))
1345 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1346 ) {
1347 self.advance();
1348 }
1349 if self.check(&Token::RBrace) {
1350 break;
1351 }
1352 variants.push(self.parse_enum_variant()?);
1353 if !self.consume_if(&Token::Comma) {
1354 break;
1355 }
1356 while matches!(
1358 self.current_token(),
1359 Some(Token::DocComment(_))
1360 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1361 ) {
1362 self.advance();
1363 }
1364 }
1365 self.expect(Token::RBrace)?;
1366
1367 Ok(EnumDef {
1368 visibility,
1369 name,
1370 generics,
1371 variants,
1372 })
1373 }
1374
1375 fn parse_enum_variant(&mut self) -> ParseResult<EnumVariant> {
1376 let name = self.parse_ident()?;
1377
1378 let fields = if self.check(&Token::LBrace) {
1379 self.expect(Token::LBrace)?;
1380 let fields = self.parse_field_defs()?;
1381 self.expect(Token::RBrace)?;
1382 StructFields::Named(fields)
1383 } else if self.check(&Token::LParen) {
1384 self.expect(Token::LParen)?;
1385 let types = self.parse_attributed_type_list()?;
1386 self.expect(Token::RParen)?;
1387 StructFields::Tuple(types)
1388 } else {
1389 StructFields::Unit
1390 };
1391
1392 let discriminant = if self.consume_if(&Token::Eq) {
1393 Some(self.parse_expr()?)
1394 } else {
1395 None
1396 };
1397
1398 Ok(EnumVariant {
1399 name,
1400 fields,
1401 discriminant,
1402 })
1403 }
1404
1405 fn parse_trait(&mut self, visibility: Visibility) -> ParseResult<TraitDef> {
1406 self.expect(Token::Trait)?;
1407 let name = self.parse_ident()?;
1408 let generics = self.parse_generics_opt()?;
1409
1410 let supertraits = if self.consume_if(&Token::Colon) {
1411 self.parse_type_bounds()?
1412 } else {
1413 vec![]
1414 };
1415
1416 self.expect(Token::LBrace)?;
1417 let mut items = Vec::new();
1418 while !self.check(&Token::RBrace) && !self.is_eof() {
1419 while matches!(
1421 self.current_token(),
1422 Some(Token::DocComment(_))
1423 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1424 ) {
1425 self.advance();
1426 }
1427 if self.check(&Token::RBrace) {
1428 break;
1429 }
1430 items.push(self.parse_trait_item()?);
1431 }
1432 self.expect(Token::RBrace)?;
1433
1434 Ok(TraitDef {
1435 visibility,
1436 name,
1437 generics,
1438 supertraits,
1439 items,
1440 })
1441 }
1442
1443 fn parse_trait_item(&mut self) -> ParseResult<TraitItem> {
1444 let visibility = self.parse_visibility()?;
1445
1446 match self.current_token() {
1447 Some(Token::Fn) | Some(Token::Async) | Some(Token::Unsafe) => {
1448 Ok(TraitItem::Function(self.parse_function(visibility)?))
1449 }
1450 Some(Token::Type) => {
1451 self.advance();
1452 let name = self.parse_ident()?;
1453 let bounds = if self.consume_if(&Token::Colon) {
1454 self.parse_type_bounds()?
1455 } else {
1456 vec![]
1457 };
1458 self.expect(Token::Semi)?;
1459 Ok(TraitItem::Type { name, bounds })
1460 }
1461 Some(Token::Const) => {
1462 if self
1464 .peek_next()
1465 .map(|t| matches!(t, Token::Fn | Token::Async))
1466 == Some(true)
1467 {
1468 Ok(TraitItem::Function(self.parse_function(visibility)?))
1469 } else {
1470 self.advance();
1471 let name = self.parse_ident()?;
1472 self.expect(Token::Colon)?;
1473 let ty = self.parse_type()?;
1474 self.expect(Token::Semi)?;
1475 Ok(TraitItem::Const { name, ty })
1476 }
1477 }
1478 Some(token) => Err(ParseError::UnexpectedToken {
1479 expected: "trait item".to_string(),
1480 found: token.clone(),
1481 span: self.current_span(),
1482 }),
1483 None => Err(ParseError::UnexpectedEof),
1484 }
1485 }
1486
1487 fn parse_impl(&mut self) -> ParseResult<ImplBlock> {
1488 self.expect(Token::Impl)?;
1489 let generics = self.parse_generics_opt()?;
1490
1491 let first_type = self.parse_type()?;
1493
1494 let (trait_, self_ty) = if self.consume_if(&Token::For) {
1495 let self_ty = self.parse_type()?;
1496 let trait_path = match first_type {
1497 TypeExpr::Path(p) => p,
1498 _ => return Err(ParseError::Custom("expected trait path".to_string())),
1499 };
1500 (Some(trait_path), self_ty)
1501 } else {
1502 (None, first_type)
1503 };
1504
1505 let _ = self.parse_where_clause_opt()?;
1507
1508 self.expect(Token::LBrace)?;
1509 let mut items = Vec::new();
1510 while !self.check(&Token::RBrace) && !self.is_eof() {
1511 while matches!(
1513 self.current_token(),
1514 Some(Token::DocComment(_))
1515 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1516 | Some(Token::Hash)
1517 ) {
1518 if self.check(&Token::Hash) {
1519 self.advance();
1521 self.consume_if(&Token::Bang);
1522 if self.consume_if(&Token::LBracket) {
1523 let mut depth = 1;
1524 while depth > 0 && !self.is_eof() {
1525 match self.current_token() {
1526 Some(Token::LBracket) => depth += 1,
1527 Some(Token::RBracket) => depth -= 1,
1528 _ => {}
1529 }
1530 self.advance();
1531 }
1532 }
1533 } else {
1534 self.advance();
1535 }
1536 }
1537 if self.check(&Token::RBrace) {
1538 break;
1539 }
1540 items.push(self.parse_impl_item()?);
1541 }
1542 self.expect(Token::RBrace)?;
1543
1544 Ok(ImplBlock {
1545 generics,
1546 trait_,
1547 self_ty,
1548 items,
1549 })
1550 }
1551
1552 fn parse_impl_item(&mut self) -> ParseResult<ImplItem> {
1553 let mut outer_attrs = Vec::new();
1555 while self.check(&Token::Hash) || self.check(&Token::At) {
1556 outer_attrs.push(self.parse_outer_attribute()?);
1557 }
1558
1559 let visibility = self.parse_visibility()?;
1560
1561 match self.current_token() {
1562 Some(Token::Fn) | Some(Token::Async) | Some(Token::Unsafe) => Ok(ImplItem::Function(
1563 self.parse_function_with_attrs(visibility, outer_attrs)?,
1564 )),
1565 Some(Token::Type) => Ok(ImplItem::Type(self.parse_type_alias(visibility)?)),
1566 Some(Token::Const) => {
1567 if self
1569 .peek_next()
1570 .map(|t| matches!(t, Token::Fn | Token::Async))
1571 == Some(true)
1572 {
1573 Ok(ImplItem::Function(
1574 self.parse_function_with_attrs(visibility, outer_attrs)?,
1575 ))
1576 } else {
1577 Ok(ImplItem::Const(self.parse_const(visibility)?))
1578 }
1579 }
1580 Some(token) => Err(ParseError::UnexpectedToken {
1581 expected: "impl item".to_string(),
1582 found: token.clone(),
1583 span: self.current_span(),
1584 }),
1585 None => Err(ParseError::UnexpectedEof),
1586 }
1587 }
1588
1589 fn parse_type_alias(&mut self, visibility: Visibility) -> ParseResult<TypeAlias> {
1590 self.expect(Token::Type)?;
1591 let name = self.parse_ident()?;
1592 let generics = self.parse_generics_opt()?;
1593 let _evidentiality = self.parse_evidentiality_opt();
1595 self.expect(Token::Eq)?;
1596 let ty = self.parse_type()?;
1597 self.consume_if(&Token::Semi);
1599
1600 Ok(TypeAlias {
1601 visibility,
1602 name,
1603 generics,
1604 ty,
1605 })
1606 }
1607
1608 fn parse_module(&mut self, visibility: Visibility) -> ParseResult<Module> {
1609 self.expect(Token::Mod)?;
1610 let name = self.parse_ident()?;
1611
1612 let items = if self.check(&Token::LBrace) {
1613 self.expect(Token::LBrace)?;
1614 let mut items = Vec::new();
1615 while !self.check(&Token::RBrace) && !self.is_eof() {
1616 while matches!(
1618 self.current_token(),
1619 Some(Token::DocComment(_))
1620 | Some(
1621 Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
1622 )
1623 ) {
1624 self.advance();
1625 }
1626 if self.check(&Token::RBrace) {
1627 break;
1628 }
1629 items.push(self.parse_item()?);
1630 }
1631 self.expect(Token::RBrace)?;
1632 Some(items)
1633 } else {
1634 self.expect_semi_or_item_start()?;
1636 None
1637 };
1638
1639 Ok(Module {
1640 visibility,
1641 name,
1642 items,
1643 })
1644 }
1645
1646 fn parse_use(&mut self, visibility: Visibility) -> ParseResult<UseDecl> {
1647 self.expect(Token::Use)?;
1648 let tree = self.parse_use_tree()?;
1649 self.expect_semi_or_item_start()?;
1651
1652 Ok(UseDecl { visibility, tree })
1653 }
1654
1655 fn parse_use_tree(&mut self) -> ParseResult<UseTree> {
1656 if self.consume_if(&Token::Star) {
1657 return Ok(UseTree::Glob);
1658 }
1659
1660 if self.check(&Token::LBrace) {
1661 self.expect(Token::LBrace)?;
1662 let mut trees = Vec::new();
1663 while !self.check(&Token::RBrace) {
1664 loop {
1666 if matches!(
1667 self.current_token(),
1668 Some(Token::DocComment(_))
1669 | Some(
1670 Token::LineComment(_)
1671 | Token::TildeComment(_)
1672 | Token::BlockComment(_)
1673 )
1674 ) {
1675 self.advance();
1676 } else if self.check(&Token::Hash) {
1677 self.skip_attribute()?;
1679 } else {
1680 break;
1681 }
1682 }
1683 if self.check(&Token::RBrace) {
1684 break;
1685 }
1686 trees.push(self.parse_use_tree()?);
1687 if !self.consume_if(&Token::Comma) {
1688 break;
1689 }
1690 loop {
1692 if matches!(
1693 self.current_token(),
1694 Some(Token::DocComment(_))
1695 | Some(
1696 Token::LineComment(_)
1697 | Token::TildeComment(_)
1698 | Token::BlockComment(_)
1699 )
1700 ) {
1701 self.advance();
1702 } else if self.check(&Token::Hash) {
1703 self.skip_attribute()?;
1705 } else {
1706 break;
1707 }
1708 }
1709 }
1710 self.expect(Token::RBrace)?;
1711 return Ok(UseTree::Group(trees));
1712 }
1713
1714 let name = if self.check(&Token::Crate) {
1716 let span = self.current_span();
1717 self.advance();
1718 Ident {
1719 name: "crate".to_string(),
1720 evidentiality: None,
1721 affect: None,
1722 span,
1723 }
1724 } else if self.check(&Token::Super) {
1725 let span = self.current_span();
1726 self.advance();
1727 Ident {
1728 name: "super".to_string(),
1729 evidentiality: None,
1730 affect: None,
1731 span,
1732 }
1733 } else if self.check(&Token::SelfLower) {
1734 let span = self.current_span();
1735 self.advance();
1736 Ident {
1737 name: "self".to_string(),
1738 evidentiality: None,
1739 affect: None,
1740 span,
1741 }
1742 } else if self.check(&Token::Sqrt) {
1743 let span = self.current_span();
1745 self.advance();
1746 if let Some(Token::IntLit(n)) = self.current_token().cloned() {
1748 let merged_span = span.merge(self.current_span());
1749 self.advance();
1750 Ident {
1751 name: format!("√{}", n),
1752 evidentiality: None,
1753 affect: None,
1754 span: merged_span,
1755 }
1756 } else {
1757 Ident {
1758 name: "√".to_string(),
1759 evidentiality: None,
1760 affect: None,
1761 span,
1762 }
1763 }
1764 } else if self.check(&Token::Phi) {
1765 let span = self.current_span();
1767 self.advance();
1768 Ident {
1769 name: "φ".to_string(),
1770 evidentiality: None,
1771 affect: None,
1772 span,
1773 }
1774 } else {
1775 self.parse_ident()?
1776 };
1777
1778 let _evidentiality = self.parse_evidentiality_opt();
1781
1782 if self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::ColonColon) {
1784 let suffix = self.parse_use_tree()?;
1785 return Ok(UseTree::Path {
1786 prefix: name,
1787 suffix: Box::new(suffix),
1788 });
1789 }
1790
1791 if self.consume_if(&Token::As) {
1793 if self.check(&Token::Underscore) {
1795 let span = self.current_span();
1796 self.advance();
1797 let alias = Ident {
1798 name: "_".to_string(),
1799 evidentiality: None,
1800 affect: None,
1801 span,
1802 };
1803 return Ok(UseTree::Rename { name, alias });
1804 }
1805 let alias = self.parse_ident()?;
1806 return Ok(UseTree::Rename { name, alias });
1807 }
1808
1809 Ok(UseTree::Name(name))
1810 }
1811
1812 fn parse_const(&mut self, visibility: Visibility) -> ParseResult<ConstDef> {
1813 self.expect(Token::Const)?;
1814 let name = self.parse_ident()?;
1815 self.expect(Token::Colon)?;
1816 let ty = self.parse_type()?;
1817 self.expect(Token::Eq)?;
1818 let value = self.parse_expr()?;
1819 self.expect_semi_or_item_start()?;
1821
1822 Ok(ConstDef {
1823 visibility,
1824 name,
1825 ty,
1826 value,
1827 })
1828 }
1829
1830 fn parse_static(&mut self, visibility: Visibility) -> ParseResult<StaticDef> {
1831 self.expect(Token::Static)?;
1832 let mutable = self.consume_if(&Token::Mut);
1833 let name = self.parse_ident()?;
1834 self.expect(Token::Colon)?;
1835 let ty = self.parse_type()?;
1836 self.expect(Token::Eq)?;
1837 let value = self.parse_expr()?;
1838 self.expect_semi_or_item_start()?;
1840
1841 Ok(StaticDef {
1842 visibility,
1843 mutable,
1844 name,
1845 ty,
1846 value,
1847 })
1848 }
1849
1850 fn parse_macro_def(&mut self, visibility: Visibility) -> ParseResult<MacroDef> {
1853 let is_macro_rules = self.check(&Token::MacroRules);
1855 if is_macro_rules {
1856 self.advance(); self.expect(Token::Bang)?; } else {
1859 self.expect(Token::Macro)?;
1860 }
1861
1862 let name = self.parse_ident()?;
1863
1864 let mut body = String::new();
1867 let mut depth = 0;
1868
1869 if self.check(&Token::LParen) {
1871 body.push('(');
1872 self.advance();
1873 depth = 1;
1874 while depth > 0 && !self.is_eof() {
1875 match self.current_token() {
1876 Some(Token::LParen) => {
1877 depth += 1;
1878 body.push('(');
1879 }
1880 Some(Token::RParen) => {
1881 depth -= 1;
1882 if depth > 0 {
1883 body.push(')');
1884 }
1885 }
1886 Some(tok) => {
1887 body.push_str(&format!("{:?} ", tok));
1888 }
1889 None => break,
1890 }
1891 self.advance();
1892 }
1893 body.push(')');
1894 }
1895
1896 self.expect(Token::LBrace)?;
1898 body.push('{');
1899 depth = 1;
1900 while depth > 0 && !self.is_eof() {
1901 match self.current_token() {
1902 Some(Token::LBrace) => {
1903 depth += 1;
1904 body.push('{');
1905 }
1906 Some(Token::RBrace) => {
1907 depth -= 1;
1908 if depth > 0 {
1909 body.push('}');
1910 }
1911 }
1912 Some(Token::LineComment(s)) => {
1913 body.push_str(&format!("//{}", s));
1914 }
1915 Some(tok) => {
1916 body.push_str(&format!("{:?} ", tok));
1917 }
1918 None => break,
1919 }
1920 self.advance();
1921 }
1922 body.push('}');
1923
1924 Ok(MacroDef {
1925 visibility,
1926 name,
1927 rules: body,
1928 })
1929 }
1930
1931 fn looks_like_macro_invocation(&mut self) -> bool {
1933 if !matches!(self.current_token(), Some(Token::Ident(_))) {
1935 return false;
1936 }
1937 let mut pos = 0;
1940 loop {
1941 match self.peek_n(pos) {
1942 Some(Token::Bang) => return true,
1943 Some(Token::ColonColon) => {
1944 pos += 1;
1945 match self.peek_n(pos) {
1947 Some(Token::Ident(_)) => {
1948 pos += 1;
1949 continue;
1950 }
1951 _ => return false,
1952 }
1953 }
1954 _ => return false,
1955 }
1956 }
1957 }
1958
1959 fn parse_macro_invocation(&mut self) -> ParseResult<MacroInvocation> {
1961 use crate::ast::{MacroDelimiter, MacroInvocation};
1962
1963 let path = self.parse_type_path()?;
1965
1966 self.expect(Token::Bang)?;
1968
1969 let (delimiter, open_tok, close_tok) = match self.current_token() {
1971 Some(Token::LBrace) => (MacroDelimiter::Brace, Token::LBrace, Token::RBrace),
1972 Some(Token::LParen) => (MacroDelimiter::Paren, Token::LParen, Token::RParen),
1973 Some(Token::LBracket) => (MacroDelimiter::Bracket, Token::LBracket, Token::RBracket),
1974 Some(tok) => {
1975 return Err(ParseError::UnexpectedToken {
1976 expected: "macro delimiter ('{', '(', or '[')".to_string(),
1977 found: tok.clone(),
1978 span: self.current_span(),
1979 });
1980 }
1981 None => return Err(ParseError::UnexpectedEof),
1982 };
1983
1984 self.advance(); let mut body = String::new();
1988 let mut depth = 1;
1989
1990 while depth > 0 && !self.is_eof() {
1991 let tok = self.current_token().cloned();
1992 match &tok {
1993 Some(t) if *t == open_tok => {
1994 depth += 1;
1995 body.push_str(&format!("{:?} ", t));
1996 }
1997 Some(t) if *t == close_tok => {
1998 depth -= 1;
1999 if depth > 0 {
2000 body.push_str(&format!("{:?} ", t));
2001 }
2002 }
2003 Some(Token::LineComment(s)) => {
2004 body.push_str(&format!("//{}\n", s));
2005 }
2006 Some(t) => {
2007 body.push_str(&format!("{:?} ", t));
2008 }
2009 None => break,
2010 }
2011 self.advance();
2012 }
2013
2014 if delimiter != MacroDelimiter::Brace {
2016 self.consume_if(&Token::Semi);
2017 }
2018
2019 Ok(MacroInvocation {
2020 path,
2021 delimiter,
2022 tokens: body,
2023 })
2024 }
2025
2026 fn parse_actor(&mut self, visibility: Visibility) -> ParseResult<ActorDef> {
2027 self.expect(Token::Actor)?;
2028 let name = self.parse_ident()?;
2029 let generics = self.parse_generics_opt()?;
2030
2031 self.expect(Token::LBrace)?;
2032
2033 let mut state = Vec::new();
2034 let mut handlers = Vec::new();
2035
2036 while !self.check(&Token::RBrace) && !self.is_eof() {
2037 if self.check(&Token::On) {
2038 handlers.push(self.parse_message_handler()?);
2039 } else {
2040 let vis = self.parse_visibility()?;
2042 let field_name = self.parse_ident()?;
2043 self.expect(Token::Colon)?;
2044 let ty = self.parse_type()?;
2045
2046 let default = if self.consume_if(&Token::Eq) {
2048 Some(self.parse_expr()?)
2049 } else {
2050 None
2051 };
2052
2053 if !self.check(&Token::RBrace) && !self.check(&Token::On) {
2054 self.consume_if(&Token::Comma);
2055 }
2056
2057 state.push(FieldDef {
2058 visibility: vis,
2059 name: field_name,
2060 ty,
2061 default,
2062 });
2063 }
2064 }
2065
2066 self.expect(Token::RBrace)?;
2067
2068 Ok(ActorDef {
2069 visibility,
2070 name,
2071 generics,
2072 state,
2073 handlers,
2074 })
2075 }
2076
2077 fn parse_extern_block(&mut self) -> ParseResult<ExternBlock> {
2079 self.expect(Token::Extern)?;
2080
2081 let abi = if let Some(Token::StringLit(s)) = self.current_token().cloned() {
2083 self.advance();
2084 s
2085 } else {
2086 "C".to_string()
2087 };
2088
2089 self.expect(Token::LBrace)?;
2090
2091 let mut items = Vec::new();
2092
2093 while !self.check(&Token::RBrace) && !self.is_eof() {
2094 let visibility = self.parse_visibility()?;
2095
2096 match self.current_token() {
2097 Some(Token::Fn) => {
2098 items.push(ExternItem::Function(
2099 self.parse_extern_function(visibility)?,
2100 ));
2101 }
2102 Some(Token::Static) => {
2103 items.push(ExternItem::Static(self.parse_extern_static(visibility)?));
2104 }
2105 Some(token) => {
2106 return Err(ParseError::UnexpectedToken {
2107 expected: "fn or static".to_string(),
2108 found: token.clone(),
2109 span: self.current_span(),
2110 });
2111 }
2112 None => return Err(ParseError::UnexpectedEof),
2113 }
2114 }
2115
2116 self.expect(Token::RBrace)?;
2117
2118 Ok(ExternBlock { abi, items })
2119 }
2120
2121 fn parse_extern_function(&mut self, visibility: Visibility) -> ParseResult<ExternFunction> {
2123 self.expect(Token::Fn)?;
2124 let name = self.parse_ident()?;
2125
2126 let _evidentiality = self.parse_evidentiality_opt();
2128
2129 self.expect(Token::LParen)?;
2130
2131 let mut params = Vec::new();
2132 let mut variadic = false;
2133
2134 while !self.check(&Token::RParen) && !self.is_eof() {
2135 if self.check(&Token::DotDot) {
2137 self.advance();
2138 if self.consume_if(&Token::Dot) {
2139 variadic = true;
2140 break;
2141 }
2142 }
2143
2144 let pattern = self.parse_pattern()?;
2145 self.expect(Token::Colon)?;
2146 let ty = self.parse_type()?;
2147
2148 params.push(Param { pattern, ty });
2149
2150 if !self.check(&Token::RParen) {
2151 self.expect(Token::Comma)?;
2152 }
2153 }
2154
2155 self.expect(Token::RParen)?;
2156
2157 let return_type = if self.consume_if(&Token::Arrow) {
2159 Some(self.parse_type()?)
2160 } else {
2161 None
2162 };
2163
2164 self.expect(Token::Semi)?;
2166
2167 Ok(ExternFunction {
2168 visibility,
2169 name,
2170 params,
2171 return_type,
2172 variadic,
2173 })
2174 }
2175
2176 fn parse_extern_static(&mut self, visibility: Visibility) -> ParseResult<ExternStatic> {
2178 self.expect(Token::Static)?;
2179 let mutable = self.consume_if(&Token::Mut);
2180 let name = self.parse_ident()?;
2181 self.expect(Token::Colon)?;
2182 let ty = self.parse_type()?;
2183 self.expect(Token::Semi)?;
2184
2185 Ok(ExternStatic {
2186 visibility,
2187 mutable,
2188 name,
2189 ty,
2190 })
2191 }
2192
2193 fn parse_message_handler(&mut self) -> ParseResult<MessageHandler> {
2194 self.expect(Token::On)?;
2195 let message = self.parse_ident()?;
2196
2197 self.expect(Token::LParen)?;
2198 let params = self.parse_params()?;
2199 self.expect(Token::RParen)?;
2200
2201 let return_type = if self.consume_if(&Token::Arrow) {
2202 Some(self.parse_type()?)
2203 } else {
2204 None
2205 };
2206
2207 let body = self.parse_block()?;
2208
2209 Ok(MessageHandler {
2210 message,
2211 params,
2212 return_type,
2213 body,
2214 })
2215 }
2216
2217 pub(crate) fn parse_type(&mut self) -> ParseResult<TypeExpr> {
2220 if let Some(ev) = self.parse_evidentiality_prefix_opt() {
2222 let inner = self.parse_type()?;
2223 return Ok(TypeExpr::Evidential {
2224 inner: Box::new(inner),
2225 evidentiality: ev,
2226 error_type: None,
2227 });
2228 }
2229
2230 let mut base = self.parse_type_base()?;
2231
2232 let path_evidentiality = if let TypeExpr::Path(ref mut path) = base {
2236 if let Some(last_seg) = path.segments.last_mut() {
2237 last_seg.ident.evidentiality.take()
2238 } else {
2239 None
2240 }
2241 } else {
2242 None
2243 };
2244 if let Some(ev) = path_evidentiality {
2245 base = TypeExpr::Evidential {
2246 inner: Box::new(base),
2247 evidentiality: ev,
2248 error_type: None,
2249 };
2250 }
2251
2252 if let Some(ev) = self.parse_evidentiality_opt() {
2254 let base = if self.check(&Token::Lt) && self.peek_looks_like_generic_arg() {
2257 if let TypeExpr::Path(mut path) = base {
2259 self.advance(); let types = self.parse_type_list()?;
2261 self.expect_gt()?;
2262 if let Some(last) = path.segments.last_mut() {
2264 last.generics = Some(types);
2265 }
2266 TypeExpr::Path(path)
2267 } else {
2268 base
2269 }
2270 } else {
2271 base
2272 };
2273
2274 let error_type = if self.check(&Token::LBracket) {
2276 self.advance(); let err_ty = self.parse_type()?;
2278 self.expect(Token::RBracket)?; Some(Box::new(err_ty))
2280 } else {
2281 None
2282 };
2283
2284 let mut result = TypeExpr::Evidential {
2285 inner: Box::new(base),
2286 evidentiality: ev,
2287 error_type,
2288 };
2289
2290 if let Some(ev2) = self.parse_evidentiality_opt() {
2292 result = TypeExpr::Evidential {
2293 inner: Box::new(result),
2294 evidentiality: ev2,
2295 error_type: None,
2296 };
2297 }
2298
2299 return Ok(result);
2300 }
2301
2302 Ok(base)
2303 }
2304
2305 fn parse_evidentiality_prefix_opt(&mut self) -> Option<Evidentiality> {
2308 match self.current_token() {
2309 Some(Token::Bang) => {
2310 if self.peek_is_type_start() {
2313 self.advance();
2314 Some(Evidentiality::Known)
2315 } else {
2316 None
2317 }
2318 }
2319 Some(Token::Question) => {
2320 if self.peek_is_type_start() {
2321 self.advance();
2322 Some(Evidentiality::Uncertain)
2323 } else {
2324 None
2325 }
2326 }
2327 Some(Token::Tilde) => {
2328 if self.peek_is_type_start() {
2329 self.advance();
2330 Some(Evidentiality::Reported)
2331 } else {
2332 None
2333 }
2334 }
2335 Some(Token::Lozenge) => {
2336 if self.peek_is_type_start() {
2337 self.advance();
2338 Some(Evidentiality::Predicted)
2339 } else {
2340 None
2341 }
2342 }
2343 Some(Token::Interrobang) => {
2344 if self.peek_is_type_start() {
2345 self.advance();
2346 Some(Evidentiality::Paradox)
2347 } else {
2348 None
2349 }
2350 }
2351 _ => None,
2352 }
2353 }
2354
2355 fn peek_is_type_start(&mut self) -> bool {
2357 match self.peek_next() {
2358 Some(Token::Ident(_)) => true,
2359 Some(Token::SelfUpper) => true,
2360 Some(Token::Amp) => true,
2361 Some(Token::AndAnd) => true, Some(Token::Star) => true,
2363 Some(Token::LBracket) => true,
2364 Some(Token::LParen) => true,
2365 Some(Token::Fn) => true,
2366 Some(Token::Underscore) => true,
2367 Some(Token::Simd) => true,
2368 Some(Token::Atomic) => true,
2369 Some(Token::Bang) => true,
2371 Some(Token::Question) => true,
2372 Some(Token::Tilde) => true,
2373 Some(Token::Interrobang) => true,
2374 _ => false,
2375 }
2376 }
2377
2378 fn parse_type_base(&mut self) -> ParseResult<TypeExpr> {
2379 match self.current_token() {
2380 Some(Token::AndAnd) => {
2381 self.advance();
2383 let lifetime = if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
2385 self.advance();
2386 Some(lt)
2387 } else {
2388 None
2389 };
2390 let mutable = self.consume_if(&Token::Mut);
2391 let inner = self.parse_type()?;
2392 let inner_ref = TypeExpr::Reference {
2394 lifetime,
2395 mutable,
2396 inner: Box::new(inner),
2397 };
2398 Ok(TypeExpr::Reference {
2400 lifetime: None,
2401 mutable: false,
2402 inner: Box::new(inner_ref),
2403 })
2404 }
2405 Some(Token::Amp) => {
2406 self.advance();
2407 let lifetime = if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
2409 self.advance();
2410 Some(lt)
2411 } else {
2412 None
2413 };
2414 let mutable = self.consume_if(&Token::Mut);
2415 let inner = self.parse_type()?;
2416 Ok(TypeExpr::Reference {
2417 lifetime,
2418 mutable,
2419 inner: Box::new(inner),
2420 })
2421 }
2422 Some(Token::Star) => {
2423 self.advance();
2424 let mutable = if self.consume_if(&Token::Const) {
2427 false
2428 } else if self.consume_if(&Token::Mut) {
2429 true
2430 } else {
2431 false
2433 };
2434 let inner = self.parse_type()?;
2435 Ok(TypeExpr::Pointer {
2436 mutable,
2437 inner: Box::new(inner),
2438 })
2439 }
2440 Some(Token::LBracket) => {
2441 self.advance();
2442 if self.check(&Token::RBracket) {
2444 self.advance();
2446 return Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(vec![]))));
2448 }
2449 let first = self.parse_type_or_lifetime()?;
2451 if self.consume_if(&Token::Semi) {
2452 let size = self.parse_expr()?;
2454 self.expect(Token::RBracket)?;
2455 Ok(TypeExpr::Array {
2456 element: Box::new(first),
2457 size: Box::new(size),
2458 })
2459 } else if self.consume_if(&Token::Comma) {
2460 let first_expr = match first {
2463 TypeExpr::Path(path) => Expr::Path(path),
2464 TypeExpr::ConstExpr(expr) => *expr,
2465 _ => Expr::Path(TypePath {
2466 segments: vec![PathSegment {
2467 ident: Ident {
2468 name: format!("{:?}", first),
2469 evidentiality: None,
2470 affect: None,
2471 span: Span::new(0, 0),
2472 },
2473 generics: None,
2474 }],
2475 }),
2476 };
2477 let mut elem_exprs = vec![first_expr];
2478 while !self.check(&Token::RBracket) && !self.is_eof() {
2479 let dim_expr = self.parse_array_dim_expr()?;
2481 elem_exprs.push(dim_expr);
2482 if !self.consume_if(&Token::Comma) {
2483 break;
2484 }
2485 }
2486 self.expect(Token::RBracket)?;
2487 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(elem_exprs))))
2488 } else if matches!(
2489 self.current_token(),
2490 Some(Token::Slash)
2491 | Some(Token::Star)
2492 | Some(Token::Plus)
2493 | Some(Token::Minus)
2494 | Some(Token::Percent)
2495 ) {
2496 let first_expr = match first {
2499 TypeExpr::Path(path) => Expr::Path(path),
2500 TypeExpr::ConstExpr(expr) => *expr,
2501 _ => Expr::Path(TypePath {
2502 segments: vec![PathSegment {
2503 ident: Ident {
2504 name: format!("{:?}", first),
2505 evidentiality: None,
2506 affect: None,
2507 span: Span::new(0, 0),
2508 },
2509 generics: None,
2510 }],
2511 }),
2512 };
2513 let op = match self.current_token() {
2515 Some(Token::Slash) => BinOp::Div,
2516 Some(Token::Star) => BinOp::Mul,
2517 Some(Token::Plus) => BinOp::Add,
2518 Some(Token::Minus) => BinOp::Sub,
2519 Some(Token::Percent) => BinOp::Rem,
2520 _ => unreachable!(),
2521 };
2522 self.advance(); let right = self.parse_const_expr_primary()?;
2524 let expr = Expr::Binary {
2525 left: Box::new(first_expr),
2526 op,
2527 right: Box::new(right),
2528 };
2529
2530 if self.consume_if(&Token::Comma) {
2532 let mut elem_exprs = vec![expr];
2533 while !self.check(&Token::RBracket) && !self.is_eof() {
2534 let dim_expr = self.parse_array_dim_expr()?;
2535 elem_exprs.push(dim_expr);
2536 if !self.consume_if(&Token::Comma) {
2537 break;
2538 }
2539 }
2540 self.expect(Token::RBracket)?;
2541 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(elem_exprs))))
2542 } else {
2543 self.expect(Token::RBracket)?;
2544 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(vec![expr]))))
2545 }
2546 } else {
2547 self.expect(Token::RBracket)?;
2549 Ok(TypeExpr::Slice(Box::new(first)))
2550 }
2551 }
2552 Some(Token::LParen) => {
2553 self.advance();
2554 if self.check(&Token::RParen) {
2555 self.advance();
2556 return Ok(TypeExpr::Tuple(vec![]));
2557 }
2558 let types = self.parse_type_list()?;
2559 self.expect(Token::RParen)?;
2560 Ok(TypeExpr::Tuple(types))
2561 }
2562 Some(Token::Fn) => {
2563 self.advance();
2564 self.expect(Token::LParen)?;
2565 let params = self.parse_type_list()?;
2566 self.expect(Token::RParen)?;
2567 let return_type = if self.consume_if(&Token::Arrow) {
2568 Some(Box::new(self.parse_type()?))
2569 } else {
2570 None
2571 };
2572 Ok(TypeExpr::Function {
2573 params,
2574 return_type,
2575 })
2576 }
2577 Some(Token::Impl) => {
2578 self.advance();
2580 let bounds = self.parse_type_bounds()?;
2582 Ok(TypeExpr::ImplTrait(bounds))
2583 }
2584 Some(Token::Bang) => {
2585 self.advance();
2586 Ok(TypeExpr::Never)
2587 }
2588 Some(Token::Underscore) => {
2589 self.advance();
2590 Ok(TypeExpr::Infer)
2591 }
2592 Some(Token::Lt) => {
2593 self.advance(); let base_type = self.parse_type()?;
2597
2598 let trait_path = if self.consume_if(&Token::As) {
2600 Some(self.parse_type_path()?)
2601 } else {
2602 None
2603 };
2604
2605 self.expect_gt()?; self.expect(Token::ColonColon)?; let mut segments = vec![self.parse_path_segment()?];
2610 while self.consume_if(&Token::ColonColon) {
2611 segments.push(self.parse_path_segment()?);
2612 }
2613
2614 Ok(TypeExpr::QualifiedPath {
2615 self_type: Box::new(base_type),
2616 trait_path,
2617 item_path: TypePath { segments },
2618 })
2619 }
2620 Some(Token::SelfUpper) => {
2621 let span = self.current_span();
2622 self.advance();
2623 let mut segments = vec![PathSegment {
2624 ident: Ident {
2625 name: "Self".to_string(),
2626 evidentiality: None,
2627 affect: None,
2628 span,
2629 },
2630 generics: None,
2631 }];
2632 while self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
2634 if self.check(&Token::Lt) {
2636 self.advance();
2637 let types = self.parse_type_list()?;
2638 self.expect_gt()?;
2639 if let Some(last) = segments.last_mut() {
2640 last.generics = Some(types);
2641 }
2642 continue;
2643 }
2644 segments.push(self.parse_path_segment()?);
2645 }
2646 Ok(TypeExpr::Path(TypePath { segments }))
2647 }
2648 Some(Token::Simd) => {
2649 self.advance();
2650 self.expect(Token::Lt)?;
2651 let element = self.parse_type()?;
2652 self.expect(Token::Comma)?;
2653 let lanes = match self.current_token() {
2654 Some(Token::IntLit(s)) => {
2655 let n = s
2656 .parse::<u8>()
2657 .map_err(|_| ParseError::Custom("invalid lane count".to_string()))?;
2658 self.advance();
2659 n
2660 }
2661 _ => return Err(ParseError::Custom("expected lane count".to_string())),
2662 };
2663 self.expect_gt()?;
2664 Ok(TypeExpr::Simd {
2665 element: Box::new(element),
2666 lanes,
2667 })
2668 }
2669 Some(Token::Atomic) => {
2670 self.advance();
2671 self.expect(Token::Lt)?;
2672 let inner = self.parse_type()?;
2673 self.expect_gt()?;
2674 Ok(TypeExpr::Atomic(Box::new(inner)))
2675 }
2676 Some(Token::Dyn) => {
2677 self.advance();
2679 let bounds = self.parse_type_bounds()?;
2680 Ok(TypeExpr::TraitObject(bounds))
2681 }
2682 Some(Token::Struct) => {
2683 self.advance();
2685 self.expect(Token::LBrace)?;
2686 let mut fields = Vec::new();
2687 while !self.check(&Token::RBrace) && !self.is_eof() {
2688 while matches!(
2690 self.current_token(),
2691 Some(Token::DocComment(_))
2692 | Some(
2693 Token::LineComment(_)
2694 | Token::TildeComment(_)
2695 | Token::BlockComment(_)
2696 )
2697 | Some(Token::Hash)
2698 ) {
2699 if self.check(&Token::Hash) {
2700 self.advance();
2702 if self.consume_if(&Token::LBracket) {
2703 let mut depth = 1;
2704 while depth > 0 && !self.is_eof() {
2705 match self.current_token() {
2706 Some(Token::LBracket) => depth += 1,
2707 Some(Token::RBracket) => depth -= 1,
2708 _ => {}
2709 }
2710 self.advance();
2711 }
2712 }
2713 } else {
2714 self.advance();
2715 }
2716 }
2717 if self.check(&Token::RBrace) {
2718 break;
2719 }
2720 let visibility = self.parse_visibility()?;
2722 let name = self.parse_ident()?;
2723 self.expect(Token::Colon)?;
2724 let ty = self.parse_type()?;
2725 fields.push(FieldDef {
2726 visibility,
2727 name,
2728 ty,
2729 default: None,
2730 });
2731 if !self.consume_if(&Token::Comma) {
2732 break;
2733 }
2734 }
2735 self.expect(Token::RBrace)?;
2736 Ok(TypeExpr::InlineStruct { fields })
2737 }
2738 Some(Token::Enum) => {
2739 self.advance();
2741 self.expect(Token::LBrace)?;
2742 let mut variants = Vec::new();
2743 while !self.check(&Token::RBrace) && !self.is_eof() {
2744 while matches!(
2746 self.current_token(),
2747 Some(Token::DocComment(_))
2748 | Some(
2749 Token::LineComment(_)
2750 | Token::TildeComment(_)
2751 | Token::BlockComment(_)
2752 )
2753 ) {
2754 self.advance();
2755 }
2756 if self.check(&Token::RBrace) {
2757 break;
2758 }
2759 let name = self.parse_ident()?;
2761 let fields = if self.check(&Token::LParen) {
2763 self.advance();
2764 let mut types = Vec::new();
2765 while !self.check(&Token::RParen) && !self.is_eof() {
2766 types.push(self.parse_type()?);
2767 if !self.consume_if(&Token::Comma) {
2768 break;
2769 }
2770 }
2771 self.expect(Token::RParen)?;
2772 StructFields::Tuple(types)
2773 } else if self.check(&Token::LBrace) {
2774 self.advance();
2775 let mut fields = Vec::new();
2776 while !self.check(&Token::RBrace) && !self.is_eof() {
2777 let name = self.parse_ident()?;
2778 self.expect(Token::Colon)?;
2779 let ty = self.parse_type()?;
2780 fields.push(FieldDef {
2781 visibility: Visibility::Private,
2782 name,
2783 ty,
2784 default: None,
2785 });
2786 if !self.consume_if(&Token::Comma) {
2787 break;
2788 }
2789 }
2790 self.expect(Token::RBrace)?;
2791 StructFields::Named(fields)
2792 } else {
2793 StructFields::Unit
2794 };
2795 let discriminant = if self.consume_if(&Token::Eq) {
2797 Some(self.parse_expr()?)
2798 } else {
2799 None
2800 };
2801 variants.push(EnumVariant {
2802 name,
2803 fields,
2804 discriminant,
2805 });
2806 if !self.consume_if(&Token::Comma) {
2807 break;
2808 }
2809 }
2810 self.expect(Token::RBrace)?;
2811 Ok(TypeExpr::InlineEnum { variants })
2812 }
2813 Some(Token::Crate) | Some(Token::SelfLower) | Some(Token::Super) => {
2815 let keyword = self.current_token().cloned();
2816 let span = self.current_span();
2817 self.advance();
2818
2819 let keyword_name = match keyword {
2821 Some(Token::Crate) => "crate",
2822 Some(Token::SelfLower) => "self",
2823 Some(Token::Super) => "super",
2824 _ => unreachable!(),
2825 };
2826 let first_segment = PathSegment {
2827 ident: Ident {
2828 name: keyword_name.to_string(),
2829 evidentiality: None,
2830 affect: None,
2831 span,
2832 },
2833 generics: None,
2834 };
2835
2836 let mut segments = vec![first_segment];
2837
2838 while self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
2840 if self.check(&Token::Lt) {
2842 self.advance();
2843 let types = self.parse_type_list()?;
2844 self.expect_gt()?;
2845 if let Some(last) = segments.last_mut() {
2846 last.generics = Some(types);
2847 }
2848 continue;
2849 }
2850 segments.push(self.parse_path_segment()?);
2851 }
2852 Ok(TypeExpr::Path(TypePath { segments }))
2853 }
2854 _ => {
2855 let path = self.parse_type_path()?;
2856 Ok(TypeExpr::Path(path))
2857 }
2858 }
2859 }
2860
2861 fn parse_type_path(&mut self) -> ParseResult<TypePath> {
2862 let mut segments = Vec::new();
2863 segments.push(self.parse_path_segment()?);
2864
2865 while !self.pending_gt.is_some()
2869 && (self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot))
2870 {
2871 if self.check(&Token::Lt) {
2873 let was_in_condition = self.in_condition;
2876 self.in_condition = false;
2877 self.advance(); let types = self.parse_type_list()?;
2879 self.expect_gt()?;
2880 self.in_condition = was_in_condition;
2881 if let Some(last) = segments.last_mut() {
2883 last.generics = Some(types);
2884 }
2885 continue;
2888 }
2889 segments.push(self.parse_path_segment()?);
2890 }
2891
2892 Ok(TypePath { segments })
2893 }
2894
2895 fn parse_path_segment(&mut self) -> ParseResult<PathSegment> {
2896 let ident = if let Some(Token::IntLit(idx)) = self.current_token().cloned() {
2898 let span = self.current_span();
2899 self.advance();
2900 Ident {
2901 name: idx,
2902 evidentiality: None,
2903 affect: None,
2904 span,
2905 }
2906 } else {
2907 self.parse_ident()?
2908 };
2909
2910 let is_fn_trait = matches!(ident.name.as_str(), "Fn" | "FnMut" | "FnOnce");
2913 if is_fn_trait && self.check(&Token::LParen) {
2914 self.advance(); let param_types = self.parse_type_list()?;
2916 self.expect(Token::RParen)?;
2917 let return_type = if self.consume_if(&Token::Arrow) {
2919 Some(self.parse_type()?)
2920 } else {
2921 None
2922 };
2923 let mut generics = vec![TypeExpr::Tuple(param_types)];
2926 if let Some(ret) = return_type {
2927 generics.push(ret);
2928 }
2929 return Ok(PathSegment {
2930 ident,
2931 generics: Some(generics),
2932 });
2933 }
2934
2935 let generics = if !self.is_in_condition()
2939 && self.check(&Token::Lt)
2940 && self.peek_looks_like_generic_arg()
2941 {
2942 self.advance(); let types = self.parse_type_list()?;
2944 self.expect_gt()?;
2946 Some(types)
2947 } else if self.check(&Token::LBracket) && self.peek_looks_like_bracket_generic() {
2948 self.advance(); let types = self.parse_type_list()?;
2951 self.expect(Token::RBracket)?;
2952 Some(types)
2953 } else {
2954 None
2955 };
2956
2957 Ok(PathSegment { ident, generics })
2958 }
2959
2960 fn peek_looks_like_bracket_generic(&mut self) -> bool {
2962 match self.peek_next().cloned() {
2965 Some(Token::Ident(name)) => {
2967 let is_type_name = name.chars().next().map_or(false, |c| c.is_uppercase());
2970 match self.peek_n(1) {
2971 Some(Token::RBracket) => is_type_name,
2974 Some(Token::Comma) => is_type_name, Some(Token::ColonColon) => true, Some(Token::Lt) => is_type_name, Some(Token::LBracket) => is_type_name, Some(Token::Question) => true,
2980 Some(Token::Bang) => true,
2981 Some(Token::Tilde) => true,
2982 Some(Token::Lozenge) => true,
2983 Some(Token::Interrobang) => true,
2984 Some(Token::Eq) => true,
2986 Some(Token::Plus) => false, Some(Token::Minus) => false, Some(Token::Star) => false, Some(Token::Slash) => false, Some(Token::DotDot) => false, Some(Token::DotDotEq) => false, _ => false, }
2995 }
2996 Some(Token::SelfUpper) => true, Some(Token::Amp) => true, Some(Token::Star) => false,
3000 Some(Token::Fn) => true, Some(Token::LParen) => {
3002 match self.peek_n(1) {
3008 Some(Token::RParen) => true, Some(Token::Ident(name)) => {
3010 if name.chars().next().map_or(false, |c| c.is_uppercase()) {
3013 true } else {
3015 match self.peek_n(2) {
3017 Some(Token::As) => false, Some(Token::Plus) => false, Some(Token::Minus) => false, Some(Token::Star) => false, Some(Token::Slash) => false, Some(Token::Dot) => false, Some(Token::LBracket) => false, Some(Token::LParen) => false, Some(Token::RParen) => false, Some(Token::Comma) => true, _ => false, }
3029 }
3030 }
3031 _ => false, }
3033 }
3034 Some(Token::Dyn) => true, Some(Token::Impl) => true, Some(Token::Crate) => true, Some(Token::Super) => true, Some(Token::IntLit(_)) => false,
3041 Some(Token::FloatLit(_)) => false,
3042 Some(Token::SelfLower) => false, _ => false,
3046 }
3047 }
3048
3049 fn peek_looks_like_generic_arg(&mut self) -> bool {
3054 match self.peek_next().cloned() {
3056 Some(Token::Amp) => true, Some(Token::Star) => {
3059 match self.peek_n(1) {
3063 Some(Token::Const) => true, Some(Token::Mut) => true, _ => false, }
3067 }
3068 Some(Token::LBracket) => true, Some(Token::LParen) => true, Some(Token::Fn) => true, Some(Token::Simd) => true, Some(Token::Atomic) => true, Some(Token::Dyn) => true, Some(Token::Impl) => true, Some(Token::SelfUpper) => true, Some(Token::Crate) => true, Some(Token::Super) => true, Some(Token::Lifetime(_)) => true, Some(Token::Underscore) => true, Some(Token::Bang) => true,
3082 Some(Token::Question) => true,
3083 Some(Token::Tilde) => true,
3084 Some(Token::Interrobang) => true,
3085 Some(Token::Crate) => true,
3087 Some(Token::Super) => true,
3088 Some(Token::Ident(name)) => {
3090 let is_type_like = name.chars().next().map_or(false, |c| c.is_uppercase())
3093 || matches!(
3094 name.as_str(),
3095 "u8" | "u16"
3097 | "u32"
3098 | "u64"
3099 | "u128"
3100 | "usize"
3101 | "i8"
3102 | "i16"
3103 | "i32"
3104 | "i64"
3105 | "i128"
3106 | "isize"
3107 | "f32"
3108 | "f64"
3109 | "bool"
3110 | "char"
3111 | "str"
3112 );
3113 match self.peek_n(1) {
3114 Some(Token::Gt) => true,
3116 Some(Token::Shr) => true, Some(Token::Comma) => is_type_like,
3120 Some(Token::ColonColon) => true, Some(Token::Lt) => true, Some(Token::LBracket) => true, Some(Token::Question) => true,
3125 Some(Token::Bang) => true,
3126 Some(Token::Tilde) => true,
3127 Some(Token::Lozenge) => true,
3128 Some(Token::Interrobang) => true,
3129 Some(Token::Eq) => true,
3131 Some(Token::Colon) => true,
3133 _ => false,
3134 }
3135 }
3136 Some(Token::SelfLower) => false, Some(Token::IntLit(_)) => {
3141 match self.peek_n(1) {
3142 Some(Token::Comma) => true, Some(Token::Gt) => true, Some(Token::Shr) => true, _ => false, }
3147 }
3148 Some(Token::FloatLit(_)) => false,
3149 Some(Token::StringLit(_)) => false,
3150 Some(Token::True) | Some(Token::False) => false,
3151 Some(Token::Null) => false,
3152 _ => false, }
3154 }
3155
3156 fn peek_looks_like_pipe_op(&mut self) -> bool {
3159 match self.peek_next() {
3160 Some(Token::Tau) => true, Some(Token::Phi) => true, Some(Token::Sigma) => true, Some(Token::Rho) => true, Some(Token::Pi) => true, Some(Token::Alpha) => true, Some(Token::Omega) => true, Some(Token::Mu) => true, Some(Token::Chi) => true, Some(Token::Nu) => true, Some(Token::Xi) => true, Some(Token::Delta) => true, Some(Token::Iota) => true, Some(Token::ForAll) => true, Some(Token::Exists) => true, Some(Token::Compose) => true, Some(Token::Bowtie) => true, Some(Token::Integral) => true, Some(Token::Partial) => true, Some(Token::Nabla) => true, Some(Token::GradeUp) => true, Some(Token::GradeDown) => true, Some(Token::Rotate) => true, Some(Token::CycleArrow) => true, Some(Token::QuadDiamond) => true, Some(Token::SquaredPlus) => true, Some(Token::ElementSmallVerticalBar) => true, Some(Token::Union) => true, Some(Token::Match) => true, Some(Token::Send) => true, Some(Token::Recv) => true, Some(Token::Stream) => true, Some(Token::ProtoSend) => true, Some(Token::ProtoRecv) => true, Some(Token::ProtoStream) => true, Some(Token::Header) => true, Some(Token::Body) => true, Some(Token::Interrobang) => true, Some(Token::Ident(_)) => {
3205 let after_ident = self.peek_n(1);
3209 match after_ident {
3210 Some(Token::LParen) | Some(Token::LBrace) => true,
3211 Some(Token::Bang)
3213 | Some(Token::Question)
3214 | Some(Token::Tilde)
3215 | Some(Token::Lozenge) => {
3216 matches!(self.peek_n(2), Some(Token::LParen) | Some(Token::LBrace))
3217 }
3218 _ => false,
3219 }
3220 }
3221 Some(Token::Amp) => true,
3223 Some(Token::LBrace) => true,
3225 _ => false,
3227 }
3228 }
3229
3230 fn parse_type_list(&mut self) -> ParseResult<Vec<TypeExpr>> {
3231 let mut types = Vec::new();
3232 if !self.check(&Token::RParen)
3234 && !self.check(&Token::RBracket)
3235 && !self.check(&Token::Gt)
3236 && !self.check(&Token::Shr)
3237 && self.pending_gt.is_none()
3238 {
3239 types.push(self.parse_type_or_lifetime()?);
3241 while !self.pending_gt.is_some()
3244 && !self.check(&Token::Gt)
3245 && !self.check(&Token::Shr)
3246 && self.consume_if(&Token::Comma)
3247 {
3248 if self.check(&Token::RParen)
3250 || self.check(&Token::RBracket)
3251 || self.check(&Token::Gt)
3252 || self.check(&Token::Shr)
3253 {
3254 break;
3255 }
3256 types.push(self.parse_type_or_lifetime()?);
3257 }
3258 }
3259 Ok(types)
3260 }
3261
3262 fn parse_attributed_type_list(&mut self) -> ParseResult<Vec<TypeExpr>> {
3265 let mut types = Vec::new();
3266 if !self.check(&Token::RParen) {
3267 loop {
3268 while self.check(&Token::Hash) {
3270 self.advance();
3271 self.consume_if(&Token::Bang); if self.consume_if(&Token::LBracket) {
3273 let mut depth = 1;
3274 while depth > 0 && !self.is_eof() {
3275 match self.current_token() {
3276 Some(Token::LBracket) => depth += 1,
3277 Some(Token::RBracket) => depth -= 1,
3278 _ => {}
3279 }
3280 self.advance();
3281 }
3282 }
3283 }
3284 types.push(self.parse_type()?);
3286 if !self.consume_if(&Token::Comma) {
3287 break;
3288 }
3289 }
3290 }
3291 Ok(types)
3292 }
3293
3294 fn parse_tuple_struct_fields(&mut self) -> ParseResult<Vec<TypeExpr>> {
3297 let mut types = Vec::new();
3298 if !self.check(&Token::RParen) {
3299 loop {
3300 if self.check(&Token::Pub) {
3302 self.advance();
3303 if self.check(&Token::LParen) {
3305 self.advance();
3306 let mut depth = 1;
3308 while depth > 0 {
3309 match self.current_token() {
3310 Some(Token::LParen) => depth += 1,
3311 Some(Token::RParen) => depth -= 1,
3312 None => break,
3313 _ => {}
3314 }
3315 self.advance();
3316 }
3317 }
3318 }
3319 types.push(self.parse_type()?);
3321 if !self.consume_if(&Token::Comma) {
3322 break;
3323 }
3324 if self.check(&Token::RParen) {
3326 break;
3327 }
3328 }
3329 }
3330 Ok(types)
3331 }
3332
3333 fn parse_type_bounds(&mut self) -> ParseResult<Vec<TypeExpr>> {
3334 let mut bounds = Vec::new();
3335
3336 if self.check(&Token::Comma) || self.check(&Token::LBrace) || self.check(&Token::Semi) {
3338 return Ok(bounds);
3339 }
3340
3341 bounds.push(self.parse_type_or_lifetime()?);
3342 while self.consume_if(&Token::Plus) {
3343 bounds.push(self.parse_type_or_lifetime()?);
3344 }
3345 Ok(bounds)
3346 }
3347
3348 fn parse_type_or_lifetime(&mut self) -> ParseResult<TypeExpr> {
3352 if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
3353 self.advance();
3354 Ok(TypeExpr::Lifetime(name))
3355 } else if self.check(&Token::For) {
3356 self.advance(); self.expect(Token::Lt)?; let mut lifetimes = Vec::new();
3360 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
3361 lifetimes.push(lt);
3362 self.advance();
3363 while self.consume_if(&Token::Comma) {
3364 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
3365 lifetimes.push(lt);
3366 self.advance();
3367 } else {
3368 break;
3369 }
3370 }
3371 }
3372 self.expect_gt()?; let bound = self.parse_type()?;
3374 Ok(TypeExpr::Hrtb {
3375 lifetimes,
3376 bound: Box::new(bound),
3377 })
3378 } else if matches!(self.current_token(), Some(Token::Ident(_)))
3379 && self.peek_next() == Some(&Token::Eq)
3380 {
3381 let name = self.parse_ident()?;
3383 self.expect(Token::Eq)?;
3384 let ty = self.parse_type()?;
3385 Ok(TypeExpr::AssocTypeBinding {
3386 name,
3387 ty: Box::new(ty),
3388 })
3389 } else if matches!(
3390 self.current_token(),
3391 Some(Token::IntLit(_))
3392 | Some(Token::HexLit(_))
3393 | Some(Token::BinaryLit(_))
3394 | Some(Token::OctalLit(_))
3395 ) {
3396 let expr = self.parse_const_expr_simple()?;
3399 Ok(TypeExpr::ConstExpr(Box::new(expr)))
3400 } else if self.check(&Token::LBrace) {
3401 self.advance();
3403 let expr = self.parse_expr()?;
3404 self.expect(Token::RBrace)?;
3405 Ok(TypeExpr::ConstExpr(Box::new(expr)))
3406 } else {
3407 self.parse_type()
3408 }
3409 }
3410
3411 fn parse_array_dim_expr(&mut self) -> ParseResult<Expr> {
3414 if self.check(&Token::LBrace) {
3416 self.advance();
3417 let expr = self.parse_expr()?;
3418 self.expect(Token::RBrace)?;
3419 return Ok(expr);
3420 }
3421 self.parse_const_expr_simple()
3423 }
3424
3425 fn parse_const_expr_simple(&mut self) -> ParseResult<Expr> {
3429 let mut lhs = self.parse_const_expr_primary()?;
3430
3431 loop {
3432 match self.current_token() {
3433 Some(Token::Star) => {
3434 self.advance();
3435 let rhs = self.parse_const_expr_primary()?;
3436 lhs = Expr::Binary {
3437 op: BinOp::Mul,
3438 left: Box::new(lhs),
3439 right: Box::new(rhs),
3440 };
3441 }
3442 Some(Token::Plus) => {
3443 self.advance();
3444 let rhs = self.parse_const_expr_primary()?;
3445 lhs = Expr::Binary {
3446 op: BinOp::Add,
3447 left: Box::new(lhs),
3448 right: Box::new(rhs),
3449 };
3450 }
3451 Some(Token::Minus) => {
3452 self.advance();
3453 let rhs = self.parse_const_expr_primary()?;
3454 lhs = Expr::Binary {
3455 op: BinOp::Sub,
3456 left: Box::new(lhs),
3457 right: Box::new(rhs),
3458 };
3459 }
3460 Some(Token::Slash) => {
3461 self.advance();
3462 let rhs = self.parse_const_expr_primary()?;
3463 lhs = Expr::Binary {
3464 op: BinOp::Div,
3465 left: Box::new(lhs),
3466 right: Box::new(rhs),
3467 };
3468 }
3469 _ => break,
3470 }
3471 }
3472 Ok(lhs)
3473 }
3474
3475 fn parse_const_expr_primary(&mut self) -> ParseResult<Expr> {
3477 match self.current_token().cloned() {
3478 Some(Token::IntLit(_))
3479 | Some(Token::HexLit(_))
3480 | Some(Token::BinaryLit(_))
3481 | Some(Token::OctalLit(_)) => {
3482 let lit = self.parse_literal()?;
3483 Ok(Expr::Literal(lit))
3484 }
3485 Some(Token::Ident(_)) => {
3486 let path = self.parse_type_path()?;
3487 Ok(Expr::Path(path))
3488 }
3489 Some(Token::Underscore) => {
3490 let span = self.current_span();
3492 self.advance();
3493 Ok(Expr::Path(TypePath {
3494 segments: vec![PathSegment {
3495 ident: Ident {
3496 name: "_".to_string(),
3497 evidentiality: None,
3498 affect: None,
3499 span,
3500 },
3501 generics: None,
3502 }],
3503 }))
3504 }
3505 Some(Token::LParen) => {
3506 self.advance();
3507 let expr = self.parse_const_expr_simple()?;
3508 self.expect(Token::RParen)?;
3509 Ok(expr)
3510 }
3511 _ => Err(ParseError::Custom("expected const expression".to_string())),
3512 }
3513 }
3514
3515 pub fn parse_expr(&mut self) -> ParseResult<Expr> {
3518 self.skip_comments();
3520 let lhs = self.parse_expr_bp(0)?;
3521
3522 if self.consume_if(&Token::Eq) {
3524 let value = self.parse_expr()?;
3525 return Ok(Expr::Assign {
3526 target: Box::new(lhs),
3527 value: Box::new(value),
3528 });
3529 }
3530
3531 let compound_op = match self.current_token() {
3534 Some(Token::PlusEq) => Some(BinOp::Add),
3535 Some(Token::MinusEq) => Some(BinOp::Sub),
3536 Some(Token::StarEq) => Some(BinOp::Mul),
3537 Some(Token::SlashEq) => Some(BinOp::Div),
3538 Some(Token::PercentEq) => Some(BinOp::Rem),
3539 Some(Token::ShlEq) => Some(BinOp::Shl),
3540 Some(Token::ShrEq) => Some(BinOp::Shr),
3541 Some(Token::PipeEq) => Some(BinOp::BitOr),
3542 Some(Token::AmpEq) => Some(BinOp::BitAnd),
3543 Some(Token::CaretEq) => Some(BinOp::BitXor),
3544 _ => None,
3545 };
3546
3547 if let Some(op) = compound_op {
3548 self.advance();
3549 let rhs = self.parse_expr()?;
3550 let binary = Expr::Binary {
3552 left: Box::new(lhs.clone()),
3553 op,
3554 right: Box::new(rhs),
3555 };
3556 return Ok(Expr::Assign {
3557 target: Box::new(lhs),
3558 value: Box::new(binary),
3559 });
3560 }
3561
3562 match self.current_token() {
3564 Some(Token::DirectSumEq) => {
3565 self.advance();
3567 let pattern = self.parse_expr()?;
3568 return Ok(Expr::LegionSuperposition {
3569 field: Box::new(lhs),
3570 pattern: Box::new(pattern),
3571 });
3572 }
3573 Some(Token::PartialEq_) => {
3574 self.advance();
3576 let rate = self.parse_expr()?;
3577 return Ok(Expr::LegionDecay {
3578 field: Box::new(lhs),
3579 rate: Box::new(rate),
3580 });
3581 }
3582 Some(Token::InterfereEq) => {
3583 self.advance();
3585 let query = self.parse_expr()?;
3586 return Ok(Expr::LegionInterference {
3587 query: Box::new(query),
3588 field: Box::new(lhs),
3589 });
3590 }
3591 _ => {}
3592 }
3593
3594 Ok(lhs)
3595 }
3596
3597 fn parse_expr_bp(&mut self, min_bp: u8) -> ParseResult<Expr> {
3598 let mut lhs = self.parse_prefix_expr()?;
3599
3600 loop {
3601 self.skip_comments();
3606
3607 if self.check(&Token::Pipe) && self.peek_looks_like_pipe_op() {
3610 lhs = self.parse_pipe_chain(lhs)?;
3611 lhs = self.parse_postfix_after_pipe(lhs)?;
3613 continue;
3614 }
3615
3616 let op = match self.current_token() {
3618 Some(Token::Pipe) => BinOp::BitOr,
3620 Some(Token::OrOr) => BinOp::Or,
3621 Some(Token::AndAnd) => BinOp::And,
3622 Some(Token::EqEq) => BinOp::Eq,
3623 Some(Token::NotEq) => BinOp::Ne,
3624 Some(Token::Lt) => BinOp::Lt,
3625 Some(Token::LtEq) => BinOp::Le,
3626 Some(Token::Gt) => BinOp::Gt,
3627 Some(Token::GtEq) => BinOp::Ge,
3628 Some(Token::Plus) => BinOp::Add,
3629 Some(Token::Minus) => BinOp::Sub,
3630 Some(Token::Star) => BinOp::Mul,
3631 Some(Token::Slash) => BinOp::Div,
3632 Some(Token::Percent) => BinOp::Rem,
3633 Some(Token::StarStar) => BinOp::Pow,
3634 Some(Token::Amp) => BinOp::BitAnd,
3635 Some(Token::Caret) => BinOp::BitXor,
3636 Some(Token::Shl) => BinOp::Shl,
3637 Some(Token::Shr) => BinOp::Shr,
3638 Some(Token::PlusPlus) => BinOp::Concat,
3639 Some(Token::At) => BinOp::MatMul,
3641 Some(Token::BitwiseAndSymbol) => BinOp::BitAnd, Some(Token::BitwiseOrSymbol) => BinOp::BitOr, Some(Token::LogicAnd) => BinOp::And, Some(Token::CircledDot) => BinOp::Hadamard, Some(Token::Tensor) => BinOp::TensorProd, Some(Token::Interfere)
3651 | Some(Token::Distribute)
3652 | Some(Token::Broadcast)
3653 | Some(Token::Gather)
3654 | Some(Token::Consensus)
3655 | Some(Token::ConfidenceHigh) => {
3656 lhs = self.parse_legion_operator(lhs)?;
3658 continue;
3659 }
3660 _ => {
3661 if min_bp == 0 && (self.check(&Token::DotDot) || self.check(&Token::DotDotEq)) {
3667 let inclusive = self.consume_if(&Token::DotDotEq);
3668 if !inclusive {
3669 self.advance(); }
3671 let end = if self.check(&Token::Semi)
3673 || self.check(&Token::RBrace)
3674 || self.check(&Token::Comma)
3675 || self.check(&Token::RParen)
3676 || self.check(&Token::RBracket)
3677 || self.check(&Token::LBrace)
3678 {
3679 None
3680 } else {
3681 Some(Box::new(self.parse_expr_bp(0)?))
3682 };
3683 lhs = Expr::Range {
3684 start: Some(Box::new(lhs)),
3685 end,
3686 inclusive,
3687 };
3688 continue;
3689 }
3690 break;
3691 }
3692 };
3693
3694 let (l_bp, r_bp) = infix_binding_power(op);
3695 if l_bp < min_bp {
3696 break;
3697 }
3698
3699 self.advance();
3700 self.skip_comments();
3704 let rhs = self.parse_expr_bp(r_bp)?;
3705
3706 lhs = Expr::Binary {
3707 left: Box::new(lhs),
3708 op,
3709 right: Box::new(rhs),
3710 };
3711 }
3712
3713 Ok(lhs)
3714 }
3715
3716 fn parse_prefix_expr(&mut self) -> ParseResult<Expr> {
3717 match self.current_token() {
3718 Some(Token::Minus) => {
3719 self.advance();
3720 let expr = self.parse_prefix_expr()?;
3721 Ok(Expr::Unary {
3722 op: UnaryOp::Neg,
3723 expr: Box::new(expr),
3724 })
3725 }
3726 Some(Token::Bang) => {
3727 self.advance();
3728 let expr = self.parse_prefix_expr()?;
3729 Ok(Expr::Unary {
3730 op: UnaryOp::Not,
3731 expr: Box::new(expr),
3732 })
3733 }
3734 Some(Token::Star) => {
3735 self.advance();
3736 let expr = self.parse_prefix_expr()?;
3737 Ok(Expr::Unary {
3738 op: UnaryOp::Deref,
3739 expr: Box::new(expr),
3740 })
3741 }
3742 Some(Token::StarStar) => {
3744 self.advance();
3745 let inner = self.parse_prefix_expr()?;
3746 let first_deref = Expr::Unary {
3748 op: UnaryOp::Deref,
3749 expr: Box::new(inner),
3750 };
3751 Ok(Expr::Unary {
3752 op: UnaryOp::Deref,
3753 expr: Box::new(first_deref),
3754 })
3755 }
3756 Some(Token::Amp) => {
3757 self.advance();
3758 let op = if self.consume_if(&Token::Mut) {
3759 UnaryOp::RefMut
3760 } else {
3761 UnaryOp::Ref
3762 };
3763 let expr = self.parse_prefix_expr()?;
3764 Ok(Expr::Unary {
3765 op,
3766 expr: Box::new(expr),
3767 })
3768 }
3769 Some(Token::Question) => {
3771 self.advance();
3772 let expr = self.parse_prefix_expr()?;
3773 Ok(Expr::Evidential {
3774 expr: Box::new(expr),
3775 evidentiality: Evidentiality::Uncertain,
3776 })
3777 }
3778 Some(Token::Tilde) => {
3779 self.advance();
3780 let expr = self.parse_prefix_expr()?;
3781 Ok(Expr::Evidential {
3782 expr: Box::new(expr),
3783 evidentiality: Evidentiality::Reported,
3784 })
3785 }
3786 Some(Token::Interrobang) => {
3787 self.advance();
3788 let expr = self.parse_prefix_expr()?;
3789 Ok(Expr::Evidential {
3790 expr: Box::new(expr),
3791 evidentiality: Evidentiality::Paradox,
3792 })
3793 }
3794 Some(Token::Move) => {
3796 self.advance();
3797 self.parse_pipe_closure_with_move(true)
3798 }
3799 Some(Token::Pipe) | Some(Token::OrOr) => self.parse_pipe_closure_with_move(false),
3801 _ => self.parse_postfix_expr(),
3802 }
3803 }
3804
3805 fn parse_pipe_closure_with_move(&mut self, is_move: bool) -> ParseResult<Expr> {
3807 let params = if self.consume_if(&Token::OrOr) {
3808 Vec::new()
3810 } else {
3811 self.expect(Token::Pipe)?;
3813 let mut params = Vec::new();
3814 if !self.check(&Token::Pipe) {
3815 loop {
3816 let pattern = self.parse_pattern()?;
3818 let ty = if self.consume_if(&Token::Colon) {
3819 Some(self.parse_type()?)
3820 } else {
3821 None
3822 };
3823 params.push(ClosureParam { pattern, ty });
3824 if !self.consume_if(&Token::Comma) {
3825 break;
3826 }
3827 if self.check(&Token::Pipe) {
3828 break;
3829 }
3830 }
3831 }
3832 self.expect(Token::Pipe)?;
3833 params
3834 };
3835
3836 let return_type = if self.consume_if(&Token::Arrow) {
3838 Some(self.parse_type()?)
3839 } else {
3840 None
3841 };
3842
3843 let body = self.parse_expr()?;
3844 Ok(Expr::Closure {
3845 params,
3846 return_type,
3847 body: Box::new(body),
3848 is_move,
3849 })
3850 }
3851
3852 fn parse_macro_tokens(&mut self) -> ParseResult<String> {
3854 let (open, close) = match self.current_token() {
3856 Some(Token::LParen) => (Token::LParen, Token::RParen),
3857 Some(Token::LBracket) => (Token::LBracket, Token::RBracket),
3858 Some(Token::LBrace) => (Token::LBrace, Token::RBrace),
3859 _ => {
3860 return Err(ParseError::Custom(
3861 "expected '(', '[', or '{' for macro invocation".to_string(),
3862 ))
3863 }
3864 };
3865
3866 self.advance(); let mut tokens = String::new();
3868 let mut depth = 1;
3869
3870 while depth > 0 && !self.is_eof() {
3871 if self.check(&open) {
3872 depth += 1;
3873 } else if self.check(&close) {
3874 depth -= 1;
3875 if depth == 0 {
3876 break;
3877 }
3878 }
3879
3880 if let Some((token, span)) = &self.current {
3882 let token_str = match token {
3884 Token::Ident(s) => s.clone(),
3885 Token::IntLit(s) => s.clone(),
3886 Token::FloatLit(s) => s.clone(),
3887 Token::StringLit(s) => {
3888 format!("\"{}\"", s.replace('\\', "\\\\").replace('"', "\\\""))
3889 }
3890 Token::CharLit(c) => format!("'{}'", c),
3891 Token::Comma => ",".to_string(),
3892 Token::Colon => ":".to_string(),
3893 Token::ColonColon => "::".to_string(),
3894 Token::Dot => ".".to_string(),
3895 Token::DotDot => "..".to_string(),
3896 Token::Semi => ";".to_string(),
3897 Token::LParen => "(".to_string(),
3898 Token::RParen => ")".to_string(),
3899 Token::LBrace => "{".to_string(),
3900 Token::RBrace => "}".to_string(),
3901 Token::LBracket => "[".to_string(),
3902 Token::RBracket => "]".to_string(),
3903 Token::Lt => "<".to_string(),
3904 Token::Gt => ">".to_string(),
3905 Token::Eq => "=".to_string(),
3906 Token::FatArrow => "=>".to_string(),
3907 Token::Bang => "!".to_string(),
3908 Token::Question => "?".to_string(),
3909 Token::Amp => "&".to_string(),
3910 Token::Pipe => "|".to_string(),
3911 Token::Underscore => "_".to_string(),
3912 Token::Plus => "+".to_string(),
3913 Token::Minus => "-".to_string(),
3914 Token::Star => "*".to_string(),
3915 Token::Slash => "/".to_string(),
3916 Token::Percent => "%".to_string(),
3917 Token::EqEq => "==".to_string(),
3918 Token::NotEq => "!=".to_string(),
3919 Token::LtEq => "<=".to_string(),
3920 Token::GtEq => ">=".to_string(),
3921 Token::AndAnd => "&&".to_string(),
3922 Token::OrOr => "||".to_string(),
3923 Token::Arrow => "->".to_string(),
3924 Token::Hash => "#".to_string(),
3925 Token::At => "@".to_string(),
3926 Token::Tilde => "~".to_string(),
3927 Token::SelfLower => "self".to_string(),
3929 Token::SelfUpper => "Self".to_string(),
3930 Token::Let => "let".to_string(),
3931 Token::Mut => "mut".to_string(),
3932 Token::Fn => "fn".to_string(),
3933 Token::If => "if".to_string(),
3934 Token::Else => "else".to_string(),
3935 Token::Match => "match".to_string(),
3936 Token::For => "for".to_string(),
3937 Token::While => "while".to_string(),
3938 Token::Loop => "loop".to_string(),
3939 Token::Break => "break".to_string(),
3940 Token::Continue => "continue".to_string(),
3941 Token::Return => "return".to_string(),
3942 Token::Struct => "struct".to_string(),
3943 Token::Enum => "enum".to_string(),
3944 Token::Impl => "impl".to_string(),
3945 Token::Trait => "trait".to_string(),
3946 Token::Type => "type".to_string(),
3947 Token::Pub => "pub".to_string(),
3948 Token::Mod => "mod".to_string(),
3949 Token::Use => "use".to_string(),
3950 Token::As => "as".to_string(),
3951 Token::In => "in".to_string(),
3952 Token::True => "true".to_string(),
3953 Token::False => "false".to_string(),
3954 Token::Null => "null".to_string(),
3955 Token::Const => "const".to_string(),
3956 Token::Static => "static".to_string(),
3957 Token::Async => "async".to_string(),
3958 Token::Await => "await".to_string(),
3959 Token::Move => "move".to_string(),
3960 Token::Ref => "ref".to_string(),
3961 Token::Where => "where".to_string(),
3962 Token::Dyn => "dyn".to_string(),
3963 Token::Super => "super".to_string(),
3964 Token::Crate => "crate".to_string(),
3965 _ => format!("{:?}", token),
3966 };
3967 let suppress_space_before = matches!(
3969 token,
3970 Token::Dot
3971 | Token::ColonColon
3972 | Token::LParen
3973 | Token::LBracket
3974 | Token::LBrace
3975 | Token::RParen
3976 | Token::RBracket
3977 | Token::RBrace
3978 | Token::Comma
3979 | Token::Semi
3980 );
3981 if !tokens.is_empty()
3982 && !suppress_space_before
3983 && !tokens.ends_with('.')
3984 && !tokens.ends_with("::")
3985 && !tokens.ends_with('(')
3986 && !tokens.ends_with('[')
3987 && !tokens.ends_with('{')
3988 {
3989 tokens.push(' ');
3990 }
3991 tokens.push_str(&token_str);
3992 }
3993 self.advance();
3994 }
3995
3996 self.expect(close)?;
3997 Ok(tokens)
3998 }
3999
4000 fn is_non_callable_expr(expr: &Expr) -> bool {
4004 matches!(
4005 expr,
4006 Expr::If { .. }
4007 | Expr::While { .. }
4008 | Expr::Match { .. }
4009 | Expr::Loop { .. }
4010 | Expr::For { .. }
4011 | Expr::Block(_)
4012 )
4013 }
4014
4015 fn parse_postfix_expr(&mut self) -> ParseResult<Expr> {
4016 let mut expr = self.parse_primary_expr()?;
4017
4018 loop {
4019 self.skip_comments();
4024
4025 match self.current_token() {
4026 Some(Token::LParen) => {
4027 if Self::is_non_callable_expr(&expr) {
4030 break;
4031 }
4032 self.advance();
4033 let args = self.parse_expr_list()?;
4034 self.expect(Token::RParen)?;
4035 expr = Expr::Call {
4036 func: Box::new(expr),
4037 args,
4038 };
4039 }
4040 Some(Token::LBracket) => {
4041 self.advance();
4042 let first = self.parse_expr()?;
4044 if self.consume_if(&Token::Comma) {
4045 let mut indices = vec![first];
4047 while !self.check(&Token::RBracket) && !self.is_eof() {
4048 indices.push(self.parse_expr()?);
4049 if !self.consume_if(&Token::Comma) {
4050 break;
4051 }
4052 }
4053 self.expect(Token::RBracket)?;
4054 expr = Expr::Index {
4056 expr: Box::new(expr),
4057 index: Box::new(Expr::Tuple(indices)),
4058 };
4059 } else {
4060 self.expect(Token::RBracket)?;
4061 expr = Expr::Index {
4062 expr: Box::new(expr),
4063 index: Box::new(first),
4064 };
4065 }
4066 }
4067 Some(Token::Dot) => {
4068 self.advance();
4069 if self.check(&Token::Hourglass) {
4071 self.advance();
4072 let evidentiality = self.parse_evidentiality_opt();
4073 expr = Expr::Await {
4074 expr: Box::new(expr),
4075 evidentiality,
4076 };
4077 continue;
4078 }
4079 let field = if let Some(Token::IntLit(idx)) = self.current_token() {
4081 let idx = idx.clone();
4082 let span = self.current_span();
4083 self.advance();
4084 Ident {
4085 name: idx,
4086 evidentiality: None,
4087 affect: None,
4088 span,
4089 }
4090 } else {
4091 self.parse_ident()?
4092 };
4093 if self.check(&Token::ColonColon) {
4095 self.advance(); self.expect(Token::Lt)?;
4097 let was_in_condition = self.in_condition;
4099 self.in_condition = false;
4100 let type_args = self.parse_type_list()?;
4101 self.expect_gt()?;
4102 self.in_condition = was_in_condition;
4103 self.expect(Token::LParen)?;
4104 let args = self.parse_expr_list()?;
4105 self.expect(Token::RParen)?;
4106 expr = Expr::MethodCall {
4107 receiver: Box::new(expr),
4108 method: field,
4109 type_args: Some(type_args),
4110 args,
4111 };
4112 } else if self.check(&Token::LParen) {
4113 self.advance();
4114 let args = self.parse_expr_list()?;
4115 self.expect(Token::RParen)?;
4116 expr = Expr::MethodCall {
4117 receiver: Box::new(expr),
4118 method: field,
4119 type_args: None,
4120 args,
4121 };
4122 } else {
4123 while self.check(&Token::Tilde) || self.check(&Token::Lozenge) {
4126 self.advance();
4127 }
4128 expr = Expr::Field {
4129 expr: Box::new(expr),
4130 field,
4131 };
4132 }
4133 }
4134 Some(Token::Question) => {
4135 if self.peek_next() == Some(&Token::LBrace) && !self.is_in_condition() {
4138 if let Expr::Path(ref path) = expr {
4139 let path = path.clone();
4140 self.advance(); self.advance(); let (fields, rest) = self.parse_struct_fields()?;
4143 self.expect(Token::RBrace)?;
4144 expr = Expr::Struct { path, fields, rest };
4145 continue;
4146 }
4147 }
4148 self.advance();
4150 expr = Expr::Try(Box::new(expr));
4151 }
4152 Some(Token::As) => {
4154 self.advance();
4155 let ty = self.parse_type()?;
4156 expr = Expr::Cast {
4157 expr: Box::new(expr),
4158 ty,
4159 };
4160 }
4161 Some(Token::Bang) => {
4162 if let Expr::Path(path) = &expr {
4164 let peeked = self.peek_next();
4165 let is_macro = match peeked {
4167 Some(Token::LParen) | Some(Token::LBracket) | Some(Token::LBrace) => {
4168 true
4169 }
4170 _ => false,
4171 };
4172 if is_macro {
4173 self.advance(); let tokens = self.parse_macro_tokens()?;
4175 expr = Expr::Macro {
4176 path: path.clone(),
4177 tokens,
4178 };
4179 continue;
4180 }
4181 }
4182 if let Some(ev) = self.parse_evidentiality_opt() {
4184 expr = Expr::Evidential {
4185 expr: Box::new(expr),
4186 evidentiality: ev,
4187 };
4188 } else {
4189 break;
4190 }
4191 }
4192 Some(Token::Tilde) | Some(Token::Interrobang) | Some(Token::Lozenge) => {
4193 if let Some(ev) = self.parse_evidentiality_opt() {
4194 if self.check(&Token::LBrace) && !self.is_in_condition() {
4197 if let Expr::Path(ref path) = expr {
4198 let path = path.clone();
4199 self.advance(); let (fields, rest) = self.parse_struct_fields()?;
4201 self.expect(Token::RBrace)?;
4202 expr = Expr::Struct { path, fields, rest };
4203 continue;
4204 }
4205 }
4206 expr = Expr::Evidential {
4208 expr: Box::new(expr),
4209 evidentiality: ev,
4210 };
4211 } else {
4212 break;
4213 }
4214 }
4215 Some(Token::ColonColon) => {
4216 self.advance(); let method = self.parse_ident()?;
4219 let type_args = if self.check(&Token::ColonColon) {
4221 self.advance();
4222 self.expect(Token::Lt)?;
4223 let types = self.parse_type_list()?;
4224 self.expect_gt()?;
4225 Some(types)
4226 } else {
4227 None
4228 };
4229 if self.check(&Token::LParen) {
4230 self.advance();
4231 let args = self.parse_expr_list()?;
4232 self.expect(Token::RParen)?;
4233 expr = Expr::MethodCall {
4235 receiver: Box::new(expr),
4236 method,
4237 type_args,
4238 args,
4239 };
4240 } else {
4241 expr = Expr::Field {
4243 expr: Box::new(expr),
4244 field: method,
4245 };
4246 }
4247 }
4248 Some(Token::Hourglass) => {
4249 self.advance();
4250 let evidentiality = match self.current_token() {
4252 Some(Token::Question) => {
4253 self.advance();
4254 Some(Evidentiality::Uncertain)
4255 }
4256 Some(Token::Bang) => {
4257 self.advance();
4258 Some(Evidentiality::Known)
4259 }
4260 Some(Token::Tilde) => {
4261 self.advance();
4262 Some(Evidentiality::Reported)
4263 }
4264 Some(Token::Lozenge) => {
4265 self.advance();
4266 Some(Evidentiality::Predicted)
4267 }
4268 Some(Token::Interrobang) => {
4269 self.advance();
4270 Some(Evidentiality::Paradox)
4271 }
4272 _ => None,
4273 };
4274 expr = Expr::Await {
4275 expr: Box::new(expr),
4276 evidentiality,
4277 };
4278 }
4279 Some(Token::MiddleDot) => {
4282 let first_segment = self.expr_to_incorporation_segment(expr.clone())?;
4284 let mut segments = vec![first_segment];
4285
4286 while self.consume_if(&Token::MiddleDot) {
4287 let name = if let Some(Token::IntLit(idx)) = self.current_token().cloned() {
4289 let span = self.current_span();
4290 self.advance();
4291 Ident {
4292 name: idx,
4293 evidentiality: None,
4294 affect: None,
4295 span,
4296 }
4297 } else {
4298 self.parse_ident()?
4299 };
4300 if self.check(&Token::LBracket) && self.peek_looks_like_bracket_generic() {
4302 self.advance(); let _generics = self.parse_type_list()?;
4304 self.expect(Token::RBracket)?;
4305 }
4307 if self.check(&Token::Lt) && self.peek_looks_like_generic_arg() {
4309 self.advance(); let _generics = self.parse_type_list()?;
4311 self.expect_gt()?;
4312 }
4313 let args = if self.check(&Token::LParen) {
4314 self.advance();
4315 let args = self.parse_expr_list()?;
4316 self.expect(Token::RParen)?;
4317 Some(args)
4318 } else {
4319 None
4320 };
4321 segments.push(IncorporationSegment { name, args });
4322 }
4323
4324 expr = Expr::Incorporation { segments };
4325 }
4326 _ => break,
4327 }
4328 }
4329
4330 Ok(expr)
4331 }
4332
4333 fn parse_primary_expr(&mut self) -> ParseResult<Expr> {
4334 match self.current_token().cloned() {
4335 Some(Token::IntLit(s)) => {
4336 self.advance();
4337 Ok(Expr::Literal(Literal::Int {
4338 value: s,
4339 base: NumBase::Decimal,
4340 suffix: None,
4341 }))
4342 }
4343 Some(Token::BinaryLit(s)) => {
4344 self.advance();
4345 Ok(Expr::Literal(Literal::Int {
4346 value: s,
4347 base: NumBase::Binary,
4348 suffix: None,
4349 }))
4350 }
4351 Some(Token::OctalLit(s)) => {
4352 self.advance();
4353 Ok(Expr::Literal(Literal::Int {
4354 value: s,
4355 base: NumBase::Octal,
4356 suffix: None,
4357 }))
4358 }
4359 Some(Token::HexLit(s)) => {
4360 self.advance();
4361 Ok(Expr::Literal(Literal::Int {
4362 value: s,
4363 base: NumBase::Hex,
4364 suffix: None,
4365 }))
4366 }
4367 Some(Token::VigesimalLit(s)) => {
4368 self.advance();
4369 Ok(Expr::Literal(Literal::Int {
4370 value: s,
4371 base: NumBase::Vigesimal,
4372 suffix: None,
4373 }))
4374 }
4375 Some(Token::SexagesimalLit(s)) => {
4376 self.advance();
4377 Ok(Expr::Literal(Literal::Int {
4378 value: s,
4379 base: NumBase::Sexagesimal,
4380 suffix: None,
4381 }))
4382 }
4383 Some(Token::DuodecimalLit(s)) => {
4384 self.advance();
4385 Ok(Expr::Literal(Literal::Int {
4386 value: s,
4387 base: NumBase::Duodecimal,
4388 suffix: None,
4389 }))
4390 }
4391 Some(Token::FloatLit(s)) => {
4392 self.advance();
4393 Ok(Expr::Literal(Literal::Float {
4394 value: s,
4395 suffix: None,
4396 }))
4397 }
4398 Some(Token::StringLit(s)) => {
4399 self.advance();
4400 Ok(Expr::Literal(Literal::String(s)))
4401 }
4402 Some(Token::MultiLineStringLit(s)) => {
4403 self.advance();
4404 Ok(Expr::Literal(Literal::MultiLineString(s)))
4405 }
4406 Some(Token::RawStringLit(s)) | Some(Token::RawStringDelimited(s)) => {
4407 self.advance();
4408 Ok(Expr::Literal(Literal::RawString(s)))
4409 }
4410 Some(Token::DotDot) | Some(Token::DotDotEq) => {
4413 let inclusive = self.consume_if(&Token::DotDotEq);
4414 if !inclusive {
4415 self.advance(); }
4417 let end = if self.check(&Token::RParen)
4419 || self.check(&Token::RBracket)
4420 || self.check(&Token::Comma)
4421 || self.check(&Token::Semi)
4422 || self.check(&Token::RBrace)
4423 {
4424 None
4425 } else {
4426 Some(Box::new(self.parse_expr()?))
4427 };
4428 Ok(Expr::Range {
4429 start: None,
4430 end,
4431 inclusive,
4432 })
4433 }
4434 Some(Token::ByteStringLit(bytes)) => {
4435 self.advance();
4436 Ok(Expr::Literal(Literal::ByteString(bytes)))
4437 }
4438 Some(Token::InterpolatedStringLit(s)) => {
4439 self.advance();
4440 let parts = self.parse_interpolation_parts(&s)?;
4442 Ok(Expr::Literal(Literal::InterpolatedString { parts }))
4443 }
4444 Some(Token::SigilStringSql(s)) => {
4445 self.advance();
4446 Ok(Expr::Literal(Literal::SigilStringSql(s)))
4447 }
4448 Some(Token::SigilStringRoute(s)) => {
4449 self.advance();
4450 Ok(Expr::Literal(Literal::SigilStringRoute(s)))
4451 }
4452 Some(Token::CharLit(c)) => {
4453 self.advance();
4454 Ok(Expr::Literal(Literal::Char(c)))
4455 }
4456 Some(Token::ByteCharLit(b)) => {
4457 self.advance();
4458 Ok(Expr::Literal(Literal::ByteChar(b)))
4459 }
4460 Some(Token::True) => {
4461 self.advance();
4462 Ok(Expr::Literal(Literal::Bool(true)))
4463 }
4464 Some(Token::False) => {
4465 self.advance();
4466 Ok(Expr::Literal(Literal::Bool(false)))
4467 }
4468 Some(Token::Null) => {
4469 self.advance();
4470 Ok(Expr::Literal(Literal::Null))
4471 }
4472 Some(Token::Empty) => {
4473 self.advance();
4474 Ok(Expr::Literal(Literal::Empty))
4475 }
4476 Some(Token::Infinity) => {
4477 self.advance();
4478 Ok(Expr::Literal(Literal::Infinity))
4479 }
4480 Some(Token::Circle) => {
4481 self.advance();
4482 Ok(Expr::Literal(Literal::Circle))
4483 }
4484 Some(Token::LParen) => {
4485 self.advance();
4486 if self.check(&Token::RParen) {
4487 self.advance();
4488 return Ok(Expr::Tuple(vec![]));
4489 }
4490 let expr = self.parse_expr()?;
4491 if self.consume_if(&Token::Comma) {
4492 let mut exprs = vec![expr];
4493 while !self.check(&Token::RParen) {
4494 exprs.push(self.parse_expr()?);
4495 if !self.consume_if(&Token::Comma) {
4496 break;
4497 }
4498 }
4499 self.expect(Token::RParen)?;
4500 Ok(Expr::Tuple(exprs))
4501 } else {
4502 self.expect(Token::RParen)?;
4503 Ok(expr)
4504 }
4505 }
4506 Some(Token::LBracket) => {
4507 self.advance();
4508 if self.check(&Token::RBracket) {
4510 self.advance();
4511 return Ok(Expr::Array(vec![]));
4512 }
4513 let first = self.parse_expr()?;
4515 if self.consume_if(&Token::Semi) {
4517 let count = self.parse_expr()?;
4518 self.expect(Token::RBracket)?;
4519 return Ok(Expr::ArrayRepeat {
4520 value: Box::new(first),
4521 count: Box::new(count),
4522 });
4523 }
4524 let mut exprs = vec![first];
4526 while self.consume_if(&Token::Comma) {
4527 self.skip_comments();
4529 if self.check(&Token::RBracket) {
4530 break; }
4532 exprs.push(self.parse_expr()?);
4533 }
4534 self.skip_comments();
4535 self.expect(Token::RBracket)?;
4536 Ok(Expr::Array(exprs))
4537 }
4538 Some(Token::LBrace) => {
4539 self.parse_block_or_closure()
4541 }
4542 Some(Token::If) => self.parse_if_expr(),
4543 Some(Token::Match) => self.parse_match_expr(),
4544 Some(Token::Unsafe) => {
4545 self.advance();
4546 let block = self.parse_block()?;
4547 Ok(Expr::Unsafe(block))
4548 }
4549 Some(Token::Async) => {
4550 self.advance();
4551 let is_move = self.consume_if(&Token::Move);
4552 let block = self.parse_block()?;
4553 Ok(Expr::Async { block, is_move })
4554 }
4555 Some(Token::Const) => {
4556 self.advance();
4559 let block = self.parse_block()?;
4560 Ok(Expr::Block(block))
4561 }
4562 Some(Token::Lifetime(name)) => {
4563 let span = self.current_span();
4565 let label = Ident {
4566 name: name.clone(),
4567 evidentiality: None,
4568 affect: None,
4569 span,
4570 };
4571 self.advance();
4572 self.expect(Token::Colon)?;
4573 match self.current_token().cloned() {
4574 Some(Token::Loop) => {
4575 self.advance();
4576 let body = self.parse_block()?;
4577 Ok(Expr::Loop {
4578 label: Some(label),
4579 body,
4580 })
4581 }
4582 Some(Token::While) => {
4583 self.advance();
4584 let condition = if self.consume_if(&Token::Let) {
4586 let pattern = self.parse_pattern()?;
4587 self.expect(Token::Eq)?;
4588 let value = self.parse_condition()?;
4589 Expr::Let {
4590 pattern,
4591 value: Box::new(value),
4592 }
4593 } else {
4594 self.parse_condition()?
4595 };
4596 let body = self.parse_block()?;
4597 Ok(Expr::While {
4598 label: Some(label),
4599 condition: Box::new(condition),
4600 body,
4601 })
4602 }
4603 Some(Token::For) => {
4604 self.advance();
4605 let pattern = self.parse_pattern()?;
4606 self.expect(Token::In)?;
4607 let iter = self.parse_condition()?;
4608 let body = self.parse_block()?;
4609 Ok(Expr::For {
4610 label: Some(label),
4611 pattern,
4612 iter: Box::new(iter),
4613 body,
4614 })
4615 }
4616 other => Err(ParseError::UnexpectedToken {
4617 expected: "loop, while, or for after label".to_string(),
4618 found: other.unwrap_or(Token::Null),
4619 span: self.current_span(),
4620 }),
4621 }
4622 }
4623 Some(Token::Loop) => {
4624 self.advance();
4625 let body = self.parse_block()?;
4626 Ok(Expr::Loop { label: None, body })
4627 }
4628 Some(Token::While) => {
4629 self.advance();
4630 let condition = if self.consume_if(&Token::Let) {
4632 let pattern = self.parse_pattern()?;
4633 self.expect(Token::Eq)?;
4634 let value = self.parse_condition()?;
4635 Expr::Let {
4636 pattern,
4637 value: Box::new(value),
4638 }
4639 } else {
4640 self.parse_condition()?
4641 };
4642 let body = self.parse_block()?;
4643 Ok(Expr::While {
4644 label: None,
4645 condition: Box::new(condition),
4646 body,
4647 })
4648 }
4649 Some(Token::For) => {
4650 self.advance();
4651 let pattern = self.parse_pattern()?;
4652 self.expect(Token::In)?;
4653 let iter = self.parse_condition()?;
4654 let body = self.parse_block()?;
4655 Ok(Expr::For {
4656 label: None,
4657 pattern,
4658 iter: Box::new(iter),
4659 body,
4660 })
4661 }
4662 Some(Token::Return) => {
4663 self.advance();
4664 let value = if self.check(&Token::Semi)
4666 || self.check(&Token::RBrace)
4667 || self.check(&Token::Comma)
4668 {
4669 None
4670 } else {
4671 Some(Box::new(self.parse_expr()?))
4672 };
4673 Ok(Expr::Return(value))
4674 }
4675 Some(Token::Break) => {
4676 self.advance();
4677 let label = if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
4679 let span = self.current_span();
4680 let label = Ident {
4681 name,
4682 evidentiality: None,
4683 affect: None,
4684 span,
4685 };
4686 self.advance();
4687 Some(label)
4688 } else {
4689 None
4690 };
4691 let value = if self.check(&Token::Semi)
4693 || self.check(&Token::RBrace)
4694 || self.check(&Token::Comma)
4695 {
4696 None
4697 } else {
4698 Some(Box::new(self.parse_expr()?))
4699 };
4700 Ok(Expr::Break { label, value })
4701 }
4702 Some(Token::Continue) => {
4703 self.advance();
4704 let label = if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
4706 let span = self.current_span();
4707 let label = Ident {
4708 name,
4709 evidentiality: None,
4710 affect: None,
4711 span,
4712 };
4713 self.advance();
4714 Some(label)
4715 } else {
4716 None
4717 };
4718 Ok(Expr::Continue { label })
4719 }
4720 Some(Token::Tau) | Some(Token::Phi) | Some(Token::Sigma) | Some(Token::Rho)
4722 | Some(Token::Lambda) | Some(Token::Pi) => {
4723 let kind = self.parse_morpheme_kind()?;
4724 if self.check(&Token::LBrace) {
4725 self.advance();
4726 self.skip_comments();
4727 let body = if self.looks_like_morpheme_closure() {
4729 self.parse_morpheme_closure()?
4730 } else {
4731 self.parse_expr()?
4732 };
4733 self.expect(Token::RBrace)?;
4734 Ok(Expr::Morpheme {
4735 kind,
4736 body: Box::new(body),
4737 })
4738 } else {
4739 Ok(Expr::Morpheme {
4741 kind,
4742 body: Box::new(Expr::Path(TypePath {
4743 segments: vec![PathSegment {
4744 ident: Ident {
4745 name: "_".to_string(),
4746 evidentiality: None,
4747 affect: None,
4748 span: Span::default(),
4749 },
4750 generics: None,
4751 }],
4752 })),
4753 })
4754 }
4755 }
4756 Some(Token::Sqrt) => {
4758 let span = self.current_span();
4760 self.advance();
4761 let name = if let Some(Token::IntLit(n)) = self.current_token().cloned() {
4762 let merged_span = span.merge(self.current_span());
4763 self.advance();
4764 (format!("√{}", n), merged_span)
4765 } else {
4766 ("√".to_string(), span)
4767 };
4768 Ok(Expr::Path(TypePath {
4769 segments: vec![PathSegment {
4770 ident: Ident {
4771 name: name.0,
4772 evidentiality: None,
4773 affect: None,
4774 span: name.1,
4775 },
4776 generics: None,
4777 }],
4778 }))
4779 }
4780 Some(Token::Underscore) => {
4781 let span = self.current_span();
4783 self.advance();
4784 Ok(Expr::Path(TypePath {
4785 segments: vec![PathSegment {
4786 ident: Ident {
4787 name: "_".to_string(),
4788 evidentiality: None,
4789 affect: None,
4790 span,
4791 },
4792 generics: None,
4793 }],
4794 }))
4795 }
4796 Some(Token::SelfLower) => {
4797 let span = self.current_span();
4799 self.advance();
4800 Ok(Expr::Path(TypePath {
4801 segments: vec![PathSegment {
4802 ident: Ident {
4803 name: "self".to_string(),
4804 evidentiality: None,
4805 affect: None,
4806 span,
4807 },
4808 generics: None,
4809 }],
4810 }))
4811 }
4812 Some(Token::SelfUpper) => {
4813 let span = self.current_span();
4815 self.advance();
4816 let mut segments = vec![PathSegment {
4817 ident: Ident {
4818 name: "Self".to_string(),
4819 evidentiality: None,
4820 affect: None,
4821 span,
4822 },
4823 generics: None,
4824 }];
4825 while self.consume_if(&Token::ColonColon) {
4827 if self.check(&Token::Lt) {
4829 self.advance(); let types = self.parse_type_list()?;
4831 self.expect_gt()?;
4832 if let Some(last) = segments.last_mut() {
4834 last.generics = Some(types);
4835 }
4836 break;
4837 }
4838 segments.push(self.parse_path_segment()?);
4839 }
4840 let path = TypePath { segments };
4841 if self.check(&Token::LBrace) && !self.is_in_condition() {
4843 self.advance();
4844 let (fields, rest) = self.parse_struct_fields()?;
4845 self.expect(Token::RBrace)?;
4846 Ok(Expr::Struct { path, fields, rest })
4847 } else {
4848 Ok(Expr::Path(path))
4849 }
4850 }
4851 Some(Token::Ident(_)) => {
4852 let path = self.parse_type_path()?;
4853
4854 if self.check(&Token::LBrace) && !self.is_in_condition() {
4858 self.advance();
4859 let (fields, rest) = self.parse_struct_fields()?;
4860 self.expect(Token::RBrace)?;
4861 Ok(Expr::Struct { path, fields, rest })
4862 } else {
4863 Ok(Expr::Path(path))
4864 }
4865 }
4866 Some(Token::Asm) => self.parse_inline_asm(),
4867 Some(Token::Volatile) => self.parse_volatile_expr(),
4868 Some(Token::Simd) => self.parse_simd_expr(),
4869 Some(Token::Atomic) => self.parse_atomic_expr(),
4870 Some(Token::Dot) => {
4876 let dot_span = self.current_span();
4877 self.advance(); match self.current_token() {
4879 Some(Token::Ident(name)) => {
4880 let field_name = name.clone();
4881 let field_span = self.current_span();
4882 self.advance();
4883 let self_expr = Expr::Path(TypePath {
4885 segments: vec![PathSegment {
4886 ident: Ident {
4887 name: "self".to_string(),
4888 evidentiality: None,
4889 affect: None,
4890 span: dot_span,
4891 },
4892 generics: None,
4893 }],
4894 });
4895 Ok(Expr::Field {
4896 expr: Box::new(self_expr),
4897 field: Ident {
4898 name: field_name,
4899 evidentiality: None,
4900 affect: None,
4901 span: field_span,
4902 },
4903 })
4904 }
4905 Some(token) => Err(ParseError::UnexpectedToken {
4906 expected: "identifier after '.' for implicit self field".to_string(),
4907 found: token.clone(),
4908 span: self.current_span(),
4909 }),
4910 None => Err(ParseError::UnexpectedEof),
4911 }
4912 }
4913 Some(ref token) if Self::keyword_as_ident(token).is_some() => {
4915 let path = self.parse_type_path()?;
4916 if self.check(&Token::LBrace) && !self.is_in_condition() {
4919 self.advance();
4920 let (fields, rest) = self.parse_struct_fields()?;
4921 self.expect(Token::RBrace)?;
4922 Ok(Expr::Struct { path, fields, rest })
4923 } else {
4924 Ok(Expr::Path(path))
4925 }
4926 }
4927 Some(token) => Err(ParseError::UnexpectedToken {
4928 expected: "expression".to_string(),
4929 found: token,
4930 span: self.current_span(),
4931 }),
4932 None => Err(ParseError::UnexpectedEof),
4933 }
4934 }
4935
4936 fn parse_inline_asm(&mut self) -> ParseResult<Expr> {
4947 self.expect(Token::Asm)?;
4948 self.expect(Token::Bang)?;
4949 self.expect(Token::LParen)?;
4950
4951 let template = match self.current_token().cloned() {
4953 Some(Token::StringLit(s)) => {
4954 self.advance();
4955 s
4956 }
4957 Some(t) => {
4958 return Err(ParseError::UnexpectedToken {
4959 expected: "assembly template string".to_string(),
4960 found: t,
4961 span: self.current_span(),
4962 });
4963 }
4964 None => return Err(ParseError::UnexpectedEof),
4965 };
4966
4967 let mut outputs = Vec::new();
4968 let mut inputs = Vec::new();
4969 let mut clobbers = Vec::new();
4970 let mut options = AsmOptions::default();
4971
4972 while self.consume_if(&Token::Comma) {
4974 if self.check(&Token::RParen) {
4975 break;
4976 }
4977
4978 match self.current_token().cloned() {
4979 Some(Token::Ident(ref name)) if name == "out" => {
4980 self.advance();
4981 let operand = self.parse_asm_operand(AsmOperandKind::Output)?;
4982 outputs.push(operand);
4983 }
4984 Some(Token::In) => {
4986 self.advance();
4987 let operand = self.parse_asm_operand(AsmOperandKind::Input)?;
4988 inputs.push(operand);
4989 }
4990 Some(Token::Ident(ref name)) if name == "inout" => {
4991 self.advance();
4992 let operand = self.parse_asm_operand(AsmOperandKind::InOut)?;
4993 outputs.push(operand);
4994 }
4995 Some(Token::Ident(ref name)) if name == "clobber" => {
4996 self.advance();
4997 self.expect(Token::LParen)?;
4998 while !self.check(&Token::RParen) {
4999 if let Some(Token::StringLit(reg)) = self.current_token().cloned() {
5000 self.advance();
5001 clobbers.push(reg);
5002 } else if let Some(Token::Ident(reg)) = self.current_token().cloned() {
5003 self.advance();
5004 clobbers.push(reg);
5005 }
5006 if !self.consume_if(&Token::Comma) {
5007 break;
5008 }
5009 }
5010 self.expect(Token::RParen)?;
5011 }
5012 Some(Token::Ident(ref name)) if name == "options" => {
5013 self.advance();
5014 self.expect(Token::LParen)?;
5015 while !self.check(&Token::RParen) {
5016 if let Some(Token::Ident(opt)) = self.current_token().cloned() {
5017 self.advance();
5018 match opt.as_str() {
5019 "volatile" => options.volatile = true,
5020 "nostack" => options.nostack = true,
5021 "pure" => options.pure_asm = true,
5022 "readonly" => options.readonly = true,
5023 "nomem" => options.nomem = true,
5024 "att_syntax" => options.att_syntax = true,
5025 _ => {}
5026 }
5027 }
5028 if !self.consume_if(&Token::Comma) {
5029 break;
5030 }
5031 }
5032 self.expect(Token::RParen)?;
5033 }
5034 _ => break,
5035 }
5036 }
5037
5038 self.expect(Token::RParen)?;
5039
5040 Ok(Expr::InlineAsm(InlineAsm {
5041 template,
5042 outputs,
5043 inputs,
5044 clobbers,
5045 options,
5046 }))
5047 }
5048
5049 fn parse_asm_operand(&mut self, kind: AsmOperandKind) -> ParseResult<AsmOperand> {
5051 self.expect(Token::LParen)?;
5052
5053 let constraint = match self.current_token().cloned() {
5054 Some(Token::StringLit(s)) => {
5055 self.advance();
5056 s
5057 }
5058 Some(Token::Ident(s)) => {
5059 self.advance();
5060 s
5061 }
5062 Some(t) => {
5063 return Err(ParseError::UnexpectedToken {
5064 expected: "register constraint".to_string(),
5065 found: t,
5066 span: self.current_span(),
5067 });
5068 }
5069 None => return Err(ParseError::UnexpectedEof),
5070 };
5071
5072 self.expect(Token::RParen)?;
5073
5074 let expr = self.parse_expr()?;
5075
5076 let output = if kind == AsmOperandKind::InOut && self.consume_if(&Token::FatArrow) {
5078 Some(Box::new(self.parse_expr()?))
5079 } else {
5080 None
5081 };
5082
5083 Ok(AsmOperand {
5084 constraint,
5085 expr,
5086 kind,
5087 output,
5088 })
5089 }
5090
5091 fn parse_volatile_expr(&mut self) -> ParseResult<Expr> {
5096 self.expect(Token::Volatile)?;
5097
5098 match self.current_token().cloned() {
5099 Some(Token::Ident(ref name)) if name == "read" => {
5100 self.advance();
5101
5102 let ty = if self.consume_if(&Token::Lt) {
5104 let t = self.parse_type()?;
5105 self.expect_gt()?;
5106 Some(t)
5107 } else {
5108 None
5109 };
5110
5111 self.expect(Token::LParen)?;
5112 let ptr = self.parse_expr()?;
5113 self.expect(Token::RParen)?;
5114
5115 Ok(Expr::VolatileRead {
5116 ptr: Box::new(ptr),
5117 ty,
5118 })
5119 }
5120 Some(Token::Ident(ref name)) if name == "write" => {
5121 self.advance();
5122
5123 let ty = if self.consume_if(&Token::Lt) {
5125 let t = self.parse_type()?;
5126 self.expect_gt()?;
5127 Some(t)
5128 } else {
5129 None
5130 };
5131
5132 self.expect(Token::LParen)?;
5133 let ptr = self.parse_expr()?;
5134 self.expect(Token::Comma)?;
5135 let value = self.parse_expr()?;
5136 self.expect(Token::RParen)?;
5137
5138 Ok(Expr::VolatileWrite {
5139 ptr: Box::new(ptr),
5140 value: Box::new(value),
5141 ty,
5142 })
5143 }
5144 Some(t) => Err(ParseError::UnexpectedToken {
5145 expected: "'read' or 'write' after 'volatile'".to_string(),
5146 found: t,
5147 span: self.current_span(),
5148 }),
5149 None => Err(ParseError::UnexpectedEof),
5150 }
5151 }
5152
5153 fn parse_simd_expr(&mut self) -> ParseResult<Expr> {
5165 self.expect(Token::Simd)?;
5166
5167 match self.current_token().cloned() {
5168 Some(Token::LBracket) => {
5169 self.advance();
5171 let elements = self.parse_expr_list()?;
5172 self.expect(Token::RBracket)?;
5173
5174 let ty = if self.consume_if(&Token::Colon) {
5176 Some(self.parse_type()?)
5177 } else {
5178 None
5179 };
5180
5181 Ok(Expr::SimdLiteral { elements, ty })
5182 }
5183 Some(Token::Dot) => {
5184 self.advance();
5185 match self.current_token().cloned() {
5186 Some(Token::Ident(ref op)) => {
5187 let op_name = op.clone();
5188 self.advance();
5189 self.expect(Token::LParen)?;
5190
5191 match op_name.as_str() {
5192 "splat" => {
5193 let value = self.parse_expr()?;
5194 self.expect(Token::Comma)?;
5195 let lanes = match self.current_token() {
5196 Some(Token::IntLit(s)) => {
5197 let n = s.parse::<u8>().map_err(|_| {
5198 ParseError::Custom("invalid lane count".to_string())
5199 })?;
5200 self.advance();
5201 n
5202 }
5203 _ => {
5204 return Err(ParseError::Custom(
5205 "expected lane count".to_string(),
5206 ))
5207 }
5208 };
5209 self.expect(Token::RParen)?;
5210 Ok(Expr::SimdSplat {
5211 value: Box::new(value),
5212 lanes,
5213 })
5214 }
5215 "shuffle" => {
5216 let a = self.parse_expr()?;
5217 self.expect(Token::Comma)?;
5218 let b = self.parse_expr()?;
5219 self.expect(Token::Comma)?;
5220 self.expect(Token::LBracket)?;
5221 let mut indices = Vec::new();
5222 loop {
5223 match self.current_token() {
5224 Some(Token::IntLit(s)) => {
5225 let n = s.parse::<u8>().map_err(|_| {
5226 ParseError::Custom("invalid index".to_string())
5227 })?;
5228 indices.push(n);
5229 self.advance();
5230 }
5231 _ => {
5232 return Err(ParseError::Custom(
5233 "expected index".to_string(),
5234 ))
5235 }
5236 }
5237 if !self.consume_if(&Token::Comma) {
5238 break;
5239 }
5240 }
5241 self.expect(Token::RBracket)?;
5242 self.expect(Token::RParen)?;
5243 Ok(Expr::SimdShuffle {
5244 a: Box::new(a),
5245 b: Box::new(b),
5246 indices,
5247 })
5248 }
5249 "extract" => {
5250 let vector = self.parse_expr()?;
5251 self.expect(Token::Comma)?;
5252 let index = match self.current_token() {
5253 Some(Token::IntLit(s)) => {
5254 let n = s.parse::<u8>().map_err(|_| {
5255 ParseError::Custom("invalid index".to_string())
5256 })?;
5257 self.advance();
5258 n
5259 }
5260 _ => {
5261 return Err(ParseError::Custom(
5262 "expected index".to_string(),
5263 ))
5264 }
5265 };
5266 self.expect(Token::RParen)?;
5267 Ok(Expr::SimdExtract {
5268 vector: Box::new(vector),
5269 index,
5270 })
5271 }
5272 "insert" => {
5273 let vector = self.parse_expr()?;
5274 self.expect(Token::Comma)?;
5275 let index = match self.current_token() {
5276 Some(Token::IntLit(s)) => {
5277 let n = s.parse::<u8>().map_err(|_| {
5278 ParseError::Custom("invalid index".to_string())
5279 })?;
5280 self.advance();
5281 n
5282 }
5283 _ => {
5284 return Err(ParseError::Custom(
5285 "expected index".to_string(),
5286 ))
5287 }
5288 };
5289 self.expect(Token::Comma)?;
5290 let value = self.parse_expr()?;
5291 self.expect(Token::RParen)?;
5292 Ok(Expr::SimdInsert {
5293 vector: Box::new(vector),
5294 index,
5295 value: Box::new(value),
5296 })
5297 }
5298 _ => {
5299 let op = Self::parse_simd_op(&op_name)?;
5301 let args = self.parse_expr_list()?;
5302 self.expect(Token::RParen)?;
5303 Ok(Expr::SimdIntrinsic { op, args })
5304 }
5305 }
5306 }
5307 Some(t) => Err(ParseError::UnexpectedToken {
5308 expected: "SIMD operation name".to_string(),
5309 found: t,
5310 span: self.current_span(),
5311 }),
5312 None => Err(ParseError::UnexpectedEof),
5313 }
5314 }
5315 Some(t) => Err(ParseError::UnexpectedToken {
5316 expected: "'[' or '.' after 'simd'".to_string(),
5317 found: t,
5318 span: self.current_span(),
5319 }),
5320 None => Err(ParseError::UnexpectedEof),
5321 }
5322 }
5323
5324 fn parse_simd_op(name: &str) -> ParseResult<SimdOp> {
5325 match name {
5326 "add" => Ok(SimdOp::Add),
5327 "sub" => Ok(SimdOp::Sub),
5328 "mul" => Ok(SimdOp::Mul),
5329 "div" => Ok(SimdOp::Div),
5330 "neg" => Ok(SimdOp::Neg),
5331 "abs" => Ok(SimdOp::Abs),
5332 "min" => Ok(SimdOp::Min),
5333 "max" => Ok(SimdOp::Max),
5334 "eq" => Ok(SimdOp::Eq),
5335 "ne" => Ok(SimdOp::Ne),
5336 "lt" => Ok(SimdOp::Lt),
5337 "le" => Ok(SimdOp::Le),
5338 "gt" => Ok(SimdOp::Gt),
5339 "ge" => Ok(SimdOp::Ge),
5340 "hadd" => Ok(SimdOp::HAdd),
5341 "dot" => Ok(SimdOp::Dot),
5342 "blend" => Ok(SimdOp::Blend),
5343 "load" => Ok(SimdOp::Load),
5344 "store" => Ok(SimdOp::Store),
5345 "load_aligned" => Ok(SimdOp::LoadAligned),
5346 "store_aligned" => Ok(SimdOp::StoreAligned),
5347 "cast" => Ok(SimdOp::Cast),
5348 "widen" => Ok(SimdOp::Widen),
5349 "narrow" => Ok(SimdOp::Narrow),
5350 "sqrt" => Ok(SimdOp::Sqrt),
5351 "rsqrt" => Ok(SimdOp::Rsqrt),
5352 "rcp" => Ok(SimdOp::Rcp),
5353 "floor" => Ok(SimdOp::Floor),
5354 "ceil" => Ok(SimdOp::Ceil),
5355 "round" => Ok(SimdOp::Round),
5356 "and" => Ok(SimdOp::And),
5357 "or" => Ok(SimdOp::Or),
5358 "xor" => Ok(SimdOp::Xor),
5359 "not" => Ok(SimdOp::Not),
5360 "shl" => Ok(SimdOp::Shl),
5361 "shr" => Ok(SimdOp::Shr),
5362 _ => Err(ParseError::Custom(format!(
5363 "unknown SIMD operation: {}",
5364 name
5365 ))),
5366 }
5367 }
5368
5369 fn parse_atomic_expr(&mut self) -> ParseResult<Expr> {
5381 self.expect(Token::Atomic)?;
5382 self.expect(Token::Dot)?;
5383
5384 match self.current_token().cloned() {
5385 Some(Token::Ident(ref op)) => {
5386 let op_name = op.clone();
5387 self.advance();
5388
5389 if op_name == "fence" {
5390 self.expect(Token::LParen)?;
5391 let ordering = self.parse_memory_ordering()?;
5392 self.expect(Token::RParen)?;
5393 return Ok(Expr::AtomicFence { ordering });
5394 }
5395
5396 self.expect(Token::LParen)?;
5397 let ptr = self.parse_expr()?;
5398
5399 let op = Self::parse_atomic_op(&op_name)?;
5400
5401 let value = match op {
5403 AtomicOp::Load => None,
5404 _ => {
5405 self.expect(Token::Comma)?;
5406 Some(Box::new(self.parse_expr()?))
5407 }
5408 };
5409
5410 let expected = match op {
5412 AtomicOp::CompareExchange | AtomicOp::CompareExchangeWeak => {
5413 self.expect(Token::Comma)?;
5414 Some(Box::new(self.parse_expr()?))
5415 }
5416 _ => None,
5417 };
5418
5419 self.expect(Token::Comma)?;
5421 let ordering = self.parse_memory_ordering()?;
5422
5423 let failure_ordering = match op {
5425 AtomicOp::CompareExchange | AtomicOp::CompareExchangeWeak => {
5426 if self.consume_if(&Token::Comma) {
5427 Some(self.parse_memory_ordering()?)
5428 } else {
5429 None
5430 }
5431 }
5432 _ => None,
5433 };
5434
5435 self.expect(Token::RParen)?;
5436
5437 Ok(Expr::AtomicOp {
5438 op,
5439 ptr: Box::new(ptr),
5440 value,
5441 expected,
5442 ordering,
5443 failure_ordering,
5444 })
5445 }
5446 Some(t) => Err(ParseError::UnexpectedToken {
5447 expected: "atomic operation name".to_string(),
5448 found: t,
5449 span: self.current_span(),
5450 }),
5451 None => Err(ParseError::UnexpectedEof),
5452 }
5453 }
5454
5455 fn parse_atomic_op(name: &str) -> ParseResult<AtomicOp> {
5456 match name {
5457 "load" => Ok(AtomicOp::Load),
5458 "store" => Ok(AtomicOp::Store),
5459 "swap" => Ok(AtomicOp::Swap),
5460 "compare_exchange" => Ok(AtomicOp::CompareExchange),
5461 "compare_exchange_weak" => Ok(AtomicOp::CompareExchangeWeak),
5462 "fetch_add" => Ok(AtomicOp::FetchAdd),
5463 "fetch_sub" => Ok(AtomicOp::FetchSub),
5464 "fetch_and" => Ok(AtomicOp::FetchAnd),
5465 "fetch_or" => Ok(AtomicOp::FetchOr),
5466 "fetch_xor" => Ok(AtomicOp::FetchXor),
5467 "fetch_min" => Ok(AtomicOp::FetchMin),
5468 "fetch_max" => Ok(AtomicOp::FetchMax),
5469 _ => Err(ParseError::Custom(format!(
5470 "unknown atomic operation: {}",
5471 name
5472 ))),
5473 }
5474 }
5475
5476 fn parse_memory_ordering(&mut self) -> ParseResult<MemoryOrdering> {
5477 match self.current_token() {
5478 Some(Token::Ident(name)) => {
5479 let ordering =
5480 match name.as_str() {
5481 "Relaxed" => MemoryOrdering::Relaxed,
5482 "Acquire" => MemoryOrdering::Acquire,
5483 "Release" => MemoryOrdering::Release,
5484 "AcqRel" => MemoryOrdering::AcqRel,
5485 "SeqCst" => MemoryOrdering::SeqCst,
5486 _ => return Err(ParseError::Custom(
5487 "expected memory ordering (Relaxed, Acquire, Release, AcqRel, SeqCst)"
5488 .to_string(),
5489 )),
5490 };
5491 self.advance();
5492 Ok(ordering)
5493 }
5494 _ => Err(ParseError::Custom("expected memory ordering".to_string())),
5495 }
5496 }
5497
5498 fn is_pipe_target_ahead(&mut self) -> bool {
5501 if let Some(next) = self.peek_next().cloned() {
5503 match &next {
5504 Token::Ident(_) => true,
5506 Token::SelfLower => true,
5507 Token::SelfUpper => true,
5508 Token::Tau
5510 | Token::Phi
5511 | Token::Sigma
5512 | Token::Rho
5513 | Token::Lambda
5514 | Token::Delta
5515 | Token::Mu
5516 | Token::Chi
5517 | Token::GradeUp
5518 | Token::GradeDown
5519 | Token::Rotate
5520 | Token::Iota
5521 | Token::ForAll
5522 | Token::Exists
5523 | Token::Pi
5524 | Token::Hourglass => true,
5525 Token::Pipe => true,
5527 Token::OrOr => true, Token::Move => true,
5530 Token::LBrace => true,
5532 Token::IntLit(_)
5534 | Token::FloatLit(_)
5535 | Token::HexLit(_)
5536 | Token::BinaryLit(_)
5537 | Token::OctalLit(_) => false,
5538 Token::LParen => false, Token::True | Token::False => false,
5540 Token::If => false, Token::Match => false, _ => true,
5544 }
5545 } else {
5546 false }
5548 }
5549
5550 fn parse_postfix_after_pipe(&mut self, mut expr: Expr) -> ParseResult<Expr> {
5552 loop {
5553 match self.current_token() {
5554 Some(Token::Question) => {
5555 self.advance();
5556 expr = Expr::Try(Box::new(expr));
5557 }
5558 Some(Token::Dot) => {
5559 self.advance();
5560 let field = if let Some(Token::IntLit(idx)) = self.current_token() {
5561 let idx = idx.clone();
5562 let span = self.current_span();
5563 self.advance();
5564 Ident {
5565 name: idx,
5566 evidentiality: None,
5567 affect: None,
5568 span,
5569 }
5570 } else {
5571 self.parse_ident()?
5572 };
5573 if self.check(&Token::ColonColon) {
5574 self.advance();
5575 self.expect(Token::Lt)?;
5576 let type_args = self.parse_type_list()?;
5577 self.expect_gt()?;
5578 self.expect(Token::LParen)?;
5579 let args = self.parse_expr_list()?;
5580 self.expect(Token::RParen)?;
5581 expr = Expr::MethodCall {
5582 receiver: Box::new(expr),
5583 method: field,
5584 type_args: Some(type_args),
5585 args,
5586 };
5587 } else if self.check(&Token::LParen) {
5588 self.advance();
5589 let args = self.parse_expr_list()?;
5590 self.expect(Token::RParen)?;
5591 expr = Expr::MethodCall {
5592 receiver: Box::new(expr),
5593 method: field,
5594 type_args: None,
5595 args,
5596 };
5597 } else {
5598 expr = Expr::Field {
5599 expr: Box::new(expr),
5600 field,
5601 };
5602 }
5603 }
5604 _ => break,
5605 }
5606 }
5607 Ok(expr)
5608 }
5609
5610 fn parse_pipe_chain(&mut self, initial: Expr) -> ParseResult<Expr> {
5612 let mut operations = Vec::new();
5613
5614 while self.consume_if(&Token::Pipe) {
5615 let op = self.parse_pipe_op()?;
5616 operations.push(op);
5617 }
5618
5619 Ok(Expr::Pipe {
5620 expr: Box::new(initial),
5621 operations,
5622 })
5623 }
5624
5625 fn parse_pipe_op(&mut self) -> ParseResult<PipeOp> {
5626 match self.current_token() {
5627 Some(Token::Tau) => {
5628 self.advance();
5629 self.expect(Token::LBrace)?;
5630 self.skip_comments();
5631 let body = if self.looks_like_morpheme_closure() {
5633 self.parse_morpheme_closure()?
5634 } else {
5635 self.parse_expr()?
5636 };
5637 self.expect(Token::RBrace)?;
5638 Ok(PipeOp::Transform(Box::new(body)))
5639 }
5640 Some(Token::Phi) => {
5641 self.advance();
5642 self.expect(Token::LBrace)?;
5643 self.skip_comments();
5644 let body = if self.looks_like_morpheme_closure() {
5646 self.parse_morpheme_closure()?
5647 } else {
5648 self.parse_expr()?
5649 };
5650 self.expect(Token::RBrace)?;
5651 Ok(PipeOp::Filter(Box::new(body)))
5652 }
5653 Some(Token::Sigma) => {
5654 if self.peek_next() == Some(&Token::LParen) {
5656 let name = Ident {
5658 name: "Σ".to_string(),
5659 evidentiality: None,
5660 affect: None,
5661 span: self.current_span(),
5662 };
5663 self.advance(); self.advance(); let args = self.parse_expr_list()?;
5666 self.expect(Token::RParen)?;
5667 Ok(PipeOp::Call(Box::new(Expr::Call {
5668 func: Box::new(Expr::Path(TypePath {
5669 segments: vec![PathSegment {
5670 ident: name,
5671 generics: None,
5672 }],
5673 })),
5674 args,
5675 })))
5676 } else {
5677 self.advance();
5678 let field = if self.consume_if(&Token::Dot) {
5679 Some(self.parse_ident()?)
5680 } else {
5681 None
5682 };
5683 Ok(PipeOp::Sort(field))
5684 }
5685 }
5686 Some(Token::Rho) => {
5687 self.advance();
5688 match self.current_token() {
5690 Some(Token::Plus) => {
5691 self.advance();
5692 Ok(PipeOp::ReduceSum)
5693 }
5694 Some(Token::Star) => {
5695 self.advance();
5696 Ok(PipeOp::ReduceProd)
5697 }
5698 Some(Token::PlusPlus) => {
5699 self.advance();
5700 Ok(PipeOp::ReduceConcat)
5701 }
5702 Some(Token::Amp) => {
5703 self.advance();
5704 Ok(PipeOp::ReduceAll)
5705 }
5706 Some(Token::Pipe) => {
5707 self.advance();
5708 Ok(PipeOp::ReduceAny)
5709 }
5710 Some(Token::Underscore) => {
5711 self.advance();
5712 if let Some(Token::Ident(name)) = self.current_token().cloned() {
5714 self.advance();
5715 match name.as_str() {
5716 "sum" => Ok(PipeOp::ReduceSum),
5717 "prod" | "product" => Ok(PipeOp::ReduceProd),
5718 "min" => Ok(PipeOp::ReduceMin),
5719 "max" => Ok(PipeOp::ReduceMax),
5720 "cat" | "concat" => Ok(PipeOp::ReduceConcat),
5721 "all" => Ok(PipeOp::ReduceAll),
5722 "any" => Ok(PipeOp::ReduceAny),
5723 _ => Err(ParseError::Custom(format!(
5724 "unknown reduction variant: ρ_{}",
5725 name
5726 ))),
5727 }
5728 } else {
5729 Err(ParseError::Custom(
5730 "expected reduction variant name after ρ_".to_string(),
5731 ))
5732 }
5733 }
5734 Some(Token::LBrace) => {
5735 self.advance();
5737 self.skip_comments();
5738 let body = if self.looks_like_morpheme_closure() {
5740 self.parse_morpheme_closure()?
5741 } else {
5742 self.parse_expr()?
5743 };
5744 self.expect(Token::RBrace)?;
5745 Ok(PipeOp::Reduce(Box::new(body)))
5746 }
5747 _ => Err(ParseError::Custom(
5748 "expected reduction variant (+, *, ++, &, |, _name) or {body} after ρ"
5749 .to_string(),
5750 )),
5751 }
5752 }
5753 Some(Token::Pi) => {
5755 self.advance();
5756 Ok(PipeOp::ReduceProd)
5757 }
5758 Some(Token::Alpha) => {
5760 self.advance();
5761 Ok(PipeOp::First)
5762 }
5763 Some(Token::Omega) => {
5764 self.advance();
5765 Ok(PipeOp::Last)
5766 }
5767 Some(Token::Mu) => {
5768 if self.peek_next() == Some(&Token::LParen) {
5771 let name = Ident {
5773 name: "μ".to_string(),
5774 evidentiality: None,
5775 affect: None,
5776 span: self.current_span(),
5777 };
5778 self.advance(); self.advance(); let args = self.parse_expr_list()?;
5781 self.expect(Token::RParen)?;
5782 Ok(PipeOp::Call(Box::new(Expr::Call {
5784 func: Box::new(Expr::Path(TypePath {
5785 segments: vec![PathSegment {
5786 ident: name,
5787 generics: None,
5788 }],
5789 })),
5790 args,
5791 })))
5792 } else {
5793 self.advance();
5794 Ok(PipeOp::Middle)
5795 }
5796 }
5797 Some(Token::Chi) => {
5798 self.advance();
5799 Ok(PipeOp::Choice)
5800 }
5801 Some(Token::Nu) => {
5802 self.advance();
5803 if self.check(&Token::LBrace) {
5805 self.advance();
5806 let index = self.parse_expr()?;
5807 self.expect(Token::RBrace)?;
5808 Ok(PipeOp::Nth(Box::new(index)))
5809 } else {
5810 Ok(PipeOp::Nth(Box::new(Expr::Literal(Literal::Int {
5812 value: "0".to_string(),
5813 base: NumBase::Decimal,
5814 suffix: None,
5815 }))))
5816 }
5817 }
5818 Some(Token::Xi) => {
5819 self.advance();
5820 Ok(PipeOp::Next)
5821 }
5822 Some(Token::Parallel) => {
5824 self.advance();
5825 let inner_op = self.parse_pipe_op()?;
5827 Ok(PipeOp::Parallel(Box::new(inner_op)))
5828 }
5829 Some(Token::Gpu) => {
5831 self.advance();
5832 let inner_op = self.parse_pipe_op()?;
5834 Ok(PipeOp::Gpu(Box::new(inner_op)))
5835 }
5836 Some(Token::Await) => {
5837 self.advance();
5838 Ok(PipeOp::Await)
5839 }
5840 Some(Token::Hourglass) => {
5841 self.advance();
5842 Ok(PipeOp::Await)
5843 }
5844 Some(Token::MiddleDot) => {
5845 self.advance();
5846 let mut prefix = Vec::new();
5847 prefix.push(self.parse_ident()?);
5848
5849 while self.consume_if(&Token::MiddleDot) {
5850 if self.check(&Token::LBrace) {
5851 break;
5852 }
5853 prefix.push(self.parse_ident()?);
5854 }
5855
5856 let body = if self.check(&Token::LBrace) {
5857 self.advance();
5858 let expr = self.parse_expr()?;
5859 self.expect(Token::RBrace)?;
5860 Some(Box::new(expr))
5861 } else {
5862 None
5863 };
5864
5865 Ok(PipeOp::Named { prefix, body })
5866 }
5867 Some(Token::Match) => {
5869 self.advance();
5870 self.expect(Token::LBrace)?;
5871 let mut arms = Vec::new();
5872 while !self.check(&Token::RBrace) && !self.is_eof() {
5873 let pattern = self.parse_or_pattern()?;
5875 let guard = if self.consume_if(&Token::If) {
5876 Some(self.parse_condition()?)
5877 } else {
5878 None
5879 };
5880 self.expect(Token::FatArrow)?;
5881 let body = self.parse_expr()?;
5882 arms.push(MatchArm {
5883 pattern,
5884 guard,
5885 body,
5886 });
5887 self.consume_if(&Token::Comma);
5889 }
5890 self.expect(Token::RBrace)?;
5891 Ok(PipeOp::Match(arms))
5892 }
5893 Some(Token::Interrobang) => {
5896 self.advance();
5897 let mapper = if self.check(&Token::LBrace) {
5898 self.advance();
5899 let expr = self.parse_expr()?;
5900 self.expect(Token::RBrace)?;
5901 Some(Box::new(expr))
5902 } else {
5903 None
5904 };
5905 Ok(PipeOp::TryMap(mapper))
5906 }
5907 Some(Token::SelfLower) | Some(Token::SelfUpper) => {
5909 let expr = self.parse_postfix_expr()?;
5911 Ok(PipeOp::Call(Box::new(expr)))
5912 }
5913 Some(Token::Nabla) => {
5915 self.advance();
5916 Ok(PipeOp::Method {
5918 name: Ident {
5919 name: "∇".to_string(),
5920 evidentiality: None,
5921 affect: None,
5922 span: self.current_span(),
5923 },
5924 type_args: None,
5925 args: vec![],
5926 })
5927 }
5928 Some(Token::Ident(_)) => {
5929 let name = self.parse_ident()?;
5930
5931 if name.name == "validate" || name.name == "assume" {
5937 let (has_marker, target_evidence) = if self.check(&Token::Bang) {
5939 let peek = self.peek_next();
5940 if matches!(peek, Some(Token::LBrace) | Some(Token::LParen)) {
5941 self.advance(); (true, Evidentiality::Known)
5943 } else {
5944 (false, Evidentiality::Known)
5945 }
5946 } else if self.check(&Token::Question) {
5947 let peek = self.peek_next();
5948 if matches!(peek, Some(Token::LBrace) | Some(Token::LParen)) {
5949 self.advance(); (true, Evidentiality::Uncertain)
5951 } else {
5952 (false, Evidentiality::Known)
5953 }
5954 } else if self.check(&Token::Tilde) {
5955 let peek = self.peek_next();
5956 if matches!(peek, Some(Token::LBrace) | Some(Token::LParen)) {
5957 self.advance(); (true, Evidentiality::Reported)
5959 } else {
5960 (false, Evidentiality::Known)
5961 }
5962 } else {
5963 (false, name.evidentiality.unwrap_or(Evidentiality::Known))
5964 };
5965
5966 if has_marker || self.check(&Token::LParen) || self.check(&Token::LBrace) {
5968 let args = if self.check(&Token::LParen) {
5969 self.advance();
5970 let args = self.parse_expr_list()?;
5971 self.expect(Token::RParen)?;
5972 args
5973 } else if self.check(&Token::LBrace) {
5974 self.advance();
5975 self.skip_comments();
5976 let body = if self.looks_like_morpheme_closure() {
5977 self.parse_morpheme_closure()?
5978 } else {
5979 self.parse_expr()?
5980 };
5981 self.expect(Token::RBrace)?;
5982 vec![body]
5983 } else {
5984 vec![]
5985 };
5986
5987 if name.name == "validate" {
5988 if args.is_empty() {
5989 return Err(ParseError::Custom(
5990 "validate requires a predicate".to_string(),
5991 ));
5992 }
5993 return Ok(PipeOp::Validate {
5994 predicate: Box::new(args.into_iter().next().unwrap()),
5995 target_evidence,
5996 });
5997 } else {
5998 let reason = args.into_iter().next().map(Box::new);
6000 return Ok(PipeOp::Assume {
6001 reason,
6002 target_evidence,
6003 });
6004 }
6005 }
6006 }
6007
6008 if self.check(&Token::Bang) {
6010 let peek = self.peek_next();
6011 if matches!(
6012 peek,
6013 Some(Token::LBrace) | Some(Token::LParen) | Some(Token::LBracket)
6014 ) {
6015 self.advance(); let tokens = self.parse_macro_tokens()?;
6017 let path = TypePath {
6018 segments: vec![PathSegment {
6019 ident: name,
6020 generics: None,
6021 }],
6022 };
6023 return Ok(PipeOp::Call(Box::new(Expr::Macro { path, tokens })));
6024 }
6025 }
6026
6027 let mut path_segments = vec![PathSegment {
6031 ident: name.clone(),
6032 generics: None,
6033 }];
6034 let type_args = loop {
6035 if self.check(&Token::ColonColon) {
6036 self.advance(); if self.check(&Token::Lt) {
6038 self.advance(); let types = self.parse_type_list()?;
6041 self.expect_gt()?;
6042 break Some(types);
6043 } else if let Some(Token::Ident(_)) = self.current_token() {
6044 let segment = self.parse_ident()?;
6046 path_segments.push(PathSegment {
6047 ident: segment,
6048 generics: None,
6049 });
6050 } else {
6052 return Err(ParseError::Custom(
6053 "expected identifier or '<' after '::'".to_string(),
6054 ));
6055 }
6056 } else {
6057 break None;
6058 }
6059 };
6060
6061 let name = if path_segments.len() > 1 {
6063 let path = TypePath {
6065 segments: path_segments,
6066 };
6067 let args = if self.check(&Token::LParen) {
6068 self.advance();
6069 let args = self.parse_expr_list()?;
6070 self.expect(Token::RParen)?;
6071 args
6072 } else {
6073 vec![]
6074 };
6075 return Ok(PipeOp::Call(Box::new(Expr::Call {
6076 func: Box::new(Expr::Path(path)),
6077 args,
6078 })));
6079 } else {
6080 name
6081 };
6082 let args = if self.check(&Token::LParen) {
6083 self.advance();
6084 let args = self.parse_expr_list()?;
6085 self.expect(Token::RParen)?;
6086 args
6087 } else if self.check(&Token::LBrace) && !self.in_condition {
6088 self.advance();
6091 self.skip_comments();
6092 let body = if self.looks_like_morpheme_closure() {
6093 self.parse_morpheme_closure()?
6094 } else {
6095 self.parse_expr()?
6096 };
6097 self.expect(Token::RBrace)?;
6098 vec![body]
6099 } else {
6100 vec![]
6101 };
6102
6103 if name.name == "validate" {
6105 let target_evidence = name.evidentiality.unwrap_or(Evidentiality::Known);
6106 if args.is_empty() {
6107 return Err(ParseError::Custom(
6108 "validate requires a predicate: |validate!{predicate}".to_string(),
6109 ));
6110 }
6111 return Ok(PipeOp::Validate {
6112 predicate: Box::new(args.into_iter().next().unwrap()),
6113 target_evidence,
6114 });
6115 }
6116 if name.name == "assume" {
6117 let target_evidence = name.evidentiality.unwrap_or(Evidentiality::Known);
6118 let reason = args.into_iter().next().map(Box::new);
6119 return Ok(PipeOp::Assume {
6120 reason,
6121 target_evidence,
6122 });
6123 }
6124
6125 Ok(PipeOp::Method {
6126 name,
6127 type_args,
6128 args,
6129 })
6130 }
6131
6132 Some(Token::Send) | Some(Token::ProtoSend) => {
6138 self.advance();
6139 self.expect(Token::LBrace)?;
6140 let data = self.parse_expr()?;
6141 self.expect(Token::RBrace)?;
6142 Ok(PipeOp::Send(Box::new(data)))
6143 }
6144
6145 Some(Token::Recv) | Some(Token::ProtoRecv) => {
6147 self.advance();
6148 Ok(PipeOp::Recv)
6149 }
6150
6151 Some(Token::Stream) | Some(Token::ProtoStream) => {
6153 self.advance();
6154 self.expect(Token::LBrace)?;
6155 let handler = self.parse_expr()?;
6156 self.expect(Token::RBrace)?;
6157 Ok(PipeOp::Stream(Box::new(handler)))
6158 }
6159
6160 Some(Token::Connect) | Some(Token::ProtoConnect) => {
6162 self.advance();
6163 let config = if self.check(&Token::LBrace) {
6164 self.advance();
6165 let expr = self.parse_expr()?;
6166 self.expect(Token::RBrace)?;
6167 Some(Box::new(expr))
6168 } else {
6169 None
6170 };
6171 Ok(PipeOp::Connect(config))
6172 }
6173
6174 Some(Token::Close) | Some(Token::Tensor) => {
6176 self.advance();
6177 Ok(PipeOp::Close)
6178 }
6179
6180 Some(Token::Timeout) | Some(Token::ProtoTimeout) => {
6182 self.advance();
6183 self.expect(Token::LBrace)?;
6184 let ms = self.parse_expr()?;
6185 self.expect(Token::RBrace)?;
6186 Ok(PipeOp::Timeout(Box::new(ms)))
6187 }
6188
6189 Some(Token::Retry) => {
6191 self.advance();
6192 self.expect(Token::LBrace)?;
6193 let count = self.parse_expr()?;
6194 let strategy = if self.consume_if(&Token::Comma) {
6195 Some(Box::new(self.parse_expr()?))
6196 } else {
6197 None
6198 };
6199 self.expect(Token::RBrace)?;
6200 Ok(PipeOp::Retry {
6201 count: Box::new(count),
6202 strategy,
6203 })
6204 }
6205
6206 Some(Token::Header) => {
6208 self.advance();
6209 self.expect(Token::LBrace)?;
6210 let name = self.parse_expr()?;
6211 self.expect(Token::Comma)?;
6212 let value = self.parse_expr()?;
6213 self.expect(Token::RBrace)?;
6214 Ok(PipeOp::Header {
6215 name: Box::new(name),
6216 value: Box::new(value),
6217 })
6218 }
6219
6220 Some(Token::Body) => {
6222 self.advance();
6223 self.expect(Token::LBrace)?;
6224 let data = self.parse_expr()?;
6225 self.expect(Token::RBrace)?;
6226 Ok(PipeOp::Body(Box::new(data)))
6227 }
6228
6229 Some(Token::ForAll) => {
6235 self.advance();
6236 self.expect(Token::LBrace)?;
6237 let pred = self.parse_expr()?;
6238 self.expect(Token::RBrace)?;
6239 Ok(PipeOp::All(Box::new(pred)))
6240 }
6241
6242 Some(Token::Exists) => {
6244 self.advance();
6245 self.expect(Token::LBrace)?;
6246 let pred = self.parse_expr()?;
6247 self.expect(Token::RBrace)?;
6248 Ok(PipeOp::Any(Box::new(pred)))
6249 }
6250
6251 Some(Token::Compose) => {
6253 self.advance();
6254 self.expect(Token::LBrace)?;
6255 let f = self.parse_expr()?;
6256 self.expect(Token::RBrace)?;
6257 Ok(PipeOp::Compose(Box::new(f)))
6258 }
6259
6260 Some(Token::Bowtie) => {
6262 self.advance();
6263 self.expect(Token::LBrace)?;
6264 let other = self.parse_expr()?;
6265 self.expect(Token::RBrace)?;
6266 Ok(PipeOp::Zip(Box::new(other)))
6267 }
6268
6269 Some(Token::Integral) => {
6271 self.advance();
6272 self.expect(Token::LBrace)?;
6273 let f = self.parse_expr()?;
6274 self.expect(Token::RBrace)?;
6275 Ok(PipeOp::Scan(Box::new(f)))
6276 }
6277
6278 Some(Token::Partial) => {
6280 self.advance();
6281 Ok(PipeOp::Diff)
6282 }
6283
6284 Some(Token::Nabla) => {
6286 self.advance();
6287 self.expect(Token::LBrace)?;
6288 let var = self.parse_expr()?;
6289 self.expect(Token::RBrace)?;
6290 Ok(PipeOp::Gradient(Box::new(var)))
6291 }
6292
6293 Some(Token::GradeUp) => {
6295 self.advance();
6296 Ok(PipeOp::SortAsc)
6297 }
6298
6299 Some(Token::GradeDown) => {
6301 self.advance();
6302 Ok(PipeOp::SortDesc)
6303 }
6304
6305 Some(Token::Rotate) => {
6307 self.advance();
6308 Ok(PipeOp::Reverse)
6309 }
6310
6311 Some(Token::CycleArrow) => {
6313 self.advance();
6314 self.expect(Token::LBrace)?;
6315 let n = self.parse_expr()?;
6316 self.expect(Token::RBrace)?;
6317 Ok(PipeOp::Cycle(Box::new(n)))
6318 }
6319
6320 Some(Token::QuadDiamond) => {
6322 self.advance();
6323 self.expect(Token::LBrace)?;
6324 let n = self.parse_expr()?;
6325 self.expect(Token::RBrace)?;
6326 Ok(PipeOp::Windows(Box::new(n)))
6327 }
6328
6329 Some(Token::SquaredPlus) => {
6331 self.advance();
6332 self.expect(Token::LBrace)?;
6333 let n = self.parse_expr()?;
6334 self.expect(Token::RBrace)?;
6335 Ok(PipeOp::Chunks(Box::new(n)))
6336 }
6337
6338 Some(Token::ElementSmallVerticalBar) => {
6340 self.advance();
6341 Ok(PipeOp::Flatten)
6342 }
6343
6344 Some(Token::Union) => {
6346 self.advance();
6347 Ok(PipeOp::Unique)
6348 }
6349
6350 Some(Token::Iota) => {
6352 self.advance();
6353 Ok(PipeOp::Enumerate)
6354 }
6355
6356 Some(Token::Amp) => {
6358 let expr = self.parse_prefix_expr()?;
6360 Ok(PipeOp::Call(Box::new(expr)))
6361 }
6362
6363 Some(Token::LBrace) => {
6366 self.advance();
6367 self.skip_comments();
6368 let body = if self.looks_like_morpheme_closure() {
6369 self.parse_morpheme_closure()?
6370 } else {
6371 self.parse_expr()?
6372 };
6373 self.expect(Token::RBrace)?;
6374 Ok(PipeOp::Call(Box::new(body)))
6375 }
6376
6377 Some(token) => Err(ParseError::UnexpectedToken {
6378 expected: "pipe operation".to_string(),
6379 found: token.clone(),
6380 span: self.current_span(),
6381 }),
6382 None => Err(ParseError::UnexpectedEof),
6383 }
6384 }
6385
6386 fn looks_like_morpheme_closure(&mut self) -> bool {
6388 if matches!(
6390 self.current_token(),
6391 Some(Token::Ident(_)) | Some(Token::Underscore)
6392 ) {
6393 match self.peek_next() {
6395 Some(Token::FatArrow) => return true,
6396 Some(Token::Tilde) | Some(Token::Lozenge) | Some(Token::Interrobang) => {
6398 if matches!(self.peek_n(1), Some(Token::FatArrow)) {
6400 return true;
6401 }
6402 }
6403 _ => {}
6404 }
6405 }
6406 if matches!(self.current_token(), Some(Token::Amp)) {
6408 if matches!(self.peek_next(), Some(Token::Ident(_))) {
6410 match self.peek_n(1) {
6412 Some(Token::FatArrow) => return true,
6413 Some(Token::Tilde) | Some(Token::Lozenge) | Some(Token::Interrobang) => {
6414 if matches!(self.peek_n(2), Some(Token::FatArrow)) {
6415 return true;
6416 }
6417 }
6418 _ => {}
6419 }
6420 } else if matches!(self.peek_next(), Some(Token::Mut)) {
6421 return true;
6423 }
6424 }
6425 if matches!(self.current_token(), Some(Token::LParen)) {
6428 return true;
6431 }
6432 false
6433 }
6434
6435 fn parse_morpheme_closure(&mut self) -> ParseResult<Expr> {
6438 let pattern = if self.check(&Token::LParen) {
6439 self.advance();
6441 let mut patterns = Vec::new();
6442 while !self.check(&Token::RParen) {
6443 let pat = self.parse_pattern()?;
6444 patterns.push(pat);
6445 if !self.consume_if(&Token::Comma) {
6446 break;
6447 }
6448 }
6449 self.expect(Token::RParen)?;
6450 Pattern::Tuple(patterns)
6452 } else if self.check(&Token::Amp) {
6453 self.parse_pattern()?
6455 } else if self.check(&Token::Underscore) {
6456 self.advance();
6458 Pattern::Wildcard
6459 } else {
6460 let name = self.parse_ident()?;
6462 Pattern::Ident {
6463 mutable: false,
6464 name,
6465 evidentiality: None,
6466 }
6467 };
6468 if !self.consume_if(&Token::FatArrow) {
6470 self.expect(Token::Pipe)?;
6471 }
6472 self.skip_comments();
6474 let body = {
6482 let mut stmts = Vec::new();
6484 loop {
6485 self.skip_comments();
6486 if self.check(&Token::RBrace) {
6487 break;
6488 }
6489 if self.check(&Token::Let) {
6490 stmts.push(self.parse_let_stmt()?);
6491 } else if self.check(&Token::Return)
6492 || self.check(&Token::Break)
6493 || self.check(&Token::Continue)
6494 {
6495 break;
6497 } else {
6498 let expr = self.parse_expr()?;
6500 self.skip_comments();
6502 if self.consume_if(&Token::Semi) {
6503 stmts.push(Stmt::Expr(expr));
6505 } else if self.check(&Token::RBrace) {
6506 if stmts.is_empty() {
6508 return Ok(Expr::Closure {
6510 params: vec![ClosureParam { pattern, ty: None }],
6511 return_type: None,
6512 body: Box::new(expr),
6513 is_move: false,
6514 });
6515 }
6516 return Ok(Expr::Closure {
6517 params: vec![ClosureParam { pattern, ty: None }],
6518 return_type: None,
6519 body: Box::new(Expr::Block(Block {
6520 stmts,
6521 expr: Some(Box::new(expr)),
6522 })),
6523 is_move: false,
6524 });
6525 } else {
6526 stmts.push(Stmt::Expr(expr));
6529 }
6530 }
6531 }
6532 Expr::Block(Block { stmts, expr: None })
6534 };
6535 Ok(Expr::Closure {
6536 params: vec![ClosureParam { pattern, ty: None }],
6537 return_type: None,
6538 body: Box::new(body),
6539 is_move: false,
6540 })
6541 }
6542
6543 fn parse_morpheme_kind(&mut self) -> ParseResult<MorphemeKind> {
6544 match self.current_token() {
6545 Some(Token::Tau) => {
6546 self.advance();
6547 Ok(MorphemeKind::Transform)
6548 }
6549 Some(Token::Phi) => {
6550 self.advance();
6551 Ok(MorphemeKind::Filter)
6552 }
6553 Some(Token::Sigma) => {
6554 self.advance();
6555 Ok(MorphemeKind::Sort)
6556 }
6557 Some(Token::Rho) => {
6558 self.advance();
6559 Ok(MorphemeKind::Reduce)
6560 }
6561 Some(Token::Lambda) => {
6562 self.advance();
6563 Ok(MorphemeKind::Lambda)
6564 }
6565 Some(Token::Pi) => {
6566 self.advance();
6567 Ok(MorphemeKind::Product)
6568 }
6569 _ => Err(ParseError::Custom("expected morpheme".to_string())),
6570 }
6571 }
6572
6573 fn parse_block_or_closure(&mut self) -> ParseResult<Expr> {
6574 self.expect(Token::LBrace)?;
6575 self.skip_comments();
6576
6577 let is_simple_closure = matches!(self.current_token(), Some(Token::Ident(_)))
6580 && matches!(self.peek_next(), Some(Token::FatArrow));
6581
6582 if is_simple_closure {
6583 let name = self.parse_ident()?;
6584 self.expect(Token::FatArrow)?;
6585 self.skip_comments();
6586 let body = self.parse_expr()?;
6587 self.skip_comments();
6588 self.expect(Token::RBrace)?;
6589 return Ok(Expr::Closure {
6590 params: vec![ClosureParam {
6591 pattern: Pattern::Ident {
6592 mutable: false,
6593 name,
6594 evidentiality: None,
6595 },
6596 ty: None,
6597 }],
6598 return_type: None,
6599 body: Box::new(body),
6600 is_move: false,
6601 });
6602 }
6603
6604 let mut stmts = Vec::new();
6606 let mut final_expr = None;
6607
6608 while !self.check(&Token::RBrace) && !self.is_eof() {
6609 self.skip_comments();
6610 if self.check(&Token::RBrace) {
6611 break;
6612 }
6613
6614 if self.check(&Token::Hash) || self.check(&Token::At) {
6616 let mut attrs = Vec::new();
6618 while self.check(&Token::Hash) || self.check(&Token::At) {
6619 attrs.push(self.parse_outer_attribute()?);
6620 self.skip_comments();
6621 }
6622
6623 if self.is_item_start() {
6625 let item = self.parse_item()?;
6627 stmts.push(Stmt::Item(Box::new(item.node)));
6628 } else if self.check(&Token::Let) {
6629 stmts.push(self.parse_let_stmt()?);
6631 } else {
6632 let expr = self.parse_expr()?;
6634 self.skip_comments();
6635 if self.consume_if(&Token::Semi) {
6636 stmts.push(Stmt::Semi(expr));
6637 } else if self.check(&Token::RBrace) {
6638 final_expr = Some(Box::new(expr));
6639 } else {
6640 stmts.push(Stmt::Expr(expr));
6641 }
6642 }
6643 } else if self.is_item_start() {
6644 let item = self.parse_item()?;
6645 stmts.push(Stmt::Item(Box::new(item.node)));
6646 } else if self.check(&Token::Let) {
6647 stmts.push(self.parse_let_stmt()?);
6648 } else {
6649 let expr = self.parse_expr()?;
6650 self.skip_comments();
6651 if self.consume_if(&Token::Semi) {
6652 stmts.push(Stmt::Semi(expr));
6653 } else if self.check(&Token::RBrace) {
6654 final_expr = Some(Box::new(expr));
6655 } else {
6656 stmts.push(Stmt::Expr(expr));
6657 }
6658 }
6659 }
6660
6661 self.expect(Token::RBrace)?;
6662
6663 Ok(Expr::Block(Block {
6664 stmts,
6665 expr: final_expr,
6666 }))
6667 }
6668
6669 pub(crate) fn parse_block(&mut self) -> ParseResult<Block> {
6670 match self.parse_block_or_closure()? {
6671 Expr::Block(block) => Ok(block),
6672 _ => Err(ParseError::Custom("expected block".to_string())),
6673 }
6674 }
6675
6676 fn parse_let_stmt(&mut self) -> ParseResult<Stmt> {
6677 self.expect(Token::Let)?;
6678 let pattern = self.parse_pattern()?;
6679 let ty = if self.consume_if(&Token::Colon) {
6680 Some(self.parse_type()?)
6681 } else {
6682 None
6683 };
6684 let init = if self.consume_if(&Token::Eq) {
6685 Some(self.parse_expr()?)
6686 } else {
6687 None
6688 };
6689
6690 if self.consume_if(&Token::Else) {
6692 let else_branch = Box::new(Expr::Block(self.parse_block()?));
6693 self.consume_if(&Token::Semi);
6695 Ok(Stmt::LetElse {
6696 pattern,
6697 ty,
6698 init: init.ok_or_else(|| {
6699 ParseError::Custom("let-else requires initializer".to_string())
6700 })?,
6701 else_branch,
6702 })
6703 } else {
6704 if !self.consume_if(&Token::Semi) {
6707 if !self.can_start_stmt() && !self.check(&Token::RBrace) {
6708 return Err(ParseError::UnexpectedToken {
6709 expected: "`;` or new statement".to_string(),
6710 found: self.current_token().cloned().unwrap_or(Token::Semi),
6711 span: self.current_span(),
6712 });
6713 }
6714 }
6715 Ok(Stmt::Let { pattern, ty, init })
6716 }
6717 }
6718
6719 fn parse_if_expr(&mut self) -> ParseResult<Expr> {
6720 self.expect(Token::If)?;
6721
6722 let condition = if self.consume_if(&Token::Let) {
6724 let pattern = self.parse_or_pattern()?;
6725 self.expect(Token::Eq)?;
6726 let expr = self.parse_condition()?;
6727 Expr::Let {
6728 pattern,
6729 value: Box::new(expr),
6730 }
6731 } else {
6732 self.parse_condition()?
6733 };
6734
6735 let then_branch = self.parse_block()?;
6736 self.skip_comments(); let else_branch = if self.consume_if(&Token::Else) {
6738 if self.check(&Token::If) {
6739 Some(Box::new(self.parse_if_expr()?))
6740 } else {
6741 Some(Box::new(Expr::Block(self.parse_block()?)))
6742 }
6743 } else {
6744 None
6745 };
6746
6747 Ok(Expr::If {
6748 condition: Box::new(condition),
6749 then_branch,
6750 else_branch,
6751 })
6752 }
6753
6754 fn parse_match_expr(&mut self) -> ParseResult<Expr> {
6755 self.expect(Token::Match)?;
6756 let expr = self.parse_condition()?;
6758 self.expect(Token::LBrace)?;
6759
6760 let mut arms = Vec::new();
6761 while !self.check(&Token::RBrace) && !self.is_eof() {
6762 loop {
6764 if matches!(
6765 self.current_token(),
6766 Some(Token::DocComment(_))
6767 | Some(
6768 Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
6769 )
6770 ) {
6771 self.advance();
6772 } else if self.check(&Token::Hash) {
6773 self.skip_attribute()?;
6775 } else {
6776 break;
6777 }
6778 }
6779 if self.check(&Token::RBrace) {
6780 break;
6781 }
6782 let pattern = self.parse_or_pattern()?;
6783 let guard = if self.consume_if(&Token::If) {
6784 Some(self.parse_condition()?)
6785 } else {
6786 None
6787 };
6788 self.expect(Token::FatArrow)?;
6789 let body = self.parse_expr()?;
6790 arms.push(MatchArm {
6791 pattern,
6792 guard,
6793 body,
6794 });
6795 self.consume_if(&Token::Comma);
6798 while matches!(
6800 self.current_token(),
6801 Some(Token::DocComment(_))
6802 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
6803 ) {
6804 self.advance();
6805 }
6806 }
6807
6808 self.expect(Token::RBrace)?;
6809
6810 Ok(Expr::Match {
6811 expr: Box::new(expr),
6812 arms,
6813 })
6814 }
6815
6816 fn parse_or_pattern(&mut self) -> ParseResult<Pattern> {
6820 let first = self.parse_pattern()?;
6821
6822 if self.check(&Token::Pipe) {
6824 let mut patterns = vec![first];
6825 while self.consume_if(&Token::Pipe) {
6826 patterns.push(self.parse_pattern()?);
6827 }
6828 Ok(Pattern::Or(patterns))
6829 } else {
6830 Ok(first)
6831 }
6832 }
6833
6834 fn parse_pattern(&mut self) -> ParseResult<Pattern> {
6835 let prefix_ev = match self.current_token() {
6837 Some(Token::Question) => {
6838 self.advance();
6839 Some(Evidentiality::Uncertain)
6840 }
6841 Some(Token::Bang) => {
6842 self.advance();
6843 Some(Evidentiality::Known)
6844 }
6845 Some(Token::Tilde) => {
6846 self.advance();
6847 Some(Evidentiality::Reported)
6848 }
6849 Some(Token::Lozenge) => {
6850 self.advance();
6851 Some(Evidentiality::Predicted)
6852 }
6853 Some(Token::Interrobang) => {
6854 self.advance();
6855 Some(Evidentiality::Paradox)
6856 }
6857 _ => None,
6858 };
6859
6860 if let Some(ev) = prefix_ev {
6863 let inner_pattern = self.parse_pattern_base()?;
6865 return match inner_pattern {
6866 Pattern::Ident {
6867 mutable,
6868 name,
6869 evidentiality: _,
6870 } => {
6871 Ok(Pattern::Ident {
6873 mutable,
6874 name,
6875 evidentiality: Some(ev),
6876 })
6877 }
6878 Pattern::Wildcard => {
6879 let span = self.current_span();
6882 Ok(Pattern::Ident {
6883 mutable: false,
6884 name: Ident {
6885 name: "_".to_string(),
6886 evidentiality: None,
6887 affect: None,
6888 span,
6889 },
6890 evidentiality: Some(ev),
6891 })
6892 }
6893 other => {
6894 Ok(other)
6899 }
6900 };
6901 }
6902
6903 self.parse_pattern_base()
6904 }
6905
6906 fn parse_pattern_base(&mut self) -> ParseResult<Pattern> {
6908 match self.current_token().cloned() {
6909 Some(Token::Underscore) => {
6910 self.advance();
6911 Ok(Pattern::Wildcard)
6912 }
6913 Some(Token::DotDot) => {
6914 self.advance();
6915 Ok(Pattern::Rest)
6916 }
6917 Some(Token::Mut) => {
6918 self.advance();
6919 let name = if self.check(&Token::SelfLower) {
6921 let span = self.current_span();
6922 self.advance();
6923 Ident {
6924 name: "self".to_string(),
6925 evidentiality: None,
6926 affect: None,
6927 span,
6928 }
6929 } else {
6930 self.parse_ident()?
6931 };
6932 let evidentiality = self.parse_evidentiality_opt();
6933 Ok(Pattern::Ident {
6934 mutable: true,
6935 name,
6936 evidentiality,
6937 })
6938 }
6939 Some(Token::Ref) => {
6941 self.advance();
6942 let mutable = self.consume_if(&Token::Mut);
6943 let name = self.parse_ident()?;
6944 let evidentiality = self.parse_evidentiality_opt();
6945 Ok(Pattern::RefBinding {
6946 mutable,
6947 name,
6948 evidentiality,
6949 })
6950 }
6951 Some(Token::Amp) => {
6953 self.advance();
6954 if matches!(self.current_token(), Some(Token::Lifetime(_))) {
6956 self.advance();
6957 }
6958 let mutable = self.consume_if(&Token::Mut);
6959 let inner = self.parse_pattern()?;
6960 Ok(Pattern::Ref {
6961 mutable,
6962 pattern: Box::new(inner),
6963 })
6964 }
6965 Some(Token::AndAnd) => {
6967 self.advance();
6968 let inner = self.parse_pattern()?;
6969 let inner_ref = Pattern::Ref {
6971 mutable: false,
6972 pattern: Box::new(inner),
6973 };
6974 Ok(Pattern::Ref {
6975 mutable: false,
6976 pattern: Box::new(inner_ref),
6977 })
6978 }
6979 Some(Token::LParen) => {
6980 self.advance();
6981 let mut patterns = Vec::new();
6982 while !self.check(&Token::RParen) {
6983 patterns.push(self.parse_pattern()?);
6984 if !self.consume_if(&Token::Comma) {
6985 break;
6986 }
6987 }
6988 self.expect(Token::RParen)?;
6989 let _ev = self.parse_evidentiality_opt();
6991 Ok(Pattern::Tuple(patterns))
6994 }
6995 Some(Token::LBracket) => {
6996 self.advance();
6997 let mut patterns = Vec::new();
6998 while !self.check(&Token::RBracket) {
6999 patterns.push(self.parse_pattern()?);
7000 if !self.consume_if(&Token::Comma) {
7001 break;
7002 }
7003 }
7004 self.expect(Token::RBracket)?;
7005 Ok(Pattern::Slice(patterns))
7006 }
7007 Some(Token::IntLit(_))
7008 | Some(Token::HexLit(_))
7009 | Some(Token::OctalLit(_))
7010 | Some(Token::BinaryLit(_))
7011 | Some(Token::FloatLit(_))
7012 | Some(Token::StringLit(_))
7013 | Some(Token::CharLit(_))
7014 | Some(Token::True)
7015 | Some(Token::False)
7016 | Some(Token::Null) => {
7017 let lit = self.parse_literal()?;
7018 if self.check(&Token::DotDot) || self.check(&Token::DotDotEq) {
7020 let inclusive = self.consume_if(&Token::DotDotEq);
7021 if !inclusive {
7022 self.advance(); }
7024 let end = if matches!(
7026 self.current_token(),
7027 Some(Token::IntLit(_))
7028 | Some(Token::HexLit(_))
7029 | Some(Token::OctalLit(_))
7030 | Some(Token::BinaryLit(_))
7031 | Some(Token::CharLit(_))
7032 ) {
7033 let end_lit = self.parse_literal()?;
7034 Some(Box::new(Pattern::Literal(end_lit)))
7035 } else {
7036 None
7037 };
7038 Ok(Pattern::Range {
7039 start: Some(Box::new(Pattern::Literal(lit))),
7040 end,
7041 inclusive,
7042 })
7043 } else {
7044 Ok(Pattern::Literal(lit))
7045 }
7046 }
7047 Some(Token::SelfUpper) => {
7049 let span = self.current_span();
7050 self.advance();
7051
7052 let mut segments = vec![PathSegment {
7054 ident: Ident {
7055 name: "Self".to_string(),
7056 evidentiality: None,
7057 affect: None,
7058 span,
7059 },
7060 generics: None,
7061 }];
7062
7063 while self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
7065 let segment_name = self.parse_ident()?;
7066 segments.push(PathSegment {
7067 ident: segment_name,
7068 generics: None,
7069 });
7070 }
7071
7072 let path = TypePath { segments };
7073
7074 if self.check(&Token::LParen) {
7076 self.advance();
7077 let mut fields = Vec::new();
7078 while !self.check(&Token::RParen) {
7079 fields.push(self.parse_pattern()?);
7080 if !self.consume_if(&Token::Comma) {
7081 break;
7082 }
7083 }
7084 self.expect(Token::RParen)?;
7085 return Ok(Pattern::TupleStruct { path, fields });
7086 }
7087
7088 if self.check(&Token::LBrace) {
7090 self.advance();
7091 let mut fields = Vec::new();
7092 let mut rest = false;
7093 while !self.check(&Token::RBrace) {
7094 while matches!(
7095 self.current_token(),
7096 Some(Token::DocComment(_))
7097 | Some(
7098 Token::LineComment(_)
7099 | Token::TildeComment(_)
7100 | Token::BlockComment(_)
7101 )
7102 ) {
7103 self.advance();
7104 }
7105 if self.check(&Token::RBrace) {
7106 break;
7107 }
7108 if self.consume_if(&Token::DotDot) {
7109 rest = true;
7110 if !self.consume_if(&Token::Comma) {
7111 break;
7112 }
7113 continue;
7114 }
7115 let field_name = self.parse_ident()?;
7116 let pattern = if self.consume_if(&Token::Colon) {
7117 Some(self.parse_pattern()?)
7118 } else {
7119 None
7120 };
7121 fields.push(FieldPattern {
7122 name: field_name,
7123 pattern,
7124 });
7125 if !self.consume_if(&Token::Comma) {
7126 break;
7127 }
7128 }
7129 self.expect(Token::RBrace)?;
7130 return Ok(Pattern::Struct { path, fields, rest });
7131 }
7132
7133 return Ok(Pattern::Path(path));
7135 }
7136 Some(Token::Crate) | Some(Token::SelfLower) | Some(Token::Super) => {
7138 let keyword = self.current_token().cloned();
7139 let span = self.current_span();
7140 self.advance();
7141
7142 if !self.consume_if(&Token::ColonColon) && !self.consume_if(&Token::MiddleDot) {
7144 if matches!(keyword, Some(Token::SelfLower)) {
7146 return Ok(Pattern::Ident {
7147 mutable: false,
7148 name: Ident {
7149 name: "self".to_string(),
7150 evidentiality: None,
7151 affect: None,
7152 span,
7153 },
7154 evidentiality: self.parse_evidentiality_opt(),
7155 });
7156 }
7157 return Err(ParseError::Custom(
7158 "expected :: after crate/super in path pattern".to_string(),
7159 ));
7160 }
7161
7162 let keyword_name = match keyword {
7164 Some(Token::Crate) => "crate",
7165 Some(Token::SelfLower) => "self",
7166 Some(Token::Super) => "super",
7167 _ => unreachable!(),
7168 };
7169 let mut segments = vec![PathSegment {
7170 ident: Ident {
7171 name: keyword_name.to_string(),
7172 evidentiality: None,
7173 affect: None,
7174 span,
7175 },
7176 generics: None,
7177 }];
7178
7179 loop {
7181 let segment_name = self.parse_ident()?;
7182 segments.push(PathSegment {
7183 ident: segment_name,
7184 generics: None,
7185 });
7186
7187 if !self.consume_if(&Token::ColonColon) && !self.consume_if(&Token::MiddleDot) {
7188 break;
7189 }
7190 }
7191
7192 let path = TypePath { segments };
7193
7194 if self.check(&Token::LParen) {
7196 self.advance();
7197 let mut fields = Vec::new();
7198 while !self.check(&Token::RParen) {
7199 fields.push(self.parse_pattern()?);
7200 if !self.consume_if(&Token::Comma) {
7201 break;
7202 }
7203 }
7204 self.expect(Token::RParen)?;
7205 return Ok(Pattern::TupleStruct { path, fields });
7206 }
7207
7208 if self.check(&Token::LBrace) {
7210 self.advance();
7211 let mut fields = Vec::new();
7212 let mut rest = false;
7213 while !self.check(&Token::RBrace) {
7214 while matches!(
7215 self.current_token(),
7216 Some(Token::DocComment(_))
7217 | Some(
7218 Token::LineComment(_)
7219 | Token::TildeComment(_)
7220 | Token::BlockComment(_)
7221 )
7222 ) {
7223 self.advance();
7224 }
7225 if self.check(&Token::RBrace) {
7226 break;
7227 }
7228 if self.consume_if(&Token::DotDot) {
7229 rest = true;
7230 if !self.consume_if(&Token::Comma) {
7231 break;
7232 }
7233 continue;
7234 }
7235 let field_name = self.parse_ident()?;
7236 let pattern = if self.consume_if(&Token::Colon) {
7237 Some(self.parse_pattern()?)
7238 } else {
7239 None
7240 };
7241 fields.push(FieldPattern {
7242 name: field_name,
7243 pattern,
7244 });
7245 if !self.consume_if(&Token::Comma) {
7246 break;
7247 }
7248 }
7249 self.expect(Token::RBrace)?;
7250 return Ok(Pattern::Struct { path, fields, rest });
7251 }
7252
7253 return Ok(Pattern::Path(path));
7255 }
7256 Some(Token::Ident(_)) => {
7257 let name = self.parse_ident()?;
7258
7259 if self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
7261 let mut segments = vec![PathSegment {
7263 ident: name,
7264 generics: None,
7265 }];
7266
7267 loop {
7269 let segment_name = self.parse_ident()?;
7270 segments.push(PathSegment {
7271 ident: segment_name,
7272 generics: None,
7273 });
7274
7275 if !self.consume_if(&Token::ColonColon)
7276 && !self.consume_if(&Token::MiddleDot)
7277 {
7278 break;
7279 }
7280 }
7281
7282 let path = TypePath { segments };
7283
7284 if self.check(&Token::LParen) {
7286 self.advance();
7287 let mut fields = Vec::new();
7288 while !self.check(&Token::RParen) {
7289 fields.push(self.parse_pattern()?);
7290 if !self.consume_if(&Token::Comma) {
7291 break;
7292 }
7293 }
7294 self.expect(Token::RParen)?;
7295 return Ok(Pattern::TupleStruct { path, fields });
7296 }
7297
7298 if self.check(&Token::LBrace) {
7300 self.advance();
7301 let mut fields = Vec::new();
7302 let mut rest = false;
7303 while !self.check(&Token::RBrace) {
7304 while matches!(
7306 self.current_token(),
7307 Some(Token::DocComment(_))
7308 | Some(
7309 Token::LineComment(_)
7310 | Token::TildeComment(_)
7311 | Token::BlockComment(_)
7312 )
7313 ) {
7314 self.advance();
7315 }
7316 if self.check(&Token::RBrace) {
7317 break;
7318 }
7319
7320 if self.consume_if(&Token::DotDot) {
7322 rest = true;
7323 if !self.consume_if(&Token::Comma) {
7324 break;
7325 }
7326 continue;
7327 }
7328
7329 let field_name = self.parse_ident()?;
7330 let pattern = if self.consume_if(&Token::Colon) {
7331 Some(self.parse_pattern()?)
7332 } else {
7333 None
7335 };
7336 fields.push(FieldPattern {
7337 name: field_name,
7338 pattern,
7339 });
7340
7341 if !self.consume_if(&Token::Comma) {
7342 break;
7343 }
7344 }
7345 self.expect(Token::RBrace)?;
7346 return Ok(Pattern::Struct { path, fields, rest });
7347 }
7348
7349 return Ok(Pattern::Path(path));
7351 }
7352
7353 if self.check(&Token::LBrace) {
7355 let path = TypePath {
7357 segments: vec![PathSegment {
7358 ident: name,
7359 generics: None,
7360 }],
7361 };
7362 self.advance();
7363 let mut fields = Vec::new();
7364 let mut rest = false;
7365 while !self.check(&Token::RBrace) {
7366 while matches!(
7367 self.current_token(),
7368 Some(Token::DocComment(_))
7369 | Some(
7370 Token::LineComment(_)
7371 | Token::TildeComment(_)
7372 | Token::BlockComment(_)
7373 )
7374 ) {
7375 self.advance();
7376 }
7377 if self.check(&Token::RBrace) {
7378 break;
7379 }
7380 if self.consume_if(&Token::DotDot) {
7381 rest = true;
7382 break;
7383 }
7384 let field_name = self.parse_ident()?;
7385 let pattern = if self.consume_if(&Token::Colon) {
7386 Some(self.parse_pattern()?)
7387 } else {
7388 None
7389 };
7390 fields.push(FieldPattern {
7391 name: field_name,
7392 pattern,
7393 });
7394 if !self.consume_if(&Token::Comma) {
7395 break;
7396 }
7397 }
7398 self.expect(Token::RBrace)?;
7399 return Ok(Pattern::Struct { path, fields, rest });
7400 }
7401
7402 if self.check(&Token::LParen) {
7404 let path = TypePath {
7405 segments: vec![PathSegment {
7406 ident: name,
7407 generics: None,
7408 }],
7409 };
7410 self.advance();
7411 let mut fields = Vec::new();
7412 while !self.check(&Token::RParen) {
7413 fields.push(self.parse_pattern()?);
7414 if !self.consume_if(&Token::Comma) {
7415 break;
7416 }
7417 }
7418 self.expect(Token::RParen)?;
7419 return Ok(Pattern::TupleStruct { path, fields });
7420 }
7421
7422 let evidentiality = self.parse_evidentiality_opt();
7424 Ok(Pattern::Ident {
7425 mutable: false,
7426 name,
7427 evidentiality,
7428 })
7429 }
7430 Some(Token::SelfLower) => {
7431 let span = self.current_span();
7433 self.advance();
7434 Ok(Pattern::Ident {
7435 mutable: false,
7436 name: Ident {
7437 name: "self".to_string(),
7438 evidentiality: None,
7439 affect: None,
7440 span,
7441 },
7442 evidentiality: None,
7443 })
7444 }
7445 Some(ref token) if Self::keyword_as_ident(token).is_some() => {
7447 let name = self.parse_ident()?;
7448 let evidentiality = self.parse_evidentiality_opt();
7449 Ok(Pattern::Ident {
7450 mutable: false,
7451 name,
7452 evidentiality,
7453 })
7454 }
7455 Some(token) => Err(ParseError::UnexpectedToken {
7456 expected: "pattern".to_string(),
7457 found: token,
7458 span: self.current_span(),
7459 }),
7460 None => Err(ParseError::UnexpectedEof),
7461 }
7462 }
7463
7464 fn parse_literal(&mut self) -> ParseResult<Literal> {
7465 match self.current_token().cloned() {
7466 Some(Token::IntLit(s)) => {
7467 self.advance();
7468 Ok(Literal::Int {
7469 value: s,
7470 base: NumBase::Decimal,
7471 suffix: None,
7472 })
7473 }
7474 Some(Token::HexLit(s)) => {
7475 self.advance();
7476 Ok(Literal::Int {
7477 value: s,
7478 base: NumBase::Hex,
7479 suffix: None,
7480 })
7481 }
7482 Some(Token::OctalLit(s)) => {
7483 self.advance();
7484 Ok(Literal::Int {
7485 value: s,
7486 base: NumBase::Octal,
7487 suffix: None,
7488 })
7489 }
7490 Some(Token::BinaryLit(s)) => {
7491 self.advance();
7492 Ok(Literal::Int {
7493 value: s,
7494 base: NumBase::Binary,
7495 suffix: None,
7496 })
7497 }
7498 Some(Token::FloatLit(s)) => {
7499 self.advance();
7500 Ok(Literal::Float {
7501 value: s,
7502 suffix: None,
7503 })
7504 }
7505 Some(Token::StringLit(s)) => {
7506 self.advance();
7507 Ok(Literal::String(s))
7508 }
7509 Some(Token::CharLit(c)) => {
7510 self.advance();
7511 Ok(Literal::Char(c))
7512 }
7513 Some(Token::True) => {
7514 self.advance();
7515 Ok(Literal::Bool(true))
7516 }
7517 Some(Token::False) => {
7518 self.advance();
7519 Ok(Literal::Bool(false))
7520 }
7521 Some(Token::Null) => {
7522 self.advance();
7523 Ok(Literal::Null)
7524 }
7525 _ => Err(ParseError::Custom("expected literal".to_string())),
7526 }
7527 }
7528
7529 fn expr_to_incorporation_segment(&self, expr: Expr) -> ParseResult<IncorporationSegment> {
7534 match expr {
7535 Expr::Path(path) if path.segments.len() == 1 => Ok(IncorporationSegment {
7536 name: path.segments[0].ident.clone(),
7537 args: None,
7538 }),
7539 Expr::Call { func, args } => {
7540 match *func {
7541 Expr::Path(path) => {
7542 if let Some(last_seg) = path.segments.last() {
7545 return Ok(IncorporationSegment {
7546 name: last_seg.ident.clone(),
7547 args: Some(args),
7548 });
7549 }
7550 Err(ParseError::Custom(
7551 "incorporation chain: empty path".to_string(),
7552 ))
7553 }
7554 Expr::Field { expr, field } => Ok(IncorporationSegment {
7556 name: field.clone(),
7557 args: Some(std::iter::once(*expr).chain(args).collect()),
7558 }),
7559 _ => Err(ParseError::Custom(
7560 "incorporation chain must start with identifier or call".to_string(),
7561 )),
7562 }
7563 }
7564 Expr::Field { expr, field } => {
7567 Ok(IncorporationSegment {
7570 name: field.clone(),
7571 args: Some(vec![*expr]), })
7573 }
7574 Expr::Literal(_) => Ok(IncorporationSegment {
7577 name: Ident {
7578 name: "__lit__".to_string(),
7579 evidentiality: None,
7580 affect: None,
7581 span: crate::span::Span::default(),
7582 },
7583 args: Some(vec![expr]),
7584 }),
7585 Expr::Unary { .. } => Ok(IncorporationSegment {
7588 name: Ident {
7589 name: "__unary__".to_string(),
7590 evidentiality: None,
7591 affect: None,
7592 span: crate::span::Span::default(),
7593 },
7594 args: Some(vec![expr]),
7595 }),
7596 Expr::Index { expr: base, index } => Ok(IncorporationSegment {
7598 name: Ident {
7599 name: "__index__".to_string(),
7600 evidentiality: None,
7601 affect: None,
7602 span: crate::span::Span::default(),
7603 },
7604 args: Some(vec![*base, *index]),
7605 }),
7606 other => Ok(IncorporationSegment {
7609 name: Ident {
7610 name: "__expr__".to_string(),
7611 evidentiality: None,
7612 affect: None,
7613 span: crate::span::Span::default(),
7614 },
7615 args: Some(vec![other]),
7616 }),
7617 }
7618 }
7619
7620 fn keyword_as_ident(token: &Token) -> Option<&'static str> {
7622 match token {
7623 Token::Packed => Some("packed"),
7625 Token::As => Some("as"),
7626 Token::Type => Some("type"),
7627 Token::Crate => Some("crate"),
7628 Token::Super => Some("super"),
7629 Token::Mod => Some("mod"),
7630 Token::Use => Some("use"),
7631 Token::Pub => Some("pub"),
7632 Token::Const => Some("const"),
7633 Token::Static => Some("static"),
7634 Token::Extern => Some("extern"),
7635 Token::Unsafe => Some("unsafe"),
7636 Token::Async => Some("async"),
7637 Token::Await => Some("await"),
7638 Token::Move => Some("move"),
7639 Token::Dyn => Some("dyn"),
7640 Token::Atomic => Some("atomic"),
7641 Token::Volatile => Some("volatile"),
7642 Token::Naked => Some("naked"),
7643 Token::Connect => Some("connect"),
7644 Token::Close => Some("close"),
7645 Token::Simd => Some("simd"),
7646 Token::Derive => Some("derive"),
7647 Token::On => Some("on"),
7648 Token::Send => Some("send"),
7649 Token::Recv => Some("recv"),
7650 Token::Stream => Some("stream"),
7651 Token::Timeout => Some("timeout"),
7652 Token::Retry => Some("retry"),
7653 Token::Header => Some("header"),
7654 Token::Body => Some("body"),
7655 Token::Http => Some("http"),
7656 Token::Https => Some("https"),
7657 Token::Ws => Some("ws"),
7658 Token::Wss => Some("wss"),
7659 Token::Grpc => Some("grpc"),
7660 Token::Kafka => Some("kafka"),
7661 Token::Amqp => Some("amqp"),
7662 Token::GraphQL => Some("graphql"),
7663 Token::Actor => Some("actor"),
7664 Token::Saga => Some("saga"),
7665 Token::Scope => Some("scope"),
7666 Token::Rune => Some("rune"),
7667 Token::Split => Some("split"),
7669 Token::Trigger => Some("trigger"),
7670 Token::Location => Some("location"),
7671 Token::States => Some("states"),
7672 Token::To => Some("to"),
7673 Token::From => Some("from"),
7674 Token::Headspace => Some("headspace"),
7675 Token::CoCon => Some("cocon"),
7676 Token::Reality => Some("reality"),
7677 Token::Layer => Some("layer"),
7678 Token::Anima => Some("anima"),
7679 Token::Struct => Some("sigil"), Token::Parallel => Some("Parallel"),
7682 Token::Nu => Some("Nu"),
7683 Token::Lambda => Some("Lambda"),
7684 Token::Delta => Some("Delta"),
7685 Token::Tau => Some("Tau"),
7686 Token::Phi => Some("Phi"),
7687 Token::Sigma => Some("Sigma"),
7688 Token::Rho => Some("Rho"),
7689 Token::Pi => Some("Pi"),
7690 Token::Epsilon => Some("Epsilon"),
7691 Token::Omega => Some("Omega"),
7692 Token::Alpha => Some("Alpha"),
7693 Token::Zeta => Some("Zeta"),
7694 Token::Mu => Some("Mu"),
7695 Token::Chi => Some("Chi"),
7696 Token::Xi => Some("Xi"),
7697 Token::Psi => Some("Psi"),
7698 Token::Theta => Some("Theta"),
7699 Token::Kappa => Some("Kappa"),
7700 Token::Nabla => Some("∇"),
7701 Token::Gpu => Some("Gpu"),
7702 Token::Broadcast => Some("broadcast"),
7704 Token::Gather => Some("gather"),
7705 Token::Distribute => Some("distribute"),
7706 Token::Interfere => Some("interfere"),
7707 Token::Consensus => Some("consensus"),
7708 Token::Ref => Some("ref"),
7710 Token::Null => Some("null"),
7711 _ => None,
7712 }
7713 }
7714
7715 pub(crate) fn parse_ident(&mut self) -> ParseResult<Ident> {
7716 match self.current.take() {
7717 Some((Token::Ident(name), span)) => {
7718 self.current = self.lexer.next_token();
7719 let evidentiality = self.parse_unambiguous_evidentiality_opt();
7722 let affect = self.parse_affect_opt();
7724 Ok(Ident {
7725 name,
7726 evidentiality,
7727 affect,
7728 span,
7729 })
7730 }
7731 Some((ref token, span)) if Self::keyword_as_ident(token).is_some() => {
7732 let mut name = Self::keyword_as_ident(token).unwrap().to_string();
7733 self.current = self.lexer.next_token();
7734 if let Some((Token::Ident(suffix), suffix_span)) = &self.current {
7737 if suffix.starts_with('_') {
7738 name.push_str(suffix);
7739 let merged_span = span.merge(*suffix_span);
7740 self.current = self.lexer.next_token();
7741 let evidentiality = self.parse_unambiguous_evidentiality_opt();
7742 let affect = self.parse_affect_opt();
7743 return Ok(Ident {
7744 name,
7745 evidentiality,
7746 affect,
7747 span: merged_span,
7748 });
7749 }
7750 }
7751 let evidentiality = self.parse_unambiguous_evidentiality_opt();
7752 let affect = self.parse_affect_opt();
7753 Ok(Ident {
7754 name,
7755 evidentiality,
7756 affect,
7757 span,
7758 })
7759 }
7760 Some((token, span)) => {
7761 self.current = Some((token.clone(), span));
7762 Err(ParseError::UnexpectedToken {
7763 expected: "identifier".to_string(),
7764 found: token,
7765 span,
7766 })
7767 }
7768 None => Err(ParseError::UnexpectedEof),
7769 }
7770 }
7771
7772 fn parse_evidentiality_opt(&mut self) -> Option<Evidentiality> {
7773 let mut ev = None;
7776 loop {
7777 match self.current_token() {
7778 Some(Token::Bang) => {
7779 self.advance();
7780 ev = Some(Evidentiality::Known);
7781 }
7782 Some(Token::Question) => {
7783 self.advance();
7784 ev = Some(Evidentiality::Uncertain);
7785 }
7786 Some(Token::Tilde) => {
7787 self.advance();
7788 ev = Some(Evidentiality::Reported);
7789 }
7790 Some(Token::Lozenge) => {
7791 self.advance();
7792 ev = Some(Evidentiality::Predicted);
7793 }
7794 Some(Token::Interrobang) => {
7795 self.advance();
7796 ev = Some(Evidentiality::Paradox);
7797 }
7798 _ => break,
7799 }
7800 }
7801 ev
7802 }
7803
7804 fn parse_unambiguous_evidentiality_opt(&mut self) -> Option<Evidentiality> {
7807 let mut ev = None;
7808 loop {
7809 match self.current_token() {
7810 Some(Token::Tilde) => {
7811 self.advance();
7812 ev = Some(Evidentiality::Reported);
7813 }
7814 Some(Token::Lozenge) => {
7815 self.advance();
7816 ev = Some(Evidentiality::Predicted);
7817 }
7818 Some(Token::Interrobang) => {
7819 self.advance();
7820 ev = Some(Evidentiality::Paradox);
7821 }
7822 _ => break,
7823 }
7824 }
7825 ev
7826 }
7827
7828 fn parse_affect_opt(&mut self) -> Option<Affect> {
7832 let mut sentiment = None;
7833 let mut sarcasm = false;
7834 let mut intensity = None;
7835 let mut formality = None;
7836 let mut emotion = None;
7837 let mut confidence = None;
7838 let mut found_any = false;
7839
7840 loop {
7842 match self.current_token() {
7843 Some(Token::DirectSum) => {
7845 self.advance();
7846 sentiment = Some(Sentiment::Positive);
7847 found_any = true;
7848 }
7849 Some(Token::AffectNegative) => {
7850 self.advance();
7851 sentiment = Some(Sentiment::Negative);
7852 found_any = true;
7853 }
7854 Some(Token::AffectNeutral) => {
7855 self.advance();
7856 sentiment = Some(Sentiment::Neutral);
7857 found_any = true;
7858 }
7859 Some(Token::IronyMark) => {
7861 self.advance();
7862 sarcasm = true;
7863 found_any = true;
7864 }
7865 Some(Token::IntensityUp) => {
7867 self.advance();
7868 intensity = Some(Intensity::Up);
7869 found_any = true;
7870 }
7871 Some(Token::IntensityDown) => {
7872 self.advance();
7873 intensity = Some(Intensity::Down);
7874 found_any = true;
7875 }
7876 Some(Token::IntensityMax) => {
7877 self.advance();
7878 intensity = Some(Intensity::Max);
7879 found_any = true;
7880 }
7881 Some(Token::FormalRegister) => {
7883 self.advance();
7884 formality = Some(Formality::Formal);
7885 found_any = true;
7886 }
7887 Some(Token::InformalRegister) => {
7888 self.advance();
7889 formality = Some(Formality::Informal);
7890 found_any = true;
7891 }
7892 Some(Token::EmotionJoy) => {
7894 self.advance();
7895 emotion = Some(Emotion::Joy);
7896 found_any = true;
7897 }
7898 Some(Token::EmotionSadness) => {
7899 self.advance();
7900 emotion = Some(Emotion::Sadness);
7901 found_any = true;
7902 }
7903 Some(Token::EmotionAnger) => {
7904 self.advance();
7905 emotion = Some(Emotion::Anger);
7906 found_any = true;
7907 }
7908 Some(Token::EmotionFear) => {
7909 self.advance();
7910 emotion = Some(Emotion::Fear);
7911 found_any = true;
7912 }
7913 Some(Token::EmotionSurprise) => {
7914 self.advance();
7915 emotion = Some(Emotion::Surprise);
7916 found_any = true;
7917 }
7918 Some(Token::EmotionLove) => {
7919 self.advance();
7920 emotion = Some(Emotion::Love);
7921 found_any = true;
7922 }
7923 Some(Token::ConfidenceHigh) => {
7925 self.advance();
7926 confidence = Some(Confidence::High);
7927 found_any = true;
7928 }
7929 Some(Token::ConfidenceMedium) => {
7930 self.advance();
7931 confidence = Some(Confidence::Medium);
7932 found_any = true;
7933 }
7934 Some(Token::ConfidenceLow) => {
7935 self.advance();
7936 confidence = Some(Confidence::Low);
7937 found_any = true;
7938 }
7939 _ => break,
7940 }
7941 }
7942
7943 if found_any {
7944 Some(Affect {
7945 sentiment,
7946 sarcasm,
7947 intensity,
7948 formality,
7949 emotion,
7950 confidence,
7951 })
7952 } else {
7953 None
7954 }
7955 }
7956
7957 pub(crate) fn parse_generics_opt(&mut self) -> ParseResult<Option<Generics>> {
7958 let use_brackets = if self.consume_if(&Token::Lt) {
7960 false
7961 } else if self.consume_if(&Token::LBracket) {
7962 true
7963 } else {
7964 return Ok(None);
7965 };
7966
7967 let mut params = Vec::new();
7968 while !self.is_eof() {
7970 self.skip_comments();
7972
7973 if use_brackets {
7974 if self.check(&Token::RBracket) {
7975 break;
7976 }
7977 } else if self.check_gt() {
7978 break;
7979 }
7980
7981 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
7983 self.advance();
7984 params.push(GenericParam::Lifetime(lt));
7985 if !self.consume_if(&Token::Comma) {
7986 break;
7987 }
7988 continue;
7989 }
7990
7991 if self.consume_if(&Token::Const) {
7993 let name = self.parse_ident()?;
7994 let ty = if self.consume_if(&Token::Colon) {
7996 self.parse_type()?
7997 } else {
7998 TypeExpr::Infer
7999 };
8000 let default = if self.consume_if(&Token::Eq) {
8002 Some(Box::new(self.parse_expr()?))
8003 } else {
8004 None
8005 };
8006 params.push(GenericParam::Const { name, ty, default });
8007 if !self.consume_if(&Token::Comma) {
8008 break;
8009 }
8010 continue;
8011 }
8012
8013 let name = self.parse_ident()?;
8015 let evidentiality = self.parse_evidentiality_opt();
8016 let bounds = if self.consume_if(&Token::Colon) {
8017 self.parse_type_bounds()?
8018 } else {
8019 vec![]
8020 };
8021 let default = if self.consume_if(&Token::Eq) {
8023 Some(self.parse_type()?)
8024 } else {
8025 None
8026 };
8027 params.push(GenericParam::Type {
8028 name,
8029 bounds,
8030 evidentiality,
8031 default,
8032 });
8033
8034 if !self.consume_if(&Token::Comma) {
8035 break;
8036 }
8037 }
8038 if use_brackets {
8040 self.expect(Token::RBracket)?;
8041 } else {
8042 self.expect_gt()?;
8044 }
8045
8046 Ok(Some(Generics { params }))
8047 }
8048
8049 pub(crate) fn parse_where_clause_opt(&mut self) -> ParseResult<Option<WhereClause>> {
8050 if !self.consume_if(&Token::Where) {
8051 return Ok(None);
8052 }
8053
8054 let mut predicates = Vec::new();
8055 loop {
8056 self.skip_comments(); let is_expr_predicate = if let Some(Token::Ident(_)) = self.current_token() {
8063 let next = self.peek_next();
8065 matches!(
8066 next,
8067 Some(Token::Percent)
8068 | Some(Token::EqEq)
8069 | Some(Token::NotEq)
8070 | Some(Token::Plus)
8071 | Some(Token::Minus)
8072 | Some(Token::Star)
8073 | Some(Token::Slash)
8074 )
8075 } else {
8076 false
8077 };
8078
8079 if is_expr_predicate {
8080 let _expr = self.parse_expr()?;
8082 self.skip_comments();
8084 if !self.consume_if(&Token::Comma) {
8085 break;
8086 }
8087 self.skip_comments();
8088 if self.check(&Token::LBrace) {
8089 break;
8090 }
8091 continue;
8092 }
8093
8094 let ty = self.parse_type()?;
8095
8096 if self.check(&Token::Colon) {
8098 self.advance(); let bounds = self.parse_type_bounds()?;
8100 self.skip_comments(); predicates.push(WherePredicate { ty, bounds });
8102 } else {
8103 }
8106
8107 if !self.consume_if(&Token::Comma) {
8108 break;
8109 }
8110 self.skip_comments();
8112 if self.check(&Token::LBrace) {
8113 break;
8114 }
8115 }
8116
8117 Ok(Some(WhereClause { predicates }))
8118 }
8119
8120 pub(crate) fn parse_params(&mut self) -> ParseResult<Vec<Param>> {
8121 let mut params = Vec::new();
8122 while !self.check(&Token::RParen) && !self.is_eof() {
8123 self.skip_comments();
8125 while self.check(&Token::At) || self.check(&Token::Hash) {
8126 self.skip_attribute()?;
8127 self.skip_comments();
8128 }
8129 if self.check(&Token::RParen) {
8130 break;
8131 }
8132 let pattern = self.parse_pattern()?;
8133 let ty = if self.consume_if(&Token::Colon) {
8135 self.parse_type()?
8136 } else {
8137 TypeExpr::Infer
8138 };
8139 params.push(Param { pattern, ty });
8140 if !self.consume_if(&Token::Comma) {
8141 break;
8142 }
8143 }
8144 Ok(params)
8145 }
8146
8147 fn skip_attribute(&mut self) -> ParseResult<()> {
8149 if self.check(&Token::At) || self.check(&Token::Hash) {
8151 self.advance();
8152 }
8153 if self.consume_if(&Token::LBracket) {
8155 let mut depth = 1;
8156 while depth > 0 && !self.is_eof() {
8157 match self.current_token() {
8158 Some(Token::LBracket) => depth += 1,
8159 Some(Token::RBracket) => depth -= 1,
8160 _ => {}
8161 }
8162 self.advance();
8163 }
8164 }
8165 Ok(())
8166 }
8167
8168 fn parse_field_defs(&mut self) -> ParseResult<Vec<FieldDef>> {
8169 let mut fields = Vec::new();
8170 while !self.check(&Token::RBrace) && !self.is_eof() {
8171 while matches!(
8173 self.current_token(),
8174 Some(Token::DocComment(_))
8175 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
8176 ) || self.check(&Token::Hash)
8177 || self.check(&Token::At)
8178 {
8179 if self.check(&Token::Hash) || self.check(&Token::At) {
8180 self.skip_attribute()?;
8181 } else {
8182 self.advance();
8183 }
8184 }
8185 if self.check(&Token::RBrace) {
8186 break;
8187 }
8188 let visibility = self.parse_visibility()?;
8189 let name = self.parse_ident()?;
8190 let _evidentiality = self.parse_evidentiality_opt();
8192 self.expect(Token::Colon)?;
8193 let ty = self.parse_type()?;
8194 let default = if self.consume_if(&Token::Eq) {
8196 Some(self.parse_expr()?)
8197 } else {
8198 None
8199 };
8200 fields.push(FieldDef {
8201 visibility,
8202 name,
8203 ty,
8204 default,
8205 });
8206 if !self.consume_if(&Token::Comma) {
8207 break;
8208 }
8209 }
8210 Ok(fields)
8211 }
8212
8213 fn parse_expr_list(&mut self) -> ParseResult<Vec<Expr>> {
8214 let mut exprs = Vec::new();
8215 self.skip_comments();
8217 while !self.check(&Token::RParen) && !self.check(&Token::RBracket) && !self.is_eof() {
8218 let expr = if let Some(Token::Ident(name)) = self.current_token().cloned() {
8222 let is_named_arg = self.peek_next() == Some(&Token::Colon);
8224 if is_named_arg {
8225 let span = self.current_span();
8226 self.advance(); self.advance(); let value = self.parse_expr()?;
8229 Expr::NamedArg {
8231 name: Ident {
8232 name,
8233 evidentiality: None,
8234 affect: None,
8235 span,
8236 },
8237 value: Box::new(value),
8238 }
8239 } else {
8240 self.parse_expr()?
8241 }
8242 } else {
8243 self.parse_expr()?
8244 };
8245 exprs.push(expr);
8246 if !self.consume_if(&Token::Comma) {
8247 break;
8248 }
8249 self.skip_comments();
8251 }
8252 Ok(exprs)
8253 }
8254
8255 fn parse_struct_fields(&mut self) -> ParseResult<(Vec<FieldInit>, Option<Box<Expr>>)> {
8256 let mut fields = Vec::new();
8257 let mut rest = None;
8258
8259 while !self.check(&Token::RBrace) && !self.is_eof() {
8260 while matches!(
8262 self.current_token(),
8263 Some(Token::DocComment(_))
8264 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
8265 | Some(Token::Hash)
8266 ) {
8267 if self.check(&Token::Hash) {
8268 self.advance();
8270 self.consume_if(&Token::Bang); if self.consume_if(&Token::LBracket) {
8272 let mut depth = 1;
8273 while depth > 0 && !self.is_eof() {
8274 match self.current_token() {
8275 Some(Token::LBracket) => depth += 1,
8276 Some(Token::RBracket) => depth -= 1,
8277 _ => {}
8278 }
8279 self.advance();
8280 }
8281 }
8282 } else {
8283 self.advance();
8284 }
8285 }
8286 if self.check(&Token::RBrace) {
8287 break;
8288 }
8289 if self.consume_if(&Token::DotDot) {
8290 rest = Some(Box::new(self.parse_expr()?));
8291 break;
8292 }
8293
8294 let name = self.parse_ident()?;
8295 let value = if self.consume_if(&Token::Colon) {
8296 Some(self.parse_expr()?)
8297 } else {
8298 None
8299 };
8300 fields.push(FieldInit { name, value });
8301
8302 if !self.consume_if(&Token::Comma) {
8303 break;
8304 }
8305 }
8306
8307 Ok((fields, rest))
8308 }
8309
8310 fn is_item_start(&mut self) -> bool {
8311 match self.current_token() {
8312 Some(Token::Fn) | Some(Token::Struct) | Some(Token::Enum) | Some(Token::Trait)
8313 | Some(Token::Impl) | Some(Token::Type) | Some(Token::Mod) | Some(Token::Use)
8314 | Some(Token::Const) | Some(Token::Static) | Some(Token::Actor) | Some(Token::Pub)
8315 | Some(Token::Extern) => true,
8316 Some(Token::Async) => matches!(self.peek_next(), Some(Token::Fn)),
8319 _ => false,
8320 }
8321 }
8322
8323 fn is_in_condition(&self) -> bool {
8324 self.in_condition
8325 }
8326
8327 fn parse_condition(&mut self) -> ParseResult<Expr> {
8329 let was_in_condition = self.in_condition;
8330 self.in_condition = true;
8331 let result = self.parse_expr();
8332 self.in_condition = was_in_condition;
8333 result
8334 }
8335
8336 fn parse_legion_operator(&mut self, lhs: Expr) -> ParseResult<Expr> {
8344 match self.current_token() {
8345 Some(Token::Interfere) => {
8346 self.advance();
8348 let field = self.parse_expr_bp(15)?; Ok(Expr::LegionInterference {
8350 query: Box::new(lhs),
8351 field: Box::new(field),
8352 })
8353 }
8354 Some(Token::Distribute) => {
8355 self.advance();
8357 let count = self.parse_expr_bp(15)?;
8358 Ok(Expr::LegionDistribute {
8359 task: Box::new(lhs),
8360 count: Box::new(count),
8361 })
8362 }
8363 Some(Token::Broadcast) => {
8364 self.advance();
8366 let target = self.parse_expr_bp(15)?;
8367 Ok(Expr::LegionBroadcast {
8368 signal: Box::new(lhs),
8369 target: Box::new(target),
8370 })
8371 }
8372 Some(Token::Gather) => {
8373 self.advance();
8375 Ok(Expr::LegionGather {
8376 fragments: Box::new(lhs),
8377 })
8378 }
8379 Some(Token::Consensus) => {
8380 self.advance();
8382 Ok(Expr::LegionConsensus {
8383 contributions: Box::new(lhs),
8384 })
8385 }
8386 Some(Token::ConfidenceHigh) => {
8387 self.advance();
8389 Ok(Expr::LegionResonance {
8390 expr: Box::new(lhs),
8391 })
8392 }
8393 _ => Ok(lhs),
8394 }
8395 }
8396
8397 fn is_legion_field_ident(&self, name: &str) -> bool {
8400 name.ends_with('∿')
8401 }
8402}
8403
8404fn infix_binding_power(op: BinOp) -> (u8, u8) {
8406 match op {
8407 BinOp::Or => (1, 2),
8408 BinOp::And => (3, 4),
8409 BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge => (5, 6),
8410 BinOp::BitOr => (7, 8),
8411 BinOp::BitXor => (9, 10),
8412 BinOp::BitAnd => (11, 12),
8413 BinOp::Shl | BinOp::Shr => (13, 14),
8414 BinOp::Add | BinOp::Sub | BinOp::Concat => (15, 16),
8415 BinOp::Mul
8416 | BinOp::Div
8417 | BinOp::Rem
8418 | BinOp::MatMul
8419 | BinOp::Hadamard
8420 | BinOp::TensorProd => (17, 18),
8421 BinOp::Pow => (20, 19), }
8423}
8424
8425#[cfg(test)]
8426mod tests {
8427 use super::*;
8428
8429 #[test]
8430 fn test_parse_function() {
8431 let source = "fn hello(name: str) -> str { return name; }";
8433 let mut parser = Parser::new(source);
8434 let file = parser.parse_file().unwrap();
8435 assert_eq!(file.items.len(), 1);
8436 }
8437
8438 #[test]
8439 fn test_parse_pipe_chain() {
8440 let source = "fn main() { let result = data|τ{_ * 2}|φ{_ > 0}|σ; }";
8441 let mut parser = Parser::new(source);
8442 let file = parser.parse_file().unwrap();
8443 assert_eq!(file.items.len(), 1);
8444 }
8445
8446 #[test]
8447 fn test_parse_async_function() {
8448 let source = "async fn fetch(url: str) -> Response~ { return client·get(url)|await; }";
8449 let mut parser = Parser::new(source);
8450 let file = parser.parse_file().unwrap();
8451 assert_eq!(file.items.len(), 1);
8452 }
8453
8454 #[test]
8455 fn test_parse_struct() {
8456 let source = "struct Point { x: f64, y: f64 }";
8457 let mut parser = Parser::new(source);
8458 let file = parser.parse_file().unwrap();
8459 assert_eq!(file.items.len(), 1);
8460 }
8461
8462 #[test]
8463 fn test_parse_actor() {
8464 let source = r#"
8466 actor Counter {
8467 state: i64 = 0
8468 on Increment(n: i64) { return self.state + n; }
8469 }
8470 "#;
8471 let mut parser = Parser::new(source);
8472 let file = parser.parse_file().unwrap();
8473 assert_eq!(file.items.len(), 1);
8474 }
8475
8476 #[test]
8477 fn test_parse_number_bases() {
8478 let source = "fn bases() { let a = 42; let b = 0b101010; let c = 0x2A; let d = 0v22; }";
8479 let mut parser = Parser::new(source);
8480 let file = parser.parse_file().unwrap();
8481 assert_eq!(file.items.len(), 1);
8482 }
8483
8484 #[test]
8485 fn test_parse_labeled_loops() {
8486 let source = r#"
8488 fn test() {
8489 'outer: loop {
8490 'inner: while true {
8491 break 'outer;
8492 }
8493 }
8494 }
8495 "#;
8496 let mut parser = Parser::new(source);
8497 let file = parser.parse_file().unwrap();
8498 assert_eq!(file.items.len(), 1);
8499
8500 let source2 = r#"
8502 fn test2() {
8503 'rows: for i in 0..10 {
8504 'cols: for j in 0..10 {
8505 if j == 5 { continue 'rows; }
8506 }
8507 }
8508 }
8509 "#;
8510 let mut parser2 = Parser::new(source2);
8511 let file2 = parser2.parse_file().unwrap();
8512 assert_eq!(file2.items.len(), 1);
8513 }
8514
8515 #[test]
8516 fn test_parse_inline_asm() {
8517 let source = r#"
8518 fn outb(port: u16, value: u8) {
8519 asm!("out dx, al",
8520 in("dx") port,
8521 in("al") value,
8522 options(nostack));
8523 }
8524 "#;
8525 let mut parser = Parser::new(source);
8526 let file = parser.parse_file().unwrap();
8527 assert_eq!(file.items.len(), 1);
8528
8529 if let Item::Function(func) = &file.items[0].node {
8530 assert_eq!(func.name.name, "outb");
8531 } else {
8532 panic!("Expected function");
8533 }
8534 }
8535
8536 #[test]
8537 fn test_parse_inline_asm_with_outputs() {
8538 let source = r#"
8539 fn inb(port: u16) -> u8 {
8540 let result: u8 = 0;
8541 asm!("in al, dx",
8542 out("al") result,
8543 in("dx") port,
8544 options(nostack, nomem));
8545 return result;
8546 }
8547 "#;
8548 let mut parser = Parser::new(source);
8549 let file = parser.parse_file().unwrap();
8550 assert_eq!(file.items.len(), 1);
8551 }
8552
8553 #[test]
8554 fn test_parse_volatile_read() {
8555 let source = r#"
8556 fn read_mmio(addr: *mut u32) -> u32 {
8557 return volatile read<u32>(addr);
8558 }
8559 "#;
8560 let mut parser = Parser::new(source);
8561 let file = parser.parse_file().unwrap();
8562 assert_eq!(file.items.len(), 1);
8563 }
8564
8565 #[test]
8566 fn test_parse_volatile_write() {
8567 let source = r#"
8568 fn write_mmio(addr: *mut u32, value: u32) {
8569 volatile write<u32>(addr, value);
8570 }
8571 "#;
8572 let mut parser = Parser::new(source);
8573 let file = parser.parse_file().unwrap();
8574 assert_eq!(file.items.len(), 1);
8575 }
8576
8577 #[test]
8578 fn test_parse_naked_function() {
8579 let source = r#"
8580 naked fn interrupt_handler() {
8581 asm!("push rax; push rbx; call handler_impl; pop rbx; pop rax; iretq",
8582 options(nostack));
8583 }
8584 "#;
8585 let mut parser = Parser::new(source);
8586 let file = parser.parse_file().unwrap();
8587 assert_eq!(file.items.len(), 1);
8588
8589 if let Item::Function(func) = &file.items[0].node {
8590 assert!(func.attrs.naked, "Function should be naked");
8591 } else {
8592 panic!("Expected function");
8593 }
8594 }
8595
8596 #[test]
8597 fn test_parse_packed_struct() {
8598 let source = r#"
8599 packed struct GDTEntry {
8600 limit_low: u16,
8601 base_low: u16,
8602 base_middle: u8,
8603 access: u8,
8604 granularity: u8,
8605 base_high: u8,
8606 }
8607 "#;
8608 let mut parser = Parser::new(source);
8609 let file = parser.parse_file().unwrap();
8610 assert_eq!(file.items.len(), 1);
8611
8612 if let Item::Struct(s) = &file.items[0].node {
8613 assert!(s.attrs.packed, "Struct should be packed");
8614 assert_eq!(s.name.name, "GDTEntry");
8615 if let StructFields::Named(fields) = &s.fields {
8616 assert_eq!(fields.len(), 6);
8617 } else {
8618 panic!("Expected named fields");
8619 }
8620 } else {
8621 panic!("Expected struct");
8622 }
8623 }
8624
8625 #[test]
8626 fn test_parse_no_std_attribute() {
8627 let source = r#"
8628 #![no_std]
8629 #![no_main]
8630
8631 fn kernel_main() -> ! {
8632 loop {}
8633 }
8634 "#;
8635 let mut parser = Parser::new(source);
8636 let file = parser.parse_file().unwrap();
8637
8638 assert!(file.config.no_std, "Should have no_std");
8639 assert!(file.config.no_main, "Should have no_main");
8640 assert_eq!(file.attrs.len(), 2);
8641 }
8642
8643 #[test]
8644 fn test_parse_feature_attribute() {
8645 let source = r#"
8646 #![feature(asm, naked_functions)]
8647
8648 fn main() -> i64 { 0 }
8649 "#;
8650 let mut parser = Parser::new(source);
8651 let file = parser.parse_file().unwrap();
8652
8653 assert_eq!(file.config.features.len(), 2);
8654 assert!(file.config.features.contains(&"asm".to_string()));
8655 assert!(file
8656 .config
8657 .features
8658 .contains(&"naked_functions".to_string()));
8659 }
8660
8661 #[test]
8662 fn test_parse_target_attribute() {
8663 let source = r#"
8664 #![no_std]
8665 #![target(arch = "x86_64", os = "none")]
8666
8667 fn kernel_main() { }
8668 "#;
8669 let mut parser = Parser::new(source);
8670 let file = parser.parse_file().unwrap();
8671
8672 assert!(file.config.no_std);
8673 let target = file
8674 .config
8675 .target
8676 .as_ref()
8677 .expect("Should have target config");
8678 assert_eq!(target.arch, Some("x86_64".to_string()));
8679 assert_eq!(target.os, Some("none".to_string()));
8680 }
8681
8682 #[test]
8683 fn test_parse_panic_handler() {
8684 let source = r#"
8685 #![no_std]
8686
8687 #[panic_handler]
8688 fn panic(info: *const PanicInfo) -> ! {
8689 loop {}
8690 }
8691 "#;
8692 let mut parser = Parser::new(source);
8693 let file = parser.parse_file().unwrap();
8694
8695 assert_eq!(file.items.len(), 1);
8696 if let Item::Function(func) = &file.items[0].node {
8697 assert!(
8698 func.attrs.panic_handler,
8699 "Should have panic_handler attribute"
8700 );
8701 } else {
8702 panic!("Expected function");
8703 }
8704 }
8705
8706 #[test]
8707 fn test_parse_entry_point() {
8708 let source = r#"
8709 #![no_std]
8710 #![no_main]
8711
8712 #[entry]
8713 #[no_mangle]
8714 fn _start() -> ! {
8715 loop {}
8716 }
8717 "#;
8718 let mut parser = Parser::new(source);
8719 let file = parser.parse_file().unwrap();
8720
8721 assert_eq!(file.items.len(), 1);
8722 if let Item::Function(func) = &file.items[0].node {
8723 assert!(func.attrs.entry, "Should have entry attribute");
8724 assert!(func.attrs.no_mangle, "Should have no_mangle attribute");
8725 } else {
8726 panic!("Expected function");
8727 }
8728 }
8729
8730 #[test]
8731 fn test_parse_link_section() {
8732 let source = r#"
8733 #[link_section = ".text.boot"]
8734 fn boot_code() { }
8735 "#;
8736 let mut parser = Parser::new(source);
8737 let file = parser.parse_file().unwrap();
8738
8739 assert_eq!(file.items.len(), 1);
8740 if let Item::Function(func) = &file.items[0].node {
8741 assert_eq!(func.attrs.link_section, Some(".text.boot".to_string()));
8742 } else {
8743 panic!("Expected function");
8744 }
8745 }
8746
8747 #[test]
8748 fn test_parse_linker_config() {
8749 let source = r#"
8750 #![no_std]
8751 #![linker_script = "kernel.ld"]
8752 #![entry_point = "_start"]
8753 #![base_address = 0x100000]
8754 #![stack_size = 0x4000]
8755
8756 fn kernel_main() { }
8757 "#;
8758 let mut parser = Parser::new(source);
8759 let file = parser.parse_file().unwrap();
8760
8761 let linker = file
8762 .config
8763 .linker
8764 .as_ref()
8765 .expect("Should have linker config");
8766 assert_eq!(linker.script, Some("kernel.ld".to_string()));
8767 assert_eq!(linker.entry_point, Some("_start".to_string()));
8768 assert_eq!(linker.base_address, Some(0x100000));
8769 assert_eq!(linker.stack_size, Some(0x4000));
8770 }
8771
8772 #[test]
8773 fn test_parse_interrupt_handler() {
8774 let source = r#"
8775 #[interrupt(32)]
8776 #[naked]
8777 fn timer_handler() {
8778 asm!("iretq", options(nostack));
8779 }
8780 "#;
8781 let mut parser = Parser::new(source);
8782 let file = parser.parse_file().unwrap();
8783
8784 if let Item::Function(func) = &file.items[0].node {
8785 assert_eq!(func.attrs.interrupt, Some(32));
8786 assert!(func.attrs.naked);
8787 } else {
8788 panic!("Expected function");
8789 }
8790 }
8791
8792 #[test]
8793 fn test_parse_inline_attributes() {
8794 let source = r#"
8795 #[inline]
8796 fn fast() -> i64 { 0 }
8797
8798 #[inline(always)]
8799 fn very_fast() -> i64 { 0 }
8800
8801 #[inline(never)]
8802 fn never_inline() -> i64 { 0 }
8803 "#;
8804 let mut parser = Parser::new(source);
8805 let file = parser.parse_file().unwrap();
8806
8807 assert_eq!(file.items.len(), 3);
8808
8809 if let Item::Function(func) = &file.items[0].node {
8810 assert_eq!(func.attrs.inline, Some(InlineHint::Hint));
8811 }
8812 if let Item::Function(func) = &file.items[1].node {
8813 assert_eq!(func.attrs.inline, Some(InlineHint::Always));
8814 }
8815 if let Item::Function(func) = &file.items[2].node {
8816 assert_eq!(func.attrs.inline, Some(InlineHint::Never));
8817 }
8818 }
8819
8820 #[test]
8821 fn test_parse_simd_type() {
8822 let source = r#"
8823 fn vec_add(a: simd<f32, 4>, b: simd<f32, 4>) -> simd<f32, 4> {
8824 return simd.add(a, b);
8825 }
8826 "#;
8827 let mut parser = Parser::new(source);
8828 let file = parser.parse_file().unwrap();
8829 assert_eq!(file.items.len(), 1);
8830
8831 if let Item::Function(func) = &file.items[0].node {
8832 assert_eq!(func.name.name, "vec_add");
8833 if let TypeExpr::Simd { element, lanes } = &func.params[0].ty {
8835 assert_eq!(*lanes, 4);
8836 if let TypeExpr::Path(path) = element.as_ref() {
8837 assert_eq!(path.segments[0].ident.name, "f32");
8838 }
8839 } else {
8840 panic!("Expected SIMD type");
8841 }
8842 } else {
8843 panic!("Expected function");
8844 }
8845 }
8846
8847 #[test]
8848 fn test_parse_simd_literal() {
8849 let source = r#"
8850 fn make_vec() -> simd<f32, 4> {
8851 return simd[1.0, 2.0, 3.0, 4.0];
8852 }
8853 "#;
8854 let mut parser = Parser::new(source);
8855 let file = parser.parse_file().unwrap();
8856 assert_eq!(file.items.len(), 1);
8857 }
8858
8859 #[test]
8860 fn test_parse_simd_intrinsics() {
8861 let source = r#"
8862 fn dot_product(a: simd<f32, 4>, b: simd<f32, 4>) -> f32 {
8863 let prod = simd.mul(a, b);
8864 return simd.hadd(prod);
8865 }
8866 "#;
8867 let mut parser = Parser::new(source);
8868 let file = parser.parse_file().unwrap();
8869 assert_eq!(file.items.len(), 1);
8870 }
8871
8872 #[test]
8873 fn test_parse_simd_shuffle() {
8874 let source = r#"
8875 fn interleave(a: simd<f32, 4>, b: simd<f32, 4>) -> simd<f32, 4> {
8876 return simd.shuffle(a, b, [0, 4, 1, 5]);
8877 }
8878 "#;
8879 let mut parser = Parser::new(source);
8880 let file = parser.parse_file().unwrap();
8881 assert_eq!(file.items.len(), 1);
8882 }
8883
8884 #[test]
8885 fn test_parse_atomic_type() {
8886 let source = r#"
8887 struct Counter {
8888 value: atomic<i64>,
8889 }
8890 "#;
8891 let mut parser = Parser::new(source);
8892 let file = parser.parse_file().unwrap();
8893 assert_eq!(file.items.len(), 1);
8894
8895 if let Item::Struct(s) = &file.items[0].node {
8896 if let StructFields::Named(fields) = &s.fields {
8897 if let TypeExpr::Atomic(inner) = &fields[0].ty {
8898 if let TypeExpr::Path(path) = inner.as_ref() {
8899 assert_eq!(path.segments[0].ident.name, "i64");
8900 }
8901 } else {
8902 panic!("Expected atomic type");
8903 }
8904 }
8905 } else {
8906 panic!("Expected struct");
8907 }
8908 }
8909
8910 #[test]
8911 fn test_parse_atomic_operations() {
8912 let source = r#"
8913 fn increment(ptr: *mut i64) -> i64 {
8914 return atomic.fetch_add(ptr, 1, SeqCst);
8915 }
8916 "#;
8917 let mut parser = Parser::new(source);
8918 let file = parser.parse_file().unwrap();
8919 assert_eq!(file.items.len(), 1);
8920 }
8921
8922 #[test]
8923 fn test_parse_atomic_compare_exchange() {
8924 let source = r#"
8925 fn cas(ptr: *mut i64, expected: i64, new: i64) -> bool {
8926 let result = atomic.compare_exchange(ptr, expected, new, AcqRel, Relaxed);
8927 return result;
8928 }
8929 "#;
8930 let mut parser = Parser::new(source);
8931 let file = parser.parse_file().unwrap();
8932 assert_eq!(file.items.len(), 1);
8933 }
8934
8935 #[test]
8936 fn test_parse_atomic_fence() {
8937 let source = r#"
8938 fn memory_barrier() {
8939 atomic.fence(SeqCst);
8940 }
8941 "#;
8942 let mut parser = Parser::new(source);
8943 let file = parser.parse_file().unwrap();
8944 assert_eq!(file.items.len(), 1);
8945 }
8946
8947 #[test]
8948 fn test_parse_derive_macro() {
8949 let source = r#"
8950 #[derive(Debug, Clone, Component)]
8951 struct Position {
8952 x: f32,
8953 y: f32,
8954 z: f32,
8955 }
8956 "#;
8957 let mut parser = Parser::new(source);
8958 let file = parser.parse_file().unwrap();
8959 assert_eq!(file.items.len(), 1);
8960
8961 if let Item::Struct(s) = &file.items[0].node {
8962 assert_eq!(s.attrs.derives.len(), 3);
8963 assert!(matches!(s.attrs.derives[0], DeriveTrait::Debug));
8964 assert!(matches!(s.attrs.derives[1], DeriveTrait::Clone));
8965 assert!(matches!(s.attrs.derives[2], DeriveTrait::Component));
8966 } else {
8967 panic!("Expected struct");
8968 }
8969 }
8970
8971 #[test]
8972 fn test_parse_repr_c_struct() {
8973 let source = r#"
8974 #[repr(C)]
8975 struct FFIStruct {
8976 field: i32,
8977 }
8978 "#;
8979 let mut parser = Parser::new(source);
8980 let file = parser.parse_file().unwrap();
8981 assert_eq!(file.items.len(), 1);
8982
8983 if let Item::Struct(s) = &file.items[0].node {
8984 assert_eq!(s.attrs.repr, Some(StructRepr::C));
8985 } else {
8986 panic!("Expected struct");
8987 }
8988 }
8989
8990 #[test]
8991 fn test_parse_allocator_trait() {
8992 let source = r#"
8993 trait Allocator {
8994 type Error;
8995
8996 fn allocate(size: usize, align: usize) -> *mut u8;
8997 fn deallocate(ptr: *mut u8, size: usize, align: usize);
8998 }
8999 "#;
9000 let mut parser = Parser::new(source);
9001 let file = parser.parse_file().unwrap();
9002 assert_eq!(file.items.len(), 1);
9003
9004 if let Item::Trait(t) = &file.items[0].node {
9005 assert_eq!(t.name.name, "Allocator");
9006 assert_eq!(t.items.len(), 3); assert!(matches!(t.items[0], TraitItem::Type { .. }));
9008 } else {
9009 panic!("Expected trait");
9010 }
9011 }
9012
9013 #[test]
9014 fn test_parse_where_clause() {
9015 let source = r#"
9016 fn alloc_array<T, A>(allocator: &mut A, count: usize) -> *mut T
9017 where
9018 A: Allocator,
9019 {
9020 return allocator.allocate(count, 8);
9021 }
9022 "#;
9023 let mut parser = Parser::new(source);
9024 let file = parser.parse_file().unwrap();
9025 assert_eq!(file.items.len(), 1);
9026
9027 if let Item::Function(func) = &file.items[0].node {
9028 assert!(func.where_clause.is_some());
9029 let wc = func.where_clause.as_ref().unwrap();
9030 assert_eq!(wc.predicates.len(), 1);
9031 } else {
9032 panic!("Expected function");
9033 }
9034 }
9035}