/ cab / syntax / node.rs
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  }