diff --git a/trunk_parser/src/ast.rs b/trunk_parser/src/ast.rs index 9a07530..4dd832e 100644 --- a/trunk_parser/src/ast.rs +++ b/trunk_parser/src/ast.rs @@ -300,9 +300,18 @@ pub enum Statement { Global { vars: Vec, }, + Declare { + declares: Vec, + }, Noop, } +#[derive(Debug, Clone, PartialEq, Serialize)] +pub struct DeclareItem { + pub key: Identifier, + pub value: Expression, +} + #[derive(Debug, Clone, Eq, PartialEq, Serialize)] pub enum CastKind { String, diff --git a/trunk_parser/src/parser/mod.rs b/trunk_parser/src/parser/mod.rs index 7e65477..6f8e122 100644 --- a/trunk_parser/src/parser/mod.rs +++ b/trunk_parser/src/parser/mod.rs @@ -1,7 +1,7 @@ use crate::{ ast::{ 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, }; @@ -169,6 +169,31 @@ impl Parser { self.skip_comments(); 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 => { self.next(); @@ -2151,7 +2176,7 @@ impl Display for ParseError { mod tests { use super::Parser; 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, }; use trunk_lexer::Lexer; @@ -3338,6 +3363,20 @@ mod tests { ); } + #[test] + fn basic_declare() { + assert_ast("