Merge pull request #35 from ryangjchandler/feature/do-while-loops

This commit is contained in:
Ryan Chandler 2022-09-12 12:11:56 +01:00 committed by GitHub
commit 028e2de1d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 0 deletions

View File

@ -833,6 +833,7 @@ fn identifier_to_keyword(ident: &str) -> Option<TokenKind> {
"const" => TokenKind::Const,
"declare" => TokenKind::Declare,
"default" => TokenKind::Default,
"do" => TokenKind::Do,
"echo" => TokenKind::Echo,
"else" => TokenKind::Else,
"elseif" => TokenKind::ElseIf,

View File

@ -169,6 +169,10 @@ pub enum Statement {
Static {
vars: Vec<StaticVar>,
},
DoWhile {
condition: Expression,
body: Block,
},
While {
condition: Expression,
body: Block,

View File

@ -193,6 +193,22 @@ impl Parser {
self.next();
s
}
TokenKind::Do => {
self.next();
self.lbrace()?;
let body = self.block(&TokenKind::RightBrace)?;
self.rbrace()?;
expect!(self, TokenKind::While, "expected while");
self.lparen()?;
let condition = self.expression(0)?;
self.rparen()?;
self.semi()?;
Statement::DoWhile { condition, body }
}
TokenKind::While => {
self.next();
self.lparen()?;
@ -3045,6 +3061,33 @@ mod tests {
);
}
#[test]
fn do_while() {
assert_ast(
"<?php do { } while ($a);",
&[Statement::DoWhile {
condition: Expression::Variable { name: "a".into() },
body: vec![],
}],
);
assert_ast(
"<?php
do {
echo 'Hi!';
} while (true);
",
&[Statement::DoWhile {
condition: Expression::Bool { value: true },
body: vec![Statement::Echo {
values: vec![Expression::ConstantString {
value: "Hi!".into(),
}],
}],
}],
)
}
fn assert_ast(source: &str, expected: &[Statement]) {
let mut lexer = Lexer::new(None);
let tokens = lexer.tokenize(source).unwrap();