parser: support break statements

This commit is contained in:
Ryan Chandler 2022-07-27 20:59:20 +01:00
parent e3a0e3e62f
commit 3ad45e6d1e
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
3 changed files with 29 additions and 0 deletions

View File

@ -621,6 +621,7 @@ fn identifier_to_keyword(ident: &str) -> Option<TokenKind> {
Some(match ident {
"abstract" => TokenKind::Abstract,
"as" => TokenKind::As,
"break" => TokenKind::Break,
"class" => TokenKind::Class,
"const" => TokenKind::Const,
"declare" => TokenKind::Declare,

View File

@ -184,6 +184,9 @@ pub enum Statement {
Return {
value: Option<Expression>,
},
Break {
num: Option<Expression>,
},
Echo {
values: Vec<Expression>,
},

View File

@ -361,6 +361,20 @@ impl Parser {
expect!(self, TokenKind::SemiColon, "expected semi-colon at the end of an echo statement");
Statement::Echo { values }
},
TokenKind::Break => {
self.next();
let mut num = None;
if self.current.kind != TokenKind::SemiColon {
num = Some(self.expression(0)?);
}
dbg!(&self.current.kind);
expect!(self, TokenKind::SemiColon, "expected semi-colon");
Statement::Break { num }
},
TokenKind::Return => {
self.next();
@ -982,6 +996,17 @@ mod tests {
]);
}
#[test]
fn breaks() {
assert_ast("<?php break;", &[
Statement::Break { num: None }
]);
assert_ast("<?php break 2;", &[
Statement::Break { num: Some(Expression::Int(2)) }
]);
}
#[test]
fn math_precedence() {
assert_ast("<?php 1 + 2 * 3 / 4 - 5;", &[