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 #[error("Deprecated Rust syntax '{rust}' at {span}. Use Sigil's native syntax: {sigil}")]
25 DeprecatedRustSyntax {
26 rust: String,
27 sigil: String,
28 span: Span,
29 },
30}
31
32fn rust_to_sigil(keyword: &str) -> &'static str {
34 match keyword {
35 "fn" => "rite (function declaration)",
36 "let" => "≔ (definition)",
37 "mut" => "Δ (delta/mutable)",
38 "const" => "◆ (diamond/const)",
39 "struct" => "Σ (sigma) or 'sigil'",
40 "enum" => "ᛈ (perthro rune)",
41 "trait" => "Θ (theta)",
42 "impl" => "⊢ (turnstile)",
43 "mod" => "scroll",
44 "use" => "invoke",
45 "pub" => "☉ (sun/public)",
46 "if" => "⎇ (branch)",
47 "else" => "⎉ (alternative)",
48 "match" => "⌥ (option)",
49 "while" => "⟳ (cycle)",
50 "for" => "∀ (forall)",
51 "in" => "∈ (element-of)",
52 "break" => "⊗ (tensor/break)",
53 "continue" => "↻ (cycle-arrow)",
54 "return" => "⤺ (return-arrow)",
55 "async" => "⌛ (hourglass)",
56 _ => "(see docs)",
57 }
58}
59
60pub type ParseResult<T> = Result<T, ParseError>;
61
62const QUANTUM_GATES: &[&str] = &[
66 "H", "X", "Y", "Z", "S", "T",
68 "Rx", "Ry", "Rz",
70 "CNOT", "CZ", "SWAP",
72 "Toffoli", "Fredkin",
74 "H_all", "X_all",
76];
77
78const QUANTUM_OPS: &[&str] = &[
80 "measure", "measure_all", "measure_both", "measure_basis", "measure_partial",
82 "probability_of",
84 "apply_at",
86];
87
88pub struct Parser<'a> {
90 lexer: Lexer<'a>,
91 current: Option<(Token, Span)>,
92 in_condition: bool,
94 pending_gt: Option<Span>,
96}
97
98impl<'a> Parser<'a> {
99 pub fn new(source: &'a str) -> Self {
100 let mut lexer = Lexer::new(source);
101 let current = lexer.next_token();
102 Self {
103 lexer,
104 current,
105 in_condition: false,
106 pending_gt: None,
107 }
108 }
109
110 pub fn parse_file(&mut self) -> ParseResult<SourceFile> {
112 let mut attrs = Vec::new();
114 while matches!(self.current_token(), Some(Token::HashBang)) {
115 attrs.push(self.parse_inner_attribute()?);
116 }
117
118 let config = self.build_crate_config(&attrs);
120
121 let mut items = Vec::new();
122 while !self.is_eof() {
123 while self.check_regular_comment() {
127 self.advance();
128 }
129 if self.is_eof() {
130 break;
131 }
132 let item = self.parse_item()?;
133 let should_include = match &item.node {
135 Item::Function(f) => self.evaluate_cfg_condition(&f.attrs.outer_attrs),
136 Item::Struct(s) => self.evaluate_cfg_condition(&s.attrs.outer_attrs),
137 _ => true,
138 };
139 if should_include {
140 items.push(item);
141 }
142 }
143 Ok(SourceFile {
144 attrs,
145 config,
146 items,
147 })
148 }
149
150 fn parse_inner_attribute(&mut self) -> ParseResult<Attribute> {
152 self.expect(Token::HashBang)?;
153 self.expect(Token::LBracket)?;
154
155 let name = self.parse_ident()?;
156 let args = self.parse_attr_args()?;
157
158 self.expect(Token::RBracket)?;
159
160 Ok(Attribute {
161 name,
162 args,
163 is_inner: true,
164 })
165 }
166
167 fn parse_outer_attribute(&mut self) -> ParseResult<Attribute> {
171 let is_at_syntax = self.check(&Token::At);
173 if is_at_syntax {
174 self.advance();
175 } else {
176 self.expect(Token::Hash)?;
177 }
178 self.expect(Token::LBracket)?;
179
180 let name = self.parse_attr_name()?;
181
182 if is_at_syntax && self.check(&Token::Comma) && !self.check(&Token::LParen) {
185 let mut args = vec![AttrArg::Ident(name)];
187 while self.consume_if(&Token::Comma) {
188 if self.check(&Token::RBracket) {
189 break; }
191 args.push(AttrArg::Ident(self.parse_attr_name()?));
192 }
193 self.expect(Token::RBracket)?;
194
195 Ok(Attribute {
197 name: Ident {
198 name: "derive".to_string(),
199 evidentiality: None,
200 affect: None,
201 span: self.current_span(),
202 },
203 args: Some(AttrArgs::Paren(args)),
204 is_inner: false,
205 })
206 } else {
207 let args = self.parse_attr_args()?;
208 self.expect(Token::RBracket)?;
209
210 Ok(Attribute {
211 name,
212 args,
213 is_inner: false,
214 })
215 }
216 }
217
218 fn evaluate_cfg_condition(&self, attrs: &[Attribute]) -> bool {
222 for attr in attrs {
223 if attr.name.name == "cfg" {
224 if let Some(AttrArgs::Paren(args)) = &attr.args {
225 for arg in args {
227 match arg {
228 AttrArg::Ident(ident) => {
229 if ident.name == "debug_assertions" {
231 return true;
233 }
234 return true;
236 }
237 AttrArg::KeyValue { key, value } => {
238 return self.evaluate_cfg_key_value(&key.name, value);
240 }
241 AttrArg::Nested(nested_attr) => {
242 if nested_attr.name.name == "not" {
244 if let Some(AttrArgs::Paren(inner_args)) = &nested_attr.args {
246 for inner_arg in inner_args {
247 match inner_arg {
248 AttrArg::Ident(inner_ident) => {
249 if inner_ident.name == "debug_assertions" {
250 return false;
252 }
253 }
254 AttrArg::KeyValue { key, value } => {
255 return !self.evaluate_cfg_key_value(&key.name, value);
256 }
257 _ => {}
258 }
259 }
260 }
261 return false;
263 }
264 if nested_attr.name.name == "any" {
265 if let Some(AttrArgs::Paren(inner_args)) = &nested_attr.args {
267 for inner_arg in inner_args {
268 if let AttrArg::KeyValue { key, value } = inner_arg {
269 if self.evaluate_cfg_key_value(&key.name, value) {
270 return true;
271 }
272 }
273 }
274 return false;
275 }
276 }
277 return true;
279 }
280 _ => {}
281 }
282 }
283 }
284 }
285 }
286 true
288 }
289
290 fn evaluate_cfg_key_value(&self, key: &str, value: &Expr) -> bool {
292 let value_str = match value {
293 Expr::Literal(Literal::String(s)) => s.as_str(),
294 _ => return false,
295 };
296 match key {
297 "target_os" => {
298 if cfg!(target_os = "linux") {
300 value_str == "linux"
301 } else if cfg!(target_os = "macos") {
302 value_str == "macos"
303 } else if cfg!(target_os = "windows") {
304 value_str == "windows"
305 } else {
306 false
307 }
308 }
309 "target_arch" => {
310 if cfg!(target_arch = "x86_64") {
311 value_str == "x86_64"
312 } else if cfg!(target_arch = "aarch64") {
313 value_str == "aarch64"
314 } else {
315 false
316 }
317 }
318 _ => false,
319 }
320 }
321
322 fn parse_attr_name(&mut self) -> ParseResult<Ident> {
324 let span = self.current_span();
325 let first_name = match self.current_token().cloned() {
326 Some(Token::Ident(name)) => {
327 self.advance();
328 name
329 }
330 Some(Token::Naked) => {
332 self.advance();
333 "naked".to_string()
334 }
335 Some(Token::Unsafe) => {
336 self.advance();
337 "unsafe".to_string()
338 }
339 Some(Token::Asm) => {
340 self.advance();
341 "asm".to_string()
342 }
343 Some(Token::Volatile) => {
344 self.advance();
345 "volatile".to_string()
346 }
347 Some(Token::Derive) => {
348 self.advance();
349 "derive".to_string()
350 }
351 Some(Token::Simd) => {
352 self.advance();
353 "simd".to_string()
354 }
355 Some(Token::Atomic) => {
356 self.advance();
357 "atomic".to_string()
358 }
359 Some(Token::Macro) => {
360 self.advance();
361 "macro".to_string()
362 }
363 Some(t) => {
364 return Err(ParseError::UnexpectedToken {
365 expected: "attribute name".to_string(),
366 found: t,
367 span,
368 })
369 }
370 None => return Err(ParseError::UnexpectedEof),
371 };
372
373 let mut full_name = first_name;
375 while self.consume_if(&Token::MiddleDot) {
376 let segment = match self.current_token().cloned() {
377 Some(Token::Ident(name)) => {
378 self.advance();
379 name
380 }
381 Some(t) => {
382 return Err(ParseError::UnexpectedToken {
383 expected: "identifier after ::".to_string(),
384 found: t,
385 span: self.current_span(),
386 })
387 }
388 None => return Err(ParseError::UnexpectedEof),
389 };
390 full_name = format!("{}::{}", full_name, segment);
391 }
392
393 Ok(Ident {
394 name: full_name,
395 evidentiality: None,
396 affect: None,
397 span,
398 })
399 }
400
401 fn parse_attr_args(&mut self) -> ParseResult<Option<AttrArgs>> {
403 if self.consume_if(&Token::LParen) {
404 let mut args = Vec::new();
405
406 while !self.check(&Token::RParen) {
407 args.push(self.parse_attr_arg()?);
408 if !self.consume_if(&Token::Comma) {
409 break;
410 }
411 }
412
413 self.expect(Token::RParen)?;
414 Ok(Some(AttrArgs::Paren(args)))
415 } else if self.consume_if(&Token::Eq) {
416 let expr = self.parse_expr()?;
417 Ok(Some(AttrArgs::Eq(Box::new(expr))))
418 } else {
419 Ok(None)
420 }
421 }
422
423 fn parse_attr_arg(&mut self) -> ParseResult<AttrArg> {
425 match self.current_token().cloned() {
426 Some(Token::StringLit(s)) => {
427 self.advance();
428 Ok(AttrArg::Literal(Literal::String(s)))
429 }
430 Some(Token::IntLit(s)) => {
431 self.advance();
432 Ok(AttrArg::Literal(Literal::Int {
433 value: s,
434 base: NumBase::Decimal,
435 suffix: None,
436 }))
437 }
438 Some(Token::HexLit(s)) => {
439 self.advance();
440 Ok(AttrArg::Literal(Literal::Int {
441 value: s,
442 base: NumBase::Hex,
443 suffix: None,
444 }))
445 }
446 Some(Token::BinaryLit(s)) => {
447 self.advance();
448 Ok(AttrArg::Literal(Literal::Int {
449 value: s,
450 base: NumBase::Binary,
451 suffix: None,
452 }))
453 }
454 Some(Token::OctalLit(s)) => {
455 self.advance();
456 Ok(AttrArg::Literal(Literal::Int {
457 value: s,
458 base: NumBase::Octal,
459 suffix: None,
460 }))
461 }
462 Some(Token::Ident(_)) => {
463 let ident = self.parse_ident()?;
464 self.parse_attr_arg_after_ident(ident)
465 }
466 Some(Token::Asm) => {
468 let span = self.current_span();
469 self.advance();
470 let ident = Ident {
471 name: "asm".to_string(),
472 evidentiality: None,
473 affect: None,
474 span,
475 };
476 self.parse_attr_arg_after_ident(ident)
477 }
478 Some(Token::Volatile) => {
479 let span = self.current_span();
480 self.advance();
481 let ident = Ident {
482 name: "volatile".to_string(),
483 evidentiality: None,
484 affect: None,
485 span,
486 };
487 self.parse_attr_arg_after_ident(ident)
488 }
489 Some(Token::Naked) => {
490 let span = self.current_span();
491 self.advance();
492 let ident = Ident {
493 name: "naked".to_string(),
494 evidentiality: None,
495 affect: None,
496 span,
497 };
498 self.parse_attr_arg_after_ident(ident)
499 }
500 Some(Token::Packed) => {
501 let span = self.current_span();
502 self.advance();
503 let ident = Ident {
504 name: "packed".to_string(),
505 evidentiality: None,
506 affect: None,
507 span,
508 };
509 self.parse_attr_arg_after_ident(ident)
510 }
511 Some(Token::Unsafe) => {
512 let span = self.current_span();
513 self.advance();
514 let ident = Ident {
515 name: "unsafe".to_string(),
516 evidentiality: None,
517 affect: None,
518 span,
519 };
520 self.parse_attr_arg_after_ident(ident)
521 }
522 Some(t) => Err(ParseError::UnexpectedToken {
523 expected: "attribute argument".to_string(),
524 found: t,
525 span: self.current_span(),
526 }),
527 None => Err(ParseError::UnexpectedEof),
528 }
529 }
530
531 fn parse_attr_arg_after_ident(&mut self, ident: Ident) -> ParseResult<AttrArg> {
533 if self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::MiddleDot) {
535 let mut path_parts = vec![ident.name.clone()];
536 loop {
537 let part = self.parse_ident()?;
538 path_parts.push(part.name);
539 if !self.consume_if(&Token::MiddleDot) && !self.consume_if(&Token::MiddleDot) {
540 break;
541 }
542 }
543 let full_path = path_parts.join("::");
545 return Ok(AttrArg::Ident(Ident {
546 name: full_path,
547 evidentiality: None,
548 affect: None,
549 span: ident.span.clone(),
550 }));
551 }
552 if self.consume_if(&Token::Eq) {
554 let value = self.parse_expr()?;
555 Ok(AttrArg::KeyValue {
556 key: ident,
557 value: Box::new(value),
558 })
559 }
560 else if self.check(&Token::LParen) {
562 let args = self.parse_attr_args()?;
563 Ok(AttrArg::Nested(Attribute {
564 name: ident,
565 args,
566 is_inner: false,
567 }))
568 }
569 else {
571 Ok(AttrArg::Ident(ident))
572 }
573 }
574
575 fn parse_interpolation_parts(&mut self, s: &str) -> ParseResult<Vec<InterpolationPart>> {
578 let mut parts = Vec::new();
579 let mut current_text = String::new();
580 let mut chars = s.chars().peekable();
581 let mut brace_depth = 0;
582 let mut expr_content = String::new();
583 let mut in_expr = false;
584
585 while let Some(c) = chars.next() {
586 if in_expr {
587 if c == '{' {
588 brace_depth += 1;
589 expr_content.push(c);
590 } else if c == '}' {
591 if brace_depth > 0 {
592 brace_depth -= 1;
593 expr_content.push(c);
594 } else {
595 in_expr = false;
597 if !expr_content.is_empty() {
598 let mut expr_parser = Parser::new(&expr_content);
600 match expr_parser.parse_expr() {
601 Ok(expr) => {
602 parts.push(InterpolationPart::Expr(Box::new(expr)));
603 }
604 Err(_) => {
605 parts.push(InterpolationPart::Text(format!(
607 "{{{}}}",
608 expr_content
609 )));
610 }
611 }
612 }
613 expr_content.clear();
614 }
615 } else {
616 expr_content.push(c);
617 }
618 } else if c == '{' {
619 if chars.peek() == Some(&'{') {
620 chars.next();
622 current_text.push('{');
623 } else {
624 if !current_text.is_empty() {
626 parts.push(InterpolationPart::Text(current_text.clone()));
627 current_text.clear();
628 }
629 in_expr = true;
630 }
631 } else if c == '}' {
632 if chars.peek() == Some(&'}') {
633 chars.next();
635 current_text.push('}');
636 } else {
637 current_text.push(c);
638 }
639 } else {
640 current_text.push(c);
641 }
642 }
643
644 if !current_text.is_empty() {
646 parts.push(InterpolationPart::Text(current_text));
647 }
648
649 if parts.is_empty() {
651 parts.push(InterpolationPart::Text(String::new()));
652 }
653
654 Ok(parts)
655 }
656
657 fn build_crate_config(&self, attrs: &[Attribute]) -> CrateConfig {
659 let mut config = CrateConfig::default();
660 let mut linker = LinkerConfig::default();
661 let mut has_linker_config = false;
662
663 for attr in attrs {
664 match attr.name.name.as_str() {
665 "no_std" => config.no_std = true,
666 "no_main" => config.no_main = true,
667 "feature" => {
668 if let Some(AttrArgs::Paren(args)) = &attr.args {
669 for arg in args {
670 if let AttrArg::Ident(ident) = arg {
671 config.features.push(ident.name.clone());
672 }
673 }
674 }
675 }
676 "target" => {
677 let mut target = TargetConfig::default();
678 if let Some(AttrArgs::Paren(args)) = &attr.args {
679 for arg in args {
680 if let AttrArg::KeyValue { key, value } = arg {
681 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
682 match key.name.as_str() {
683 "arch" => target.arch = Some(s.clone()),
684 "os" => target.os = Some(s.clone()),
685 "abi" => target.abi = Some(s.clone()),
686 _ => {}
687 }
688 }
689 }
690 }
691 }
692 config.target = Some(target);
693 }
694 "linker_script" => {
696 if let Some(AttrArgs::Eq(value)) = &attr.args {
697 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
698 linker.script = Some(s.clone());
699 has_linker_config = true;
700 }
701 }
702 }
703 "entry_point" => {
704 if let Some(AttrArgs::Eq(value)) = &attr.args {
705 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
706 linker.entry_point = Some(s.clone());
707 has_linker_config = true;
708 }
709 }
710 }
711 "base_address" => {
712 if let Some(AttrArgs::Eq(value)) = &attr.args {
713 if let Expr::Literal(Literal::Int { value: s, base, .. }) = value.as_ref() {
714 let addr = Self::parse_int_value(s, *base);
715 linker.base_address = Some(addr);
716 has_linker_config = true;
717 }
718 }
719 }
720 "stack_size" => {
721 if let Some(AttrArgs::Eq(value)) = &attr.args {
722 if let Expr::Literal(Literal::Int { value: s, base, .. }) = value.as_ref() {
723 let size = Self::parse_int_value(s, *base);
724 linker.stack_size = Some(size);
725 has_linker_config = true;
726 }
727 }
728 }
729 "link" => {
730 if let Some(AttrArgs::Paren(args)) = &attr.args {
732 for arg in args {
733 if let AttrArg::KeyValue { key, value } = arg {
734 if key.name == "flag" {
735 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
736 linker.flags.push(s.clone());
737 has_linker_config = true;
738 }
739 }
740 }
741 }
742 }
743 }
744 _ => {}
745 }
746 }
747
748 if has_linker_config {
749 config.linker = Some(linker);
750 }
751
752 config
753 }
754
755 fn parse_int_value(s: &str, base: NumBase) -> u64 {
757 let (stripped, radix) = match base {
759 NumBase::Binary => (
760 s.strip_prefix("0b").or(s.strip_prefix("0B")).unwrap_or(s),
761 2,
762 ),
763 NumBase::Octal => (
764 s.strip_prefix("0o").or(s.strip_prefix("0O")).unwrap_or(s),
765 8,
766 ),
767 NumBase::Decimal => (s, 10),
768 NumBase::Hex => (
769 s.strip_prefix("0x").or(s.strip_prefix("0X")).unwrap_or(s),
770 16,
771 ),
772 NumBase::Vigesimal => (
773 s.strip_prefix("0v").or(s.strip_prefix("0V")).unwrap_or(s),
774 20,
775 ),
776 NumBase::Duodecimal => (
777 s.strip_prefix("0d").or(s.strip_prefix("0D")).unwrap_or(s),
778 12,
779 ),
780 NumBase::Sexagesimal => (
781 s.strip_prefix("0s").or(s.strip_prefix("0S")).unwrap_or(s),
782 60,
783 ),
784 NumBase::Explicit(r) => (s, r as u32),
785 };
786 let clean: String = stripped.chars().filter(|c| *c != '_').collect();
788 u64::from_str_radix(&clean, radix).unwrap_or(0)
789 }
790
791 pub(crate) fn current_token(&self) -> Option<&Token> {
794 self.current.as_ref().map(|(t, _)| t)
795 }
796
797 pub(crate) fn current_span(&self) -> Span {
798 self.current.as_ref().map(|(_, s)| *s).unwrap_or_default()
799 }
800
801 pub(crate) fn advance(&mut self) -> Option<(Token, Span)> {
802 let prev = self.current.take();
803 self.current = self.lexer.next_token();
804 prev
805 }
806
807 pub(crate) fn is_eof(&self) -> bool {
808 self.current.is_none()
809 }
810
811 fn strip_float_suffix(s: &str) -> (String, Option<String>) {
815 for suffix in &["f128", "f64", "f32", "f16"] {
816 if s.ends_with(suffix) {
817 let before = &s[..s.len() - suffix.len()];
818 let value = before.strip_suffix('_').unwrap_or(before).to_string();
820 return (value, Some(suffix.to_string()));
821 }
822 }
823 (s.to_string(), None)
824 }
825
826 pub(crate) fn expect(&mut self, expected: Token) -> ParseResult<Span> {
827 match &self.current {
828 Some((token, span))
829 if std::mem::discriminant(token) == std::mem::discriminant(&expected) =>
830 {
831 let span = *span;
832 self.advance();
833 Ok(span)
834 }
835 Some((Token::DeprecatedRustKeyword(kw), span)) => {
836 Err(ParseError::DeprecatedRustSyntax {
837 rust: kw.clone(),
838 sigil: rust_to_sigil(kw).to_string(),
839 span: *span,
840 })
841 }
842 Some((Token::DeprecatedColonColon, span)) => {
843 Err(ParseError::DeprecatedRustSyntax {
844 rust: "::".to_string(),
845 sigil: "· (middledot) for path separator".to_string(),
846 span: *span,
847 })
848 }
849 Some((token, span)) => Err(ParseError::UnexpectedToken {
850 expected: format!("{:?}", expected),
851 found: token.clone(),
852 span: *span,
853 }),
854 None => Err(ParseError::UnexpectedEof),
855 }
856 }
857
858 pub(crate) fn expect_one_of(&mut self, expected: &[Token]) -> ParseResult<Span> {
861 match &self.current {
862 Some((Token::DeprecatedRustKeyword(kw), span)) => {
863 Err(ParseError::DeprecatedRustSyntax {
864 rust: kw.clone(),
865 sigil: rust_to_sigil(kw).to_string(),
866 span: *span,
867 })
868 }
869 Some((Token::DeprecatedColonColon, span)) => {
870 Err(ParseError::DeprecatedRustSyntax {
871 rust: "::".to_string(),
872 sigil: "· (middledot) for path separator".to_string(),
873 span: *span,
874 })
875 }
876 Some((token, span)) => {
877 let current_discriminant = std::mem::discriminant(token);
878 for exp in expected {
879 if current_discriminant == std::mem::discriminant(exp) {
880 let span = *span;
881 self.advance();
882 return Ok(span);
883 }
884 }
885 Err(ParseError::UnexpectedToken {
886 expected: expected.iter().map(|t| format!("{:?}", t)).collect::<Vec<_>>().join(" or "),
887 found: token.clone(),
888 span: *span,
889 })
890 }
891 None => Err(ParseError::UnexpectedEof),
892 }
893 }
894
895 pub(crate) fn check_one_of(&self, expected: &[Token]) -> bool {
897 match &self.current {
898 Some((token, _)) => {
899 let current_discriminant = std::mem::discriminant(token);
900 expected.iter().any(|exp| current_discriminant == std::mem::discriminant(exp))
901 }
902 None => false,
903 }
904 }
905
906 pub(crate) fn check(&self, expected: &Token) -> bool {
907 matches!(&self.current, Some((token, _)) if std::mem::discriminant(token) == std::mem::discriminant(expected))
908 }
909
910 pub(crate) fn check_deprecated(&self) -> ParseResult<()> {
913 match &self.current {
914 Some((Token::DeprecatedRustKeyword(kw), span)) => {
915 Err(ParseError::DeprecatedRustSyntax {
916 rust: kw.clone(),
917 sigil: rust_to_sigil(kw).to_string(),
918 span: *span,
919 })
920 }
921 Some((Token::DeprecatedColonColon, span)) => {
922 Err(ParseError::DeprecatedRustSyntax {
923 rust: "::".to_string(),
924 sigil: "· (middledot) for path separator".to_string(),
925 span: *span,
926 })
927 }
928 Some((Token::DeprecatedAmpMut, span)) => {
929 Err(ParseError::DeprecatedRustSyntax {
930 rust: "&mut".to_string(),
931 sigil: "&Δ (reference to mutable) or just Δ for mutable binding".to_string(),
932 span: *span,
933 })
934 }
935 _ => Ok(()),
936 }
937 }
938
939 pub(crate) fn peek_next(&mut self) -> Option<&Token> {
941 self.lexer.peek().map(|(t, _)| t)
942 }
943
944 pub(crate) fn peek_n(&mut self, n: usize) -> Option<&Token> {
946 self.lexer.peek_n(n).map(|(t, _)| t)
947 }
948
949 pub(crate) fn consume_if(&mut self, expected: &Token) -> bool {
950 if self.check(expected) {
951 self.advance();
952 true
953 } else {
954 false
955 }
956 }
957
958 fn is_comment_token(tok: &Token) -> bool {
960 matches!(tok, Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
961 || tok.is_doc_comment()
962 }
963
964 pub(crate) fn skip_comments(&mut self) {
966 while let Some(tok) = self.current_token() {
967 if Self::is_comment_token(&tok) {
968 self.advance();
969 } else {
970 break;
971 }
972 }
973 }
974
975 pub(crate) fn current_is_comment(&self) -> bool {
977 self.current_token().map(|t| Self::is_comment_token(&t)).unwrap_or(false)
978 }
979
980 fn check_regular_comment(&self) -> bool {
983 matches!(
984 self.current_token(),
985 Some(Token::LineComment(_)) | Some(Token::TildeComment(_)) | Some(Token::BlockComment(_))
986 )
987 }
988
989 pub(crate) fn collect_doc_comments(&mut self) -> Vec<crate::ast::DocComment> {
992 use crate::ast::{DocComment, Evidentiality};
993
994 let mut doc_comments = Vec::new();
995
996 while let Some((tok, span)) = self.current.clone() {
997 match &tok {
999 Token::DocCommentVerified(content) => {
1000 doc_comments.push(DocComment::new(
1001 Evidentiality::Known,
1002 false,
1003 content.clone(),
1004 span,
1005 ));
1006 self.advance();
1007 }
1008 Token::DocCommentVerifiedInner(content) => {
1009 doc_comments.push(DocComment::new(
1010 Evidentiality::Known,
1011 true,
1012 content.clone(),
1013 span,
1014 ));
1015 self.advance();
1016 }
1017 Token::DocCommentReported(content) => {
1018 doc_comments.push(DocComment::new(
1019 Evidentiality::Reported,
1020 false,
1021 content.clone(),
1022 span,
1023 ));
1024 self.advance();
1025 }
1026 Token::DocCommentReportedInner(content) => {
1027 doc_comments.push(DocComment::new(
1028 Evidentiality::Reported,
1029 true,
1030 content.clone(),
1031 span,
1032 ));
1033 self.advance();
1034 }
1035 Token::DocCommentUncertain(content) => {
1036 doc_comments.push(DocComment::new(
1037 Evidentiality::Uncertain,
1038 false,
1039 content.clone(),
1040 span,
1041 ));
1042 self.advance();
1043 }
1044 Token::DocCommentUncertainInner(content) => {
1045 doc_comments.push(DocComment::new(
1046 Evidentiality::Uncertain,
1047 true,
1048 content.clone(),
1049 span,
1050 ));
1051 self.advance();
1052 }
1053 Token::DocCommentPredicted(content) => {
1054 doc_comments.push(DocComment::new(
1055 Evidentiality::Predicted,
1056 false,
1057 content.clone(),
1058 span,
1059 ));
1060 self.advance();
1061 }
1062 Token::DocCommentPredictedInner(content) => {
1063 doc_comments.push(DocComment::new(
1064 Evidentiality::Predicted,
1065 true,
1066 content.clone(),
1067 span,
1068 ));
1069 self.advance();
1070 }
1071 Token::DocCommentParadox(content) => {
1072 doc_comments.push(DocComment::new(
1073 Evidentiality::Paradox,
1074 false,
1075 content.clone(),
1076 span,
1077 ));
1078 self.advance();
1079 }
1080 Token::DocCommentParadoxInner(content) => {
1081 doc_comments.push(DocComment::new(
1082 Evidentiality::Paradox,
1083 true,
1084 content.clone(),
1085 span,
1086 ));
1087 self.advance();
1088 }
1089 Token::DocComment(content) => {
1090 doc_comments.push(DocComment::new(
1092 Evidentiality::Reported,
1093 false,
1094 content.clone(),
1095 span,
1096 ));
1097 self.advance();
1098 }
1099 Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_) => {
1101 self.advance();
1102 }
1103 _ => break,
1105 }
1106 }
1107
1108 doc_comments
1109 }
1110
1111 pub(crate) fn check_gt(&self) -> bool {
1113 self.pending_gt.is_some() || self.check(&Token::Gt)
1114 }
1115
1116 pub(crate) fn expect_gt(&mut self) -> ParseResult<Span> {
1119 if let Some(span) = self.pending_gt.take() {
1121 return Ok(span);
1122 }
1123
1124 match &self.current {
1125 Some((Token::Gt, span)) => {
1126 let span = *span;
1127 self.advance();
1128 Ok(span)
1129 }
1130 Some((Token::Shr, span)) => {
1131 let span = *span;
1134 self.pending_gt = Some(span);
1135 self.advance();
1136 Ok(span)
1137 }
1138 Some((token, span)) => Err(ParseError::UnexpectedToken {
1139 expected: "Gt".to_string(),
1140 found: token.clone(),
1141 span: *span,
1142 }),
1143 None => Err(ParseError::UnexpectedEof),
1144 }
1145 }
1146
1147 fn consume_gt(&mut self) -> bool {
1149 if self.pending_gt.is_some() {
1150 self.pending_gt = None;
1151 return true;
1152 }
1153 if self.check(&Token::Gt) {
1154 self.advance();
1155 return true;
1156 }
1157 if self.check(&Token::Shr) {
1159 let span = self.current_span();
1160 self.pending_gt = Some(span);
1161 self.advance();
1162 return true;
1163 }
1164 false
1165 }
1166
1167 fn can_start_item(&self) -> bool {
1170 matches!(
1171 self.current_token(),
1172 Some(
1173 Token::Pub
1174 | Token::Fn
1175 | Token::Async
1176 | Token::Struct
1177 | Token::Enum
1178 | Token::Trait
1179 | Token::Impl
1180 | Token::Type
1181 | Token::Mod
1182 | Token::Use
1183 | Token::Const
1184 | Token::Static
1185 | Token::Actor
1186 | Token::Extern
1187 | Token::Hash
1188 | Token::At
1189 | Token::Naked
1190 | Token::Packed
1191 | Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
1192 | Token::DocComment(_)
1193 | Token::Alter
1195 | Token::Headspace
1196 | Token::Reality
1197 | Token::CoCon
1198 )
1199 ) || (matches!(self.current_token(), Some(Token::On)) && self.peek_next_is_trigger())
1200 }
1201
1202 fn peek_next_is_trigger(&self) -> bool {
1204 false }
1207
1208 fn can_start_stmt(&self) -> bool {
1211 if let Some(token) = self.current_token() {
1213 if Self::keyword_as_ident(token).is_some() {
1214 return true;
1215 }
1216 }
1217 matches!(
1218 self.current_token(),
1219 Some(
1220 Token::Let
1221 | Token::If
1222 | Token::Match
1223 | Token::Loop
1224 | Token::While
1225 | Token::ForAll
1226 | Token::Return
1227 | Token::Tensor
1228 | Token::CycleArrow
1229 | Token::Ident(_)
1230 | Token::SelfLower
1231 | Token::SelfUpper
1232 | Token::LParen
1233 | Token::LBracket
1234 | Token::LBrace
1235 | Token::StringLit(_)
1237 | Token::IntLit(_)
1238 | Token::FloatLit(_)
1239 | Token::True
1240 | Token::False
1241 | Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)
1242 | Token::DocComment(_)
1243 )
1244 ) || self.can_start_item()
1245 }
1246
1247 fn expect_semi_or_item_start(&mut self) -> ParseResult<()> {
1250 if self.consume_if(&Token::Semi) {
1251 return Ok(());
1252 }
1253 if self.can_start_item() || self.is_eof() || self.check(&Token::RBrace) {
1254 return Ok(());
1256 }
1257 let span = self.current_span();
1258 Err(ParseError::UnexpectedToken {
1259 expected: "`;` or new item".to_string(),
1260 found: self.current_token().cloned().unwrap_or(Token::Semi),
1261 span,
1262 })
1263 }
1264
1265 fn parse_item(&mut self) -> ParseResult<Spanned<Item>> {
1268 self.check_deprecated()?;
1270
1271 let start_span = self.current_span();
1272
1273 let doc_comments = self.collect_doc_comments();
1275
1276 let mut outer_attrs = Vec::new();
1278 while self.check(&Token::Hash) || self.check(&Token::At) {
1279 outer_attrs.push(self.parse_outer_attribute()?);
1280 }
1281
1282 let visibility = self.parse_visibility()?;
1283
1284 let item = match self.current_token() {
1285 Some(Token::Fn) | Some(Token::Async) => {
1286 Item::Function(self.parse_function_with_doc_comments(visibility, outer_attrs, doc_comments)?)
1287 }
1288 Some(Token::Struct) => {
1289 Item::Struct(self.parse_struct_with_doc_comments(visibility, outer_attrs, doc_comments)?)
1290 }
1291 Some(Token::Enum) => Item::Enum(self.parse_enum_with_doc_comments(visibility, doc_comments)?),
1292 Some(Token::Trait) => Item::Trait(self.parse_trait_with_doc_comments(visibility, doc_comments)?),
1293 Some(Token::Impl) => Item::Impl(self.parse_impl_with_doc_comments(doc_comments)?),
1294 Some(Token::Unsafe) => {
1295 self.advance(); match self.current_token() {
1298 Some(Token::Impl) => Item::Impl(self.parse_impl_with_doc_comments(doc_comments)?),
1299 Some(Token::Fn) | Some(Token::Async) => {
1300 Item::Function(self.parse_function_with_doc_comments(visibility, outer_attrs, doc_comments)?)
1301 }
1302 Some(Token::Trait) => Item::Trait(self.parse_trait_with_doc_comments(visibility, doc_comments)?),
1303 Some(t) => {
1304 return Err(ParseError::UnexpectedToken {
1305 expected: "impl, fn, or trait after unsafe".to_string(),
1306 found: t.clone(),
1307 span: self.current_span(),
1308 })
1309 }
1310 None => return Err(ParseError::UnexpectedEof),
1311 }
1312 }
1313 Some(Token::Type) => Item::TypeAlias(self.parse_type_alias(visibility)?),
1314 Some(Token::Mod) => Item::Module(self.parse_module_with_doc_comments(visibility, doc_comments)?),
1315 Some(Token::Use) => Item::Use(self.parse_use(visibility)?),
1316 Some(Token::Const) => {
1317 if self.peek_next().map(|t| matches!(t, Token::Fn | Token::Async)) == Some(true) {
1319 Item::Function(self.parse_function_with_doc_comments(visibility, outer_attrs, doc_comments)?)
1320 } else {
1321 Item::Const(self.parse_const_with_doc_comments(visibility, doc_comments)?)
1322 }
1323 }
1324 Some(Token::Static) => Item::Static(self.parse_static_with_doc_comments(visibility, doc_comments)?),
1325 Some(Token::Actor) => Item::Actor(self.parse_actor(visibility)?),
1326 Some(Token::Extern) => Item::ExternBlock(self.parse_extern_block()?),
1327 Some(Token::Macro) | Some(Token::MacroRules) | Some(Token::Rune) => Item::Macro(self.parse_macro_def(visibility)?),
1328 Some(Token::Naked) => {
1329 Item::Function(self.parse_function_with_doc_comments(visibility, outer_attrs, doc_comments)?)
1331 }
1332 Some(Token::Packed) => {
1333 Item::Struct(self.parse_struct_with_doc_comments(visibility, outer_attrs, doc_comments)?)
1335 }
1336 Some(Token::Alter) => {
1338 use crate::plurality::PluralityParser;
1339 Item::Plurality(crate::plurality::PluralityItem::Alter(
1340 self.parse_alter_def(visibility)?,
1341 ))
1342 }
1343 Some(Token::Headspace) => {
1344 use crate::plurality::PluralityParser;
1345 Item::Plurality(crate::plurality::PluralityItem::Headspace(
1346 self.parse_headspace_def(visibility)?,
1347 ))
1348 }
1349 Some(Token::Reality) => {
1350 use crate::plurality::PluralityParser;
1351 Item::Plurality(crate::plurality::PluralityItem::Reality(
1352 self.parse_reality_def(visibility)?,
1353 ))
1354 }
1355 Some(Token::CoCon) => {
1356 use crate::plurality::PluralityParser;
1357 Item::Plurality(crate::plurality::PluralityItem::CoConChannel(
1358 self.parse_cocon_channel()?,
1359 ))
1360 }
1361 Some(Token::On) => {
1362 if self.peek_next() == Some(&Token::Trigger) {
1364 use crate::plurality::PluralityParser;
1365 Item::Plurality(crate::plurality::PluralityItem::TriggerHandler(
1366 self.parse_trigger_handler()?,
1367 ))
1368 } else {
1369 return Err(ParseError::UnexpectedToken {
1370 expected: "item".to_string(),
1371 found: Token::On,
1372 span: self.current_span(),
1373 });
1374 }
1375 }
1376 Some(Token::Ident(_)) => {
1378 if self.looks_like_macro_invocation() {
1380 Item::MacroInvocation(self.parse_macro_invocation()?)
1381 } else {
1382 return Err(ParseError::UnexpectedToken {
1383 expected: "item".to_string(),
1384 found: self.current_token().unwrap().clone(),
1385 span: self.current_span(),
1386 });
1387 }
1388 }
1389 Some(token) => {
1390 return Err(ParseError::UnexpectedToken {
1391 expected: "item".to_string(),
1392 found: token.clone(),
1393 span: self.current_span(),
1394 });
1395 }
1396 None => return Err(ParseError::UnexpectedEof),
1397 };
1398
1399 let end_span = self.current_span();
1400 Ok(Spanned::new(item, start_span.merge(end_span)))
1401 }
1402
1403 pub(crate) fn parse_visibility(&mut self) -> ParseResult<Visibility> {
1404 if self.consume_if(&Token::Pub) {
1405 Ok(Visibility::Public)
1406 } else {
1407 Ok(Visibility::Private)
1408 }
1409 }
1410
1411 fn parse_function(&mut self, visibility: Visibility) -> ParseResult<Function> {
1412 self.parse_function_with_doc_comments(visibility, Vec::new(), vec![])
1413 }
1414
1415 fn parse_function_with_attrs(
1416 &mut self,
1417 visibility: Visibility,
1418 outer_attrs: Vec<Attribute>,
1419 ) -> ParseResult<Function> {
1420 self.parse_function_with_doc_comments(visibility, outer_attrs, vec![])
1421 }
1422
1423 fn parse_function_with_doc_comments(
1424 &mut self,
1425 visibility: Visibility,
1426 outer_attrs: Vec<Attribute>,
1427 doc_comments: Vec<crate::ast::DocComment>,
1428 ) -> ParseResult<Function> {
1429 let mut attrs = self.process_function_attrs(&outer_attrs);
1431
1432 if self.consume_if(&Token::Naked) {
1434 attrs.naked = true;
1435 }
1436
1437 let is_unsafe = self.consume_if(&Token::Unsafe);
1439
1440 let is_const = self.consume_if(&Token::Const);
1442
1443 let is_async = self.consume_if(&Token::Async);
1444 self.expect(Token::Fn)?;
1445
1446 let mut name = self.parse_ident()?;
1447
1448 if let Some(ev) = self.parse_evidentiality_opt() {
1451 if name.evidentiality.is_none() {
1453 name.evidentiality = Some(ev);
1454 }
1455 }
1456
1457 let aspect = match self.current_token() {
1459 Some(Token::AspectProgressive) => {
1460 self.advance();
1461 Some(Aspect::Progressive)
1462 }
1463 Some(Token::AspectPerfective) => {
1464 self.advance();
1465 Some(Aspect::Perfective)
1466 }
1467 Some(Token::AspectPotential) => {
1468 self.advance();
1469 Some(Aspect::Potential)
1470 }
1471 Some(Token::AspectResultative) => {
1472 self.advance();
1473 Some(Aspect::Resultative)
1474 }
1475 _ => None,
1476 };
1477
1478 let generics = self.parse_generics_opt()?;
1479
1480 self.expect(Token::LParen)?;
1481 let params = self.parse_params()?;
1482 self.expect(Token::RParen)?;
1483
1484 let return_type = if self.consume_if(&Token::Arrow) {
1485 Some(self.parse_type()?)
1486 } else {
1487 None
1488 };
1489
1490 let is_async = is_async || self.consume_if(&Token::Async);
1493
1494 let where_clause = self.parse_where_clause_opt()?;
1495
1496 let body = if self.check(&Token::LBrace) {
1497 Some(self.parse_block()?)
1498 } else {
1499 if !self.consume_if(&Token::Semi) {
1502 let valid_terminator = matches!(
1508 self.current_token(),
1509 Some(Token::Fn) | Some(Token::Async) | Some(Token::Unsafe)
1510 | Some(Token::Const) | Some(Token::Type) | Some(Token::Pub)
1511 | Some(Token::DocComment(_)) | Some(Token::LineComment(_))
1512 | Some(Token::BlockComment(_)) | Some(Token::TildeComment(_))
1513 | Some(Token::RBrace) | Some(Token::Hash)
1514 );
1515 if !valid_terminator {
1516 return match self.current_token().cloned() {
1517 Some(token) => Err(ParseError::UnexpectedToken {
1518 expected: "Semi".to_string(),
1519 found: token,
1520 span: self.current_span(),
1521 }),
1522 None => Err(ParseError::UnexpectedEof),
1523 };
1524 }
1525 }
1526 None
1527 };
1528
1529 Ok(Function {
1530 doc_comments,
1531 visibility,
1532 is_async,
1533 is_const,
1534 is_unsafe,
1535 attrs,
1536 name,
1537 aspect,
1538 generics,
1539 params,
1540 return_type,
1541 where_clause,
1542 body,
1543 })
1544 }
1545
1546 fn process_function_attrs(&self, attrs: &[Attribute]) -> FunctionAttrs {
1548 let mut func_attrs = FunctionAttrs::default();
1549
1550 for attr in attrs {
1551 match attr.name.name.as_str() {
1552 "panic_handler" => func_attrs.panic_handler = true,
1553 "entry" => func_attrs.entry = true,
1554 "no_mangle" => func_attrs.no_mangle = true,
1555 "export" => func_attrs.export = true,
1556 "cold" => func_attrs.cold = true,
1557 "hot" => func_attrs.hot = true,
1558 "test" => func_attrs.test = true,
1559 "naked" => func_attrs.naked = true,
1560 "inline" => {
1561 func_attrs.inline = Some(match &attr.args {
1562 Some(AttrArgs::Paren(args)) => {
1563 if let Some(AttrArg::Ident(ident)) = args.first() {
1564 match ident.name.as_str() {
1565 "always" => InlineHint::Always,
1566 "never" => InlineHint::Never,
1567 _ => InlineHint::Hint,
1568 }
1569 } else {
1570 InlineHint::Hint
1571 }
1572 }
1573 _ => InlineHint::Hint,
1574 });
1575 }
1576 "link_section" => {
1577 if let Some(AttrArgs::Eq(value)) = &attr.args {
1578 if let Expr::Literal(Literal::String(s)) = value.as_ref() {
1579 func_attrs.link_section = Some(s.clone());
1580 }
1581 }
1582 }
1583 "interrupt" => {
1584 if let Some(AttrArgs::Paren(args)) = &attr.args {
1585 if let Some(AttrArg::Literal(Literal::Int { value, base, .. })) =
1586 args.first()
1587 {
1588 let num = Self::parse_int_value(value, *base) as u32;
1589 func_attrs.interrupt = Some(num);
1590 }
1591 }
1592 }
1593 "align" => {
1594 if let Some(AttrArgs::Paren(args)) = &attr.args {
1595 if let Some(AttrArg::Literal(Literal::Int { value, base, .. })) =
1596 args.first()
1597 {
1598 let align = Self::parse_int_value(value, *base) as usize;
1599 func_attrs.align = Some(align);
1600 }
1601 }
1602 }
1603 _ => {
1604 func_attrs.outer_attrs.push(attr.clone());
1606 }
1607 }
1608 }
1609
1610 func_attrs
1611 }
1612
1613 fn parse_struct_with_doc_comments(
1614 &mut self,
1615 visibility: Visibility,
1616 outer_attrs: Vec<Attribute>,
1617 doc_comments: Vec<crate::ast::DocComment>,
1618 ) -> ParseResult<StructDef> {
1619 let mut result = self.parse_struct_with_attrs_internal(visibility, outer_attrs)?;
1620 result.doc_comments = doc_comments;
1621 Ok(result)
1622 }
1623
1624 fn parse_struct_with_attrs(
1625 &mut self,
1626 visibility: Visibility,
1627 outer_attrs: Vec<Attribute>,
1628 ) -> ParseResult<StructDef> {
1629 self.parse_struct_with_attrs_internal(visibility, outer_attrs)
1630 }
1631
1632 fn parse_struct_with_attrs_internal(
1633 &mut self,
1634 visibility: Visibility,
1635 outer_attrs: Vec<Attribute>,
1636 ) -> ParseResult<StructDef> {
1637 let mut attrs = StructAttrs::default();
1639 attrs.outer_attrs = outer_attrs.clone();
1640
1641 for attr in &outer_attrs {
1643 if attr.name.name == "derive" {
1644 if let Some(AttrArgs::Paren(args)) = &attr.args {
1645 for arg in args {
1646 if let AttrArg::Ident(ident) = arg {
1647 let derive = Self::parse_derive_trait(&ident.name)?;
1648 attrs.derives.push(derive);
1649 }
1650 }
1651 }
1652 } else if attr.name.name == "simd" {
1653 attrs.simd = true;
1654 } else if attr.name.name == "repr" {
1655 if let Some(AttrArgs::Paren(args)) = &attr.args {
1656 for arg in args {
1657 if let AttrArg::Ident(ident) = arg {
1658 attrs.repr = Some(match ident.name.as_str() {
1659 "C" => StructRepr::C,
1660 "transparent" => StructRepr::Transparent,
1661 "packed" => {
1662 attrs.packed = true;
1663 StructRepr::C }
1665 other => StructRepr::Int(other.to_string()),
1666 });
1667 } else if let AttrArg::Nested(nested) = arg {
1668 if nested.name.name == "align" {
1669 if let Some(AttrArgs::Paren(align_args)) = &nested.args {
1670 if let Some(AttrArg::Literal(Literal::Int { value, .. })) =
1671 align_args.first()
1672 {
1673 if let Ok(n) = value.parse::<usize>() {
1674 attrs.align = Some(n);
1675 }
1676 }
1677 }
1678 }
1679 }
1680 }
1681 }
1682 }
1683 }
1684
1685 if self.consume_if(&Token::Packed) {
1687 attrs.packed = true;
1688 }
1689
1690 self.expect(Token::Struct)?;
1691 let name = self.parse_ident()?;
1692
1693 let _evidentiality_before = self.parse_evidentiality_opt();
1699
1700 let generics = self.parse_generics_opt()?;
1701
1702 let _evidentiality_after = self.parse_evidentiality_opt();
1704
1705 let _ = self.parse_where_clause_opt()?;
1707
1708 let fields = if self.check(&Token::LBrace) {
1709 self.expect(Token::LBrace)?;
1710 let fields = self.parse_field_defs()?;
1711 self.expect(Token::RBrace)?;
1712 StructFields::Named(fields)
1713 } else if self.check(&Token::LParen) {
1714 self.expect(Token::LParen)?;
1715 let types = self.parse_tuple_struct_fields()?;
1716 self.expect(Token::RParen)?;
1717 self.expect_semi_or_item_start()?;
1719 StructFields::Tuple(types)
1720 } else {
1721 self.expect_semi_or_item_start()?;
1723 StructFields::Unit
1724 };
1725
1726 Ok(StructDef {
1727 doc_comments: vec![], visibility,
1729 attrs,
1730 name,
1731 generics,
1732 fields,
1733 })
1734 }
1735
1736 fn parse_derive_trait(name: &str) -> ParseResult<DeriveTrait> {
1737 match name {
1738 "Debug" => Ok(DeriveTrait::Debug),
1739 "Clone" => Ok(DeriveTrait::Clone),
1740 "Copy" => Ok(DeriveTrait::Copy),
1741 "Default" => Ok(DeriveTrait::Default),
1742 "PartialEq" => Ok(DeriveTrait::PartialEq),
1743 "Eq" => Ok(DeriveTrait::Eq),
1744 "PartialOrd" => Ok(DeriveTrait::PartialOrd),
1745 "Ord" => Ok(DeriveTrait::Ord),
1746 "Hash" => Ok(DeriveTrait::Hash),
1747 "Component" => Ok(DeriveTrait::Component),
1749 "Resource" => Ok(DeriveTrait::Resource),
1750 "Bundle" => Ok(DeriveTrait::Bundle),
1751 "Serialize" => Ok(DeriveTrait::Serialize),
1753 "Deserialize" => Ok(DeriveTrait::Deserialize),
1754 _ => Ok(DeriveTrait::Custom(name.to_string())),
1756 }
1757 }
1758
1759 fn parse_enum_with_doc_comments(
1760 &mut self,
1761 visibility: Visibility,
1762 doc_comments: Vec<crate::ast::DocComment>,
1763 ) -> ParseResult<EnumDef> {
1764 let mut result = self.parse_enum(visibility)?;
1765 result.doc_comments = doc_comments;
1766 Ok(result)
1767 }
1768
1769 fn parse_enum(&mut self, visibility: Visibility) -> ParseResult<EnumDef> {
1770 self.expect(Token::Enum)?;
1771 let name = self.parse_ident()?;
1772 let generics = self.parse_generics_opt()?;
1773
1774 self.expect(Token::LBrace)?;
1775 let mut variants = Vec::new();
1776 while !self.check(&Token::RBrace) && !self.is_eof() {
1777 while matches!(
1779 self.current_token(),
1780 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1781 ) {
1782 self.advance();
1783 }
1784 while self.check(&Token::Hash) || self.check(&Token::At) {
1786 self.parse_outer_attribute()?;
1787 }
1788 while matches!(
1790 self.current_token(),
1791 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1792 ) {
1793 self.advance();
1794 }
1795 if self.check(&Token::RBrace) {
1796 break;
1797 }
1798 variants.push(self.parse_enum_variant()?);
1799 if !self.consume_if(&Token::Comma) {
1800 break;
1801 }
1802 while matches!(
1804 self.current_token(),
1805 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1806 ) {
1807 self.advance();
1808 }
1809 }
1810 self.expect(Token::RBrace)?;
1811
1812 Ok(EnumDef {
1813 doc_comments: vec![], visibility,
1815 name,
1816 generics,
1817 variants,
1818 })
1819 }
1820
1821 fn parse_enum_variant(&mut self) -> ParseResult<EnumVariant> {
1822 let name = self.parse_ident()?;
1823
1824 let fields = if self.check(&Token::LBrace) {
1825 self.expect(Token::LBrace)?;
1826 let fields = self.parse_field_defs()?;
1827 self.expect(Token::RBrace)?;
1828 StructFields::Named(fields)
1829 } else if self.check(&Token::LParen) {
1830 self.expect(Token::LParen)?;
1831 let types = self.parse_attributed_type_list()?;
1832 self.expect(Token::RParen)?;
1833 StructFields::Tuple(types)
1834 } else {
1835 StructFields::Unit
1836 };
1837
1838 let discriminant = if self.consume_if(&Token::Eq) {
1839 Some(self.parse_expr()?)
1840 } else {
1841 None
1842 };
1843
1844 Ok(EnumVariant {
1845 name,
1846 fields,
1847 discriminant,
1848 })
1849 }
1850
1851 fn parse_trait_with_doc_comments(
1852 &mut self,
1853 visibility: Visibility,
1854 doc_comments: Vec<crate::ast::DocComment>,
1855 ) -> ParseResult<TraitDef> {
1856 let mut result = self.parse_trait(visibility)?;
1857 result.doc_comments = doc_comments;
1858 Ok(result)
1859 }
1860
1861 fn parse_trait(&mut self, visibility: Visibility) -> ParseResult<TraitDef> {
1862 self.expect(Token::Trait)?;
1863 let name = self.parse_ident()?;
1864 let generics = self.parse_generics_opt()?;
1865
1866 let supertraits = if self.consume_if(&Token::Colon) {
1867 self.parse_type_bounds()?
1868 } else {
1869 vec![]
1870 };
1871
1872 self.expect(Token::LBrace)?;
1873 let mut items = Vec::new();
1874 while !self.check(&Token::RBrace) && !self.is_eof() {
1875 while matches!(
1877 self.current_token(),
1878 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
1879 ) {
1880 self.advance();
1881 }
1882 if self.check(&Token::RBrace) {
1883 break;
1884 }
1885 items.push(self.parse_trait_item()?);
1886 }
1887 self.expect(Token::RBrace)?;
1888
1889 Ok(TraitDef {
1890 doc_comments: vec![], visibility,
1892 name,
1893 generics,
1894 supertraits,
1895 items,
1896 })
1897 }
1898
1899 fn parse_trait_item(&mut self) -> ParseResult<TraitItem> {
1900 let visibility = self.parse_visibility()?;
1901
1902 match self.current_token() {
1903 Some(Token::Fn) | Some(Token::Async) | Some(Token::Unsafe) => {
1904 Ok(TraitItem::Function(self.parse_function(visibility)?))
1905 }
1906 Some(Token::Type) => {
1907 self.advance();
1908 let name = self.parse_ident()?;
1909 let bounds = if self.consume_if(&Token::Colon) {
1910 self.parse_type_bounds()?
1911 } else {
1912 vec![]
1913 };
1914 self.expect(Token::Semi)?;
1915 Ok(TraitItem::Type { name, bounds })
1916 }
1917 Some(Token::Const) => {
1918 if self.peek_next().map(|t| matches!(t, Token::Fn | Token::Async)) == Some(true) {
1920 Ok(TraitItem::Function(self.parse_function(visibility)?))
1921 } else {
1922 self.advance();
1923 let name = self.parse_ident()?;
1924 self.expect(Token::Colon)?;
1925 let ty = self.parse_type()?;
1926 self.expect(Token::Semi)?;
1927 Ok(TraitItem::Const { name, ty })
1928 }
1929 }
1930 Some(token) => Err(ParseError::UnexpectedToken {
1931 expected: "trait item".to_string(),
1932 found: token.clone(),
1933 span: self.current_span(),
1934 }),
1935 None => Err(ParseError::UnexpectedEof),
1936 }
1937 }
1938
1939 fn parse_impl_with_doc_comments(
1940 &mut self,
1941 doc_comments: Vec<crate::ast::DocComment>,
1942 ) -> ParseResult<ImplBlock> {
1943 let mut result = self.parse_impl()?;
1944 result.doc_comments = doc_comments;
1945 Ok(result)
1946 }
1947
1948 fn parse_impl(&mut self) -> ParseResult<ImplBlock> {
1949 self.expect(Token::Impl)?;
1950 let generics = self.parse_generics_opt()?;
1951
1952 let first_type = self.parse_type()?;
1954
1955 let (trait_, self_ty) = if self.consume_if(&Token::ForAll) {
1957 let self_ty = self.parse_type()?;
1959 let trait_path = match first_type {
1960 TypeExpr::Path(p) => p,
1961 _ => return Err(ParseError::Custom("expected trait path".to_string())),
1962 };
1963 (Some(trait_path), self_ty)
1964 } else if self.consume_if(&Token::Colon) {
1965 let trait_ty = self.parse_type()?;
1967 let trait_path = match trait_ty {
1968 TypeExpr::Path(p) => p,
1969 _ => return Err(ParseError::Custom("expected trait path".to_string())),
1970 };
1971 (Some(trait_path), first_type)
1972 } else {
1973 (None, first_type)
1974 };
1975
1976 let _ = self.parse_where_clause_opt()?;
1978
1979 self.expect(Token::LBrace)?;
1980 let mut items = Vec::new();
1981 while !self.check(&Token::RBrace) && !self.is_eof() {
1982 while matches!(
1984 self.current_token(),
1985 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)) | Some(Token::Hash)
1986 ) {
1987 if self.check(&Token::Hash) {
1988 self.advance();
1990 self.consume_if(&Token::Bang);
1991 if self.consume_if(&Token::LBracket) {
1992 let mut depth = 1;
1993 while depth > 0 && !self.is_eof() {
1994 match self.current_token() {
1995 Some(Token::LBracket) => depth += 1,
1996 Some(Token::RBracket) => depth -= 1,
1997 _ => {}
1998 }
1999 self.advance();
2000 }
2001 }
2002 } else {
2003 self.advance();
2004 }
2005 }
2006 if self.check(&Token::RBrace) {
2007 break;
2008 }
2009 items.push(self.parse_impl_item()?);
2010 }
2011 self.expect(Token::RBrace)?;
2012
2013 Ok(ImplBlock {
2014 doc_comments: vec![], generics,
2016 trait_,
2017 self_ty,
2018 items,
2019 })
2020 }
2021
2022 fn parse_impl_item(&mut self) -> ParseResult<ImplItem> {
2023 let mut outer_attrs = Vec::new();
2025 while self.check(&Token::Hash) || self.check(&Token::At) {
2026 outer_attrs.push(self.parse_outer_attribute()?);
2027 }
2028
2029 let visibility = self.parse_visibility()?;
2030
2031 match self.current_token() {
2032 Some(Token::Fn) | Some(Token::Async) | Some(Token::Unsafe) => {
2033 Ok(ImplItem::Function(self.parse_function_with_attrs(visibility, outer_attrs)?))
2034 }
2035 Some(Token::Type) => Ok(ImplItem::Type(self.parse_type_alias(visibility)?)),
2036 Some(Token::Const) => {
2037 if self.peek_next().map(|t| matches!(t, Token::Fn | Token::Async)) == Some(true) {
2039 Ok(ImplItem::Function(self.parse_function_with_attrs(visibility, outer_attrs)?))
2040 } else {
2041 Ok(ImplItem::Const(self.parse_const(visibility)?))
2042 }
2043 }
2044 Some(token) => Err(ParseError::UnexpectedToken {
2045 expected: "impl item".to_string(),
2046 found: token.clone(),
2047 span: self.current_span(),
2048 }),
2049 None => Err(ParseError::UnexpectedEof),
2050 }
2051 }
2052
2053 fn parse_type_alias(&mut self, visibility: Visibility) -> ParseResult<TypeAlias> {
2054 self.expect(Token::Type)?;
2055 let name = self.parse_ident()?;
2056 let generics = self.parse_generics_opt()?;
2057 let _evidentiality = self.parse_evidentiality_opt();
2059 self.expect(Token::Eq)?;
2060 let ty = self.parse_type()?;
2061 self.consume_if(&Token::Semi);
2063
2064 Ok(TypeAlias {
2065 visibility,
2066 name,
2067 generics,
2068 ty,
2069 })
2070 }
2071
2072 fn parse_module_with_doc_comments(
2073 &mut self,
2074 visibility: Visibility,
2075 doc_comments: Vec<crate::ast::DocComment>,
2076 ) -> ParseResult<Module> {
2077 let mut result = self.parse_module(visibility)?;
2078 result.doc_comments = doc_comments;
2079 Ok(result)
2080 }
2081
2082 fn parse_module(&mut self, visibility: Visibility) -> ParseResult<Module> {
2083 self.expect(Token::Mod)?;
2084 let name = self.parse_ident()?;
2085
2086 let items = if self.check(&Token::LBrace) {
2087 self.expect(Token::LBrace)?;
2088 let mut items = Vec::new();
2089 while !self.check(&Token::RBrace) && !self.is_eof() {
2090 while matches!(
2092 self.current_token(),
2093 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
2094 ) {
2095 self.advance();
2096 }
2097 if self.check(&Token::RBrace) {
2098 break;
2099 }
2100 items.push(self.parse_item()?);
2101 }
2102 self.expect(Token::RBrace)?;
2103 Some(items)
2104 } else {
2105 self.expect_semi_or_item_start()?;
2107 None
2108 };
2109
2110 Ok(Module {
2111 doc_comments: vec![], visibility,
2113 name,
2114 items,
2115 })
2116 }
2117
2118 fn parse_use(&mut self, visibility: Visibility) -> ParseResult<UseDecl> {
2119 self.expect(Token::Use)?;
2120 let tree = self.parse_use_tree()?;
2121 self.expect_semi_or_item_start()?;
2123
2124 Ok(UseDecl { visibility, tree })
2125 }
2126
2127 fn parse_use_tree(&mut self) -> ParseResult<UseTree> {
2128 if self.consume_if(&Token::Star) {
2129 return Ok(UseTree::Glob);
2130 }
2131
2132 if self.check(&Token::LBrace) {
2133 self.expect(Token::LBrace)?;
2134 let mut trees = Vec::new();
2135 while !self.check(&Token::RBrace) {
2136 loop {
2138 if matches!(
2139 self.current_token(),
2140 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
2141 ) {
2142 self.advance();
2143 } else if self.check(&Token::Hash) {
2144 self.skip_attribute()?;
2146 } else {
2147 break;
2148 }
2149 }
2150 if self.check(&Token::RBrace) {
2151 break;
2152 }
2153 trees.push(self.parse_use_tree()?);
2154 if !self.consume_if(&Token::Comma) {
2155 break;
2156 }
2157 loop {
2159 if matches!(
2160 self.current_token(),
2161 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
2162 ) {
2163 self.advance();
2164 } else if self.check(&Token::Hash) {
2165 self.skip_attribute()?;
2167 } else {
2168 break;
2169 }
2170 }
2171 }
2172 self.expect(Token::RBrace)?;
2173 return Ok(UseTree::Group(trees));
2174 }
2175
2176 let name = if self.check(&Token::Crate) {
2178 let span = self.current_span();
2179 self.advance();
2180 Ident {
2181 name: "crate".to_string(),
2182 evidentiality: None,
2183 affect: None,
2184 span,
2185 }
2186 } else if self.check(&Token::Super) {
2187 let span = self.current_span();
2188 self.advance();
2189 Ident {
2190 name: "super".to_string(),
2191 evidentiality: None,
2192 affect: None,
2193 span,
2194 }
2195 } else if self.check(&Token::SelfLower) {
2196 let span = self.current_span();
2197 self.advance();
2198 Ident {
2199 name: "self".to_string(),
2200 evidentiality: None,
2201 affect: None,
2202 span,
2203 }
2204 } else if self.check(&Token::Sqrt) {
2205 let span = self.current_span();
2207 self.advance();
2208 if let Some(Token::IntLit(n)) = self.current_token().cloned() {
2210 let merged_span = span.merge(self.current_span());
2211 self.advance();
2212 Ident {
2213 name: format!("√{}", n),
2214 evidentiality: None,
2215 affect: None,
2216 span: merged_span,
2217 }
2218 } else {
2219 Ident {
2220 name: "√".to_string(),
2221 evidentiality: None,
2222 affect: None,
2223 span,
2224 }
2225 }
2226 } else if self.check(&Token::Phi) {
2227 let span = self.current_span();
2229 self.advance();
2230 Ident {
2231 name: "φ".to_string(),
2232 evidentiality: None,
2233 affect: None,
2234 span,
2235 }
2236 } else {
2237 self.parse_ident()?
2238 };
2239
2240 let _evidentiality = self.parse_evidentiality_opt();
2243
2244 if self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::MiddleDot) {
2246 let suffix = self.parse_use_tree()?;
2247 return Ok(UseTree::Path {
2248 prefix: name,
2249 suffix: Box::new(suffix),
2250 });
2251 }
2252
2253 if self.consume_if(&Token::As) {
2255 if self.check(&Token::Underscore) {
2257 let span = self.current_span();
2258 self.advance();
2259 let alias = Ident {
2260 name: "_".to_string(),
2261 evidentiality: None,
2262 affect: None,
2263 span,
2264 };
2265 return Ok(UseTree::Rename { name, alias });
2266 }
2267 let alias = self.parse_ident()?;
2268 return Ok(UseTree::Rename { name, alias });
2269 }
2270
2271 Ok(UseTree::Name(name))
2272 }
2273
2274 fn parse_const_with_doc_comments(
2275 &mut self,
2276 visibility: Visibility,
2277 doc_comments: Vec<crate::ast::DocComment>,
2278 ) -> ParseResult<ConstDef> {
2279 let mut result = self.parse_const(visibility)?;
2280 result.doc_comments = doc_comments;
2281 Ok(result)
2282 }
2283
2284 fn parse_const(&mut self, visibility: Visibility) -> ParseResult<ConstDef> {
2285 self.expect(Token::Const)?;
2286 let name = self.parse_ident()?;
2287 self.expect(Token::Colon)?;
2288 let ty = self.parse_type()?;
2289 self.expect(Token::Eq)?;
2290 let value = self.parse_expr()?;
2291 self.expect_semi_or_item_start()?;
2293
2294 Ok(ConstDef {
2295 doc_comments: vec![],
2296 visibility,
2297 name,
2298 ty,
2299 value,
2300 })
2301 }
2302
2303 fn parse_static_with_doc_comments(
2304 &mut self,
2305 visibility: Visibility,
2306 doc_comments: Vec<crate::ast::DocComment>,
2307 ) -> ParseResult<StaticDef> {
2308 let mut result = self.parse_static(visibility)?;
2309 result.doc_comments = doc_comments;
2310 Ok(result)
2311 }
2312
2313 fn parse_static(&mut self, visibility: Visibility) -> ParseResult<StaticDef> {
2314 self.expect(Token::Static)?;
2315 let mutable = self.consume_if(&Token::Mut);
2316 let name = self.parse_ident()?;
2317 self.expect(Token::Colon)?;
2318 let ty = self.parse_type()?;
2319 self.expect(Token::Eq)?;
2320 let value = self.parse_expr()?;
2321 self.expect_semi_or_item_start()?;
2323
2324 Ok(StaticDef {
2325 doc_comments: vec![],
2326 visibility,
2327 mutable,
2328 name,
2329 ty,
2330 value,
2331 })
2332 }
2333
2334 fn parse_macro_def(&mut self, visibility: Visibility) -> ParseResult<MacroDef> {
2337 let is_macro_rules = self.check(&Token::MacroRules);
2339 let is_rune = self.check(&Token::Rune);
2340 if is_macro_rules {
2341 self.advance(); self.expect(Token::Bang)?; } else if is_rune {
2344 self.advance(); } else {
2346 self.expect(Token::Macro)?;
2347 }
2348
2349 let name = self.parse_ident()?;
2350
2351 if is_rune {
2353 let _ = self.consume_if(&Token::Bang);
2354 }
2355
2356 let mut body = String::new();
2359 let mut depth = 0;
2360
2361 if self.check(&Token::LParen) {
2363 body.push('(');
2364 self.advance();
2365 depth = 1;
2366 while depth > 0 && !self.is_eof() {
2367 match self.current_token() {
2368 Some(Token::LParen) => {
2369 depth += 1;
2370 body.push('(');
2371 }
2372 Some(Token::RParen) => {
2373 depth -= 1;
2374 if depth > 0 {
2375 body.push(')');
2376 }
2377 }
2378 Some(tok) => {
2379 body.push_str(&Self::token_to_source(tok));
2380 if !matches!(tok, Token::Dollar) {
2382 body.push(' ');
2383 }
2384 }
2385 None => break,
2386 }
2387 self.advance();
2388 }
2389 body.push(')');
2390 }
2391
2392 self.expect(Token::LBrace)?;
2394 body.push('{');
2395 depth = 1;
2396 while depth > 0 && !self.is_eof() {
2397 match self.current_token() {
2398 Some(Token::LBrace) => {
2399 depth += 1;
2400 body.push('{');
2401 }
2402 Some(Token::RBrace) => {
2403 depth -= 1;
2404 if depth > 0 {
2405 body.push('}');
2406 }
2407 }
2408 Some(Token::LineComment(s)) => {
2409 body.push_str(&format!("//{}\n", s));
2410 }
2411 Some(tok) => {
2412 body.push_str(&Self::token_to_source(tok));
2413 if !matches!(tok, Token::Dollar) {
2415 body.push(' ');
2416 }
2417 }
2418 None => break,
2419 }
2420 self.advance();
2421 }
2422 body.push('}');
2423
2424 Ok(MacroDef {
2425 visibility,
2426 name,
2427 rules: body,
2428 })
2429 }
2430
2431 fn looks_like_macro_invocation(&mut self) -> bool {
2433 if !matches!(self.current_token(), Some(Token::Ident(_))) {
2435 return false;
2436 }
2437 let mut pos = 0;
2440 loop {
2441 match self.peek_n(pos) {
2442 Some(Token::Bang) => return true,
2443 Some(Token::MiddleDot) => {
2444 pos += 1;
2445 match self.peek_n(pos) {
2447 Some(Token::Ident(_)) => {
2448 pos += 1;
2449 continue;
2450 }
2451 _ => return false,
2452 }
2453 }
2454 _ => return false,
2455 }
2456 }
2457 }
2458
2459 fn token_to_source(tok: &Token) -> String {
2461 match tok {
2462 Token::Pub => "☉".to_string(),
2465 Token::Static => "static".to_string(),
2466 Token::Mut => "Δ".to_string(),
2467 Token::Const => "const".to_string(),
2468 Token::Let => "≔".to_string(),
2469 Token::Fn => "rite".to_string(),
2470 Token::Struct => "sigil".to_string(),
2471 Token::Enum => "ᛈ".to_string(),
2472 Token::Impl => "⊢".to_string(),
2473 Token::Trait => "aspect".to_string(),
2474 Token::Type => "type".to_string(),
2475 Token::Mod => "scroll".to_string(),
2476 Token::Use => "invoke".to_string(),
2477 Token::ForAll => "∀".to_string(),
2478 Token::ElementOf => "∈".to_string(),
2479 Token::If => "⎇".to_string(),
2480 Token::Else => "⎉".to_string(),
2481 Token::Match => "⌥".to_string(),
2482 Token::While => "⟳".to_string(),
2483 Token::Loop => "loop".to_string(),
2484 Token::Tensor => "⊗".to_string(),
2485 Token::CycleArrow => "↻".to_string(),
2486 Token::Return => "⤺".to_string(),
2487 Token::Yield => "yield".to_string(),
2488 Token::True => "true".to_string(),
2489 Token::False => "false".to_string(),
2490 Token::SelfLower => "self".to_string(),
2491 Token::SelfUpper => "Self".to_string(),
2492 Token::Super => "super".to_string(),
2493 Token::Crate => "tome".to_string(), Token::Where => "where".to_string(),
2495 Token::As => "as".to_string(),
2496 Token::Async => "async".to_string(),
2497 Token::Await => "await".to_string(),
2498 Token::Dyn => "dyn".to_string(),
2499 Token::Extern => "extern".to_string(),
2500 Token::Move => "move".to_string(),
2501 Token::Ref => "ref".to_string(),
2502 Token::Unsafe => "unsafe".to_string(),
2503 Token::On => "on".to_string(),
2504 Token::Actor => "actor".to_string(),
2505 Token::Macro => "macro".to_string(),
2506 Token::MacroRules => "macro_rules".to_string(),
2507 Token::Null => "null".to_string(),
2508 Token::Ident(s) => s.clone(),
2510 Token::IntLit(s) => s.clone(),
2511 Token::FloatLit(s) => s.clone(),
2512 Token::HexLit(s) => s.clone(),
2513 Token::OctalLit(s) => s.clone(),
2514 Token::BinaryLit(s) => s.clone(),
2515 Token::StringLit(s) => format!("\"{}\"", s),
2516 Token::RawStringLit(s) => format!("r\"{}\"", s),
2517 Token::RawStringDelimited(s) => format!("r#\"{}\"#", s),
2518 Token::MultiLineStringLit(s) => format!("\"\"\"{}\"\"\"", s),
2519 Token::CharLit(c) => format!("'{}'", c),
2520 Token::ByteStringLit(bytes) => {
2521 format!("b\"{}\"", String::from_utf8_lossy(bytes))
2522 }
2523 Token::ByteCharLit(b) => format!("b'{}'", *b as char),
2524 Token::Lifetime(s) => format!("'{}", s),
2525 Token::InterpolatedStringLit(s) => format!("f\"{}\"", s),
2526 Token::Colon => ":".to_string(),
2528 Token::MiddleDot => "·".to_string(),
2529 Token::Semi => ";".to_string(),
2530 Token::Comma => ",".to_string(),
2531 Token::Dot => ".".to_string(),
2532 Token::DotDot => "..".to_string(),
2533 Token::DotDotEq => "..=".to_string(),
2534 Token::Arrow => "->".to_string(),
2535 Token::FatArrow => "=>".to_string(),
2536 Token::LeftArrow => "<-".to_string(),
2537 Token::Question => "?".to_string(),
2538 Token::Bang => "!".to_string(),
2539 Token::Hash => "#".to_string(),
2540 Token::HashBang => "#!".to_string(),
2541 Token::At => "@".to_string(),
2542 Token::Dollar => "$".to_string(),
2543 Token::Underscore => "_".to_string(),
2544 Token::Eq => "=".to_string(),
2546 Token::EqEq => "==".to_string(),
2547 Token::NotEq => "!=".to_string(),
2548 Token::Lt => "<".to_string(),
2549 Token::LtEq => "<=".to_string(),
2550 Token::Gt => ">".to_string(),
2551 Token::GtEq => ">=".to_string(),
2552 Token::Plus => "+".to_string(),
2554 Token::Minus => "-".to_string(),
2555 Token::Star => "*".to_string(),
2556 Token::Slash => "/".to_string(),
2557 Token::Percent => "%".to_string(),
2558 Token::StarStar => "**".to_string(),
2559 Token::PlusPlus => "++".to_string(),
2560 Token::Amp => "&".to_string(),
2562 Token::AndAnd => "&&".to_string(),
2563 Token::Pipe => "|".to_string(),
2564 Token::OrOr => "||".to_string(),
2565 Token::Caret => "^".to_string(),
2566 Token::Tilde => "~".to_string(),
2567 Token::Shl => "<<".to_string(),
2568 Token::Shr => ">>".to_string(),
2569 Token::PlusEq => "+=".to_string(),
2571 Token::MinusEq => "-=".to_string(),
2572 Token::StarEq => "*=".to_string(),
2573 Token::SlashEq => "/=".to_string(),
2574 Token::PercentEq => "%=".to_string(),
2575 Token::AmpEq => "&=".to_string(),
2576 Token::PipeEq => "|=".to_string(),
2577 Token::CaretEq => "^=".to_string(),
2578 Token::ShlEq => "<<=".to_string(),
2579 Token::ShrEq => ">>=".to_string(),
2580 Token::LParen => "(".to_string(),
2582 Token::RParen => ")".to_string(),
2583 Token::LBrace => "{".to_string(),
2584 Token::RBrace => "}".to_string(),
2585 Token::LBracket => "[".to_string(),
2586 Token::RBracket => "]".to_string(),
2587 Token::MiddleDot => "·".to_string(),
2588 Token::Tau => "τ".to_string(),
2590 Token::Phi => "φ".to_string(),
2591 Token::Sigma => "σ".to_string(),
2592 Token::Rho => "ρ".to_string(),
2593 Token::Alpha => "α".to_string(),
2594 Token::Omega => "ω".to_string(),
2595 Token::Mu => "μ".to_string(),
2596 Token::Lambda => "Λ".to_string(),
2597 Token::LambdaExpr => "λ".to_string(),
2598 Token::Pi => "Π".to_string(),
2599 Token::Delta => "δ".to_string(),
2600 Token::Epsilon => "ε".to_string(),
2601 Token::Zeta => "ζ".to_string(),
2602 Token::Chi => "χ".to_string(),
2603 Token::Nu => "ν".to_string(),
2604 Token::Xi => "ξ".to_string(),
2605 Token::Psi => "ψ".to_string(),
2606 Token::Theta => "θ".to_string(),
2607 Token::Kappa => "κ".to_string(),
2608 Token::Nabla => "∇".to_string(),
2609 Token::Empty => "∅".to_string(),
2611 Token::Circle => "◯".to_string(),
2612 Token::Infinity => "∞".to_string(),
2613 Token::Async => "⌛".to_string(),
2614 Token::LineComment(s) => format!("//{}", s),
2616 Token::TildeComment(s) => format!("~~{}", s),
2617 Token::BlockComment(s) => format!("/*{}*/", s),
2618 Token::DocComment(s) => format!("///{}", s),
2619 _ => format!("{:?}", tok),
2621 }
2622 }
2623
2624 fn parse_macro_invocation(&mut self) -> ParseResult<MacroInvocation> {
2626 use crate::ast::{MacroDelimiter, MacroInvocation};
2627
2628 let path = self.parse_type_path()?;
2630
2631 self.expect(Token::Bang)?;
2633
2634 let (delimiter, open_tok, close_tok) = match self.current_token() {
2636 Some(Token::LBrace) => (MacroDelimiter::Brace, Token::LBrace, Token::RBrace),
2637 Some(Token::LParen) => (MacroDelimiter::Paren, Token::LParen, Token::RParen),
2638 Some(Token::LBracket) => (MacroDelimiter::Bracket, Token::LBracket, Token::RBracket),
2639 Some(tok) => {
2640 return Err(ParseError::UnexpectedToken {
2641 expected: "macro delimiter ('{', '(', or '[')".to_string(),
2642 found: tok.clone(),
2643 span: self.current_span(),
2644 });
2645 }
2646 None => return Err(ParseError::UnexpectedEof),
2647 };
2648
2649 self.advance(); let mut body = String::new();
2653 let mut depth = 1;
2654
2655 while depth > 0 && !self.is_eof() {
2656 let tok = self.current_token().cloned();
2657 match &tok {
2658 Some(t) if *t == open_tok => {
2659 depth += 1;
2660 body.push_str(&Self::token_to_source(t));
2661 body.push(' ');
2662 }
2663 Some(t) if *t == close_tok => {
2664 depth -= 1;
2665 if depth > 0 {
2666 body.push_str(&Self::token_to_source(t));
2667 body.push(' ');
2668 }
2669 }
2670 Some(t) => {
2671 body.push_str(&Self::token_to_source(t));
2672 body.push(' ');
2673 }
2674 None => break,
2675 }
2676 self.advance();
2677 }
2678
2679 if delimiter != MacroDelimiter::Brace {
2681 self.consume_if(&Token::Semi);
2682 }
2683
2684 Ok(MacroInvocation {
2685 path,
2686 delimiter,
2687 tokens: body,
2688 })
2689 }
2690
2691 fn parse_actor(&mut self, visibility: Visibility) -> ParseResult<ActorDef> {
2692 self.expect(Token::Actor)?;
2693 let name = self.parse_ident()?;
2694 let generics = self.parse_generics_opt()?;
2695
2696 self.expect(Token::LBrace)?;
2697
2698 let mut state = Vec::new();
2699 let mut handlers = Vec::new();
2700
2701 while !self.check(&Token::RBrace) && !self.is_eof() {
2702 if self.check(&Token::On) {
2703 handlers.push(self.parse_message_handler()?);
2704 } else {
2705 let vis = self.parse_visibility()?;
2707 let field_name = self.parse_ident()?;
2708 self.expect(Token::Colon)?;
2709 let ty = self.parse_type()?;
2710
2711 let default = if self.consume_if(&Token::Eq) {
2713 Some(self.parse_expr()?)
2714 } else {
2715 None
2716 };
2717
2718 if !self.check(&Token::RBrace) && !self.check(&Token::On) {
2719 self.consume_if(&Token::Comma);
2720 }
2721
2722 state.push(FieldDef {
2723 visibility: vis,
2724 name: field_name,
2725 ty,
2726 default,
2727 });
2728 }
2729 }
2730
2731 self.expect(Token::RBrace)?;
2732
2733 Ok(ActorDef {
2734 visibility,
2735 name,
2736 generics,
2737 state,
2738 handlers,
2739 })
2740 }
2741
2742 fn parse_extern_block(&mut self) -> ParseResult<ExternBlock> {
2744 self.expect(Token::Extern)?;
2745
2746 let abi = if let Some(Token::StringLit(s)) = self.current_token().cloned() {
2748 self.advance();
2749 s
2750 } else {
2751 "C".to_string()
2752 };
2753
2754 self.expect(Token::LBrace)?;
2755
2756 let mut items = Vec::new();
2757
2758 while !self.check(&Token::RBrace) && !self.is_eof() {
2759 let visibility = self.parse_visibility()?;
2760
2761 match self.current_token() {
2762 Some(Token::Fn) => {
2763 items.push(ExternItem::Function(
2764 self.parse_extern_function(visibility)?,
2765 ));
2766 }
2767 Some(Token::Static) => {
2768 items.push(ExternItem::Static(self.parse_extern_static(visibility)?));
2769 }
2770 Some(token) => {
2771 return Err(ParseError::UnexpectedToken {
2772 expected: "fn or static".to_string(),
2773 found: token.clone(),
2774 span: self.current_span(),
2775 });
2776 }
2777 None => return Err(ParseError::UnexpectedEof),
2778 }
2779 }
2780
2781 self.expect(Token::RBrace)?;
2782
2783 Ok(ExternBlock { abi, items })
2784 }
2785
2786 fn parse_extern_function(&mut self, visibility: Visibility) -> ParseResult<ExternFunction> {
2788 self.expect(Token::Fn)?;
2789 let name = self.parse_ident()?;
2790
2791 let _evidentiality = self.parse_evidentiality_opt();
2793
2794 self.expect(Token::LParen)?;
2795
2796 let mut params = Vec::new();
2797 let mut variadic = false;
2798
2799 while !self.check(&Token::RParen) && !self.is_eof() {
2800 if self.check(&Token::DotDot) {
2802 self.advance();
2803 if self.consume_if(&Token::Dot) {
2804 variadic = true;
2805 break;
2806 }
2807 }
2808
2809 let pattern = self.parse_pattern()?;
2810 self.expect(Token::Colon)?;
2811 let ty = self.parse_type()?;
2812
2813 params.push(Param { pattern, ty });
2814
2815 if !self.check(&Token::RParen) {
2816 self.expect(Token::Comma)?;
2817 }
2818 }
2819
2820 self.expect(Token::RParen)?;
2821
2822 let return_type = if self.consume_if(&Token::Arrow) {
2824 Some(self.parse_type()?)
2825 } else {
2826 None
2827 };
2828
2829 self.expect(Token::Semi)?;
2831
2832 Ok(ExternFunction {
2833 visibility,
2834 name,
2835 params,
2836 return_type,
2837 variadic,
2838 })
2839 }
2840
2841 fn parse_extern_static(&mut self, visibility: Visibility) -> ParseResult<ExternStatic> {
2843 self.expect(Token::Static)?;
2844 let mutable = self.consume_if(&Token::Mut);
2845 let name = self.parse_ident()?;
2846 self.expect(Token::Colon)?;
2847 let ty = self.parse_type()?;
2848 self.expect(Token::Semi)?;
2849
2850 Ok(ExternStatic {
2851 visibility,
2852 mutable,
2853 name,
2854 ty,
2855 })
2856 }
2857
2858 fn parse_message_handler(&mut self) -> ParseResult<MessageHandler> {
2859 self.expect(Token::On)?;
2860 let message = self.parse_ident()?;
2861
2862 self.expect(Token::LParen)?;
2863 let params = self.parse_params()?;
2864 self.expect(Token::RParen)?;
2865
2866 let return_type = if self.consume_if(&Token::Arrow) {
2867 Some(self.parse_type()?)
2868 } else {
2869 None
2870 };
2871
2872 let body = self.parse_block()?;
2873
2874 Ok(MessageHandler {
2875 message,
2876 params,
2877 return_type,
2878 body,
2879 })
2880 }
2881
2882 pub(crate) fn parse_type(&mut self) -> ParseResult<TypeExpr> {
2885 if let Some(ev) = self.parse_evidentiality_prefix_opt() {
2887 let inner = self.parse_type()?;
2888 return Ok(TypeExpr::Evidential {
2889 inner: Box::new(inner),
2890 evidentiality: ev,
2891 error_type: None,
2892 });
2893 }
2894
2895 let mut base = self.parse_type_base()?;
2896
2897 let path_evidentiality = if let TypeExpr::Path(ref mut path) = base {
2901 if let Some(last_seg) = path.segments.last_mut() {
2902 last_seg.ident.evidentiality.take()
2903 } else {
2904 None
2905 }
2906 } else {
2907 None
2908 };
2909 if let Some(ev) = path_evidentiality {
2910 base = TypeExpr::Evidential {
2911 inner: Box::new(base),
2912 evidentiality: ev,
2913 error_type: None,
2914 };
2915 }
2916
2917 if let Some(ev) = self.parse_evidentiality_opt() {
2919 let base = if self.check(&Token::Lt) && self.peek_looks_like_generic_arg() {
2922 if let TypeExpr::Path(mut path) = base {
2924 self.advance(); let types = self.parse_type_list()?;
2926 self.expect_gt()?;
2927 if let Some(last) = path.segments.last_mut() {
2929 last.generics = Some(types);
2930 }
2931 TypeExpr::Path(path)
2932 } else {
2933 base
2934 }
2935 } else {
2936 base
2937 };
2938
2939 let error_type = if self.check(&Token::LBracket) {
2941 self.advance(); let err_ty = self.parse_type()?;
2943 self.expect(Token::RBracket)?; Some(Box::new(err_ty))
2945 } else {
2946 None
2947 };
2948
2949 let mut result = TypeExpr::Evidential {
2950 inner: Box::new(base),
2951 evidentiality: ev,
2952 error_type,
2953 };
2954
2955 if let Some(ev2) = self.parse_evidentiality_opt() {
2957 result = TypeExpr::Evidential {
2958 inner: Box::new(result),
2959 evidentiality: ev2,
2960 error_type: None,
2961 };
2962 }
2963
2964 return Ok(result);
2965 }
2966
2967 Ok(base)
2968 }
2969
2970 fn parse_evidentiality_prefix_opt(&mut self) -> Option<Evidentiality> {
2973 match self.current_token() {
2974 Some(Token::Bang) => {
2975 if self.peek_is_type_start() {
2978 self.advance();
2979 Some(Evidentiality::Known)
2980 } else {
2981 None
2982 }
2983 }
2984 Some(Token::Question) => {
2985 if self.peek_is_type_start() {
2986 self.advance();
2987 Some(Evidentiality::Uncertain)
2988 } else {
2989 None
2990 }
2991 }
2992 Some(Token::Tilde) => {
2993 if self.peek_is_type_start() {
2994 self.advance();
2995 Some(Evidentiality::Reported)
2996 } else {
2997 None
2998 }
2999 }
3000 Some(Token::Lozenge) => {
3001 if self.peek_is_type_start() {
3002 self.advance();
3003 Some(Evidentiality::Predicted)
3004 } else {
3005 None
3006 }
3007 }
3008 Some(Token::Interrobang) => {
3009 if self.peek_is_type_start() {
3010 self.advance();
3011 Some(Evidentiality::Paradox)
3012 } else {
3013 None
3014 }
3015 }
3016 _ => None,
3017 }
3018 }
3019
3020 fn peek_is_type_start(&mut self) -> bool {
3022 match self.peek_next() {
3023 Some(Token::Ident(_)) => true,
3024 Some(Token::SelfUpper) => true,
3025 Some(Token::Amp) => true,
3026 Some(Token::AndAnd) => true, Some(Token::Star) => true,
3028 Some(Token::LBracket) => true,
3029 Some(Token::LParen) => true,
3030 Some(Token::Fn) => true,
3031 Some(Token::Underscore) => true,
3032 Some(Token::Simd) => true,
3033 Some(Token::Atomic) => true,
3034 Some(Token::Bang) => true,
3036 Some(Token::Question) => true,
3037 Some(Token::Tilde) => true,
3038 Some(Token::Interrobang) => true,
3039 _ => false,
3040 }
3041 }
3042
3043 fn parse_type_base(&mut self) -> ParseResult<TypeExpr> {
3044 if let Some(Token::DeprecatedAmpMut) = self.current_token() {
3046 let span = self.current_span();
3047 return Err(ParseError::DeprecatedRustSyntax {
3048 rust: "&mut".to_string(),
3049 sigil: "&Δ (reference to mutable) or just Δ for mutable binding".to_string(),
3050 span,
3051 });
3052 }
3053
3054 match self.current_token() {
3055 Some(Token::AndAnd) => {
3056 self.advance();
3058 let lifetime = if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
3060 self.advance();
3061 Some(lt)
3062 } else {
3063 None
3064 };
3065 let mutable = self.consume_if(&Token::Mut);
3066 let inner = self.parse_type()?;
3067 let inner_ref = TypeExpr::Reference {
3069 lifetime,
3070 mutable,
3071 inner: Box::new(inner),
3072 };
3073 Ok(TypeExpr::Reference {
3075 lifetime: None,
3076 mutable: false,
3077 inner: Box::new(inner_ref),
3078 })
3079 }
3080 Some(Token::Amp) => {
3081 self.advance();
3082 let lifetime = if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
3084 self.advance();
3085 Some(lt)
3086 } else {
3087 None
3088 };
3089 let mutable = self.consume_if(&Token::Mut);
3090 let inner = self.parse_type()?;
3091 Ok(TypeExpr::Reference {
3092 lifetime,
3093 mutable,
3094 inner: Box::new(inner),
3095 })
3096 }
3097 Some(Token::Star) => {
3098 self.advance();
3099 let mutable = if self.consume_if(&Token::Const) {
3102 false
3103 } else if self.consume_if(&Token::Mut) {
3104 true
3105 } else {
3106 false
3108 };
3109 let inner = self.parse_type()?;
3110 Ok(TypeExpr::Pointer {
3111 mutable,
3112 inner: Box::new(inner),
3113 })
3114 }
3115 Some(Token::LBracket) => {
3116 self.advance();
3117 if self.check(&Token::RBracket) {
3119 self.advance();
3121 return Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(vec![]))));
3123 }
3124 let first = self.parse_type_or_lifetime()?;
3126 if self.consume_if(&Token::Semi) {
3127 let size = self.parse_expr()?;
3129 self.expect(Token::RBracket)?;
3130 Ok(TypeExpr::Array {
3131 element: Box::new(first),
3132 size: Box::new(size),
3133 })
3134 } else if self.consume_if(&Token::Comma) {
3135 let first_expr = match first {
3138 TypeExpr::Path(path) => Expr::Path(path),
3139 TypeExpr::ConstExpr(expr) => *expr,
3140 _ => Expr::Path(TypePath {
3141 segments: vec![PathSegment {
3142 ident: Ident {
3143 name: format!("{:?}", first),
3144 evidentiality: None,
3145 affect: None,
3146 span: Span::new(0, 0),
3147 },
3148 generics: None,
3149 }],
3150 }),
3151 };
3152 let mut elem_exprs = vec![first_expr];
3153 while !self.check(&Token::RBracket) && !self.is_eof() {
3154 let dim_expr = self.parse_array_dim_expr()?;
3156 elem_exprs.push(dim_expr);
3157 if !self.consume_if(&Token::Comma) {
3158 break;
3159 }
3160 }
3161 self.expect(Token::RBracket)?;
3162 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(elem_exprs))))
3163 } else if matches!(
3164 self.current_token(),
3165 Some(Token::Slash)
3166 | Some(Token::Star)
3167 | Some(Token::Plus)
3168 | Some(Token::Minus)
3169 | Some(Token::Percent)
3170 ) {
3171 let first_expr = match first {
3174 TypeExpr::Path(path) => Expr::Path(path),
3175 TypeExpr::ConstExpr(expr) => *expr,
3176 _ => Expr::Path(TypePath {
3177 segments: vec![PathSegment {
3178 ident: Ident {
3179 name: format!("{:?}", first),
3180 evidentiality: None,
3181 affect: None,
3182 span: Span::new(0, 0),
3183 },
3184 generics: None,
3185 }],
3186 }),
3187 };
3188 let op = match self.current_token() {
3190 Some(Token::Slash) => BinOp::Div,
3191 Some(Token::Star) => BinOp::Mul,
3192 Some(Token::Plus) => BinOp::Add,
3193 Some(Token::Minus) => BinOp::Sub,
3194 Some(Token::Percent) => BinOp::Rem,
3195 _ => unreachable!(),
3196 };
3197 self.advance(); let right = self.parse_const_expr_primary()?;
3199 let expr = Expr::Binary {
3200 left: Box::new(first_expr),
3201 op,
3202 right: Box::new(right),
3203 };
3204
3205 if self.consume_if(&Token::Comma) {
3207 let mut elem_exprs = vec![expr];
3208 while !self.check(&Token::RBracket) && !self.is_eof() {
3209 let dim_expr = self.parse_array_dim_expr()?;
3210 elem_exprs.push(dim_expr);
3211 if !self.consume_if(&Token::Comma) {
3212 break;
3213 }
3214 }
3215 self.expect(Token::RBracket)?;
3216 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(elem_exprs))))
3217 } else {
3218 self.expect(Token::RBracket)?;
3219 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(vec![expr]))))
3220 }
3221 } else {
3222 self.expect(Token::RBracket)?;
3223 match &first {
3226 TypeExpr::ConstExpr(expr) => {
3227 if matches!(expr.as_ref(), Expr::Literal(Literal::Int { .. })) {
3228 let first_expr = *expr.clone();
3230 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(vec![first_expr]))))
3231 } else {
3232 Ok(TypeExpr::Slice(Box::new(first)))
3234 }
3235 }
3236 TypeExpr::Path(path) if path.segments.len() == 1 => {
3238 let name = &path.segments[0].ident.name;
3239 if name.chars().all(|c| c.is_ascii_digit()) {
3240 let first_expr = Expr::Literal(Literal::Int {
3242 value: name.clone(),
3243 base: NumBase::Decimal,
3244 suffix: None,
3245 });
3246 Ok(TypeExpr::ConstExpr(Box::new(Expr::Array(vec![first_expr]))))
3247 } else {
3248 Ok(TypeExpr::Slice(Box::new(first)))
3250 }
3251 }
3252 _ => {
3253 Ok(TypeExpr::Slice(Box::new(first)))
3255 }
3256 }
3257 }
3258 }
3259 Some(Token::LParen) => {
3260 self.advance();
3261 if self.check(&Token::RParen) {
3262 self.advance();
3263 return Ok(TypeExpr::Tuple(vec![]));
3264 }
3265 let types = self.parse_type_list()?;
3266 self.expect(Token::RParen)?;
3267 Ok(TypeExpr::Tuple(types))
3268 }
3269 Some(Token::Fn) => {
3270 self.advance();
3271 self.expect(Token::LParen)?;
3272 let params = self.parse_type_list()?;
3273 self.expect(Token::RParen)?;
3274 let return_type = if self.consume_if(&Token::Arrow) {
3275 Some(Box::new(self.parse_type()?))
3276 } else {
3277 None
3278 };
3279 Ok(TypeExpr::Function {
3280 params,
3281 return_type,
3282 })
3283 }
3284 Some(Token::Impl) => {
3285 self.advance();
3287 let bounds = self.parse_type_bounds()?;
3289 Ok(TypeExpr::ImplTrait(bounds))
3290 }
3291 Some(Token::Bang) => {
3292 self.advance();
3293 Ok(TypeExpr::Never)
3294 }
3295 Some(Token::Underscore) => {
3296 self.advance();
3297 Ok(TypeExpr::Infer)
3298 }
3299 Some(Token::Lt) => {
3300 self.advance(); let base_type = self.parse_type()?;
3304
3305 let trait_path = if self.consume_if(&Token::As) {
3307 Some(self.parse_type_path()?)
3308 } else {
3309 None
3310 };
3311
3312 self.expect_gt()?; if !self.consume_if(&Token::MiddleDot) && !self.consume_if(&Token::MiddleDot) {
3315 match self.current_token().cloned() {
3316 Some(found) => {
3317 return Err(ParseError::UnexpectedToken {
3318 expected: "path separator (`·` or `::`) after `>`".to_string(),
3319 found,
3320 span: self.current_span(),
3321 });
3322 }
3323 None => return Err(ParseError::UnexpectedEof),
3324 }
3325 }
3326
3327 let mut segments = vec![self.parse_path_segment()?];
3329 while self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::MiddleDot) {
3330 segments.push(self.parse_path_segment()?);
3331 }
3332
3333 Ok(TypeExpr::QualifiedPath {
3334 self_type: Box::new(base_type),
3335 trait_path,
3336 item_path: TypePath { segments },
3337 })
3338 }
3339 Some(Token::SelfUpper) => {
3340 let span = self.current_span();
3341 self.advance();
3342 let mut segments = vec![PathSegment {
3343 ident: Ident {
3344 name: "Self".to_string(),
3345 evidentiality: None,
3346 affect: None,
3347 span,
3348 },
3349 generics: None,
3350 }];
3351 while self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::MiddleDot) {
3353 if self.check(&Token::Lt) {
3355 self.advance();
3356 let types = self.parse_type_list()?;
3357 self.expect_gt()?;
3358 if let Some(last) = segments.last_mut() {
3359 last.generics = Some(types);
3360 }
3361 continue;
3362 }
3363 segments.push(self.parse_path_segment()?);
3364 }
3365 Ok(TypeExpr::Path(TypePath { segments }))
3366 }
3367 Some(Token::Simd) => {
3368 self.advance();
3369 self.expect(Token::Lt)?;
3370 let element = self.parse_type()?;
3371 self.expect(Token::Comma)?;
3372 let lanes = match self.current_token() {
3373 Some(Token::IntLit(s)) => {
3374 let n = s
3375 .parse::<u8>()
3376 .map_err(|_| ParseError::Custom("invalid lane count".to_string()))?;
3377 self.advance();
3378 n
3379 }
3380 _ => return Err(ParseError::Custom("expected lane count".to_string())),
3381 };
3382 self.expect_gt()?;
3383 Ok(TypeExpr::Simd {
3384 element: Box::new(element),
3385 lanes,
3386 })
3387 }
3388 Some(Token::Atomic) => {
3389 self.advance();
3390 self.expect(Token::Lt)?;
3391 let inner = self.parse_type()?;
3392 self.expect_gt()?;
3393 Ok(TypeExpr::Atomic(Box::new(inner)))
3394 }
3395 Some(Token::Dyn) => {
3396 self.advance();
3398 let bounds = self.parse_type_bounds()?;
3399 Ok(TypeExpr::TraitObject(bounds))
3400 }
3401 Some(Token::Linear) => {
3402 self.advance();
3404 let inner = self.parse_type()?;
3405 Ok(TypeExpr::Linear(Box::new(inner)))
3406 }
3407 Some(Token::Affine) => {
3408 self.advance();
3410 let inner = self.parse_type()?;
3411 Ok(TypeExpr::Affine(Box::new(inner)))
3412 }
3413 Some(Token::Relevant) => {
3414 self.advance();
3416 let inner = self.parse_type()?;
3417 Ok(TypeExpr::Relevant(Box::new(inner)))
3418 }
3419 Some(Token::Struct) => {
3420 self.advance();
3422 self.expect(Token::LBrace)?;
3423 let mut fields = Vec::new();
3424 while !self.check(&Token::RBrace) && !self.is_eof() {
3425 while matches!(
3427 self.current_token(),
3428 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)) | Some(Token::Hash)
3429 ) {
3430 if self.check(&Token::Hash) {
3431 self.advance();
3433 if self.consume_if(&Token::LBracket) {
3434 let mut depth = 1;
3435 while depth > 0 && !self.is_eof() {
3436 match self.current_token() {
3437 Some(Token::LBracket) => depth += 1,
3438 Some(Token::RBracket) => depth -= 1,
3439 _ => {}
3440 }
3441 self.advance();
3442 }
3443 }
3444 } else {
3445 self.advance();
3446 }
3447 }
3448 if self.check(&Token::RBrace) {
3449 break;
3450 }
3451 let visibility = self.parse_visibility()?;
3453 let name = self.parse_ident()?;
3454 self.expect(Token::Colon)?;
3455 let ty = self.parse_type()?;
3456 fields.push(FieldDef {
3457 visibility,
3458 name,
3459 ty,
3460 default: None,
3461 });
3462 if !self.consume_if(&Token::Comma) {
3463 break;
3464 }
3465 }
3466 self.expect(Token::RBrace)?;
3467 Ok(TypeExpr::InlineStruct { fields })
3468 }
3469 Some(Token::Enum) => {
3470 self.advance();
3472 self.expect(Token::LBrace)?;
3473 let mut variants = Vec::new();
3474 while !self.check(&Token::RBrace) && !self.is_eof() {
3475 while matches!(
3477 self.current_token(),
3478 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
3479 ) {
3480 self.advance();
3481 }
3482 if self.check(&Token::RBrace) {
3483 break;
3484 }
3485 let name = self.parse_ident()?;
3487 let fields = if self.check(&Token::LParen) {
3489 self.advance();
3490 let mut types = Vec::new();
3491 while !self.check(&Token::RParen) && !self.is_eof() {
3492 types.push(self.parse_type()?);
3493 if !self.consume_if(&Token::Comma) {
3494 break;
3495 }
3496 }
3497 self.expect(Token::RParen)?;
3498 StructFields::Tuple(types)
3499 } else if self.check(&Token::LBrace) {
3500 self.advance();
3501 let mut fields = Vec::new();
3502 while !self.check(&Token::RBrace) && !self.is_eof() {
3503 let name = self.parse_ident()?;
3504 self.expect(Token::Colon)?;
3505 let ty = self.parse_type()?;
3506 fields.push(FieldDef {
3507 visibility: Visibility::Private,
3508 name,
3509 ty,
3510 default: None,
3511 });
3512 if !self.consume_if(&Token::Comma) {
3513 break;
3514 }
3515 }
3516 self.expect(Token::RBrace)?;
3517 StructFields::Named(fields)
3518 } else {
3519 StructFields::Unit
3520 };
3521 let discriminant = if self.consume_if(&Token::Eq) {
3523 Some(self.parse_expr()?)
3524 } else {
3525 None
3526 };
3527 variants.push(EnumVariant {
3528 name,
3529 fields,
3530 discriminant,
3531 });
3532 if !self.consume_if(&Token::Comma) {
3533 break;
3534 }
3535 }
3536 self.expect(Token::RBrace)?;
3537 Ok(TypeExpr::InlineEnum { variants })
3538 }
3539 Some(Token::Crate) | Some(Token::SelfLower) | Some(Token::Super) => {
3541 let keyword = self.current_token().cloned();
3542 let span = self.current_span();
3543 self.advance();
3544
3545 let keyword_name = match keyword {
3548 Some(Token::Crate) => "tome",
3549 Some(Token::SelfLower) => "self",
3550 Some(Token::Super) => "super",
3551 _ => unreachable!(),
3552 };
3553 let first_segment = PathSegment {
3554 ident: Ident {
3555 name: keyword_name.to_string(),
3556 evidentiality: None,
3557 affect: None,
3558 span,
3559 },
3560 generics: None,
3561 };
3562
3563 let mut segments = vec![first_segment];
3564
3565 while self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::MiddleDot) {
3567 if self.check(&Token::Lt) {
3569 self.advance();
3570 let types = self.parse_type_list()?;
3571 self.expect_gt()?;
3572 if let Some(last) = segments.last_mut() {
3573 last.generics = Some(types);
3574 }
3575 continue;
3576 }
3577 segments.push(self.parse_path_segment()?);
3578 }
3579 Ok(TypeExpr::Path(TypePath { segments }))
3580 }
3581 _ => {
3582 let path = self.parse_type_path()?;
3583 Ok(TypeExpr::Path(path))
3584 }
3585 }
3586 }
3587
3588 fn parse_type_path(&mut self) -> ParseResult<TypePath> {
3589 let mut segments = Vec::new();
3590 segments.push(self.parse_path_segment()?);
3591
3592 let first_segment_is_type = segments
3601 .first()
3602 .map(|s| s.ident.name.chars().next().map_or(false, |c| c.is_uppercase()))
3603 .unwrap_or(false);
3604
3605 while !self.pending_gt.is_some() {
3606 let is_path_sep = self.consume_if(&Token::MiddleDot)
3609 || (first_segment_is_type && self.consume_if(&Token::MiddleDot));
3610 if !is_path_sep {
3611 break;
3612 }
3613 if self.check(&Token::Lt) {
3615 let was_in_condition = self.in_condition;
3618 self.in_condition = false;
3619 self.advance(); let types = self.parse_type_list()?;
3621 self.expect_gt()?;
3622 self.in_condition = was_in_condition;
3623 if let Some(last) = segments.last_mut() {
3625 last.generics = Some(types);
3626 }
3627 continue;
3630 }
3631 segments.push(self.parse_path_segment()?);
3632 }
3633
3634 Ok(TypePath { segments })
3635 }
3636
3637 fn parse_path_segment(&mut self) -> ParseResult<PathSegment> {
3638 let ident = if let Some(Token::IntLit(idx)) = self.current_token().cloned() {
3640 let span = self.current_span();
3641 self.advance();
3642 Ident {
3643 name: idx,
3644 evidentiality: None,
3645 affect: None,
3646 span,
3647 }
3648 } else {
3649 self.parse_ident()?
3650 };
3651
3652 let is_fn_trait = matches!(ident.name.as_str(), "Fn" | "FnMut" | "FnOnce");
3655 if is_fn_trait && self.check(&Token::LParen) {
3656 self.advance(); let param_types = self.parse_type_list()?;
3658 self.expect(Token::RParen)?;
3659 let return_type = if self.consume_if(&Token::Arrow) {
3661 Some(self.parse_type()?)
3662 } else {
3663 None
3664 };
3665 let mut generics = vec![TypeExpr::Tuple(param_types)];
3668 if let Some(ret) = return_type {
3669 generics.push(ret);
3670 }
3671 return Ok(PathSegment {
3672 ident,
3673 generics: Some(generics),
3674 });
3675 }
3676
3677 let generics = if !self.is_in_condition()
3681 && self.check(&Token::Lt)
3682 && self.peek_looks_like_generic_arg()
3683 {
3684 self.advance(); let types = self.parse_type_list()?;
3686 self.expect_gt()?;
3688 Some(types)
3689 } else if self.check(&Token::LBracket) && self.peek_looks_like_bracket_generic() {
3690 self.advance(); let types = self.parse_type_list()?;
3693 self.expect(Token::RBracket)?;
3694 Some(types)
3695 } else {
3696 None
3697 };
3698
3699 Ok(PathSegment { ident, generics })
3700 }
3701
3702 fn peek_looks_like_bracket_generic(&mut self) -> bool {
3704 match self.peek_next().cloned() {
3707 Some(Token::Ident(name)) => {
3709 let is_type_name = name.chars().next().map_or(false, |c| c.is_uppercase())
3713 || Self::is_primitive_type(&name);
3714 match self.peek_n(1) {
3715 Some(Token::RBracket) => is_type_name,
3718 Some(Token::Comma) => is_type_name, Some(Token::MiddleDot) => true, Some(Token::Lt) => is_type_name, Some(Token::LBracket) => is_type_name, Some(Token::Question) => true,
3724 Some(Token::Bang) => true,
3725 Some(Token::Tilde) => true,
3726 Some(Token::Lozenge) => true,
3727 Some(Token::Interrobang) => true,
3728 Some(Token::Eq) => true,
3730 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, }
3739 }
3740 Some(Token::SelfUpper) => true, Some(Token::Amp) => true, Some(Token::Star) => false,
3744 Some(Token::Fn) => true, Some(Token::LParen) => {
3746 match self.peek_n(1) {
3752 Some(Token::RParen) => true, Some(Token::Ident(name)) => {
3754 if name.chars().next().map_or(false, |c| c.is_uppercase()) {
3757 true } else {
3759 match self.peek_n(2) {
3761 Some(Token::As) => false, Some(Token::Plus) => false, Some(Token::Minus) => false, Some(Token::Star) => false, Some(Token::Slash) => false, Some(Token::Dot) => false, Some(Token::LBracket) => false, Some(Token::LParen) => false, Some(Token::RParen) => false, Some(Token::Comma) => true, _ => false }
3773 }
3774 }
3775 _ => false }
3777 }
3778 Some(Token::Dyn) => true, Some(Token::Impl) => true, Some(Token::Underscore) => true, Some(Token::Crate) => true, Some(Token::Super) => true, Some(Token::IntLit(_)) => false,
3786 Some(Token::FloatLit(_)) => false,
3787 Some(Token::SelfLower) => false, _ => false,
3791 }
3792 }
3793
3794 fn is_primitive_type(name: &str) -> bool {
3796 matches!(
3797 name,
3798 "bool" | "char" | "str"
3799 | "i8" | "i16" | "i32" | "i64" | "i128" | "isize"
3800 | "u8" | "u16" | "u32" | "u64" | "u128" | "usize"
3801 | "f32" | "f64"
3802 )
3803 }
3804
3805 fn peek_looks_like_generic_arg(&mut self) -> bool {
3810 match self.peek_next().cloned() {
3812 Some(Token::Amp) => true, Some(Token::Star) => {
3815 match self.peek_n(1) {
3819 Some(Token::Const) => true, Some(Token::Mut) => true, _ => false, }
3823 }
3824 Some(Token::LBracket) => true, Some(Token::LParen) => true, Some(Token::Fn) => true, Some(Token::Simd) => true, Some(Token::Atomic) => true, Some(Token::Dyn) => true, Some(Token::Impl) => true, Some(Token::SelfUpper) => true, Some(Token::Crate) => true, Some(Token::Super) => true, Some(Token::Lifetime(_)) => true, Some(Token::Underscore) => true, Some(Token::Bang) => true,
3838 Some(Token::Question) => true,
3839 Some(Token::Tilde) => true,
3840 Some(Token::Interrobang) => true,
3841 Some(Token::Crate) => true,
3843 Some(Token::Super) => true,
3844 Some(Token::Ident(name)) => {
3846 let is_type_like = name.chars().next().map_or(false, |c| c.is_uppercase())
3849 || matches!(name.as_str(),
3850 "u8" | "u16" | "u32" | "u64" | "u128" | "usize"
3852 | "i8" | "i16" | "i32" | "i64" | "i128" | "isize"
3853 | "f32" | "f64" | "bool" | "char" | "str"
3854 );
3855 match self.peek_n(1) {
3856 Some(Token::Gt) => true,
3858 Some(Token::Shr) => true, Some(Token::Comma) => is_type_like,
3862 Some(Token::MiddleDot) => true, Some(Token::Lt) => true, Some(Token::LBracket) => true, Some(Token::Question) => true,
3867 Some(Token::Bang) => true,
3868 Some(Token::Tilde) => true,
3869 Some(Token::Lozenge) => true,
3870 Some(Token::Interrobang) => true,
3871 Some(Token::Eq) => true,
3873 Some(Token::Colon) => true,
3875 _ => false,
3876 }
3877 }
3878 Some(Token::SelfLower) => false, Some(Token::IntLit(_)) => {
3883 match self.peek_n(1) {
3884 Some(Token::Comma) => true, Some(Token::Gt) => true, Some(Token::Shr) => true, _ => false, }
3889 }
3890 Some(Token::FloatLit(_)) => false,
3891 Some(Token::StringLit(_)) => false,
3892 Some(Token::True) | Some(Token::False) => false,
3893 Some(Token::Null) => false,
3894 _ => false, }
3896 }
3897
3898 fn peek_looks_like_pipe_op(&mut self) -> bool {
3901 match self.peek_next() {
3902 Some(Token::Tau) => true, Some(Token::Phi) => true, Some(Token::Sigma) => true, Some(Token::Struct) => 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::Lozenge) => true, Some(Token::BoxSquare) => 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::Connect) => true, Some(Token::ProtoConnect) => true, Some(Token::Close) => true, Some(Token::Timeout) => true, Some(Token::ProtoTimeout) => true, Some(Token::Retry) => true, Some(Token::Header) => true, Some(Token::Body) => true, Some(Token::Interrobang) => true, Some(Token::Ident(name)) => {
3957 let collection_pipe_methods = ["observe", "collect", "sum", "product", "len",
3960 "min", "max", "first", "last", "head", "tail",
3961 "reverse", "flatten", "enumerate", "encode",
3962 "error_correct", "quantum_reconstruct", "interfere",
3964 "partial_trace", "qh_compress", "is_pure",
3965 "apply_noise", "scatter", "teleport", "size",
3966 "relu", "softmax", "sigmoid", "tanh", "backward", "Σ"];
3968 if collection_pipe_methods.contains(&name.as_str())
3969 || QUANTUM_GATES.contains(&name.as_str())
3970 || QUANTUM_OPS.contains(&name.as_str()) {
3971 return true;
3972 }
3973
3974 let after_ident = self.peek_n(1);
3978 match after_ident {
3979 Some(Token::LParen) | Some(Token::LBrace) => true,
3980 Some(Token::Bang) | Some(Token::Question) | Some(Token::Tilde) | Some(Token::Lozenge) => {
3982 matches!(self.peek_n(2), Some(Token::LParen) | Some(Token::LBrace))
3983 }
3984 _ => false,
3985 }
3986 }
3987 Some(Token::Amp) => true,
3989 Some(Token::LBrace) => true,
3991 Some(Token::Interfere) => true, Some(Token::Await) => true, Some(Token::Async) => true, _ => false,
3998 }
3999 }
4000
4001 fn parse_type_list(&mut self) -> ParseResult<Vec<TypeExpr>> {
4002 let mut types = Vec::new();
4003 if !self.check(&Token::RParen)
4005 && !self.check(&Token::RBracket)
4006 && !self.check(&Token::Gt)
4007 && !self.check(&Token::Shr)
4008 && self.pending_gt.is_none()
4009 {
4010 types.push(self.parse_type_or_lifetime()?);
4012 while !self.pending_gt.is_some()
4015 && !self.check(&Token::Gt)
4016 && !self.check(&Token::Shr)
4017 && self.consume_if(&Token::Comma)
4018 {
4019 if self.check(&Token::RParen)
4021 || self.check(&Token::RBracket)
4022 || self.check(&Token::Gt)
4023 || self.check(&Token::Shr)
4024 {
4025 break;
4026 }
4027 types.push(self.parse_type_or_lifetime()?);
4028 }
4029 }
4030 Ok(types)
4031 }
4032
4033 fn parse_attributed_type_list(&mut self) -> ParseResult<Vec<TypeExpr>> {
4036 let mut types = Vec::new();
4037 if !self.check(&Token::RParen) {
4038 loop {
4039 while self.check(&Token::Hash) {
4041 self.advance();
4042 self.consume_if(&Token::Bang); if self.consume_if(&Token::LBracket) {
4044 let mut depth = 1;
4045 while depth > 0 && !self.is_eof() {
4046 match self.current_token() {
4047 Some(Token::LBracket) => depth += 1,
4048 Some(Token::RBracket) => depth -= 1,
4049 _ => {}
4050 }
4051 self.advance();
4052 }
4053 }
4054 }
4055 types.push(self.parse_type()?);
4057 if !self.consume_if(&Token::Comma) {
4058 break;
4059 }
4060 }
4061 }
4062 Ok(types)
4063 }
4064
4065 fn parse_tuple_struct_fields(&mut self) -> ParseResult<Vec<TypeExpr>> {
4068 let mut types = Vec::new();
4069 if !self.check(&Token::RParen) {
4070 loop {
4071 if self.check(&Token::Pub) {
4073 self.advance();
4074 if self.check(&Token::LParen) {
4076 self.advance();
4077 let mut depth = 1;
4079 while depth > 0 {
4080 match self.current_token() {
4081 Some(Token::LParen) => depth += 1,
4082 Some(Token::RParen) => depth -= 1,
4083 None => break,
4084 _ => {}
4085 }
4086 self.advance();
4087 }
4088 }
4089 }
4090 types.push(self.parse_type()?);
4092 if !self.consume_if(&Token::Comma) {
4093 break;
4094 }
4095 if self.check(&Token::RParen) {
4097 break;
4098 }
4099 }
4100 }
4101 Ok(types)
4102 }
4103
4104 fn parse_type_bounds(&mut self) -> ParseResult<Vec<TypeExpr>> {
4105 let mut bounds = Vec::new();
4106
4107 if self.check(&Token::Comma) || self.check(&Token::LBrace) || self.check(&Token::Semi) {
4109 return Ok(bounds);
4110 }
4111
4112 bounds.push(self.parse_type_or_lifetime()?);
4113 while self.consume_if(&Token::Plus) {
4114 bounds.push(self.parse_type_or_lifetime()?);
4115 }
4116 Ok(bounds)
4117 }
4118
4119 fn parse_type_or_lifetime(&mut self) -> ParseResult<TypeExpr> {
4123 if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
4124 self.advance();
4125 Ok(TypeExpr::Lifetime(name))
4126 } else if self.check(&Token::ForAll) {
4127 self.advance(); self.expect(Token::Lt)?; let mut lifetimes = Vec::new();
4131 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
4132 lifetimes.push(lt);
4133 self.advance();
4134 while self.consume_if(&Token::Comma) {
4135 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
4136 lifetimes.push(lt);
4137 self.advance();
4138 } else {
4139 break;
4140 }
4141 }
4142 }
4143 self.expect_gt()?; let bound = self.parse_type()?;
4145 Ok(TypeExpr::Hrtb {
4146 lifetimes,
4147 bound: Box::new(bound),
4148 })
4149 } else if matches!(self.current_token(), Some(Token::Ident(_)))
4150 && self.peek_next() == Some(&Token::Eq)
4151 {
4152 let name = self.parse_ident()?;
4154 self.expect(Token::Eq)?;
4155 let ty = self.parse_type()?;
4156 Ok(TypeExpr::AssocTypeBinding {
4157 name,
4158 ty: Box::new(ty),
4159 })
4160 } else if matches!(
4161 self.current_token(),
4162 Some(Token::IntLit(_))
4163 | Some(Token::HexLit(_))
4164 | Some(Token::BinaryLit(_))
4165 | Some(Token::OctalLit(_))
4166 ) {
4167 let expr = self.parse_const_expr_simple()?;
4170 Ok(TypeExpr::ConstExpr(Box::new(expr)))
4171 } else if self.check(&Token::LBrace) {
4172 self.advance();
4174 let expr = self.parse_expr()?;
4175 self.expect(Token::RBrace)?;
4176 Ok(TypeExpr::ConstExpr(Box::new(expr)))
4177 } else {
4178 self.parse_type()
4179 }
4180 }
4181
4182 fn parse_array_dim_expr(&mut self) -> ParseResult<Expr> {
4185 if self.check(&Token::LBrace) {
4187 self.advance();
4188 let expr = self.parse_expr()?;
4189 self.expect(Token::RBrace)?;
4190 return Ok(expr);
4191 }
4192 self.parse_const_expr_simple()
4194 }
4195
4196 fn parse_const_expr_simple(&mut self) -> ParseResult<Expr> {
4200 let mut lhs = self.parse_const_expr_primary()?;
4201
4202 loop {
4203 match self.current_token() {
4204 Some(Token::Star) => {
4205 self.advance();
4206 let rhs = self.parse_const_expr_primary()?;
4207 lhs = Expr::Binary {
4208 op: BinOp::Mul,
4209 left: Box::new(lhs),
4210 right: Box::new(rhs),
4211 };
4212 }
4213 Some(Token::Plus) => {
4214 self.advance();
4215 let rhs = self.parse_const_expr_primary()?;
4216 lhs = Expr::Binary {
4217 op: BinOp::Add,
4218 left: Box::new(lhs),
4219 right: Box::new(rhs),
4220 };
4221 }
4222 Some(Token::Minus) => {
4223 self.advance();
4224 let rhs = self.parse_const_expr_primary()?;
4225 lhs = Expr::Binary {
4226 op: BinOp::Sub,
4227 left: Box::new(lhs),
4228 right: Box::new(rhs),
4229 };
4230 }
4231 Some(Token::Slash) => {
4232 self.advance();
4233 let rhs = self.parse_const_expr_primary()?;
4234 lhs = Expr::Binary {
4235 op: BinOp::Div,
4236 left: Box::new(lhs),
4237 right: Box::new(rhs),
4238 };
4239 }
4240 _ => break,
4241 }
4242 }
4243 Ok(lhs)
4244 }
4245
4246 fn parse_const_expr_primary(&mut self) -> ParseResult<Expr> {
4248 match self.current_token().cloned() {
4249 Some(Token::IntLit(_)) | Some(Token::HexLit(_))
4250 | Some(Token::BinaryLit(_)) | Some(Token::OctalLit(_)) => {
4251 let lit = self.parse_literal()?;
4252 Ok(Expr::Literal(lit))
4253 }
4254 Some(Token::Ident(_)) => {
4255 let path = self.parse_type_path()?;
4256 Ok(Expr::Path(path))
4257 }
4258 Some(Token::Underscore) => {
4259 let span = self.current_span();
4261 self.advance();
4262 Ok(Expr::Path(TypePath {
4263 segments: vec![PathSegment {
4264 ident: Ident {
4265 name: "_".to_string(),
4266 evidentiality: None,
4267 affect: None,
4268 span,
4269 },
4270 generics: None,
4271 }],
4272 }))
4273 }
4274 Some(Token::LParen) => {
4275 self.advance();
4276 let expr = self.parse_const_expr_simple()?;
4277 self.expect(Token::RParen)?;
4278 Ok(expr)
4279 }
4280 _ => Err(ParseError::Custom("expected const expression".to_string())),
4281 }
4282 }
4283
4284 pub fn parse_expr(&mut self) -> ParseResult<Expr> {
4287 self.skip_comments();
4289 let lhs = self.parse_expr_bp(0)?;
4290
4291 if self.consume_if(&Token::Eq) {
4293 let value = self.parse_expr()?;
4294 return Ok(Expr::Assign {
4295 target: Box::new(lhs),
4296 value: Box::new(value),
4297 });
4298 }
4299
4300 let compound_op = match self.current_token() {
4303 Some(Token::PlusEq) => Some(BinOp::Add),
4304 Some(Token::MinusEq) => Some(BinOp::Sub),
4305 Some(Token::StarEq) => Some(BinOp::Mul),
4306 Some(Token::SlashEq) => Some(BinOp::Div),
4307 Some(Token::PercentEq) => Some(BinOp::Rem),
4308 Some(Token::ShlEq) => Some(BinOp::Shl),
4309 Some(Token::ShrEq) => Some(BinOp::Shr),
4310 Some(Token::PipeEq) => Some(BinOp::BitOr),
4311 Some(Token::AmpEq) => Some(BinOp::BitAnd),
4312 Some(Token::CaretEq) => Some(BinOp::BitXor),
4313 _ => None,
4314 };
4315
4316 if let Some(op) = compound_op {
4317 self.advance();
4318 let rhs = self.parse_expr()?;
4319 let binary = Expr::Binary {
4321 left: Box::new(lhs.clone()),
4322 op,
4323 right: Box::new(rhs),
4324 };
4325 return Ok(Expr::Assign {
4326 target: Box::new(lhs),
4327 value: Box::new(binary),
4328 });
4329 }
4330
4331 match self.current_token() {
4333 Some(Token::DirectSumEq) => {
4334 self.advance();
4336 let pattern = self.parse_expr()?;
4337 return Ok(Expr::LegionSuperposition {
4338 field: Box::new(lhs),
4339 pattern: Box::new(pattern),
4340 });
4341 }
4342 Some(Token::PartialEq_) => {
4343 self.advance();
4345 let rate = self.parse_expr()?;
4346 return Ok(Expr::LegionDecay {
4347 field: Box::new(lhs),
4348 rate: Box::new(rate),
4349 });
4350 }
4351 Some(Token::InterfereEq) => {
4352 self.advance();
4354 let query = self.parse_expr()?;
4355 return Ok(Expr::LegionInterference {
4356 query: Box::new(query),
4357 field: Box::new(lhs),
4358 });
4359 }
4360 _ => {}
4361 }
4362
4363 Ok(lhs)
4364 }
4365
4366 fn parse_expr_bp(&mut self, min_bp: u8) -> ParseResult<Expr> {
4367 let mut lhs = self.parse_prefix_expr()?;
4368
4369 loop {
4370 self.skip_comments();
4375
4376 if self.check(&Token::Pipe) && self.peek_looks_like_pipe_op() {
4379 lhs = self.parse_pipe_chain(lhs)?;
4380 lhs = self.parse_postfix_after_pipe(lhs)?;
4382 continue;
4383 }
4384
4385 let op = match self.current_token() {
4387 Some(Token::Pipe) => BinOp::BitOr,
4389 Some(Token::OrOr) => BinOp::Or,
4390 Some(Token::AndAnd) => BinOp::And,
4391 Some(Token::EqEq) => BinOp::Eq,
4392 Some(Token::NotEq) => BinOp::Ne,
4393 Some(Token::Lt) => BinOp::Lt,
4394 Some(Token::LtEq) => BinOp::Le,
4395 Some(Token::Gt) => BinOp::Gt,
4396 Some(Token::GtEq) => BinOp::Ge,
4397 Some(Token::Plus) => BinOp::Add,
4398 Some(Token::Minus) => BinOp::Sub,
4399 Some(Token::Star) => BinOp::Mul,
4400 Some(Token::Slash) => BinOp::Div,
4401 Some(Token::Percent) => BinOp::Rem,
4402 Some(Token::StarStar) => BinOp::Pow,
4403 Some(Token::Amp) => BinOp::BitAnd,
4404 Some(Token::Caret) => BinOp::BitXor,
4405 Some(Token::Shl) => BinOp::Shl,
4406 Some(Token::Shr) => BinOp::Shr,
4407 Some(Token::PlusPlus) => BinOp::Concat,
4408 Some(Token::At) => BinOp::MatMul,
4410 Some(Token::BitwiseAndSymbol) => BinOp::BitAnd, Some(Token::BitwiseOrSymbol) => BinOp::BitOr, Some(Token::LogicAnd) => BinOp::And, Some(Token::LogicOr) => BinOp::Or, Some(Token::CircledDot) => BinOp::Hadamard, Some(Token::Tensor) => BinOp::TensorProd, Some(Token::Convolve) => BinOp::Convolve, Some(Token::Interfere) | Some(Token::Distribute) | Some(Token::Broadcast)
4422 | Some(Token::Gather) | Some(Token::Consensus) | Some(Token::ConfidenceHigh) => {
4423 lhs = self.parse_legion_operator(lhs)?;
4425 continue;
4426 }
4427 _ => {
4428 if min_bp == 0 && (self.check(&Token::DotDot) || self.check(&Token::DotDotEq)) {
4434 let inclusive = self.consume_if(&Token::DotDotEq);
4435 if !inclusive {
4436 self.advance(); }
4438 let end = if self.check(&Token::Semi)
4440 || self.check(&Token::RBrace)
4441 || self.check(&Token::Comma)
4442 || self.check(&Token::RParen)
4443 || self.check(&Token::RBracket)
4444 || self.check(&Token::LBrace)
4445 {
4446 None
4447 } else {
4448 Some(Box::new(self.parse_expr_bp(0)?))
4449 };
4450 lhs = Expr::Range {
4451 start: Some(Box::new(lhs)),
4452 end,
4453 inclusive,
4454 };
4455 continue;
4456 }
4457 break;
4458 }
4459 };
4460
4461 let (l_bp, r_bp) = infix_binding_power(op);
4462 if l_bp < min_bp {
4463 break;
4464 }
4465
4466 self.advance();
4467 self.skip_comments();
4471 let rhs = self.parse_expr_bp(r_bp)?;
4472
4473 lhs = Expr::Binary {
4474 left: Box::new(lhs),
4475 op,
4476 right: Box::new(rhs),
4477 };
4478 }
4479
4480 Ok(lhs)
4481 }
4482
4483 fn parse_prefix_expr(&mut self) -> ParseResult<Expr> {
4484 match self.current_token() {
4485 Some(Token::Minus) => {
4486 self.advance();
4487 let expr = self.parse_prefix_expr()?;
4488 Ok(Expr::Unary {
4489 op: UnaryOp::Neg,
4490 expr: Box::new(expr),
4491 })
4492 }
4493 Some(Token::Bang) | Some(Token::LogicNot) => {
4494 self.advance();
4495 let expr = self.parse_prefix_expr()?;
4496 Ok(Expr::Unary {
4497 op: UnaryOp::Not,
4498 expr: Box::new(expr),
4499 })
4500 }
4501 Some(Token::Star) => {
4502 self.advance();
4503 let expr = self.parse_prefix_expr()?;
4504 Ok(Expr::Unary {
4505 op: UnaryOp::Deref,
4506 expr: Box::new(expr),
4507 })
4508 }
4509 Some(Token::StarStar) => {
4511 self.advance();
4512 let inner = self.parse_prefix_expr()?;
4513 let first_deref = Expr::Unary {
4515 op: UnaryOp::Deref,
4516 expr: Box::new(inner),
4517 };
4518 Ok(Expr::Unary {
4519 op: UnaryOp::Deref,
4520 expr: Box::new(first_deref),
4521 })
4522 }
4523 Some(Token::Amp) => {
4524 self.advance();
4525 let op = if self.consume_if(&Token::Mut) {
4526 UnaryOp::RefMut
4527 } else {
4528 UnaryOp::Ref
4529 };
4530 let expr = self.parse_prefix_expr()?;
4531 Ok(Expr::Unary {
4532 op,
4533 expr: Box::new(expr),
4534 })
4535 }
4536 Some(Token::Question) => {
4538 self.advance();
4539 let expr = self.parse_prefix_expr()?;
4540 Ok(Expr::Evidential {
4541 expr: Box::new(expr),
4542 evidentiality: Evidentiality::Uncertain,
4543 })
4544 }
4545 Some(Token::Tilde) => {
4546 self.advance();
4547 let expr = self.parse_prefix_expr()?;
4548 Ok(Expr::Evidential {
4549 expr: Box::new(expr),
4550 evidentiality: Evidentiality::Reported,
4551 })
4552 }
4553 Some(Token::Interrobang) => {
4554 self.advance();
4555 let expr = self.parse_prefix_expr()?;
4556 Ok(Expr::Evidential {
4557 expr: Box::new(expr),
4558 evidentiality: Evidentiality::Paradox,
4559 })
4560 }
4561 Some(Token::Move) => {
4563 self.advance();
4564 if self.check(&Token::LambdaExpr) {
4565 self.parse_lambda_closure(true)
4566 } else {
4567 self.parse_pipe_closure_with_move(true)
4568 }
4569 }
4570 Some(Token::LambdaExpr) => self.parse_lambda_closure(false),
4572 Some(Token::Pipe) | Some(Token::OrOr) => self.parse_pipe_closure_with_move(false),
4574 _ => self.parse_postfix_expr(),
4575 }
4576 }
4577
4578 fn parse_pipe_closure_with_move(&mut self, is_move: bool) -> ParseResult<Expr> {
4580 let params = if self.consume_if(&Token::OrOr) {
4581 Vec::new()
4583 } else {
4584 self.expect(Token::Pipe)?;
4586 let mut params = Vec::new();
4587 if !self.check(&Token::Pipe) {
4588 loop {
4589 let pattern = self.parse_pattern()?;
4591 let ty = if self.consume_if(&Token::Colon) {
4592 Some(self.parse_type()?)
4593 } else {
4594 None
4595 };
4596 params.push(ClosureParam { pattern, ty });
4597 if !self.consume_if(&Token::Comma) {
4598 break;
4599 }
4600 if self.check(&Token::Pipe) {
4601 break;
4602 }
4603 }
4604 }
4605 self.expect(Token::Pipe)?;
4606 params
4607 };
4608
4609 let return_type = if self.consume_if(&Token::Arrow) {
4611 Some(self.parse_type()?)
4612 } else {
4613 None
4614 };
4615
4616 let body = self.parse_expr()?;
4617 Ok(Expr::Closure {
4618 params,
4619 return_type,
4620 body: Box::new(body),
4621 is_move,
4622 })
4623 }
4624
4625 fn parse_lambda_closure(&mut self, is_move: bool) -> ParseResult<Expr> {
4628 self.expect(Token::LambdaExpr)?; self.expect(Token::LParen)?;
4632 let mut params = Vec::new();
4633 if !self.check(&Token::RParen) {
4634 loop {
4635 let pattern = self.parse_pattern()?;
4636 let ty = if self.consume_if(&Token::Colon) {
4637 Some(self.parse_type()?)
4638 } else {
4639 None
4640 };
4641 params.push(ClosureParam { pattern, ty });
4642 if !self.consume_if(&Token::Comma) {
4643 break;
4644 }
4645 if self.check(&Token::RParen) {
4646 break;
4647 }
4648 }
4649 }
4650 self.expect(Token::RParen)?;
4651
4652 let return_type = if self.consume_if(&Token::Arrow) {
4654 Some(self.parse_type()?)
4655 } else {
4656 None
4657 };
4658
4659 let body = self.parse_block_or_closure()?;
4661
4662 Ok(Expr::Closure {
4663 params,
4664 return_type,
4665 body: Box::new(body),
4666 is_move,
4667 })
4668 }
4669
4670 fn parse_macro_tokens(&mut self) -> ParseResult<String> {
4672 let (open, close) = match self.current_token() {
4674 Some(Token::LParen) => (Token::LParen, Token::RParen),
4675 Some(Token::LBracket) => (Token::LBracket, Token::RBracket),
4676 Some(Token::LBrace) => (Token::LBrace, Token::RBrace),
4677 _ => {
4678 return Err(ParseError::Custom(
4679 "expected '(', '[', or '{' for macro invocation".to_string(),
4680 ))
4681 }
4682 };
4683
4684 self.advance(); let mut tokens = String::new();
4686 let mut depth = 1;
4687
4688 while depth > 0 && !self.is_eof() {
4689 if self.check(&open) {
4690 depth += 1;
4691 } else if self.check(&close) {
4692 depth -= 1;
4693 if depth == 0 {
4694 break;
4695 }
4696 }
4697
4698 if let Some((token, span)) = &self.current {
4700 if matches!(token, Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)) {
4702 self.advance();
4703 continue;
4704 }
4705 if token.is_doc_comment() {
4707 self.advance();
4708 continue;
4709 }
4710 let token_str = match token {
4712 Token::Ident(s) => s.clone(),
4713 Token::IntLit(s) => s.clone(),
4714 Token::FloatLit(s) => s.clone(),
4715 Token::StringLit(s) => format!("\"{}\"", s.replace('\\', "\\\\").replace('"', "\\\"")),
4716 Token::CharLit(c) => format!("'{}'", c),
4717 Token::Comma => ",".to_string(),
4718 Token::Colon => ":".to_string(),
4719 Token::MiddleDot => "·".to_string(),
4720 Token::Dot => ".".to_string(),
4721 Token::DotDot => "..".to_string(),
4722 Token::Semi => ";".to_string(),
4723 Token::LParen => "(".to_string(),
4724 Token::RParen => ")".to_string(),
4725 Token::LBrace => "{".to_string(),
4726 Token::RBrace => "}".to_string(),
4727 Token::LBracket => "[".to_string(),
4728 Token::RBracket => "]".to_string(),
4729 Token::Lt => "<".to_string(),
4730 Token::Gt => ">".to_string(),
4731 Token::Eq => "=".to_string(),
4732 Token::FatArrow => "=>".to_string(),
4733 Token::Bang => "!".to_string(),
4734 Token::Question => "?".to_string(),
4735 Token::Amp => "&".to_string(),
4736 Token::Pipe => "|".to_string(),
4737 Token::Underscore => "_".to_string(),
4738 Token::Plus => "+".to_string(),
4739 Token::Minus => "-".to_string(),
4740 Token::Star => "*".to_string(),
4741 Token::Slash => "/".to_string(),
4742 Token::Percent => "%".to_string(),
4743 Token::EqEq => "==".to_string(),
4744 Token::NotEq => "!=".to_string(),
4745 Token::LtEq => "<=".to_string(),
4746 Token::GtEq => ">=".to_string(),
4747 Token::AndAnd => "&&".to_string(),
4748 Token::OrOr => "||".to_string(),
4749 Token::Arrow => "->".to_string(),
4750 Token::Hash => "#".to_string(),
4751 Token::At => "@".to_string(),
4752 Token::Tilde => "~".to_string(),
4753 Token::SelfLower => "self".to_string(),
4755 Token::SelfUpper => "Self".to_string(),
4756 Token::Let => "let".to_string(),
4757 Token::Mut => "mut".to_string(),
4758 Token::Fn => "fn".to_string(),
4759 Token::If => "if".to_string(),
4760 Token::Else => "else".to_string(),
4761 Token::Match => "match".to_string(),
4762 Token::ForAll => "for".to_string(),
4763 Token::While => "while".to_string(),
4764 Token::Loop => "loop".to_string(),
4765 Token::Tensor => "break".to_string(),
4766 Token::CycleArrow => "continue".to_string(),
4767 Token::Return => "return".to_string(),
4768 Token::Struct => "struct".to_string(),
4769 Token::Enum => "enum".to_string(),
4770 Token::Impl => "impl".to_string(),
4771 Token::Trait => "trait".to_string(),
4772 Token::Type => "type".to_string(),
4773 Token::Pub => "pub".to_string(),
4774 Token::Mod => "mod".to_string(),
4775 Token::Use => "use".to_string(),
4776 Token::As => "as".to_string(),
4777 Token::ElementOf => "in".to_string(),
4778 Token::True => "true".to_string(),
4779 Token::False => "false".to_string(),
4780 Token::Null => "null".to_string(),
4781 Token::Const => "const".to_string(),
4782 Token::Static => "static".to_string(),
4783 Token::Async => "async".to_string(),
4784 Token::Await => "await".to_string(),
4785 Token::Move => "move".to_string(),
4786 Token::Ref => "ref".to_string(),
4787 Token::Where => "where".to_string(),
4788 Token::Dyn => "dyn".to_string(),
4789 Token::Super => "super".to_string(),
4790 Token::Crate => "tome".to_string(),
4791 Token::MiddleDot => "·".to_string(), Token::Nabla => "∇".to_string(), Token::Tau => "τ".to_string(), Token::Rho => "ρ".to_string(), Token::Sigma => "σ".to_string(), Token::Delta => "δ".to_string(), Token::Lambda => "Λ".to_string(), Token::LambdaExpr => "λ".to_string(), Token::Pi => "π".to_string(), Token::Phi => "φ".to_string(), Token::Zeta => "ζ".to_string(), Token::Mu => "μ".to_string(), Token::Theta => "θ".to_string(), Token::Alpha => "α".to_string(), Token::Omega => "ω".to_string(), Token::Epsilon => "ε".to_string(), Token::Chi => "χ".to_string(), Token::Nu => "ν".to_string(), Token::Xi => "ξ".to_string(), Token::Psi => "ψ".to_string(), Token::Kappa => "κ".to_string(), Token::Iota => "ι".to_string(), Token::PlusPlus => "++".to_string(), Token::PlusEq => "+=".to_string(),
4816 Token::MinusEq => "-=".to_string(),
4817 Token::StarEq => "*=".to_string(),
4818 Token::SlashEq => "/=".to_string(),
4819 Token::AndAnd => "&&".to_string(), Token::OrOr => "||".to_string(), Token::Caret => "^".to_string(), Token::CaretEq => "^=".to_string(),
4823 Token::AmpEq => "&=".to_string(),
4824 Token::PipeEq => "|=".to_string(),
4825 Token::Shl => "<<".to_string(), Token::Shr => ">>".to_string(), Token::ShlEq => "<<=".to_string(),
4828 Token::ShrEq => ">>=".to_string(),
4829 Token::DotDotEq => "..=".to_string(), Token::Async => "⏳".to_string(), Token::Parallel => "‖".to_string(), Token::Compose => "∘".to_string(), Token::ForAll => "∀".to_string(), Token::Exists => "∃".to_string(), Token::ElementOf => "∈".to_string(), Token::Union => "∪".to_string(), Token::Intersection => "∩".to_string(), _ => {
4839 if let Some(ident) = Self::keyword_as_ident(token) {
4841 ident.to_string()
4842 } else {
4843 format!("{:?}", token)
4844 }
4845 }
4846 };
4847 let suppress_space_before = matches!(token,
4849 Token::Dot | Token::MiddleDot | Token::MiddleDot | Token::LParen | Token::LBracket |
4850 Token::LBrace | Token::RParen | Token::RBracket | Token::RBrace |
4851 Token::Comma | Token::Semi | Token::Question);
4852 if !tokens.is_empty() && !suppress_space_before && !tokens.ends_with('.') &&
4853 !tokens.ends_with("::") && !tokens.ends_with('(') && !tokens.ends_with('[') &&
4854 !tokens.ends_with('{') {
4855 tokens.push(' ');
4856 }
4857 tokens.push_str(&token_str);
4858 }
4859 self.advance();
4860 }
4861
4862 self.expect(close)?;
4863 Ok(tokens)
4864 }
4865
4866 fn is_non_callable_expr(expr: &Expr) -> bool {
4870 matches!(
4871 expr,
4872 Expr::If { .. }
4873 | Expr::While { .. }
4874 | Expr::Match { .. }
4875 | Expr::Loop { .. }
4876 | Expr::For { .. }
4877 | Expr::Block(_)
4878 | Expr::Unsafe(_)
4879 )
4880 }
4881
4882 fn parse_postfix_expr(&mut self) -> ParseResult<Expr> {
4883 let mut expr = self.parse_primary_expr()?;
4884
4885 loop {
4886 self.skip_comments();
4891
4892 match self.current_token() {
4893 Some(Token::LParen) => {
4894 if Self::is_non_callable_expr(&expr) {
4897 break;
4898 }
4899 self.advance();
4900 let args = self.parse_expr_list()?;
4901 self.expect(Token::RParen)?;
4902 expr = Expr::Call {
4903 func: Box::new(expr),
4904 args,
4905 };
4906 }
4907 Some(Token::LBracket) => {
4908 self.advance();
4909 let first = self.parse_expr()?;
4911 if self.consume_if(&Token::Comma) {
4912 let mut indices = vec![first];
4914 while !self.check(&Token::RBracket) && !self.is_eof() {
4915 indices.push(self.parse_expr()?);
4916 if !self.consume_if(&Token::Comma) {
4917 break;
4918 }
4919 }
4920 self.expect(Token::RBracket)?;
4921 expr = Expr::Index {
4923 expr: Box::new(expr),
4924 index: Box::new(Expr::Tuple(indices)),
4925 };
4926 } else {
4927 self.expect(Token::RBracket)?;
4928 expr = Expr::Index {
4929 expr: Box::new(expr),
4930 index: Box::new(first),
4931 };
4932 }
4933 }
4934 Some(Token::Dot) => {
4935 self.advance();
4936 if self.check(&Token::Async) {
4938 self.advance();
4939 let evidentiality = self.parse_evidentiality_opt();
4940 expr = Expr::Await {
4941 expr: Box::new(expr),
4942 evidentiality,
4943 };
4944 continue;
4945 }
4946 let field = if let Some(Token::IntLit(idx)) = self.current_token() {
4948 let idx = idx.clone();
4949 let span = self.current_span();
4950 self.advance();
4951 Ident {
4952 name: idx,
4953 evidentiality: None,
4954 affect: None,
4955 span,
4956 }
4957 } else {
4958 self.parse_ident()?
4959 };
4960 if self.check(&Token::MiddleDot) {
4962 self.advance(); self.expect(Token::Lt)?;
4964 let was_in_condition = self.in_condition;
4966 self.in_condition = false;
4967 let type_args = self.parse_type_list()?;
4968 self.expect_gt()?;
4969 self.in_condition = was_in_condition;
4970 self.expect(Token::LParen)?;
4971 let args = self.parse_expr_list()?;
4972 self.expect(Token::RParen)?;
4973 expr = Expr::MethodCall {
4974 receiver: Box::new(expr),
4975 method: field,
4976 type_args: Some(type_args),
4977 args,
4978 };
4979 } else if self.check(&Token::LParen) {
4980 self.advance();
4981 let args = self.parse_expr_list()?;
4982 self.expect(Token::RParen)?;
4983 expr = Expr::MethodCall {
4984 receiver: Box::new(expr),
4985 method: field,
4986 type_args: None,
4987 args,
4988 };
4989 } else {
4990 while self.check(&Token::Tilde) || self.check(&Token::Lozenge) {
4993 self.advance();
4994 }
4995 expr = Expr::Field {
4996 expr: Box::new(expr),
4997 field,
4998 };
4999 }
5000 }
5001 Some(Token::Question) => {
5002 if self.peek_next() == Some(&Token::LBrace) && !self.is_in_condition() {
5004 if let Expr::Path(ref path) = expr {
5005 let path = path.clone();
5006 self.advance(); self.advance(); let (fields, rest) = self.parse_struct_fields()?;
5009 self.expect(Token::RBrace)?;
5010 expr = Expr::Struct { path, fields, rest };
5011 continue;
5012 }
5013 }
5014 if let Some(ev) = self.parse_evidentiality_opt() {
5016 expr = Expr::Evidential {
5017 expr: Box::new(expr),
5018 evidentiality: ev,
5019 };
5020 } else {
5021 break;
5022 }
5023 }
5024 Some(Token::As) | Some(Token::Arrow) => {
5026 self.advance();
5027 let ty = self.parse_type()?;
5028 expr = Expr::Cast {
5029 expr: Box::new(expr),
5030 ty,
5031 };
5032 }
5033 Some(Token::Bang) => {
5034 if let Expr::Path(path) = &expr {
5036 let peeked = self.peek_next();
5037 let is_macro = match peeked {
5040 Some(Token::LParen) | Some(Token::LBracket) => true,
5041 Some(Token::LBrace) => !self.is_in_condition(),
5042 _ => false,
5043 };
5044 if is_macro {
5045 self.advance(); let tokens = self.parse_macro_tokens()?;
5047 expr = Expr::Macro {
5048 path: path.clone(),
5049 tokens,
5050 };
5051 continue;
5052 }
5053 }
5054 if let Some(ev) = self.parse_evidentiality_opt() {
5056 expr = Expr::Evidential {
5057 expr: Box::new(expr),
5058 evidentiality: ev,
5059 };
5060 } else {
5061 break;
5062 }
5063 }
5064 Some(Token::Tilde) | Some(Token::Interrobang) | Some(Token::Lozenge) => {
5065 if let Some(ev) = self.parse_evidentiality_opt() {
5066 if self.check(&Token::LBrace) && !self.is_in_condition() {
5069 if let Expr::Path(ref path) = expr {
5070 let path = path.clone();
5071 self.advance(); let (fields, rest) = self.parse_struct_fields()?;
5073 self.expect(Token::RBrace)?;
5074 expr = Expr::Struct { path, fields, rest };
5075 continue;
5076 }
5077 }
5078 expr = Expr::Evidential {
5080 expr: Box::new(expr),
5081 evidentiality: ev,
5082 };
5083 } else {
5084 break;
5085 }
5086 }
5087 Some(Token::MiddleDot) => {
5088 self.advance(); let method = self.parse_ident()?;
5091 let type_args = if self.check(&Token::MiddleDot) {
5093 self.advance();
5094 self.expect(Token::Lt)?;
5095 let types = self.parse_type_list()?;
5096 self.expect_gt()?;
5097 Some(types)
5098 } else {
5099 None
5100 };
5101 if self.check(&Token::LParen) {
5102 self.advance();
5103 let args = self.parse_expr_list()?;
5104 self.expect(Token::RParen)?;
5105 expr = Expr::MethodCall {
5107 receiver: Box::new(expr),
5108 method,
5109 type_args,
5110 args,
5111 };
5112 } else {
5113 expr = Expr::Field {
5115 expr: Box::new(expr),
5116 field: method,
5117 };
5118 }
5119 }
5120 Some(Token::Async) => {
5121 self.advance();
5122 let evidentiality = match self.current_token() {
5124 Some(Token::Question) => {
5125 self.advance();
5126 Some(Evidentiality::Uncertain)
5127 }
5128 Some(Token::Bang) => {
5129 self.advance();
5130 Some(Evidentiality::Known)
5131 }
5132 Some(Token::Tilde) => {
5133 self.advance();
5134 Some(Evidentiality::Reported)
5135 }
5136 Some(Token::Lozenge) => {
5137 self.advance();
5138 Some(Evidentiality::Predicted)
5139 }
5140 Some(Token::Interrobang) => {
5141 self.advance();
5142 Some(Evidentiality::Paradox)
5143 }
5144 _ => None,
5145 };
5146 expr = Expr::Await {
5147 expr: Box::new(expr),
5148 evidentiality,
5149 };
5150 }
5151 Some(Token::MiddleDot) => {
5154 let first_segment = self.expr_to_incorporation_segment(expr.clone())?;
5156 let mut segments = vec![first_segment];
5157
5158 while self.consume_if(&Token::MiddleDot) {
5159 if self.check(&Token::Async) {
5161 self.advance();
5162 let evidentiality = self.parse_evidentiality_opt();
5163 expr = if segments.len() == 1 && segments[0].args.is_none() {
5165 expr.clone()
5167 } else {
5168 Expr::Incorporation { segments: segments.clone() }
5169 };
5170 expr = Expr::Await {
5171 expr: Box::new(expr),
5172 evidentiality,
5173 };
5174 let first_segment = self.expr_to_incorporation_segment(expr.clone())?;
5176 segments = vec![first_segment];
5177 continue;
5178 }
5179 let name = if let Some(Token::IntLit(idx)) = self.current_token().cloned() {
5181 let span = self.current_span();
5182 self.advance();
5183 Ident {
5184 name: idx,
5185 evidentiality: None,
5186 affect: None,
5187 span,
5188 }
5189 } else {
5190 self.parse_ident()?
5191 };
5192 if self.check(&Token::LBracket) && self.peek_looks_like_bracket_generic() {
5194 self.advance(); let _generics = self.parse_type_list()?;
5196 self.expect(Token::RBracket)?;
5197 }
5199 if self.check(&Token::Lt) && self.peek_looks_like_generic_arg() {
5201 self.advance(); let _generics = self.parse_type_list()?;
5203 self.expect_gt()?;
5204 }
5205 let args = if self.check(&Token::LParen) {
5206 self.advance();
5207 let args = self.parse_expr_list()?;
5208 self.expect(Token::RParen)?;
5209 Some(args)
5210 } else {
5211 None
5212 };
5213 segments.push(IncorporationSegment { name, args });
5214 }
5215
5216 expr = Expr::Incorporation { segments };
5217 }
5218 _ => break,
5219 }
5220 }
5221
5222 Ok(expr)
5223 }
5224
5225 fn parse_primary_expr(&mut self) -> ParseResult<Expr> {
5226 match self.current_token().cloned() {
5227 Some(Token::IntLit(s)) => {
5228 self.advance();
5229 Ok(Expr::Literal(Literal::Int {
5230 value: s,
5231 base: NumBase::Decimal,
5232 suffix: None,
5233 }))
5234 }
5235 Some(Token::BinaryLit(s)) => {
5236 self.advance();
5237 Ok(Expr::Literal(Literal::Int {
5238 value: s,
5239 base: NumBase::Binary,
5240 suffix: None,
5241 }))
5242 }
5243 Some(Token::OctalLit(s)) => {
5244 self.advance();
5245 Ok(Expr::Literal(Literal::Int {
5246 value: s,
5247 base: NumBase::Octal,
5248 suffix: None,
5249 }))
5250 }
5251 Some(Token::HexLit(s)) => {
5252 self.advance();
5253 Ok(Expr::Literal(Literal::Int {
5254 value: s,
5255 base: NumBase::Hex,
5256 suffix: None,
5257 }))
5258 }
5259 Some(Token::VigesimalLit(s)) => {
5260 self.advance();
5261 Ok(Expr::Literal(Literal::Int {
5262 value: s,
5263 base: NumBase::Vigesimal,
5264 suffix: None,
5265 }))
5266 }
5267 Some(Token::SexagesimalLit(s)) => {
5268 self.advance();
5269 Ok(Expr::Literal(Literal::Int {
5270 value: s,
5271 base: NumBase::Sexagesimal,
5272 suffix: None,
5273 }))
5274 }
5275 Some(Token::DuodecimalLit(s)) => {
5276 self.advance();
5277 Ok(Expr::Literal(Literal::Int {
5278 value: s,
5279 base: NumBase::Duodecimal,
5280 suffix: None,
5281 }))
5282 }
5283 Some(Token::FloatLit(s)) => {
5284 self.advance();
5285 let (value, suffix) = Self::strip_float_suffix(&s);
5286 Ok(Expr::Literal(Literal::Float { value, suffix }))
5287 }
5288 Some(Token::StringLit(s)) => {
5289 self.advance();
5290 Ok(Expr::Literal(Literal::String(s)))
5291 }
5292 Some(Token::MultiLineStringLit(s)) => {
5293 self.advance();
5294 Ok(Expr::Literal(Literal::MultiLineString(s)))
5295 }
5296 Some(Token::RawStringLit(s)) | Some(Token::RawStringDelimited(s)) => {
5297 self.advance();
5298 Ok(Expr::Literal(Literal::RawString(s)))
5299 }
5300 Some(Token::DotDot) | Some(Token::DotDotEq) => {
5303 let inclusive = self.consume_if(&Token::DotDotEq);
5304 if !inclusive {
5305 self.advance(); }
5307 let end = if self.check(&Token::RParen)
5309 || self.check(&Token::RBracket)
5310 || self.check(&Token::Comma)
5311 || self.check(&Token::Semi)
5312 || self.check(&Token::RBrace)
5313 {
5314 None
5315 } else {
5316 Some(Box::new(self.parse_expr()?))
5317 };
5318 Ok(Expr::Range {
5319 start: None,
5320 end,
5321 inclusive,
5322 })
5323 }
5324 Some(Token::ByteStringLit(bytes)) => {
5325 self.advance();
5326 Ok(Expr::Literal(Literal::ByteString(bytes)))
5327 }
5328 Some(Token::InterpolatedStringLit(s)) => {
5329 self.advance();
5330 let parts = self.parse_interpolation_parts(&s)?;
5332 Ok(Expr::Literal(Literal::InterpolatedString { parts }))
5333 }
5334 Some(Token::SigilStringSql(s)) => {
5335 self.advance();
5336 Ok(Expr::Literal(Literal::SigilStringSql(s)))
5337 }
5338 Some(Token::SigilStringRoute(s)) => {
5339 self.advance();
5340 Ok(Expr::Literal(Literal::SigilStringRoute(s)))
5341 }
5342 Some(Token::CharLit(c)) => {
5343 self.advance();
5344 Ok(Expr::Literal(Literal::Char(c)))
5345 }
5346 Some(Token::ByteCharLit(b)) => {
5347 self.advance();
5348 Ok(Expr::Literal(Literal::ByteChar(b)))
5349 }
5350 Some(Token::True) | Some(Token::Top) => {
5351 self.advance();
5352 Ok(Expr::Literal(Literal::Bool(true)))
5353 }
5354 Some(Token::False) | Some(Token::Bottom) => {
5355 self.advance();
5356 Ok(Expr::Literal(Literal::Bool(false)))
5357 }
5358 Some(Token::Null) => {
5359 self.advance();
5360 Ok(Expr::Literal(Literal::Null))
5361 }
5362 Some(Token::Empty) => {
5363 self.advance();
5364 Ok(Expr::Literal(Literal::Empty))
5365 }
5366 Some(Token::Infinity) => {
5367 if self.peek_next() == Some(&Token::LBrace) {
5369 self.advance();
5371 let body = self.parse_block()?;
5372 Ok(Expr::Loop { label: None, body })
5373 } else {
5374 self.advance();
5375 Ok(Expr::Literal(Literal::Infinity))
5376 }
5377 }
5378 Some(Token::Circle) => {
5379 self.advance();
5380 Ok(Expr::Literal(Literal::Circle))
5381 }
5382 Some(Token::LParen) => {
5383 self.advance();
5384 if self.check(&Token::RParen) {
5385 self.advance();
5386 return Ok(Expr::Tuple(vec![]));
5387 }
5388 let expr = self.parse_expr()?;
5389 if self.consume_if(&Token::Comma) {
5390 let mut exprs = vec![expr];
5391 while !self.check(&Token::RParen) {
5392 exprs.push(self.parse_expr()?);
5393 if !self.consume_if(&Token::Comma) {
5394 break;
5395 }
5396 }
5397 self.expect(Token::RParen)?;
5398 Ok(Expr::Tuple(exprs))
5399 } else {
5400 self.expect(Token::RParen)?;
5401 Ok(expr)
5402 }
5403 }
5404 Some(Token::LBracket) => {
5405 self.advance();
5406 if self.check(&Token::RBracket) {
5408 self.advance();
5409 return Ok(Expr::Array(vec![]));
5410 }
5411 let first = self.parse_expr()?;
5413 if self.consume_if(&Token::Semi) {
5415 let count = self.parse_expr()?;
5416 self.expect(Token::RBracket)?;
5417 return Ok(Expr::ArrayRepeat {
5418 value: Box::new(first),
5419 count: Box::new(count),
5420 });
5421 }
5422 let mut exprs = vec![first];
5424 while self.consume_if(&Token::Comma) {
5425 self.skip_comments();
5427 if self.check(&Token::RBracket) {
5428 break; }
5430 exprs.push(self.parse_expr()?);
5431 }
5432 self.skip_comments();
5433 self.expect(Token::RBracket)?;
5434 Ok(Expr::Array(exprs))
5435 }
5436 Some(Token::LBrace) => {
5437 self.parse_block_or_closure()
5439 }
5440 Some(Token::If) => self.parse_if_expr(),
5441 Some(Token::Match) => self.parse_match_expr(),
5442 Some(Token::ForAll) => {
5443 self.advance();
5445 let pattern = self.parse_pattern()?;
5446 self.expect(Token::ElementOf)?;
5447 let iter = self.parse_condition()?;
5448 let body = self.parse_block()?;
5449 Ok(Expr::For {
5450 label: None,
5451 pattern,
5452 iter: Box::new(iter),
5453 body,
5454 })
5455 }
5456 Some(Token::Unsafe) => {
5457 self.advance();
5458 let block = self.parse_block()?;
5459 Ok(Expr::Unsafe(block))
5460 }
5461 Some(Token::Async) => {
5462 self.advance();
5463 let is_move = self.consume_if(&Token::Move);
5464 let block = self.parse_block()?;
5465 Ok(Expr::Async { block, is_move })
5466 }
5467 Some(Token::Const) => {
5468 self.advance();
5471 let block = self.parse_block()?;
5472 Ok(Expr::Block(block))
5473 }
5474 Some(Token::Lifetime(name)) => {
5475 let span = self.current_span();
5477 let label = Ident {
5478 name: name.clone(),
5479 evidentiality: None,
5480 affect: None,
5481 span,
5482 };
5483 self.advance();
5484 self.expect(Token::Colon)?;
5485 match self.current_token().cloned() {
5486 Some(Token::Loop) | Some(Token::Infinity) => {
5487 self.advance();
5488 let body = self.parse_block()?;
5489 Ok(Expr::Loop { label: Some(label), body })
5490 }
5491 Some(Token::While) => {
5492 self.advance();
5493 let condition = if self.consume_if(&Token::Let) {
5495 let pattern = self.parse_pattern()?;
5496 self.expect(Token::Eq)?;
5497 let value = self.parse_condition()?;
5498 Expr::Let {
5499 pattern,
5500 value: Box::new(value),
5501 }
5502 } else {
5503 self.parse_condition()?
5504 };
5505 let body = self.parse_block()?;
5506 Ok(Expr::While {
5507 label: Some(label),
5508 condition: Box::new(condition),
5509 body,
5510 })
5511 }
5512 Some(Token::ForAll) | Some(Token::ForAll) => {
5513 self.advance();
5514 let pattern = self.parse_pattern()?;
5515 self.expect(Token::ElementOf)?;
5516 let iter = self.parse_condition()?;
5517 let body = self.parse_block()?;
5518 Ok(Expr::For {
5519 label: Some(label),
5520 pattern,
5521 iter: Box::new(iter),
5522 body,
5523 })
5524 }
5525 other => Err(ParseError::UnexpectedToken {
5526 expected: "loop, while, or for after label".to_string(),
5527 found: other.unwrap_or(Token::Null),
5528 span: self.current_span(),
5529 })
5530 }
5531 }
5532 Some(Token::Loop) | Some(Token::Infinity) => {
5533 self.advance();
5534 let body = self.parse_block()?;
5535 Ok(Expr::Loop { label: None, body })
5536 }
5537 Some(Token::While) => {
5538 self.advance();
5539 let condition = if self.consume_if(&Token::Let) {
5541 let pattern = self.parse_pattern()?;
5542 self.expect(Token::Eq)?;
5543 let value = self.parse_condition()?;
5544 Expr::Let {
5545 pattern,
5546 value: Box::new(value),
5547 }
5548 } else {
5549 self.parse_condition()?
5550 };
5551 let body = self.parse_block()?;
5552 Ok(Expr::While {
5553 label: None,
5554 condition: Box::new(condition),
5555 body,
5556 })
5557 }
5558 Some(Token::ForAll) | Some(Token::ForAll) => {
5559 self.advance();
5560 let pattern = self.parse_pattern()?;
5561 self.expect(Token::ElementOf)?;
5562 let iter = self.parse_condition()?;
5563 let body = self.parse_block()?;
5564 Ok(Expr::For {
5565 label: None,
5566 pattern,
5567 iter: Box::new(iter),
5568 body,
5569 })
5570 }
5571 Some(Token::Return) => {
5572 self.advance();
5573 let value = if self.check(&Token::Semi)
5575 || self.check(&Token::RBrace)
5576 || self.check(&Token::Comma)
5577 {
5578 None
5579 } else {
5580 Some(Box::new(self.parse_expr()?))
5581 };
5582 Ok(Expr::Return(value))
5583 }
5584 Some(Token::Tensor) | Some(Token::Tensor) => {
5585 self.advance();
5587 let label = if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
5589 let span = self.current_span();
5590 let label = Ident {
5591 name,
5592 evidentiality: None,
5593 affect: None,
5594 span,
5595 };
5596 self.advance();
5597 Some(label)
5598 } else {
5599 None
5600 };
5601 let value = if self.check(&Token::Semi)
5603 || self.check(&Token::RBrace)
5604 || self.check(&Token::Comma)
5605 {
5606 None
5607 } else {
5608 Some(Box::new(self.parse_expr()?))
5609 };
5610 Ok(Expr::Break { label, value })
5611 }
5612 Some(Token::CycleArrow) | Some(Token::CycleArrow) => {
5613 self.advance();
5615 let label = if let Some(Token::Lifetime(name)) = self.current_token().cloned() {
5617 let span = self.current_span();
5618 let label = Ident {
5619 name,
5620 evidentiality: None,
5621 affect: None,
5622 span,
5623 };
5624 self.advance();
5625 Some(label)
5626 } else {
5627 None
5628 };
5629 Ok(Expr::Continue { label })
5630 }
5631 Some(Token::Tau) | Some(Token::Phi) | Some(Token::Sigma) | Some(Token::Rho)
5633 | Some(Token::Lambda) | Some(Token::Pi) => {
5634 let kind = self.parse_morpheme_kind()?;
5635 if self.check(&Token::LBrace) {
5636 self.advance();
5637 self.skip_comments();
5638 let body = if self.looks_like_morpheme_closure() {
5640 self.parse_morpheme_closure()?
5641 } else {
5642 self.parse_expr()?
5643 };
5644 self.expect(Token::RBrace)?;
5645 Ok(Expr::Morpheme {
5646 kind,
5647 body: Box::new(body),
5648 })
5649 } else {
5650 Ok(Expr::Morpheme {
5652 kind,
5653 body: Box::new(Expr::Path(TypePath {
5654 segments: vec![PathSegment {
5655 ident: Ident {
5656 name: "_".to_string(),
5657 evidentiality: None,
5658 affect: None,
5659 span: Span::default(),
5660 },
5661 generics: None,
5662 }],
5663 })),
5664 })
5665 }
5666 }
5667 Some(Token::Sqrt) => {
5669 let span = self.current_span();
5671 self.advance();
5672 let name = if let Some(Token::IntLit(n)) = self.current_token().cloned() {
5673 let merged_span = span.merge(self.current_span());
5674 self.advance();
5675 (format!("√{}", n), merged_span)
5676 } else {
5677 ("√".to_string(), span)
5678 };
5679 Ok(Expr::Path(TypePath {
5680 segments: vec![PathSegment {
5681 ident: Ident {
5682 name: name.0,
5683 evidentiality: None,
5684 affect: None,
5685 span: name.1,
5686 },
5687 generics: None,
5688 }],
5689 }))
5690 }
5691 Some(Token::Underscore) => {
5692 let span = self.current_span();
5694 self.advance();
5695 Ok(Expr::Path(TypePath {
5696 segments: vec![PathSegment {
5697 ident: Ident {
5698 name: "_".to_string(),
5699 evidentiality: None,
5700 affect: None,
5701 span,
5702 },
5703 generics: None,
5704 }],
5705 }))
5706 }
5707 Some(Token::SelfLower) => {
5708 let span = self.current_span();
5710 self.advance();
5711 Ok(Expr::Path(TypePath {
5712 segments: vec![PathSegment {
5713 ident: Ident {
5714 name: "self".to_string(),
5715 evidentiality: None,
5716 affect: None,
5717 span,
5718 },
5719 generics: None,
5720 }],
5721 }))
5722 }
5723 Some(Token::SelfUpper) => {
5724 let span = self.current_span();
5726 self.advance();
5727 let mut segments = vec![PathSegment {
5728 ident: Ident {
5729 name: "Self".to_string(),
5730 evidentiality: None,
5731 affect: None,
5732 span,
5733 },
5734 generics: None,
5735 }];
5736 while self.consume_if(&Token::MiddleDot) {
5738 if self.check(&Token::Lt) {
5740 self.advance(); let types = self.parse_type_list()?;
5742 self.expect_gt()?;
5743 if let Some(last) = segments.last_mut() {
5745 last.generics = Some(types);
5746 }
5747 break;
5748 }
5749 segments.push(self.parse_path_segment()?);
5750 }
5751 let path = TypePath { segments };
5752 if self.check(&Token::LBrace) && !self.is_in_condition() {
5754 self.advance();
5755 let (fields, rest) = self.parse_struct_fields()?;
5756 self.expect(Token::RBrace)?;
5757 Ok(Expr::Struct { path, fields, rest })
5758 } else {
5759 Ok(Expr::Path(path))
5760 }
5761 }
5762 Some(Token::Ident(_)) => {
5763 let path = self.parse_type_path()?;
5764
5765 if self.check(&Token::LBrace) && !self.is_in_condition() {
5769 self.advance();
5770 let (fields, rest) = self.parse_struct_fields()?;
5771 self.expect(Token::RBrace)?;
5772 Ok(Expr::Struct { path, fields, rest })
5773 } else {
5774 Ok(Expr::Path(path))
5775 }
5776 }
5777 Some(Token::Asm) => self.parse_inline_asm(),
5778 Some(Token::Volatile) => self.parse_volatile_expr(),
5779 Some(Token::Simd) => self.parse_simd_expr(),
5780 Some(Token::Atomic) => self.parse_atomic_expr(),
5781 Some(Token::Dot) => {
5787 let dot_span = self.current_span();
5788 self.advance(); match self.current_token() {
5790 Some(Token::Ident(name)) => {
5791 let field_name = name.clone();
5792 let field_span = self.current_span();
5793 self.advance();
5794 let self_expr = Expr::Path(TypePath {
5796 segments: vec![PathSegment {
5797 ident: Ident {
5798 name: "self".to_string(),
5799 evidentiality: None,
5800 affect: None,
5801 span: dot_span,
5802 },
5803 generics: None,
5804 }],
5805 });
5806 Ok(Expr::Field {
5807 expr: Box::new(self_expr),
5808 field: Ident {
5809 name: field_name,
5810 evidentiality: None,
5811 affect: None,
5812 span: field_span,
5813 },
5814 })
5815 }
5816 Some(token) => Err(ParseError::UnexpectedToken {
5817 expected: "identifier after '.' for implicit self field".to_string(),
5818 found: token.clone(),
5819 span: self.current_span(),
5820 }),
5821 None => Err(ParseError::UnexpectedEof),
5822 }
5823 }
5824 Some(ref token) if Self::keyword_as_ident(token).is_some() => {
5826 let path = self.parse_type_path()?;
5827 if self.check(&Token::LBrace) && !self.is_in_condition() {
5830 self.advance();
5831 let (fields, rest) = self.parse_struct_fields()?;
5832 self.expect(Token::RBrace)?;
5833 Ok(Expr::Struct { path, fields, rest })
5834 } else {
5835 Ok(Expr::Path(path))
5836 }
5837 }
5838 Some(token) => Err(ParseError::UnexpectedToken {
5839 expected: "expression".to_string(),
5840 found: token,
5841 span: self.current_span(),
5842 }),
5843 None => Err(ParseError::UnexpectedEof),
5844 }
5845 }
5846
5847 fn parse_inline_asm(&mut self) -> ParseResult<Expr> {
5858 self.expect(Token::Asm)?;
5859 self.expect(Token::Bang)?;
5860 self.expect(Token::LParen)?;
5861
5862 let template = match self.current_token().cloned() {
5864 Some(Token::StringLit(s)) => {
5865 self.advance();
5866 s
5867 }
5868 Some(t) => {
5869 return Err(ParseError::UnexpectedToken {
5870 expected: "assembly template string".to_string(),
5871 found: t,
5872 span: self.current_span(),
5873 });
5874 }
5875 None => return Err(ParseError::UnexpectedEof),
5876 };
5877
5878 let mut outputs = Vec::new();
5879 let mut inputs = Vec::new();
5880 let mut clobbers = Vec::new();
5881 let mut options = AsmOptions::default();
5882
5883 while self.consume_if(&Token::Comma) {
5885 if self.check(&Token::RParen) {
5886 break;
5887 }
5888
5889 match self.current_token().cloned() {
5890 Some(Token::Ident(ref name)) if name == "out" => {
5891 self.advance();
5892 let operand = self.parse_asm_operand(AsmOperandKind::Output)?;
5893 outputs.push(operand);
5894 }
5895 Some(Token::ElementOf) => {
5897 self.advance();
5898 let operand = self.parse_asm_operand(AsmOperandKind::Input)?;
5899 inputs.push(operand);
5900 }
5901 Some(Token::Ident(ref name)) if name == "inout" => {
5902 self.advance();
5903 let operand = self.parse_asm_operand(AsmOperandKind::InOut)?;
5904 outputs.push(operand);
5905 }
5906 Some(Token::Ident(ref name)) if name == "clobber" => {
5907 self.advance();
5908 self.expect(Token::LParen)?;
5909 while !self.check(&Token::RParen) {
5910 if let Some(Token::StringLit(reg)) = self.current_token().cloned() {
5911 self.advance();
5912 clobbers.push(reg);
5913 } else if let Some(Token::Ident(reg)) = self.current_token().cloned() {
5914 self.advance();
5915 clobbers.push(reg);
5916 }
5917 if !self.consume_if(&Token::Comma) {
5918 break;
5919 }
5920 }
5921 self.expect(Token::RParen)?;
5922 }
5923 Some(Token::Ident(ref name)) if name == "options" => {
5924 self.advance();
5925 self.expect(Token::LParen)?;
5926 while !self.check(&Token::RParen) {
5927 if let Some(Token::Ident(opt)) = self.current_token().cloned() {
5928 self.advance();
5929 match opt.as_str() {
5930 "volatile" => options.volatile = true,
5931 "nostack" => options.nostack = true,
5932 "pure" => options.pure_asm = true,
5933 "readonly" => options.readonly = true,
5934 "nomem" => options.nomem = true,
5935 "att_syntax" => options.att_syntax = true,
5936 _ => {}
5937 }
5938 }
5939 if !self.consume_if(&Token::Comma) {
5940 break;
5941 }
5942 }
5943 self.expect(Token::RParen)?;
5944 }
5945 _ => break,
5946 }
5947 }
5948
5949 self.expect(Token::RParen)?;
5950
5951 Ok(Expr::InlineAsm(InlineAsm {
5952 template,
5953 outputs,
5954 inputs,
5955 clobbers,
5956 options,
5957 }))
5958 }
5959
5960 fn parse_asm_operand(&mut self, kind: AsmOperandKind) -> ParseResult<AsmOperand> {
5962 self.expect(Token::LParen)?;
5963
5964 let constraint = match self.current_token().cloned() {
5965 Some(Token::StringLit(s)) => {
5966 self.advance();
5967 s
5968 }
5969 Some(Token::Ident(s)) => {
5970 self.advance();
5971 s
5972 }
5973 Some(t) => {
5974 return Err(ParseError::UnexpectedToken {
5975 expected: "register constraint".to_string(),
5976 found: t,
5977 span: self.current_span(),
5978 });
5979 }
5980 None => return Err(ParseError::UnexpectedEof),
5981 };
5982
5983 self.expect(Token::RParen)?;
5984
5985 let expr = self.parse_expr()?;
5986
5987 let output = if kind == AsmOperandKind::InOut && self.consume_if(&Token::FatArrow) {
5989 Some(Box::new(self.parse_expr()?))
5990 } else {
5991 None
5992 };
5993
5994 Ok(AsmOperand {
5995 constraint,
5996 expr,
5997 kind,
5998 output,
5999 })
6000 }
6001
6002 fn parse_volatile_expr(&mut self) -> ParseResult<Expr> {
6007 self.expect(Token::Volatile)?;
6008
6009 match self.current_token().cloned() {
6010 Some(Token::Ident(ref name)) if name == "read" => {
6011 self.advance();
6012
6013 let ty = if self.consume_if(&Token::Lt) {
6015 let t = self.parse_type()?;
6016 self.expect_gt()?;
6017 Some(t)
6018 } else {
6019 None
6020 };
6021
6022 self.expect(Token::LParen)?;
6023 let ptr = self.parse_expr()?;
6024 self.expect(Token::RParen)?;
6025
6026 Ok(Expr::VolatileRead {
6027 ptr: Box::new(ptr),
6028 ty,
6029 })
6030 }
6031 Some(Token::Ident(ref name)) if name == "write" => {
6032 self.advance();
6033
6034 let ty = if self.consume_if(&Token::Lt) {
6036 let t = self.parse_type()?;
6037 self.expect_gt()?;
6038 Some(t)
6039 } else {
6040 None
6041 };
6042
6043 self.expect(Token::LParen)?;
6044 let ptr = self.parse_expr()?;
6045 self.expect(Token::Comma)?;
6046 let value = self.parse_expr()?;
6047 self.expect(Token::RParen)?;
6048
6049 Ok(Expr::VolatileWrite {
6050 ptr: Box::new(ptr),
6051 value: Box::new(value),
6052 ty,
6053 })
6054 }
6055 Some(t) => Err(ParseError::UnexpectedToken {
6056 expected: "'read' or 'write' after 'volatile'".to_string(),
6057 found: t,
6058 span: self.current_span(),
6059 }),
6060 None => Err(ParseError::UnexpectedEof),
6061 }
6062 }
6063
6064 fn parse_simd_expr(&mut self) -> ParseResult<Expr> {
6076 self.expect(Token::Simd)?;
6077
6078 match self.current_token().cloned() {
6079 Some(Token::LBracket) => {
6080 self.advance();
6082 let elements = self.parse_expr_list()?;
6083 self.expect(Token::RBracket)?;
6084
6085 let ty = if self.consume_if(&Token::Colon) {
6087 Some(self.parse_type()?)
6088 } else {
6089 None
6090 };
6091
6092 Ok(Expr::SimdLiteral { elements, ty })
6093 }
6094 Some(Token::Dot) => {
6095 self.advance();
6096 match self.current_token().cloned() {
6097 Some(Token::Ident(ref op)) => {
6098 let op_name = op.clone();
6099 self.advance();
6100 self.expect(Token::LParen)?;
6101
6102 match op_name.as_str() {
6103 "splat" => {
6104 let value = self.parse_expr()?;
6105 self.expect(Token::Comma)?;
6106 let lanes = match self.current_token() {
6107 Some(Token::IntLit(s)) => {
6108 let n = s.parse::<u8>().map_err(|_| {
6109 ParseError::Custom("invalid lane count".to_string())
6110 })?;
6111 self.advance();
6112 n
6113 }
6114 _ => {
6115 return Err(ParseError::Custom(
6116 "expected lane count".to_string(),
6117 ))
6118 }
6119 };
6120 self.expect(Token::RParen)?;
6121 Ok(Expr::SimdSplat {
6122 value: Box::new(value),
6123 lanes,
6124 })
6125 }
6126 "shuffle" => {
6127 let a = self.parse_expr()?;
6128 self.expect(Token::Comma)?;
6129 let b = self.parse_expr()?;
6130 self.expect(Token::Comma)?;
6131 self.expect(Token::LBracket)?;
6132 let mut indices = Vec::new();
6133 loop {
6134 match self.current_token() {
6135 Some(Token::IntLit(s)) => {
6136 let n = s.parse::<u8>().map_err(|_| {
6137 ParseError::Custom("invalid index".to_string())
6138 })?;
6139 indices.push(n);
6140 self.advance();
6141 }
6142 _ => {
6143 return Err(ParseError::Custom(
6144 "expected index".to_string(),
6145 ))
6146 }
6147 }
6148 if !self.consume_if(&Token::Comma) {
6149 break;
6150 }
6151 }
6152 self.expect(Token::RBracket)?;
6153 self.expect(Token::RParen)?;
6154 Ok(Expr::SimdShuffle {
6155 a: Box::new(a),
6156 b: Box::new(b),
6157 indices,
6158 })
6159 }
6160 "extract" => {
6161 let vector = self.parse_expr()?;
6162 self.expect(Token::Comma)?;
6163 let index = match self.current_token() {
6164 Some(Token::IntLit(s)) => {
6165 let n = s.parse::<u8>().map_err(|_| {
6166 ParseError::Custom("invalid index".to_string())
6167 })?;
6168 self.advance();
6169 n
6170 }
6171 _ => {
6172 return Err(ParseError::Custom(
6173 "expected index".to_string(),
6174 ))
6175 }
6176 };
6177 self.expect(Token::RParen)?;
6178 Ok(Expr::SimdExtract {
6179 vector: Box::new(vector),
6180 index,
6181 })
6182 }
6183 "insert" => {
6184 let vector = self.parse_expr()?;
6185 self.expect(Token::Comma)?;
6186 let index = match self.current_token() {
6187 Some(Token::IntLit(s)) => {
6188 let n = s.parse::<u8>().map_err(|_| {
6189 ParseError::Custom("invalid index".to_string())
6190 })?;
6191 self.advance();
6192 n
6193 }
6194 _ => {
6195 return Err(ParseError::Custom(
6196 "expected index".to_string(),
6197 ))
6198 }
6199 };
6200 self.expect(Token::Comma)?;
6201 let value = self.parse_expr()?;
6202 self.expect(Token::RParen)?;
6203 Ok(Expr::SimdInsert {
6204 vector: Box::new(vector),
6205 index,
6206 value: Box::new(value),
6207 })
6208 }
6209 _ => {
6210 let op = Self::parse_simd_op(&op_name)?;
6212 let args = self.parse_expr_list()?;
6213 self.expect(Token::RParen)?;
6214 Ok(Expr::SimdIntrinsic { op, args })
6215 }
6216 }
6217 }
6218 Some(t) => Err(ParseError::UnexpectedToken {
6219 expected: "SIMD operation name".to_string(),
6220 found: t,
6221 span: self.current_span(),
6222 }),
6223 None => Err(ParseError::UnexpectedEof),
6224 }
6225 }
6226 Some(t) => Err(ParseError::UnexpectedToken {
6227 expected: "'[' or '.' after 'simd'".to_string(),
6228 found: t,
6229 span: self.current_span(),
6230 }),
6231 None => Err(ParseError::UnexpectedEof),
6232 }
6233 }
6234
6235 fn parse_simd_op(name: &str) -> ParseResult<SimdOp> {
6236 match name {
6237 "add" => Ok(SimdOp::Add),
6238 "sub" => Ok(SimdOp::Sub),
6239 "mul" => Ok(SimdOp::Mul),
6240 "div" => Ok(SimdOp::Div),
6241 "neg" => Ok(SimdOp::Neg),
6242 "abs" => Ok(SimdOp::Abs),
6243 "min" => Ok(SimdOp::Min),
6244 "max" => Ok(SimdOp::Max),
6245 "eq" => Ok(SimdOp::Eq),
6246 "ne" => Ok(SimdOp::Ne),
6247 "lt" => Ok(SimdOp::Lt),
6248 "le" => Ok(SimdOp::Le),
6249 "gt" => Ok(SimdOp::Gt),
6250 "ge" => Ok(SimdOp::Ge),
6251 "hadd" => Ok(SimdOp::HAdd),
6252 "dot" => Ok(SimdOp::Dot),
6253 "blend" => Ok(SimdOp::Blend),
6254 "load" => Ok(SimdOp::Load),
6255 "store" => Ok(SimdOp::Store),
6256 "load_aligned" => Ok(SimdOp::LoadAligned),
6257 "store_aligned" => Ok(SimdOp::StoreAligned),
6258 "cast" => Ok(SimdOp::Cast),
6259 "widen" => Ok(SimdOp::Widen),
6260 "narrow" => Ok(SimdOp::Narrow),
6261 "sqrt" => Ok(SimdOp::Sqrt),
6262 "rsqrt" => Ok(SimdOp::Rsqrt),
6263 "rcp" => Ok(SimdOp::Rcp),
6264 "floor" => Ok(SimdOp::Floor),
6265 "ceil" => Ok(SimdOp::Ceil),
6266 "round" => Ok(SimdOp::Round),
6267 "and" => Ok(SimdOp::And),
6268 "or" => Ok(SimdOp::Or),
6269 "xor" => Ok(SimdOp::Xor),
6270 "not" => Ok(SimdOp::Not),
6271 "shl" => Ok(SimdOp::Shl),
6272 "shr" => Ok(SimdOp::Shr),
6273 _ => Err(ParseError::Custom(format!(
6274 "unknown SIMD operation: {}",
6275 name
6276 ))),
6277 }
6278 }
6279
6280 fn parse_atomic_expr(&mut self) -> ParseResult<Expr> {
6292 self.expect(Token::Atomic)?;
6293 self.expect(Token::Dot)?;
6294
6295 match self.current_token().cloned() {
6296 Some(Token::Ident(ref op)) => {
6297 let op_name = op.clone();
6298 self.advance();
6299
6300 if op_name == "fence" {
6301 self.expect(Token::LParen)?;
6302 let ordering = self.parse_memory_ordering()?;
6303 self.expect(Token::RParen)?;
6304 return Ok(Expr::AtomicFence { ordering });
6305 }
6306
6307 self.expect(Token::LParen)?;
6308 let ptr = self.parse_expr()?;
6309
6310 let op = Self::parse_atomic_op(&op_name)?;
6311
6312 let value = match op {
6314 AtomicOp::Load => None,
6315 _ => {
6316 self.expect(Token::Comma)?;
6317 Some(Box::new(self.parse_expr()?))
6318 }
6319 };
6320
6321 let expected = match op {
6323 AtomicOp::CompareExchange | AtomicOp::CompareExchangeWeak => {
6324 self.expect(Token::Comma)?;
6325 Some(Box::new(self.parse_expr()?))
6326 }
6327 _ => None,
6328 };
6329
6330 self.expect(Token::Comma)?;
6332 let ordering = self.parse_memory_ordering()?;
6333
6334 let failure_ordering = match op {
6336 AtomicOp::CompareExchange | AtomicOp::CompareExchangeWeak => {
6337 if self.consume_if(&Token::Comma) {
6338 Some(self.parse_memory_ordering()?)
6339 } else {
6340 None
6341 }
6342 }
6343 _ => None,
6344 };
6345
6346 self.expect(Token::RParen)?;
6347
6348 Ok(Expr::AtomicOp {
6349 op,
6350 ptr: Box::new(ptr),
6351 value,
6352 expected,
6353 ordering,
6354 failure_ordering,
6355 })
6356 }
6357 Some(t) => Err(ParseError::UnexpectedToken {
6358 expected: "atomic operation name".to_string(),
6359 found: t,
6360 span: self.current_span(),
6361 }),
6362 None => Err(ParseError::UnexpectedEof),
6363 }
6364 }
6365
6366 fn parse_atomic_op(name: &str) -> ParseResult<AtomicOp> {
6367 match name {
6368 "load" => Ok(AtomicOp::Load),
6369 "store" => Ok(AtomicOp::Store),
6370 "swap" => Ok(AtomicOp::Swap),
6371 "compare_exchange" => Ok(AtomicOp::CompareExchange),
6372 "compare_exchange_weak" => Ok(AtomicOp::CompareExchangeWeak),
6373 "fetch_add" => Ok(AtomicOp::FetchAdd),
6374 "fetch_sub" => Ok(AtomicOp::FetchSub),
6375 "fetch_and" => Ok(AtomicOp::FetchAnd),
6376 "fetch_or" => Ok(AtomicOp::FetchOr),
6377 "fetch_xor" => Ok(AtomicOp::FetchXor),
6378 "fetch_min" => Ok(AtomicOp::FetchMin),
6379 "fetch_max" => Ok(AtomicOp::FetchMax),
6380 _ => Err(ParseError::Custom(format!(
6381 "unknown atomic operation: {}",
6382 name
6383 ))),
6384 }
6385 }
6386
6387 fn parse_memory_ordering(&mut self) -> ParseResult<MemoryOrdering> {
6388 match self.current_token() {
6389 Some(Token::Ident(name)) => {
6390 let ordering =
6391 match name.as_str() {
6392 "Relaxed" => MemoryOrdering::Relaxed,
6393 "Acquire" => MemoryOrdering::Acquire,
6394 "Release" => MemoryOrdering::Release,
6395 "AcqRel" => MemoryOrdering::AcqRel,
6396 "SeqCst" => MemoryOrdering::SeqCst,
6397 _ => return Err(ParseError::Custom(
6398 "expected memory ordering (Relaxed, Acquire, Release, AcqRel, SeqCst)"
6399 .to_string(),
6400 )),
6401 };
6402 self.advance();
6403 Ok(ordering)
6404 }
6405 _ => Err(ParseError::Custom("expected memory ordering".to_string())),
6406 }
6407 }
6408
6409 fn is_pipe_target_ahead(&mut self) -> bool {
6412 if let Some(next) = self.peek_next().cloned() {
6414 match &next {
6415 Token::Ident(_) => true,
6417 Token::SelfLower => true,
6418 Token::SelfUpper => true,
6419 Token::Tau | Token::Phi | Token::Sigma | Token::Rho
6421 | Token::Lambda | Token::Delta | Token::Mu | Token::Chi
6422 | Token::GradeUp | Token::GradeDown | Token::Rotate
6423 | Token::Iota | Token::ForAll | Token::Exists
6424 | Token::Pi | Token::Async => true,
6425 Token::LambdaExpr => true,
6427 Token::Pipe => true,
6429 Token::OrOr => true, Token::Move => true,
6432 Token::LBrace => true,
6434 Token::IntLit(_) | Token::FloatLit(_) | Token::HexLit(_)
6436 | Token::BinaryLit(_) | Token::OctalLit(_) => false,
6437 Token::LParen => false, Token::True | Token::False => false,
6439 Token::If => false, Token::Match => false, _ => true,
6443 }
6444 } else {
6445 false }
6447 }
6448
6449 fn parse_postfix_after_pipe(&mut self, mut expr: Expr) -> ParseResult<Expr> {
6451 loop {
6452 self.skip_comments();
6454
6455 match self.current_token() {
6456 Some(Token::Question) => {
6457 self.advance();
6458 expr = Expr::Try(Box::new(expr));
6459 }
6460 Some(Token::Tilde) => {
6462 self.advance();
6463 expr = Expr::Evidential {
6464 expr: Box::new(expr),
6465 evidentiality: Evidentiality::Reported,
6466 };
6467 }
6468 Some(Token::Bang) => {
6469 self.advance();
6471 expr = Expr::Evidential {
6472 expr: Box::new(expr),
6473 evidentiality: Evidentiality::Known,
6474 };
6475 }
6476 Some(Token::Dot) => {
6477 self.advance();
6478 let field = if let Some(Token::IntLit(idx)) = self.current_token() {
6479 let idx = idx.clone();
6480 let span = self.current_span();
6481 self.advance();
6482 Ident {
6483 name: idx,
6484 evidentiality: None,
6485 affect: None,
6486 span,
6487 }
6488 } else {
6489 self.parse_ident()?
6490 };
6491 if self.check(&Token::MiddleDot) {
6492 self.advance();
6493 self.expect(Token::Lt)?;
6494 let type_args = self.parse_type_list()?;
6495 self.expect_gt()?;
6496 self.expect(Token::LParen)?;
6497 let args = self.parse_expr_list()?;
6498 self.expect(Token::RParen)?;
6499 expr = Expr::MethodCall {
6500 receiver: Box::new(expr),
6501 method: field,
6502 type_args: Some(type_args),
6503 args,
6504 };
6505 } else if self.check(&Token::LParen) {
6506 self.advance();
6507 let args = self.parse_expr_list()?;
6508 self.expect(Token::RParen)?;
6509 expr = Expr::MethodCall {
6510 receiver: Box::new(expr),
6511 method: field,
6512 type_args: None,
6513 args,
6514 };
6515 } else {
6516 expr = Expr::Field {
6517 expr: Box::new(expr),
6518 field,
6519 };
6520 }
6521 }
6522 Some(Token::MiddleDot) => {
6524 let first_segment = self.expr_to_incorporation_segment(expr.clone())?;
6526 let mut segments = vec![first_segment];
6527
6528 while self.consume_if(&Token::MiddleDot) {
6529 if self.check(&Token::Async) {
6531 self.advance();
6532 let evidentiality = self.parse_evidentiality_opt();
6533 expr = if segments.len() == 1 && segments[0].args.is_none() {
6535 expr.clone()
6537 } else {
6538 Expr::Incorporation { segments: segments.clone() }
6539 };
6540 expr = Expr::Await {
6541 expr: Box::new(expr),
6542 evidentiality,
6543 };
6544 let first_segment = self.expr_to_incorporation_segment(expr.clone())?;
6546 segments = vec![first_segment];
6547 continue;
6548 }
6549 let name = if let Some(Token::IntLit(idx)) = self.current_token().cloned() {
6551 let span = self.current_span();
6552 self.advance();
6553 Ident {
6554 name: idx,
6555 evidentiality: None,
6556 affect: None,
6557 span,
6558 }
6559 } else {
6560 self.parse_ident()?
6561 };
6562 if self.check(&Token::LBracket) && self.peek_looks_like_bracket_generic() {
6564 self.advance(); let _generics = self.parse_type_list()?;
6566 self.expect(Token::RBracket)?;
6567 }
6568 if self.check(&Token::Lt) && self.peek_looks_like_generic_arg() {
6570 self.advance(); let _generics = self.parse_type_list()?;
6572 self.expect_gt()?;
6573 }
6574 let args = if self.check(&Token::LParen) {
6575 self.advance();
6576 let args = self.parse_expr_list()?;
6577 self.expect(Token::RParen)?;
6578 Some(args)
6579 } else {
6580 None
6581 };
6582 segments.push(IncorporationSegment { name, args });
6583 }
6584
6585 expr = Expr::Incorporation { segments };
6586 }
6587 _ => break,
6588 }
6589 }
6590 Ok(expr)
6591 }
6592
6593 fn parse_pipe_chain(&mut self, initial: Expr) -> ParseResult<Expr> {
6595 let mut operations = Vec::new();
6596
6597 while self.consume_if(&Token::Pipe) {
6598 let op = self.parse_pipe_op()?;
6599 operations.push(op);
6600 }
6601
6602 Ok(Expr::Pipe {
6603 expr: Box::new(initial),
6604 operations,
6605 })
6606 }
6607
6608 fn parse_pipe_op(&mut self) -> ParseResult<PipeOp> {
6609 match self.current_token() {
6610 Some(Token::Tau) => {
6611 self.advance();
6612 self.expect(Token::LBrace)?;
6613 self.skip_comments();
6614 let body = if self.looks_like_morpheme_closure() {
6616 self.parse_morpheme_closure()?
6617 } else {
6618 self.parse_expr()?
6619 };
6620 self.expect(Token::RBrace)?;
6621 Ok(PipeOp::Transform(Box::new(body)))
6622 }
6623 Some(Token::Phi) => {
6624 self.advance();
6625 self.expect(Token::LBrace)?;
6626 self.skip_comments();
6627 let body = if self.looks_like_morpheme_closure() {
6629 self.parse_morpheme_closure()?
6630 } else {
6631 self.parse_expr()?
6632 };
6633 self.expect(Token::RBrace)?;
6634 Ok(PipeOp::Filter(Box::new(body)))
6635 }
6636 Some(Token::Sigma) => {
6637 if self.peek_next() == Some(&Token::LParen) {
6639 let name = Ident {
6641 name: "Σ".to_string(),
6642 evidentiality: None,
6643 affect: None,
6644 span: self.current_span(),
6645 };
6646 self.advance(); self.advance(); let args = self.parse_expr_list()?;
6649 self.expect(Token::RParen)?;
6650 Ok(PipeOp::Call(Box::new(Expr::Call {
6651 func: Box::new(Expr::Path(TypePath {
6652 segments: vec![PathSegment { ident: name, generics: None }],
6653 })),
6654 args,
6655 })))
6656 } else if self.peek_next() == Some(&Token::LBrace) {
6657 self.advance(); self.advance(); self.skip_comments();
6661 let body = if self.looks_like_morpheme_closure() {
6662 self.parse_morpheme_closure()?
6663 } else {
6664 self.parse_expr()?
6665 };
6666 self.expect(Token::RBrace)?;
6667 Ok(PipeOp::SortBy(Box::new(body)))
6668 } else {
6669 self.advance();
6670 let field = if self.consume_if(&Token::Dot) {
6671 Some(self.parse_ident()?)
6672 } else {
6673 None
6674 };
6675 Ok(PipeOp::Sort(field))
6676 }
6677 }
6678 Some(Token::Rho) => {
6679 self.advance();
6680 match self.current_token() {
6682 Some(Token::Plus) => {
6683 self.advance();
6684 Ok(PipeOp::ReduceSum)
6685 }
6686 Some(Token::Star) => {
6687 self.advance();
6688 Ok(PipeOp::ReduceProd)
6689 }
6690 Some(Token::PlusPlus) => {
6691 self.advance();
6692 Ok(PipeOp::ReduceConcat)
6693 }
6694 Some(Token::Amp) => {
6695 self.advance();
6696 Ok(PipeOp::ReduceAll)
6697 }
6698 Some(Token::Pipe) => {
6699 self.advance();
6700 Ok(PipeOp::ReduceAny)
6701 }
6702 Some(Token::Underscore) => {
6703 self.advance();
6704 if let Some(Token::Ident(name)) = self.current_token().cloned() {
6706 self.advance();
6707 match name.as_str() {
6708 "sum" => Ok(PipeOp::ReduceSum),
6709 "prod" | "product" => Ok(PipeOp::ReduceProd),
6710 "min" => Ok(PipeOp::ReduceMin),
6711 "max" => Ok(PipeOp::ReduceMax),
6712 "cat" | "concat" => Ok(PipeOp::ReduceConcat),
6713 "all" => Ok(PipeOp::ReduceAll),
6714 "any" => Ok(PipeOp::ReduceAny),
6715 _ => Err(ParseError::Custom(format!(
6716 "unknown reduction variant: ρ_{}",
6717 name
6718 ))),
6719 }
6720 } else {
6721 Err(ParseError::Custom(
6722 "expected reduction variant name after ρ_".to_string(),
6723 ))
6724 }
6725 }
6726 Some(Token::LBrace) => {
6727 self.advance();
6729 self.skip_comments();
6730 if self.looks_like_morpheme_closure() {
6731 let body = self.parse_morpheme_closure()?;
6733 self.expect(Token::RBrace)?;
6734 Ok(PipeOp::Reduce(Box::new(body)))
6735 } else {
6736 let init = self.parse_expr()?;
6738 self.expect(Token::Comma)?;
6739 self.skip_comments();
6740 let closure = self.parse_morpheme_closure()?;
6741 self.expect(Token::RBrace)?;
6742 Ok(PipeOp::ReduceWithInit(Box::new(init), Box::new(closure)))
6743 }
6744 }
6745 _ => Err(ParseError::Custom(
6746 "expected reduction variant (+, *, ++, &, |, _name) or {body} after ρ"
6747 .to_string(),
6748 )),
6749 }
6750 }
6751 Some(Token::Pi) => {
6753 self.advance();
6754 Ok(PipeOp::ReduceProd)
6755 }
6756 Some(Token::Alpha) => {
6758 self.advance();
6759 Ok(PipeOp::First)
6760 }
6761 Some(Token::Omega) => {
6762 self.advance();
6763 Ok(PipeOp::Last)
6764 }
6765 Some(Token::Mu) => {
6766 if self.peek_next() == Some(&Token::LParen) {
6769 let name = Ident {
6771 name: "μ".to_string(),
6772 evidentiality: None,
6773 affect: None,
6774 span: self.current_span(),
6775 };
6776 self.advance(); self.advance(); let args = self.parse_expr_list()?;
6779 self.expect(Token::RParen)?;
6780 Ok(PipeOp::Call(Box::new(Expr::Call {
6782 func: Box::new(Expr::Path(TypePath {
6783 segments: vec![PathSegment { ident: name, generics: None }],
6784 })),
6785 args,
6786 })))
6787 } else {
6788 self.advance();
6789 Ok(PipeOp::Middle)
6790 }
6791 }
6792 Some(Token::Chi) => {
6793 self.advance();
6794 Ok(PipeOp::Choice)
6795 }
6796 Some(Token::Nu) => {
6797 self.advance();
6798 if self.check(&Token::LBrace) {
6800 self.advance();
6801 let index = self.parse_expr()?;
6802 self.expect(Token::RBrace)?;
6803 Ok(PipeOp::Nth(Box::new(index)))
6804 } else {
6805 Ok(PipeOp::Nth(Box::new(Expr::Literal(Literal::Int {
6807 value: "0".to_string(),
6808 base: NumBase::Decimal,
6809 suffix: None,
6810 }))))
6811 }
6812 }
6813 Some(Token::Xi) => {
6814 self.advance();
6815 Ok(PipeOp::Next)
6816 }
6817 Some(Token::Delta) => {
6819 self.advance();
6820 Ok(PipeOp::Unique)
6821 }
6822 Some(Token::Parallel) => {
6824 self.advance();
6825 let inner_op = self.parse_pipe_op()?;
6827 Ok(PipeOp::Parallel(Box::new(inner_op)))
6828 }
6829 Some(Token::Gpu) => {
6831 self.advance();
6832 let inner_op = self.parse_pipe_op()?;
6834 Ok(PipeOp::Gpu(Box::new(inner_op)))
6835 }
6836 Some(Token::Await) => {
6837 self.advance();
6838 Ok(PipeOp::Await)
6839 }
6840 Some(Token::Async) => {
6841 self.advance();
6842 Ok(PipeOp::Await)
6843 }
6844 Some(Token::MiddleDot) => {
6845 self.advance();
6846 let mut prefix = Vec::new();
6847 prefix.push(self.parse_ident()?);
6848
6849 while self.consume_if(&Token::MiddleDot) {
6850 if self.check(&Token::LBrace) {
6851 break;
6852 }
6853 prefix.push(self.parse_ident()?);
6854 }
6855
6856 let body = if self.check(&Token::LBrace) {
6857 self.advance();
6858 let expr = self.parse_expr()?;
6859 self.expect(Token::RBrace)?;
6860 Some(Box::new(expr))
6861 } else {
6862 None
6863 };
6864
6865 Ok(PipeOp::Named { prefix, body })
6866 }
6867 Some(Token::Match) => {
6869 self.advance();
6870 self.expect(Token::LBrace)?;
6871 let mut arms = Vec::new();
6872 while !self.check(&Token::RBrace) && !self.is_eof() {
6873 let pattern = self.parse_or_pattern()?;
6875 let guard = if self.consume_if(&Token::If) {
6876 Some(self.parse_condition()?)
6877 } else {
6878 None
6879 };
6880 self.expect(Token::FatArrow)?;
6881 let body = self.parse_expr()?;
6882 arms.push(MatchArm {
6883 pattern,
6884 guard,
6885 body,
6886 });
6887 self.consume_if(&Token::Comma);
6889 }
6890 self.expect(Token::RBrace)?;
6891 Ok(PipeOp::Match(arms))
6892 }
6893 Some(Token::Interrobang) => {
6896 self.advance();
6897 let mapper = if self.check(&Token::LBrace) {
6898 self.advance();
6899 let expr = self.parse_expr()?;
6900 self.expect(Token::RBrace)?;
6901 Some(Box::new(expr))
6902 } else {
6903 None
6904 };
6905 Ok(PipeOp::TryMap(mapper))
6906 }
6907 Some(Token::SelfLower) | Some(Token::SelfUpper) => {
6909 let expr = self.parse_postfix_expr()?;
6911 Ok(PipeOp::Call(Box::new(expr)))
6912 }
6913 Some(Token::Nabla) => {
6915 self.advance();
6916 Ok(PipeOp::Method {
6918 name: Ident {
6919 name: "∇".to_string(),
6920 evidentiality: None,
6921 affect: None,
6922 span: self.current_span(),
6923 },
6924 type_args: None,
6925 args: vec![],
6926 })
6927 }
6928 Some(Token::Interfere) => {
6930 self.advance(); let name = Ident {
6932 name: "interfere".to_string(),
6933 evidentiality: None,
6934 affect: None,
6935 span: self.current_span(),
6936 };
6937 let args = if self.check(&Token::LParen) {
6939 self.advance();
6940 let args = self.parse_expr_list()?;
6941 self.expect(Token::RParen)?;
6942 args
6943 } else {
6944 vec![]
6945 };
6946 Ok(PipeOp::Method { name, type_args: None, args })
6947 }
6948 Some(Token::Struct) => {
6950 self.advance(); let name = Ident {
6952 name: "Σ".to_string(),
6953 evidentiality: None,
6954 affect: None,
6955 span: self.current_span(),
6956 };
6957 let args = if self.check(&Token::LParen) {
6959 self.advance();
6960 let args = self.parse_expr_list()?;
6961 self.expect(Token::RParen)?;
6962 args
6963 } else {
6964 vec![]
6965 };
6966 Ok(PipeOp::Method { name, type_args: None, args })
6967 }
6968 Some(Token::Lozenge) => {
6970 self.advance();
6971 if let Some(Token::Ident(_)) = self.current_token() {
6972 let method = self.parse_ident()?;
6974 let args = if self.check(&Token::LParen) {
6975 self.advance();
6976 let args = self.parse_expr_list()?;
6977 self.expect(Token::RParen)?;
6978 args
6979 } else {
6980 vec![]
6981 };
6982 Ok(PipeOp::Possibility { method, args })
6983 } else {
6984 Ok(PipeOp::PossibilityExtract)
6986 }
6987 }
6988 Some(Token::BoxSquare) => {
6990 self.advance();
6991 if let Some(Token::Ident(_)) = self.current_token() {
6992 let method = self.parse_ident()?;
6994 let args = if self.check(&Token::LParen) {
6995 self.advance();
6996 let args = self.parse_expr_list()?;
6997 self.expect(Token::RParen)?;
6998 args
6999 } else {
7000 vec![]
7001 };
7002 Ok(PipeOp::Necessity { method, args })
7003 } else {
7004 Ok(PipeOp::NecessityVerify)
7006 }
7007 }
7008 Some(Token::Ident(_)) => {
7009 let name = self.parse_ident()?;
7010
7011 if name.name == "validate" || name.name == "assume" {
7017 let (has_marker, target_evidence) = if self.check(&Token::Question) {
7022 let peek = self.peek_next();
7023 if matches!(peek, Some(Token::LBrace) | Some(Token::LParen)) {
7024 self.advance(); (true, Evidentiality::Uncertain)
7026 } else {
7027 (false, Evidentiality::Known)
7028 }
7029 } else if self.check(&Token::Tilde) {
7030 let peek = self.peek_next();
7031 if matches!(peek, Some(Token::LBrace) | Some(Token::LParen)) {
7032 self.advance(); (true, Evidentiality::Reported)
7034 } else {
7035 (false, Evidentiality::Known)
7036 }
7037 } else {
7038 (false, name.evidentiality.unwrap_or(Evidentiality::Known))
7039 };
7040
7041 if has_marker || self.check(&Token::LParen) || self.check(&Token::LBrace) {
7043
7044 let args = if self.check(&Token::LParen) {
7045 self.advance();
7046 let args = self.parse_expr_list()?;
7047 self.expect(Token::RParen)?;
7048 args
7049 } else if self.check(&Token::LBrace) {
7050 self.advance();
7051 self.skip_comments();
7052 let body = if self.looks_like_morpheme_closure() {
7053 self.parse_morpheme_closure()?
7054 } else {
7055 self.parse_expr()?
7056 };
7057 self.expect(Token::RBrace)?;
7058 vec![body]
7059 } else {
7060 vec![]
7061 };
7062
7063 if name.name == "validate" {
7064 if args.is_empty() {
7065 return Err(ParseError::Custom("validate requires a predicate".to_string()));
7066 }
7067 return Ok(PipeOp::Validate {
7068 predicate: Box::new(args.into_iter().next().unwrap()),
7069 target_evidence,
7070 });
7071 } else {
7072 let reason = args.into_iter().next().map(Box::new);
7074 return Ok(PipeOp::Assume {
7075 reason,
7076 target_evidence,
7077 });
7078 }
7079 }
7080 }
7081
7082 if self.check(&Token::Bang) {
7084 let peek = self.peek_next();
7085 if matches!(peek, Some(Token::LBrace) | Some(Token::LParen) | Some(Token::LBracket)) {
7086 self.advance(); let tokens = self.parse_macro_tokens()?;
7088 let path = TypePath {
7089 segments: vec![PathSegment { ident: name, generics: None }],
7090 };
7091 return Ok(PipeOp::Call(Box::new(Expr::Macro { path, tokens })));
7092 }
7093 }
7094
7095 let mut path_segments = vec![PathSegment { ident: name.clone(), generics: None }];
7099 let type_args = loop {
7100 if self.check(&Token::MiddleDot) {
7101 self.advance(); if self.check(&Token::Lt) {
7103 self.advance(); let types = self.parse_type_list()?;
7106 self.expect_gt()?;
7107 break Some(types);
7108 } else if let Some(Token::Ident(_)) = self.current_token() {
7109 let segment = self.parse_ident()?;
7111 path_segments.push(PathSegment { ident: segment, generics: None });
7112 } else {
7114 return Err(ParseError::Custom(
7115 "expected identifier or '<' after '::'".to_string()
7116 ));
7117 }
7118 } else {
7119 break None;
7120 }
7121 };
7122
7123 let name = if path_segments.len() > 1 {
7125 let path = TypePath { segments: path_segments };
7127 let args = if self.check(&Token::LParen) {
7128 self.advance();
7129 let args = self.parse_expr_list()?;
7130 self.expect(Token::RParen)?;
7131 args
7132 } else {
7133 vec![]
7134 };
7135 return Ok(PipeOp::Call(Box::new(Expr::Call {
7136 func: Box::new(Expr::Path(path)),
7137 args,
7138 })));
7139 } else {
7140 name
7141 };
7142 let args = if self.check(&Token::LParen) {
7143 self.advance();
7144 let args = self.parse_expr_list()?;
7145 self.expect(Token::RParen)?;
7146 args
7147 } else if self.check(&Token::LBrace) && !self.in_condition {
7148 self.advance();
7151 self.skip_comments();
7152 let body = if self.looks_like_morpheme_closure() {
7153 self.parse_morpheme_closure()?
7154 } else {
7155 self.parse_expr()?
7156 };
7157 self.expect(Token::RBrace)?;
7158 vec![body]
7159 } else {
7160 vec![]
7161 };
7162
7163 if name.name == "validate" {
7165 let target_evidence = name.evidentiality.unwrap_or(Evidentiality::Known);
7166 if args.is_empty() {
7167 return Err(ParseError::Custom("validate requires a predicate: |validate!{predicate}".to_string()));
7168 }
7169 return Ok(PipeOp::Validate {
7170 predicate: Box::new(args.into_iter().next().unwrap()),
7171 target_evidence,
7172 });
7173 }
7174 if name.name == "assume" {
7175 let target_evidence = name.evidentiality.unwrap_or(Evidentiality::Known);
7176 let reason = args.into_iter().next().map(Box::new);
7177 return Ok(PipeOp::Assume {
7178 reason,
7179 target_evidence,
7180 });
7181 }
7182
7183 if QUANTUM_GATES.contains(&name.name.as_str())
7187 || QUANTUM_OPS.contains(&name.name.as_str()) {
7188 let path_expr = Expr::Path(TypePath {
7192 segments: vec![PathSegment { ident: name, generics: None }],
7193 });
7194 let call_expr = if args.is_empty() {
7195 path_expr
7196 } else {
7197 Expr::Call {
7198 func: Box::new(path_expr),
7199 args,
7200 }
7201 };
7202 return Ok(PipeOp::Call(Box::new(call_expr)));
7203 }
7204
7205 Ok(PipeOp::Method { name, type_args, args })
7206 }
7207
7208 Some(Token::Send) | Some(Token::ProtoSend) => {
7214 self.advance();
7215 self.expect(Token::LBrace)?;
7216 let data = self.parse_expr()?;
7217 self.expect(Token::RBrace)?;
7218 Ok(PipeOp::Send(Box::new(data)))
7219 }
7220
7221 Some(Token::Recv) | Some(Token::ProtoRecv) => {
7223 self.advance();
7224 Ok(PipeOp::Recv)
7225 }
7226
7227 Some(Token::Stream) | Some(Token::ProtoStream) => {
7229 self.advance();
7230 self.expect(Token::LBrace)?;
7231 let handler = self.parse_expr()?;
7232 self.expect(Token::RBrace)?;
7233 Ok(PipeOp::Stream(Box::new(handler)))
7234 }
7235
7236 Some(Token::Connect) | Some(Token::ProtoConnect) => {
7238 self.advance();
7239 let config = if self.check(&Token::LBrace) {
7240 self.advance();
7241 let expr = self.parse_expr()?;
7242 self.expect(Token::RBrace)?;
7243 Some(Box::new(expr))
7244 } else {
7245 None
7246 };
7247 Ok(PipeOp::Connect(config))
7248 }
7249
7250 Some(Token::Close) | Some(Token::Tensor) => {
7252 self.advance();
7253 Ok(PipeOp::Close)
7254 }
7255
7256 Some(Token::Timeout) | Some(Token::ProtoTimeout) => {
7258 self.advance();
7259 self.expect(Token::LBrace)?;
7260 let ms = self.parse_expr()?;
7261 self.expect(Token::RBrace)?;
7262 Ok(PipeOp::Timeout(Box::new(ms)))
7263 }
7264
7265 Some(Token::Retry) => {
7267 self.advance();
7268 self.expect(Token::LBrace)?;
7269 let count = self.parse_expr()?;
7270 let strategy = if self.consume_if(&Token::Comma) {
7271 Some(Box::new(self.parse_expr()?))
7272 } else {
7273 None
7274 };
7275 self.expect(Token::RBrace)?;
7276 Ok(PipeOp::Retry {
7277 count: Box::new(count),
7278 strategy,
7279 })
7280 }
7281
7282 Some(Token::Header) => {
7284 self.advance();
7285 self.expect(Token::LBrace)?;
7286 let name = self.parse_expr()?;
7287 self.expect(Token::Comma)?;
7288 let value = self.parse_expr()?;
7289 self.expect(Token::RBrace)?;
7290 Ok(PipeOp::Header {
7291 name: Box::new(name),
7292 value: Box::new(value),
7293 })
7294 }
7295
7296 Some(Token::Body) => {
7298 self.advance();
7299 self.expect(Token::LBrace)?;
7300 let data = self.parse_expr()?;
7301 self.expect(Token::RBrace)?;
7302 Ok(PipeOp::Body(Box::new(data)))
7303 }
7304
7305 Some(Token::ForAll) => {
7312 self.advance();
7313 if self.current_token() == Some(&Token::LBrace) {
7316 self.advance(); let pred = self.parse_expr()?;
7318 self.expect(Token::RBrace)?;
7319 Ok(PipeOp::All(Box::new(pred)))
7320 } else {
7321 Ok(PipeOp::Universal)
7323 }
7324 }
7325
7326 Some(Token::Exists) => {
7328 self.advance();
7329 self.expect(Token::LBrace)?;
7330 let pred = self.parse_expr()?;
7331 self.expect(Token::RBrace)?;
7332 Ok(PipeOp::Any(Box::new(pred)))
7333 }
7334
7335 Some(Token::Compose) => {
7337 self.advance();
7338 self.expect(Token::LBrace)?;
7339 let f = self.parse_expr()?;
7340 self.expect(Token::RBrace)?;
7341 Ok(PipeOp::Compose(Box::new(f)))
7342 }
7343
7344 Some(Token::Bowtie) => {
7346 self.advance();
7347 self.expect(Token::LBrace)?;
7348 let other = self.parse_expr()?;
7349 self.expect(Token::RBrace)?;
7350 Ok(PipeOp::Zip(Box::new(other)))
7351 }
7352
7353 Some(Token::Integral) => {
7355 self.advance();
7356 self.expect(Token::LBrace)?;
7357 let f = self.parse_expr()?;
7358 self.expect(Token::RBrace)?;
7359 Ok(PipeOp::Scan(Box::new(f)))
7360 }
7361
7362 Some(Token::Partial) => {
7364 self.advance();
7365 Ok(PipeOp::Diff)
7366 }
7367
7368 Some(Token::Nabla) => {
7370 self.advance();
7371 self.expect(Token::LBrace)?;
7372 let var = self.parse_expr()?;
7373 self.expect(Token::RBrace)?;
7374 Ok(PipeOp::Gradient(Box::new(var)))
7375 }
7376
7377 Some(Token::GradeUp) => {
7379 self.advance();
7380 Ok(PipeOp::SortAsc)
7381 }
7382
7383 Some(Token::GradeDown) => {
7385 self.advance();
7386 Ok(PipeOp::SortDesc)
7387 }
7388
7389 Some(Token::Rotate) => {
7391 self.advance();
7392 Ok(PipeOp::Reverse)
7393 }
7394
7395 Some(Token::CycleArrow) => {
7397 self.advance();
7398 self.expect(Token::LBrace)?;
7399 let n = self.parse_expr()?;
7400 self.expect(Token::RBrace)?;
7401 Ok(PipeOp::Cycle(Box::new(n)))
7402 }
7403
7404 Some(Token::QuadDiamond) => {
7406 self.advance();
7407 self.expect(Token::LBrace)?;
7408 let n = self.parse_expr()?;
7409 self.expect(Token::RBrace)?;
7410 Ok(PipeOp::Windows(Box::new(n)))
7411 }
7412
7413 Some(Token::SquaredPlus) => {
7415 self.advance();
7416 self.expect(Token::LBrace)?;
7417 let n = self.parse_expr()?;
7418 self.expect(Token::RBrace)?;
7419 Ok(PipeOp::Chunks(Box::new(n)))
7420 }
7421
7422 Some(Token::ElementSmallVerticalBar) => {
7424 self.advance();
7425 Ok(PipeOp::Flatten)
7426 }
7427
7428 Some(Token::Union) => {
7430 self.advance();
7431 Ok(PipeOp::Unique)
7432 }
7433
7434 Some(Token::Iota) => {
7436 self.advance();
7437 Ok(PipeOp::Enumerate)
7438 }
7439
7440 Some(Token::Amp) => {
7445 let expr = self.parse_prefix_expr()?;
7447 Ok(PipeOp::Call(Box::new(expr)))
7448 }
7449
7450 Some(Token::LBrace) => {
7453 self.advance();
7454 self.skip_comments();
7455 let body = if self.looks_like_morpheme_closure() {
7456 self.parse_morpheme_closure()?
7457 } else {
7458 self.parse_expr()?
7459 };
7460 self.expect(Token::RBrace)?;
7461 Ok(PipeOp::Call(Box::new(body)))
7462 }
7463
7464 Some(token) => Err(ParseError::UnexpectedToken {
7465 expected: "pipe operation".to_string(),
7466 found: token.clone(),
7467 span: self.current_span(),
7468 }),
7469 None => Err(ParseError::UnexpectedEof),
7470 }
7471 }
7472
7473 fn looks_like_morpheme_closure(&mut self) -> bool {
7475 if matches!(self.current_token(), Some(Token::Ident(_)) | Some(Token::Underscore)) {
7477 match self.peek_next() {
7479 Some(Token::FatArrow) => return true,
7480 Some(Token::Comma) => return true,
7483 Some(Token::Tilde) | Some(Token::Lozenge) | Some(Token::Interrobang) => {
7485 if matches!(self.peek_n(1), Some(Token::FatArrow)) {
7487 return true;
7488 }
7489 }
7490 _ => {}
7491 }
7492 }
7493 if matches!(self.current_token(), Some(Token::Amp)) {
7495 if matches!(self.peek_next(), Some(Token::Ident(_))) {
7497 match self.peek_n(1) {
7499 Some(Token::FatArrow) => return true,
7500 Some(Token::Tilde) | Some(Token::Lozenge) | Some(Token::Interrobang) => {
7501 if matches!(self.peek_n(2), Some(Token::FatArrow)) {
7502 return true;
7503 }
7504 }
7505 _ => {}
7506 }
7507 } else if matches!(self.peek_next(), Some(Token::Mut)) {
7508 return true;
7510 }
7511 }
7512 if matches!(self.current_token(), Some(Token::LParen)) {
7515 return true;
7518 }
7519 false
7520 }
7521
7522 fn parse_morpheme_closure(&mut self) -> ParseResult<Expr> {
7526 let params = if self.check(&Token::LParen) {
7527 self.advance();
7529 let mut patterns = Vec::new();
7530 while !self.check(&Token::RParen) {
7531 let pat = self.parse_pattern()?;
7532 patterns.push(pat);
7533 if !self.consume_if(&Token::Comma) {
7534 break;
7535 }
7536 }
7537 self.expect(Token::RParen)?;
7538 vec![ClosureParam { pattern: Pattern::Tuple(patterns), ty: None }]
7540 } else if self.check(&Token::Amp) {
7541 vec![ClosureParam { pattern: self.parse_pattern()?, ty: None }]
7543 } else if self.check(&Token::Underscore) {
7544 self.advance();
7546 vec![ClosureParam { pattern: Pattern::Wildcard, ty: None }]
7547 } else {
7548 let name = self.parse_ident()?;
7550 let first = ClosureParam {
7551 pattern: Pattern::Ident {
7552 mutable: false,
7553 name,
7554 evidentiality: None,
7555 },
7556 ty: None,
7557 };
7558 let mut params = vec![first];
7559 while self.consume_if(&Token::Comma) {
7561 let name = self.parse_ident()?;
7562 params.push(ClosureParam {
7563 pattern: Pattern::Ident {
7564 mutable: false,
7565 name,
7566 evidentiality: None,
7567 },
7568 ty: None,
7569 });
7570 }
7571 params
7572 };
7573 if !self.consume_if(&Token::FatArrow) {
7575 self.expect(Token::Pipe)?;
7576 }
7577 self.skip_comments();
7579 let body = {
7587 let mut stmts = Vec::new();
7589 loop {
7590 self.skip_comments();
7591 if self.check(&Token::RBrace) {
7592 break;
7593 }
7594 if self.check(&Token::Let) {
7595 stmts.push(self.parse_let_stmt()?);
7596 } else if self.check(&Token::Return) || self.check(&Token::Tensor)
7597 || self.check(&Token::CycleArrow)
7598 {
7599 break;
7601 } else {
7602 let expr = self.parse_expr()?;
7604 self.skip_comments();
7606 if self.consume_if(&Token::Semi) {
7607 stmts.push(Stmt::Expr(expr));
7609 } else if self.check(&Token::RBrace) {
7610 if stmts.is_empty() {
7612 return Ok(Expr::Closure {
7614 params: params.clone(),
7615 return_type: None,
7616 body: Box::new(expr),
7617 is_move: false,
7618 });
7619 }
7620 return Ok(Expr::Closure {
7621 params: params.clone(),
7622 return_type: None,
7623 body: Box::new(Expr::Block(Block {
7624 stmts,
7625 expr: Some(Box::new(expr)),
7626 })),
7627 is_move: false,
7628 });
7629 } else {
7630 stmts.push(Stmt::Expr(expr));
7633 }
7634 }
7635 }
7636 Expr::Block(Block { stmts, expr: None })
7638 };
7639 Ok(Expr::Closure {
7640 params,
7641 return_type: None,
7642 body: Box::new(body),
7643 is_move: false,
7644 })
7645 }
7646
7647 fn parse_morpheme_kind(&mut self) -> ParseResult<MorphemeKind> {
7648 match self.current_token() {
7649 Some(Token::Tau) => {
7650 self.advance();
7651 Ok(MorphemeKind::Transform)
7652 }
7653 Some(Token::Phi) => {
7654 self.advance();
7655 Ok(MorphemeKind::Filter)
7656 }
7657 Some(Token::Sigma) => {
7658 self.advance();
7659 Ok(MorphemeKind::Sort)
7660 }
7661 Some(Token::Rho) => {
7662 self.advance();
7663 Ok(MorphemeKind::Reduce)
7664 }
7665 Some(Token::Lambda) => {
7666 self.advance();
7667 Ok(MorphemeKind::Lambda)
7668 }
7669 Some(Token::Pi) => {
7670 self.advance();
7671 Ok(MorphemeKind::Product)
7672 }
7673 _ => Err(ParseError::Custom("expected morpheme".to_string())),
7674 }
7675 }
7676
7677 fn parse_block_or_closure(&mut self) -> ParseResult<Expr> {
7678 self.expect(Token::LBrace)?;
7679 self.skip_comments();
7680
7681 let is_anon_struct = matches!(self.current_token(), Some(Token::Ident(_)))
7684 && matches!(self.peek_next(), Some(Token::Colon));
7685
7686 if is_anon_struct {
7687 let (fields, rest) = self.parse_struct_fields()?;
7688 self.expect(Token::RBrace)?;
7689 let anon_path = TypePath {
7690 segments: vec![PathSegment {
7691 ident: Ident {
7692 name: "__anonymous__".to_string(),
7693 evidentiality: None,
7694 affect: None,
7695 span: Span::new(0, 0),
7696 },
7697 generics: None,
7698 }],
7699 };
7700 return Ok(Expr::Struct {
7701 path: anon_path,
7702 fields,
7703 rest,
7704 });
7705 }
7706
7707 let is_simple_closure = matches!(self.current_token(), Some(Token::Ident(_)))
7710 && matches!(self.peek_next(), Some(Token::FatArrow));
7711
7712 if is_simple_closure {
7713 let name = self.parse_ident()?;
7714 self.expect(Token::FatArrow)?;
7715 self.skip_comments();
7716 let body = self.parse_expr()?;
7717 self.skip_comments();
7718 self.expect(Token::RBrace)?;
7719 return Ok(Expr::Closure {
7720 params: vec![ClosureParam {
7721 pattern: Pattern::Ident {
7722 mutable: false,
7723 name,
7724 evidentiality: None,
7725 },
7726 ty: None,
7727 }],
7728 return_type: None,
7729 body: Box::new(body),
7730 is_move: false,
7731 });
7732 }
7733
7734 let mut stmts = Vec::new();
7736 let mut final_expr = None;
7737
7738 while !self.check(&Token::RBrace) && !self.is_eof() {
7739 self.skip_comments();
7740 if self.check(&Token::RBrace) {
7741 break;
7742 }
7743
7744 if self.check(&Token::Hash) || self.check(&Token::At) {
7746 let mut attrs = Vec::new();
7748 while self.check(&Token::Hash) || self.check(&Token::At) {
7749 attrs.push(self.parse_outer_attribute()?);
7750 self.skip_comments();
7751 }
7752
7753 if !self.evaluate_cfg_condition(&attrs) {
7755 if self.is_item_start() {
7757 let _ = self.parse_item()?; } else if self.check(&Token::Let) {
7759 let _ = self.parse_let_stmt()?; } else {
7761 let _ = self.parse_expr()?; self.skip_comments();
7763 self.consume_if(&Token::Semi); }
7765 continue; }
7767
7768 if self.is_item_start() {
7770 let item = self.parse_item()?;
7772 stmts.push(Stmt::Item(Box::new(item.node)));
7773 } else if self.check(&Token::Let) {
7774 stmts.push(self.parse_let_stmt()?);
7776 } else {
7777 let expr = self.parse_expr()?;
7779 self.skip_comments();
7780 if self.consume_if(&Token::Semi) {
7781 stmts.push(Stmt::Semi(expr));
7782 } else if self.check(&Token::RBrace) {
7783 final_expr = Some(Box::new(expr));
7784 } else {
7785 stmts.push(Stmt::Expr(expr));
7786 }
7787 }
7788 } else if self.is_item_start() {
7789 let item = self.parse_item()?;
7790 stmts.push(Stmt::Item(Box::new(item.node)));
7791 } else if self.check(&Token::Let) {
7792 stmts.push(self.parse_let_stmt()?);
7793 } else {
7794 let expr = self.parse_expr()?;
7795 self.skip_comments();
7796 if self.consume_if(&Token::Semi) {
7797 stmts.push(Stmt::Semi(expr));
7798 } else if self.check(&Token::RBrace) {
7799 final_expr = Some(Box::new(expr));
7800 } else {
7801 stmts.push(Stmt::Expr(expr));
7802 }
7803 }
7804 }
7805
7806 self.expect(Token::RBrace)?;
7807
7808 Ok(Expr::Block(Block {
7809 stmts,
7810 expr: final_expr,
7811 }))
7812 }
7813
7814 pub(crate) fn parse_block(&mut self) -> ParseResult<Block> {
7815 match self.parse_block_or_closure()? {
7816 Expr::Block(block) => Ok(block),
7817 _ => Err(ParseError::Custom("expected block".to_string())),
7818 }
7819 }
7820
7821 fn parse_let_stmt(&mut self) -> ParseResult<Stmt> {
7822 self.expect(Token::Let)?;
7823 let pattern = self.parse_pattern()?;
7824 let ty = if self.consume_if(&Token::Colon) {
7825 Some(self.parse_type()?)
7826 } else {
7827 None
7828 };
7829 let init = if self.consume_if(&Token::Eq) {
7830 Some(self.parse_expr()?)
7831 } else {
7832 None
7833 };
7834
7835 if self.consume_if(&Token::Else) {
7837 let else_branch = Box::new(Expr::Block(self.parse_block()?));
7838 self.consume_if(&Token::Semi);
7840 Ok(Stmt::LetElse {
7841 pattern,
7842 ty,
7843 init: init.ok_or_else(|| ParseError::Custom("let-else requires initializer".to_string()))?,
7844 else_branch,
7845 })
7846 } else {
7847 if !self.consume_if(&Token::Semi) {
7850 if !self.can_start_stmt() && !self.check(&Token::RBrace) {
7851 self.check_deprecated()?;
7853 return Err(ParseError::UnexpectedToken {
7854 expected: "`;` or new statement".to_string(),
7855 found: self.current_token().cloned().unwrap_or(Token::Semi),
7856 span: self.current_span(),
7857 });
7858 }
7859 }
7860 Ok(Stmt::Let { pattern, ty, init })
7861 }
7862 }
7863
7864 fn parse_if_expr(&mut self) -> ParseResult<Expr> {
7865 self.expect(Token::If)?;
7866
7867 let condition = if self.consume_if(&Token::Let) {
7869 let pattern = self.parse_or_pattern()?;
7870 self.expect(Token::Eq)?;
7871 let expr = self.parse_condition()?;
7872 Expr::Let {
7873 pattern,
7874 value: Box::new(expr),
7875 }
7876 } else {
7877 self.parse_condition()?
7878 };
7879
7880 let then_branch = self.parse_block()?;
7881 self.skip_comments(); let else_branch = if self.consume_if(&Token::Else) {
7883 if self.check(&Token::If) {
7884 Some(Box::new(self.parse_if_expr()?))
7885 } else {
7886 Some(Box::new(Expr::Block(self.parse_block()?)))
7887 }
7888 } else {
7889 None
7890 };
7891
7892 Ok(Expr::If {
7893 condition: Box::new(condition),
7894 then_branch,
7895 else_branch,
7896 })
7897 }
7898
7899 fn parse_match_expr(&mut self) -> ParseResult<Expr> {
7900 self.expect(Token::Match)?;
7901 let expr = self.parse_condition()?;
7903 self.expect(Token::LBrace)?;
7904
7905 let mut arms = Vec::new();
7906 while !self.check(&Token::RBrace) && !self.is_eof() {
7907 loop {
7909 if matches!(
7910 self.current_token(),
7911 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
7912 ) {
7913 self.advance();
7914 } else if self.check(&Token::Hash) {
7915 self.skip_attribute()?;
7917 } else {
7918 break;
7919 }
7920 }
7921 if self.check(&Token::RBrace) {
7922 break;
7923 }
7924 let pattern = self.parse_or_pattern()?;
7925 let guard = if self.consume_if(&Token::If) {
7926 Some(self.parse_condition()?)
7927 } else {
7928 None
7929 };
7930 self.expect(Token::FatArrow)?;
7931 let body = self.parse_expr()?;
7932 arms.push(MatchArm {
7933 pattern,
7934 guard,
7935 body,
7936 });
7937 self.consume_if(&Token::Comma);
7940 while matches!(
7942 self.current_token(),
7943 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
7944 ) {
7945 self.advance();
7946 }
7947 }
7948
7949 self.expect(Token::RBrace)?;
7950
7951 Ok(Expr::Match {
7952 expr: Box::new(expr),
7953 arms,
7954 })
7955 }
7956
7957 fn parse_or_pattern(&mut self) -> ParseResult<Pattern> {
7961 let first = self.parse_pattern()?;
7962
7963 if self.check(&Token::Pipe) {
7965 let mut patterns = vec![first];
7966 while self.consume_if(&Token::Pipe) {
7967 patterns.push(self.parse_pattern()?);
7968 }
7969 Ok(Pattern::Or(patterns))
7970 } else {
7971 Ok(first)
7972 }
7973 }
7974
7975 fn parse_pattern(&mut self) -> ParseResult<Pattern> {
7976 let prefix_ev = match self.current_token() {
7978 Some(Token::Question) => {
7979 self.advance();
7980 Some(Evidentiality::Uncertain)
7981 }
7982 Some(Token::Bang) => {
7983 self.advance();
7984 Some(Evidentiality::Known)
7985 }
7986 Some(Token::Tilde) => {
7987 self.advance();
7988 Some(Evidentiality::Reported)
7989 }
7990 Some(Token::Lozenge) => {
7991 self.advance();
7992 Some(Evidentiality::Predicted)
7993 }
7994 Some(Token::Interrobang) => {
7995 self.advance();
7996 Some(Evidentiality::Paradox)
7997 }
7998 _ => None,
7999 };
8000
8001 if let Some(ev) = prefix_ev {
8004 let inner_pattern = self.parse_pattern_base()?;
8006 return match inner_pattern {
8007 Pattern::Ident { mutable, name, evidentiality: _ } => {
8008 Ok(Pattern::Ident {
8010 mutable,
8011 name,
8012 evidentiality: Some(ev),
8013 })
8014 }
8015 Pattern::Wildcard => {
8016 let span = self.current_span();
8019 Ok(Pattern::Ident {
8020 mutable: false,
8021 name: Ident {
8022 name: "_".to_string(),
8023 evidentiality: None,
8024 affect: None,
8025 span,
8026 },
8027 evidentiality: Some(ev),
8028 })
8029 }
8030 other => {
8031 Ok(other)
8036 }
8037 };
8038 }
8039
8040 self.parse_pattern_base()
8041 }
8042
8043 fn parse_pattern_base(&mut self) -> ParseResult<Pattern> {
8045
8046 match self.current_token().cloned() {
8047 Some(Token::Underscore) => {
8048 let span = self.current_span();
8049 self.advance();
8050 let ev = self.parse_evidentiality_opt();
8052 if ev.is_some() {
8053 Ok(Pattern::Ident {
8055 mutable: false,
8056 name: Ident {
8057 name: "_".to_string(),
8058 evidentiality: None,
8059 affect: None,
8060 span,
8061 },
8062 evidentiality: ev,
8063 })
8064 } else {
8065 Ok(Pattern::Wildcard)
8066 }
8067 }
8068 Some(Token::DotDot) => {
8069 self.advance();
8070 Ok(Pattern::Rest)
8071 }
8072 Some(Token::Mut) => {
8073 self.advance();
8074 let name = if self.check(&Token::SelfLower) {
8076 let span = self.current_span();
8077 self.advance();
8078 Ident {
8079 name: "self".to_string(),
8080 evidentiality: None,
8081 affect: None,
8082 span,
8083 }
8084 } else {
8085 self.parse_ident()?
8086 };
8087 let evidentiality = self.parse_evidentiality_opt();
8088 Ok(Pattern::Ident {
8089 mutable: true,
8090 name,
8091 evidentiality,
8092 })
8093 }
8094 Some(Token::Ref) => {
8096 self.advance();
8097 let mutable = self.consume_if(&Token::Mut);
8098 let name = self.parse_ident()?;
8099 let evidentiality = self.parse_evidentiality_opt();
8100 Ok(Pattern::RefBinding {
8101 mutable,
8102 name,
8103 evidentiality,
8104 })
8105 }
8106 Some(Token::Amp) => {
8108 self.advance();
8109 if matches!(self.current_token(), Some(Token::Lifetime(_))) {
8111 self.advance();
8112 }
8113 let mutable = self.consume_if(&Token::Mut);
8114 let inner = self.parse_pattern()?;
8115 Ok(Pattern::Ref {
8116 mutable,
8117 pattern: Box::new(inner),
8118 })
8119 }
8120 Some(Token::AndAnd) => {
8122 self.advance();
8123 let inner = self.parse_pattern()?;
8124 let inner_ref = Pattern::Ref {
8126 mutable: false,
8127 pattern: Box::new(inner),
8128 };
8129 Ok(Pattern::Ref {
8130 mutable: false,
8131 pattern: Box::new(inner_ref),
8132 })
8133 }
8134 Some(Token::LParen) => {
8135 self.advance();
8136 let mut patterns = Vec::new();
8137 while !self.check(&Token::RParen) {
8138 patterns.push(self.parse_pattern()?);
8139 if !self.consume_if(&Token::Comma) {
8140 break;
8141 }
8142 }
8143 self.expect(Token::RParen)?;
8144 let _ev = self.parse_evidentiality_opt();
8146 Ok(Pattern::Tuple(patterns))
8149 }
8150 Some(Token::LBracket) => {
8151 self.advance();
8152 let mut patterns = Vec::new();
8153 while !self.check(&Token::RBracket) {
8154 patterns.push(self.parse_pattern()?);
8155 if !self.consume_if(&Token::Comma) {
8156 break;
8157 }
8158 }
8159 self.expect(Token::RBracket)?;
8160 Ok(Pattern::Slice(patterns))
8161 }
8162 Some(Token::IntLit(_))
8163 | Some(Token::HexLit(_))
8164 | Some(Token::OctalLit(_))
8165 | Some(Token::BinaryLit(_))
8166 | Some(Token::FloatLit(_))
8167 | Some(Token::StringLit(_))
8168 | Some(Token::CharLit(_))
8169 | Some(Token::True)
8170 | Some(Token::False)
8171 | Some(Token::Null) => {
8172 let lit = self.parse_literal()?;
8173 if self.check(&Token::DotDot) || self.check(&Token::DotDotEq) {
8175 let inclusive = self.consume_if(&Token::DotDotEq);
8176 if !inclusive {
8177 self.advance(); }
8179 let end = if matches!(
8181 self.current_token(),
8182 Some(Token::IntLit(_)) | Some(Token::HexLit(_)) | Some(Token::OctalLit(_))
8183 | Some(Token::BinaryLit(_)) | Some(Token::CharLit(_))
8184 ) {
8185 let end_lit = self.parse_literal()?;
8186 Some(Box::new(Pattern::Literal(end_lit)))
8187 } else {
8188 None
8189 };
8190 Ok(Pattern::Range {
8191 start: Some(Box::new(Pattern::Literal(lit))),
8192 end,
8193 inclusive,
8194 })
8195 } else {
8196 Ok(Pattern::Literal(lit))
8197 }
8198 }
8199 Some(Token::SelfUpper) => {
8201 let span = self.current_span();
8202 self.advance();
8203
8204 let mut segments = vec![PathSegment {
8206 ident: Ident {
8207 name: "Self".to_string(),
8208 evidentiality: None,
8209 affect: None,
8210 span,
8211 },
8212 generics: None,
8213 }];
8214
8215 while self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::MiddleDot) {
8217 let segment_name = self.parse_ident()?;
8218 segments.push(PathSegment {
8219 ident: segment_name,
8220 generics: None,
8221 });
8222 }
8223
8224 let path = TypePath { segments };
8225
8226 if self.check(&Token::LParen) {
8228 self.advance();
8229 let mut fields = Vec::new();
8230 while !self.check(&Token::RParen) {
8231 fields.push(self.parse_pattern()?);
8232 if !self.consume_if(&Token::Comma) {
8233 break;
8234 }
8235 }
8236 self.expect(Token::RParen)?;
8237 return Ok(Pattern::TupleStruct { path, fields });
8238 }
8239
8240 if self.check(&Token::LBrace) {
8242 self.advance();
8243 let mut fields = Vec::new();
8244 let mut rest = false;
8245 while !self.check(&Token::RBrace) {
8246 while matches!(
8247 self.current_token(),
8248 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
8249 ) {
8250 self.advance();
8251 }
8252 if self.check(&Token::RBrace) {
8253 break;
8254 }
8255 if self.consume_if(&Token::DotDot) {
8256 rest = true;
8257 if !self.consume_if(&Token::Comma) {
8258 break;
8259 }
8260 continue;
8261 }
8262 let has_ref = self.consume_if(&Token::Ref);
8264 let has_mut = has_ref && self.consume_if(&Token::Mut);
8265
8266 let field_name = self.parse_ident()?;
8267 let pattern = if self.consume_if(&Token::Colon) {
8268 Some(self.parse_pattern()?)
8269 } else if has_ref {
8270 Some(Pattern::RefBinding {
8272 mutable: has_mut,
8273 name: field_name.clone(),
8274 evidentiality: None,
8275 })
8276 } else {
8277 None
8278 };
8279 fields.push(FieldPattern {
8280 name: field_name,
8281 pattern,
8282 });
8283 if !self.consume_if(&Token::Comma) {
8284 break;
8285 }
8286 }
8287 self.expect(Token::RBrace)?;
8288 return Ok(Pattern::Struct { path, fields, rest });
8289 }
8290
8291 return Ok(Pattern::Path(path));
8293 }
8294 Some(Token::Crate) | Some(Token::SelfLower) | Some(Token::Super) => {
8296 let keyword = self.current_token().cloned();
8297 let span = self.current_span();
8298 self.advance();
8299
8300 if !self.consume_if(&Token::MiddleDot) && !self.consume_if(&Token::MiddleDot) {
8302 if matches!(keyword, Some(Token::SelfLower)) {
8304 return Ok(Pattern::Ident {
8305 mutable: false,
8306 name: Ident {
8307 name: "self".to_string(),
8308 evidentiality: None,
8309 affect: None,
8310 span,
8311 },
8312 evidentiality: self.parse_evidentiality_opt(),
8313 });
8314 }
8315 return Err(ParseError::Custom("expected :: after crate/super in path pattern".to_string()));
8316 }
8317
8318 let keyword_name = match keyword {
8321 Some(Token::Crate) => "tome",
8322 Some(Token::SelfLower) => "self",
8323 Some(Token::Super) => "super",
8324 _ => unreachable!(),
8325 };
8326 let mut segments = vec![PathSegment {
8327 ident: Ident {
8328 name: keyword_name.to_string(),
8329 evidentiality: None,
8330 affect: None,
8331 span,
8332 },
8333 generics: None,
8334 }];
8335
8336 loop {
8338 let segment_name = self.parse_ident()?;
8339 segments.push(PathSegment {
8340 ident: segment_name,
8341 generics: None,
8342 });
8343
8344 if !self.consume_if(&Token::MiddleDot) && !self.consume_if(&Token::MiddleDot) {
8345 break;
8346 }
8347 }
8348
8349 let path = TypePath { segments };
8350
8351 if self.check(&Token::LParen) {
8353 self.advance();
8354 let mut fields = Vec::new();
8355 while !self.check(&Token::RParen) {
8356 fields.push(self.parse_pattern()?);
8357 if !self.consume_if(&Token::Comma) {
8358 break;
8359 }
8360 }
8361 self.expect(Token::RParen)?;
8362 return Ok(Pattern::TupleStruct { path, fields });
8363 }
8364
8365 if self.check(&Token::LBrace) {
8367 self.advance();
8368 let mut fields = Vec::new();
8369 let mut rest = false;
8370 while !self.check(&Token::RBrace) {
8371 while matches!(
8372 self.current_token(),
8373 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
8374 ) {
8375 self.advance();
8376 }
8377 if self.check(&Token::RBrace) {
8378 break;
8379 }
8380 if self.consume_if(&Token::DotDot) {
8381 rest = true;
8382 if !self.consume_if(&Token::Comma) {
8383 break;
8384 }
8385 continue;
8386 }
8387 let has_ref = self.consume_if(&Token::Ref);
8389 let has_mut = has_ref && self.consume_if(&Token::Mut);
8390
8391 let field_name = self.parse_ident()?;
8392 let pattern = if self.consume_if(&Token::Colon) {
8393 Some(self.parse_pattern()?)
8394 } else if has_ref {
8395 Some(Pattern::RefBinding {
8396 mutable: has_mut,
8397 name: field_name.clone(),
8398 evidentiality: None,
8399 })
8400 } else {
8401 None
8402 };
8403 fields.push(FieldPattern {
8404 name: field_name,
8405 pattern,
8406 });
8407 if !self.consume_if(&Token::Comma) {
8408 break;
8409 }
8410 }
8411 self.expect(Token::RBrace)?;
8412 return Ok(Pattern::Struct { path, fields, rest });
8413 }
8414
8415 return Ok(Pattern::Path(path));
8417 }
8418 Some(Token::Ident(_)) => {
8419 let name = self.parse_ident()?;
8420
8421 if self.consume_if(&Token::MiddleDot) || self.consume_if(&Token::MiddleDot) {
8423 let mut segments = vec![PathSegment {
8425 ident: name,
8426 generics: None,
8427 }];
8428
8429 loop {
8431 let segment_name = self.parse_ident()?;
8432 segments.push(PathSegment {
8433 ident: segment_name,
8434 generics: None,
8435 });
8436
8437 if !self.consume_if(&Token::MiddleDot) && !self.consume_if(&Token::MiddleDot) {
8438 break;
8439 }
8440 }
8441
8442 let path = TypePath { segments };
8443
8444 if self.check(&Token::LParen) {
8446 self.advance();
8447 let mut fields = Vec::new();
8448 while !self.check(&Token::RParen) {
8449 fields.push(self.parse_pattern()?);
8450 if !self.consume_if(&Token::Comma) {
8451 break;
8452 }
8453 }
8454 self.expect(Token::RParen)?;
8455 return Ok(Pattern::TupleStruct { path, fields });
8456 }
8457
8458 if self.check(&Token::LBrace) {
8460 self.advance();
8461 let mut fields = Vec::new();
8462 let mut rest = false;
8463 while !self.check(&Token::RBrace) {
8464 while matches!(
8466 self.current_token(),
8467 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
8468 ) {
8469 self.advance();
8470 }
8471 if self.check(&Token::RBrace) {
8472 break;
8473 }
8474
8475 if self.consume_if(&Token::DotDot) {
8477 rest = true;
8478 if !self.consume_if(&Token::Comma) {
8479 break;
8480 }
8481 continue;
8482 }
8483
8484 let has_ref = self.consume_if(&Token::Ref);
8486 let has_mut = has_ref && self.consume_if(&Token::Mut);
8487
8488 let field_name = self.parse_ident()?;
8489 let pattern = if self.consume_if(&Token::Colon) {
8490 Some(self.parse_pattern()?)
8491 } else if has_ref {
8492 Some(Pattern::RefBinding {
8493 mutable: has_mut,
8494 name: field_name.clone(),
8495 evidentiality: None,
8496 })
8497 } else {
8498 None
8500 };
8501 fields.push(FieldPattern {
8502 name: field_name,
8503 pattern,
8504 });
8505
8506 if !self.consume_if(&Token::Comma) {
8507 break;
8508 }
8509 }
8510 self.expect(Token::RBrace)?;
8511 return Ok(Pattern::Struct { path, fields, rest });
8512 }
8513
8514 return Ok(Pattern::Path(path));
8516 }
8517
8518 if self.check(&Token::LBrace) {
8520 let path = TypePath {
8522 segments: vec![PathSegment {
8523 ident: name,
8524 generics: None,
8525 }],
8526 };
8527 self.advance();
8528 let mut fields = Vec::new();
8529 let mut rest = false;
8530 while !self.check(&Token::RBrace) {
8531 while matches!(
8532 self.current_token(),
8533 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
8534 ) {
8535 self.advance();
8536 }
8537 if self.check(&Token::RBrace) {
8538 break;
8539 }
8540 if self.consume_if(&Token::DotDot) {
8541 rest = true;
8542 break;
8543 }
8544 let has_ref = self.consume_if(&Token::Ref);
8546 let has_mut = has_ref && self.consume_if(&Token::Mut);
8547
8548 let field_name = self.parse_ident()?;
8549 let pattern = if self.consume_if(&Token::Colon) {
8550 Some(self.parse_pattern()?)
8551 } else if has_ref {
8552 Some(Pattern::RefBinding {
8553 mutable: has_mut,
8554 name: field_name.clone(),
8555 evidentiality: None,
8556 })
8557 } else {
8558 None
8559 };
8560 fields.push(FieldPattern {
8561 name: field_name,
8562 pattern,
8563 });
8564 if !self.consume_if(&Token::Comma) {
8565 break;
8566 }
8567 }
8568 self.expect(Token::RBrace)?;
8569 return Ok(Pattern::Struct { path, fields, rest });
8570 }
8571
8572 if self.check(&Token::LParen) {
8574 let path = TypePath {
8575 segments: vec![PathSegment {
8576 ident: name,
8577 generics: None,
8578 }],
8579 };
8580 self.advance();
8581 let mut fields = Vec::new();
8582 while !self.check(&Token::RParen) {
8583 fields.push(self.parse_pattern()?);
8584 if !self.consume_if(&Token::Comma) {
8585 break;
8586 }
8587 }
8588 self.expect(Token::RParen)?;
8589 return Ok(Pattern::TupleStruct { path, fields });
8590 }
8591
8592 let evidentiality = self.parse_evidentiality_opt();
8594 Ok(Pattern::Ident {
8595 mutable: false,
8596 name,
8597 evidentiality,
8598 })
8599 }
8600 Some(Token::SelfLower) => {
8601 let span = self.current_span();
8603 self.advance();
8604 Ok(Pattern::Ident {
8605 mutable: false,
8606 name: Ident {
8607 name: "self".to_string(),
8608 evidentiality: None,
8609 affect: None,
8610 span,
8611 },
8612 evidentiality: None,
8613 })
8614 }
8615 Some(ref token) if Self::keyword_as_ident(token).is_some() => {
8617 let name = self.parse_ident()?;
8618 let evidentiality = self.parse_evidentiality_opt();
8619 Ok(Pattern::Ident {
8620 mutable: false,
8621 name,
8622 evidentiality,
8623 })
8624 }
8625 Some(token) => Err(ParseError::UnexpectedToken {
8626 expected: "pattern".to_string(),
8627 found: token,
8628 span: self.current_span(),
8629 }),
8630 None => Err(ParseError::UnexpectedEof),
8631 }
8632 }
8633
8634 fn parse_literal(&mut self) -> ParseResult<Literal> {
8635 match self.current_token().cloned() {
8636 Some(Token::IntLit(s)) => {
8637 self.advance();
8638 Ok(Literal::Int {
8639 value: s,
8640 base: NumBase::Decimal,
8641 suffix: None,
8642 })
8643 }
8644 Some(Token::HexLit(s)) => {
8645 self.advance();
8646 Ok(Literal::Int {
8647 value: s,
8648 base: NumBase::Hex,
8649 suffix: None,
8650 })
8651 }
8652 Some(Token::OctalLit(s)) => {
8653 self.advance();
8654 Ok(Literal::Int {
8655 value: s,
8656 base: NumBase::Octal,
8657 suffix: None,
8658 })
8659 }
8660 Some(Token::BinaryLit(s)) => {
8661 self.advance();
8662 Ok(Literal::Int {
8663 value: s,
8664 base: NumBase::Binary,
8665 suffix: None,
8666 })
8667 }
8668 Some(Token::FloatLit(s)) => {
8669 self.advance();
8670 let (value, suffix) = Self::strip_float_suffix(&s);
8671 Ok(Literal::Float { value, suffix })
8672 }
8673 Some(Token::StringLit(s)) => {
8674 self.advance();
8675 Ok(Literal::String(s))
8676 }
8677 Some(Token::CharLit(c)) => {
8678 self.advance();
8679 Ok(Literal::Char(c))
8680 }
8681 Some(Token::True) => {
8682 self.advance();
8683 Ok(Literal::Bool(true))
8684 }
8685 Some(Token::False) => {
8686 self.advance();
8687 Ok(Literal::Bool(false))
8688 }
8689 Some(Token::Null) => {
8690 self.advance();
8691 Ok(Literal::Null)
8692 }
8693 _ => Err(ParseError::Custom("expected literal".to_string())),
8694 }
8695 }
8696
8697 fn expr_to_incorporation_segment(&self, expr: Expr) -> ParseResult<IncorporationSegment> {
8702 match expr {
8703 Expr::Path(path) if path.segments.len() == 1 => Ok(IncorporationSegment {
8704 name: path.segments[0].ident.clone(),
8705 args: None,
8706 }),
8707 Expr::Call { func, args } => {
8708 match *func {
8709 Expr::Path(path) => {
8710 if let Some(last_seg) = path.segments.last() {
8713 return Ok(IncorporationSegment {
8714 name: last_seg.ident.clone(),
8715 args: Some(args),
8716 });
8717 }
8718 Err(ParseError::Custom(
8719 "incorporation chain: empty path".to_string(),
8720 ))
8721 }
8722 Expr::Field { expr, field } => {
8724 Ok(IncorporationSegment {
8725 name: field.clone(),
8726 args: Some(std::iter::once(*expr).chain(args).collect()),
8727 })
8728 }
8729 _ => Err(ParseError::Custom(
8730 "incorporation chain must start with identifier or call".to_string(),
8731 )),
8732 }
8733 }
8734 Expr::Field { expr, field } => {
8737 Ok(IncorporationSegment {
8740 name: field.clone(),
8741 args: Some(vec![*expr]), })
8743 }
8744 Expr::Literal(_) => {
8747 Ok(IncorporationSegment {
8748 name: Ident {
8749 name: "__lit__".to_string(),
8750 evidentiality: None,
8751 affect: None,
8752 span: crate::span::Span::default(),
8753 },
8754 args: Some(vec![expr]),
8755 })
8756 }
8757 Expr::Unary { .. } => {
8760 Ok(IncorporationSegment {
8761 name: Ident {
8762 name: "__unary__".to_string(),
8763 evidentiality: None,
8764 affect: None,
8765 span: crate::span::Span::default(),
8766 },
8767 args: Some(vec![expr]),
8768 })
8769 }
8770 Expr::Index { expr: base, index } => {
8772 Ok(IncorporationSegment {
8773 name: Ident {
8774 name: "__index__".to_string(),
8775 evidentiality: None,
8776 affect: None,
8777 span: crate::span::Span::default(),
8778 },
8779 args: Some(vec![*base, *index]),
8780 })
8781 }
8782 other => {
8785 Ok(IncorporationSegment {
8786 name: Ident {
8787 name: "__expr__".to_string(),
8788 evidentiality: None,
8789 affect: None,
8790 span: crate::span::Span::default(),
8791 },
8792 args: Some(vec![other]),
8793 })
8794 }
8795 }
8796 }
8797
8798 fn keyword_as_ident(token: &Token) -> Option<&'static str> {
8800 match token {
8801 Token::Packed => Some("packed"),
8803 Token::As => Some("as"),
8804 Token::Type => Some("type"),
8805 Token::Crate => Some("tome"),
8806 Token::Super => Some("super"),
8807 Token::Mod => Some("scroll"),
8808 Token::Use => Some("invoke"),
8809 Token::Pub => Some("pub"),
8810 Token::Const => Some("const"),
8811 Token::Static => Some("static"),
8812 Token::Extern => Some("extern"),
8813 Token::Unsafe => Some("unsafe"),
8814 Token::Async => Some("async"),
8815 Token::Await => Some("await"),
8816 Token::Move => Some("move"),
8817 Token::Dyn => Some("dyn"),
8818 Token::Atomic => Some("atomic"),
8819 Token::Volatile => Some("volatile"),
8820 Token::Naked => Some("naked"),
8821 Token::Connect => Some("connect"),
8822 Token::Close => Some("close"),
8823 Token::Simd => Some("simd"),
8824 Token::Derive => Some("derive"),
8825 Token::On => Some("on"),
8826 Token::Send => Some("send"),
8827 Token::Recv => Some("recv"),
8828 Token::Stream => Some("stream"),
8829 Token::Timeout => Some("timeout"),
8830 Token::Retry => Some("retry"),
8831 Token::Header => Some("header"),
8832 Token::Body => Some("body"),
8833 Token::Http => Some("http"),
8834 Token::Https => Some("https"),
8835 Token::Ws => Some("ws"),
8836 Token::Wss => Some("wss"),
8837 Token::Grpc => Some("grpc"),
8838 Token::Kafka => Some("kafka"),
8839 Token::Amqp => Some("amqp"),
8840 Token::GraphQL => Some("graphql"),
8841 Token::Actor => Some("actor"),
8842 Token::Saga => Some("saga"),
8843 Token::Scope => Some("scope"),
8844 Token::Rune => Some("rune"),
8845 Token::Split => Some("split"),
8847 Token::Trigger => Some("trigger"),
8848 Token::Location => Some("location"),
8849 Token::States => Some("states"),
8850 Token::To => Some("to"),
8851 Token::From => Some("from"),
8852 Token::Headspace => Some("headspace"),
8853 Token::CoCon => Some("cocon"),
8854 Token::Reality => Some("reality"),
8855 Token::Layer => Some("layer"),
8856 Token::Anima => Some("anima"),
8857 Token::Struct => Some("sigil"), Token::Parallel => Some("Parallel"),
8860 Token::Nu => Some("Nu"),
8861 Token::Lambda => Some("Lambda"),
8862 Token::Delta => Some("Delta"),
8863 Token::Tau => Some("Tau"),
8864 Token::Phi => Some("Phi"),
8865 Token::Sigma => Some("Sigma"),
8866 Token::Rho => Some("Rho"),
8867 Token::Pi => Some("Pi"),
8868 Token::Epsilon => Some("Epsilon"),
8869 Token::Omega => Some("Omega"),
8870 Token::Alpha => Some("Alpha"),
8871 Token::Zeta => Some("Zeta"),
8872 Token::Mu => Some("Mu"),
8873 Token::Chi => Some("Chi"),
8874 Token::Xi => Some("Xi"),
8875 Token::Psi => Some("Psi"),
8876 Token::Theta => Some("Theta"),
8877 Token::Kappa => Some("Kappa"),
8878 Token::Nabla => Some("∇"),
8879 Token::Gpu => Some("Gpu"),
8880 Token::Broadcast => Some("broadcast"),
8882 Token::Gather => Some("gather"),
8883 Token::Distribute => Some("distribute"),
8884 Token::Interfere => Some("interfere"),
8885 Token::Consensus => Some("consensus"),
8886 Token::Ref => Some("ref"),
8888 Token::Null => Some("null"),
8889 Token::Fn => Some("rite"), Token::LambdaExpr => Some("λ"), Token::Linear => Some("linear"),
8893 Token::Affine => Some("affine"),
8894 Token::Relevant => Some("relevant"),
8895 _ => None,
8896 }
8897 }
8898
8899 pub(crate) fn parse_ident(&mut self) -> ParseResult<Ident> {
8900 match self.current.take() {
8901 Some((Token::Ident(name), span)) => {
8902 self.current = self.lexer.next_token();
8903 let evidentiality = self.parse_unambiguous_evidentiality_opt();
8906 let affect = self.parse_affect_opt();
8908 Ok(Ident {
8909 name,
8910 evidentiality,
8911 affect,
8912 span,
8913 })
8914 }
8915 Some((ref token, span)) if Self::keyword_as_ident(token).is_some() => {
8916 let mut name = Self::keyword_as_ident(token).unwrap().to_string();
8917 self.current = self.lexer.next_token();
8918 if let Some((Token::Ident(suffix), suffix_span)) = &self.current {
8921 if suffix.starts_with('_') {
8922 name.push_str(suffix);
8923 let merged_span = span.merge(*suffix_span);
8924 self.current = self.lexer.next_token();
8925 let evidentiality = self.parse_unambiguous_evidentiality_opt();
8926 let affect = self.parse_affect_opt();
8927 return Ok(Ident {
8928 name,
8929 evidentiality,
8930 affect,
8931 span: merged_span,
8932 });
8933 }
8934 }
8935 let evidentiality = self.parse_unambiguous_evidentiality_opt();
8936 let affect = self.parse_affect_opt();
8937 Ok(Ident {
8938 name,
8939 evidentiality,
8940 affect,
8941 span,
8942 })
8943 }
8944 Some((token, span)) => {
8945 self.current = Some((token.clone(), span));
8946 Err(ParseError::UnexpectedToken {
8947 expected: "identifier".to_string(),
8948 found: token,
8949 span,
8950 })
8951 }
8952 None => Err(ParseError::UnexpectedEof),
8953 }
8954 }
8955
8956 fn parse_evidentiality_opt(&mut self) -> Option<Evidentiality> {
8957 let mut ev = None;
8960 loop {
8961 match self.current_token() {
8962 Some(Token::Bang) => {
8963 self.advance();
8964 ev = Some(Evidentiality::Known);
8965 }
8966 Some(Token::Question) => {
8967 self.advance();
8968 ev = Some(Evidentiality::Uncertain);
8969 }
8970 Some(Token::Tilde) => {
8971 self.advance();
8972 ev = Some(Evidentiality::Reported);
8973 }
8974 Some(Token::Lozenge) => {
8975 self.advance();
8976 ev = Some(Evidentiality::Predicted);
8977 }
8978 Some(Token::Interrobang) => {
8979 self.advance();
8980 ev = Some(Evidentiality::Paradox);
8981 }
8982 _ => break,
8983 }
8984 }
8985 ev
8986 }
8987
8988 fn parse_unambiguous_evidentiality_opt(&mut self) -> Option<Evidentiality> {
8991 let mut ev = None;
8992 loop {
8993 match self.current_token() {
8994 Some(Token::Tilde) => {
8995 self.advance();
8996 ev = Some(Evidentiality::Reported);
8997 }
8998 Some(Token::Lozenge) => {
8999 self.advance();
9000 ev = Some(Evidentiality::Predicted);
9001 }
9002 Some(Token::Interrobang) => {
9003 self.advance();
9004 ev = Some(Evidentiality::Paradox);
9005 }
9006 _ => break,
9007 }
9008 }
9009 ev
9010 }
9011
9012 fn parse_affect_opt(&mut self) -> Option<Affect> {
9016 let mut sentiment = None;
9017 let mut sarcasm = false;
9018 let mut intensity = None;
9019 let mut formality = None;
9020 let mut emotion = None;
9021 let mut confidence = None;
9022 let mut found_any = false;
9023
9024 loop {
9026 match self.current_token() {
9027 Some(Token::DirectSum) => {
9029 self.advance();
9030 sentiment = Some(Sentiment::Positive);
9031 found_any = true;
9032 }
9033 Some(Token::AffectNegative) => {
9034 self.advance();
9035 sentiment = Some(Sentiment::Negative);
9036 found_any = true;
9037 }
9038 Some(Token::AffectNeutral) => {
9039 self.advance();
9040 sentiment = Some(Sentiment::Neutral);
9041 found_any = true;
9042 }
9043 Some(Token::IronyMark) => {
9045 self.advance();
9046 sarcasm = true;
9047 found_any = true;
9048 }
9049 Some(Token::IntensityUp) => {
9051 self.advance();
9052 intensity = Some(Intensity::Up);
9053 found_any = true;
9054 }
9055 Some(Token::IntensityDown) => {
9056 self.advance();
9057 intensity = Some(Intensity::Down);
9058 found_any = true;
9059 }
9060 Some(Token::IntensityMax) => {
9061 self.advance();
9062 intensity = Some(Intensity::Max);
9063 found_any = true;
9064 }
9065 Some(Token::FormalRegister) => {
9067 self.advance();
9068 formality = Some(Formality::Formal);
9069 found_any = true;
9070 }
9071 Some(Token::InformalRegister) => {
9072 self.advance();
9073 formality = Some(Formality::Informal);
9074 found_any = true;
9075 }
9076 Some(Token::EmotionJoy) => {
9078 self.advance();
9079 emotion = Some(Emotion::Joy);
9080 found_any = true;
9081 }
9082 Some(Token::EmotionSadness) => {
9083 self.advance();
9084 emotion = Some(Emotion::Sadness);
9085 found_any = true;
9086 }
9087 Some(Token::EmotionAnger) => {
9088 self.advance();
9089 emotion = Some(Emotion::Anger);
9090 found_any = true;
9091 }
9092 Some(Token::EmotionFear) => {
9093 self.advance();
9094 emotion = Some(Emotion::Fear);
9095 found_any = true;
9096 }
9097 Some(Token::EmotionSurprise) => {
9098 self.advance();
9099 emotion = Some(Emotion::Surprise);
9100 found_any = true;
9101 }
9102 Some(Token::EmotionLove) => {
9103 self.advance();
9104 emotion = Some(Emotion::Love);
9105 found_any = true;
9106 }
9107 Some(Token::ConfidenceHigh) => {
9109 self.advance();
9110 confidence = Some(Confidence::High);
9111 found_any = true;
9112 }
9113 Some(Token::ConfidenceMedium) => {
9114 self.advance();
9115 confidence = Some(Confidence::Medium);
9116 found_any = true;
9117 }
9118 Some(Token::ConfidenceLow) => {
9119 self.advance();
9120 confidence = Some(Confidence::Low);
9121 found_any = true;
9122 }
9123 _ => break,
9124 }
9125 }
9126
9127 if found_any {
9128 Some(Affect {
9129 sentiment,
9130 sarcasm,
9131 intensity,
9132 formality,
9133 emotion,
9134 confidence,
9135 })
9136 } else {
9137 None
9138 }
9139 }
9140
9141 pub(crate) fn parse_generics_opt(&mut self) -> ParseResult<Option<Generics>> {
9142 let use_brackets = if self.consume_if(&Token::Lt) {
9144 false
9145 } else if self.consume_if(&Token::LBracket) {
9146 true
9147 } else {
9148 return Ok(None);
9149 };
9150
9151 let mut params = Vec::new();
9152 while !self.is_eof() {
9154 self.skip_comments();
9156
9157 if use_brackets {
9158 if self.check(&Token::RBracket) {
9159 break;
9160 }
9161 } else if self.check_gt() {
9162 break;
9163 }
9164
9165 if let Some(Token::Lifetime(lt)) = self.current_token().cloned() {
9167 self.advance();
9168 params.push(GenericParam::Lifetime(lt));
9169 if !self.consume_if(&Token::Comma) {
9170 break;
9171 }
9172 continue;
9173 }
9174
9175 if self.consume_if(&Token::Const) {
9177 let name = self.parse_ident()?;
9178 let ty = if self.consume_if(&Token::Colon) {
9180 self.parse_type()?
9181 } else {
9182 TypeExpr::Infer
9183 };
9184 let default = if self.consume_if(&Token::Eq) {
9186 Some(Box::new(self.parse_expr()?))
9187 } else {
9188 None
9189 };
9190 params.push(GenericParam::Const { name, ty, default });
9191 if !self.consume_if(&Token::Comma) {
9192 break;
9193 }
9194 continue;
9195 }
9196
9197 let name = self.parse_ident()?;
9199 let evidentiality = self.parse_evidentiality_opt();
9200 let bounds = if self.consume_if(&Token::Colon) {
9201 self.parse_type_bounds()?
9202 } else {
9203 vec![]
9204 };
9205 let default = if self.consume_if(&Token::Eq) {
9207 Some(self.parse_type()?)
9208 } else {
9209 None
9210 };
9211 params.push(GenericParam::Type {
9212 name,
9213 bounds,
9214 evidentiality,
9215 default,
9216 });
9217
9218 if !self.consume_if(&Token::Comma) {
9219 break;
9220 }
9221 }
9222 if use_brackets {
9224 self.expect(Token::RBracket)?;
9225 } else {
9226 self.expect_gt()?;
9228 }
9229
9230 Ok(Some(Generics { params }))
9231 }
9232
9233 pub(crate) fn parse_where_clause_opt(&mut self) -> ParseResult<Option<WhereClause>> {
9234 if !self.consume_if(&Token::Where) {
9235 return Ok(None);
9236 }
9237
9238 let mut predicates = Vec::new();
9239 loop {
9240 self.skip_comments(); let is_expr_predicate = if let Some(Token::Ident(_)) = self.current_token() {
9247 let next = self.peek_next();
9249 matches!(
9250 next,
9251 Some(Token::Percent)
9252 | Some(Token::EqEq)
9253 | Some(Token::NotEq)
9254 | Some(Token::Plus)
9255 | Some(Token::Minus)
9256 | Some(Token::Star)
9257 | Some(Token::Slash)
9258 )
9259 } else {
9260 false
9261 };
9262
9263 if is_expr_predicate {
9264 let _expr = self.parse_expr()?;
9266 self.skip_comments();
9268 if !self.consume_if(&Token::Comma) {
9269 break;
9270 }
9271 self.skip_comments();
9272 if self.check(&Token::LBrace) {
9273 break;
9274 }
9275 continue;
9276 }
9277
9278 let ty = self.parse_type()?;
9279
9280 if self.check(&Token::Colon) {
9282 self.advance(); let bounds = self.parse_type_bounds()?;
9284 self.skip_comments(); predicates.push(WherePredicate { ty, bounds });
9286 } else {
9287 }
9290
9291 if !self.consume_if(&Token::Comma) {
9292 break;
9293 }
9294 self.skip_comments();
9296 if self.check(&Token::LBrace) {
9297 break;
9298 }
9299 }
9300
9301 Ok(Some(WhereClause { predicates }))
9302 }
9303
9304 pub(crate) fn parse_params(&mut self) -> ParseResult<Vec<Param>> {
9305 let mut params = Vec::new();
9306 while !self.check(&Token::RParen) && !self.is_eof() {
9307 self.skip_comments();
9309 while self.check(&Token::At) || self.check(&Token::Hash) {
9310 self.skip_attribute()?;
9311 self.skip_comments();
9312 }
9313 if self.check(&Token::RParen) {
9314 break;
9315 }
9316 let pattern = self.parse_pattern()?;
9317 let ty = if self.consume_if(&Token::Colon) {
9319 self.parse_type()?
9320 } else {
9321 TypeExpr::Infer
9322 };
9323 params.push(Param { pattern, ty });
9324 if !self.consume_if(&Token::Comma) {
9325 break;
9326 }
9327 }
9328 Ok(params)
9329 }
9330
9331 fn skip_attribute(&mut self) -> ParseResult<()> {
9333 if self.check(&Token::At) || self.check(&Token::Hash) {
9335 self.advance();
9336 }
9337 if self.consume_if(&Token::LBracket) {
9339 let mut depth = 1;
9340 while depth > 0 && !self.is_eof() {
9341 match self.current_token() {
9342 Some(Token::LBracket) => depth += 1,
9343 Some(Token::RBracket) => depth -= 1,
9344 _ => {}
9345 }
9346 self.advance();
9347 }
9348 }
9349 Ok(())
9350 }
9351
9352 fn parse_field_defs(&mut self) -> ParseResult<Vec<FieldDef>> {
9353 let mut fields = Vec::new();
9354 while !self.check(&Token::RBrace) && !self.is_eof() {
9355 while matches!(
9357 self.current_token(),
9358 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_))
9359 ) || self.check(&Token::Hash) || self.check(&Token::At)
9360 {
9361 if self.check(&Token::Hash) || self.check(&Token::At) {
9362 self.skip_attribute()?;
9363 } else {
9364 self.advance();
9365 }
9366 }
9367 if self.check(&Token::RBrace) {
9368 break;
9369 }
9370 let visibility = self.parse_visibility()?;
9371 let name = self.parse_ident()?;
9372 let _evidentiality = self.parse_evidentiality_opt();
9374 self.expect(Token::Colon)?;
9375 let ty = self.parse_type()?;
9376 let default = if self.consume_if(&Token::Eq) {
9378 Some(self.parse_expr()?)
9379 } else {
9380 None
9381 };
9382 fields.push(FieldDef {
9383 visibility,
9384 name,
9385 ty,
9386 default,
9387 });
9388 if !self.consume_if(&Token::Comma) {
9389 break;
9390 }
9391 }
9392 Ok(fields)
9393 }
9394
9395 fn parse_expr_list(&mut self) -> ParseResult<Vec<Expr>> {
9396 let mut exprs = Vec::new();
9397 self.skip_comments();
9399 while !self.check(&Token::RParen) && !self.check(&Token::RBracket) && !self.is_eof() {
9400 let expr = if let Some(Token::Ident(name)) = self.current_token().cloned() {
9404 let is_named_arg = self.peek_next() == Some(&Token::Colon);
9406 if is_named_arg {
9407 let span = self.current_span();
9408 self.advance(); self.advance(); let value = self.parse_expr()?;
9411 Expr::NamedArg {
9413 name: Ident {
9414 name,
9415 evidentiality: None,
9416 affect: None,
9417 span,
9418 },
9419 value: Box::new(value),
9420 }
9421 } else {
9422 self.parse_expr()?
9423 }
9424 } else {
9425 self.parse_expr()?
9426 };
9427 exprs.push(expr);
9428 if !self.consume_if(&Token::Comma) {
9429 break;
9430 }
9431 self.skip_comments();
9433 }
9434 Ok(exprs)
9435 }
9436
9437 fn parse_struct_fields(&mut self) -> ParseResult<(Vec<FieldInit>, Option<Box<Expr>>)> {
9438 let mut fields = Vec::new();
9439 let mut rest = None;
9440
9441 while !self.check(&Token::RBrace) && !self.is_eof() {
9442 while matches!(
9444 self.current_token(),
9445 Some(Token::DocComment(_)) | Some(Token::LineComment(_) | Token::TildeComment(_) | Token::BlockComment(_)) | Some(Token::Hash)
9446 ) {
9447 if self.check(&Token::Hash) {
9448 self.advance();
9450 self.consume_if(&Token::Bang); if self.consume_if(&Token::LBracket) {
9452 let mut depth = 1;
9453 while depth > 0 && !self.is_eof() {
9454 match self.current_token() {
9455 Some(Token::LBracket) => depth += 1,
9456 Some(Token::RBracket) => depth -= 1,
9457 _ => {}
9458 }
9459 self.advance();
9460 }
9461 }
9462 } else {
9463 self.advance();
9464 }
9465 }
9466 if self.check(&Token::RBrace) {
9467 break;
9468 }
9469 if self.consume_if(&Token::DotDot) {
9470 rest = Some(Box::new(self.parse_expr()?));
9471 break;
9472 }
9473
9474 let name = self.parse_ident()?;
9475 let value = if self.consume_if(&Token::Colon) {
9476 Some(self.parse_expr()?)
9477 } else {
9478 None
9479 };
9480 fields.push(FieldInit { name, value });
9481
9482 if !self.consume_if(&Token::Comma) {
9483 break;
9484 }
9485 }
9486
9487 Ok((fields, rest))
9488 }
9489
9490 fn is_item_start(&mut self) -> bool {
9491 match self.current_token() {
9492 Some(Token::Fn)
9493 | Some(Token::Struct)
9494 | Some(Token::Enum)
9495 | Some(Token::Trait)
9496 | Some(Token::Impl)
9497 | Some(Token::Type)
9498 | Some(Token::Mod)
9499 | Some(Token::Use)
9500 | Some(Token::Const)
9501 | Some(Token::Static)
9502 | Some(Token::Actor)
9503 | Some(Token::Pub)
9504 | Some(Token::Extern) => true,
9505 Some(Token::Async) => matches!(self.peek_next(), Some(Token::Fn)),
9508 _ => false,
9509 }
9510 }
9511
9512 fn is_in_condition(&self) -> bool {
9513 self.in_condition
9514 }
9515
9516 fn parse_condition(&mut self) -> ParseResult<Expr> {
9518 let was_in_condition = self.in_condition;
9519 self.in_condition = true;
9520 let result = self.parse_expr();
9521 self.in_condition = was_in_condition;
9522 result
9523 }
9524
9525 fn parse_legion_operator(&mut self, lhs: Expr) -> ParseResult<Expr> {
9533 match self.current_token() {
9534 Some(Token::Interfere) => {
9535 self.advance();
9537 let field = self.parse_expr_bp(15)?; Ok(Expr::LegionInterference {
9539 query: Box::new(lhs),
9540 field: Box::new(field),
9541 })
9542 }
9543 Some(Token::Distribute) => {
9544 self.advance();
9546 let count = self.parse_expr_bp(15)?;
9547 Ok(Expr::LegionDistribute {
9548 task: Box::new(lhs),
9549 count: Box::new(count),
9550 })
9551 }
9552 Some(Token::Broadcast) => {
9553 self.advance();
9555 let target = self.parse_expr_bp(15)?;
9556 Ok(Expr::LegionBroadcast {
9557 signal: Box::new(lhs),
9558 target: Box::new(target),
9559 })
9560 }
9561 Some(Token::Gather) => {
9562 self.advance();
9564 Ok(Expr::LegionGather {
9565 fragments: Box::new(lhs),
9566 })
9567 }
9568 Some(Token::Consensus) => {
9569 self.advance();
9571 Ok(Expr::LegionConsensus {
9572 contributions: Box::new(lhs),
9573 })
9574 }
9575 Some(Token::ConfidenceHigh) => {
9576 self.advance();
9578 Ok(Expr::LegionResonance {
9579 expr: Box::new(lhs),
9580 })
9581 }
9582 _ => Ok(lhs),
9583 }
9584 }
9585
9586 fn is_legion_field_ident(&self, name: &str) -> bool {
9589 name.ends_with('∿')
9590 }
9591}
9592
9593fn infix_binding_power(op: BinOp) -> (u8, u8) {
9595 match op {
9596 BinOp::Or => (1, 2),
9597 BinOp::And => (3, 4),
9598 BinOp::Eq | BinOp::Ne | BinOp::Lt | BinOp::Le | BinOp::Gt | BinOp::Ge => (5, 6),
9599 BinOp::BitOr => (7, 8),
9600 BinOp::BitXor => (9, 10),
9601 BinOp::BitAnd => (11, 12),
9602 BinOp::Shl | BinOp::Shr => (13, 14),
9603 BinOp::Add | BinOp::Sub | BinOp::Concat => (15, 16),
9604 BinOp::Mul | BinOp::Div | BinOp::Rem | BinOp::MatMul
9605 | BinOp::Hadamard | BinOp::TensorProd | BinOp::Convolve => (17, 18),
9606 BinOp::Pow => (20, 19), }
9608}
9609
9610#[cfg(test)]
9611mod tests {
9612 use super::*;
9613
9614 #[test]
9615 fn test_parse_function() {
9616 let source = "rite hello(name: str) -> str { ⤺ name; }";
9618 let mut parser = Parser::new(source);
9619 let file = parser.parse_file().unwrap();
9620 assert_eq!(file.items.len(), 1);
9621 }
9622
9623 #[test]
9624 fn test_parse_pipe_chain() {
9625 let source = "rite main() { ≔ result = data|τ{_ * 2}|φ{_ > 0}|σ; }";
9626 let mut parser = Parser::new(source);
9627 let file = parser.parse_file().unwrap();
9628 assert_eq!(file.items.len(), 1);
9629 }
9630
9631 #[test]
9632 fn test_parse_async_function() {
9633 let source = "async rite fetch(url: str) -> Response~ { ⤺ client·get(url)|await; }";
9634 let mut parser = Parser::new(source);
9635 let file = parser.parse_file().unwrap();
9636 assert_eq!(file.items.len(), 1);
9637 }
9638
9639 #[test]
9640 fn test_parse_struct() {
9641 let source = "sigil Point { x: f64, y: f64 }";
9642 let mut parser = Parser::new(source);
9643 let file = parser.parse_file().unwrap();
9644 assert_eq!(file.items.len(), 1);
9645 }
9646
9647 #[test]
9648 fn test_parse_actor() {
9649 let source = r#"
9651 actor Counter {
9652 state: i64 = 0
9653 on Increment(n: i64) { ⤺ self.state + n; }
9654 }
9655 "#;
9656 let mut parser = Parser::new(source);
9657 let file = parser.parse_file().unwrap();
9658 assert_eq!(file.items.len(), 1);
9659 }
9660
9661 #[test]
9662 fn test_parse_number_bases() {
9663 let source = "rite bases() { ≔ a = 42; ≔ b = 0b101010; ≔ c = 0x2A; ≔ d = 0v22; }";
9664 let mut parser = Parser::new(source);
9665 let file = parser.parse_file().unwrap();
9666 assert_eq!(file.items.len(), 1);
9667 }
9668
9669 #[test]
9670 fn test_parse_labeled_loops() {
9671 let source = r#"
9674 rite test() {
9675 'outer: loop {
9676 'inner: ⟳ true {
9677 ⊗ 'outer;
9678 }
9679 }
9680 }
9681 "#;
9682 let mut parser = Parser::new(source);
9683 let file = parser.parse_file().unwrap();
9684 assert_eq!(file.items.len(), 1);
9685
9686 let source2 = r#"
9689 rite test2() {
9690 'rows: ∀ i ∈ 0..10 {
9691 'cols: ∀ j ∈ 0..10 {
9692 ⎇ j == 5 { ↻ 'rows; }
9693 }
9694 }
9695 }
9696 "#;
9697 let mut parser2 = Parser::new(source2);
9698 let file2 = parser2.parse_file().unwrap();
9699 assert_eq!(file2.items.len(), 1);
9700 }
9701
9702 #[test]
9703 fn test_parse_inline_asm() {
9704 let source = r#"
9705 rite outb(port: u16, value: u8) {
9706 asm!("out dx, al",
9707 ∈("dx") port,
9708 ∈("al") value,
9709 options(nostack));
9710 }
9711 "#;
9712 let mut parser = Parser::new(source);
9713 let file = parser.parse_file().unwrap();
9714 assert_eq!(file.items.len(), 1);
9715
9716 if let Item::Function(func) = &file.items[0].node {
9717 assert_eq!(func.name.name, "outb");
9718 } else {
9719 panic!("Expected function");
9720 }
9721 }
9722
9723 #[test]
9724 fn test_parse_inline_asm_with_outputs() {
9725 let source = r#"
9726 rite inb(port: u16) -> u8 {
9727 ≔ result: u8 = 0;
9728 asm!("∈ al, dx",
9729 out("al") result,
9730 ∈("dx") port,
9731 options(nostack, nomem));
9732 ⤺ result;
9733 }
9734 "#;
9735 let mut parser = Parser::new(source);
9736 let file = parser.parse_file().unwrap();
9737 assert_eq!(file.items.len(), 1);
9738 }
9739
9740 #[test]
9741 fn test_parse_volatile_read() {
9742 let source = r#"
9743 rite read_mmio(addr: *Δ u32) -> u32 {
9744 ⤺ volatile read<u32>(addr);
9745 }
9746 "#;
9747 let mut parser = Parser::new(source);
9748 let file = parser.parse_file().unwrap();
9749 assert_eq!(file.items.len(), 1);
9750 }
9751
9752 #[test]
9753 fn test_parse_volatile_write() {
9754 let source = r#"
9755 rite write_mmio(addr: *Δ u32, value: u32) {
9756 volatile write<u32>(addr, value);
9757 }
9758 "#;
9759 let mut parser = Parser::new(source);
9760 let file = parser.parse_file().unwrap();
9761 assert_eq!(file.items.len(), 1);
9762 }
9763
9764 #[test]
9765 fn test_parse_naked_function() {
9766 let source = r#"
9767 naked rite interrupt_handler() {
9768 asm!("push rax; push rbx; call handler_impl; pop rbx; pop rax; iretq",
9769 options(nostack));
9770 }
9771 "#;
9772 let mut parser = Parser::new(source);
9773 let file = parser.parse_file().unwrap();
9774 assert_eq!(file.items.len(), 1);
9775
9776 if let Item::Function(func) = &file.items[0].node {
9777 assert!(func.attrs.naked, "Function should be naked");
9778 } else {
9779 panic!("Expected function");
9780 }
9781 }
9782
9783 #[test]
9784 fn test_parse_packed_struct() {
9785 let source = r#"
9786 packed sigil GDTEntry {
9787 limit_low: u16,
9788 base_low: u16,
9789 base_middle: u8,
9790 access: u8,
9791 granularity: u8,
9792 base_high: u8,
9793 }
9794 "#;
9795 let mut parser = Parser::new(source);
9796 let file = parser.parse_file().unwrap();
9797 assert_eq!(file.items.len(), 1);
9798
9799 if let Item::Struct(s) = &file.items[0].node {
9800 assert!(s.attrs.packed, "Struct should be packed");
9801 assert_eq!(s.name.name, "GDTEntry");
9802 if let StructFields::Named(fields) = &s.fields {
9803 assert_eq!(fields.len(), 6);
9804 } else {
9805 panic!("Expected named fields");
9806 }
9807 } else {
9808 panic!("Expected struct");
9809 }
9810 }
9811
9812 #[test]
9813 fn test_parse_no_std_attribute() {
9814 let source = r#"
9815 #![no_std]
9816 #![no_main]
9817
9818 rite kernel_main() -> ! {
9819 loop {}
9820 }
9821 "#;
9822 let mut parser = Parser::new(source);
9823 let file = parser.parse_file().unwrap();
9824
9825 assert!(file.config.no_std, "Should have no_std");
9826 assert!(file.config.no_main, "Should have no_main");
9827 assert_eq!(file.attrs.len(), 2);
9828 }
9829
9830 #[test]
9831 fn test_parse_feature_attribute() {
9832 let source = r#"
9833 #![feature(asm, naked_functions)]
9834
9835 rite main() -> i64 { 0 }
9836 "#;
9837 let mut parser = Parser::new(source);
9838 let file = parser.parse_file().unwrap();
9839
9840 assert_eq!(file.config.features.len(), 2);
9841 assert!(file.config.features.contains(&"asm".to_string()));
9842 assert!(file
9843 .config
9844 .features
9845 .contains(&"naked_functions".to_string()));
9846 }
9847
9848 #[test]
9849 fn test_parse_target_attribute() {
9850 let source = r#"
9851 #![no_std]
9852 #![target(arch = "x86_64", os = "none")]
9853
9854 rite kernel_main() { }
9855 "#;
9856 let mut parser = Parser::new(source);
9857 let file = parser.parse_file().unwrap();
9858
9859 assert!(file.config.no_std);
9860 let target = file
9861 .config
9862 .target
9863 .as_ref()
9864 .expect("Should have target config");
9865 assert_eq!(target.arch, Some("x86_64".to_string()));
9866 assert_eq!(target.os, Some("none".to_string()));
9867 }
9868
9869 #[test]
9870 fn test_parse_panic_handler() {
9871 let source = r#"
9872 #![no_std]
9873
9874 #[panic_handler]
9875 rite panic(info: *const PanicInfo) -> ! {
9876 loop {}
9877 }
9878 "#;
9879 let mut parser = Parser::new(source);
9880 let file = parser.parse_file().unwrap();
9881
9882 assert_eq!(file.items.len(), 1);
9883 if let Item::Function(func) = &file.items[0].node {
9884 assert!(
9885 func.attrs.panic_handler,
9886 "Should have panic_handler attribute"
9887 );
9888 } else {
9889 panic!("Expected function");
9890 }
9891 }
9892
9893 #[test]
9894 fn test_parse_entry_point() {
9895 let source = r#"
9896 #![no_std]
9897 #![no_main]
9898
9899 #[entry]
9900 #[no_mangle]
9901 rite _start() -> ! {
9902 loop {}
9903 }
9904 "#;
9905 let mut parser = Parser::new(source);
9906 let file = parser.parse_file().unwrap();
9907
9908 assert_eq!(file.items.len(), 1);
9909 if let Item::Function(func) = &file.items[0].node {
9910 assert!(func.attrs.entry, "Should have entry attribute");
9911 assert!(func.attrs.no_mangle, "Should have no_mangle attribute");
9912 } else {
9913 panic!("Expected function");
9914 }
9915 }
9916
9917 #[test]
9918 fn test_parse_link_section() {
9919 let source = r#"
9920 #[link_section = ".text.boot"]
9921 rite boot_code() { }
9922 "#;
9923 let mut parser = Parser::new(source);
9924 let file = parser.parse_file().unwrap();
9925
9926 assert_eq!(file.items.len(), 1);
9927 if let Item::Function(func) = &file.items[0].node {
9928 assert_eq!(func.attrs.link_section, Some(".text.boot".to_string()));
9929 } else {
9930 panic!("Expected function");
9931 }
9932 }
9933
9934 #[test]
9935 fn test_parse_linker_config() {
9936 let source = r#"
9937 #![no_std]
9938 #![linker_script = "kernel.ld"]
9939 #![entry_point = "_start"]
9940 #![base_address = 0x100000]
9941 #![stack_size = 0x4000]
9942
9943 rite kernel_main() { }
9944 "#;
9945 let mut parser = Parser::new(source);
9946 let file = parser.parse_file().unwrap();
9947
9948 let linker = file
9949 .config
9950 .linker
9951 .as_ref()
9952 .expect("Should have linker config");
9953 assert_eq!(linker.script, Some("kernel.ld".to_string()));
9954 assert_eq!(linker.entry_point, Some("_start".to_string()));
9955 assert_eq!(linker.base_address, Some(0x100000));
9956 assert_eq!(linker.stack_size, Some(0x4000));
9957 }
9958
9959 #[test]
9960 fn test_parse_interrupt_handler() {
9961 let source = r#"
9962 #[interrupt(32)]
9963 #[naked]
9964 rite timer_handler() {
9965 asm!("iretq", options(nostack));
9966 }
9967 "#;
9968 let mut parser = Parser::new(source);
9969 let file = parser.parse_file().unwrap();
9970
9971 if let Item::Function(func) = &file.items[0].node {
9972 assert_eq!(func.attrs.interrupt, Some(32));
9973 assert!(func.attrs.naked);
9974 } else {
9975 panic!("Expected function");
9976 }
9977 }
9978
9979 #[test]
9980 fn test_parse_inline_attributes() {
9981 let source = r#"
9982 #[inline]
9983 rite fast() -> i64 { 0 }
9984
9985 #[inline(always)]
9986 rite very_fast() -> i64 { 0 }
9987
9988 #[inline(never)]
9989 rite never_inline() -> i64 { 0 }
9990 "#;
9991 let mut parser = Parser::new(source);
9992 let file = parser.parse_file().unwrap();
9993
9994 assert_eq!(file.items.len(), 3);
9995
9996 if let Item::Function(func) = &file.items[0].node {
9997 assert_eq!(func.attrs.inline, Some(InlineHint::Hint));
9998 }
9999 if let Item::Function(func) = &file.items[1].node {
10000 assert_eq!(func.attrs.inline, Some(InlineHint::Always));
10001 }
10002 if let Item::Function(func) = &file.items[2].node {
10003 assert_eq!(func.attrs.inline, Some(InlineHint::Never));
10004 }
10005 }
10006
10007 #[test]
10008 fn test_parse_simd_type() {
10009 let source = r#"
10010 rite vec_add(a: simd<f32, 4>, b: simd<f32, 4>) -> simd<f32, 4> {
10011 ⤺ simd.add(a, b);
10012 }
10013 "#;
10014 let mut parser = Parser::new(source);
10015 let file = parser.parse_file().unwrap();
10016 assert_eq!(file.items.len(), 1);
10017
10018 if let Item::Function(func) = &file.items[0].node {
10019 assert_eq!(func.name.name, "vec_add");
10020 if let TypeExpr::Simd { element, lanes } = &func.params[0].ty {
10022 assert_eq!(*lanes, 4);
10023 if let TypeExpr::Path(path) = element.as_ref() {
10024 assert_eq!(path.segments[0].ident.name, "f32");
10025 }
10026 } else {
10027 panic!("Expected SIMD type");
10028 }
10029 } else {
10030 panic!("Expected function");
10031 }
10032 }
10033
10034 #[test]
10035 fn test_parse_simd_literal() {
10036 let source = r#"
10037 rite make_vec() -> simd<f32, 4> {
10038 ⤺ simd[1.0, 2.0, 3.0, 4.0];
10039 }
10040 "#;
10041 let mut parser = Parser::new(source);
10042 let file = parser.parse_file().unwrap();
10043 assert_eq!(file.items.len(), 1);
10044 }
10045
10046 #[test]
10047 fn test_parse_simd_intrinsics() {
10048 let source = r#"
10049 rite dot_product(a: simd<f32, 4>, b: simd<f32, 4>) -> f32 {
10050 ≔ prod = simd.mul(a, b);
10051 ⤺ simd.hadd(prod);
10052 }
10053 "#;
10054 let mut parser = Parser::new(source);
10055 let file = parser.parse_file().unwrap();
10056 assert_eq!(file.items.len(), 1);
10057 }
10058
10059 #[test]
10060 fn test_parse_simd_shuffle() {
10061 let source = r#"
10062 rite interleave(a: simd<f32, 4>, b: simd<f32, 4>) -> simd<f32, 4> {
10063 ⤺ simd.shuffle(a, b, [0, 4, 1, 5]);
10064 }
10065 "#;
10066 let mut parser = Parser::new(source);
10067 let file = parser.parse_file().unwrap();
10068 assert_eq!(file.items.len(), 1);
10069 }
10070
10071 #[test]
10072 fn test_parse_atomic_type() {
10073 let source = r#"
10074 sigil Counter {
10075 value: atomic<i64>,
10076 }
10077 "#;
10078 let mut parser = Parser::new(source);
10079 let file = parser.parse_file().unwrap();
10080 assert_eq!(file.items.len(), 1);
10081
10082 if let Item::Struct(s) = &file.items[0].node {
10083 if let StructFields::Named(fields) = &s.fields {
10084 if let TypeExpr::Atomic(inner) = &fields[0].ty {
10085 if let TypeExpr::Path(path) = inner.as_ref() {
10086 assert_eq!(path.segments[0].ident.name, "i64");
10087 }
10088 } else {
10089 panic!("Expected atomic type");
10090 }
10091 }
10092 } else {
10093 panic!("Expected struct");
10094 }
10095 }
10096
10097 #[test]
10098 fn test_parse_atomic_operations() {
10099 let source = r#"
10100 rite increment(ptr: *Δ i64) -> i64 {
10101 ⤺ atomic.fetch_add(ptr, 1, SeqCst);
10102 }
10103 "#;
10104 let mut parser = Parser::new(source);
10105 let file = parser.parse_file().unwrap();
10106 assert_eq!(file.items.len(), 1);
10107 }
10108
10109 #[test]
10110 fn test_parse_atomic_compare_exchange() {
10111 let source = r#"
10112 rite cas(ptr: *Δ i64, expected: i64, new: i64) -> bool {
10113 ≔ result = atomic.compare_exchange(ptr, expected, new, AcqRel, Relaxed);
10114 ⤺ result;
10115 }
10116 "#;
10117 let mut parser = Parser::new(source);
10118 let file = parser.parse_file().unwrap();
10119 assert_eq!(file.items.len(), 1);
10120 }
10121
10122 #[test]
10123 fn test_parse_atomic_fence() {
10124 let source = r#"
10125 rite memory_barrier() {
10126 atomic.fence(SeqCst);
10127 }
10128 "#;
10129 let mut parser = Parser::new(source);
10130 let file = parser.parse_file().unwrap();
10131 assert_eq!(file.items.len(), 1);
10132 }
10133
10134 #[test]
10135 fn test_parse_derive_macro() {
10136 let source = r#"
10137 #[derive(Debug, Clone, Component)]
10138 sigil Position {
10139 x: f32,
10140 y: f32,
10141 z: f32,
10142 }
10143 "#;
10144 let mut parser = Parser::new(source);
10145 let file = parser.parse_file().unwrap();
10146 assert_eq!(file.items.len(), 1);
10147
10148 if let Item::Struct(s) = &file.items[0].node {
10149 assert_eq!(s.attrs.derives.len(), 3);
10150 assert!(matches!(s.attrs.derives[0], DeriveTrait::Debug));
10151 assert!(matches!(s.attrs.derives[1], DeriveTrait::Clone));
10152 assert!(matches!(s.attrs.derives[2], DeriveTrait::Component));
10153 } else {
10154 panic!("Expected struct");
10155 }
10156 }
10157
10158 #[test]
10159 fn test_parse_repr_c_struct() {
10160 let source = r#"
10161 #[repr(C)]
10162 sigil FFIStruct {
10163 field: i32,
10164 }
10165 "#;
10166 let mut parser = Parser::new(source);
10167 let file = parser.parse_file().unwrap();
10168 assert_eq!(file.items.len(), 1);
10169
10170 if let Item::Struct(s) = &file.items[0].node {
10171 assert_eq!(s.attrs.repr, Some(StructRepr::C));
10172 } else {
10173 panic!("Expected struct");
10174 }
10175 }
10176
10177 #[test]
10178 fn test_parse_allocator_trait() {
10179 let source = r#"
10180 Θ Allocator {
10181 type Error;
10182
10183 rite allocate(size: usize, align: usize) -> *Δ u8;
10184 rite deallocate(ptr: *Δ u8, size: usize, align: usize);
10185 }
10186 "#;
10187 let mut parser = Parser::new(source);
10188 let file = parser.parse_file().unwrap();
10189 assert_eq!(file.items.len(), 1);
10190
10191 if let Item::Trait(t) = &file.items[0].node {
10192 assert_eq!(t.name.name, "Allocator");
10193 assert_eq!(t.items.len(), 3); assert!(matches!(t.items[0], TraitItem::Type { .. }));
10195 } else {
10196 panic!("Expected trait");
10197 }
10198 }
10199
10200 #[test]
10201 fn test_parse_where_clause() {
10202 let source = r#"
10203 rite alloc_array<T, A>(allocator: &Δ A, count: usize) -> *Δ T
10204 where
10205 A: Allocator,
10206 {
10207 ⤺ allocator.allocate(count, 8);
10208 }
10209 "#;
10210 let mut parser = Parser::new(source);
10211 let file = parser.parse_file().unwrap();
10212 assert_eq!(file.items.len(), 1);
10213
10214 if let Item::Function(func) = &file.items[0].node {
10215 assert!(func.where_clause.is_some());
10216 let wc = func.where_clause.as_ref().unwrap();
10217 assert_eq!(wc.predicates.len(), 1);
10218 } else {
10219 panic!("Expected function");
10220 }
10221 }
10222}