parser: support basic declare statements

This commit is contained in:
Ryan Chandler 2022-09-13 00:53:18 +01:00
parent 980b1c1d9c
commit a48258146d
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
2 changed files with 50 additions and 2 deletions

View File

@ -300,9 +300,18 @@ pub enum Statement {
Global { Global {
vars: Vec<Identifier>, vars: Vec<Identifier>,
}, },
Declare {
declares: Vec<DeclareItem>,
},
Noop, Noop,
} }
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct DeclareItem {
pub key: Identifier,
pub value: Expression,
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize)] #[derive(Debug, Clone, Eq, PartialEq, Serialize)]
pub enum CastKind { pub enum CastKind {
String, String,

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
ast::{ ast::{
Arg, ArrayItem, BackedEnumType, ClassFlag, ClosureUse, ElseIf, IncludeKind, MagicConst, Arg, ArrayItem, BackedEnumType, ClassFlag, ClosureUse, ElseIf, IncludeKind, MagicConst,
MethodFlag, StaticVar, Use, UseKind, MethodFlag, StaticVar, Use, UseKind, DeclareItem,
}, },
Block, Case, Catch, Expression, Identifier, MatchArm, Program, Statement, Type, Block, Case, Catch, Expression, Identifier, MatchArm, Program, Statement, Type,
}; };
@ -169,6 +169,31 @@ impl Parser {
self.skip_comments(); self.skip_comments();
let statement = match &self.current.kind { let statement = match &self.current.kind {
TokenKind::Declare => {
self.next();
self.lparen()?;
let mut declares = Vec::new();
while self.current.kind != TokenKind::RightParen {
let key = self.ident()?;
expect!(self, TokenKind::Equals, "expected =");
let value = self.expression(0)?;
self.optional_comma()?;
declares.push(DeclareItem {
key: key.into(),
value,
});
}
self.rparen()?;
self.semi()?;
Statement::Declare { declares }
},
TokenKind::Global => { TokenKind::Global => {
self.next(); self.next();
@ -2151,7 +2176,7 @@ impl Display for ParseError {
mod tests { mod tests {
use super::Parser; use super::Parser;
use crate::{ use crate::{
ast::{Arg, ArrayItem, ElseIf, IncludeKind, InfixOp, MethodFlag, PropertyFlag}, ast::{Arg, ArrayItem, ElseIf, IncludeKind, InfixOp, MethodFlag, PropertyFlag, DeclareItem},
Catch, Expression, Identifier, Param, Statement, Type, Catch, Expression, Identifier, Param, Statement, Type,
}; };
use trunk_lexer::Lexer; use trunk_lexer::Lexer;
@ -3338,6 +3363,20 @@ mod tests {
); );
} }
#[test]
fn basic_declare() {
assert_ast("<?php declare(A='B');", &[
Statement::Declare {
declares: vec![
DeclareItem {
key: "A".into(),
value: Expression::ConstantString { value: "B".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();