parser: support short foreach statement

This commit is contained in:
Ryan Chandler 2022-09-19 11:24:45 +01:00
parent ea5919a85d
commit 2492a82bcc
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
2 changed files with 31 additions and 3 deletions

View File

@ -1020,6 +1020,7 @@ impl Lexer {
fn identifier_to_keyword(ident: &[u8]) -> Option<TokenKind> {
Some(match ident {
b"endforeach" => TokenKind::EndForeach,
b"endif" => TokenKind::EndIf,
b"from" => TokenKind::From,
b"and" => TokenKind::LogicalAnd,

View File

@ -396,11 +396,23 @@ impl Parser {
}
self.rparen()?;
self.lbrace()?;
let body = self.block(&TokenKind::RightBrace)?;
let end_token = if self.current.kind == TokenKind::Colon {
self.colon()?;
TokenKind::EndForeach
} else {
self.lbrace()?;
TokenKind::RightBrace
};
self.rbrace()?;
let body = self.block(&end_token)?;
if end_token == TokenKind::EndForeach {
expect!(self, TokenKind::EndForeach, "expected endforeach");
self.semi()?;
} else {
self.rbrace()?;
}
Statement::Foreach {
expr,
@ -5111,6 +5123,21 @@ mod tests {
)
}
#[test]
fn short_foreach() {
assert_ast("<?php foreach ($a as $b): $c; endforeach;", &[
Statement::Foreach {
expr: Expression::Variable { name: "a".into() },
by_ref: false,
key_var: None,
value_var: Expression::Variable { name: "b".into() },
body: vec![
expr!(Expression::Variable { name: "c".into() })
]
}
]);
}
fn assert_ast(source: &str, expected: &[Statement]) {
let mut lexer = Lexer::new(None);
let tokens = lexer.tokenize(source).unwrap();