node.rs
1 //! Typed [`Node`] definitions. 2 //! 3 //! [`Node`]: crate::Node 4 use std::{ 5 collections::VecDeque, 6 ops, 7 ptr, 8 }; 9 10 use cab_util::{ 11 force, 12 lazy, 13 read, 14 ready, 15 reffed, 16 }; 17 use derive_more::Deref; 18 use dup::Dupe; 19 use paste::paste; 20 use ranged::{ 21 IntoSpan as _, 22 Span, 23 }; 24 use ust::report::Report; 25 26 use crate::{ 27 Kind::{ 28 self, 29 *, 30 }, 31 red, 32 segment::{ 33 Segment, 34 Segmented, 35 }, 36 token, 37 }; 38 39 macro_rules! node { 40 ( 41 #[from($kind:ident)] 42 $(#[$attribute:meta])* 43 struct $name:ident; 44 ) => { 45 $(#[$attribute])* 46 #[derive(Deref, Debug, Clone, Dupe, PartialEq, Eq, Hash)] 47 #[repr(transparent)] 48 pub struct $name(red::Node); 49 50 impl<'a> TryFrom<&'a red::Node> for &'a $name { 51 type Error = (); 52 53 fn try_from(node: &'a red::Node) -> Result<Self, ()> { 54 if node.kind() != $kind { 55 return Err(()); 56 } 57 58 // SAFETY: node is &red::Node and we are casting it to &$name. 59 // $name holds red::Node with #[repr(transparent)], so the layout 60 // is the exact same for &red::Node and &$name. 61 Ok(unsafe { &*ptr::from_ref(node).cast::<$name>() }) 62 } 63 } 64 65 impl TryFrom<red::Node> for $name { 66 type Error = (); 67 68 fn try_from(node: red::Node) -> Result<Self, ()> { 69 if node.kind() != $kind { 70 return Err(()); 71 } 72 73 Ok(Self(node)) 74 } 75 } 76 77 impl $name { 78 pub const KIND: Kind = $kind; 79 } 80 }; 81 82 ( 83 #[from($($variant:ident),* $(,)?)] 84 $(#[$attribute:meta])* 85 enum $name:ident; 86 ) => { 87 reffed! { 88 $(#[$attribute])* 89 #[derive(Debug, Clone, Dupe, PartialEq, Eq, Hash)] 90 pub enum $name { 91 $($variant($variant),)* 92 } 93 } 94 95 impl ops::Deref for $name { 96 type Target = red::Node; 97 98 fn deref(&self) -> &Self::Target { 99 match *self { 100 $(Self::$variant(ref node) => &**node,)* 101 } 102 } 103 } 104 105 impl TryFrom<red::Node> for $name { 106 type Error = (); 107 108 fn try_from(node: red::Node) -> Result<Self, ()> { 109 Ok(match node.kind() { 110 $($variant::KIND => Self::$variant($variant::try_from(node)?),)* 111 _ => return Err(()), 112 }) 113 } 114 } 115 116 $( 117 impl From<$variant> for $name { 118 fn from(from: $variant) -> Self { 119 Self::$variant(from) 120 } 121 } 122 123 impl TryFrom<$name> for $variant { 124 type Error = (); 125 126 fn try_from(from: $name) -> Result<Self, ()> { 127 if let $name::$variant(node) = from { 128 Ok(node) 129 } else { 130 Err(()) 131 } 132 } 133 } 134 )* 135 136 paste! { 137 impl ops::Deref for [<$name Ref>]<'_> { 138 type Target = red::Node; 139 140 fn deref(&self) -> &Self::Target { 141 match *self { 142 $(Self::$variant(ref node) => &**node,)* 143 } 144 } 145 } 146 147 impl<'a> TryFrom<&'a red::Node> for [<$name Ref>]<'a> { 148 type Error = (); 149 150 fn try_from(node: &'a red::Node) -> Result<Self, ()> { 151 Ok(match node.kind() { 152 $($variant::KIND => Self::$variant(<&$variant>::try_from(node)?),)* 153 _ => return Err(()), 154 }) 155 } 156 } 157 158 $( 159 impl<'a> From<&'a $variant> for [<$name Ref>]<'a> { 160 fn from(from: &'a $variant) -> Self { 161 Self::$variant(from) 162 } 163 } 164 165 impl<'a> TryFrom<[<$name Ref>]<'a>> for &'a $variant { 166 type Error = (); 167 168 fn try_from(from: [<$name Ref>]<'a>) -> Result<Self, ()> { 169 if let [<$name Ref>]::$variant(node) = from { 170 Ok(node) 171 } else { 172 Err(()) 173 } 174 } 175 } 176 )* 177 } 178 }; 179 } 180 181 macro_rules! get_token { 182 ($name:ident -> $($skip:literal @)? Option<$kind:ident>) => { 183 #[must_use] 184 pub fn $name(&self) -> Option<&red::Token> { 185 self.children_with_tokens() 186 .filter_map(red::ElementRef::into_token) 187 $(.skip($skip))? 188 .find(|token| token.kind() == $kind) 189 } 190 }; 191 192 ($name:ident -> $($skip:literal @)? $kind:ident) => { 193 #[must_use] 194 pub fn $name(&self) -> &red::Token { 195 self.children_with_tokens() 196 .filter_map(red::ElementRef::into_token) 197 $(.skip($skip))? 198 .find(|token| token.kind() == $kind) 199 .expect("node must have a token child") 200 } 201 }; 202 203 ($name:ident -> $($skip:literal @)? Option<$type:ty>) => { 204 #[must_use] 205 pub fn $name(&self) -> $type { 206 self.children_with_tokens() 207 .filter_map(red::ElementRef::into_token) 208 $(.skip($skip))? 209 .find_map(|token| <$type>::try_from(token).ok()) 210 } 211 }; 212 213 ($name:ident -> $($skip:literal @)? $type:ty) => { 214 #[must_use] 215 pub fn $name(&self) -> $type { 216 self.children_with_tokens() 217 .filter_map(red::ElementRef::into_token) 218 $(.skip($skip))? 219 .find_map(|token| <$type>::try_from(token).ok()) 220 .expect("node must have a token child") 221 } 222 }; 223 } 224 225 macro_rules! get_node { 226 ($name:ident -> $($skip:literal @)? Option<$type:ty>) => { 227 #[must_use] 228 pub fn $name(&self) -> Option<$type> { 229 self.children() 230 .filter_map(|node| <$type>::try_from(node).ok()) 231 $(.skip($skip))? 232 .next() 233 } 234 }; 235 236 ($name:ident -> $($skip:literal @)? $type:ty) => { 237 #[must_use] 238 pub fn $name(&self) -> $type { 239 self.children() 240 .filter_map(|node| <$type>::try_from(node).ok()) 241 $(.skip($skip))? 242 .next() 243 .expect("node must have a node child of given type") 244 } 245 }; 246 } 247 248 // EXPRESSION 249 250 node! { 251 #[from( 252 Error, 253 254 Parenthesis, 255 List, 256 Attributes, 257 258 PrefixOperation, 259 InfixOperation, 260 SuffixOperation, 261 262 Path, 263 264 Bind, 265 Identifier, 266 267 SString, 268 269 Char, 270 Integer, 271 Float, 272 273 If, 274 )] 275 /// An expression. Everything is an expression. 276 enum Expression; 277 } 278 279 impl<'a> ExpressionRef<'a> { 280 #[stacksafe::stacksafe] 281 pub fn validate(self, to: &mut Vec<Report>) { 282 match self { 283 Self::Parenthesis(parenthesis) => parenthesis.validate(to), 284 Self::List(list) => list.validate(to), 285 Self::Attributes(attributes) => attributes.validate(to), 286 Self::PrefixOperation(operation) => operation.validate(to), 287 Self::InfixOperation(operation) => operation.validate(to), 288 Self::SuffixOperation(operation) => operation.validate(to), 289 Self::Path(path) => path.validate(to), 290 Self::Bind(bind) => bind.validate(to), 291 Self::Identifier(identifier) => identifier.validate(to), 292 Self::SString(string) => string.validate(to), 293 Self::Char(char) => char.validate(to), 294 Self::Integer(integer) => integer.validate(to), 295 Self::Float(float) => float.validate(to), 296 Self::If(if_else) => if_else.validate(to), 297 298 Self::Error(_) => {}, 299 } 300 } 301 302 /// Iterates over all subexpressions delimited with the same operator. 303 pub fn same_items(self) -> impl Iterator<Item = ExpressionRef<'a>> { 304 gen move { 305 let mut expressions = VecDeque::from([self]); 306 307 while let Some(expression) = expressions.pop_back() { 308 match expression { 309 ExpressionRef::InfixOperation(operation) 310 if let InfixOperator::Same = operation.operator() => 311 { 312 if let Some(left) = operation.left() { 313 expressions.push_front(left); 314 } 315 if let Some(right) = operation.right() { 316 expressions.push_front(right); 317 } 318 }, 319 320 normal => yield normal, 321 } 322 } 323 } 324 } 325 } 326 327 // ERROR 328 329 node! { 330 #[from(NODE_ERROR)] 331 /// An error node. Also a valid expression. 332 struct Error; 333 } 334 335 // PARENTHESIS 336 337 node! { 338 #[from(NODE_PARENTHESIS)] 339 /// A parenthesis. Contains a single expression. 340 struct Parenthesis; 341 } 342 343 impl Parenthesis { 344 get_token! { token_parenthesis_left -> TOKEN_PARENTHESIS_LEFT } 345 346 get_node! { expression -> Option<ExpressionRef<'_>> } 347 348 get_token! { token_parenthesis_right -> Option<TOKEN_PARENTHESIS_RIGHT> } 349 350 pub fn validate(&self, to: &mut Vec<Report>) { 351 match self.expression() { 352 Some(expression) => { 353 expression.validate(to); 354 }, 355 356 None => { 357 to.push( 358 Report::error("parenthesis without inner expression").primary( 359 Span::empty(self.token_parenthesis_left().span().end), 360 "expected an expression here", 361 ), 362 ); 363 }, 364 } 365 366 if self.token_parenthesis_right().is_none() { 367 to.push( 368 Report::error("unclosed parenthesis") 369 .primary(Span::empty(self.span().end), "expected ')' here") 370 .secondary(self.token_parenthesis_left().span(), "unclosed '(' here"), 371 ); 372 } 373 } 374 } 375 376 // LIST 377 378 node! { 379 #[from(NODE_LIST)] 380 /// A list. Contains a list of expressions delimited by the same operator. 381 struct List; 382 } 383 384 impl List { 385 get_token! { token_bracket_left -> TOKEN_BRACKET_LEFT } 386 387 get_node! { expression -> Option<ExpressionRef<'_>> } 388 389 get_token! { token_bracket_right -> Option<TOKEN_BRACKET_RIGHT> } 390 391 /// Iterates over all the items of the list. 392 pub fn items(&self) -> impl Iterator<Item = ExpressionRef<'_>> { 393 self 394 .expression() 395 .into_iter() 396 .flat_map(ExpressionRef::same_items) 397 } 398 399 pub fn validate(&self, to: &mut Vec<Report>) { 400 if let Some(ExpressionRef::InfixOperation(operation)) = self.expression() 401 && operation.operator() == InfixOperator::Sequence 402 { 403 to.push( 404 Report::error("inner expression of list cannot be sequence") 405 .primary(operation.span(), "consider parenthesizing this"), 406 ); 407 } 408 409 for item in self.items() { 410 item.validate(to); 411 } 412 413 if self.token_bracket_right().is_none() { 414 to.push( 415 Report::error("unclosed list") 416 .primary(Span::empty(self.span().end), "expected ']' here") 417 .secondary(self.token_bracket_left().span(), "unclosed '[' here"), 418 ); 419 } 420 } 421 } 422 423 // ATTRIBUTES 424 425 node! { 426 #[from(NODE_ATTRIBUTES)] 427 /// Attributes. May contain an expression that contains binds, which get appended to its scope. 428 struct Attributes; 429 } 430 431 impl Attributes { 432 get_token! { token_curlybrace_left -> TOKEN_CURLYBRACE_LEFT } 433 434 get_node! { expression -> Option<ExpressionRef<'_>> } 435 436 get_token! { token_curlybrace_right -> Option<TOKEN_CURLYBRACE_RIGHT> } 437 438 pub fn validate(&self, to: &mut Vec<Report>) { 439 // TODO: Warn for non-binding children. 440 441 if self.token_curlybrace_right().is_none() { 442 to.push( 443 Report::error("unclosed attributes") 444 .primary(Span::empty(self.span().end), "expected '}' here") 445 .secondary(self.token_curlybrace_left().span(), "unclosed '{' here"), 446 ); 447 } 448 } 449 } 450 451 // PREFIX OPERATION 452 453 /// A prefix operator. 454 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 455 pub enum PrefixOperator { 456 Swwallation, // Get it? 457 Negation, 458 459 Not, 460 } 461 462 impl TryFrom<Kind> for PrefixOperator { 463 type Error = (); 464 465 fn try_from(from: Kind) -> Result<Self, ()> { 466 Ok(match from { 467 TOKEN_PLUS => Self::Swwallation, 468 TOKEN_MINUS => Self::Negation, 469 470 TOKEN_EXCLAMATION => Self::Not, 471 472 _ => return Err(()), 473 }) 474 } 475 } 476 477 impl PrefixOperator { 478 /// Returns the binding power of this operator. 479 #[must_use] 480 pub fn binding_power(self) -> ((), u16) { 481 match self { 482 Self::Swwallation | Self::Negation => ((), 145), 483 Self::Not => ((), 125), 484 } 485 } 486 } 487 488 node! { 489 #[from(NODE_PREFIX_OPERATION)] 490 /// A prefix operation. 491 struct PrefixOperation; 492 } 493 494 impl PrefixOperation { 495 get_node! { right -> 0 @ Option<ExpressionRef<'_>> } 496 497 /// Returns the operator token of this operation. 498 pub fn operator_token(&self) -> &red::Token { 499 self 500 .children_with_tokens() 501 .filter_map(red::ElementRef::into_token) 502 .find(|token| PrefixOperator::try_from(token.kind()).is_ok()) 503 .unwrap() 504 } 505 506 /// Returns the operator of this operation. 507 pub fn operator(&self) -> PrefixOperator { 508 self 509 .children_with_tokens() 510 .filter_map(red::ElementRef::into_token) 511 .find_map(|token| PrefixOperator::try_from(token.kind()).ok()) 512 .unwrap() 513 } 514 515 pub fn validate(&self, to: &mut Vec<Report>) { 516 if let Some(right) = self.right() { 517 right.validate(to); 518 } else { 519 // TODO: Temporary. 520 to.push( 521 Report::error("curried prefix functions aren't supported yet") 522 .primary(self.span(), "unsupported") 523 .tip("create a lambda instead"), 524 ); 525 } 526 } 527 } 528 529 // INFIX OPERATION 530 531 /// An infix operator. 532 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 533 pub enum InfixOperator { 534 Same, 535 Sequence, 536 537 ImplicitApply, 538 Apply, 539 Pipe, 540 541 Concat, 542 Construct, 543 544 Select, 545 Update, 546 547 LessOrEqual, 548 Less, 549 MoreOrEqual, 550 More, 551 552 Equal, 553 NotEqual, 554 555 And, 556 Or, 557 Implication, 558 559 All, 560 Any, 561 562 Addition, 563 Subtraction, 564 Multiplication, 565 Power, 566 Division, 567 568 Lambda, 569 } 570 571 impl TryFrom<Kind> for InfixOperator { 572 type Error = (); 573 574 fn try_from(from: Kind) -> Result<Self, ()> { 575 Ok(match from { 576 TOKEN_COMMA => Self::Same, 577 TOKEN_SEMICOLON => Self::Sequence, 578 579 kind if kind.is_argument() => Self::ImplicitApply, 580 TOKEN_LESS_PIPE => Self::Apply, 581 TOKEN_PIPE_MORE => Self::Pipe, 582 583 TOKEN_PLUS_PLUS => Self::Concat, 584 TOKEN_COLON => Self::Construct, 585 586 TOKEN_PERIOD => Self::Select, 587 TOKEN_SLASH_SLASH => Self::Update, 588 589 TOKEN_LESS_EQUAL => Self::LessOrEqual, 590 TOKEN_LESS => Self::Less, 591 TOKEN_MORE_EQUAL => Self::MoreOrEqual, 592 TOKEN_MORE => Self::More, 593 594 TOKEN_EQUAL => Self::Equal, 595 TOKEN_EXCLAMATION_EQUAL => Self::NotEqual, 596 597 TOKEN_AMPERSAND_AMPERSAND => Self::And, 598 TOKEN_PIPE_PIPE => Self::Or, 599 TOKEN_MINUS_MORE => Self::Implication, 600 601 TOKEN_AMPERSAND => Self::All, 602 TOKEN_PIPE => Self::Any, 603 604 TOKEN_PLUS => Self::Addition, 605 TOKEN_MINUS => Self::Subtraction, 606 TOKEN_ASTERISK => Self::Multiplication, 607 TOKEN_CARET => Self::Power, 608 TOKEN_SLASH => Self::Division, 609 610 TOKEN_EQUAL_MORE => Self::Lambda, 611 612 _ => return Err(()), 613 }) 614 } 615 } 616 617 impl InfixOperator { 618 /// Returns the binding power of this operator. 619 #[must_use] 620 pub fn binding_power(self) -> (u16, u16) { 621 match self { 622 Self::Select => (185, 180), 623 Self::ImplicitApply => (170, 175), 624 625 Self::Concat => (160, 165), 626 627 Self::Multiplication | Self::Division => (150, 155), 628 Self::Power => (155, 150), 629 630 // PrefixOperator::Swallation | PrefixOperator::Negation 631 Self::Addition | Self::Subtraction => (130, 135), 632 // PrefixOperator::Not 633 Self::Update => (110, 115), 634 635 Self::LessOrEqual | Self::Less | Self::MoreOrEqual | Self::More /* | PrefixOperator::Try */ => { 636 (100, 105) 637 }, 638 639 Self::Construct => (95, 90), 640 641 Self::And | Self::All => (85, 80), 642 Self::Or | Self::Any => (75, 70), 643 Self::Implication => (65, 60), 644 645 Self::Pipe => (50, 55), 646 Self::Apply => (55, 50), 647 648 Self::Lambda => (45, 40), 649 650 Self::Equal | Self::NotEqual => (35, 30), 651 652 Self::Same => (25, 20), 653 Self::Sequence => (15, 10), 654 } 655 } 656 657 /// Whether this operator actually owns a token. Not owning a token means 658 /// that the operator doesn't actually "exist". 659 #[must_use] 660 pub fn is_token_owning(self) -> bool { 661 self != Self::ImplicitApply 662 } 663 } 664 665 node! { 666 #[from(NODE_INFIX_OPERATION)] 667 /// An infix operation. 668 struct InfixOperation; 669 } 670 671 impl InfixOperation { 672 #[must_use] 673 pub fn left(&self) -> Option<ExpressionRef<'_>> { 674 let operator_token = self.operator_token(); 675 676 self 677 .children_with_tokens() 678 .take_while(|element| { 679 let Some(operator_token) = operator_token else { 680 // When there is no operator token, take it all. 681 return true; 682 }; 683 684 // Take part before token. 685 element 686 .into_token() 687 .is_none_or(|token| token != operator_token) 688 }) 689 .find_map(|element| <ExpressionRef<'_>>::try_from(element.into_node()?).ok()) 690 } 691 692 #[must_use] 693 pub fn right(&self) -> Option<ExpressionRef<'_>> { 694 let operator_token = self.operator_token(); 695 696 self 697 .children_with_tokens() 698 .skip_while(|element| { 699 let Some(operator_token) = operator_token else { 700 // When there is no operator token, don't skip. 701 return false; 702 }; 703 704 // Skip all until a token, aka the operator. 705 element 706 .into_token() 707 .is_none_or(|token| token != operator_token) 708 }) 709 .filter_map(|element| <ExpressionRef<'_>>::try_from(element.into_node()?).ok()) 710 .last() 711 } 712 713 /// Returns the operator token of this operation. 714 pub fn operator_token(&self) -> Option<&'_ red::Token> { 715 self 716 .children_with_tokens() 717 .filter_map(red::ElementRef::into_token) 718 .find(|token| InfixOperator::try_from(token.kind()).is_ok()) 719 } 720 721 /// Returns the operator of this operation. 722 pub fn operator(&self) -> InfixOperator { 723 self 724 .children_with_tokens() 725 .filter_map(red::ElementRef::into_token) 726 .find_map(|token| InfixOperator::try_from(token.kind()).ok()) 727 .unwrap_or(InfixOperator::ImplicitApply) 728 } 729 730 pub fn validate(&self, to: &mut Vec<Report>) { 731 let expressions = [self.left(), self.right()]; 732 733 // TODO: Temporary. 734 if expressions.iter().any(Option::is_none) { 735 to.push( 736 Report::error("curried infix functions aren't supported yet") 737 .primary(self.span(), "unsupported") 738 .tip("create a lambda instead"), 739 ); 740 return; 741 } 742 743 for expression in expressions.iter().flatten() { 744 expression.validate(to); 745 } 746 747 let operator = self.operator(); 748 let (InfixOperator::Apply | InfixOperator::Pipe) = operator else { 749 return; 750 }; 751 752 for expression in expressions.iter().flatten() { 753 if let &ExpressionRef::InfixOperation(operation) = expression 754 && let child_operator @ (InfixOperator::Apply | InfixOperator::Pipe) = 755 operation.operator() 756 && child_operator != operator 757 { 758 to.push( 759 Report::error("application and pipe operators do not associate") 760 .secondary(self.span(), "this") 761 .primary(operation.span(), "does not associate with this"), 762 ); 763 } 764 } 765 } 766 } 767 768 // SUFFIX OPERATION 769 770 /// A suffix operator. 771 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 772 pub enum SuffixOperator {} 773 774 impl TryFrom<Kind> for SuffixOperator { 775 type Error = (); 776 777 #[expect(clippy::match_single_binding)] 778 fn try_from(from: Kind) -> Result<Self, ()> { 779 match from { 780 _ => Err(()), 781 } 782 } 783 } 784 785 impl SuffixOperator { 786 /// Returns the binding power of this operator. 787 #[must_use] 788 pub fn binding_power(self) -> (u16, ()) { 789 match self {} 790 } 791 } 792 793 node! { 794 #[from(NODE_SUFFIX_OPERATION)] 795 /// A suffix operation. 796 struct SuffixOperation; 797 } 798 799 impl SuffixOperation { 800 get_node! { left -> 0 @ Option<ExpressionRef<'_>> } 801 802 /// Returns the operator token of this operation. 803 pub fn operator_token(&self) -> &'_ red::Token { 804 self 805 .children_with_tokens() 806 .filter_map(red::ElementRef::into_token) 807 .find(|token| SuffixOperator::try_from(token.kind()).is_ok()) 808 .unwrap() 809 } 810 811 /// Returns the operator of this operation. 812 pub fn operator(&self) -> SuffixOperator { 813 self 814 .children_with_tokens() 815 .filter_map(red::ElementRef::into_token) 816 .find_map(|token| SuffixOperator::try_from(token.kind()).ok()) 817 .unwrap() 818 } 819 820 pub fn validate(&self, to: &mut Vec<Report>) { 821 if let Some(left) = self.left() { 822 left.validate(to); 823 } 824 } 825 } 826 827 // INTERPOLATION 828 829 node! { 830 #[from(NODE_INTERPOLATION)] 831 /// Interpolation. Is a segment that has a single expression within. 832 struct Interpolation; 833 } 834 835 impl Interpolation { 836 get_token! { interpolation_token_start -> TOKEN_INTERPOLATION_START } 837 838 get_node! { expression -> ExpressionRef<'_> } 839 840 get_token! { interpolation_token_end -> Option<TOKEN_INTERPOLATION_END> } 841 } 842 843 // PATH 844 845 node! { 846 #[from(NODE_PATH)] 847 /// A path. 848 struct Path; 849 } 850 851 impl Segmented for Path {} 852 853 impl Path { 854 pub fn validate(&self, to: &mut Vec<Report>) { 855 // No `validate_closing` here because paths are always closed. 856 // It has no visible closing delimiter. 857 858 let mut report = lazy!(Report::error("invalid path")); 859 860 let segments = self.segments(); 861 segments.validate(to, &mut report); 862 863 // Only assert if the report wasn't initialized, because 864 // /etc/ssl\<newline-here> actually gets parsed as a 865 // multiline segment. And when that happens report is ready. 866 if !ready!(report) { 867 assert!(!segments.is_multiline); 868 } 869 870 if let Some(report) = read!(report) { 871 to.push(report); 872 } 873 } 874 } 875 876 // BIND 877 878 node! { 879 #[from(NODE_BIND)] 880 /// A bind. Contains an identifier to bind to when compared with a value. 881 struct Bind; 882 } 883 884 impl Bind { 885 get_token! { token_at -> TOKEN_AT } 886 887 get_node! { expression -> ExpressionRef<'_> } 888 889 #[must_use] 890 pub fn identifier(&self) -> &Identifier { 891 let ExpressionRef::Identifier(identifier) = self.expression() else { 892 unreachable!("node must be valid") 893 }; 894 895 identifier 896 } 897 898 pub fn validate(&self, to: &mut Vec<Report>) { 899 let identifier = self.expression(); 900 901 if let ExpressionRef::Identifier(identifier) = identifier { 902 identifier.validate(to); 903 } else if identifier.kind() != NODE_ERROR { 904 to.push(Report::error("invalid bind").primary( 905 identifier.span(), 906 format!( 907 "expected an identifier, not {kind}", 908 kind = identifier.kind() 909 ), 910 )); 911 } 912 } 913 } 914 915 // IDENTIFIER 916 917 node! { 918 #[from(NODE_IDENTIFIER)] 919 /// A quoted identifier. 920 struct IdentifierQuoted; 921 } 922 923 impl Segmented for IdentifierQuoted {} 924 925 impl IdentifierQuoted { 926 pub fn validate(&self, to: &mut Vec<Report>) { 927 let to_len = to.len(); 928 self.validate_closing(to, TOKEN_QUOTED_IDENTIFIER_END, "quoted identifier"); 929 if to_len != to.len() { 930 return; 931 } 932 933 let mut report = lazy!(Report::error("invalid quoted identifier")); 934 935 let segments = self.segments(); 936 segments.validate(to, &mut report); 937 938 if segments.is_multiline { 939 force!(report).push_primary(self.span(), "here"); 940 force!(report).push_tip("quoted identifiers cannot contain newlines"); 941 } 942 943 if let Some(report) = read!(report) { 944 to.push(report); 945 } 946 } 947 } 948 949 reffed! { 950 /// An identifier value. 951 #[derive(Debug, Clone, PartialEq, Eq, Hash)] 952 pub enum IdentifierValue { 953 /// A plain identifier backed by a [`token::Identifier`]. 954 Plain(token::Identifier), 955 /// A quoted identifier backed by a [`IdentifierQuoted`]. 956 Quoted(IdentifierQuoted), 957 } 958 } 959 960 impl IdentifierValueRef<'_> { 961 /// Return whether this value can be treated as a literal. 962 #[must_use] 963 pub fn is_trivial(self) -> bool { 964 match self { 965 IdentifierValueRef::Plain(_) => true, 966 IdentifierValueRef::Quoted(quoted) => quoted.is_trivial(), 967 } 968 } 969 } 970 971 node! { 972 #[from(NODE_IDENTIFIER)] 973 /// An identifier. Can either be a raw identifier token or a quoted identifier. 974 struct Identifier; 975 } 976 977 impl Identifier { 978 /// Returns the value of this identifier. A value may either be a 979 /// [`token::Identifier`] or a [`IdentifierQuoted`]. 980 #[must_use] 981 pub fn value(&self) -> IdentifierValueRef<'_> { 982 let first_token = self 983 .first_token() 984 .expect("identifier node must have children"); 985 986 assert!( 987 !first_token.kind().is_trivia(), 988 "identifier node's first child must not be trivia" 989 ); 990 991 if let Ok(token) = <&token::Identifier>::try_from(first_token) { 992 return IdentifierValueRef::Plain(token); 993 } 994 995 if let Ok(quoted) = <&IdentifierQuoted>::try_from(&**self) { 996 return IdentifierValueRef::Quoted(quoted); 997 } 998 999 unreachable!("identifier node must contain an identifier token or quoted identifier") 1000 } 1001 1002 pub fn validate(&self, to: &mut Vec<Report>) { 1003 if let IdentifierValueRef::Quoted(quoted) = self.value() { 1004 quoted.validate(to); 1005 } 1006 } 1007 } 1008 1009 // STRING 1010 1011 node! { 1012 #[from(NODE_STRING)] 1013 /// A string. 1014 struct SString; 1015 } 1016 1017 impl Segmented for SString {} 1018 1019 impl SString { 1020 pub fn validate(&self, to: &mut Vec<Report>) { 1021 let to_len = to.len(); 1022 self.validate_closing(to, TOKEN_STRING_END, "string"); 1023 if to_len != to.len() { 1024 return; 1025 } 1026 1027 let mut report = lazy!(Report::error("invalid string")); 1028 1029 let segments = self.segments(); 1030 segments.validate(to, &mut report); 1031 1032 if let Some(report) = read!(report) { 1033 to.push(report); 1034 } 1035 } 1036 } 1037 1038 // CHAR 1039 1040 node! { 1041 #[from(NODE_CHAR)] 1042 /// A character. 1043 struct Char; 1044 } 1045 1046 impl Segmented for Char {} 1047 1048 impl Char { 1049 #[must_use] 1050 pub fn value(&self) -> char { 1051 let Segment::Content { content, .. } = self.segments().into_iter().next().unwrap() else { 1052 unreachable!() 1053 }; 1054 1055 content.chars().next().unwrap() 1056 } 1057 1058 pub fn validate(&self, to: &mut Vec<Report>) { 1059 let to_len = to.len(); 1060 self.validate_closing(to, TOKEN_CHAR_END, "char"); 1061 if to_len != to.len() { 1062 return; 1063 } 1064 1065 let mut report = lazy!(Report::error("invalid char")); 1066 1067 let segments = self.segments(); 1068 segments.validate(to, &mut report); 1069 1070 if segments.is_multiline { 1071 force!(report).push_primary(self.span(), "chars cannot cannot contain newlines"); 1072 } 1073 1074 if !ready!(report) { 1075 let mut got: usize = 0; 1076 for segment in segments { 1077 match segment { 1078 Segment::Content { content, .. } => { 1079 got += content.chars().count(); 1080 }, 1081 1082 Segment::Interpolation(interpolation) => { 1083 force!(report) 1084 .push_primary(interpolation.span(), "chars cannot contain interpolation"); 1085 }, 1086 } 1087 } 1088 1089 match got { 1090 0 => force!(report).push_primary(self.span(), "empty char"), 1091 1 => {}, 1092 _ => force!(report).push_primary(self.span(), "too long"), 1093 } 1094 } 1095 1096 if let Some(report) = read!(report) { 1097 to.push(report); 1098 } 1099 } 1100 } 1101 1102 // INTEGER 1103 1104 node! { 1105 #[from(NODE_INTEGER)] 1106 /// An integer. 1107 struct Integer; 1108 } 1109 1110 impl Integer { 1111 get_token! { token_integer -> &token::Integer } 1112 1113 #[must_use] 1114 pub fn value(&self) -> num::BigInt { 1115 self.token_integer().value().expect("integer must be valid") 1116 } 1117 1118 pub fn validate(&self, to: &mut Vec<Report>) { 1119 if self.token_integer().value().is_err() { 1120 to.push( 1121 Report::error("invalid integer").primary(self.span(), "why do you even need this?"), 1122 ); 1123 } 1124 } 1125 } 1126 1127 // FLOAT 1128 1129 node! { 1130 #[from(NODE_FLOAT)] 1131 /// A float. 1132 struct Float; 1133 } 1134 1135 impl Float { 1136 get_token! { token_float -> &token::Float } 1137 1138 #[must_use] 1139 pub fn value(&self) -> f64 { 1140 self.token_float().value().expect("float must be valid") 1141 } 1142 1143 pub fn validate(&self, to: &mut Vec<Report>) { 1144 if self.token_float().value().is_err() { 1145 to.push(Report::error("invalid float").primary(self.span(), "usecase?")); 1146 } 1147 } 1148 } 1149 1150 // IF 1151 1152 node! { 1153 #[from(NODE_IF)] 1154 /// An if-else. 1155 struct If; 1156 } 1157 1158 impl If { 1159 get_token! { token_if -> TOKEN_KEYWORD_IF } 1160 1161 get_node! { condition -> 0 @ ExpressionRef<'_> } 1162 1163 get_token! { token_then -> Option<TOKEN_KEYWORD_THEN> } 1164 1165 get_node! { consequence -> 1 @ ExpressionRef<'_> } 1166 1167 get_token! { token_else -> Option<TOKEN_KEYWORD_ELSE> } 1168 1169 get_node! { alternative -> 2 @ ExpressionRef<'_> } 1170 1171 pub fn validate(&self, to: &mut Vec<Report>) { 1172 self.condition().validate(to); 1173 self.consequence().validate(to); 1174 self.alternative().validate(to); 1175 } 1176 }