parser: support use list in closures

This commit is contained in:
Ryan Chandler 2022-07-28 13:38:16 +01:00
parent 6ba2532af6
commit b4e11bd6bd
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
3 changed files with 27 additions and 2 deletions

View File

@ -0,0 +1,3 @@
<?php
$foo = function () use ($bar) {};

View File

@ -260,7 +260,7 @@ pub enum Expression {
Identifier(String), Identifier(String),
Assign(Box<Self>, Box<Self>), Assign(Box<Self>, Box<Self>),
Array(Vec<ArrayItem>), Array(Vec<ArrayItem>),
Closure(Vec<Param>, Option<Type>, Block), Closure(Vec<Param>, Vec<Expression>, Option<Type>, Block),
ArrowFunction(Vec<Param>, Option<Type>, Box<Self>), ArrowFunction(Vec<Param>, Option<Type>, Box<Self>),
New(Box<Self>, Vec<Self>), New(Box<Self>, Vec<Self>),
ConstantString(String), ConstantString(String),

View File

@ -757,6 +757,28 @@ impl Parser {
self.rparen()?; self.rparen()?;
let mut uses = vec![];
if self.current.kind == TokenKind::Use {
self.next();
self.lparen()?;
while self.current.kind != TokenKind::RightParen {
let var = match self.expression(0)? {
s @ Expression::Variable(_) => s,
_ => return Err(ParseError::UnexpectedToken("expected variable".into(), self.current.span))
};
uses.push(var);
if self.current.kind == TokenKind::Comma {
self.next();
}
}
self.rparen()?;
}
let mut return_type = None; let mut return_type = None;
if self.current.kind == TokenKind::Colon { if self.current.kind == TokenKind::Colon {
self.next(); self.next();
@ -770,7 +792,7 @@ impl Parser {
self.rbrace()?; self.rbrace()?;
Expression::Closure(params, return_type, body) Expression::Closure(params, uses, return_type, body)
}, },
TokenKind::Fn => { TokenKind::Fn => {
self.next(); self.next();