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 expect_struct(&mut self) -> ParseResult<Span> {
664 match &self.current {
665 Some((Token::Struct | Token::Sigma, span)) => {
666 let span = *span;
667 self.advance();
668 Ok(span)
669 }
670 Some((token, span)) => Err(ParseError::UnexpectedToken {
671 expected: "struct or Σ".to_string(),
672 found: token.clone(),
673 span: *span,
674 }),
675 None => Err(ParseError::UnexpectedEof),
676 }
677 }
678
679 pub(crate) fn expect_fn(&mut self) -> ParseResult<Span> {
681 match &self.current {
682 Some((Token::Fn | Token::Lambda, span)) => {
683 let span = *span;
684 self.advance();
685 Ok(span)
686 }
687 Some((token, span)) => Err(ParseError::UnexpectedToken {
688 expected: "fn or λ".to_string(),
689 found: token.clone(),
690 span: *span,
691 }),
692 None => Err(ParseError::UnexpectedEof),
693 }
694 }
695
696 pub(crate) fn expect_trait(&mut self) -> ParseResult<Span> {
698 match &self.current {
699 Some((Token::Trait | Token::Theta, span)) => {
700 let span = *span;
701 self.advance();
702 Ok(span)
703 }
704 Some((token, span)) => Err(ParseError::UnexpectedToken {
705 expected: "trait or Θ".to_string(),
706 found: token.clone(),
707 span: *span,
708 }),
709 None => Err(ParseError::UnexpectedEof),
710 }
711 }
712
713 pub(crate) fn check(&self, expected: &Token) -> bool {
714 matches!(&self.current, Some((token, _)) if std::mem::discriminant(token) == std::mem::discriminant(expected))
715 }
716
717 pub(crate) fn peek_next(&mut self) -> Option<&Token> {
719 self.lexer.peek().map(|(t, _)| t)
720 }
721
722 pub(crate) fn peek_n(&mut self, n: usize) -> Option<&Token> {
724 self.lexer.peek_n(n).map(|(t, _)| t)
725 }
726
727 pub(crate) fn consume_if(&mut self, expected: &Token) -> bool {
728 if self.check(expected) {
729 self.advance();
730 true
731 } else {
732 false
733 }
734 }
735
736 pub(crate) fn check_mut(&self) -> bool {
738 matches!(self.current_token(), Some(Token::Mut) | Some(Token::Delta))
739 }
740
741 pub(crate) fn consume_if_mut(&mut self) -> bool {
743 if self.check_mut() {
744 self.advance();
745 true
746 } else {
747 false
748 }
749 }
750
751 pub(crate) fn check_self(&self) -> bool {
753 matches!(self.current_token(), Some(Token::SelfLower) | Some(Token::Xi))
754 }
755
756 pub(crate) fn check_path_sep(&self) -> bool {
758 matches!(self.current_token(), Some(Token::ColonColon) | Some(Token::MiddleDot))
759 }
760
761 pub(crate) fn consume_if_path_sep(&mut self) -> bool {
763 if self.check_path_sep() {
764 self.advance();
765 true
766 } else {
767 false
768 }
769 }
770
771 pub(crate) fn check_as(&self) -> bool {
773 matches!(self.current_token(), Some(Token::As) | Some(Token::Arrow))
774 }
775
776 pub(crate) fn consume_if_as(&mut self) -> bool {
778 if self.check_as() {
779 self.advance();
780 true
781 } else {
782 false
783 }
784 }
785
786 pub(crate) fn skip_comments(&mut self) {
788 while matches!(
789 self.current_token(),
790 Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
791 | Some(Token::DocComment(_))
792 ) {
793 self.advance();
794 }
795 }
796
797 pub(crate) fn check_gt(&self) -> bool {
799 self.pending_gt.is_some() || self.check(&Token::Gt)
800 }
801
802 pub(crate) fn expect_gt(&mut self) -> ParseResult<Span> {
805 if let Some(span) = self.pending_gt.take() {
807 return Ok(span);
808 }
809
810 match &self.current {
811 Some((Token::Gt, span)) => {
812 let span = *span;
813 self.advance();
814 Ok(span)
815 }
816 Some((Token::Shr, span)) => {
817 let span = *span;
820 self.pending_gt = Some(span);
821 self.advance();
822 Ok(span)
823 }
824 Some((token, span)) => Err(ParseError::UnexpectedToken {
825 expected: "Gt".to_string(),
826 found: token.clone(),
827 span: *span,
828 }),
829 None => Err(ParseError::UnexpectedEof),
830 }
831 }
832
833 fn consume_gt(&mut self) -> bool {
835 if self.pending_gt.is_some() {
836 self.pending_gt = None;
837 return true;
838 }
839 if self.check(&Token::Gt) {
840 self.advance();
841 return true;
842 }
843 if self.check(&Token::Shr) {
845 let span = self.current_span();
846 self.pending_gt = Some(span);
847 self.advance();
848 return true;
849 }
850 false
851 }
852
853 fn can_start_item(&self) -> bool {
856 matches!(
857 self.current_token(),
858 Some(
859 Token::Pub
860 | Token::Fn | Token::Lambda | Token::Async | Token::Hourglass | Token::Struct | Token::Sigma | Token::Enum | Token::Trait | Token::Theta | Token::Impl | Token::Type
867 | Token::Mod
868 | Token::Use
869 | Token::Const
870 | Token::Static
871 | Token::Actor
872 | Token::Extern
873 | Token::Hash
874 | Token::At
875 | Token::Naked
876 | Token::Packed
877 | Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
878 | Token::DocComment(_)
879 | Token::Alter
881 | Token::Headspace
882 | Token::Reality
883 | Token::CoCon
884 )
885 ) || (matches!(self.current_token(), Some(Token::On)) && self.peek_next_is_trigger())
886 }
887
888 fn peek_next_is_trigger(&self) -> bool {
890 false }
893
894 fn can_start_stmt(&self) -> bool {
897 if let Some(token) = self.current_token() {
899 if Self::keyword_as_ident(token).is_some() {
900 return true;
901 }
902 }
903 matches!(
904 self.current_token(),
905 Some(
906 Token::Let | Token::If | Token::Match | Token::Loop | Token::Infinity | Token::While | Token::For | Token::ForAll | Token::Return | Token::Break | Token::Continue | Token::Ident(_)
916 | Token::SelfLower | Token::Xi | Token::SelfUpper | Token::LParen
919 | Token::LBracket
920 | Token::LBrace
921 | Token::StringLit(_)
923 | Token::IntLit(_)
924 | Token::FloatLit(_)
925 | Token::True | Token::Top | Token::False | Token::Bottom | Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
928 | Token::DocComment(_)
929 )
930 ) || self.can_start_item()
931 }
932
933 fn expect_semi_or_item_start(&mut self) -> ParseResult<()> {
936 if self.consume_if(&Token::Semi) {
937 return Ok(());
938 }
939 if self.can_start_item() || self.is_eof() || self.check(&Token::RBrace) {
940 return Ok(());
942 }
943 let span = self.current_span();
944 Err(ParseError::UnexpectedToken {
945 expected: "`;` or new item".to_string(),
946 found: self.current_token().cloned().unwrap_or(Token::Semi),
947 span,
948 })
949 }
950
951 fn parse_item(&mut self) -> ParseResult<Spanned<Item>> {
954 let start_span = self.current_span();
955
956 let mut outer_attrs = Vec::new();
958 while self.check(&Token::Hash) || self.check(&Token::At) {
959 outer_attrs.push(self.parse_outer_attribute()?);
960 }
961
962 let visibility = self.parse_visibility()?;
963
964 let item = match self.current_token() {
965 Some(Token::Fn) | Some(Token::Lambda) | Some(Token::Async) | Some(Token::Hourglass) => {
966 Item::Function(self.parse_function_with_attrs(visibility, outer_attrs)?)
967 }
968 Some(Token::Struct) | Some(Token::Sigma) => {
969 Item::Struct(self.parse_struct_with_attrs(visibility, outer_attrs)?)
970 }
971 Some(Token::Enum) => Item::Enum(self.parse_enum(visibility)?),
972 Some(Token::Trait) | Some(Token::Theta) => Item::Trait(self.parse_trait(visibility)?),
973 Some(Token::Impl) => Item::Impl(self.parse_impl()?),
974 Some(Token::Unsafe) => {
975 self.advance(); match self.current_token() {
978 Some(Token::Impl) => Item::Impl(self.parse_impl()?),
979 Some(Token::Fn) | Some(Token::Async) => {
980 Item::Function(self.parse_function_with_attrs(visibility, outer_attrs)?)
981 }
982 Some(Token::Trait) => Item::Trait(self.parse_trait(visibility)?),
983 Some(t) => {
984 return Err(ParseError::UnexpectedToken {
985 expected: "impl, fn, or trait after unsafe".to_string(),
986 found: t.clone(),
987 span: self.current_span(),
988 })
989 }
990 None => return Err(ParseError::UnexpectedEof),
991 }
992 }
993 Some(Token::Type) => Item::TypeAlias(self.parse_type_alias(visibility)?),
994 Some(Token::Mod) => Item::Module(self.parse_module(visibility)?),
995 Some(Token::Use) => Item::Use(self.parse_use(visibility)?),
996 Some(Token::Const) => {
997 if self
999 .peek_next()
1000 .map(|t| matches!(t, Token::Fn | Token::Async))
1001 == Some(true)
1002 {
1003 Item::Function(self.parse_function_with_attrs(visibility, outer_attrs)?)
1004 } else {
1005 Item::Const(self.parse_const(visibility)?)
1006 }
1007 }
1008 Some(Token::Static) => Item::Static(self.parse_static(visibility)?),
1009 Some(Token::Actor) => Item::Actor(self.parse_actor(visibility)?),
1010 Some(Token::Extern) => Item::ExternBlock(self.parse_extern_block()?),
1011 Some(Token::Macro) | Some(Token::MacroRules) => {
1012 Item::Macro(self.parse_macro_def(visibility)?)
1013 }
1014 Some(Token::Naked) => {
1015 Item::Function(self.parse_function_with_attrs(visibility, outer_attrs)?)
1017 }
1018 Some(Token::Packed) => {
1019 Item::Struct(self.parse_struct_with_attrs(visibility, outer_attrs)?)
1021 }
1022 Some(Token::Alter) => {
1024 use crate::plurality::PluralityParser;
1025 Item::Plurality(crate::plurality::PluralityItem::Alter(
1026 self.parse_alter_def(visibility)?,
1027 ))
1028 }
1029 Some(Token::Headspace) => {
1030 use crate::plurality::PluralityParser;
1031 Item::Plurality(crate::plurality::PluralityItem::Headspace(
1032 self.parse_headspace_def(visibility)?,
1033 ))
1034 }
1035 Some(Token::Reality) => {
1036 use crate::plurality::PluralityParser;
1037 Item::Plurality(crate::plurality::PluralityItem::Reality(
1038 self.parse_reality_def(visibility)?,
1039 ))
1040 }
1041 Some(Token::CoCon) => {
1042 use crate::plurality::PluralityParser;
1043 Item::Plurality(crate::plurality::PluralityItem::CoConChannel(
1044 self.parse_cocon_channel()?,
1045 ))
1046 }
1047 Some(Token::On) => {
1048 if self.peek_next() == Some(&Token::Trigger) {
1050 use crate::plurality::PluralityParser;
1051 Item::Plurality(crate::plurality::PluralityItem::TriggerHandler(
1052 self.parse_trigger_handler()?,
1053 ))
1054 } else {
1055 return Err(ParseError::UnexpectedToken {
1056 expected: "item".to_string(),
1057 found: Token::On,
1058 span: self.current_span(),
1059 });
1060 }
1061 }
1062 Some(Token::Ident(_)) => {
1064 if self.looks_like_macro_invocation() {
1066 Item::MacroInvocation(self.parse_macro_invocation()?)
1067 } else {
1068 return Err(ParseError::UnexpectedToken {
1069 expected: "item".to_string(),
1070 found: self.current_token().unwrap().clone(),
1071 span: self.current_span(),
1072 });
1073 }
1074 }
1075 Some(token) => {
1076 return Err(ParseError::UnexpectedToken {
1077 expected: "item".to_string(),
1078 found: token.clone(),
1079 span: self.current_span(),
1080 });
1081 }
1082 None => return Err(ParseError::UnexpectedEof),
1083 };
1084
1085 let end_span = self.current_span();
1086 Ok(Spanned::new(item, start_span.merge(end_span)))
1087 }
1088
1089 pub(crate) fn parse_visibility(&mut self) -> ParseResult<Visibility> {
1090 if self.consume_if(&Token::Pub) {
1091 Ok(Visibility::Public)
1092 } else {
1093 Ok(Visibility::Private)
1094 }
1095 }
1096
1097 fn parse_function(&mut self, visibility: Visibility) -> ParseResult<Function> {
1098 self.parse_function_with_attrs(visibility, Vec::new())
1099 }
1100
1101 fn parse_function_with_attrs(
1102 &mut self,
1103 visibility: Visibility,
1104 outer_attrs: Vec<Attribute>,
1105 ) -> ParseResult<Function> {
1106 let mut attrs = self.process_function_attrs(&outer_attrs);
1108
1109 if self.consume_if(&Token::Naked) {
1111 attrs.naked = true;
1112 }
1113
1114 let is_unsafe = self.consume_if(&Token::Unsafe);
1116
1117 let is_const = self.consume_if(&Token::Const);
1119
1120 let is_async = self.consume_if(&Token::Async);
1121 self.expect_fn()?;
1122
1123 let mut name = self.parse_ident()?;
1124
1125 if let Some(ev) = self.parse_evidentiality_opt() {
1128 if name.evidentiality.is_none() {
1130 name.evidentiality = Some(ev);
1131 }
1132 }
1133
1134 let aspect = match self.current_token() {
1136 Some(Token::AspectProgressive) => {
1137 self.advance();
1138 Some(Aspect::Progressive)
1139 }
1140 Some(Token::AspectPerfective) => {
1141 self.advance();
1142 Some(Aspect::Perfective)
1143 }
1144 Some(Token::AspectPotential) => {
1145 self.advance();
1146 Some(Aspect::Potential)
1147 }
1148 Some(Token::AspectResultative) => {
1149 self.advance();
1150 Some(Aspect::Resultative)
1151 }
1152 _ => None,
1153 };
1154
1155 let generics = self.parse_generics_opt()?;
1156
1157 self.expect(Token::LParen)?;
1158 let params = self.parse_params()?;
1159 self.expect(Token::RParen)?;
1160
1161 let return_type = if self.consume_if(&Token::Arrow) {
1162 Some(self.parse_type()?)
1163 } else {
1164 None
1165 };
1166
1167 let is_async = is_async || self.consume_if(&Token::Hourglass);
1170
1171 let where_clause = self.parse_where_clause_opt()?;
1172
1173 let body = if self.check(&Token::LBrace) {
1174 Some(self.parse_block()?)
1175 } else {
1176 if !self.consume_if(&Token::Semi) {
1179 let valid_terminator = matches!(
1185 self.current_token(),
1186 Some(Token::Fn)
1187 | Some(Token::Async)
1188 | Some(Token::Unsafe)
1189 | Some(Token::Const)
1190 | Some(Token::Type)
1191 | Some(Token::Pub)
1192 | Some(Token::DocComment(_))
1193 | Some(Token::LineComment(_))
1194 | Some(Token::BlockComment(_))
1195 | Some(Token::TildeComment(_))
1196 | Some(Token::RBrace)
1197 | Some(Token::Hash)
1198 );
1199 if !valid_terminator {
1200 return match self.current_token().cloned() {
1201 Some(token) => Err(ParseError::UnexpectedToken {
1202 expected: "Semi".to_string(),
1203 found: token,
1204 span: self.current_span(),
1205 }),
1206 None => Err(ParseError::UnexpectedEof),
1207 };
1208 }
1209 }
1210 None
1211 };
1212
1213 Ok(Function {
1214 visibility,
1215 is_async,
1216 is_const,
1217 is_unsafe,
1218 attrs,
1219 name,
1220 aspect,
1221 generics,
1222 params,
1223 return_type,
1224 where_clause,
1225 body,
1226 })
1227 }
1228
1229 fn process_function_attrs(&self, attrs: &[Attribute]) -> FunctionAttrs {
1231 let mut func_attrs = FunctionAttrs::default();
1232
1233 for attr in attrs {
1234 match attr.name.name.as_str() {
1235 "panic_handler" => func_attrs.panic_handler = true,
1236 "entry" => func_attrs.entry = true,
1237 "no_mangle" => func_attrs.no_mangle = true,
1238 "export" => func_attrs.export = true,
1239 "cold" => func_attrs.cold = true,
1240 "hot" => func_attrs.hot = true,
1241 "test" => func_attrs.test = true,
1242 "naked" => func_attrs.naked = true,
1243 "inline" => {
1244 func_attrs.inline = Some(match &attr.args {
1245 Some(AttrArgs::Paren(args)) => {
1246 if let Some(AttrArg::Ident(ident)) = args.first() {
1247 match ident.name.as_str() {
1248 "always" => InlineHint::Always,
1249 "never" => InlineHint::Never,
1250 _ => InlineHint::Hint,
1251 }
1252 } else {
1253 InlineHint::Hint
1254 }
1255 }
1256 _ => InlineHint::Hint,
1257 });
1258 }
1259 "link_section" => {
1260 if let Some(AttrArgs::Eq(value)) = &attr.args {
1261 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
1262 func_attrs.link_section = Some(s.clone());
1263 }
1264 }
1265 }
1266 "interrupt" => {
1267 if let Some(AttrArgs::Paren(args)) = &attr.args {
1268 if let Some(AttrArg::Literal(Literal::Int { value, base, .. })) =
1269 args.first()
1270 {
1271 let num = Self::parse_int_value(value, *base) as u32;
1272 func_attrs.interrupt = Some(num);
1273 }
1274 }
1275 }
1276 "align" => {
1277 if let Some(AttrArgs::Paren(args)) = &attr.args {
1278 if let Some(AttrArg::Literal(Literal::Int { value, base, .. })) =
1279 args.first()
1280 {
1281 let align = Self::parse_int_value(value, *base) as usize;
1282 func_attrs.align = Some(align);
1283 }
1284 }
1285 }
1286 _ => {
1287 func_attrs.outer_attrs.push(attr.clone());
1289 }
1290 }
1291 }
1292
1293 func_attrs
1294 }
1295
1296 fn parse_struct_with_attrs(
1297 &mut self,
1298 visibility: Visibility,
1299 outer_attrs: Vec<Attribute>,
1300 ) -> ParseResult<StructDef> {
1301 let mut attrs = StructAttrs::default();
1303 attrs.outer_attrs = outer_attrs.clone();
1304
1305 for attr in &outer_attrs {
1307 if attr.name.name == "derive" {
1308 if let Some(AttrArgs::Paren(args)) = &attr.args {
1309 for arg in args {
1310 if let AttrArg::Ident(ident) = arg {
1311 let derive = Self::parse_derive_trait(&ident.name)?;
1312 attrs.derives.push(derive);
1313 }
1314 }
1315 }
1316 } else if attr.name.name == "simd" {
1317 attrs.simd = true;
1318 } else if attr.name.name == "repr" {
1319 if let Some(AttrArgs::Paren(args)) = &attr.args {
1320 for arg in args {
1321 if let AttrArg::Ident(ident) = arg {
1322 attrs.repr = Some(match ident.name.as_str() {
1323 "C" => StructRepr::C,
1324 "transparent" => StructRepr::Transparent,
1325 "packed" => {
1326 attrs.packed = true;
1327 StructRepr::C }
1329 other => StructRepr::Int(other.to_string()),
1330 });
1331 } else if let AttrArg::Nested(nested) = arg {
1332 if nested.name.name == "align" {
1333 if let Some(AttrArgs::Paren(align_args)) = &nested.args {
1334 if let Some(AttrArg::Literal(Literal::Int { value, .. })) =
1335 align_args.first()
1336 {
1337 if let Ok(n) = value.parse::<usize>() {
1338 attrs.align = Some(n);
1339 }
1340 }
1341 }
1342 }
1343 }
1344 }
1345 }
1346 }
1347 }
1348
1349 if self.consume_if(&Token::Packed) {
1351 attrs.packed = true;
1352 }
1353
1354 self.expect_struct()?;
1355 let name = self.parse_ident()?;
1356
1357 let _evidentiality_before = self.parse_evidentiality_opt();
1363
1364 let generics = self.parse_generics_opt()?;
1365
1366 let _evidentiality_after = self.parse_evidentiality_opt();
1368
1369 let _ = self.parse_where_clause_opt()?;
1371
1372 let fields = if self.check(&Token::LBrace) {
1373 self.expect(Token::LBrace)?;
1374 let fields = self.parse_field_defs()?;
1375 self.expect(Token::RBrace)?;
1376 StructFields::Named(fields)
1377 } else if self.check(&Token::LParen) {
1378 self.expect(Token::LParen)?;
1379 let types = self.parse_tuple_struct_fields()?;
1380 self.expect(Token::RParen)?;
1381 self.expect_semi_or_item_start()?;
1383 StructFields::Tuple(types)
1384 } else {
1385 self.expect_semi_or_item_start()?;
1387 StructFields::Unit
1388 };
1389
1390 Ok(StructDef {
1391 visibility,
1392 attrs,
1393 name,
1394 generics,
1395 fields,
1396 })
1397 }
1398
1399 fn parse_derive_trait(name: &str) -> ParseResult<DeriveTrait> {
1400 match name {
1401 "Debug" => Ok(DeriveTrait::Debug),
1402 "Clone" => Ok(DeriveTrait::Clone),
1403 "Copy" => Ok(DeriveTrait::Copy),
1404 "Default" => Ok(DeriveTrait::Default),
1405 "PartialEq" => Ok(DeriveTrait::PartialEq),
1406 "Eq" => Ok(DeriveTrait::Eq),
1407 "PartialOrd" => Ok(DeriveTrait::PartialOrd),
1408 "Ord" => Ok(DeriveTrait::Ord),
1409 "Hash" => Ok(DeriveTrait::Hash),
1410 "Component" => Ok(DeriveTrait::Component),
1412 "Resource" => Ok(DeriveTrait::Resource),
1413 "Bundle" => Ok(DeriveTrait::Bundle),
1414 "Serialize" => Ok(DeriveTrait::Serialize),
1416 "Deserialize" => Ok(DeriveTrait::Deserialize),
1417 _ => Ok(DeriveTrait::Custom(name.to_string())),
1419 }
1420 }
1421
1422 fn parse_enum(&mut self, visibility: Visibility) -> ParseResult<EnumDef> {
1423 self.expect(Token::Enum)?;
1424 let name = self.parse_ident()?;
1425 let generics = self.parse_generics_opt()?;
1426
1427 self.expect(Token::LBrace)?;
1428 let mut variants = Vec::new();
1429 while !self.check(&Token::RBrace) && !self.is_eof() {
1430 while matches!(
1432 self.current_token(),
1433 Some(Token::DocComment(_))
1434 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1435 ) {
1436 self.advance();
1437 }
1438 while self.check(&Token::Hash) || self.check(&Token::At) {
1440 self.parse_outer_attribute()?;
1441 }
1442 while matches!(
1444 self.current_token(),
1445 Some(Token::DocComment(_))
1446 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1447 ) {
1448 self.advance();
1449 }
1450 if self.check(&Token::RBrace) {
1451 break;
1452 }
1453 variants.push(self.parse_enum_variant()?);
1454 if !self.consume_if(&Token::Comma) {
1455 break;
1456 }
1457 while matches!(
1459 self.current_token(),
1460 Some(Token::DocComment(_))
1461 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1462 ) {
1463 self.advance();
1464 }
1465 }
1466 self.expect(Token::RBrace)?;
1467
1468 Ok(EnumDef {
1469 visibility,
1470 name,
1471 generics,
1472 variants,
1473 })
1474 }
1475
1476 fn parse_enum_variant(&mut self) -> ParseResult<EnumVariant> {
1477 let name = self.parse_ident()?;
1478
1479 let fields = if self.check(&Token::LBrace) {
1480 self.expect(Token::LBrace)?;
1481 let fields = self.parse_field_defs()?;
1482 self.expect(Token::RBrace)?;
1483 StructFields::Named(fields)
1484 } else if self.check(&Token::LParen) {
1485 self.expect(Token::LParen)?;
1486 let types = self.parse_attributed_type_list()?;
1487 self.expect(Token::RParen)?;
1488 StructFields::Tuple(types)
1489 } else {
1490 StructFields::Unit
1491 };
1492
1493 let discriminant = if self.consume_if(&Token::Eq) {
1494 Some(self.parse_expr()?)
1495 } else {
1496 None
1497 };
1498
1499 Ok(EnumVariant {
1500 name,
1501 fields,
1502 discriminant,
1503 })
1504 }
1505
1506 fn parse_trait(&mut self, visibility: Visibility) -> ParseResult<TraitDef> {
1507 self.expect_trait()?;
1508 let name = self.parse_ident()?;
1509 let generics = self.parse_generics_opt()?;
1510
1511 let supertraits = if self.consume_if(&Token::Colon) {
1512 self.parse_type_bounds()?
1513 } else {
1514 vec![]
1515 };
1516
1517 self.expect(Token::LBrace)?;
1518 let mut items = Vec::new();
1519 while !self.check(&Token::RBrace) && !self.is_eof() {
1520 while matches!(
1522 self.current_token(),
1523 Some(Token::DocComment(_))
1524 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1525 ) {
1526 self.advance();
1527 }
1528 if self.check(&Token::RBrace) {
1529 break;
1530 }
1531 items.push(self.parse_trait_item()?);
1532 }
1533 self.expect(Token::RBrace)?;
1534
1535 Ok(TraitDef {
1536 visibility,
1537 name,
1538 generics,
1539 supertraits,
1540 items,
1541 })
1542 }
1543
1544 fn parse_trait_item(&mut self) -> ParseResult<TraitItem> {
1545 let visibility = self.parse_visibility()?;
1546
1547 match self.current_token() {
1548 Some(Token::Fn) | Some(Token::Lambda) | Some(Token::Async) | Some(Token::Hourglass) | Some(Token::Unsafe) => {
1549 Ok(TraitItem::Function(self.parse_function(visibility)?))
1550 }
1551 Some(Token::Type) => {
1552 self.advance();
1553 let name = self.parse_ident()?;
1554 let bounds = if self.consume_if(&Token::Colon) {
1555 self.parse_type_bounds()?
1556 } else {
1557 vec![]
1558 };
1559 self.expect(Token::Semi)?;
1560 Ok(TraitItem::Type { name, bounds })
1561 }
1562 Some(Token::Const) => {
1563 if self
1565 .peek_next()
1566 .map(|t| matches!(t, Token::Fn | Token::Lambda | Token::Async | Token::Hourglass))
1567 == Some(true)
1568 {
1569 Ok(TraitItem::Function(self.parse_function(visibility)?))
1570 } else {
1571 self.advance();
1572 let name = self.parse_ident()?;
1573 self.expect(Token::Colon)?;
1574 let ty = self.parse_type()?;
1575 self.expect(Token::Semi)?;
1576 Ok(TraitItem::Const { name, ty })
1577 }
1578 }
1579 Some(token) => Err(ParseError::UnexpectedToken {
1580 expected: "trait item".to_string(),
1581 found: token.clone(),
1582 span: self.current_span(),
1583 }),
1584 None => Err(ParseError::UnexpectedEof),
1585 }
1586 }
1587
1588 fn parse_impl(&mut self) -> ParseResult<ImplBlock> {
1589 self.expect(Token::Impl)?;
1590 let generics = self.parse_generics_opt()?;
1591
1592 let first_type = self.parse_type()?;
1595
1596 let (trait_, self_ty) = if self.consume_if(&Token::Colon) {
1597 let trait_type = self.parse_type()?;
1599 let trait_path = match trait_type {
1600 TypeExpr::Path(p) => p,
1601 _ => return Err(ParseError::Custom("expected aspect path".to_string())),
1602 };
1603 (Some(trait_path), first_type)
1604 } else {
1605 (None, first_type)
1606 };
1607
1608 let _ = self.parse_where_clause_opt()?;
1610
1611 self.expect(Token::LBrace)?;
1612 let mut items = Vec::new();
1613 while !self.check(&Token::RBrace) && !self.is_eof() {
1614 while matches!(
1616 self.current_token(),
1617 Some(Token::DocComment(_))
1618 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1619 | Some(Token::Hash)
1620 ) {
1621 if self.check(&Token::Hash) {
1622 self.advance();
1624 self.consume_if(&Token::Bang);
1625 if self.consume_if(&Token::LBracket) {
1626 let mut depth = 1;
1627 while depth > 0 && !self.is_eof() {
1628 match self.current_token() {
1629 Some(Token::LBracket) => depth += 1,
1630 Some(Token::RBracket) => depth -= 1,
1631 _ => {}
1632 }
1633 self.advance();
1634 }
1635 }
1636 } else {
1637 self.advance();
1638 }
1639 }
1640 if self.check(&Token::RBrace) {
1641 break;
1642 }
1643 items.push(self.parse_impl_item()?);
1644 }
1645 self.expect(Token::RBrace)?;
1646
1647 Ok(ImplBlock {
1648 generics,
1649 trait_,
1650 self_ty,
1651 items,
1652 })
1653 }
1654
1655 fn parse_impl_item(&mut self) -> ParseResult<ImplItem> {
1656 let mut outer_attrs = Vec::new();
1658 while self.check(&Token::Hash) || self.check(&Token::At) {
1659 outer_attrs.push(self.parse_outer_attribute()?);
1660 }
1661
1662 let visibility = self.parse_visibility()?;
1663
1664 match self.current_token() {
1665 Some(Token::Fn) | Some(Token::Lambda) | Some(Token::Async) | Some(Token::Hourglass) | Some(Token::Unsafe) => Ok(ImplItem::Function(
1666 self.parse_function_with_attrs(visibility, outer_attrs)?,
1667 )),
1668 Some(Token::Type) => Ok(ImplItem::Type(self.parse_type_alias(visibility)?)),
1669 Some(Token::Const) => {
1670 if self
1672 .peek_next()
1673 .map(|t| matches!(t, Token::Fn | Token::Lambda | Token::Async | Token::Hourglass))
1674 == Some(true)
1675 {
1676 Ok(ImplItem::Function(
1677 self.parse_function_with_attrs(visibility, outer_attrs)?,
1678 ))
1679 } else {
1680 Ok(ImplItem::Const(self.parse_const(visibility)?))
1681 }
1682 }
1683 Some(token) => Err(ParseError::UnexpectedToken {
1684 expected: "impl item".to_string(),
1685 found: token.clone(),
1686 span: self.current_span(),
1687 }),
1688 None => Err(ParseError::UnexpectedEof),
1689 }
1690 }
1691
1692 fn parse_type_alias(&mut self, visibility: Visibility) -> ParseResult<TypeAlias> {
1693 self.expect(Token::Type)?;
1694 let name = self.parse_ident()?;
1695 let generics = self.parse_generics_opt()?;
1696 let _evidentiality = self.parse_evidentiality_opt();
1698 self.expect(Token::Eq)?;
1699 let ty = self.parse_type()?;
1700 self.consume_if(&Token::Semi);
1702
1703 Ok(TypeAlias {
1704 visibility,
1705 name,
1706 generics,
1707 ty,
1708 })
1709 }
1710
1711 fn parse_module(&mut self, visibility: Visibility) -> ParseResult<Module> {
1712 self.expect(Token::Mod)?;
1713 let name = self.parse_ident()?;
1714
1715 let items = if self.check(&Token::LBrace) {
1716 self.expect(Token::LBrace)?;
1717 let mut items = Vec::new();
1718 while !self.check(&Token::RBrace) && !self.is_eof() {
1719 while matches!(
1721 self.current_token(),
1722 Some(Token::DocComment(_))
1723 | Some(
1724 Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
1725 )
1726 ) {
1727 self.advance();
1728 }
1729 if self.check(&Token::RBrace) {
1730 break;
1731 }
1732 items.push(self.parse_item()?);
1733 }
1734 self.expect(Token::RBrace)?;
1735 Some(items)
1736 } else {
1737 self.expect_semi_or_item_start()?;
1739 None
1740 };
1741
1742 Ok(Module {
1743 visibility,
1744 name,
1745 items,
1746 })
1747 }
1748
1749 fn parse_use(&mut self, visibility: Visibility) -> ParseResult<UseDecl> {
1750 self.expect(Token::Use)?;
1751 let tree = self.parse_use_tree()?;
1752 self.expect_semi_or_item_start()?;
1754
1755 Ok(UseDecl { visibility, tree })
1756 }
1757
1758 fn parse_use_tree(&mut self) -> ParseResult<UseTree> {
1759 if self.consume_if(&Token::Star) {
1760 return Ok(UseTree::Glob);
1761 }
1762
1763 if self.check(&Token::LBrace) {
1764 self.expect(Token::LBrace)?;
1765 let mut trees = Vec::new();
1766 while !self.check(&Token::RBrace) {
1767 loop {
1769 if matches!(
1770 self.current_token(),
1771 Some(Token::DocComment(_))
1772 | Some(
1773 Token::LineComment(_)
1774 | Token::TildeComment(_)
1775 | Token::BlockComment(_)
1776 )
1777 ) {
1778 self.advance();
1779 } else if self.check(&Token::Hash) {
1780 self.skip_attribute()?;
1782 } else {
1783 break;
1784 }
1785 }
1786 if self.check(&Token::RBrace) {
1787 break;
1788 }
1789 trees.push(self.parse_use_tree()?);
1790 if !self.consume_if(&Token::Comma) {
1791 break;
1792 }
1793 loop {
1795 if matches!(
1796 self.current_token(),
1797 Some(Token::DocComment(_))
1798 | Some(
1799 Token::LineComment(_)
1800 | Token::TildeComment(_)
1801 | Token::BlockComment(_)
1802 )
1803 ) {
1804 self.advance();
1805 } else if self.check(&Token::Hash) {
1806 self.skip_attribute()?;
1808 } else {
1809 break;
1810 }
1811 }
1812 }
1813 self.expect(Token::RBrace)?;
1814 return Ok(UseTree::Group(trees));
1815 }
1816
1817 let name = if self.check(&Token::Crate) {
1819 let span = self.current_span();
1820 self.advance();
1821 Ident {
1822 name: "crate".to_string(),
1823 evidentiality: None,
1824 affect: None,
1825 span,
1826 }
1827 } else if self.check(&Token::Super) {
1828 let span = self.current_span();
1829 self.advance();
1830 Ident {
1831 name: "super".to_string(),
1832 evidentiality: None,
1833 affect: None,
1834 span,
1835 }
1836 } else if self.check_self() {
1837 let span = self.current_span();
1839 self.advance();
1840 Ident {
1841 name: "self".to_string(),
1842 evidentiality: None,
1843 affect: None,
1844 span,
1845 }
1846 } else if self.check(&Token::Sqrt) {
1847 let span = self.current_span();
1849 self.advance();
1850 if let Some(Token::IntLit(n)) = self.current_token().cloned() {
1852 let merged_span = span.merge(self.current_span());
1853 self.advance();
1854 Ident {
1855 name: format!("√{}", n),
1856 evidentiality: None,
1857 affect: None,
1858 span: merged_span,
1859 }
1860 } else {
1861 Ident {
1862 name: "√".to_string(),
1863 evidentiality: None,
1864 affect: None,
1865 span,
1866 }
1867 }
1868 } else if self.check(&Token::Phi) {
1869 let span = self.current_span();
1871 self.advance();
1872 Ident {
1873 name: "φ".to_string(),
1874 evidentiality: None,
1875 affect: None,
1876 span,
1877 }
1878 } else {
1879 self.parse_ident()?
1880 };
1881
1882 let _evidentiality = self.parse_evidentiality_opt();
1885
1886 if self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::ColonColon) {
1888 let suffix = self.parse_use_tree()?;
1889 return Ok(UseTree::Path {
1890 prefix: name,
1891 suffix: Box::new(suffix),
1892 });
1893 }
1894
1895 if self.consume_if_as() {
1897 if self.check(&Token::Underscore) {
1899 let span = self.current_span();
1900 self.advance();
1901 let alias = Ident {
1902 name: "_".to_string(),
1903 evidentiality: None,
1904 affect: None,
1905 span,
1906 };
1907 return Ok(UseTree::Rename { name, alias });
1908 }
1909 let alias = self.parse_ident()?;
1910 return Ok(UseTree::Rename { name, alias });
1911 }
1912
1913 Ok(UseTree::Name(name))
1914 }
1915
1916 fn parse_const(&mut self, visibility: Visibility) -> ParseResult<ConstDef> {
1917 self.expect(Token::Const)?;
1918 let name = self.parse_ident()?;
1919 self.expect(Token::Colon)?;
1920 let ty = self.parse_type()?;
1921 self.expect(Token::Eq)?;
1922 let value = self.parse_expr()?;
1923 self.expect_semi_or_item_start()?;
1925
1926 Ok(ConstDef {
1927 visibility,
1928 name,
1929 ty,
1930 value,
1931 })
1932 }
1933
1934 fn parse_static(&mut self, visibility: Visibility) -> ParseResult<StaticDef> {
1935 self.expect(Token::Static)?;
1936 let mutable = self.consume_if_mut();
1937 let name = self.parse_ident()?;
1938 self.expect(Token::Colon)?;
1939 let ty = self.parse_type()?;
1940 self.expect(Token::Eq)?;
1941 let value = self.parse_expr()?;
1942 self.expect_semi_or_item_start()?;
1944
1945 Ok(StaticDef {
1946 visibility,
1947 mutable,
1948 name,
1949 ty,
1950 value,
1951 })
1952 }
1953
1954 fn parse_macro_def(&mut self, visibility: Visibility) -> ParseResult<MacroDef> {
1957 let is_macro_rules = self.check(&Token::MacroRules);
1959 if is_macro_rules {
1960 self.advance(); self.expect(Token::Bang)?; } else {
1963 self.expect(Token::Macro)?;
1964 }
1965
1966 let name = self.parse_ident()?;
1967
1968 let mut body = String::new();
1971 let mut depth = 0;
1972
1973 if self.check(&Token::LParen) {
1975 body.push('(');
1976 self.advance();
1977 depth = 1;
1978 while depth > 0 && !self.is_eof() {
1979 match self.current_token() {
1980 Some(Token::LParen) => {
1981 depth += 1;
1982 body.push('(');
1983 }
1984 Some(Token::RParen) => {
1985 depth -= 1;
1986 if depth > 0 {
1987 body.push(')');
1988 }
1989 }
1990 Some(tok) => {
1991 body.push_str(&format!("{:?} ", tok));
1992 }
1993 None => break,
1994 }
1995 self.advance();
1996 }
1997 body.push(')');
1998 }
1999
2000 self.expect(Token::LBrace)?;
2002 body.push('{');
2003 depth = 1;
2004 while depth > 0 && !self.is_eof() {
2005 match self.current_token() {
2006 Some(Token::LBrace) => {
2007 depth += 1;
2008 body.push('{');
2009 }
2010 Some(Token::RBrace) => {
2011 depth -= 1;
2012 if depth > 0 {
2013 body.push('}');
2014 }
2015 }
2016 Some(Token::LineComment(s)) => {
2017 body.push_str(&format!("//{}", s));
2018 }
2019 Some(tok) => {
2020 body.push_str(&format!("{:?} ", tok));
2021 }
2022 None => break,
2023 }
2024 self.advance();
2025 }
2026 body.push('}');
2027
2028 Ok(MacroDef {
2029 visibility,
2030 name,
2031 rules: body,
2032 })
2033 }
2034
2035 fn looks_like_macro_invocation(&mut self) -> bool {
2037 if !matches!(self.current_token(), Some(Token::Ident(_))) {
2039 return false;
2040 }
2041 let mut pos = 0;
2044 loop {
2045 match self.peek_n(pos) {
2046 Some(Token::Bang) => return true,
2047 Some(Token::ColonColon) => {
2048 pos += 1;
2049 match self.peek_n(pos) {
2051 Some(Token::Ident(_)) => {
2052 pos += 1;
2053 continue;
2054 }
2055 _ => return false,
2056 }
2057 }
2058 _ => return false,
2059 }
2060 }
2061 }
2062
2063 fn parse_macro_invocation(&mut self) -> ParseResult<MacroInvocation> {
2065 use crate::ast::{MacroDelimiter, MacroInvocation};
2066
2067 let path = self.parse_type_path()?;
2069
2070 self.expect(Token::Bang)?;
2072
2073 let (delimiter, open_tok, close_tok) = match self.current_token() {
2075 Some(Token::LBrace) => (MacroDelimiter::Brace, Token::LBrace, Token::RBrace),
2076 Some(Token::LParen) => (MacroDelimiter::Paren, Token::LParen, Token::RParen),
2077 Some(Token::LBracket) => (MacroDelimiter::Bracket, Token::LBracket, Token::RBracket),
2078 Some(tok) => {
2079 return Err(ParseError::UnexpectedToken {
2080 expected: "macro delimiter ('{', '(', or '[')".to_string(),
2081 found: tok.clone(),
2082 span: self.current_span(),
2083 });
2084 }
2085 None => return Err(ParseError::UnexpectedEof),
2086 };
2087
2088 self.advance(); let mut body = String::new();
2092 let mut depth = 1;
2093
2094 while depth > 0 && !self.is_eof() {
2095 let tok = self.current_token().cloned();
2096 match &tok {
2097 Some(t) if *t == open_tok => {
2098 depth += 1;
2099 body.push_str(&format!("{:?} ", t));
2100 }
2101 Some(t) if *t == close_tok => {
2102 depth -= 1;
2103 if depth > 0 {
2104 body.push_str(&format!("{:?} ", t));
2105 }
2106 }
2107 Some(Token::LineComment(s)) => {
2108 body.push_str(&format!("//{}\n", s));
2109 }
2110 Some(t) => {
2111 body.push_str(&format!("{:?} ", t));
2112 }
2113 None => break,
2114 }
2115 self.advance();
2116 }
2117
2118 if delimiter != MacroDelimiter::Brace {
2120 self.consume_if(&Token::Semi);
2121 }
2122
2123 Ok(MacroInvocation {
2124 path,
2125 delimiter,
2126 tokens: body,
2127 })
2128 }
2129
2130 fn parse_actor(&mut self, visibility: Visibility) -> ParseResult<ActorDef> {
2131 self.expect(Token::Actor)?;
2132 let name = self.parse_ident()?;
2133 let generics = self.parse_generics_opt()?;
2134
2135 self.expect(Token::LBrace)?;
2136
2137 let mut state = Vec::new();
2138 let mut handlers = Vec::new();
2139
2140 while !self.check(&Token::RBrace) && !self.is_eof() {
2141 if self.check(&Token::On) {
2142 handlers.push(self.parse_message_handler()?);
2143 } else {
2144 let vis = self.parse_visibility()?;
2146 let field_name = self.parse_ident()?;
2147 self.expect(Token::Colon)?;
2148 let ty = self.parse_type()?;
2149
2150 let default = if self.consume_if(&Token::Eq) {
2152 Some(self.parse_expr()?)
2153 } else {
2154 None
2155 };
2156
2157 if !self.check(&Token::RBrace) && !self.check(&Token::On) {
2158 self.consume_if(&Token::Comma);
2159 }
2160
2161 state.push(FieldDef {
2162 visibility: vis,
2163 name: field_name,
2164 ty,
2165 default,
2166 });
2167 }
2168 }
2169
2170 self.expect(Token::RBrace)?;
2171
2172 Ok(ActorDef {
2173 visibility,
2174 name,
2175 generics,
2176 state,
2177 handlers,
2178 })
2179 }
2180
2181 fn parse_extern_block(&mut self) -> ParseResult<ExternBlock> {
2183 self.expect(Token::Extern)?;
2184
2185 let abi = if let Some(Token::StringLit(s)) = self.current_token().cloned() {
2187 self.advance();
2188 s
2189 } else {
2190 "C".to_string()
2191 };
2192
2193 self.expect(Token::LBrace)?;
2194
2195 let mut items = Vec::new();
2196
2197 while !self.check(&Token::RBrace) && !self.is_eof() {
2198 let visibility = self.parse_visibility()?;
2199
2200 match self.current_token() {
2201 Some(Token::Fn) => {
2202 items.push(ExternItem::Function(
2203 self.parse_extern_function(visibility)?,
2204 ));
2205 }
2206 Some(Token::Static) => {
2207 items.push(ExternItem::Static(self.parse_extern_static(visibility)?));
2208 }
2209 Some(token) => {
2210 return Err(ParseError::UnexpectedToken {
2211 expected: "fn or static".to_string(),
2212 found: token.clone(),
2213 span: self.current_span(),
2214 });
2215 }
2216 None => return Err(ParseError::UnexpectedEof),
2217 }
2218 }
2219
2220 self.expect(Token::RBrace)?;
2221
2222 Ok(ExternBlock { abi, items })
2223 }
2224
2225 fn parse_extern_function(&mut self, visibility: Visibility) -> ParseResult<ExternFunction> {
2227 self.expect_fn()?;
2228 let name = self.parse_ident()?;
2229
2230 let _evidentiality = self.parse_evidentiality_opt();
2232
2233 self.expect(Token::LParen)?;
2234
2235 let mut params = Vec::new();
2236 let mut variadic = false;
2237
2238 while !self.check(&Token::RParen) && !self.is_eof() {
2239 if self.check(&Token::DotDot) {
2241 self.advance();
2242 if self.consume_if(&Token::Dot) {
2243 variadic = true;
2244 break;
2245 }
2246 }
2247
2248 let pattern = self.parse_pattern()?;
2249 self.expect(Token::Colon)?;
2250 let ty = self.parse_type()?;
2251
2252 params.push(Param { pattern, ty });
2253
2254 if !self.check(&Token::RParen) {
2255 self.expect(Token::Comma)?;
2256 }
2257 }
2258
2259 self.expect(Token::RParen)?;
2260
2261 let return_type = if self.consume_if(&Token::Arrow) {
2263 Some(self.parse_type()?)
2264 } else {
2265 None
2266 };
2267
2268 self.expect(Token::Semi)?;
2270
2271 Ok(ExternFunction {
2272 visibility,
2273 name,
2274 params,
2275 return_type,
2276 variadic,
2277 })
2278 }
2279
2280 fn parse_extern_static(&mut self, visibility: Visibility) -> ParseResult<ExternStatic> {
2282 self.expect(Token::Static)?;
2283 let mutable = self.consume_if_mut();
2284 let name = self.parse_ident()?;
2285 self.expect(Token::Colon)?;
2286 let ty = self.parse_type()?;
2287 self.expect(Token::Semi)?;
2288
2289 Ok(ExternStatic {
2290 visibility,
2291 mutable,
2292 name,
2293 ty,
2294 })
2295 }
2296
2297 fn parse_message_handler(&mut self) -> ParseResult<MessageHandler> {
2298 self.expect(Token::On)?;
2299 let message = self.parse_ident()?;
2300
2301 self.expect(Token::LParen)?;
2302 let params = self.parse_params()?;
2303 self.expect(Token::RParen)?;
2304
2305 let return_type = if self.consume_if(&Token::Arrow) {
2306 Some(self.parse_type()?)
2307 } else {
2308 None
2309 };
2310
2311 let body = self.parse_block()?;
2312
2313 Ok(MessageHandler {
2314 message,
2315 params,
2316 return_type,
2317 body,
2318 })
2319 }
2320
2321 pub(crate) fn parse_type(&mut self) -> ParseResult<TypeExpr> {
2324 if let Some(ev) = self.parse_evidentiality_prefix_opt() {
2326 let inner = self.parse_type()?;
2327 return Ok(TypeExpr::Evidential {
2328 inner: Box::new(inner),
2329 evidentiality: ev,
2330 error_type: None,
2331 });
2332 }
2333
2334 let mut base = self.parse_type_base()?;
2335
2336 let path_evidentiality = if let TypeExpr::Path(ref mut path) = base {
2340 if let Some(last_seg) = path.segments.last_mut() {
2341 last_seg.ident.evidentiality.take()
2342 } else {
2343 None
2344 }
2345 } else {
2346 None
2347 };
2348 if let Some(ev) = path_evidentiality {
2349 base = TypeExpr::Evidential {
2350 inner: Box::new(base),
2351 evidentiality: ev,
2352 error_type: None,
2353 };
2354 }
2355
2356 if let Some(ev) = self.parse_evidentiality_opt() {
2358 let base = if self.check(&Token::Lt) && self.peek_looks_like_generic_arg() {
2361 if let TypeExpr::Path(mut path) = base {
2363 self.advance(); let types = self.parse_type_list()?;
2365 self.expect_gt()?;
2366 if let Some(last) = path.segments.last_mut() {
2368 last.generics = Some(types);
2369 }
2370 TypeExpr::Path(path)
2371 } else {
2372 base
2373 }
2374 } else {
2375 base
2376 };
2377
2378 let error_type = if self.check(&Token::LBracket) {
2380 self.advance(); let err_ty = self.parse_type()?;
2382 self.expect(Token::RBracket)?; Some(Box::new(err_ty))
2384 } else {
2385 None
2386 };
2387
2388 let mut result = TypeExpr::Evidential {
2389 inner: Box::new(base),
2390 evidentiality: ev,
2391 error_type,
2392 };
2393
2394 if let Some(ev2) = self.parse_evidentiality_opt() {
2396 result = TypeExpr::Evidential {
2397 inner: Box::new(result),
2398 evidentiality: ev2,
2399 error_type: None,
2400 };
2401 }
2402
2403 return Ok(result);
2404 }
2405
2406 Ok(base)
2407 }
2408
2409 fn parse_evidentiality_prefix_opt(&mut self) -> Option<Evidentiality> {
2412 match self.current_token() {
2413 Some(Token::Bang) => {
2414 if self.peek_is_type_start() {
2417 self.advance();
2418 Some(Evidentiality::Known)
2419 } else {
2420 None
2421 }
2422 }
2423 Some(Token::Question) => {
2424 if self.peek_is_type_start() {
2425 self.advance();
2426 Some(Evidentiality::Uncertain)
2427 } else {
2428 None
2429 }
2430 }
2431 Some(Token::Tilde) => {
2432 if self.peek_is_type_start() {
2433 self.advance();
2434 Some(Evidentiality::Reported)
2435 } else {
2436 None
2437 }
2438 }
2439 Some(Token::Lozenge) => {
2440 if self.peek_is_type_start() {
2441 self.advance();
2442 Some(Evidentiality::Predicted)
2443 } else {
2444 None
2445 }
2446 }
2447 Some(Token::Interrobang) => {
2448 if self.peek_is_type_start() {
2449 self.advance();
2450 Some(Evidentiality::Paradox)
2451 } else {
2452 None
2453 }
2454 }
2455 _ => None,
2456 }
2457 }
2458
2459 fn peek_is_type_start(&mut self) -> bool {
2461 match self.peek_next() {
2462 Some(Token::Ident(_)) => true,
2463 Some(Token::SelfUpper) => true,
2464 Some(Token::Amp) => true,
2465 Some(Token::AndAnd) => true, Some(Token::Star) => true,
2467 Some(Token::LBracket) => true,
2468 Some(Token::LParen) => true,
2469 Some(Token::Fn) => true,
2470 Some(Token::Underscore) => true,
2471 Some(Token::Simd) => true,
2472 Some(Token::Atomic) => true,
2473 Some(Token::Bang) => true,
2475 Some(Token::Question) => true,
2476 Some(Token::Tilde) => true,
2477 Some(Token::Interrobang) => true,
2478 _ => false,
2479 }
2480 }
2481
2482 fn parse_type_base(&mut self) -> ParseResult<TypeExpr> {
2483 match self.current_token() {
2484 Some(Token::AndAnd) => {
2485 self.advance();
2487 let lifetime = if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
2489 self.advance();
2490 Some(lt)
2491 } else {
2492 None
2493 };
2494 let mutable = self.consume_if_mut();
2495 let inner = self.parse_type()?;
2496 let inner_ref = TypeExpr::Reference {
2498 lifetime,
2499 mutable,
2500 inner: Box::new(inner),
2501 };
2502 Ok(TypeExpr::Reference {
2504 lifetime: None,
2505 mutable: false,
2506 inner: Box::new(inner_ref),
2507 })
2508 }
2509 Some(Token::Amp) => {
2510 self.advance();
2511 let lifetime = if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
2513 self.advance();
2514 Some(lt)
2515 } else {
2516 None
2517 };
2518 let mutable = self.consume_if_mut();
2519 let inner = self.parse_type()?;
2520 Ok(TypeExpr::Reference {
2521 lifetime,
2522 mutable,
2523 inner: Box::new(inner),
2524 })
2525 }
2526 Some(Token::Star) => {
2527 self.advance();
2528 let mutable = if self.consume_if(&Token::Const) {
2531 false
2532 } else if self.consume_if_mut() {
2533 true
2534 } else {
2535 false
2537 };
2538 let inner = self.parse_type()?;
2539 Ok(TypeExpr::Pointer {
2540 mutable,
2541 inner: Box::new(inner),
2542 })
2543 }
2544 Some(Token::Linear) => {
2545 self.advance();
2547 let inner = self.parse_type()?;
2548 Ok(TypeExpr::Linear(Box::new(inner)))
2549 }
2550 Some(Token::LBracket) => {
2551 self.advance();
2552 if self.check(&Token::RBracket) {
2554 self.advance();
2556 return Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(vec![]))));
2558 }
2559 let first = self.parse_type_or_lifetime()?;
2561 if self.consume_if(&Token::Semi) {
2562 let size = self.parse_expr()?;
2564 self.expect(Token::RBracket)?;
2565 Ok(TypeExpr::Array {
2566 element: Box::new(first),
2567 size: Box::new(size),
2568 })
2569 } else if self.consume_if(&Token::Comma) {
2570 let first_expr = match first {
2573 TypeExpr::Path(path) => Expr::Path(path),
2574 TypeExpr::ConstExpr(expr) => *expr,
2575 _ => Expr::Path(TypePath {
2576 segments: vec![PathSegment {
2577 ident: Ident {
2578 name: format!("{:?}", first),
2579 evidentiality: None,
2580 affect: None,
2581 span: Span::new(0, 0),
2582 },
2583 generics: None,
2584 }],
2585 }),
2586 };
2587 let mut elem_exprs = vec![first_expr];
2588 while !self.check(&Token::RBracket) && !self.is_eof() {
2589 let dim_expr = self.parse_array_dim_expr()?;
2591 elem_exprs.push(dim_expr);
2592 if !self.consume_if(&Token::Comma) {
2593 break;
2594 }
2595 }
2596 self.expect(Token::RBracket)?;
2597 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(elem_exprs))))
2598 } else if matches!(
2599 self.current_token(),
2600 Some(Token::Slash)
2601 | Some(Token::Star)
2602 | Some(Token::Plus)
2603 | Some(Token::Minus)
2604 | Some(Token::Percent)
2605 ) {
2606 let first_expr = match first {
2609 TypeExpr::Path(path) => Expr::Path(path),
2610 TypeExpr::ConstExpr(expr) => *expr,
2611 _ => Expr::Path(TypePath {
2612 segments: vec![PathSegment {
2613 ident: Ident {
2614 name: format!("{:?}", first),
2615 evidentiality: None,
2616 affect: None,
2617 span: Span::new(0, 0),
2618 },
2619 generics: None,
2620 }],
2621 }),
2622 };
2623 let op = match self.current_token() {
2625 Some(Token::Slash) => BinOp::Div,
2626 Some(Token::Star) => BinOp::Mul,
2627 Some(Token::Plus) => BinOp::Add,
2628 Some(Token::Minus) => BinOp::Sub,
2629 Some(Token::Percent) => BinOp::Rem,
2630 _ => unreachable!(),
2631 };
2632 self.advance(); let right = self.parse_const_expr_primary()?;
2634 let expr = Expr::Binary {
2635 left: Box::new(first_expr),
2636 op,
2637 right: Box::new(right),
2638 };
2639
2640 if self.consume_if(&Token::Comma) {
2642 let mut elem_exprs = vec![expr];
2643 while !self.check(&Token::RBracket) && !self.is_eof() {
2644 let dim_expr = self.parse_array_dim_expr()?;
2645 elem_exprs.push(dim_expr);
2646 if !self.consume_if(&Token::Comma) {
2647 break;
2648 }
2649 }
2650 self.expect(Token::RBracket)?;
2651 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(elem_exprs))))
2652 } else {
2653 self.expect(Token::RBracket)?;
2654 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(vec![expr]))))
2655 }
2656 } else {
2657 self.expect(Token::RBracket)?;
2659 Ok(TypeExpr::Slice(Box::new(first)))
2660 }
2661 }
2662 Some(Token::LParen) => {
2663 self.advance();
2664 if self.check(&Token::RParen) {
2665 self.advance();
2666 return Ok(TypeExpr::Tuple(vec![]));
2667 }
2668 let types = self.parse_type_list()?;
2669 self.expect(Token::RParen)?;
2670 Ok(TypeExpr::Tuple(types))
2671 }
2672 Some(Token::Fn) => {
2673 self.advance();
2674 self.expect(Token::LParen)?;
2675 let params = self.parse_type_list()?;
2676 self.expect(Token::RParen)?;
2677 let return_type = if self.consume_if(&Token::Arrow) {
2678 Some(Box::new(self.parse_type()?))
2679 } else {
2680 None
2681 };
2682 Ok(TypeExpr::Function {
2683 params,
2684 return_type,
2685 })
2686 }
2687 Some(Token::Impl) => {
2688 self.advance();
2690 let bounds = self.parse_type_bounds()?;
2692 Ok(TypeExpr::ImplTrait(bounds))
2693 }
2694 Some(Token::Bang) => {
2695 self.advance();
2696 Ok(TypeExpr::Never)
2697 }
2698 Some(Token::Underscore) => {
2699 self.advance();
2700 Ok(TypeExpr::Infer)
2701 }
2702 Some(Token::Lt) => {
2703 self.advance(); let base_type = self.parse_type()?;
2707
2708 let trait_path = if self.consume_if_as() {
2710 Some(self.parse_type_path()?)
2711 } else {
2712 None
2713 };
2714
2715 self.expect_gt()?; if !self.consume_if(&Token::ColonColon) && !self.consume_if(&Token::MiddleDot) {
2718 return match &self.current {
2719 Some((token, span)) => Err(ParseError::UnexpectedToken {
2720 expected: "ColonColon or MiddleDot".to_string(),
2721 found: token.clone(),
2722 span: *span,
2723 }),
2724 None => Err(ParseError::UnexpectedEof),
2725 };
2726 }
2727
2728 let mut segments = vec![self.parse_path_segment()?];
2730 while self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
2731 segments.push(self.parse_path_segment()?);
2732 }
2733
2734 Ok(TypeExpr::QualifiedPath {
2735 self_type: Box::new(base_type),
2736 trait_path,
2737 item_path: TypePath { segments },
2738 })
2739 }
2740 Some(Token::SelfUpper) => {
2741 let span = self.current_span();
2742 self.advance();
2743 let mut segments = vec![PathSegment {
2744 ident: Ident {
2745 name: "Self".to_string(),
2746 evidentiality: None,
2747 affect: None,
2748 span,
2749 },
2750 generics: None,
2751 }];
2752 while self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
2754 if self.check(&Token::Lt) {
2756 self.advance();
2757 let types = self.parse_type_list()?;
2758 self.expect_gt()?;
2759 if let Some(last) = segments.last_mut() {
2760 last.generics = Some(types);
2761 }
2762 continue;
2763 }
2764 segments.push(self.parse_path_segment()?);
2765 }
2766 Ok(TypeExpr::Path(TypePath { segments }))
2767 }
2768 Some(Token::Simd) => {
2769 self.advance();
2770 self.expect(Token::Lt)?;
2771 let element = self.parse_type()?;
2772 self.expect(Token::Comma)?;
2773 let lanes = match self.current_token() {
2774 Some(Token::IntLit(s)) => {
2775 let n = s
2776 .parse::<u8>()
2777 .map_err(|_| ParseError::Custom("invalid lane count".to_string()))?;
2778 self.advance();
2779 n
2780 }
2781 _ => return Err(ParseError::Custom("expected lane count".to_string())),
2782 };
2783 self.expect_gt()?;
2784 Ok(TypeExpr::Simd {
2785 element: Box::new(element),
2786 lanes,
2787 })
2788 }
2789 Some(Token::Atomic) => {
2790 self.advance();
2791 self.expect(Token::Lt)?;
2792 let inner = self.parse_type()?;
2793 self.expect_gt()?;
2794 Ok(TypeExpr::Atomic(Box::new(inner)))
2795 }
2796 Some(Token::Dyn) => {
2797 self.advance();
2799 let bounds = self.parse_type_bounds()?;
2800 Ok(TypeExpr::TraitObject(bounds))
2801 }
2802 Some(Token::Struct) | Some(Token::Sigma) => {
2803 self.advance();
2805 self.expect(Token::LBrace)?;
2806 let mut fields = Vec::new();
2807 while !self.check(&Token::RBrace) && !self.is_eof() {
2808 while matches!(
2810 self.current_token(),
2811 Some(Token::DocComment(_))
2812 | Some(
2813 Token::LineComment(_)
2814 | Token::TildeComment(_)
2815 | Token::BlockComment(_)
2816 )
2817 | Some(Token::Hash)
2818 ) {
2819 if self.check(&Token::Hash) {
2820 self.advance();
2822 if self.consume_if(&Token::LBracket) {
2823 let mut depth = 1;
2824 while depth > 0 && !self.is_eof() {
2825 match self.current_token() {
2826 Some(Token::LBracket) => depth += 1,
2827 Some(Token::RBracket) => depth -= 1,
2828 _ => {}
2829 }
2830 self.advance();
2831 }
2832 }
2833 } else {
2834 self.advance();
2835 }
2836 }
2837 if self.check(&Token::RBrace) {
2838 break;
2839 }
2840 let visibility = self.parse_visibility()?;
2842 let name = self.parse_ident()?;
2843 self.expect(Token::Colon)?;
2844 let ty = self.parse_type()?;
2845 fields.push(FieldDef {
2846 visibility,
2847 name,
2848 ty,
2849 default: None,
2850 });
2851 if !self.consume_if(&Token::Comma) {
2852 break;
2853 }
2854 }
2855 self.expect(Token::RBrace)?;
2856 Ok(TypeExpr::InlineStruct { fields })
2857 }
2858 Some(Token::Enum) => {
2859 self.advance();
2861 self.expect(Token::LBrace)?;
2862 let mut variants = Vec::new();
2863 while !self.check(&Token::RBrace) && !self.is_eof() {
2864 while matches!(
2866 self.current_token(),
2867 Some(Token::DocComment(_))
2868 | Some(
2869 Token::LineComment(_)
2870 | Token::TildeComment(_)
2871 | Token::BlockComment(_)
2872 )
2873 ) {
2874 self.advance();
2875 }
2876 if self.check(&Token::RBrace) {
2877 break;
2878 }
2879 let name = self.parse_ident()?;
2881 let fields = if self.check(&Token::LParen) {
2883 self.advance();
2884 let mut types = Vec::new();
2885 while !self.check(&Token::RParen) && !self.is_eof() {
2886 types.push(self.parse_type()?);
2887 if !self.consume_if(&Token::Comma) {
2888 break;
2889 }
2890 }
2891 self.expect(Token::RParen)?;
2892 StructFields::Tuple(types)
2893 } else if self.check(&Token::LBrace) {
2894 self.advance();
2895 let mut fields = Vec::new();
2896 while !self.check(&Token::RBrace) && !self.is_eof() {
2897 let name = self.parse_ident()?;
2898 self.expect(Token::Colon)?;
2899 let ty = self.parse_type()?;
2900 fields.push(FieldDef {
2901 visibility: Visibility::Private,
2902 name,
2903 ty,
2904 default: None,
2905 });
2906 if !self.consume_if(&Token::Comma) {
2907 break;
2908 }
2909 }
2910 self.expect(Token::RBrace)?;
2911 StructFields::Named(fields)
2912 } else {
2913 StructFields::Unit
2914 };
2915 let discriminant = if self.consume_if(&Token::Eq) {
2917 Some(self.parse_expr()?)
2918 } else {
2919 None
2920 };
2921 variants.push(EnumVariant {
2922 name,
2923 fields,
2924 discriminant,
2925 });
2926 if !self.consume_if(&Token::Comma) {
2927 break;
2928 }
2929 }
2930 self.expect(Token::RBrace)?;
2931 Ok(TypeExpr::InlineEnum { variants })
2932 }
2933 Some(Token::Crate) | Some(Token::SelfLower) | Some(Token::Xi) | Some(Token::Super) | Some(Token::IntensityUp) => {
2935 let keyword = self.current_token().cloned();
2936 let span = self.current_span();
2937 self.advance();
2938
2939 let keyword_name = match keyword {
2941 Some(Token::Crate) => "crate",
2942 Some(Token::SelfLower) | Some(Token::Xi) => "self", Some(Token::Super) | Some(Token::IntensityUp) => "super", _ => unreachable!(),
2945 };
2946 let first_segment = PathSegment {
2947 ident: Ident {
2948 name: keyword_name.to_string(),
2949 evidentiality: None,
2950 affect: None,
2951 span,
2952 },
2953 generics: None,
2954 };
2955
2956 let mut segments = vec![first_segment];
2957
2958 while self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
2960 if self.check(&Token::Lt) {
2962 self.advance();
2963 let types = self.parse_type_list()?;
2964 self.expect_gt()?;
2965 if let Some(last) = segments.last_mut() {
2966 last.generics = Some(types);
2967 }
2968 continue;
2969 }
2970 segments.push(self.parse_path_segment()?);
2971 }
2972 Ok(TypeExpr::Path(TypePath { segments }))
2973 }
2974 _ => {
2975 let path = self.parse_type_path()?;
2976 Ok(TypeExpr::Path(path))
2977 }
2978 }
2979 }
2980
2981 fn parse_type_path(&mut self) -> ParseResult<TypePath> {
2982 let mut segments = Vec::new();
2983 segments.push(self.parse_path_segment()?);
2984
2985 while !self.pending_gt.is_some()
2989 && (self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot))
2990 {
2991 if self.check(&Token::Lt) {
2993 let was_in_condition = self.in_condition;
2996 self.in_condition = false;
2997 self.advance(); let types = self.parse_type_list()?;
2999 self.expect_gt()?;
3000 self.in_condition = was_in_condition;
3001 if let Some(last) = segments.last_mut() {
3003 last.generics = Some(types);
3004 }
3005 continue;
3008 }
3009 segments.push(self.parse_path_segment()?);
3010 }
3011
3012 Ok(TypePath { segments })
3013 }
3014
3015 fn parse_path_segment(&mut self) -> ParseResult<PathSegment> {
3016 let ident = if let Some(Token::IntLit(idx)) = self.current_token().cloned() {
3018 let span = self.current_span();
3019 self.advance();
3020 Ident {
3021 name: idx,
3022 evidentiality: None,
3023 affect: None,
3024 span,
3025 }
3026 } else {
3027 self.parse_ident()?
3028 };
3029
3030 let is_fn_trait = matches!(ident.name.as_str(), "Fn" | "FnMut" | "FnOnce");
3033 if is_fn_trait && self.check(&Token::LParen) {
3034 self.advance(); let param_types = self.parse_type_list()?;
3036 self.expect(Token::RParen)?;
3037 let return_type = if self.consume_if(&Token::Arrow) {
3039 Some(self.parse_type()?)
3040 } else {
3041 None
3042 };
3043 let mut generics = vec![TypeExpr::Tuple(param_types)];
3046 if let Some(ret) = return_type {
3047 generics.push(ret);
3048 }
3049 return Ok(PathSegment {
3050 ident,
3051 generics: Some(generics),
3052 });
3053 }
3054
3055 let generics = if !self.is_in_condition()
3059 && self.check(&Token::Lt)
3060 && self.peek_looks_like_generic_arg()
3061 {
3062 self.advance(); let types = self.parse_type_list()?;
3064 self.expect_gt()?;
3066 Some(types)
3067 } else if self.check(&Token::LBracket) && self.peek_looks_like_bracket_generic() {
3068 self.advance(); let types = self.parse_type_list()?;
3071 self.expect(Token::RBracket)?;
3072 Some(types)
3073 } else {
3074 None
3075 };
3076
3077 Ok(PathSegment { ident, generics })
3078 }
3079
3080 fn peek_looks_like_bracket_generic(&mut self) -> bool {
3082 match self.peek_next().cloned() {
3085 Some(Token::Ident(name)) => {
3087 let is_type_name = name.chars().next().map_or(false, |c| c.is_uppercase());
3090 match self.peek_n(1) {
3091 Some(Token::RBracket) => is_type_name,
3094 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,
3100 Some(Token::Bang) => true,
3101 Some(Token::Tilde) => true,
3102 Some(Token::Lozenge) => true,
3103 Some(Token::Interrobang) => true,
3104 Some(Token::Eq) => true,
3106 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, }
3115 }
3116 Some(Token::SelfUpper) => true, Some(Token::Amp) => true, Some(Token::Star) => false,
3120 Some(Token::Fn) => true, Some(Token::LParen) => {
3122 match self.peek_n(1) {
3128 Some(Token::RParen) => true, Some(Token::Ident(name)) => {
3130 if name.chars().next().map_or(false, |c| c.is_uppercase()) {
3133 true } else {
3135 match self.peek_n(2) {
3137 Some(Token::As) | Some(Token::Arrow) => 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, }
3149 }
3150 }
3151 _ => false, }
3153 }
3154 Some(Token::Dyn) => true, Some(Token::Impl) => true, Some(Token::Crate) => true, Some(Token::Super) | Some(Token::IntensityUp) => true, Some(Token::IntLit(_)) => false,
3161 Some(Token::FloatLit(_)) => false,
3162 Some(Token::SelfLower) | Some(Token::Xi) => false, _ => false,
3166 }
3167 }
3168
3169 fn peek_looks_like_generic_arg(&mut self) -> bool {
3174 match self.peek_next().cloned() {
3176 Some(Token::Amp) => true, Some(Token::Star) => {
3179 match self.peek_n(1) {
3183 Some(Token::Const) => true, Some(Token::Mut) | Some(Token::Delta) => true, _ => false, }
3187 }
3188 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) | Some(Token::IntensityUp) => true, Some(Token::Lifetime(_)) => true, Some(Token::Underscore) => true, Some(Token::Bang) => true,
3202 Some(Token::Question) => true,
3203 Some(Token::Tilde) => true,
3204 Some(Token::Interrobang) => true,
3205 Some(Token::Ident(name)) => {
3207 let is_type_like = name.chars().next().map_or(false, |c| c.is_uppercase())
3210 || matches!(
3211 name.as_str(),
3212 "u8" | "u16"
3214 | "u32"
3215 | "u64"
3216 | "u128"
3217 | "usize"
3218 | "i8"
3219 | "i16"
3220 | "i32"
3221 | "i64"
3222 | "i128"
3223 | "isize"
3224 | "f32"
3225 | "f64"
3226 | "bool"
3227 | "char"
3228 | "str"
3229 );
3230 match self.peek_n(1) {
3231 Some(Token::Gt) => true,
3233 Some(Token::Shr) => true, Some(Token::Comma) => is_type_like,
3237 Some(Token::ColonColon) => true, Some(Token::MiddleDot) => true, Some(Token::Lt) => true, Some(Token::LBracket) => true, Some(Token::Question) => true,
3243 Some(Token::Bang) => true,
3244 Some(Token::Tilde) => true,
3245 Some(Token::Lozenge) => true,
3246 Some(Token::Interrobang) => true,
3247 Some(Token::Eq) => true,
3249 Some(Token::Colon) => true,
3251 _ => false,
3252 }
3253 }
3254 Some(Token::SelfLower) | Some(Token::Xi) => false, Some(Token::IntLit(_)) => {
3259 match self.peek_n(1) {
3260 Some(Token::Comma) => true, Some(Token::Gt) => true, Some(Token::Shr) => true, _ => false, }
3265 }
3266 Some(Token::FloatLit(_)) => false,
3267 Some(Token::StringLit(_)) => false,
3268 Some(Token::True) | Some(Token::False) | Some(Token::Top) | Some(Token::Bottom) => false, Some(Token::Null) => false,
3270 _ => false, }
3272 }
3273
3274 fn peek_looks_like_pipe_op(&mut self) -> bool {
3277 match self.peek_next() {
3278 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::Lozenge) => true, Some(Token::BoxSymbol) => true, Some(Token::Ident(name)) => {
3326 let no_args_pipe_methods = [
3328 "collect", "observe", "len", "first", "last", "reverse",
3329 "iter", "into_iter", "enumerate", "sum", "product",
3330 "min", "max", "count", "flatten", "unique",
3331 "H", "X", "Y", "Z", "S", "T", "measure",
3333 "H_all", "measure_all",
3334 "relu", "softmax", "reshape", "backward",
3336 ];
3337 if no_args_pipe_methods.contains(&name.as_str()) {
3338 return true;
3339 }
3340 let after_ident = self.peek_n(1);
3344 match after_ident {
3345 Some(Token::LParen) | Some(Token::LBrace) => true,
3346 Some(Token::Bang)
3348 | Some(Token::Question)
3349 | Some(Token::Tilde)
3350 | Some(Token::Lozenge) => {
3351 matches!(self.peek_n(2), Some(Token::LParen) | Some(Token::LBrace))
3352 }
3353 _ => false,
3354 }
3355 }
3356 Some(Token::Amp) => true,
3358 Some(Token::LBrace) => true,
3360 _ => false,
3362 }
3363 }
3364
3365 fn parse_type_list(&mut self) -> ParseResult<Vec<TypeExpr>> {
3366 let mut types = Vec::new();
3367 if !self.check(&Token::RParen)
3369 && !self.check(&Token::RBracket)
3370 && !self.check(&Token::Gt)
3371 && !self.check(&Token::Shr)
3372 && self.pending_gt.is_none()
3373 {
3374 types.push(self.parse_type_or_lifetime()?);
3376 while !self.pending_gt.is_some()
3379 && !self.check(&Token::Gt)
3380 && !self.check(&Token::Shr)
3381 && self.consume_if(&Token::Comma)
3382 {
3383 if self.check(&Token::RParen)
3385 || self.check(&Token::RBracket)
3386 || self.check(&Token::Gt)
3387 || self.check(&Token::Shr)
3388 {
3389 break;
3390 }
3391 types.push(self.parse_type_or_lifetime()?);
3392 }
3393 }
3394 Ok(types)
3395 }
3396
3397 fn parse_attributed_type_list(&mut self) -> ParseResult<Vec<TypeExpr>> {
3400 let mut types = Vec::new();
3401 if !self.check(&Token::RParen) {
3402 loop {
3403 while self.check(&Token::Hash) {
3405 self.advance();
3406 self.consume_if(&Token::Bang); if self.consume_if(&Token::LBracket) {
3408 let mut depth = 1;
3409 while depth > 0 && !self.is_eof() {
3410 match self.current_token() {
3411 Some(Token::LBracket) => depth += 1,
3412 Some(Token::RBracket) => depth -= 1,
3413 _ => {}
3414 }
3415 self.advance();
3416 }
3417 }
3418 }
3419 types.push(self.parse_type()?);
3421 if !self.consume_if(&Token::Comma) {
3422 break;
3423 }
3424 }
3425 }
3426 Ok(types)
3427 }
3428
3429 fn parse_tuple_struct_fields(&mut self) -> ParseResult<Vec<TypeExpr>> {
3432 let mut types = Vec::new();
3433 if !self.check(&Token::RParen) {
3434 loop {
3435 if self.check(&Token::Pub) {
3437 self.advance();
3438 if self.check(&Token::LParen) {
3440 self.advance();
3441 let mut depth = 1;
3443 while depth > 0 {
3444 match self.current_token() {
3445 Some(Token::LParen) => depth += 1,
3446 Some(Token::RParen) => depth -= 1,
3447 None => break,
3448 _ => {}
3449 }
3450 self.advance();
3451 }
3452 }
3453 }
3454 types.push(self.parse_type()?);
3456 if !self.consume_if(&Token::Comma) {
3457 break;
3458 }
3459 if self.check(&Token::RParen) {
3461 break;
3462 }
3463 }
3464 }
3465 Ok(types)
3466 }
3467
3468 fn parse_type_bounds(&mut self) -> ParseResult<Vec<TypeExpr>> {
3469 let mut bounds = Vec::new();
3470
3471 if self.check(&Token::Comma) || self.check(&Token::LBrace) || self.check(&Token::Semi) {
3473 return Ok(bounds);
3474 }
3475
3476 bounds.push(self.parse_type_or_lifetime()?);
3477 while self.consume_if(&Token::Plus) {
3478 bounds.push(self.parse_type_or_lifetime()?);
3479 }
3480 Ok(bounds)
3481 }
3482
3483 fn parse_type_or_lifetime(&mut self) -> ParseResult<TypeExpr> {
3487 if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
3488 self.advance();
3489 Ok(TypeExpr::Lifetime(name))
3490 } else if self.check(&Token::For) {
3491 self.advance(); self.expect(Token::Lt)?; let mut lifetimes = Vec::new();
3495 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
3496 lifetimes.push(lt);
3497 self.advance();
3498 while self.consume_if(&Token::Comma) {
3499 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
3500 lifetimes.push(lt);
3501 self.advance();
3502 } else {
3503 break;
3504 }
3505 }
3506 }
3507 self.expect_gt()?; let bound = self.parse_type()?;
3509 Ok(TypeExpr::Hrtb {
3510 lifetimes,
3511 bound: Box::new(bound),
3512 })
3513 } else if matches!(self.current_token(), Some(Token::Ident(_)))
3514 && self.peek_next() == Some(&Token::Eq)
3515 {
3516 let name = self.parse_ident()?;
3518 self.expect(Token::Eq)?;
3519 let ty = self.parse_type()?;
3520 Ok(TypeExpr::AssocTypeBinding {
3521 name,
3522 ty: Box::new(ty),
3523 })
3524 } else if matches!(
3525 self.current_token(),
3526 Some(Token::IntLit(_))
3527 | Some(Token::HexLit(_))
3528 | Some(Token::BinaryLit(_))
3529 | Some(Token::OctalLit(_))
3530 ) {
3531 let expr = self.parse_const_expr_simple()?;
3534 Ok(TypeExpr::ConstExpr(Box::new(expr)))
3535 } else if self.check(&Token::LBrace) {
3536 self.advance();
3538 let expr = self.parse_expr()?;
3539 self.expect(Token::RBrace)?;
3540 Ok(TypeExpr::ConstExpr(Box::new(expr)))
3541 } else {
3542 self.parse_type()
3543 }
3544 }
3545
3546 fn parse_array_dim_expr(&mut self) -> ParseResult<Expr> {
3549 if self.check(&Token::LBrace) {
3551 self.advance();
3552 let expr = self.parse_expr()?;
3553 self.expect(Token::RBrace)?;
3554 return Ok(expr);
3555 }
3556 self.parse_const_expr_simple()
3558 }
3559
3560 fn parse_const_expr_simple(&mut self) -> ParseResult<Expr> {
3564 let mut lhs = self.parse_const_expr_primary()?;
3565
3566 loop {
3567 match self.current_token() {
3568 Some(Token::Star) => {
3569 self.advance();
3570 let rhs = self.parse_const_expr_primary()?;
3571 lhs = Expr::Binary {
3572 op: BinOp::Mul,
3573 left: Box::new(lhs),
3574 right: Box::new(rhs),
3575 };
3576 }
3577 Some(Token::Plus) => {
3578 self.advance();
3579 let rhs = self.parse_const_expr_primary()?;
3580 lhs = Expr::Binary {
3581 op: BinOp::Add,
3582 left: Box::new(lhs),
3583 right: Box::new(rhs),
3584 };
3585 }
3586 Some(Token::Minus) => {
3587 self.advance();
3588 let rhs = self.parse_const_expr_primary()?;
3589 lhs = Expr::Binary {
3590 op: BinOp::Sub,
3591 left: Box::new(lhs),
3592 right: Box::new(rhs),
3593 };
3594 }
3595 Some(Token::Slash) => {
3596 self.advance();
3597 let rhs = self.parse_const_expr_primary()?;
3598 lhs = Expr::Binary {
3599 op: BinOp::Div,
3600 left: Box::new(lhs),
3601 right: Box::new(rhs),
3602 };
3603 }
3604 _ => break,
3605 }
3606 }
3607 Ok(lhs)
3608 }
3609
3610 fn parse_const_expr_primary(&mut self) -> ParseResult<Expr> {
3612 match self.current_token().cloned() {
3613 Some(Token::IntLit(_))
3614 | Some(Token::HexLit(_))
3615 | Some(Token::BinaryLit(_))
3616 | Some(Token::OctalLit(_)) => {
3617 let lit = self.parse_literal()?;
3618 Ok(Expr::Literal(lit))
3619 }
3620 Some(Token::Ident(_)) => {
3621 let path = self.parse_type_path()?;
3622 Ok(Expr::Path(path))
3623 }
3624 Some(Token::Underscore) => {
3625 let span = self.current_span();
3627 self.advance();
3628 Ok(Expr::Path(TypePath {
3629 segments: vec![PathSegment {
3630 ident: Ident {
3631 name: "_".to_string(),
3632 evidentiality: None,
3633 affect: None,
3634 span,
3635 },
3636 generics: None,
3637 }],
3638 }))
3639 }
3640 Some(Token::LParen) => {
3641 self.advance();
3642 let expr = self.parse_const_expr_simple()?;
3643 self.expect(Token::RParen)?;
3644 Ok(expr)
3645 }
3646 _ => Err(ParseError::Custom("expected const expression".to_string())),
3647 }
3648 }
3649
3650 pub fn parse_expr(&mut self) -> ParseResult<Expr> {
3653 self.skip_comments();
3655 let lhs = self.parse_expr_bp(0)?;
3656
3657 if self.consume_if(&Token::Eq) {
3659 let value = self.parse_expr()?;
3660 return Ok(Expr::Assign {
3661 target: Box::new(lhs),
3662 value: Box::new(value),
3663 });
3664 }
3665
3666 let compound_op = match self.current_token() {
3669 Some(Token::PlusEq) => Some(BinOp::Add),
3670 Some(Token::MinusEq) => Some(BinOp::Sub),
3671 Some(Token::StarEq) => Some(BinOp::Mul),
3672 Some(Token::SlashEq) => Some(BinOp::Div),
3673 Some(Token::PercentEq) => Some(BinOp::Rem),
3674 Some(Token::ShlEq) => Some(BinOp::Shl),
3675 Some(Token::ShrEq) => Some(BinOp::Shr),
3676 Some(Token::PipeEq) => Some(BinOp::BitOr),
3677 Some(Token::AmpEq) => Some(BinOp::BitAnd),
3678 Some(Token::CaretEq) => Some(BinOp::BitXor),
3679 _ => None,
3680 };
3681
3682 if let Some(op) = compound_op {
3683 self.advance();
3684 let rhs = self.parse_expr()?;
3685 let binary = Expr::Binary {
3687 left: Box::new(lhs.clone()),
3688 op,
3689 right: Box::new(rhs),
3690 };
3691 return Ok(Expr::Assign {
3692 target: Box::new(lhs),
3693 value: Box::new(binary),
3694 });
3695 }
3696
3697 match self.current_token() {
3699 Some(Token::DirectSumEq) => {
3700 self.advance();
3702 let pattern = self.parse_expr()?;
3703 return Ok(Expr::LegionSuperposition {
3704 field: Box::new(lhs),
3705 pattern: Box::new(pattern),
3706 });
3707 }
3708 Some(Token::PartialEq_) => {
3709 self.advance();
3711 let rate = self.parse_expr()?;
3712 return Ok(Expr::LegionDecay {
3713 field: Box::new(lhs),
3714 rate: Box::new(rate),
3715 });
3716 }
3717 Some(Token::InterfereEq) => {
3718 self.advance();
3720 let query = self.parse_expr()?;
3721 return Ok(Expr::LegionInterference {
3722 query: Box::new(query),
3723 field: Box::new(lhs),
3724 });
3725 }
3726 _ => {}
3727 }
3728
3729 Ok(lhs)
3730 }
3731
3732 fn parse_expr_bp(&mut self, min_bp: u8) -> ParseResult<Expr> {
3733 let mut lhs = self.parse_prefix_expr()?;
3734
3735 loop {
3736 self.skip_comments();
3741
3742 if self.check(&Token::Pipe) && self.peek_looks_like_pipe_op() {
3745 lhs = self.parse_pipe_chain(lhs)?;
3746 lhs = self.parse_postfix_after_pipe(lhs)?;
3748 continue;
3749 }
3750
3751 let op = match self.current_token() {
3753 Some(Token::Pipe) => BinOp::BitOr,
3755 Some(Token::OrOr) | Some(Token::LogicOr) => BinOp::Or, Some(Token::AndAnd) | Some(Token::LogicAnd) => BinOp::And, Some(Token::EqEq) => BinOp::Eq,
3758 Some(Token::NotEq) => BinOp::Ne,
3759 Some(Token::Lt) => BinOp::Lt,
3760 Some(Token::LtEq) => BinOp::Le,
3761 Some(Token::Gt) => BinOp::Gt,
3762 Some(Token::GtEq) => BinOp::Ge,
3763 Some(Token::Plus) => BinOp::Add,
3764 Some(Token::Minus) => BinOp::Sub,
3765 Some(Token::Star) => BinOp::Mul,
3766 Some(Token::Slash) => BinOp::Div,
3767 Some(Token::Percent) => BinOp::Rem,
3768 Some(Token::StarStar) => BinOp::Pow,
3769 Some(Token::Amp) => BinOp::BitAnd,
3770 Some(Token::Caret) => BinOp::BitXor,
3771 Some(Token::Shl) => BinOp::Shl,
3772 Some(Token::Shr) => BinOp::Shr,
3773 Some(Token::PlusPlus) => BinOp::Concat,
3774 Some(Token::At) => BinOp::MatMul,
3776 Some(Token::BitwiseAndSymbol) => BinOp::BitAnd, Some(Token::BitwiseOrSymbol) => BinOp::BitOr, Some(Token::CircledDot) => BinOp::Hadamard, Some(Token::Tensor) => BinOp::TensorProd, Some(Token::Gpu) => BinOp::Convolve, Some(Token::Interfere)
3786 | Some(Token::Distribute)
3787 | Some(Token::Broadcast)
3788 | Some(Token::Gather)
3789 | Some(Token::Consensus)
3790 | Some(Token::ConfidenceHigh) => {
3791 lhs = self.parse_legion_operator(lhs)?;
3793 continue;
3794 }
3795 _ => {
3796 if min_bp == 0 && (self.check(&Token::DotDot) || self.check(&Token::DotDotEq)) {
3802 let inclusive = self.consume_if(&Token::DotDotEq);
3803 if !inclusive {
3804 self.advance(); }
3806 let end = if self.check(&Token::Semi)
3808 || self.check(&Token::RBrace)
3809 || self.check(&Token::Comma)
3810 || self.check(&Token::RParen)
3811 || self.check(&Token::RBracket)
3812 || self.check(&Token::LBrace)
3813 {
3814 None
3815 } else {
3816 Some(Box::new(self.parse_expr_bp(0)?))
3817 };
3818 lhs = Expr::Range {
3819 start: Some(Box::new(lhs)),
3820 end,
3821 inclusive,
3822 };
3823 continue;
3824 }
3825 break;
3826 }
3827 };
3828
3829 let (l_bp, r_bp) = infix_binding_power(op);
3830 if l_bp < min_bp {
3831 break;
3832 }
3833
3834 self.advance();
3835 self.skip_comments();
3839 let rhs = self.parse_expr_bp(r_bp)?;
3840
3841 lhs = Expr::Binary {
3842 left: Box::new(lhs),
3843 op,
3844 right: Box::new(rhs),
3845 };
3846 }
3847
3848 Ok(lhs)
3849 }
3850
3851 fn parse_prefix_expr(&mut self) -> ParseResult<Expr> {
3852 match self.current_token() {
3853 Some(Token::Minus) => {
3854 self.advance();
3855 let expr = self.parse_prefix_expr()?;
3856 Ok(Expr::Unary {
3857 op: UnaryOp::Neg,
3858 expr: Box::new(expr),
3859 })
3860 }
3861 Some(Token::Bang) | Some(Token::LogicNot) => {
3862 self.advance();
3863 let expr = self.parse_prefix_expr()?;
3864 Ok(Expr::Unary {
3865 op: UnaryOp::Not,
3866 expr: Box::new(expr),
3867 })
3868 }
3869 Some(Token::Star) => {
3870 self.advance();
3871 let expr = self.parse_prefix_expr()?;
3872 Ok(Expr::Unary {
3873 op: UnaryOp::Deref,
3874 expr: Box::new(expr),
3875 })
3876 }
3877 Some(Token::StarStar) => {
3879 self.advance();
3880 let inner = self.parse_prefix_expr()?;
3881 let first_deref = Expr::Unary {
3883 op: UnaryOp::Deref,
3884 expr: Box::new(inner),
3885 };
3886 Ok(Expr::Unary {
3887 op: UnaryOp::Deref,
3888 expr: Box::new(first_deref),
3889 })
3890 }
3891 Some(Token::Amp) => {
3892 self.advance();
3893 let op = if self.consume_if_mut() {
3894 UnaryOp::RefMut
3895 } else {
3896 UnaryOp::Ref
3897 };
3898 let expr = self.parse_prefix_expr()?;
3899 Ok(Expr::Unary {
3900 op,
3901 expr: Box::new(expr),
3902 })
3903 }
3904 Some(Token::Question) => {
3906 self.advance();
3907 let expr = self.parse_prefix_expr()?;
3908 Ok(Expr::Evidential {
3909 expr: Box::new(expr),
3910 evidentiality: Evidentiality::Uncertain,
3911 })
3912 }
3913 Some(Token::Tilde) => {
3914 self.advance();
3915 let expr = self.parse_prefix_expr()?;
3916 Ok(Expr::Evidential {
3917 expr: Box::new(expr),
3918 evidentiality: Evidentiality::Reported,
3919 })
3920 }
3921 Some(Token::Interrobang) => {
3922 self.advance();
3923 let expr = self.parse_prefix_expr()?;
3924 Ok(Expr::Evidential {
3925 expr: Box::new(expr),
3926 evidentiality: Evidentiality::Paradox,
3927 })
3928 }
3929 Some(Token::Move) => {
3931 self.advance();
3932 self.parse_pipe_closure_with_move(true)
3933 }
3934 Some(Token::Pipe) | Some(Token::OrOr) | Some(Token::LogicOr) => self.parse_pipe_closure_with_move(false),
3936 _ => self.parse_postfix_expr(),
3937 }
3938 }
3939
3940 fn parse_pipe_closure_with_move(&mut self, is_move: bool) -> ParseResult<Expr> {
3942 let params = if self.consume_if(&Token::OrOr) || self.consume_if(&Token::LogicOr) {
3943 Vec::new()
3945 } else {
3946 self.expect(Token::Pipe)?;
3948 let mut params = Vec::new();
3949 if !self.check(&Token::Pipe) {
3950 loop {
3951 let pattern = self.parse_pattern()?;
3953 let ty = if self.consume_if(&Token::Colon) {
3954 Some(self.parse_type()?)
3955 } else {
3956 None
3957 };
3958 params.push(ClosureParam { pattern, ty });
3959 if !self.consume_if(&Token::Comma) {
3960 break;
3961 }
3962 if self.check(&Token::Pipe) {
3963 break;
3964 }
3965 }
3966 }
3967 self.expect(Token::Pipe)?;
3968 params
3969 };
3970
3971 let return_type = if self.consume_if(&Token::Arrow) {
3973 Some(self.parse_type()?)
3974 } else {
3975 None
3976 };
3977
3978 let body = self.parse_expr()?;
3979 Ok(Expr::Closure {
3980 params,
3981 return_type,
3982 body: Box::new(body),
3983 is_move,
3984 })
3985 }
3986
3987 fn parse_macro_tokens(&mut self) -> ParseResult<String> {
3989 let (open, close) = match self.current_token() {
3991 Some(Token::LParen) => (Token::LParen, Token::RParen),
3992 Some(Token::LBracket) => (Token::LBracket, Token::RBracket),
3993 Some(Token::LBrace) => (Token::LBrace, Token::RBrace),
3994 _ => {
3995 return Err(ParseError::Custom(
3996 "expected '(', '[', or '{' for macro invocation".to_string(),
3997 ))
3998 }
3999 };
4000
4001 self.advance(); let mut tokens = String::new();
4003 let mut depth = 1;
4004
4005 while depth > 0 && !self.is_eof() {
4006 if self.check(&open) {
4007 depth += 1;
4008 } else if self.check(&close) {
4009 depth -= 1;
4010 if depth == 0 {
4011 break;
4012 }
4013 }
4014
4015 if let Some((token, span)) = &self.current {
4017 let token_str = match token {
4019 Token::Ident(s) => s.clone(),
4020 Token::IntLit(s) => s.clone(),
4021 Token::FloatLit(s) => s.clone(),
4022 Token::StringLit(s) => {
4023 format!("\"{}\"", s.replace('\\', "\\\\").replace('"', "\\\""))
4024 }
4025 Token::CharLit(c) => format!("'{}'", c),
4026 Token::Comma => ",".to_string(),
4027 Token::Colon => ":".to_string(),
4028 Token::ColonColon => "::".to_string(),
4029 Token::Dot => ".".to_string(),
4030 Token::DotDot => "..".to_string(),
4031 Token::Semi => ";".to_string(),
4032 Token::LParen => "(".to_string(),
4033 Token::RParen => ")".to_string(),
4034 Token::LBrace => "{".to_string(),
4035 Token::RBrace => "}".to_string(),
4036 Token::LBracket => "[".to_string(),
4037 Token::RBracket => "]".to_string(),
4038 Token::Lt => "<".to_string(),
4039 Token::Gt => ">".to_string(),
4040 Token::Eq => "=".to_string(),
4041 Token::FatArrow => "=>".to_string(),
4042 Token::Bang => "!".to_string(),
4043 Token::Question => "?".to_string(),
4044 Token::Amp => "&".to_string(),
4045 Token::Pipe => "|".to_string(),
4046 Token::Underscore => "_".to_string(),
4047 Token::Plus => "+".to_string(),
4048 Token::Minus => "-".to_string(),
4049 Token::Star => "*".to_string(),
4050 Token::Slash => "/".to_string(),
4051 Token::Percent => "%".to_string(),
4052 Token::EqEq => "==".to_string(),
4053 Token::NotEq => "!=".to_string(),
4054 Token::LtEq => "<=".to_string(),
4055 Token::GtEq => ">=".to_string(),
4056 Token::AndAnd => "&&".to_string(),
4057 Token::OrOr => "||".to_string(),
4058 Token::Arrow => "->".to_string(),
4059 Token::Hash => "#".to_string(),
4060 Token::At => "@".to_string(),
4061 Token::Tilde => "~".to_string(),
4062 Token::SelfLower => "self".to_string(),
4064 Token::SelfUpper => "Self".to_string(),
4065 Token::Let => "let".to_string(),
4066 Token::Mut => "mut".to_string(),
4067 Token::Fn => "fn".to_string(),
4068 Token::If => "if".to_string(),
4069 Token::Else => "else".to_string(),
4070 Token::Match => "match".to_string(),
4071 Token::For => "for".to_string(),
4072 Token::While => "while".to_string(),
4073 Token::Loop => "loop".to_string(),
4074 Token::Break => "break".to_string(),
4075 Token::Continue => "continue".to_string(),
4076 Token::Return => "return".to_string(),
4077 Token::Struct => "struct".to_string(),
4078 Token::Enum => "enum".to_string(),
4079 Token::Impl => "impl".to_string(),
4080 Token::Trait => "trait".to_string(),
4081 Token::Type => "type".to_string(),
4082 Token::Pub => "pub".to_string(),
4083 Token::Mod => "mod".to_string(),
4084 Token::Use => "use".to_string(),
4085 Token::As => "as".to_string(),
4086 Token::In => "in".to_string(),
4087 Token::True => "true".to_string(),
4088 Token::False => "false".to_string(),
4089 Token::Null => "null".to_string(),
4090 Token::Const => "const".to_string(),
4091 Token::Static => "static".to_string(),
4092 Token::Async => "async".to_string(),
4093 Token::Await => "await".to_string(),
4094 Token::Move => "move".to_string(),
4095 Token::Ref => "ref".to_string(),
4096 Token::Where => "where".to_string(),
4097 Token::Dyn => "dyn".to_string(),
4098 Token::Super => "super".to_string(),
4099 Token::Crate => "crate".to_string(),
4100 _ => format!("{:?}", token),
4101 };
4102 let suppress_space_before = matches!(
4104 token,
4105 Token::Dot
4106 | Token::ColonColon
4107 | Token::LParen
4108 | Token::LBracket
4109 | Token::LBrace
4110 | Token::RParen
4111 | Token::RBracket
4112 | Token::RBrace
4113 | Token::Comma
4114 | Token::Semi
4115 );
4116 if !tokens.is_empty()
4117 && !suppress_space_before
4118 && !tokens.ends_with('.')
4119 && !tokens.ends_with("::")
4120 && !tokens.ends_with('(')
4121 && !tokens.ends_with('[')
4122 && !tokens.ends_with('{')
4123 {
4124 tokens.push(' ');
4125 }
4126 tokens.push_str(&token_str);
4127 }
4128 self.advance();
4129 }
4130
4131 self.expect(close)?;
4132 Ok(tokens)
4133 }
4134
4135 fn is_non_callable_expr(expr: &Expr) -> bool {
4139 matches!(
4140 expr,
4141 Expr::If { .. }
4142 | Expr::While { .. }
4143 | Expr::Match { .. }
4144 | Expr::Loop { .. }
4145 | Expr::For { .. }
4146 | Expr::Block(_)
4147 )
4148 }
4149
4150 fn parse_postfix_expr(&mut self) -> ParseResult<Expr> {
4151 let mut expr = self.parse_primary_expr()?;
4152
4153 loop {
4154 self.skip_comments();
4159
4160 match self.current_token() {
4161 Some(Token::LParen) => {
4162 if Self::is_non_callable_expr(&expr) {
4165 break;
4166 }
4167 self.advance();
4168 let args = self.parse_expr_list()?;
4169 self.expect(Token::RParen)?;
4170 expr = Expr::Call {
4171 func: Box::new(expr),
4172 args,
4173 };
4174 }
4175 Some(Token::LBracket) => {
4176 self.advance();
4177 let first = self.parse_expr()?;
4179 if self.consume_if(&Token::Comma) {
4180 let mut indices = vec![first];
4182 while !self.check(&Token::RBracket) && !self.is_eof() {
4183 indices.push(self.parse_expr()?);
4184 if !self.consume_if(&Token::Comma) {
4185 break;
4186 }
4187 }
4188 self.expect(Token::RBracket)?;
4189 expr = Expr::Index {
4191 expr: Box::new(expr),
4192 index: Box::new(Expr::Tuple(indices)),
4193 };
4194 } else {
4195 self.expect(Token::RBracket)?;
4196 expr = Expr::Index {
4197 expr: Box::new(expr),
4198 index: Box::new(first),
4199 };
4200 }
4201 }
4202 Some(Token::Dot) => {
4203 self.advance();
4204 if self.check(&Token::Hourglass) {
4206 self.advance();
4207 let evidentiality = self.parse_evidentiality_opt();
4208 expr = Expr::Await {
4209 expr: Box::new(expr),
4210 evidentiality,
4211 };
4212 continue;
4213 }
4214 let field = if let Some(Token::IntLit(idx)) = self.current_token() {
4216 let idx = idx.clone();
4217 let span = self.current_span();
4218 self.advance();
4219 Ident {
4220 name: idx,
4221 evidentiality: None,
4222 affect: None,
4223 span,
4224 }
4225 } else {
4226 self.parse_ident()?
4227 };
4228 if self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
4230 self.expect(Token::Lt)?;
4232 let was_in_condition = self.in_condition;
4234 self.in_condition = false;
4235 let type_args = self.parse_type_list()?;
4236 self.expect_gt()?;
4237 self.in_condition = was_in_condition;
4238 self.expect(Token::LParen)?;
4239 let args = self.parse_expr_list()?;
4240 self.expect(Token::RParen)?;
4241 expr = Expr::MethodCall {
4242 receiver: Box::new(expr),
4243 method: field,
4244 type_args: Some(type_args),
4245 args,
4246 };
4247 } else if self.check(&Token::LParen) {
4248 self.advance();
4249 let args = self.parse_expr_list()?;
4250 self.expect(Token::RParen)?;
4251 expr = Expr::MethodCall {
4252 receiver: Box::new(expr),
4253 method: field,
4254 type_args: None,
4255 args,
4256 };
4257 } else {
4258 while self.check(&Token::Tilde) || self.check(&Token::Lozenge) {
4261 self.advance();
4262 }
4263 expr = Expr::Field {
4264 expr: Box::new(expr),
4265 field,
4266 };
4267 }
4268 }
4269 Some(Token::Question) => {
4270 if self.peek_next() == Some(&Token::LBrace) && !self.is_in_condition() {
4273 if let Expr::Path(ref path) = expr {
4274 let path = path.clone();
4275 self.advance(); self.advance(); let (fields, rest) = self.parse_struct_fields()?;
4278 self.expect(Token::RBrace)?;
4279 expr = Expr::Struct { path, fields, rest };
4280 continue;
4281 }
4282 }
4283 self.advance();
4285 expr = Expr::Try(Box::new(expr));
4286 }
4287 Some(Token::As) | Some(Token::Arrow) => {
4289 self.advance();
4290 let ty = self.parse_type()?;
4291 expr = Expr::Cast {
4292 expr: Box::new(expr),
4293 ty,
4294 };
4295 }
4296 Some(Token::Bang) => {
4297 if let Expr::Path(path) = &expr {
4299 let peeked = self.peek_next();
4300 let is_macro = match peeked {
4302 Some(Token::LParen) | Some(Token::LBracket) | Some(Token::LBrace) => {
4303 true
4304 }
4305 _ => false,
4306 };
4307 if is_macro {
4308 self.advance(); let tokens = self.parse_macro_tokens()?;
4310 expr = Expr::Macro {
4311 path: path.clone(),
4312 tokens,
4313 };
4314 continue;
4315 }
4316 }
4317 if let Some(ev) = self.parse_evidentiality_opt() {
4319 expr = Expr::Evidential {
4320 expr: Box::new(expr),
4321 evidentiality: ev,
4322 };
4323 } else {
4324 break;
4325 }
4326 }
4327 Some(Token::Tilde) | Some(Token::Interrobang) | Some(Token::Lozenge) => {
4328 if let Some(ev) = self.parse_evidentiality_opt() {
4329 if self.check(&Token::LBrace) && !self.is_in_condition() {
4332 if let Expr::Path(ref path) = expr {
4333 let path = path.clone();
4334 self.advance(); let (fields, rest) = self.parse_struct_fields()?;
4336 self.expect(Token::RBrace)?;
4337 expr = Expr::Struct { path, fields, rest };
4338 continue;
4339 }
4340 }
4341 expr = Expr::Evidential {
4343 expr: Box::new(expr),
4344 evidentiality: ev,
4345 };
4346 } else {
4347 break;
4348 }
4349 }
4350 Some(Token::ColonColon) => {
4351 self.advance(); let method = self.parse_ident()?;
4354 let type_args = if self.check(&Token::ColonColon) {
4356 self.advance();
4357 self.expect(Token::Lt)?;
4358 let types = self.parse_type_list()?;
4359 self.expect_gt()?;
4360 Some(types)
4361 } else {
4362 None
4363 };
4364 if self.check(&Token::LParen) {
4365 self.advance();
4366 let args = self.parse_expr_list()?;
4367 self.expect(Token::RParen)?;
4368 expr = Expr::MethodCall {
4370 receiver: Box::new(expr),
4371 method,
4372 type_args,
4373 args,
4374 };
4375 } else {
4376 expr = Expr::Field {
4378 expr: Box::new(expr),
4379 field: method,
4380 };
4381 }
4382 }
4383 Some(Token::Hourglass) => {
4384 self.advance();
4385 let evidentiality = match self.current_token() {
4387 Some(Token::Question) => {
4388 self.advance();
4389 Some(Evidentiality::Uncertain)
4390 }
4391 Some(Token::Bang) => {
4392 self.advance();
4393 Some(Evidentiality::Known)
4394 }
4395 Some(Token::Tilde) => {
4396 self.advance();
4397 Some(Evidentiality::Reported)
4398 }
4399 Some(Token::Lozenge) => {
4400 self.advance();
4401 Some(Evidentiality::Predicted)
4402 }
4403 Some(Token::Interrobang) => {
4404 self.advance();
4405 Some(Evidentiality::Paradox)
4406 }
4407 _ => None,
4408 };
4409 expr = Expr::Await {
4410 expr: Box::new(expr),
4411 evidentiality,
4412 };
4413 }
4414 Some(Token::MiddleDot) => {
4417 let first_segment = self.expr_to_incorporation_segment(expr.clone())?;
4419 let mut segments = vec![first_segment];
4420
4421 while self.consume_if(&Token::MiddleDot) {
4422 let name = if let Some(Token::IntLit(idx)) = self.current_token().cloned() {
4424 let span = self.current_span();
4425 self.advance();
4426 Ident {
4427 name: idx,
4428 evidentiality: None,
4429 affect: None,
4430 span,
4431 }
4432 } else {
4433 self.parse_ident()?
4434 };
4435 if self.check(&Token::LBracket) && self.peek_looks_like_bracket_generic() {
4437 self.advance(); let _generics = self.parse_type_list()?;
4439 self.expect(Token::RBracket)?;
4440 }
4442 if self.check(&Token::Lt) && self.peek_looks_like_generic_arg() {
4444 self.advance(); let _generics = self.parse_type_list()?;
4446 self.expect_gt()?;
4447 }
4448 let args = if self.check(&Token::LParen) {
4449 self.advance();
4450 let args = self.parse_expr_list()?;
4451 self.expect(Token::RParen)?;
4452 Some(args)
4453 } else {
4454 None
4455 };
4456 segments.push(IncorporationSegment { name, args });
4457 }
4458
4459 expr = Expr::Incorporation { segments };
4460 }
4461 _ => break,
4462 }
4463 }
4464
4465 Ok(expr)
4466 }
4467
4468 fn parse_primary_expr(&mut self) -> ParseResult<Expr> {
4469 match self.current_token().cloned() {
4470 Some(Token::IntLit(s)) => {
4471 self.advance();
4472 Ok(Expr::Literal(Literal::Int {
4473 value: s,
4474 base: NumBase::Decimal,
4475 suffix: None,
4476 }))
4477 }
4478 Some(Token::BinaryLit(s)) => {
4479 self.advance();
4480 Ok(Expr::Literal(Literal::Int {
4481 value: s,
4482 base: NumBase::Binary,
4483 suffix: None,
4484 }))
4485 }
4486 Some(Token::OctalLit(s)) => {
4487 self.advance();
4488 Ok(Expr::Literal(Literal::Int {
4489 value: s,
4490 base: NumBase::Octal,
4491 suffix: None,
4492 }))
4493 }
4494 Some(Token::HexLit(s)) => {
4495 self.advance();
4496 Ok(Expr::Literal(Literal::Int {
4497 value: s,
4498 base: NumBase::Hex,
4499 suffix: None,
4500 }))
4501 }
4502 Some(Token::VigesimalLit(s)) => {
4503 self.advance();
4504 Ok(Expr::Literal(Literal::Int {
4505 value: s,
4506 base: NumBase::Vigesimal,
4507 suffix: None,
4508 }))
4509 }
4510 Some(Token::SexagesimalLit(s)) => {
4511 self.advance();
4512 Ok(Expr::Literal(Literal::Int {
4513 value: s,
4514 base: NumBase::Sexagesimal,
4515 suffix: None,
4516 }))
4517 }
4518 Some(Token::DuodecimalLit(s)) => {
4519 self.advance();
4520 Ok(Expr::Literal(Literal::Int {
4521 value: s,
4522 base: NumBase::Duodecimal,
4523 suffix: None,
4524 }))
4525 }
4526 Some(Token::FloatLit(s)) => {
4527 self.advance();
4528 Ok(Expr::Literal(Literal::Float {
4529 value: s,
4530 suffix: None,
4531 }))
4532 }
4533 Some(Token::StringLit(s)) => {
4534 self.advance();
4535 Ok(Expr::Literal(Literal::String(s)))
4536 }
4537 Some(Token::MultiLineStringLit(s)) => {
4538 self.advance();
4539 Ok(Expr::Literal(Literal::MultiLineString(s)))
4540 }
4541 Some(Token::RawStringLit(s)) | Some(Token::RawStringDelimited(s)) => {
4542 self.advance();
4543 Ok(Expr::Literal(Literal::RawString(s)))
4544 }
4545 Some(Token::DotDot) | Some(Token::DotDotEq) => {
4548 let inclusive = self.consume_if(&Token::DotDotEq);
4549 if !inclusive {
4550 self.advance(); }
4552 let end = if self.check(&Token::RParen)
4554 || self.check(&Token::RBracket)
4555 || self.check(&Token::Comma)
4556 || self.check(&Token::Semi)
4557 || self.check(&Token::RBrace)
4558 {
4559 None
4560 } else {
4561 Some(Box::new(self.parse_expr()?))
4562 };
4563 Ok(Expr::Range {
4564 start: None,
4565 end,
4566 inclusive,
4567 })
4568 }
4569 Some(Token::ByteStringLit(bytes)) => {
4570 self.advance();
4571 Ok(Expr::Literal(Literal::ByteString(bytes)))
4572 }
4573 Some(Token::InterpolatedStringLit(s)) => {
4574 self.advance();
4575 let parts = self.parse_interpolation_parts(&s)?;
4577 Ok(Expr::Literal(Literal::InterpolatedString { parts }))
4578 }
4579 Some(Token::SigilStringSql(s)) => {
4580 self.advance();
4581 Ok(Expr::Literal(Literal::SigilStringSql(s)))
4582 }
4583 Some(Token::SigilStringRoute(s)) => {
4584 self.advance();
4585 Ok(Expr::Literal(Literal::SigilStringRoute(s)))
4586 }
4587 Some(Token::CharLit(c)) => {
4588 self.advance();
4589 Ok(Expr::Literal(Literal::Char(c)))
4590 }
4591 Some(Token::ByteCharLit(b)) => {
4592 self.advance();
4593 Ok(Expr::Literal(Literal::ByteChar(b)))
4594 }
4595 Some(Token::True) | Some(Token::Top) => {
4596 self.advance();
4597 Ok(Expr::Literal(Literal::Bool(true)))
4598 }
4599 Some(Token::False) | Some(Token::Bottom) => {
4600 self.advance();
4601 Ok(Expr::Literal(Literal::Bool(false)))
4602 }
4603 Some(Token::Null) => {
4604 self.advance();
4605 Ok(Expr::Literal(Literal::Null))
4606 }
4607 Some(Token::Empty) => {
4608 self.advance();
4609 Ok(Expr::Literal(Literal::Empty))
4610 }
4611 Some(Token::Infinity) => {
4612 if matches!(self.peek_next(), Some(Token::LBrace)) {
4614 self.advance();
4616 let body = self.parse_block()?;
4617 Ok(Expr::Loop { label: None, body })
4618 } else {
4619 self.advance();
4621 Ok(Expr::Literal(Literal::Infinity))
4622 }
4623 }
4624 Some(Token::Circle) => {
4625 self.advance();
4626 Ok(Expr::Literal(Literal::Circle))
4627 }
4628 Some(Token::LParen) => {
4629 self.advance();
4630 if self.check(&Token::RParen) {
4631 self.advance();
4632 return Ok(Expr::Tuple(vec![]));
4633 }
4634 let expr = self.parse_expr()?;
4635 if self.consume_if(&Token::Comma) {
4636 let mut exprs = vec![expr];
4637 while !self.check(&Token::RParen) {
4638 exprs.push(self.parse_expr()?);
4639 if !self.consume_if(&Token::Comma) {
4640 break;
4641 }
4642 }
4643 self.expect(Token::RParen)?;
4644 Ok(Expr::Tuple(exprs))
4645 } else {
4646 self.expect(Token::RParen)?;
4647 Ok(expr)
4648 }
4649 }
4650 Some(Token::LBracket) => {
4651 self.advance();
4652 if self.check(&Token::RBracket) {
4654 self.advance();
4655 return Ok(Expr::Array(vec![]));
4656 }
4657 let first = self.parse_expr()?;
4659 if self.consume_if(&Token::Semi) {
4661 let count = self.parse_expr()?;
4662 self.expect(Token::RBracket)?;
4663 return Ok(Expr::ArrayRepeat {
4664 value: Box::new(first),
4665 count: Box::new(count),
4666 });
4667 }
4668 let mut exprs = vec![first];
4670 while self.consume_if(&Token::Comma) {
4671 self.skip_comments();
4673 if self.check(&Token::RBracket) {
4674 break; }
4676 exprs.push(self.parse_expr()?);
4677 }
4678 self.skip_comments();
4679 self.expect(Token::RBracket)?;
4680 Ok(Expr::Array(exprs))
4681 }
4682 Some(Token::LBrace) => {
4683 self.parse_block_or_closure()
4685 }
4686 Some(Token::If) => self.parse_if_expr(),
4687 Some(Token::Match) => self.parse_match_expr(),
4688 Some(Token::Unsafe) => {
4689 self.advance();
4690 let block = self.parse_block()?;
4691 Ok(Expr::Unsafe(block))
4692 }
4693 Some(Token::Async) => {
4694 self.advance();
4695 let is_move = self.consume_if(&Token::Move);
4696 let block = self.parse_block()?;
4697 Ok(Expr::Async { block, is_move })
4698 }
4699 Some(Token::Const) => {
4700 self.advance();
4703 let block = self.parse_block()?;
4704 Ok(Expr::Block(block))
4705 }
4706 Some(Token::Lifetime(name)) => {
4707 let span = self.current_span();
4709 let label = Ident {
4710 name: name.clone(),
4711 evidentiality: None,
4712 affect: None,
4713 span,
4714 };
4715 self.advance();
4716 self.expect(Token::Colon)?;
4717 match self.current_token().cloned() {
4718 Some(Token::Loop) | Some(Token::Infinity) => {
4719 self.advance();
4720 let body = self.parse_block()?;
4721 Ok(Expr::Loop {
4722 label: Some(label),
4723 body,
4724 })
4725 }
4726 Some(Token::While) => {
4727 self.advance();
4728 let condition = if self.consume_if(&Token::Let) {
4730 let pattern = self.parse_pattern()?;
4731 self.expect(Token::Eq)?;
4732 let value = self.parse_condition()?;
4733 Expr::Let {
4734 pattern,
4735 value: Box::new(value),
4736 }
4737 } else {
4738 self.parse_condition()?
4739 };
4740 let body = self.parse_block()?;
4741 Ok(Expr::While {
4742 label: Some(label),
4743 condition: Box::new(condition),
4744 body,
4745 })
4746 }
4747 Some(Token::For) | Some(Token::ForAll) => {
4748 self.advance();
4749 let pattern = self.parse_pattern()?;
4750 if !self.consume_if(&Token::In) && !self.consume_if(&Token::ElementOf) {
4752 return Err(ParseError::UnexpectedToken {
4753 expected: "in or ∈".to_string(),
4754 found: self.current_token().cloned().unwrap_or(Token::Null),
4755 span: self.current_span(),
4756 });
4757 }
4758 let iter = self.parse_condition()?;
4759 let body = self.parse_block()?;
4760 Ok(Expr::For {
4761 label: Some(label),
4762 pattern,
4763 iter: Box::new(iter),
4764 body,
4765 })
4766 }
4767 other => Err(ParseError::UnexpectedToken {
4768 expected: "loop/∞, while/⟳, or for/∀ after label".to_string(),
4769 found: other.unwrap_or(Token::Null),
4770 span: self.current_span(),
4771 }),
4772 }
4773 }
4774 Some(Token::Loop) | Some(Token::Infinity) => {
4775 self.advance();
4776 let body = self.parse_block()?;
4777 Ok(Expr::Loop { label: None, body })
4778 }
4779 Some(Token::While) => {
4780 self.advance();
4781 let condition = if self.consume_if(&Token::Let) {
4783 let pattern = self.parse_pattern()?;
4784 self.expect(Token::Eq)?;
4785 let value = self.parse_condition()?;
4786 Expr::Let {
4787 pattern,
4788 value: Box::new(value),
4789 }
4790 } else {
4791 self.parse_condition()?
4792 };
4793 let body = self.parse_block()?;
4794 Ok(Expr::While {
4795 label: None,
4796 condition: Box::new(condition),
4797 body,
4798 })
4799 }
4800 Some(Token::For) | Some(Token::ForAll) => {
4801 self.advance();
4802 let pattern = self.parse_pattern()?;
4803 if !self.consume_if(&Token::In) && !self.consume_if(&Token::ElementOf) {
4805 return Err(ParseError::UnexpectedToken {
4806 expected: "in or ∈".to_string(),
4807 found: self.current_token().cloned().unwrap_or(Token::Null),
4808 span: self.current_span(),
4809 });
4810 }
4811 let iter = self.parse_condition()?;
4812 let body = self.parse_block()?;
4813 Ok(Expr::For {
4814 label: None,
4815 pattern,
4816 iter: Box::new(iter),
4817 body,
4818 })
4819 }
4820 Some(Token::Return) => {
4821 self.advance();
4822 let value = if self.check(&Token::Semi)
4824 || self.check(&Token::RBrace)
4825 || self.check(&Token::Comma)
4826 {
4827 None
4828 } else {
4829 Some(Box::new(self.parse_expr()?))
4830 };
4831 Ok(Expr::Return(value))
4832 }
4833 Some(Token::Break) | Some(Token::Tensor) => {
4834 self.advance();
4835 let label = if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
4837 let span = self.current_span();
4838 let label = Ident {
4839 name,
4840 evidentiality: None,
4841 affect: None,
4842 span,
4843 };
4844 self.advance();
4845 Some(label)
4846 } else {
4847 None
4848 };
4849 let value = if self.check(&Token::Semi)
4851 || self.check(&Token::RBrace)
4852 || self.check(&Token::Comma)
4853 {
4854 None
4855 } else {
4856 Some(Box::new(self.parse_expr()?))
4857 };
4858 Ok(Expr::Break { label, value })
4859 }
4860 Some(Token::Continue) | Some(Token::CycleArrow) => {
4861 self.advance();
4862 let label = if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
4864 let span = self.current_span();
4865 let label = Ident {
4866 name,
4867 evidentiality: None,
4868 affect: None,
4869 span,
4870 };
4871 self.advance();
4872 Some(label)
4873 } else {
4874 None
4875 };
4876 Ok(Expr::Continue { label })
4877 }
4878 Some(Token::Tau) | Some(Token::Phi) | Some(Token::Sigma) | Some(Token::Rho)
4880 | Some(Token::Lambda) | Some(Token::Pi) => {
4881 let kind = self.parse_morpheme_kind()?;
4882 if self.check(&Token::LBrace) {
4883 self.advance();
4884 self.skip_comments();
4885 let body = if self.looks_like_morpheme_closure() {
4887 self.parse_morpheme_closure()?
4888 } else {
4889 self.parse_expr()?
4890 };
4891 self.expect(Token::RBrace)?;
4892 Ok(Expr::Morpheme {
4893 kind,
4894 body: Box::new(body),
4895 })
4896 } else {
4897 Ok(Expr::Morpheme {
4899 kind,
4900 body: Box::new(Expr::Path(TypePath {
4901 segments: vec![PathSegment {
4902 ident: Ident {
4903 name: "_".to_string(),
4904 evidentiality: None,
4905 affect: None,
4906 span: Span::default(),
4907 },
4908 generics: None,
4909 }],
4910 })),
4911 })
4912 }
4913 }
4914 Some(Token::Sqrt) => {
4916 let span = self.current_span();
4918 self.advance();
4919 let name = if let Some(Token::IntLit(n)) = self.current_token().cloned() {
4920 let merged_span = span.merge(self.current_span());
4921 self.advance();
4922 (format!("√{}", n), merged_span)
4923 } else {
4924 ("√".to_string(), span)
4925 };
4926 Ok(Expr::Path(TypePath {
4927 segments: vec![PathSegment {
4928 ident: Ident {
4929 name: name.0,
4930 evidentiality: None,
4931 affect: None,
4932 span: name.1,
4933 },
4934 generics: None,
4935 }],
4936 }))
4937 }
4938 Some(Token::Underscore) => {
4939 let span = self.current_span();
4941 self.advance();
4942 Ok(Expr::Path(TypePath {
4943 segments: vec![PathSegment {
4944 ident: Ident {
4945 name: "_".to_string(),
4946 evidentiality: None,
4947 affect: None,
4948 span,
4949 },
4950 generics: None,
4951 }],
4952 }))
4953 }
4954 Some(Token::SelfLower) | Some(Token::Xi) => {
4955 let span = self.current_span();
4957 self.advance();
4958 Ok(Expr::Path(TypePath {
4959 segments: vec![PathSegment {
4960 ident: Ident {
4961 name: "self".to_string(),
4962 evidentiality: None,
4963 affect: None,
4964 span,
4965 },
4966 generics: None,
4967 }],
4968 }))
4969 }
4970 Some(Token::SelfUpper) => {
4971 let span = self.current_span();
4973 self.advance();
4974 let mut segments = vec![PathSegment {
4975 ident: Ident {
4976 name: "Self".to_string(),
4977 evidentiality: None,
4978 affect: None,
4979 span,
4980 },
4981 generics: None,
4982 }];
4983 while self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
4986 if self.check(&Token::Lt) {
4988 self.advance(); let types = self.parse_type_list()?;
4990 self.expect_gt()?;
4991 if let Some(last) = segments.last_mut() {
4993 last.generics = Some(types);
4994 }
4995 continue;
4998 }
4999 segments.push(self.parse_path_segment()?);
5000 }
5001 let path = TypePath { segments };
5002 if self.check(&Token::LBrace) && !self.is_in_condition() {
5004 self.advance();
5005 let (fields, rest) = self.parse_struct_fields()?;
5006 self.expect(Token::RBrace)?;
5007 Ok(Expr::Struct { path, fields, rest })
5008 } else {
5009 Ok(Expr::Path(path))
5010 }
5011 }
5012 Some(Token::Ident(_)) => {
5013 let path = self.parse_type_path()?;
5014
5015 if self.check(&Token::LBrace) && !self.is_in_condition() {
5019 self.advance();
5020 let (fields, rest) = self.parse_struct_fields()?;
5021 self.expect(Token::RBrace)?;
5022 Ok(Expr::Struct { path, fields, rest })
5023 } else {
5024 Ok(Expr::Path(path))
5025 }
5026 }
5027 Some(Token::Asm) => self.parse_inline_asm(),
5028 Some(Token::Volatile) => self.parse_volatile_expr(),
5029 Some(Token::Simd) => self.parse_simd_expr(),
5030 Some(Token::Atomic) => self.parse_atomic_expr(),
5031 Some(Token::Dot) => {
5037 let dot_span = self.current_span();
5038 self.advance(); match self.current_token() {
5040 Some(Token::Ident(name)) => {
5041 let field_name = name.clone();
5042 let field_span = self.current_span();
5043 self.advance();
5044 let self_expr = Expr::Path(TypePath {
5046 segments: vec![PathSegment {
5047 ident: Ident {
5048 name: "self".to_string(),
5049 evidentiality: None,
5050 affect: None,
5051 span: dot_span,
5052 },
5053 generics: None,
5054 }],
5055 });
5056 Ok(Expr::Field {
5057 expr: Box::new(self_expr),
5058 field: Ident {
5059 name: field_name,
5060 evidentiality: None,
5061 affect: None,
5062 span: field_span,
5063 },
5064 })
5065 }
5066 Some(token) => Err(ParseError::UnexpectedToken {
5067 expected: "identifier after '.' for implicit self field".to_string(),
5068 found: token.clone(),
5069 span: self.current_span(),
5070 }),
5071 None => Err(ParseError::UnexpectedEof),
5072 }
5073 }
5074 Some(ref token) if Self::keyword_as_ident(token).is_some() => {
5076 let path = self.parse_type_path()?;
5077 if self.check(&Token::LBrace) && !self.is_in_condition() {
5080 self.advance();
5081 let (fields, rest) = self.parse_struct_fields()?;
5082 self.expect(Token::RBrace)?;
5083 Ok(Expr::Struct { path, fields, rest })
5084 } else {
5085 Ok(Expr::Path(path))
5086 }
5087 }
5088 Some(token) => Err(ParseError::UnexpectedToken {
5089 expected: "expression".to_string(),
5090 found: token,
5091 span: self.current_span(),
5092 }),
5093 None => Err(ParseError::UnexpectedEof),
5094 }
5095 }
5096
5097 fn parse_inline_asm(&mut self) -> ParseResult<Expr> {
5108 self.expect(Token::Asm)?;
5109 self.expect(Token::Bang)?;
5110 self.expect(Token::LParen)?;
5111
5112 let template = match self.current_token().cloned() {
5114 Some(Token::StringLit(s)) => {
5115 self.advance();
5116 s
5117 }
5118 Some(t) => {
5119 return Err(ParseError::UnexpectedToken {
5120 expected: "assembly template string".to_string(),
5121 found: t,
5122 span: self.current_span(),
5123 });
5124 }
5125 None => return Err(ParseError::UnexpectedEof),
5126 };
5127
5128 let mut outputs = Vec::new();
5129 let mut inputs = Vec::new();
5130 let mut clobbers = Vec::new();
5131 let mut options = AsmOptions::default();
5132
5133 while self.consume_if(&Token::Comma) {
5135 if self.check(&Token::RParen) {
5136 break;
5137 }
5138
5139 match self.current_token().cloned() {
5140 Some(Token::Ident(ref name)) if name == "out" => {
5141 self.advance();
5142 let operand = self.parse_asm_operand(AsmOperandKind::Output)?;
5143 outputs.push(operand);
5144 }
5145 Some(Token::In) => {
5147 self.advance();
5148 let operand = self.parse_asm_operand(AsmOperandKind::Input)?;
5149 inputs.push(operand);
5150 }
5151 Some(Token::Ident(ref name)) if name == "inout" => {
5152 self.advance();
5153 let operand = self.parse_asm_operand(AsmOperandKind::InOut)?;
5154 outputs.push(operand);
5155 }
5156 Some(Token::Ident(ref name)) if name == "clobber" => {
5157 self.advance();
5158 self.expect(Token::LParen)?;
5159 while !self.check(&Token::RParen) {
5160 if let Some(Token::StringLit(reg)) = self.current_token().cloned() {
5161 self.advance();
5162 clobbers.push(reg);
5163 } else if let Some(Token::Ident(reg)) = self.current_token().cloned() {
5164 self.advance();
5165 clobbers.push(reg);
5166 }
5167 if !self.consume_if(&Token::Comma) {
5168 break;
5169 }
5170 }
5171 self.expect(Token::RParen)?;
5172 }
5173 Some(Token::Ident(ref name)) if name == "options" => {
5174 self.advance();
5175 self.expect(Token::LParen)?;
5176 while !self.check(&Token::RParen) {
5177 if let Some(Token::Ident(opt)) = self.current_token().cloned() {
5178 self.advance();
5179 match opt.as_str() {
5180 "volatile" => options.volatile = true,
5181 "nostack" => options.nostack = true,
5182 "pure" => options.pure_asm = true,
5183 "readonly" => options.readonly = true,
5184 "nomem" => options.nomem = true,
5185 "att_syntax" => options.att_syntax = true,
5186 _ => {}
5187 }
5188 }
5189 if !self.consume_if(&Token::Comma) {
5190 break;
5191 }
5192 }
5193 self.expect(Token::RParen)?;
5194 }
5195 _ => break,
5196 }
5197 }
5198
5199 self.expect(Token::RParen)?;
5200
5201 Ok(Expr::InlineAsm(InlineAsm {
5202 template,
5203 outputs,
5204 inputs,
5205 clobbers,
5206 options,
5207 }))
5208 }
5209
5210 fn parse_asm_operand(&mut self, kind: AsmOperandKind) -> ParseResult<AsmOperand> {
5212 self.expect(Token::LParen)?;
5213
5214 let constraint = match self.current_token().cloned() {
5215 Some(Token::StringLit(s)) => {
5216 self.advance();
5217 s
5218 }
5219 Some(Token::Ident(s)) => {
5220 self.advance();
5221 s
5222 }
5223 Some(t) => {
5224 return Err(ParseError::UnexpectedToken {
5225 expected: "register constraint".to_string(),
5226 found: t,
5227 span: self.current_span(),
5228 });
5229 }
5230 None => return Err(ParseError::UnexpectedEof),
5231 };
5232
5233 self.expect(Token::RParen)?;
5234
5235 let expr = self.parse_expr()?;
5236
5237 let output = if kind == AsmOperandKind::InOut && self.consume_if(&Token::FatArrow) {
5239 Some(Box::new(self.parse_expr()?))
5240 } else {
5241 None
5242 };
5243
5244 Ok(AsmOperand {
5245 constraint,
5246 expr,
5247 kind,
5248 output,
5249 })
5250 }
5251
5252 fn parse_volatile_expr(&mut self) -> ParseResult<Expr> {
5257 self.expect(Token::Volatile)?;
5258
5259 match self.current_token().cloned() {
5260 Some(Token::Ident(ref name)) if name == "read" => {
5261 self.advance();
5262
5263 let ty = if self.consume_if(&Token::Lt) {
5265 let t = self.parse_type()?;
5266 self.expect_gt()?;
5267 Some(t)
5268 } else {
5269 None
5270 };
5271
5272 self.expect(Token::LParen)?;
5273 let ptr = self.parse_expr()?;
5274 self.expect(Token::RParen)?;
5275
5276 Ok(Expr::VolatileRead {
5277 ptr: Box::new(ptr),
5278 ty,
5279 })
5280 }
5281 Some(Token::Ident(ref name)) if name == "write" => {
5282 self.advance();
5283
5284 let ty = if self.consume_if(&Token::Lt) {
5286 let t = self.parse_type()?;
5287 self.expect_gt()?;
5288 Some(t)
5289 } else {
5290 None
5291 };
5292
5293 self.expect(Token::LParen)?;
5294 let ptr = self.parse_expr()?;
5295 self.expect(Token::Comma)?;
5296 let value = self.parse_expr()?;
5297 self.expect(Token::RParen)?;
5298
5299 Ok(Expr::VolatileWrite {
5300 ptr: Box::new(ptr),
5301 value: Box::new(value),
5302 ty,
5303 })
5304 }
5305 Some(t) => Err(ParseError::UnexpectedToken {
5306 expected: "'read' or 'write' after 'volatile'".to_string(),
5307 found: t,
5308 span: self.current_span(),
5309 }),
5310 None => Err(ParseError::UnexpectedEof),
5311 }
5312 }
5313
5314 fn parse_simd_expr(&mut self) -> ParseResult<Expr> {
5326 self.expect(Token::Simd)?;
5327
5328 match self.current_token().cloned() {
5329 Some(Token::LBracket) => {
5330 self.advance();
5332 let elements = self.parse_expr_list()?;
5333 self.expect(Token::RBracket)?;
5334
5335 let ty = if self.consume_if(&Token::Colon) {
5337 Some(self.parse_type()?)
5338 } else {
5339 None
5340 };
5341
5342 Ok(Expr::SimdLiteral { elements, ty })
5343 }
5344 Some(Token::Dot) => {
5345 self.advance();
5346 match self.current_token().cloned() {
5347 Some(Token::Ident(ref op)) => {
5348 let op_name = op.clone();
5349 self.advance();
5350 self.expect(Token::LParen)?;
5351
5352 match op_name.as_str() {
5353 "splat" => {
5354 let value = self.parse_expr()?;
5355 self.expect(Token::Comma)?;
5356 let lanes = match self.current_token() {
5357 Some(Token::IntLit(s)) => {
5358 let n = s.parse::<u8>().map_err(|_| {
5359 ParseError::Custom("invalid lane count".to_string())
5360 })?;
5361 self.advance();
5362 n
5363 }
5364 _ => {
5365 return Err(ParseError::Custom(
5366 "expected lane count".to_string(),
5367 ))
5368 }
5369 };
5370 self.expect(Token::RParen)?;
5371 Ok(Expr::SimdSplat {
5372 value: Box::new(value),
5373 lanes,
5374 })
5375 }
5376 "shuffle" => {
5377 let a = self.parse_expr()?;
5378 self.expect(Token::Comma)?;
5379 let b = self.parse_expr()?;
5380 self.expect(Token::Comma)?;
5381 self.expect(Token::LBracket)?;
5382 let mut indices = Vec::new();
5383 loop {
5384 match self.current_token() {
5385 Some(Token::IntLit(s)) => {
5386 let n = s.parse::<u8>().map_err(|_| {
5387 ParseError::Custom("invalid index".to_string())
5388 })?;
5389 indices.push(n);
5390 self.advance();
5391 }
5392 _ => {
5393 return Err(ParseError::Custom(
5394 "expected index".to_string(),
5395 ))
5396 }
5397 }
5398 if !self.consume_if(&Token::Comma) {
5399 break;
5400 }
5401 }
5402 self.expect(Token::RBracket)?;
5403 self.expect(Token::RParen)?;
5404 Ok(Expr::SimdShuffle {
5405 a: Box::new(a),
5406 b: Box::new(b),
5407 indices,
5408 })
5409 }
5410 "extract" => {
5411 let vector = self.parse_expr()?;
5412 self.expect(Token::Comma)?;
5413 let index = match self.current_token() {
5414 Some(Token::IntLit(s)) => {
5415 let n = s.parse::<u8>().map_err(|_| {
5416 ParseError::Custom("invalid index".to_string())
5417 })?;
5418 self.advance();
5419 n
5420 }
5421 _ => {
5422 return Err(ParseError::Custom(
5423 "expected index".to_string(),
5424 ))
5425 }
5426 };
5427 self.expect(Token::RParen)?;
5428 Ok(Expr::SimdExtract {
5429 vector: Box::new(vector),
5430 index,
5431 })
5432 }
5433 "insert" => {
5434 let vector = self.parse_expr()?;
5435 self.expect(Token::Comma)?;
5436 let index = match self.current_token() {
5437 Some(Token::IntLit(s)) => {
5438 let n = s.parse::<u8>().map_err(|_| {
5439 ParseError::Custom("invalid index".to_string())
5440 })?;
5441 self.advance();
5442 n
5443 }
5444 _ => {
5445 return Err(ParseError::Custom(
5446 "expected index".to_string(),
5447 ))
5448 }
5449 };
5450 self.expect(Token::Comma)?;
5451 let value = self.parse_expr()?;
5452 self.expect(Token::RParen)?;
5453 Ok(Expr::SimdInsert {
5454 vector: Box::new(vector),
5455 index,
5456 value: Box::new(value),
5457 })
5458 }
5459 _ => {
5460 let op = Self::parse_simd_op(&op_name)?;
5462 let args = self.parse_expr_list()?;
5463 self.expect(Token::RParen)?;
5464 Ok(Expr::SimdIntrinsic { op, args })
5465 }
5466 }
5467 }
5468 Some(t) => Err(ParseError::UnexpectedToken {
5469 expected: "SIMD operation name".to_string(),
5470 found: t,
5471 span: self.current_span(),
5472 }),
5473 None => Err(ParseError::UnexpectedEof),
5474 }
5475 }
5476 Some(t) => Err(ParseError::UnexpectedToken {
5477 expected: "'[' or '.' after 'simd'".to_string(),
5478 found: t,
5479 span: self.current_span(),
5480 }),
5481 None => Err(ParseError::UnexpectedEof),
5482 }
5483 }
5484
5485 fn parse_simd_op(name: &str) -> ParseResult<SimdOp> {
5486 match name {
5487 "add" => Ok(SimdOp::Add),
5488 "sub" => Ok(SimdOp::Sub),
5489 "mul" => Ok(SimdOp::Mul),
5490 "div" => Ok(SimdOp::Div),
5491 "neg" => Ok(SimdOp::Neg),
5492 "abs" => Ok(SimdOp::Abs),
5493 "min" => Ok(SimdOp::Min),
5494 "max" => Ok(SimdOp::Max),
5495 "eq" => Ok(SimdOp::Eq),
5496 "ne" => Ok(SimdOp::Ne),
5497 "lt" => Ok(SimdOp::Lt),
5498 "le" => Ok(SimdOp::Le),
5499 "gt" => Ok(SimdOp::Gt),
5500 "ge" => Ok(SimdOp::Ge),
5501 "hadd" => Ok(SimdOp::HAdd),
5502 "dot" => Ok(SimdOp::Dot),
5503 "blend" => Ok(SimdOp::Blend),
5504 "load" => Ok(SimdOp::Load),
5505 "store" => Ok(SimdOp::Store),
5506 "load_aligned" => Ok(SimdOp::LoadAligned),
5507 "store_aligned" => Ok(SimdOp::StoreAligned),
5508 "cast" => Ok(SimdOp::Cast),
5509 "widen" => Ok(SimdOp::Widen),
5510 "narrow" => Ok(SimdOp::Narrow),
5511 "sqrt" => Ok(SimdOp::Sqrt),
5512 "rsqrt" => Ok(SimdOp::Rsqrt),
5513 "rcp" => Ok(SimdOp::Rcp),
5514 "floor" => Ok(SimdOp::Floor),
5515 "ceil" => Ok(SimdOp::Ceil),
5516 "round" => Ok(SimdOp::Round),
5517 "and" => Ok(SimdOp::And),
5518 "or" => Ok(SimdOp::Or),
5519 "xor" => Ok(SimdOp::Xor),
5520 "not" => Ok(SimdOp::Not),
5521 "shl" => Ok(SimdOp::Shl),
5522 "shr" => Ok(SimdOp::Shr),
5523 _ => Err(ParseError::Custom(format!(
5524 "unknown SIMD operation: {}",
5525 name
5526 ))),
5527 }
5528 }
5529
5530 fn parse_atomic_expr(&mut self) -> ParseResult<Expr> {
5542 self.expect(Token::Atomic)?;
5543 self.expect(Token::Dot)?;
5544
5545 match self.current_token().cloned() {
5546 Some(Token::Ident(ref op)) => {
5547 let op_name = op.clone();
5548 self.advance();
5549
5550 if op_name == "fence" {
5551 self.expect(Token::LParen)?;
5552 let ordering = self.parse_memory_ordering()?;
5553 self.expect(Token::RParen)?;
5554 return Ok(Expr::AtomicFence { ordering });
5555 }
5556
5557 self.expect(Token::LParen)?;
5558 let ptr = self.parse_expr()?;
5559
5560 let op = Self::parse_atomic_op(&op_name)?;
5561
5562 let value = match op {
5564 AtomicOp::Load => None,
5565 _ => {
5566 self.expect(Token::Comma)?;
5567 Some(Box::new(self.parse_expr()?))
5568 }
5569 };
5570
5571 let expected = match op {
5573 AtomicOp::CompareExchange | AtomicOp::CompareExchangeWeak => {
5574 self.expect(Token::Comma)?;
5575 Some(Box::new(self.parse_expr()?))
5576 }
5577 _ => None,
5578 };
5579
5580 self.expect(Token::Comma)?;
5582 let ordering = self.parse_memory_ordering()?;
5583
5584 let failure_ordering = match op {
5586 AtomicOp::CompareExchange | AtomicOp::CompareExchangeWeak => {
5587 if self.consume_if(&Token::Comma) {
5588 Some(self.parse_memory_ordering()?)
5589 } else {
5590 None
5591 }
5592 }
5593 _ => None,
5594 };
5595
5596 self.expect(Token::RParen)?;
5597
5598 Ok(Expr::AtomicOp {
5599 op,
5600 ptr: Box::new(ptr),
5601 value,
5602 expected,
5603 ordering,
5604 failure_ordering,
5605 })
5606 }
5607 Some(t) => Err(ParseError::UnexpectedToken {
5608 expected: "atomic operation name".to_string(),
5609 found: t,
5610 span: self.current_span(),
5611 }),
5612 None => Err(ParseError::UnexpectedEof),
5613 }
5614 }
5615
5616 fn parse_atomic_op(name: &str) -> ParseResult<AtomicOp> {
5617 match name {
5618 "load" => Ok(AtomicOp::Load),
5619 "store" => Ok(AtomicOp::Store),
5620 "swap" => Ok(AtomicOp::Swap),
5621 "compare_exchange" => Ok(AtomicOp::CompareExchange),
5622 "compare_exchange_weak" => Ok(AtomicOp::CompareExchangeWeak),
5623 "fetch_add" => Ok(AtomicOp::FetchAdd),
5624 "fetch_sub" => Ok(AtomicOp::FetchSub),
5625 "fetch_and" => Ok(AtomicOp::FetchAnd),
5626 "fetch_or" => Ok(AtomicOp::FetchOr),
5627 "fetch_xor" => Ok(AtomicOp::FetchXor),
5628 "fetch_min" => Ok(AtomicOp::FetchMin),
5629 "fetch_max" => Ok(AtomicOp::FetchMax),
5630 _ => Err(ParseError::Custom(format!(
5631 "unknown atomic operation: {}",
5632 name
5633 ))),
5634 }
5635 }
5636
5637 fn parse_memory_ordering(&mut self) -> ParseResult<MemoryOrdering> {
5638 match self.current_token() {
5639 Some(Token::Ident(name)) => {
5640 let ordering =
5641 match name.as_str() {
5642 "Relaxed" => MemoryOrdering::Relaxed,
5643 "Acquire" => MemoryOrdering::Acquire,
5644 "Release" => MemoryOrdering::Release,
5645 "AcqRel" => MemoryOrdering::AcqRel,
5646 "SeqCst" => MemoryOrdering::SeqCst,
5647 _ => return Err(ParseError::Custom(
5648 "expected memory ordering (Relaxed, Acquire, Release, AcqRel, SeqCst)"
5649 .to_string(),
5650 )),
5651 };
5652 self.advance();
5653 Ok(ordering)
5654 }
5655 _ => Err(ParseError::Custom("expected memory ordering".to_string())),
5656 }
5657 }
5658
5659 fn is_pipe_target_ahead(&mut self) -> bool {
5662 if let Some(next) = self.peek_next().cloned() {
5664 match &next {
5665 Token::Ident(_) => true,
5667 Token::SelfLower | Token::Xi => true, Token::SelfUpper => true, Token::Tau
5671 | Token::Phi
5672 | Token::Sigma
5673 | Token::Rho
5674 | Token::Lambda
5675 | Token::Delta
5676 | Token::Mu
5677 | Token::Chi
5678 | Token::GradeUp
5679 | Token::GradeDown
5680 | Token::Rotate
5681 | Token::Iota
5682 | Token::ForAll
5683 | Token::Exists
5684 | Token::Pi
5685 | Token::Hourglass => true,
5686 Token::Pipe => true,
5688 Token::OrOr => true, Token::LogicOr => true, Token::Move => true,
5692 Token::LBrace => true,
5694 Token::IntLit(_)
5696 | Token::FloatLit(_)
5697 | Token::HexLit(_)
5698 | Token::BinaryLit(_)
5699 | Token::OctalLit(_) => false,
5700 Token::LParen => false, Token::True | Token::False => false,
5702 Token::If => false, Token::Match => false, _ => true,
5706 }
5707 } else {
5708 false }
5710 }
5711
5712 fn parse_postfix_after_pipe(&mut self, mut expr: Expr) -> ParseResult<Expr> {
5714 loop {
5715 match self.current_token() {
5716 Some(Token::Question) => {
5717 self.advance();
5718 expr = Expr::Try(Box::new(expr));
5719 }
5720 Some(Token::Dot) => {
5721 self.advance();
5722 let field = if let Some(Token::IntLit(idx)) = self.current_token() {
5723 let idx = idx.clone();
5724 let span = self.current_span();
5725 self.advance();
5726 Ident {
5727 name: idx,
5728 evidentiality: None,
5729 affect: None,
5730 span,
5731 }
5732 } else {
5733 self.parse_ident()?
5734 };
5735 if self.check(&Token::ColonColon) {
5736 self.advance();
5737 self.expect(Token::Lt)?;
5738 let type_args = self.parse_type_list()?;
5739 self.expect_gt()?;
5740 self.expect(Token::LParen)?;
5741 let args = self.parse_expr_list()?;
5742 self.expect(Token::RParen)?;
5743 expr = Expr::MethodCall {
5744 receiver: Box::new(expr),
5745 method: field,
5746 type_args: Some(type_args),
5747 args,
5748 };
5749 } else if self.check(&Token::LParen) {
5750 self.advance();
5751 let args = self.parse_expr_list()?;
5752 self.expect(Token::RParen)?;
5753 expr = Expr::MethodCall {
5754 receiver: Box::new(expr),
5755 method: field,
5756 type_args: None,
5757 args,
5758 };
5759 } else {
5760 expr = Expr::Field {
5761 expr: Box::new(expr),
5762 field,
5763 };
5764 }
5765 }
5766 _ => break,
5767 }
5768 }
5769 Ok(expr)
5770 }
5771
5772 fn parse_pipe_chain(&mut self, initial: Expr) -> ParseResult<Expr> {
5774 let mut operations = Vec::new();
5775
5776 while self.consume_if(&Token::Pipe) {
5777 let op = self.parse_pipe_op()?;
5778 operations.push(op);
5779 }
5780
5781 Ok(Expr::Pipe {
5782 expr: Box::new(initial),
5783 operations,
5784 })
5785 }
5786
5787 fn parse_pipe_op(&mut self) -> ParseResult<PipeOp> {
5788 match self.current_token() {
5789 Some(Token::Tau) => {
5790 self.advance();
5791 self.expect(Token::LBrace)?;
5792 self.skip_comments();
5793 let body = if self.looks_like_morpheme_closure() {
5795 self.parse_morpheme_closure()?
5796 } else {
5797 self.parse_expr()?
5798 };
5799 self.expect(Token::RBrace)?;
5800 Ok(PipeOp::Transform(Box::new(body)))
5801 }
5802 Some(Token::Phi) => {
5803 self.advance();
5804 self.expect(Token::LBrace)?;
5805 self.skip_comments();
5806 let body = if self.looks_like_morpheme_closure() {
5808 self.parse_morpheme_closure()?
5809 } else {
5810 self.parse_expr()?
5811 };
5812 self.expect(Token::RBrace)?;
5813 Ok(PipeOp::Filter(Box::new(body)))
5814 }
5815 Some(Token::Sigma) => {
5816 if self.peek_next() == Some(&Token::LParen) {
5818 let name = Ident {
5820 name: "Σ".to_string(),
5821 evidentiality: None,
5822 affect: None,
5823 span: self.current_span(),
5824 };
5825 self.advance(); self.advance(); let args = self.parse_expr_list()?;
5828 self.expect(Token::RParen)?;
5829 Ok(PipeOp::Call(Box::new(Expr::Call {
5830 func: Box::new(Expr::Path(TypePath {
5831 segments: vec![PathSegment {
5832 ident: name,
5833 generics: None,
5834 }],
5835 })),
5836 args,
5837 })))
5838 } else {
5839 self.advance();
5840 let field = if self.consume_if(&Token::Dot) {
5841 Some(self.parse_ident()?)
5842 } else {
5843 None
5844 };
5845 Ok(PipeOp::Sort(field))
5846 }
5847 }
5848 Some(Token::Rho) => {
5849 self.advance();
5850 match self.current_token() {
5852 Some(Token::Plus) => {
5853 self.advance();
5854 Ok(PipeOp::ReduceSum)
5855 }
5856 Some(Token::Star) => {
5857 self.advance();
5858 Ok(PipeOp::ReduceProd)
5859 }
5860 Some(Token::PlusPlus) => {
5861 self.advance();
5862 Ok(PipeOp::ReduceConcat)
5863 }
5864 Some(Token::Amp) => {
5865 self.advance();
5866 Ok(PipeOp::ReduceAll)
5867 }
5868 Some(Token::Pipe) => {
5869 self.advance();
5870 Ok(PipeOp::ReduceAny)
5871 }
5872 Some(Token::Underscore) => {
5873 self.advance();
5874 if let Some(Token::Ident(name)) = self.current_token().cloned() {
5876 self.advance();
5877 match name.as_str() {
5878 "sum" => Ok(PipeOp::ReduceSum),
5879 "prod" | "product" => Ok(PipeOp::ReduceProd),
5880 "min" => Ok(PipeOp::ReduceMin),
5881 "max" => Ok(PipeOp::ReduceMax),
5882 "cat" | "concat" => Ok(PipeOp::ReduceConcat),
5883 "all" => Ok(PipeOp::ReduceAll),
5884 "any" => Ok(PipeOp::ReduceAny),
5885 _ => Err(ParseError::Custom(format!(
5886 "unknown reduction variant: ρ_{}",
5887 name
5888 ))),
5889 }
5890 } else {
5891 Err(ParseError::Custom(
5892 "expected reduction variant name after ρ_".to_string(),
5893 ))
5894 }
5895 }
5896 Some(Token::LBrace) => {
5897 self.advance();
5899 self.skip_comments();
5900 let body = if self.looks_like_morpheme_closure() {
5902 self.parse_morpheme_closure()?
5903 } else {
5904 self.parse_expr()?
5905 };
5906 self.expect(Token::RBrace)?;
5907 Ok(PipeOp::Reduce(Box::new(body)))
5908 }
5909 _ => Err(ParseError::Custom(
5910 "expected reduction variant (+, *, ++, &, |, _name) or {body} after ρ"
5911 .to_string(),
5912 )),
5913 }
5914 }
5915 Some(Token::Pi) => {
5917 self.advance();
5918 Ok(PipeOp::ReduceProd)
5919 }
5920 Some(Token::Alpha) => {
5922 self.advance();
5923 Ok(PipeOp::First)
5924 }
5925 Some(Token::Omega) => {
5926 self.advance();
5927 Ok(PipeOp::Last)
5928 }
5929 Some(Token::Mu) => {
5930 if self.peek_next() == Some(&Token::LParen) {
5933 let name = Ident {
5935 name: "μ".to_string(),
5936 evidentiality: None,
5937 affect: None,
5938 span: self.current_span(),
5939 };
5940 self.advance(); self.advance(); let args = self.parse_expr_list()?;
5943 self.expect(Token::RParen)?;
5944 Ok(PipeOp::Call(Box::new(Expr::Call {
5946 func: Box::new(Expr::Path(TypePath {
5947 segments: vec![PathSegment {
5948 ident: name,
5949 generics: None,
5950 }],
5951 })),
5952 args,
5953 })))
5954 } else {
5955 self.advance();
5956 Ok(PipeOp::Middle)
5957 }
5958 }
5959 Some(Token::Chi) => {
5960 self.advance();
5961 Ok(PipeOp::Choice)
5962 }
5963 Some(Token::Nu) => {
5964 self.advance();
5965 if self.check(&Token::LBrace) {
5967 self.advance();
5968 let index = self.parse_expr()?;
5969 self.expect(Token::RBrace)?;
5970 Ok(PipeOp::Nth(Box::new(index)))
5971 } else {
5972 Ok(PipeOp::Nth(Box::new(Expr::Literal(Literal::Int {
5974 value: "0".to_string(),
5975 base: NumBase::Decimal,
5976 suffix: None,
5977 }))))
5978 }
5979 }
5980 Some(Token::Xi) => {
5981 self.advance();
5982 Ok(PipeOp::Next)
5983 }
5984 Some(Token::Parallel) => {
5986 self.advance();
5987 let inner_op = self.parse_pipe_op()?;
5989 Ok(PipeOp::Parallel(Box::new(inner_op)))
5990 }
5991 Some(Token::Gpu) => {
5993 self.advance();
5994 let inner_op = self.parse_pipe_op()?;
5996 Ok(PipeOp::Gpu(Box::new(inner_op)))
5997 }
5998 Some(Token::Await) => {
5999 self.advance();
6000 Ok(PipeOp::Await)
6001 }
6002 Some(Token::Hourglass) => {
6003 self.advance();
6004 Ok(PipeOp::Await)
6005 }
6006 Some(Token::MiddleDot) => {
6007 self.advance();
6008 let mut prefix = Vec::new();
6009 prefix.push(self.parse_ident()?);
6010
6011 while self.consume_if(&Token::MiddleDot) {
6012 if self.check(&Token::LBrace) {
6013 break;
6014 }
6015 prefix.push(self.parse_ident()?);
6016 }
6017
6018 let body = if self.check(&Token::LBrace) {
6019 self.advance();
6020 let expr = self.parse_expr()?;
6021 self.expect(Token::RBrace)?;
6022 Some(Box::new(expr))
6023 } else {
6024 None
6025 };
6026
6027 Ok(PipeOp::Named { prefix, body })
6028 }
6029 Some(Token::Match) => {
6031 self.advance();
6032 self.expect(Token::LBrace)?;
6033 let mut arms = Vec::new();
6034 while !self.check(&Token::RBrace) && !self.is_eof() {
6035 let pattern = self.parse_or_pattern()?;
6037 let guard = if self.consume_if(&Token::If) {
6038 Some(self.parse_condition()?)
6039 } else {
6040 None
6041 };
6042 self.expect(Token::FatArrow)?;
6043 let body = self.parse_expr()?;
6044 arms.push(MatchArm {
6045 pattern,
6046 guard,
6047 body,
6048 });
6049 self.consume_if(&Token::Comma);
6051 }
6052 self.expect(Token::RBrace)?;
6053 Ok(PipeOp::Match(arms))
6054 }
6055 Some(Token::Interrobang) => {
6058 self.advance();
6059 let mapper = if self.check(&Token::LBrace) {
6060 self.advance();
6061 let expr = self.parse_expr()?;
6062 self.expect(Token::RBrace)?;
6063 Some(Box::new(expr))
6064 } else {
6065 None
6066 };
6067 Ok(PipeOp::TryMap(mapper))
6068 }
6069 Some(Token::SelfLower) | Some(Token::SelfUpper) | Some(Token::Xi) => {
6071 let expr = self.parse_postfix_expr()?;
6073 Ok(PipeOp::Call(Box::new(expr)))
6074 }
6075 Some(Token::Nabla) => {
6077 self.advance();
6078 Ok(PipeOp::Method {
6080 name: Ident {
6081 name: "∇".to_string(),
6082 evidentiality: None,
6083 affect: None,
6084 span: self.current_span(),
6085 },
6086 type_args: None,
6087 args: vec![],
6088 })
6089 }
6090 Some(Token::Ident(_)) => {
6091 let name = self.parse_ident()?;
6092
6093 if name.name == "validate" || name.name == "assume" {
6100 let (has_marker, target_evidence) = if self.check(&Token::Bang) {
6104 let peek = self.peek_next();
6105 if matches!(peek, Some(Token::LParen)) {
6106 self.advance(); (true, Evidentiality::Known)
6109 } else {
6110 (false, Evidentiality::Known)
6112 }
6113 } else if self.check(&Token::Question) {
6114 let peek = self.peek_next();
6115 if matches!(peek, Some(Token::LBrace) | Some(Token::LParen)) {
6116 self.advance(); (true, Evidentiality::Uncertain)
6118 } else {
6119 (false, Evidentiality::Known)
6120 }
6121 } else if self.check(&Token::Tilde) {
6122 let peek = self.peek_next();
6123 if matches!(peek, Some(Token::LBrace) | Some(Token::LParen)) {
6124 self.advance(); (true, Evidentiality::Reported)
6126 } else {
6127 (false, Evidentiality::Known)
6128 }
6129 } else {
6130 (false, name.evidentiality.unwrap_or(Evidentiality::Known))
6131 };
6132
6133 if has_marker || self.check(&Token::LParen) || self.check(&Token::LBrace) {
6135 let args = if self.check(&Token::LParen) {
6136 self.advance();
6137 let args = self.parse_expr_list()?;
6138 self.expect(Token::RParen)?;
6139 args
6140 } else if self.check(&Token::LBrace) {
6141 self.advance();
6142 self.skip_comments();
6143 let body = if self.looks_like_morpheme_closure() {
6144 self.parse_morpheme_closure()?
6145 } else {
6146 self.parse_expr()?
6147 };
6148 self.expect(Token::RBrace)?;
6149 vec![body]
6150 } else {
6151 vec![]
6152 };
6153
6154 if name.name == "validate" {
6155 if args.is_empty() {
6156 return Err(ParseError::Custom(
6157 "validate requires a predicate".to_string(),
6158 ));
6159 }
6160 return Ok(PipeOp::Validate {
6161 predicate: Box::new(args.into_iter().next().unwrap()),
6162 target_evidence,
6163 });
6164 } else {
6165 let reason = args.into_iter().next().map(Box::new);
6167 return Ok(PipeOp::Assume {
6168 reason,
6169 target_evidence,
6170 });
6171 }
6172 }
6173 }
6174
6175 if self.check(&Token::Bang) {
6177 let peek = self.peek_next();
6178 if matches!(
6179 peek,
6180 Some(Token::LBrace) | Some(Token::LParen) | Some(Token::LBracket)
6181 ) {
6182 self.advance(); let tokens = self.parse_macro_tokens()?;
6184 let path = TypePath {
6185 segments: vec![PathSegment {
6186 ident: name,
6187 generics: None,
6188 }],
6189 };
6190 return Ok(PipeOp::Call(Box::new(Expr::Macro { path, tokens })));
6191 }
6192 }
6193
6194 let mut path_segments = vec![PathSegment {
6198 ident: name.clone(),
6199 generics: None,
6200 }];
6201 let type_args = loop {
6202 if self.check(&Token::ColonColon) || self.check(&Token::MiddleDot) {
6203 let is_middledot = self.check(&Token::MiddleDot);
6204 self.advance(); if self.check(&Token::Lt) {
6206 self.advance(); let types = self.parse_type_list()?;
6209 self.expect_gt()?;
6210 break Some(types);
6211 } else if let Some(Token::Ident(_)) = self.current_token() {
6212 let segment = self.parse_ident()?;
6214 path_segments.push(PathSegment {
6215 ident: segment,
6216 generics: None,
6217 });
6218 } else {
6220 let sep = if is_middledot { "·" } else { "::" };
6221 return Err(ParseError::Custom(format!(
6222 "expected identifier or '<' after '{}'",
6223 sep
6224 )));
6225 }
6226 } else {
6227 break None;
6228 }
6229 };
6230
6231 let name = if path_segments.len() > 1 {
6233 let path = TypePath {
6235 segments: path_segments,
6236 };
6237 let args = if self.check(&Token::LParen) {
6238 self.advance();
6239 let args = self.parse_expr_list()?;
6240 self.expect(Token::RParen)?;
6241 args
6242 } else {
6243 vec![]
6244 };
6245 return Ok(PipeOp::Call(Box::new(Expr::Call {
6246 func: Box::new(Expr::Path(path)),
6247 args,
6248 })));
6249 } else {
6250 name
6251 };
6252 let args = if self.check(&Token::LParen) {
6253 self.advance();
6254 let args = self.parse_expr_list()?;
6255 self.expect(Token::RParen)?;
6256 args
6257 } else if self.check(&Token::LBrace) && !self.in_condition {
6258 self.advance();
6261 self.skip_comments();
6262 let body = if self.looks_like_morpheme_closure() {
6263 self.parse_morpheme_closure()?
6264 } else {
6265 self.parse_expr()?
6266 };
6267 self.expect(Token::RBrace)?;
6268 vec![body]
6269 } else {
6270 vec![]
6271 };
6272
6273 if name.name == "validate" {
6275 let target_evidence = name.evidentiality.unwrap_or(Evidentiality::Known);
6276 if args.is_empty() {
6277 return Err(ParseError::Custom(
6278 "validate requires a predicate: |validate!{predicate}".to_string(),
6279 ));
6280 }
6281 return Ok(PipeOp::Validate {
6282 predicate: Box::new(args.into_iter().next().unwrap()),
6283 target_evidence,
6284 });
6285 }
6286 if name.name == "assume" {
6287 let target_evidence = name.evidentiality.unwrap_or(Evidentiality::Known);
6288 let reason = args.into_iter().next().map(Box::new);
6289 return Ok(PipeOp::Assume {
6290 reason,
6291 target_evidence,
6292 });
6293 }
6294
6295 Ok(PipeOp::Method {
6296 name,
6297 type_args,
6298 args,
6299 })
6300 }
6301
6302 Some(Token::Send) | Some(Token::ProtoSend) => {
6308 self.advance();
6309 self.expect(Token::LBrace)?;
6310 let data = self.parse_expr()?;
6311 self.expect(Token::RBrace)?;
6312 Ok(PipeOp::Send(Box::new(data)))
6313 }
6314
6315 Some(Token::Recv) | Some(Token::ProtoRecv) => {
6317 self.advance();
6318 Ok(PipeOp::Recv)
6319 }
6320
6321 Some(Token::Stream) | Some(Token::ProtoStream) => {
6323 self.advance();
6324 self.expect(Token::LBrace)?;
6325 let handler = self.parse_expr()?;
6326 self.expect(Token::RBrace)?;
6327 Ok(PipeOp::Stream(Box::new(handler)))
6328 }
6329
6330 Some(Token::Connect) | Some(Token::ProtoConnect) => {
6332 self.advance();
6333 let config = if self.check(&Token::LBrace) {
6334 self.advance();
6335 let expr = self.parse_expr()?;
6336 self.expect(Token::RBrace)?;
6337 Some(Box::new(expr))
6338 } else {
6339 None
6340 };
6341 Ok(PipeOp::Connect(config))
6342 }
6343
6344 Some(Token::Close) | Some(Token::Tensor) => {
6346 self.advance();
6347 Ok(PipeOp::Close)
6348 }
6349
6350 Some(Token::Timeout) | Some(Token::ProtoTimeout) => {
6352 self.advance();
6353 self.expect(Token::LBrace)?;
6354 let ms = self.parse_expr()?;
6355 self.expect(Token::RBrace)?;
6356 Ok(PipeOp::Timeout(Box::new(ms)))
6357 }
6358
6359 Some(Token::Retry) => {
6361 self.advance();
6362 self.expect(Token::LBrace)?;
6363 let count = self.parse_expr()?;
6364 let strategy = if self.consume_if(&Token::Comma) {
6365 Some(Box::new(self.parse_expr()?))
6366 } else {
6367 None
6368 };
6369 self.expect(Token::RBrace)?;
6370 Ok(PipeOp::Retry {
6371 count: Box::new(count),
6372 strategy,
6373 })
6374 }
6375
6376 Some(Token::Header) => {
6378 self.advance();
6379 self.expect(Token::LBrace)?;
6380 let name = self.parse_expr()?;
6381 self.expect(Token::Comma)?;
6382 let value = self.parse_expr()?;
6383 self.expect(Token::RBrace)?;
6384 Ok(PipeOp::Header {
6385 name: Box::new(name),
6386 value: Box::new(value),
6387 })
6388 }
6389
6390 Some(Token::Body) => {
6392 self.advance();
6393 self.expect(Token::LBrace)?;
6394 let data = self.parse_expr()?;
6395 self.expect(Token::RBrace)?;
6396 Ok(PipeOp::Body(Box::new(data)))
6397 }
6398
6399 Some(Token::ForAll) => {
6405 self.advance();
6406 if self.check(&Token::LBrace) {
6409 self.advance(); let pred = self.parse_expr()?;
6411 self.expect(Token::RBrace)?;
6412 Ok(PipeOp::All(Box::new(pred)))
6413 } else {
6414 Ok(PipeOp::Universal)
6416 }
6417 }
6418
6419 Some(Token::Lozenge) => {
6421 self.advance();
6422 if let Some(Token::Ident(_)) = self.current_token() {
6424 let name = self.parse_ident()?;
6425 let args = if self.check(&Token::LParen) {
6427 self.advance();
6428 let args = self.parse_expr_list()?;
6429 self.expect(Token::RParen)?;
6430 args
6431 } else {
6432 vec![]
6433 };
6434 Ok(PipeOp::PossibilityMethod { name, args })
6435 } else {
6436 Ok(PipeOp::Possibility)
6437 }
6438 }
6439
6440 Some(Token::BoxSymbol) => {
6442 self.advance();
6443 if let Some(Token::Ident(_)) = self.current_token() {
6445 let name = self.parse_ident()?;
6446 let args = if self.check(&Token::LParen) {
6448 self.advance();
6449 let args = self.parse_expr_list()?;
6450 self.expect(Token::RParen)?;
6451 args
6452 } else {
6453 vec![]
6454 };
6455 Ok(PipeOp::NecessityMethod { name, args })
6456 } else {
6457 Ok(PipeOp::Necessity)
6458 }
6459 }
6460
6461 Some(Token::Exists) => {
6463 self.advance();
6464 self.expect(Token::LBrace)?;
6465 let pred = self.parse_expr()?;
6466 self.expect(Token::RBrace)?;
6467 Ok(PipeOp::Any(Box::new(pred)))
6468 }
6469
6470 Some(Token::Compose) => {
6472 self.advance();
6473 self.expect(Token::LBrace)?;
6474 let f = self.parse_expr()?;
6475 self.expect(Token::RBrace)?;
6476 Ok(PipeOp::Compose(Box::new(f)))
6477 }
6478
6479 Some(Token::Bowtie) => {
6481 self.advance();
6482 self.expect(Token::LBrace)?;
6483 let other = self.parse_expr()?;
6484 self.expect(Token::RBrace)?;
6485 Ok(PipeOp::Zip(Box::new(other)))
6486 }
6487
6488 Some(Token::Integral) => {
6490 self.advance();
6491 self.expect(Token::LBrace)?;
6492 let f = self.parse_expr()?;
6493 self.expect(Token::RBrace)?;
6494 Ok(PipeOp::Scan(Box::new(f)))
6495 }
6496
6497 Some(Token::Partial) => {
6499 self.advance();
6500 Ok(PipeOp::Diff)
6501 }
6502
6503 Some(Token::Nabla) => {
6505 self.advance();
6506 self.expect(Token::LBrace)?;
6507 let var = self.parse_expr()?;
6508 self.expect(Token::RBrace)?;
6509 Ok(PipeOp::Gradient(Box::new(var)))
6510 }
6511
6512 Some(Token::GradeUp) => {
6514 self.advance();
6515 Ok(PipeOp::SortAsc)
6516 }
6517
6518 Some(Token::GradeDown) => {
6520 self.advance();
6521 Ok(PipeOp::SortDesc)
6522 }
6523
6524 Some(Token::Rotate) => {
6526 self.advance();
6527 Ok(PipeOp::Reverse)
6528 }
6529
6530 Some(Token::CycleArrow) => {
6532 self.advance();
6533 self.expect(Token::LBrace)?;
6534 let n = self.parse_expr()?;
6535 self.expect(Token::RBrace)?;
6536 Ok(PipeOp::Cycle(Box::new(n)))
6537 }
6538
6539 Some(Token::QuadDiamond) => {
6541 self.advance();
6542 self.expect(Token::LBrace)?;
6543 let n = self.parse_expr()?;
6544 self.expect(Token::RBrace)?;
6545 Ok(PipeOp::Windows(Box::new(n)))
6546 }
6547
6548 Some(Token::SquaredPlus) => {
6550 self.advance();
6551 self.expect(Token::LBrace)?;
6552 let n = self.parse_expr()?;
6553 self.expect(Token::RBrace)?;
6554 Ok(PipeOp::Chunks(Box::new(n)))
6555 }
6556
6557 Some(Token::ElementSmallVerticalBar) => {
6559 self.advance();
6560 Ok(PipeOp::Flatten)
6561 }
6562
6563 Some(Token::Union) => {
6565 self.advance();
6566 Ok(PipeOp::Unique)
6567 }
6568
6569 Some(Token::Iota) => {
6571 self.advance();
6572 Ok(PipeOp::Enumerate)
6573 }
6574
6575 Some(Token::Amp) => {
6577 let expr = self.parse_prefix_expr()?;
6579 Ok(PipeOp::Call(Box::new(expr)))
6580 }
6581
6582 Some(Token::LBrace) => {
6585 self.advance();
6586 self.skip_comments();
6587 let body = if self.looks_like_morpheme_closure() {
6588 self.parse_morpheme_closure()?
6589 } else {
6590 self.parse_expr()?
6591 };
6592 self.expect(Token::RBrace)?;
6593 Ok(PipeOp::Call(Box::new(body)))
6594 }
6595
6596 Some(token) => Err(ParseError::UnexpectedToken {
6597 expected: "pipe operation".to_string(),
6598 found: token.clone(),
6599 span: self.current_span(),
6600 }),
6601 None => Err(ParseError::UnexpectedEof),
6602 }
6603 }
6604
6605 fn looks_like_morpheme_closure(&mut self) -> bool {
6607 if matches!(
6609 self.current_token(),
6610 Some(Token::Ident(_)) | Some(Token::Underscore)
6611 ) {
6612 match self.peek_next() {
6614 Some(Token::FatArrow) => return true,
6615 Some(Token::Tilde) | Some(Token::Lozenge) | Some(Token::Interrobang) => {
6617 if matches!(self.peek_n(1), Some(Token::FatArrow)) {
6619 return true;
6620 }
6621 }
6622 _ => {}
6623 }
6624 }
6625 if matches!(self.current_token(), Some(Token::Amp)) {
6627 if matches!(self.peek_next(), Some(Token::Ident(_))) {
6629 match self.peek_n(1) {
6631 Some(Token::FatArrow) => return true,
6632 Some(Token::Tilde) | Some(Token::Lozenge) | Some(Token::Interrobang) => {
6633 if matches!(self.peek_n(2), Some(Token::FatArrow)) {
6634 return true;
6635 }
6636 }
6637 _ => {}
6638 }
6639 } else if matches!(self.peek_next(), Some(Token::Mut) | Some(Token::Delta)) {
6640 return true;
6642 }
6643 }
6644 if matches!(self.current_token(), Some(Token::LParen)) {
6647 return true;
6650 }
6651 false
6652 }
6653
6654 fn parse_morpheme_closure(&mut self) -> ParseResult<Expr> {
6657 let pattern = if self.check(&Token::LParen) {
6658 self.advance();
6660 let mut patterns = Vec::new();
6661 while !self.check(&Token::RParen) {
6662 let pat = self.parse_pattern()?;
6663 patterns.push(pat);
6664 if !self.consume_if(&Token::Comma) {
6665 break;
6666 }
6667 }
6668 self.expect(Token::RParen)?;
6669 Pattern::Tuple(patterns)
6671 } else if self.check(&Token::Amp) {
6672 self.parse_pattern()?
6674 } else if self.check(&Token::Underscore) {
6675 self.advance();
6677 Pattern::Wildcard
6678 } else {
6679 let name = self.parse_ident()?;
6681 Pattern::Ident {
6682 mutable: false,
6683 name,
6684 evidentiality: None,
6685 }
6686 };
6687 if !self.consume_if(&Token::FatArrow) {
6689 self.expect(Token::Pipe)?;
6690 }
6691 self.skip_comments();
6693 let body = {
6701 let mut stmts = Vec::new();
6703 loop {
6704 self.skip_comments();
6705 if self.check(&Token::RBrace) {
6706 break;
6707 }
6708 if self.check(&Token::Let) {
6709 stmts.push(self.parse_let_stmt()?);
6710 } else if self.check(&Token::Return)
6711 || self.check(&Token::Break) || self.check(&Token::Tensor)
6712 || self.check(&Token::Continue) || self.check(&Token::CycleArrow)
6713 {
6714 break;
6716 } else {
6717 let expr = self.parse_expr()?;
6719 self.skip_comments();
6721 if self.consume_if(&Token::Semi) {
6722 stmts.push(Stmt::Expr(expr));
6724 } else if self.check(&Token::RBrace) {
6725 if stmts.is_empty() {
6727 return Ok(Expr::Closure {
6729 params: vec![ClosureParam { pattern, ty: None }],
6730 return_type: None,
6731 body: Box::new(expr),
6732 is_move: false,
6733 });
6734 }
6735 return Ok(Expr::Closure {
6736 params: vec![ClosureParam { pattern, ty: None }],
6737 return_type: None,
6738 body: Box::new(Expr::Block(Block {
6739 stmts,
6740 expr: Some(Box::new(expr)),
6741 })),
6742 is_move: false,
6743 });
6744 } else {
6745 stmts.push(Stmt::Expr(expr));
6748 }
6749 }
6750 }
6751 Expr::Block(Block { stmts, expr: None })
6753 };
6754 Ok(Expr::Closure {
6755 params: vec![ClosureParam { pattern, ty: None }],
6756 return_type: None,
6757 body: Box::new(body),
6758 is_move: false,
6759 })
6760 }
6761
6762 fn parse_morpheme_kind(&mut self) -> ParseResult<MorphemeKind> {
6763 match self.current_token() {
6764 Some(Token::Tau) => {
6765 self.advance();
6766 Ok(MorphemeKind::Transform)
6767 }
6768 Some(Token::Phi) => {
6769 self.advance();
6770 Ok(MorphemeKind::Filter)
6771 }
6772 Some(Token::Sigma) => {
6773 self.advance();
6774 Ok(MorphemeKind::Sort)
6775 }
6776 Some(Token::Rho) => {
6777 self.advance();
6778 Ok(MorphemeKind::Reduce)
6779 }
6780 Some(Token::Lambda) => {
6781 self.advance();
6782 Ok(MorphemeKind::Lambda)
6783 }
6784 Some(Token::Pi) => {
6785 self.advance();
6786 Ok(MorphemeKind::Product)
6787 }
6788 _ => Err(ParseError::Custom("expected morpheme".to_string())),
6789 }
6790 }
6791
6792 fn parse_block_or_closure(&mut self) -> ParseResult<Expr> {
6793 self.expect(Token::LBrace)?;
6794 self.skip_comments();
6795
6796 let is_simple_closure = matches!(self.current_token(), Some(Token::Ident(_)))
6799 && matches!(self.peek_next(), Some(Token::FatArrow));
6800
6801 if is_simple_closure {
6802 let name = self.parse_ident()?;
6803 self.expect(Token::FatArrow)?;
6804 self.skip_comments();
6805 let body = self.parse_expr()?;
6806 self.skip_comments();
6807 self.expect(Token::RBrace)?;
6808 return Ok(Expr::Closure {
6809 params: vec![ClosureParam {
6810 pattern: Pattern::Ident {
6811 mutable: false,
6812 name,
6813 evidentiality: None,
6814 },
6815 ty: None,
6816 }],
6817 return_type: None,
6818 body: Box::new(body),
6819 is_move: false,
6820 });
6821 }
6822
6823 let mut stmts = Vec::new();
6825 let mut final_expr = None;
6826
6827 while !self.check(&Token::RBrace) && !self.is_eof() {
6828 self.skip_comments();
6829 if self.check(&Token::RBrace) {
6830 break;
6831 }
6832
6833 if self.check(&Token::Hash) || self.check(&Token::At) {
6835 let mut attrs = Vec::new();
6837 while self.check(&Token::Hash) || self.check(&Token::At) {
6838 attrs.push(self.parse_outer_attribute()?);
6839 self.skip_comments();
6840 }
6841
6842 if self.is_item_start() {
6844 let item = self.parse_item()?;
6846 stmts.push(Stmt::Item(Box::new(item.node)));
6847 } else if self.check(&Token::Let) {
6848 stmts.push(self.parse_let_stmt()?);
6850 } else {
6851 let expr = self.parse_expr()?;
6853 self.skip_comments();
6854 if self.consume_if(&Token::Semi) {
6855 stmts.push(Stmt::Semi(expr));
6856 } else if self.check(&Token::RBrace) {
6857 final_expr = Some(Box::new(expr));
6858 } else {
6859 stmts.push(Stmt::Expr(expr));
6860 }
6861 }
6862 } else if self.is_item_start() {
6863 let item = self.parse_item()?;
6864 stmts.push(Stmt::Item(Box::new(item.node)));
6865 } else if self.check(&Token::Let) {
6866 stmts.push(self.parse_let_stmt()?);
6867 } else {
6868 let expr = self.parse_expr()?;
6869 self.skip_comments();
6870 if self.consume_if(&Token::Semi) {
6871 stmts.push(Stmt::Semi(expr));
6872 } else if self.check(&Token::RBrace) {
6873 final_expr = Some(Box::new(expr));
6874 } else {
6875 stmts.push(Stmt::Expr(expr));
6876 }
6877 }
6878 }
6879
6880 self.expect(Token::RBrace)?;
6881
6882 Ok(Expr::Block(Block {
6883 stmts,
6884 expr: final_expr,
6885 }))
6886 }
6887
6888 pub(crate) fn parse_block(&mut self) -> ParseResult<Block> {
6889 match self.parse_block_or_closure()? {
6890 Expr::Block(block) => Ok(block),
6891 _ => Err(ParseError::Custom("expected block".to_string())),
6892 }
6893 }
6894
6895 fn parse_let_stmt(&mut self) -> ParseResult<Stmt> {
6896 self.expect(Token::Let)?;
6897 let pattern = self.parse_pattern()?;
6898 let ty = if self.consume_if(&Token::Colon) {
6899 Some(self.parse_type()?)
6900 } else {
6901 None
6902 };
6903 let init = if self.consume_if(&Token::Eq) {
6904 Some(self.parse_expr()?)
6905 } else {
6906 None
6907 };
6908
6909 if self.consume_if(&Token::Else) {
6911 let else_branch = Box::new(Expr::Block(self.parse_block()?));
6912 self.consume_if(&Token::Semi);
6914 Ok(Stmt::LetElse {
6915 pattern,
6916 ty,
6917 init: init.ok_or_else(|| {
6918 ParseError::Custom("let-else requires initializer".to_string())
6919 })?,
6920 else_branch,
6921 })
6922 } else {
6923 if !self.consume_if(&Token::Semi) {
6926 if !self.can_start_stmt() && !self.check(&Token::RBrace) {
6927 return Err(ParseError::UnexpectedToken {
6928 expected: "`;` or new statement".to_string(),
6929 found: self.current_token().cloned().unwrap_or(Token::Semi),
6930 span: self.current_span(),
6931 });
6932 }
6933 }
6934 Ok(Stmt::Let { pattern, ty, init })
6935 }
6936 }
6937
6938 fn parse_if_expr(&mut self) -> ParseResult<Expr> {
6939 self.expect(Token::If)?;
6940
6941 let condition = if self.consume_if(&Token::Let) {
6943 let pattern = self.parse_or_pattern()?;
6944 self.expect(Token::Eq)?;
6945 let expr = self.parse_condition()?;
6946 Expr::Let {
6947 pattern,
6948 value: Box::new(expr),
6949 }
6950 } else {
6951 self.parse_condition()?
6952 };
6953
6954 let then_branch = self.parse_block()?;
6955 self.skip_comments(); let else_branch = if self.consume_if(&Token::Else) {
6957 if self.check(&Token::If) {
6958 Some(Box::new(self.parse_if_expr()?))
6959 } else {
6960 Some(Box::new(Expr::Block(self.parse_block()?)))
6961 }
6962 } else {
6963 None
6964 };
6965
6966 Ok(Expr::If {
6967 condition: Box::new(condition),
6968 then_branch,
6969 else_branch,
6970 })
6971 }
6972
6973 fn parse_match_expr(&mut self) -> ParseResult<Expr> {
6974 self.expect(Token::Match)?;
6975 let expr = self.parse_condition()?;
6977 self.expect(Token::LBrace)?;
6978
6979 let mut arms = Vec::new();
6980 while !self.check(&Token::RBrace) && !self.is_eof() {
6981 loop {
6983 if matches!(
6984 self.current_token(),
6985 Some(Token::DocComment(_))
6986 | Some(
6987 Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
6988 )
6989 ) {
6990 self.advance();
6991 } else if self.check(&Token::Hash) {
6992 self.skip_attribute()?;
6994 } else {
6995 break;
6996 }
6997 }
6998 if self.check(&Token::RBrace) {
6999 break;
7000 }
7001 let pattern = self.parse_or_pattern()?;
7002 let guard = if self.consume_if(&Token::If) {
7003 Some(self.parse_condition()?)
7004 } else {
7005 None
7006 };
7007 self.expect(Token::FatArrow)?;
7008 let body = self.parse_expr()?;
7009 arms.push(MatchArm {
7010 pattern,
7011 guard,
7012 body,
7013 });
7014 self.consume_if(&Token::Comma);
7017 while matches!(
7019 self.current_token(),
7020 Some(Token::DocComment(_))
7021 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
7022 ) {
7023 self.advance();
7024 }
7025 }
7026
7027 self.expect(Token::RBrace)?;
7028
7029 Ok(Expr::Match {
7030 expr: Box::new(expr),
7031 arms,
7032 })
7033 }
7034
7035 fn parse_or_pattern(&mut self) -> ParseResult<Pattern> {
7039 let first = self.parse_pattern()?;
7040
7041 if self.check(&Token::Pipe) {
7043 let mut patterns = vec![first];
7044 while self.consume_if(&Token::Pipe) {
7045 patterns.push(self.parse_pattern()?);
7046 }
7047 Ok(Pattern::Or(patterns))
7048 } else {
7049 Ok(first)
7050 }
7051 }
7052
7053 fn parse_pattern(&mut self) -> ParseResult<Pattern> {
7054 let prefix_ev = match self.current_token() {
7056 Some(Token::Question) => {
7057 self.advance();
7058 Some(Evidentiality::Uncertain)
7059 }
7060 Some(Token::Bang) => {
7061 self.advance();
7062 Some(Evidentiality::Known)
7063 }
7064 Some(Token::Tilde) => {
7065 self.advance();
7066 Some(Evidentiality::Reported)
7067 }
7068 Some(Token::Lozenge) => {
7069 self.advance();
7070 Some(Evidentiality::Predicted)
7071 }
7072 Some(Token::Interrobang) => {
7073 self.advance();
7074 Some(Evidentiality::Paradox)
7075 }
7076 _ => None,
7077 };
7078
7079 if let Some(ev) = prefix_ev {
7082 let inner_pattern = self.parse_pattern_base()?;
7084 return match inner_pattern {
7085 Pattern::Ident {
7086 mutable,
7087 name,
7088 evidentiality: _,
7089 } => {
7090 Ok(Pattern::Ident {
7092 mutable,
7093 name,
7094 evidentiality: Some(ev),
7095 })
7096 }
7097 Pattern::Wildcard => {
7098 let span = self.current_span();
7101 Ok(Pattern::Ident {
7102 mutable: false,
7103 name: Ident {
7104 name: "_".to_string(),
7105 evidentiality: None,
7106 affect: None,
7107 span,
7108 },
7109 evidentiality: Some(ev),
7110 })
7111 }
7112 other => {
7113 Ok(other)
7118 }
7119 };
7120 }
7121
7122 self.parse_pattern_base()
7123 }
7124
7125 fn parse_pattern_base(&mut self) -> ParseResult<Pattern> {
7127 match self.current_token().cloned() {
7128 Some(Token::Underscore) => {
7129 self.advance();
7130 Ok(Pattern::Wildcard)
7131 }
7132 Some(Token::DotDot) => {
7133 self.advance();
7134 Ok(Pattern::Rest)
7135 }
7136 Some(Token::Mut) | Some(Token::Delta) => {
7137 self.advance();
7138 let name = if self.check_self() {
7140 let span = self.current_span();
7141 self.advance();
7142 Ident {
7143 name: "self".to_string(),
7144 evidentiality: None,
7145 affect: None,
7146 span,
7147 }
7148 } else {
7149 self.parse_ident()?
7150 };
7151 let evidentiality = self.parse_evidentiality_opt();
7152 Ok(Pattern::Ident {
7153 mutable: true,
7154 name,
7155 evidentiality,
7156 })
7157 }
7158 Some(Token::Ref) => {
7160 self.advance();
7161 let mutable = self.consume_if_mut();
7162 let name = self.parse_ident()?;
7163 let evidentiality = self.parse_evidentiality_opt();
7164 Ok(Pattern::RefBinding {
7165 mutable,
7166 name,
7167 evidentiality,
7168 })
7169 }
7170 Some(Token::Amp) => {
7172 self.advance();
7173 if matches!(self.current_token(), Some(Token::Lifetime(_))) {
7175 self.advance();
7176 }
7177 let mutable = self.consume_if_mut();
7178 let inner = self.parse_pattern()?;
7179 Ok(Pattern::Ref {
7180 mutable,
7181 pattern: Box::new(inner),
7182 })
7183 }
7184 Some(Token::AndAnd) => {
7186 self.advance();
7187 let inner = self.parse_pattern()?;
7188 let inner_ref = Pattern::Ref {
7190 mutable: false,
7191 pattern: Box::new(inner),
7192 };
7193 Ok(Pattern::Ref {
7194 mutable: false,
7195 pattern: Box::new(inner_ref),
7196 })
7197 }
7198 Some(Token::LParen) => {
7199 self.advance();
7200 let mut patterns = Vec::new();
7201 while !self.check(&Token::RParen) {
7202 patterns.push(self.parse_pattern()?);
7203 if !self.consume_if(&Token::Comma) {
7204 break;
7205 }
7206 }
7207 self.expect(Token::RParen)?;
7208 let _ev = self.parse_evidentiality_opt();
7210 Ok(Pattern::Tuple(patterns))
7213 }
7214 Some(Token::LBracket) => {
7215 self.advance();
7216 let mut patterns = Vec::new();
7217 while !self.check(&Token::RBracket) {
7218 patterns.push(self.parse_pattern()?);
7219 if !self.consume_if(&Token::Comma) {
7220 break;
7221 }
7222 }
7223 self.expect(Token::RBracket)?;
7224 Ok(Pattern::Slice(patterns))
7225 }
7226 Some(Token::IntLit(_))
7227 | Some(Token::HexLit(_))
7228 | Some(Token::OctalLit(_))
7229 | Some(Token::BinaryLit(_))
7230 | Some(Token::FloatLit(_))
7231 | Some(Token::StringLit(_))
7232 | Some(Token::CharLit(_))
7233 | Some(Token::True)
7234 | Some(Token::False)
7235 | Some(Token::Null) => {
7236 let lit = self.parse_literal()?;
7237 if self.check(&Token::DotDot) || self.check(&Token::DotDotEq) {
7239 let inclusive = self.consume_if(&Token::DotDotEq);
7240 if !inclusive {
7241 self.advance(); }
7243 let end = if matches!(
7245 self.current_token(),
7246 Some(Token::IntLit(_))
7247 | Some(Token::HexLit(_))
7248 | Some(Token::OctalLit(_))
7249 | Some(Token::BinaryLit(_))
7250 | Some(Token::CharLit(_))
7251 ) {
7252 let end_lit = self.parse_literal()?;
7253 Some(Box::new(Pattern::Literal(end_lit)))
7254 } else {
7255 None
7256 };
7257 Ok(Pattern::Range {
7258 start: Some(Box::new(Pattern::Literal(lit))),
7259 end,
7260 inclusive,
7261 })
7262 } else {
7263 Ok(Pattern::Literal(lit))
7264 }
7265 }
7266 Some(Token::SelfUpper) => {
7268 let span = self.current_span();
7269 self.advance();
7270
7271 let mut segments = vec![PathSegment {
7273 ident: Ident {
7274 name: "Self".to_string(),
7275 evidentiality: None,
7276 affect: None,
7277 span,
7278 },
7279 generics: None,
7280 }];
7281
7282 while self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
7284 let segment_name = self.parse_ident()?;
7285 segments.push(PathSegment {
7286 ident: segment_name,
7287 generics: None,
7288 });
7289 }
7290
7291 let path = TypePath { segments };
7292
7293 if self.check(&Token::LParen) {
7295 self.advance();
7296 let mut fields = Vec::new();
7297 while !self.check(&Token::RParen) {
7298 fields.push(self.parse_pattern()?);
7299 if !self.consume_if(&Token::Comma) {
7300 break;
7301 }
7302 }
7303 self.expect(Token::RParen)?;
7304 return Ok(Pattern::TupleStruct { path, fields });
7305 }
7306
7307 if self.check(&Token::LBrace) {
7309 self.advance();
7310 let mut fields = Vec::new();
7311 let mut rest = false;
7312 while !self.check(&Token::RBrace) {
7313 while matches!(
7314 self.current_token(),
7315 Some(Token::DocComment(_))
7316 | Some(
7317 Token::LineComment(_)
7318 | Token::TildeComment(_)
7319 | Token::BlockComment(_)
7320 )
7321 ) {
7322 self.advance();
7323 }
7324 if self.check(&Token::RBrace) {
7325 break;
7326 }
7327 if self.consume_if(&Token::DotDot) {
7328 rest = true;
7329 if !self.consume_if(&Token::Comma) {
7330 break;
7331 }
7332 continue;
7333 }
7334 let field_name = self.parse_ident()?;
7335 let pattern = if self.consume_if(&Token::Colon) {
7336 Some(self.parse_pattern()?)
7337 } else {
7338 None
7339 };
7340 fields.push(FieldPattern {
7341 name: field_name,
7342 pattern,
7343 });
7344 if !self.consume_if(&Token::Comma) {
7345 break;
7346 }
7347 }
7348 self.expect(Token::RBrace)?;
7349 return Ok(Pattern::Struct { path, fields, rest });
7350 }
7351
7352 return Ok(Pattern::Path(path));
7354 }
7355 Some(Token::Crate) | Some(Token::SelfLower) | Some(Token::Xi) | Some(Token::Super) | Some(Token::IntensityUp) => {
7357 let keyword = self.current_token().cloned();
7358 let span = self.current_span();
7359 self.advance();
7360
7361 if !self.consume_if(&Token::ColonColon) && !self.consume_if(&Token::MiddleDot) {
7363 if matches!(keyword, Some(Token::SelfLower) | Some(Token::Xi)) {
7365 return Ok(Pattern::Ident {
7366 mutable: false,
7367 name: Ident {
7368 name: "self".to_string(),
7369 evidentiality: None,
7370 affect: None,
7371 span,
7372 },
7373 evidentiality: self.parse_evidentiality_opt(),
7374 });
7375 }
7376 return Err(ParseError::Custom(
7377 "expected · after crate/super in path pattern".to_string(),
7378 ));
7379 }
7380
7381 let keyword_name = match keyword {
7383 Some(Token::Crate) => "crate",
7384 Some(Token::SelfLower) | Some(Token::Xi) => "self", Some(Token::Super) | Some(Token::IntensityUp) => "super", _ => unreachable!(),
7387 };
7388 let mut segments = vec![PathSegment {
7389 ident: Ident {
7390 name: keyword_name.to_string(),
7391 evidentiality: None,
7392 affect: None,
7393 span,
7394 },
7395 generics: None,
7396 }];
7397
7398 loop {
7400 let segment_name = self.parse_ident()?;
7401 segments.push(PathSegment {
7402 ident: segment_name,
7403 generics: None,
7404 });
7405
7406 if !self.consume_if(&Token::ColonColon) && !self.consume_if(&Token::MiddleDot) {
7407 break;
7408 }
7409 }
7410
7411 let path = TypePath { segments };
7412
7413 if self.check(&Token::LParen) {
7415 self.advance();
7416 let mut fields = Vec::new();
7417 while !self.check(&Token::RParen) {
7418 fields.push(self.parse_pattern()?);
7419 if !self.consume_if(&Token::Comma) {
7420 break;
7421 }
7422 }
7423 self.expect(Token::RParen)?;
7424 return Ok(Pattern::TupleStruct { path, fields });
7425 }
7426
7427 if self.check(&Token::LBrace) {
7429 self.advance();
7430 let mut fields = Vec::new();
7431 let mut rest = false;
7432 while !self.check(&Token::RBrace) {
7433 while matches!(
7434 self.current_token(),
7435 Some(Token::DocComment(_))
7436 | Some(
7437 Token::LineComment(_)
7438 | Token::TildeComment(_)
7439 | Token::BlockComment(_)
7440 )
7441 ) {
7442 self.advance();
7443 }
7444 if self.check(&Token::RBrace) {
7445 break;
7446 }
7447 if self.consume_if(&Token::DotDot) {
7448 rest = true;
7449 if !self.consume_if(&Token::Comma) {
7450 break;
7451 }
7452 continue;
7453 }
7454 let field_name = self.parse_ident()?;
7455 let pattern = if self.consume_if(&Token::Colon) {
7456 Some(self.parse_pattern()?)
7457 } else {
7458 None
7459 };
7460 fields.push(FieldPattern {
7461 name: field_name,
7462 pattern,
7463 });
7464 if !self.consume_if(&Token::Comma) {
7465 break;
7466 }
7467 }
7468 self.expect(Token::RBrace)?;
7469 return Ok(Pattern::Struct { path, fields, rest });
7470 }
7471
7472 return Ok(Pattern::Path(path));
7474 }
7475 Some(Token::Ident(_)) => {
7476 let name = self.parse_ident()?;
7477
7478 if self.consume_if(&Token::ColonColon) || self.consume_if(&Token::MiddleDot) {
7480 let mut segments = vec![PathSegment {
7482 ident: name,
7483 generics: None,
7484 }];
7485
7486 loop {
7488 let segment_name = self.parse_ident()?;
7489 segments.push(PathSegment {
7490 ident: segment_name,
7491 generics: None,
7492 });
7493
7494 if !self.consume_if(&Token::ColonColon)
7495 && !self.consume_if(&Token::MiddleDot)
7496 {
7497 break;
7498 }
7499 }
7500
7501 let path = TypePath { segments };
7502
7503 if self.check(&Token::LParen) {
7505 self.advance();
7506 let mut fields = Vec::new();
7507 while !self.check(&Token::RParen) {
7508 fields.push(self.parse_pattern()?);
7509 if !self.consume_if(&Token::Comma) {
7510 break;
7511 }
7512 }
7513 self.expect(Token::RParen)?;
7514 return Ok(Pattern::TupleStruct { path, fields });
7515 }
7516
7517 if self.check(&Token::LBrace) {
7519 self.advance();
7520 let mut fields = Vec::new();
7521 let mut rest = false;
7522 while !self.check(&Token::RBrace) {
7523 while matches!(
7525 self.current_token(),
7526 Some(Token::DocComment(_))
7527 | Some(
7528 Token::LineComment(_)
7529 | Token::TildeComment(_)
7530 | Token::BlockComment(_)
7531 )
7532 ) {
7533 self.advance();
7534 }
7535 if self.check(&Token::RBrace) {
7536 break;
7537 }
7538
7539 if self.consume_if(&Token::DotDot) {
7541 rest = true;
7542 if !self.consume_if(&Token::Comma) {
7543 break;
7544 }
7545 continue;
7546 }
7547
7548 let field_name = self.parse_ident()?;
7549 let pattern = if self.consume_if(&Token::Colon) {
7550 Some(self.parse_pattern()?)
7551 } else {
7552 None
7554 };
7555 fields.push(FieldPattern {
7556 name: field_name,
7557 pattern,
7558 });
7559
7560 if !self.consume_if(&Token::Comma) {
7561 break;
7562 }
7563 }
7564 self.expect(Token::RBrace)?;
7565 return Ok(Pattern::Struct { path, fields, rest });
7566 }
7567
7568 return Ok(Pattern::Path(path));
7570 }
7571
7572 if self.check(&Token::LBrace) {
7574 let path = TypePath {
7576 segments: vec![PathSegment {
7577 ident: name,
7578 generics: None,
7579 }],
7580 };
7581 self.advance();
7582 let mut fields = Vec::new();
7583 let mut rest = false;
7584 while !self.check(&Token::RBrace) {
7585 while matches!(
7586 self.current_token(),
7587 Some(Token::DocComment(_))
7588 | Some(
7589 Token::LineComment(_)
7590 | Token::TildeComment(_)
7591 | Token::BlockComment(_)
7592 )
7593 ) {
7594 self.advance();
7595 }
7596 if self.check(&Token::RBrace) {
7597 break;
7598 }
7599 if self.consume_if(&Token::DotDot) {
7600 rest = true;
7601 break;
7602 }
7603 let field_name = self.parse_ident()?;
7604 let pattern = if self.consume_if(&Token::Colon) {
7605 Some(self.parse_pattern()?)
7606 } else {
7607 None
7608 };
7609 fields.push(FieldPattern {
7610 name: field_name,
7611 pattern,
7612 });
7613 if !self.consume_if(&Token::Comma) {
7614 break;
7615 }
7616 }
7617 self.expect(Token::RBrace)?;
7618 return Ok(Pattern::Struct { path, fields, rest });
7619 }
7620
7621 if self.check(&Token::LParen) {
7623 let path = TypePath {
7624 segments: vec![PathSegment {
7625 ident: name,
7626 generics: None,
7627 }],
7628 };
7629 self.advance();
7630 let mut fields = Vec::new();
7631 while !self.check(&Token::RParen) {
7632 fields.push(self.parse_pattern()?);
7633 if !self.consume_if(&Token::Comma) {
7634 break;
7635 }
7636 }
7637 self.expect(Token::RParen)?;
7638 return Ok(Pattern::TupleStruct { path, fields });
7639 }
7640
7641 let evidentiality = self.parse_evidentiality_opt();
7643 Ok(Pattern::Ident {
7644 mutable: false,
7645 name,
7646 evidentiality,
7647 })
7648 }
7649 Some(Token::SelfLower) | Some(Token::Xi) => {
7650 let span = self.current_span();
7652 self.advance();
7653 Ok(Pattern::Ident {
7654 mutable: false,
7655 name: Ident {
7656 name: "self".to_string(),
7657 evidentiality: None,
7658 affect: None,
7659 span,
7660 },
7661 evidentiality: None,
7662 })
7663 }
7664 Some(ref token) if Self::keyword_as_ident(token).is_some() => {
7666 let name = self.parse_ident()?;
7667 let evidentiality = self.parse_evidentiality_opt();
7668 Ok(Pattern::Ident {
7669 mutable: false,
7670 name,
7671 evidentiality,
7672 })
7673 }
7674 Some(token) => Err(ParseError::UnexpectedToken {
7675 expected: "pattern".to_string(),
7676 found: token,
7677 span: self.current_span(),
7678 }),
7679 None => Err(ParseError::UnexpectedEof),
7680 }
7681 }
7682
7683 fn parse_literal(&mut self) -> ParseResult<Literal> {
7684 match self.current_token().cloned() {
7685 Some(Token::IntLit(s)) => {
7686 self.advance();
7687 Ok(Literal::Int {
7688 value: s,
7689 base: NumBase::Decimal,
7690 suffix: None,
7691 })
7692 }
7693 Some(Token::HexLit(s)) => {
7694 self.advance();
7695 Ok(Literal::Int {
7696 value: s,
7697 base: NumBase::Hex,
7698 suffix: None,
7699 })
7700 }
7701 Some(Token::OctalLit(s)) => {
7702 self.advance();
7703 Ok(Literal::Int {
7704 value: s,
7705 base: NumBase::Octal,
7706 suffix: None,
7707 })
7708 }
7709 Some(Token::BinaryLit(s)) => {
7710 self.advance();
7711 Ok(Literal::Int {
7712 value: s,
7713 base: NumBase::Binary,
7714 suffix: None,
7715 })
7716 }
7717 Some(Token::FloatLit(s)) => {
7718 self.advance();
7719 Ok(Literal::Float {
7720 value: s,
7721 suffix: None,
7722 })
7723 }
7724 Some(Token::StringLit(s)) => {
7725 self.advance();
7726 Ok(Literal::String(s))
7727 }
7728 Some(Token::CharLit(c)) => {
7729 self.advance();
7730 Ok(Literal::Char(c))
7731 }
7732 Some(Token::True) => {
7733 self.advance();
7734 Ok(Literal::Bool(true))
7735 }
7736 Some(Token::False) => {
7737 self.advance();
7738 Ok(Literal::Bool(false))
7739 }
7740 Some(Token::Null) => {
7741 self.advance();
7742 Ok(Literal::Null)
7743 }
7744 _ => Err(ParseError::Custom("expected literal".to_string())),
7745 }
7746 }
7747
7748 fn expr_to_incorporation_segment(&self, expr: Expr) -> ParseResult<IncorporationSegment> {
7753 match expr {
7754 Expr::Path(path) if path.segments.len() == 1 => Ok(IncorporationSegment {
7755 name: path.segments[0].ident.clone(),
7756 args: None,
7757 }),
7758 Expr::Call { func, args } => {
7759 match *func {
7760 Expr::Path(path) => {
7761 if let Some(last_seg) = path.segments.last() {
7764 return Ok(IncorporationSegment {
7765 name: last_seg.ident.clone(),
7766 args: Some(args),
7767 });
7768 }
7769 Err(ParseError::Custom(
7770 "incorporation chain: empty path".to_string(),
7771 ))
7772 }
7773 Expr::Field { expr, field } => Ok(IncorporationSegment {
7775 name: field.clone(),
7776 args: Some(std::iter::once(*expr).chain(args).collect()),
7777 }),
7778 _ => Err(ParseError::Custom(
7779 "incorporation chain must start with identifier or call".to_string(),
7780 )),
7781 }
7782 }
7783 Expr::Field { expr, field } => {
7786 Ok(IncorporationSegment {
7789 name: field.clone(),
7790 args: Some(vec![*expr]), })
7792 }
7793 Expr::Literal(_) => Ok(IncorporationSegment {
7796 name: Ident {
7797 name: "__lit__".to_string(),
7798 evidentiality: None,
7799 affect: None,
7800 span: crate::span::Span::default(),
7801 },
7802 args: Some(vec![expr]),
7803 }),
7804 Expr::Unary { .. } => Ok(IncorporationSegment {
7807 name: Ident {
7808 name: "__unary__".to_string(),
7809 evidentiality: None,
7810 affect: None,
7811 span: crate::span::Span::default(),
7812 },
7813 args: Some(vec![expr]),
7814 }),
7815 Expr::Index { expr: base, index } => Ok(IncorporationSegment {
7817 name: Ident {
7818 name: "__index__".to_string(),
7819 evidentiality: None,
7820 affect: None,
7821 span: crate::span::Span::default(),
7822 },
7823 args: Some(vec![*base, *index]),
7824 }),
7825 other => Ok(IncorporationSegment {
7828 name: Ident {
7829 name: "__expr__".to_string(),
7830 evidentiality: None,
7831 affect: None,
7832 span: crate::span::Span::default(),
7833 },
7834 args: Some(vec![other]),
7835 }),
7836 }
7837 }
7838
7839 fn keyword_as_ident(token: &Token) -> Option<&'static str> {
7841 match token {
7842 Token::Packed => Some("packed"),
7844 Token::As => Some("as"),
7845 Token::Type => Some("type"),
7846 Token::Crate => Some("crate"),
7847 Token::Super => Some("super"),
7848 Token::Mod => Some("mod"),
7849 Token::Use => Some("use"),
7850 Token::Pub => Some("pub"),
7851 Token::Const => Some("const"),
7852 Token::Static => Some("static"),
7853 Token::Extern => Some("extern"),
7854 Token::Unsafe => Some("unsafe"),
7855 Token::Async => Some("async"),
7856 Token::Await => Some("await"),
7857 Token::Move => Some("move"),
7858 Token::Dyn => Some("dyn"),
7859 Token::Atomic => Some("atomic"),
7860 Token::Volatile => Some("volatile"),
7861 Token::Naked => Some("naked"),
7862 Token::Connect => Some("connect"),
7863 Token::Close => Some("close"),
7864 Token::Simd => Some("simd"),
7865 Token::Derive => Some("derive"),
7866 Token::On => Some("on"),
7867 Token::Send => Some("send"),
7868 Token::Recv => Some("recv"),
7869 Token::Stream => Some("stream"),
7870 Token::Timeout => Some("timeout"),
7871 Token::Retry => Some("retry"),
7872 Token::Header => Some("header"),
7873 Token::Body => Some("body"),
7874 Token::Http => Some("http"),
7875 Token::Https => Some("https"),
7876 Token::Ws => Some("ws"),
7877 Token::Wss => Some("wss"),
7878 Token::Grpc => Some("grpc"),
7879 Token::Kafka => Some("kafka"),
7880 Token::Amqp => Some("amqp"),
7881 Token::GraphQL => Some("graphql"),
7882 Token::Actor => Some("actor"),
7883 Token::Saga => Some("saga"),
7884 Token::Scope => Some("scope"),
7885 Token::Rune => Some("rune"),
7886 Token::Split => Some("split"),
7888 Token::Trigger => Some("trigger"),
7889 Token::Location => Some("location"),
7890 Token::States => Some("states"),
7891 Token::To => Some("to"),
7892 Token::From => Some("from"),
7893 Token::Headspace => Some("headspace"),
7894 Token::CoCon => Some("cocon"),
7895 Token::Reality => Some("reality"),
7896 Token::Layer => Some("layer"),
7897 Token::Anima => Some("anima"),
7898 Token::Struct => Some("sigil"), Token::Parallel => Some("Parallel"),
7901 Token::Nu => Some("Nu"),
7902 Token::Lambda => Some("Lambda"),
7903 Token::Delta => Some("Delta"),
7904 Token::Tau => Some("Tau"),
7905 Token::Phi => Some("Phi"),
7906 Token::Sigma => Some("Sigma"),
7907 Token::Rho => Some("Rho"),
7908 Token::Pi => Some("Pi"),
7909 Token::Epsilon => Some("Epsilon"),
7910 Token::Omega => Some("Omega"),
7911 Token::Alpha => Some("Alpha"),
7912 Token::Zeta => Some("Zeta"),
7913 Token::Mu => Some("Mu"),
7914 Token::Chi => Some("Chi"),
7915 Token::Xi => Some("Xi"),
7916 Token::Psi => Some("Psi"),
7917 Token::Theta => Some("Theta"),
7918 Token::Kappa => Some("Kappa"),
7919 Token::Nabla => Some("∇"),
7920 Token::Gpu => Some("Gpu"),
7921 Token::Broadcast => Some("broadcast"),
7923 Token::Gather => Some("gather"),
7924 Token::Distribute => Some("distribute"),
7925 Token::Interfere => Some("interfere"),
7926 Token::Consensus => Some("consensus"),
7927 Token::Ref => Some("ref"),
7929 Token::Null => Some("null"),
7930 Token::Linear => Some("linear"),
7932 _ => None,
7933 }
7934 }
7935
7936 pub(crate) fn parse_ident(&mut self) -> ParseResult<Ident> {
7937 match self.current.take() {
7938 Some((Token::Ident(name), span)) => {
7939 self.current = self.lexer.next_token();
7940 let evidentiality = self.parse_unambiguous_evidentiality_opt();
7943 let affect = self.parse_affect_opt();
7945 Ok(Ident {
7946 name,
7947 evidentiality,
7948 affect,
7949 span,
7950 })
7951 }
7952 Some((ref token, span)) if Self::keyword_as_ident(token).is_some() => {
7953 let mut name = Self::keyword_as_ident(token).unwrap().to_string();
7954 self.current = self.lexer.next_token();
7955 if let Some((Token::Ident(suffix), suffix_span)) = &self.current {
7958 if suffix.starts_with('_') {
7959 name.push_str(suffix);
7960 let merged_span = span.merge(*suffix_span);
7961 self.current = self.lexer.next_token();
7962 let evidentiality = self.parse_unambiguous_evidentiality_opt();
7963 let affect = self.parse_affect_opt();
7964 return Ok(Ident {
7965 name,
7966 evidentiality,
7967 affect,
7968 span: merged_span,
7969 });
7970 }
7971 }
7972 let evidentiality = self.parse_unambiguous_evidentiality_opt();
7973 let affect = self.parse_affect_opt();
7974 Ok(Ident {
7975 name,
7976 evidentiality,
7977 affect,
7978 span,
7979 })
7980 }
7981 Some((token, span)) => {
7982 self.current = Some((token.clone(), span));
7983 Err(ParseError::UnexpectedToken {
7984 expected: "identifier".to_string(),
7985 found: token,
7986 span,
7987 })
7988 }
7989 None => Err(ParseError::UnexpectedEof),
7990 }
7991 }
7992
7993 fn parse_evidentiality_opt(&mut self) -> Option<Evidentiality> {
7994 let mut ev = None;
7997 loop {
7998 match self.current_token() {
7999 Some(Token::Bang) => {
8000 self.advance();
8001 ev = Some(Evidentiality::Known);
8002 }
8003 Some(Token::Question) => {
8004 self.advance();
8005 ev = Some(Evidentiality::Uncertain);
8006 }
8007 Some(Token::Tilde) => {
8008 self.advance();
8009 ev = Some(Evidentiality::Reported);
8010 }
8011 Some(Token::Lozenge) => {
8012 self.advance();
8013 ev = Some(Evidentiality::Predicted);
8014 }
8015 Some(Token::Interrobang) => {
8016 self.advance();
8017 ev = Some(Evidentiality::Paradox);
8018 }
8019 _ => break,
8020 }
8021 }
8022 ev
8023 }
8024
8025 fn parse_unambiguous_evidentiality_opt(&mut self) -> Option<Evidentiality> {
8028 let mut ev = None;
8029 loop {
8030 match self.current_token() {
8031 Some(Token::Tilde) => {
8032 self.advance();
8033 ev = Some(Evidentiality::Reported);
8034 }
8035 Some(Token::Lozenge) => {
8036 self.advance();
8037 ev = Some(Evidentiality::Predicted);
8038 }
8039 Some(Token::Interrobang) => {
8040 self.advance();
8041 ev = Some(Evidentiality::Paradox);
8042 }
8043 _ => break,
8044 }
8045 }
8046 ev
8047 }
8048
8049 fn parse_affect_opt(&mut self) -> Option<Affect> {
8053 let mut sentiment = None;
8054 let mut sarcasm = false;
8055 let mut intensity = None;
8056 let mut formality = None;
8057 let mut emotion = None;
8058 let mut confidence = None;
8059 let mut found_any = false;
8060
8061 loop {
8063 match self.current_token() {
8064 Some(Token::DirectSum) => {
8066 self.advance();
8067 sentiment = Some(Sentiment::Positive);
8068 found_any = true;
8069 }
8070 Some(Token::AffectNegative) => {
8071 self.advance();
8072 sentiment = Some(Sentiment::Negative);
8073 found_any = true;
8074 }
8075 Some(Token::AffectNeutral) => {
8076 self.advance();
8077 sentiment = Some(Sentiment::Neutral);
8078 found_any = true;
8079 }
8080 Some(Token::IronyMark) => {
8082 self.advance();
8083 sarcasm = true;
8084 found_any = true;
8085 }
8086 Some(Token::IntensityUp) => {
8088 self.advance();
8089 intensity = Some(Intensity::Up);
8090 found_any = true;
8091 }
8092 Some(Token::IntensityDown) => {
8093 self.advance();
8094 intensity = Some(Intensity::Down);
8095 found_any = true;
8096 }
8097 Some(Token::IntensityMax) => {
8098 self.advance();
8099 intensity = Some(Intensity::Max);
8100 found_any = true;
8101 }
8102 Some(Token::FormalRegister) => {
8104 self.advance();
8105 formality = Some(Formality::Formal);
8106 found_any = true;
8107 }
8108 Some(Token::InformalRegister) => {
8109 self.advance();
8110 formality = Some(Formality::Informal);
8111 found_any = true;
8112 }
8113 Some(Token::EmotionJoy) => {
8115 self.advance();
8116 emotion = Some(Emotion::Joy);
8117 found_any = true;
8118 }
8119 Some(Token::EmotionSadness) => {
8120 self.advance();
8121 emotion = Some(Emotion::Sadness);
8122 found_any = true;
8123 }
8124 Some(Token::EmotionAnger) => {
8125 self.advance();
8126 emotion = Some(Emotion::Anger);
8127 found_any = true;
8128 }
8129 Some(Token::EmotionFear) => {
8130 self.advance();
8131 emotion = Some(Emotion::Fear);
8132 found_any = true;
8133 }
8134 Some(Token::EmotionSurprise) => {
8135 self.advance();
8136 emotion = Some(Emotion::Surprise);
8137 found_any = true;
8138 }
8139 Some(Token::EmotionLove) => {
8140 self.advance();
8141 emotion = Some(Emotion::Love);
8142 found_any = true;
8143 }
8144 Some(Token::ConfidenceHigh) => {
8146 self.advance();
8147 confidence = Some(Confidence::High);
8148 found_any = true;
8149 }
8150 Some(Token::ConfidenceMedium) => {
8151 self.advance();
8152 confidence = Some(Confidence::Medium);
8153 found_any = true;
8154 }
8155 Some(Token::ConfidenceLow) => {
8156 self.advance();
8157 confidence = Some(Confidence::Low);
8158 found_any = true;
8159 }
8160 _ => break,
8161 }
8162 }
8163
8164 if found_any {
8165 Some(Affect {
8166 sentiment,
8167 sarcasm,
8168 intensity,
8169 formality,
8170 emotion,
8171 confidence,
8172 })
8173 } else {
8174 None
8175 }
8176 }
8177
8178 pub(crate) fn parse_generics_opt(&mut self) -> ParseResult<Option<Generics>> {
8179 let use_brackets = if self.consume_if(&Token::Lt) {
8181 false
8182 } else if self.consume_if(&Token::LBracket) {
8183 true
8184 } else {
8185 return Ok(None);
8186 };
8187
8188 let mut params = Vec::new();
8189 while !self.is_eof() {
8191 self.skip_comments();
8193
8194 if use_brackets {
8195 if self.check(&Token::RBracket) {
8196 break;
8197 }
8198 } else if self.check_gt() {
8199 break;
8200 }
8201
8202 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
8204 self.advance();
8205 params.push(GenericParam::Lifetime(lt));
8206 if !self.consume_if(&Token::Comma) {
8207 break;
8208 }
8209 continue;
8210 }
8211
8212 if self.consume_if(&Token::Const) {
8214 let name = self.parse_ident()?;
8215 let ty = if self.consume_if(&Token::Colon) {
8217 self.parse_type()?
8218 } else {
8219 TypeExpr::Infer
8220 };
8221 let default = if self.consume_if(&Token::Eq) {
8223 Some(Box::new(self.parse_expr()?))
8224 } else {
8225 None
8226 };
8227 params.push(GenericParam::Const { name, ty, default });
8228 if !self.consume_if(&Token::Comma) {
8229 break;
8230 }
8231 continue;
8232 }
8233
8234 let name = self.parse_ident()?;
8236 let evidentiality = self.parse_evidentiality_opt();
8237 let bounds = if self.consume_if(&Token::Colon) {
8238 self.parse_type_bounds()?
8239 } else {
8240 vec![]
8241 };
8242 let default = if self.consume_if(&Token::Eq) {
8244 Some(self.parse_type()?)
8245 } else {
8246 None
8247 };
8248 params.push(GenericParam::Type {
8249 name,
8250 bounds,
8251 evidentiality,
8252 default,
8253 });
8254
8255 if !self.consume_if(&Token::Comma) {
8256 break;
8257 }
8258 }
8259 if use_brackets {
8261 self.expect(Token::RBracket)?;
8262 } else {
8263 self.expect_gt()?;
8265 }
8266
8267 Ok(Some(Generics { params }))
8268 }
8269
8270 pub(crate) fn parse_where_clause_opt(&mut self) -> ParseResult<Option<WhereClause>> {
8271 if !self.consume_if(&Token::Where) {
8272 return Ok(None);
8273 }
8274
8275 let mut predicates = Vec::new();
8276 loop {
8277 self.skip_comments(); let is_expr_predicate = if let Some(Token::Ident(_)) = self.current_token() {
8284 let next = self.peek_next();
8286 matches!(
8287 next,
8288 Some(Token::Percent)
8289 | Some(Token::EqEq)
8290 | Some(Token::NotEq)
8291 | Some(Token::Plus)
8292 | Some(Token::Minus)
8293 | Some(Token::Star)
8294 | Some(Token::Slash)
8295 )
8296 } else {
8297 false
8298 };
8299
8300 if is_expr_predicate {
8301 let _expr = self.parse_expr()?;
8303 self.skip_comments();
8305 if !self.consume_if(&Token::Comma) {
8306 break;
8307 }
8308 self.skip_comments();
8309 if self.check(&Token::LBrace) {
8310 break;
8311 }
8312 continue;
8313 }
8314
8315 let ty = self.parse_type()?;
8316
8317 if self.check(&Token::Colon) {
8319 self.advance(); let bounds = self.parse_type_bounds()?;
8321 self.skip_comments(); predicates.push(WherePredicate { ty, bounds });
8323 } else {
8324 }
8327
8328 if !self.consume_if(&Token::Comma) {
8329 break;
8330 }
8331 self.skip_comments();
8333 if self.check(&Token::LBrace) {
8334 break;
8335 }
8336 }
8337
8338 Ok(Some(WhereClause { predicates }))
8339 }
8340
8341 pub(crate) fn parse_params(&mut self) -> ParseResult<Vec<Param>> {
8342 let mut params = Vec::new();
8343 while !self.check(&Token::RParen) && !self.is_eof() {
8344 self.skip_comments();
8346 while self.check(&Token::At) || self.check(&Token::Hash) {
8347 self.skip_attribute()?;
8348 self.skip_comments();
8349 }
8350 if self.check(&Token::RParen) {
8351 break;
8352 }
8353 let pattern = self.parse_pattern()?;
8354 let ty = if self.consume_if(&Token::Colon) {
8356 self.parse_type()?
8357 } else {
8358 TypeExpr::Infer
8359 };
8360 params.push(Param { pattern, ty });
8361 if !self.consume_if(&Token::Comma) {
8362 break;
8363 }
8364 }
8365 Ok(params)
8366 }
8367
8368 fn skip_attribute(&mut self) -> ParseResult<()> {
8370 if self.check(&Token::At) || self.check(&Token::Hash) {
8372 self.advance();
8373 }
8374 if self.consume_if(&Token::LBracket) {
8376 let mut depth = 1;
8377 while depth > 0 && !self.is_eof() {
8378 match self.current_token() {
8379 Some(Token::LBracket) => depth += 1,
8380 Some(Token::RBracket) => depth -= 1,
8381 _ => {}
8382 }
8383 self.advance();
8384 }
8385 }
8386 Ok(())
8387 }
8388
8389 fn parse_field_defs(&mut self) -> ParseResult<Vec<FieldDef>> {
8390 let mut fields = Vec::new();
8391 while !self.check(&Token::RBrace) && !self.is_eof() {
8392 while matches!(
8394 self.current_token(),
8395 Some(Token::DocComment(_))
8396 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
8397 ) || self.check(&Token::Hash)
8398 || self.check(&Token::At)
8399 {
8400 if self.check(&Token::Hash) || self.check(&Token::At) {
8401 self.skip_attribute()?;
8402 } else {
8403 self.advance();
8404 }
8405 }
8406 if self.check(&Token::RBrace) {
8407 break;
8408 }
8409 let visibility = self.parse_visibility()?;
8410 let name = self.parse_ident()?;
8411 let _evidentiality = self.parse_evidentiality_opt();
8413 self.expect(Token::Colon)?;
8414 let ty = self.parse_type()?;
8415 let default = if self.consume_if(&Token::Eq) {
8417 Some(self.parse_expr()?)
8418 } else {
8419 None
8420 };
8421 fields.push(FieldDef {
8422 visibility,
8423 name,
8424 ty,
8425 default,
8426 });
8427 if !self.consume_if(&Token::Comma) {
8428 break;
8429 }
8430 }
8431 Ok(fields)
8432 }
8433
8434 fn parse_expr_list(&mut self) -> ParseResult<Vec<Expr>> {
8435 let mut exprs = Vec::new();
8436 self.skip_comments();
8438 while !self.check(&Token::RParen) && !self.check(&Token::RBracket) && !self.is_eof() {
8439 let expr = if let Some(Token::Ident(name)) = self.current_token().cloned() {
8443 let is_named_arg = self.peek_next() == Some(&Token::Colon);
8445 if is_named_arg {
8446 let span = self.current_span();
8447 self.advance(); self.advance(); let value = self.parse_expr()?;
8450 Expr::NamedArg {
8452 name: Ident {
8453 name,
8454 evidentiality: None,
8455 affect: None,
8456 span,
8457 },
8458 value: Box::new(value),
8459 }
8460 } else {
8461 self.parse_expr()?
8462 }
8463 } else {
8464 self.parse_expr()?
8465 };
8466 exprs.push(expr);
8467 if !self.consume_if(&Token::Comma) {
8468 break;
8469 }
8470 self.skip_comments();
8472 }
8473 Ok(exprs)
8474 }
8475
8476 fn parse_struct_fields(&mut self) -> ParseResult<(Vec<FieldInit>, Option<Box<Expr>>)> {
8477 let mut fields = Vec::new();
8478 let mut rest = None;
8479
8480 while !self.check(&Token::RBrace) && !self.is_eof() {
8481 while matches!(
8483 self.current_token(),
8484 Some(Token::DocComment(_))
8485 | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
8486 | Some(Token::Hash)
8487 ) {
8488 if self.check(&Token::Hash) {
8489 self.advance();
8491 self.consume_if(&Token::Bang); if self.consume_if(&Token::LBracket) {
8493 let mut depth = 1;
8494 while depth > 0 && !self.is_eof() {
8495 match self.current_token() {
8496 Some(Token::LBracket) => depth += 1,
8497 Some(Token::RBracket) => depth -= 1,
8498 _ => {}
8499 }
8500 self.advance();
8501 }
8502 }
8503 } else {
8504 self.advance();
8505 }
8506 }
8507 if self.check(&Token::RBrace) {
8508 break;
8509 }
8510 if self.consume_if(&Token::DotDot) {
8511 rest = Some(Box::new(self.parse_expr()?));
8512 break;
8513 }
8514
8515 let name = self.parse_ident()?;
8516 let value = if self.consume_if(&Token::Colon) {
8517 Some(self.parse_expr()?)
8518 } else {
8519 None
8520 };
8521 fields.push(FieldInit { name, value });
8522
8523 if !self.consume_if(&Token::Comma) {
8524 break;
8525 }
8526 }
8527
8528 Ok((fields, rest))
8529 }
8530
8531 fn is_item_start(&mut self) -> bool {
8532 match self.current_token() {
8533 Some(Token::Fn) | Some(Token::Lambda) | Some(Token::Struct) | Some(Token::Sigma) | Some(Token::Enum) | Some(Token::Trait) | Some(Token::Theta) | Some(Token::Impl) | Some(Token::Type) | Some(Token::Mod) | Some(Token::Use)
8539 | Some(Token::Const) | Some(Token::Static) | Some(Token::Actor) | Some(Token::Pub)
8540 | Some(Token::Extern) => true,
8541 Some(Token::Async) | Some(Token::Hourglass) => {
8543 matches!(self.peek_next(), Some(Token::Fn) | Some(Token::Lambda))
8544 }
8545 _ => false,
8546 }
8547 }
8548
8549 fn is_in_condition(&self) -> bool {
8550 self.in_condition
8551 }
8552
8553 fn parse_condition(&mut self) -> ParseResult<Expr> {
8555 let was_in_condition = self.in_condition;
8556 self.in_condition = true;
8557 let result = self.parse_expr();
8558 self.in_condition = was_in_condition;
8559 result
8560 }
8561
8562 fn parse_legion_operator(&mut self, lhs: Expr) -> ParseResult<Expr> {
8570 match self.current_token() {
8571 Some(Token::Interfere) => {
8572 self.advance();
8574 let field = self.parse_expr_bp(15)?; Ok(Expr::LegionInterference {
8576 query: Box::new(lhs),
8577 field: Box::new(field),
8578 })
8579 }
8580 Some(Token::Distribute) => {
8581 self.advance();
8583 let count = self.parse_expr_bp(15)?;
8584 Ok(Expr::LegionDistribute {
8585 task: Box::new(lhs),
8586 count: Box::new(count),
8587 })
8588 }
8589 Some(Token::Broadcast) => {
8590 self.advance();
8592 let target = self.parse_expr_bp(15)?;
8593 Ok(Expr::LegionBroadcast {
8594 signal: Box::new(lhs),
8595 target: Box::new(target),
8596 })
8597 }
8598 Some(Token::Gather) => {
8599 self.advance();
8601 Ok(Expr::LegionGather {
8602 fragments: Box::new(lhs),
8603 })
8604 }
8605 Some(Token::Consensus) => {
8606 self.advance();
8608 Ok(Expr::LegionConsensus {
8609 contributions: Box::new(lhs),
8610 })
8611 }
8612 Some(Token::ConfidenceHigh) => {
8613 self.advance();
8615 Ok(Expr::LegionResonance {
8616 expr: Box::new(lhs),
8617 })
8618 }
8619 _ => Ok(lhs),
8620 }
8621 }
8622
8623 fn is_legion_field_ident(&self, name: &str) -> bool {
8626 name.ends_with('∿')
8627 }
8628}
8629
8630fn infix_binding_power(op: BinOp) -> (u8, u8) {
8632 match op {
8633 BinOp::Or => (1, 2),
8634 BinOp::And => (3, 4),
8635 BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge => (5, 6),
8636 BinOp::BitOr => (7, 8),
8637 BinOp::BitXor => (9, 10),
8638 BinOp::BitAnd => (11, 12),
8639 BinOp::Shl | BinOp::Shr => (13, 14),
8640 BinOp::Add | BinOp::Sub | BinOp::Concat => (15, 16),
8641 BinOp::Mul
8642 | BinOp::Div
8643 | BinOp::Rem
8644 | BinOp::MatMul
8645 | BinOp::Hadamard
8646 | BinOp::TensorProd
8647 | BinOp::Convolve => (17, 18),
8648 BinOp::Pow => (20, 19), }
8650}
8651
8652#[cfg(test)]
8653mod tests {
8654 use super::*;
8655
8656 #[test]
8657 fn test_parse_function() {
8658 let source = "fn hello(name: str) -> str { return name; }";
8660 let mut parser = Parser::new(source);
8661 let file = parser.parse_file().unwrap();
8662 assert_eq!(file.items.len(), 1);
8663 }
8664
8665 #[test]
8666 fn test_parse_pipe_chain() {
8667 let source = "fn main() { let result = data|τ{_ * 2}|φ{_ > 0}|σ; }";
8668 let mut parser = Parser::new(source);
8669 let file = parser.parse_file().unwrap();
8670 assert_eq!(file.items.len(), 1);
8671 }
8672
8673 #[test]
8674 fn test_parse_async_function() {
8675 let source = "async fn fetch(url: str) -> Response~ { return client·get(url)|await; }";
8676 let mut parser = Parser::new(source);
8677 let file = parser.parse_file().unwrap();
8678 assert_eq!(file.items.len(), 1);
8679 }
8680
8681 #[test]
8682 fn test_parse_struct() {
8683 let source = "struct Point { x: f64, y: f64 }";
8684 let mut parser = Parser::new(source);
8685 let file = parser.parse_file().unwrap();
8686 assert_eq!(file.items.len(), 1);
8687 }
8688
8689 #[test]
8690 fn test_parse_actor() {
8691 let source = r#"
8693 actor Counter {
8694 state: i64 = 0
8695 on Increment(n: i64) { return self.state + n; }
8696 }
8697 "#;
8698 let mut parser = Parser::new(source);
8699 let file = parser.parse_file().unwrap();
8700 assert_eq!(file.items.len(), 1);
8701 }
8702
8703 #[test]
8704 fn test_parse_number_bases() {
8705 let source = "fn bases() { let a = 42; let b = 0b101010; let c = 0x2A; let d = 0v22; }";
8706 let mut parser = Parser::new(source);
8707 let file = parser.parse_file().unwrap();
8708 assert_eq!(file.items.len(), 1);
8709 }
8710
8711 #[test]
8712 fn test_parse_labeled_loops() {
8713 let source = r#"
8715 fn test() {
8716 'outer: loop {
8717 'inner: while true {
8718 break 'outer;
8719 }
8720 }
8721 }
8722 "#;
8723 let mut parser = Parser::new(source);
8724 let file = parser.parse_file().unwrap();
8725 assert_eq!(file.items.len(), 1);
8726
8727 let source2 = r#"
8729 fn test2() {
8730 'rows: for i in 0..10 {
8731 'cols: for j in 0..10 {
8732 if j == 5 { continue 'rows; }
8733 }
8734 }
8735 }
8736 "#;
8737 let mut parser2 = Parser::new(source2);
8738 let file2 = parser2.parse_file().unwrap();
8739 assert_eq!(file2.items.len(), 1);
8740 }
8741
8742 #[test]
8743 fn test_parse_inline_asm() {
8744 let source = r#"
8745 fn outb(port: u16, value: u8) {
8746 asm!("out dx, al",
8747 in("dx") port,
8748 in("al") value,
8749 options(nostack));
8750 }
8751 "#;
8752 let mut parser = Parser::new(source);
8753 let file = parser.parse_file().unwrap();
8754 assert_eq!(file.items.len(), 1);
8755
8756 if let Item::Function(func) = &file.items[0].node {
8757 assert_eq!(func.name.name, "outb");
8758 } else {
8759 panic!("Expected function");
8760 }
8761 }
8762
8763 #[test]
8764 fn test_parse_inline_asm_with_outputs() {
8765 let source = r#"
8766 fn inb(port: u16) -> u8 {
8767 let result: u8 = 0;
8768 asm!("in al, dx",
8769 out("al") result,
8770 in("dx") port,
8771 options(nostack, nomem));
8772 return result;
8773 }
8774 "#;
8775 let mut parser = Parser::new(source);
8776 let file = parser.parse_file().unwrap();
8777 assert_eq!(file.items.len(), 1);
8778 }
8779
8780 #[test]
8781 fn test_parse_volatile_read() {
8782 let source = r#"
8783 fn read_mmio(addr: *mut u32) -> u32 {
8784 return volatile read<u32>(addr);
8785 }
8786 "#;
8787 let mut parser = Parser::new(source);
8788 let file = parser.parse_file().unwrap();
8789 assert_eq!(file.items.len(), 1);
8790 }
8791
8792 #[test]
8793 fn test_parse_volatile_write() {
8794 let source = r#"
8795 fn write_mmio(addr: *mut u32, value: u32) {
8796 volatile write<u32>(addr, value);
8797 }
8798 "#;
8799 let mut parser = Parser::new(source);
8800 let file = parser.parse_file().unwrap();
8801 assert_eq!(file.items.len(), 1);
8802 }
8803
8804 #[test]
8805 fn test_parse_naked_function() {
8806 let source = r#"
8807 naked fn interrupt_handler() {
8808 asm!("push rax; push rbx; call handler_impl; pop rbx; pop rax; iretq",
8809 options(nostack));
8810 }
8811 "#;
8812 let mut parser = Parser::new(source);
8813 let file = parser.parse_file().unwrap();
8814 assert_eq!(file.items.len(), 1);
8815
8816 if let Item::Function(func) = &file.items[0].node {
8817 assert!(func.attrs.naked, "Function should be naked");
8818 } else {
8819 panic!("Expected function");
8820 }
8821 }
8822
8823 #[test]
8824 fn test_parse_packed_struct() {
8825 let source = r#"
8826 packed struct GDTEntry {
8827 limit_low: u16,
8828 base_low: u16,
8829 base_middle: u8,
8830 access: u8,
8831 granularity: u8,
8832 base_high: u8,
8833 }
8834 "#;
8835 let mut parser = Parser::new(source);
8836 let file = parser.parse_file().unwrap();
8837 assert_eq!(file.items.len(), 1);
8838
8839 if let Item::Struct(s) = &file.items[0].node {
8840 assert!(s.attrs.packed, "Struct should be packed");
8841 assert_eq!(s.name.name, "GDTEntry");
8842 if let StructFields::Named(fields) = &s.fields {
8843 assert_eq!(fields.len(), 6);
8844 } else {
8845 panic!("Expected named fields");
8846 }
8847 } else {
8848 panic!("Expected struct");
8849 }
8850 }
8851
8852 #[test]
8853 fn test_parse_no_std_attribute() {
8854 let source = r#"
8855 #![no_std]
8856 #![no_main]
8857
8858 fn kernel_main() -> ! {
8859 loop {}
8860 }
8861 "#;
8862 let mut parser = Parser::new(source);
8863 let file = parser.parse_file().unwrap();
8864
8865 assert!(file.config.no_std, "Should have no_std");
8866 assert!(file.config.no_main, "Should have no_main");
8867 assert_eq!(file.attrs.len(), 2);
8868 }
8869
8870 #[test]
8871 fn test_parse_feature_attribute() {
8872 let source = r#"
8873 #![feature(asm, naked_functions)]
8874
8875 fn main() -> i64 { 0 }
8876 "#;
8877 let mut parser = Parser::new(source);
8878 let file = parser.parse_file().unwrap();
8879
8880 assert_eq!(file.config.features.len(), 2);
8881 assert!(file.config.features.contains(&"asm".to_string()));
8882 assert!(file
8883 .config
8884 .features
8885 .contains(&"naked_functions".to_string()));
8886 }
8887
8888 #[test]
8889 fn test_parse_target_attribute() {
8890 let source = r#"
8891 #![no_std]
8892 #![target(arch = "x86_64", os = "none")]
8893
8894 fn kernel_main() { }
8895 "#;
8896 let mut parser = Parser::new(source);
8897 let file = parser.parse_file().unwrap();
8898
8899 assert!(file.config.no_std);
8900 let target = file
8901 .config
8902 .target
8903 .as_ref()
8904 .expect("Should have target config");
8905 assert_eq!(target.arch, Some("x86_64".to_string()));
8906 assert_eq!(target.os, Some("none".to_string()));
8907 }
8908
8909 #[test]
8910 fn test_parse_panic_handler() {
8911 let source = r#"
8912 #![no_std]
8913
8914 #[panic_handler]
8915 fn panic(info: *const PanicInfo) -> ! {
8916 loop {}
8917 }
8918 "#;
8919 let mut parser = Parser::new(source);
8920 let file = parser.parse_file().unwrap();
8921
8922 assert_eq!(file.items.len(), 1);
8923 if let Item::Function(func) = &file.items[0].node {
8924 assert!(
8925 func.attrs.panic_handler,
8926 "Should have panic_handler attribute"
8927 );
8928 } else {
8929 panic!("Expected function");
8930 }
8931 }
8932
8933 #[test]
8934 fn test_parse_entry_point() {
8935 let source = r#"
8936 #![no_std]
8937 #![no_main]
8938
8939 #[entry]
8940 #[no_mangle]
8941 fn _start() -> ! {
8942 loop {}
8943 }
8944 "#;
8945 let mut parser = Parser::new(source);
8946 let file = parser.parse_file().unwrap();
8947
8948 assert_eq!(file.items.len(), 1);
8949 if let Item::Function(func) = &file.items[0].node {
8950 assert!(func.attrs.entry, "Should have entry attribute");
8951 assert!(func.attrs.no_mangle, "Should have no_mangle attribute");
8952 } else {
8953 panic!("Expected function");
8954 }
8955 }
8956
8957 #[test]
8958 fn test_parse_link_section() {
8959 let source = r#"
8960 #[link_section = ".text.boot"]
8961 fn boot_code() { }
8962 "#;
8963 let mut parser = Parser::new(source);
8964 let file = parser.parse_file().unwrap();
8965
8966 assert_eq!(file.items.len(), 1);
8967 if let Item::Function(func) = &file.items[0].node {
8968 assert_eq!(func.attrs.link_section, Some(".text.boot".to_string()));
8969 } else {
8970 panic!("Expected function");
8971 }
8972 }
8973
8974 #[test]
8975 fn test_parse_linker_config() {
8976 let source = r#"
8977 #![no_std]
8978 #![linker_script = "kernel.ld"]
8979 #![entry_point = "_start"]
8980 #![base_address = 0x100000]
8981 #![stack_size = 0x4000]
8982
8983 fn kernel_main() { }
8984 "#;
8985 let mut parser = Parser::new(source);
8986 let file = parser.parse_file().unwrap();
8987
8988 let linker = file
8989 .config
8990 .linker
8991 .as_ref()
8992 .expect("Should have linker config");
8993 assert_eq!(linker.script, Some("kernel.ld".to_string()));
8994 assert_eq!(linker.entry_point, Some("_start".to_string()));
8995 assert_eq!(linker.base_address, Some(0x100000));
8996 assert_eq!(linker.stack_size, Some(0x4000));
8997 }
8998
8999 #[test]
9000 fn test_parse_interrupt_handler() {
9001 let source = r#"
9002 #[interrupt(32)]
9003 #[naked]
9004 fn timer_handler() {
9005 asm!("iretq", options(nostack));
9006 }
9007 "#;
9008 let mut parser = Parser::new(source);
9009 let file = parser.parse_file().unwrap();
9010
9011 if let Item::Function(func) = &file.items[0].node {
9012 assert_eq!(func.attrs.interrupt, Some(32));
9013 assert!(func.attrs.naked);
9014 } else {
9015 panic!("Expected function");
9016 }
9017 }
9018
9019 #[test]
9020 fn test_parse_inline_attributes() {
9021 let source = r#"
9022 #[inline]
9023 fn fast() -> i64 { 0 }
9024
9025 #[inline(always)]
9026 fn very_fast() -> i64 { 0 }
9027
9028 #[inline(never)]
9029 fn never_inline() -> i64 { 0 }
9030 "#;
9031 let mut parser = Parser::new(source);
9032 let file = parser.parse_file().unwrap();
9033
9034 assert_eq!(file.items.len(), 3);
9035
9036 if let Item::Function(func) = &file.items[0].node {
9037 assert_eq!(func.attrs.inline, Some(InlineHint::Hint));
9038 }
9039 if let Item::Function(func) = &file.items[1].node {
9040 assert_eq!(func.attrs.inline, Some(InlineHint::Always));
9041 }
9042 if let Item::Function(func) = &file.items[2].node {
9043 assert_eq!(func.attrs.inline, Some(InlineHint::Never));
9044 }
9045 }
9046
9047 #[test]
9048 fn test_parse_simd_type() {
9049 let source = r#"
9050 fn vec_add(a: simd<f32, 4>, b: simd<f32, 4>) -> simd<f32, 4> {
9051 return simd.add(a, b);
9052 }
9053 "#;
9054 let mut parser = Parser::new(source);
9055 let file = parser.parse_file().unwrap();
9056 assert_eq!(file.items.len(), 1);
9057
9058 if let Item::Function(func) = &file.items[0].node {
9059 assert_eq!(func.name.name, "vec_add");
9060 if let TypeExpr::Simd { element, lanes } = &func.params[0].ty {
9062 assert_eq!(*lanes, 4);
9063 if let TypeExpr::Path(path) = element.as_ref() {
9064 assert_eq!(path.segments[0].ident.name, "f32");
9065 }
9066 } else {
9067 panic!("Expected SIMD type");
9068 }
9069 } else {
9070 panic!("Expected function");
9071 }
9072 }
9073
9074 #[test]
9075 fn test_parse_simd_literal() {
9076 let source = r#"
9077 fn make_vec() -> simd<f32, 4> {
9078 return simd[1.0, 2.0, 3.0, 4.0];
9079 }
9080 "#;
9081 let mut parser = Parser::new(source);
9082 let file = parser.parse_file().unwrap();
9083 assert_eq!(file.items.len(), 1);
9084 }
9085
9086 #[test]
9087 fn test_parse_simd_intrinsics() {
9088 let source = r#"
9089 fn dot_product(a: simd<f32, 4>, b: simd<f32, 4>) -> f32 {
9090 let prod = simd.mul(a, b);
9091 return simd.hadd(prod);
9092 }
9093 "#;
9094 let mut parser = Parser::new(source);
9095 let file = parser.parse_file().unwrap();
9096 assert_eq!(file.items.len(), 1);
9097 }
9098
9099 #[test]
9100 fn test_parse_simd_shuffle() {
9101 let source = r#"
9102 fn interleave(a: simd<f32, 4>, b: simd<f32, 4>) -> simd<f32, 4> {
9103 return simd.shuffle(a, b, [0, 4, 1, 5]);
9104 }
9105 "#;
9106 let mut parser = Parser::new(source);
9107 let file = parser.parse_file().unwrap();
9108 assert_eq!(file.items.len(), 1);
9109 }
9110
9111 #[test]
9112 fn test_parse_atomic_type() {
9113 let source = r#"
9114 struct Counter {
9115 value: atomic<i64>,
9116 }
9117 "#;
9118 let mut parser = Parser::new(source);
9119 let file = parser.parse_file().unwrap();
9120 assert_eq!(file.items.len(), 1);
9121
9122 if let Item::Struct(s) = &file.items[0].node {
9123 if let StructFields::Named(fields) = &s.fields {
9124 if let TypeExpr::Atomic(inner) = &fields[0].ty {
9125 if let TypeExpr::Path(path) = inner.as_ref() {
9126 assert_eq!(path.segments[0].ident.name, "i64");
9127 }
9128 } else {
9129 panic!("Expected atomic type");
9130 }
9131 }
9132 } else {
9133 panic!("Expected struct");
9134 }
9135 }
9136
9137 #[test]
9138 fn test_parse_atomic_operations() {
9139 let source = r#"
9140 fn increment(ptr: *mut i64) -> i64 {
9141 return atomic.fetch_add(ptr, 1, SeqCst);
9142 }
9143 "#;
9144 let mut parser = Parser::new(source);
9145 let file = parser.parse_file().unwrap();
9146 assert_eq!(file.items.len(), 1);
9147 }
9148
9149 #[test]
9150 fn test_parse_atomic_compare_exchange() {
9151 let source = r#"
9152 fn cas(ptr: *mut i64, expected: i64, new: i64) -> bool {
9153 let result = atomic.compare_exchange(ptr, expected, new, AcqRel, Relaxed);
9154 return result;
9155 }
9156 "#;
9157 let mut parser = Parser::new(source);
9158 let file = parser.parse_file().unwrap();
9159 assert_eq!(file.items.len(), 1);
9160 }
9161
9162 #[test]
9163 fn test_parse_atomic_fence() {
9164 let source = r#"
9165 fn memory_barrier() {
9166 atomic.fence(SeqCst);
9167 }
9168 "#;
9169 let mut parser = Parser::new(source);
9170 let file = parser.parse_file().unwrap();
9171 assert_eq!(file.items.len(), 1);
9172 }
9173
9174 #[test]
9175 fn test_parse_derive_macro() {
9176 let source = r#"
9177 #[derive(Debug, Clone, Component)]
9178 struct Position {
9179 x: f32,
9180 y: f32,
9181 z: f32,
9182 }
9183 "#;
9184 let mut parser = Parser::new(source);
9185 let file = parser.parse_file().unwrap();
9186 assert_eq!(file.items.len(), 1);
9187
9188 if let Item::Struct(s) = &file.items[0].node {
9189 assert_eq!(s.attrs.derives.len(), 3);
9190 assert!(matches!(s.attrs.derives[0], DeriveTrait::Debug));
9191 assert!(matches!(s.attrs.derives[1], DeriveTrait::Clone));
9192 assert!(matches!(s.attrs.derives[2], DeriveTrait::Component));
9193 } else {
9194 panic!("Expected struct");
9195 }
9196 }
9197
9198 #[test]
9199 fn test_parse_repr_c_struct() {
9200 let source = r#"
9201 #[repr(C)]
9202 struct FFIStruct {
9203 field: i32,
9204 }
9205 "#;
9206 let mut parser = Parser::new(source);
9207 let file = parser.parse_file().unwrap();
9208 assert_eq!(file.items.len(), 1);
9209
9210 if let Item::Struct(s) = &file.items[0].node {
9211 assert_eq!(s.attrs.repr, Some(StructRepr::C));
9212 } else {
9213 panic!("Expected struct");
9214 }
9215 }
9216
9217 #[test]
9218 fn test_parse_allocator_trait() {
9219 let source = r#"
9220 trait Allocator {
9221 type Error;
9222
9223 fn allocate(size: usize, align: usize) -> *mut u8;
9224 fn deallocate(ptr: *mut u8, size: usize, align: usize);
9225 }
9226 "#;
9227 let mut parser = Parser::new(source);
9228 let file = parser.parse_file().unwrap();
9229 assert_eq!(file.items.len(), 1);
9230
9231 if let Item::Trait(t) = &file.items[0].node {
9232 assert_eq!(t.name.name, "Allocator");
9233 assert_eq!(t.items.len(), 3); assert!(matches!(t.items[0], TraitItem::Type { .. }));
9235 } else {
9236 panic!("Expected trait");
9237 }
9238 }
9239
9240 #[test]
9241 fn test_parse_where_clause() {
9242 let source = r#"
9243 fn alloc_array<T, A>(allocator: &mut A, count: usize) -> *mut T
9244 where
9245 A: Allocator,
9246 {
9247 return allocator.allocate(count, 8);
9248 }
9249 "#;
9250 let mut parser = Parser::new(source);
9251 let file = parser.parse_file().unwrap();
9252 assert_eq!(file.items.len(), 1);
9253
9254 if let Item::Function(func) = &file.items[0].node {
9255 assert!(func.where_clause.is_some());
9256 let wc = func.where_clause.as_ref().unwrap();
9257 assert_eq!(wc.predicates.len(), 1);
9258 } else {
9259 panic!("Expected function");
9260 }
9261 }
9262}