parser: support using closure args by ref

This commit is contained in:
Ryan Chandler 2022-08-09 11:39:40 +01:00
parent 4aa3b3af6b
commit 698aef1afc
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
2 changed files with 21 additions and 5 deletions

View File

@ -352,7 +352,7 @@ pub enum Expression {
},
Closure {
params: Vec<Param>,
uses: Vec<Expression>,
uses: Vec<ClosureUse>,
return_type: Option<Type>,
body: Block
},
@ -438,6 +438,12 @@ pub enum Expression {
},
}
#[derive(Debug, PartialEq, Clone, Serialize)]
pub struct ClosureUse {
pub var: Expression,
pub by_ref: bool,
}
#[derive(Debug, PartialEq, Clone, Serialize)]
pub struct MatchArm {
pub conditions: Option<Vec<Expression>>,

View File

@ -1,6 +1,6 @@
use std::{vec::IntoIter, fmt::{Display}};
use trunk_lexer::{Token, TokenKind, Span};
use crate::{Program, Statement, Block, Expression, ast::{ArrayItem, Use, MethodFlag, ClassFlag, ElseIf, UseKind, MagicConst, BackedEnumType}, Identifier, Type, MatchArm, Catch, Case};
use crate::{Program, Statement, Block, Expression, ast::{ArrayItem, Use, MethodFlag, ClassFlag, ElseIf, UseKind, MagicConst, BackedEnumType, ClosureUse}, Identifier, Type, MatchArm, Catch, Case};
type ParseResult<T> = Result<T, ParseError>;
@ -1144,9 +1144,19 @@ impl Parser {
self.lparen()?;
while self.current.kind != TokenKind::RightParen {
let var = match self.expression(0)? {
s @ Expression::Variable { .. } => s,
let var = match self.current.kind {
TokenKind::Ampersand => {
self.next();
match self.expression(0)? {
s @ Expression::Variable { .. } => ClosureUse { var: s, by_ref: true },
_ => return Err(ParseError::UnexpectedToken("expected variable".into(), self.current.span))
}
},
_ => match self.expression(0)? {
s @ Expression::Variable { .. } => ClosureUse { var: s, by_ref: false },
_ => return Err(ParseError::UnexpectedToken("expected variable".into(), self.current.span))
}
};
uses.push(var);