diff --git a/trunk_lexer/src/lexer.rs b/trunk_lexer/src/lexer.rs index fad860d..b30cfaf 100644 --- a/trunk_lexer/src/lexer.rs +++ b/trunk_lexer/src/lexer.rs @@ -808,6 +808,7 @@ fn identifier_to_keyword(ident: &[u8]) -> Option { b"for" => TokenKind::For, b"foreach" => TokenKind::Foreach, b"function" => TokenKind::Function, + b"goto" => TokenKind::Goto, b"if" => TokenKind::If, b"include" => TokenKind::Include, b"include_once" => TokenKind::IncludeOnce, diff --git a/trunk_lexer/src/token.rs b/trunk_lexer/src/token.rs index 67e8b3c..90710f7 100644 --- a/trunk_lexer/src/token.rs +++ b/trunk_lexer/src/token.rs @@ -91,6 +91,7 @@ pub enum TokenKind { Foreach, FullyQualifiedIdentifier(ByteString), Function, + Goto, GreaterThan, GreaterThanEquals, Identifier(ByteString), @@ -259,6 +260,7 @@ impl Display for TokenKind { return write!(f, "{}", String::from_utf8_lossy(id)); } Self::Function => "function", + Self::Goto => "goto", Self::GreaterThan => ">", Self::GreaterThanEquals => ">=", Self::Identifier(id) => { diff --git a/trunk_parser/src/ast.rs b/trunk_parser/src/ast.rs index 44b4aaa..e728da2 100644 --- a/trunk_parser/src/ast.rs +++ b/trunk_parser/src/ast.rs @@ -178,6 +178,9 @@ impl From<&TokenKind> for IncludeKind { #[derive(Debug, PartialEq, Clone)] pub enum Statement { InlineHtml(ByteString), + Goto { + label: Identifier, + }, HaltCompiler { content: Option, }, diff --git a/trunk_parser/src/parser/mod.rs b/trunk_parser/src/parser/mod.rs index 016f080..84372c1 100644 --- a/trunk_parser/src/parser/mod.rs +++ b/trunk_parser/src/parser/mod.rs @@ -171,6 +171,15 @@ impl Parser { self.skip_comments(); let statement = match &self.current.kind { + TokenKind::Goto => { + self.next(); + + let label = self.ident()?.into(); + + self.semi()?; + + Statement::Goto { label } + }, TokenKind::HaltCompiler => { self.next(); @@ -4078,6 +4087,13 @@ mod tests { ); } + #[test] + fn simple_goto() { + assert_ast("