parser: support shorthand while

This commit is contained in:
Ryan Chandler 2022-09-22 20:20:56 +01:00
parent f3b01d1812
commit b534d2c9d4
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
2 changed files with 28 additions and 3 deletions

View File

@ -1084,6 +1084,7 @@ fn parse_int(buffer: &str, base: u32) -> Result<TokenKind, LexerError> {
fn identifier_to_keyword(ident: &[u8]) -> Option<TokenKind> { fn identifier_to_keyword(ident: &[u8]) -> Option<TokenKind> {
Some(match ident { Some(match ident {
b"endwhile" => TokenKind::EndWhile,
b"endforeach" => TokenKind::EndForeach, b"endforeach" => TokenKind::EndForeach,
b"endif" => TokenKind::EndIf, b"endif" => TokenKind::EndIf,
b"from" => TokenKind::From, b"from" => TokenKind::From,

View File

@ -308,11 +308,23 @@ impl Parser {
let condition = self.expression(Precedence::Lowest)?; let condition = self.expression(Precedence::Lowest)?;
self.rparen()?; self.rparen()?;
self.lbrace()?;
let body = self.block(&TokenKind::RightBrace)?; let end_token = if self.current.kind == TokenKind::Colon {
self.colon()?;
TokenKind::EndWhile
} else {
self.lbrace()?;
TokenKind::RightBrace
};
self.rbrace()?; let body = self.block(&end_token)?;
if end_token == TokenKind::RightBrace {
self.rbrace()?;
} else {
expect!(self, TokenKind::EndWhile, "expected endwhile");
self.semi()?;
}
Statement::While { condition, body } Statement::While { condition, body }
} }
@ -5150,6 +5162,18 @@ mod tests {
); );
} }
#[test]
fn short_while() {
assert_ast("<?php while (true): $a; endwhile;", &[
Statement::While {
condition: Expression::Bool { value: true },
body: vec![
expr!(Expression::Variable { name: "a".into() })
]
}
]);
}
fn assert_ast(source: &str, expected: &[Statement]) { fn assert_ast(source: &str, expected: &[Statement]) {
let mut lexer = Lexer::new(None); let mut lexer = Lexer::new(None);
let tokens = lexer.tokenize(source).unwrap(); let tokens = lexer.tokenize(source).unwrap();