diff --git a/trunk_lexer/src/lexer.rs b/trunk_lexer/src/lexer.rs index f5b5f29..a245255 100644 --- a/trunk_lexer/src/lexer.rs +++ b/trunk_lexer/src/lexer.rs @@ -167,6 +167,11 @@ impl Lexer { let char = self.current.unwrap(); let kind = match char { + '@' => { + self.col += 1; + + TokenKind::At + } '!' => { self.col += 1; diff --git a/trunk_lexer/src/token.rs b/trunk_lexer/src/token.rs index f18d89e..99da139 100644 --- a/trunk_lexer/src/token.rs +++ b/trunk_lexer/src/token.rs @@ -17,6 +17,7 @@ pub enum TokenKind { ArrayCast, Arrow, NullsafeArrow, + At, As, Asterisk, Attribute, diff --git a/trunk_parser/src/ast.rs b/trunk_parser/src/ast.rs index 1351c6e..cadbb33 100644 --- a/trunk_parser/src/ast.rs +++ b/trunk_parser/src/ast.rs @@ -376,6 +376,9 @@ pub struct Use { #[derive(Debug, PartialEq, Clone, Serialize)] pub enum Expression { Static, + ErrorSuppress { + expr: Box, + }, Increment { value: Box, }, diff --git a/trunk_parser/src/parser/mod.rs b/trunk_parser/src/parser/mod.rs index 881ab74..575abc3 100644 --- a/trunk_parser/src/parser/mod.rs +++ b/trunk_parser/src/parser/mod.rs @@ -1993,6 +1993,7 @@ fn is_prefix(op: &TokenKind) -> bool { | TokenKind::BoolCast | TokenKind::IntCast | TokenKind::DoubleCast + | TokenKind::At ) } @@ -2003,8 +2004,9 @@ fn prefix_binding_power(op: &TokenKind) -> u8 { | TokenKind::BoolCast | TokenKind::IntCast | TokenKind::DoubleCast => 101, - TokenKind::Minus => 100, - TokenKind::Bang => 99, + TokenKind::At => 16, + TokenKind::Minus => 99, + TokenKind::Bang => 98, _ => unreachable!(), } } @@ -2025,6 +2027,9 @@ fn prefix(op: &TokenKind, rhs: Expression) -> Expression { kind: op.into(), value: Box::new(rhs), }, + TokenKind::At => Expression::ErrorSuppress { + expr: Box::new(rhs), + }, _ => unreachable!(), } } @@ -3157,6 +3162,21 @@ mod tests { ); } + #[test] + fn error_suppress() { + assert_ast( + "