diff --git a/trunk_parser/src/ast.rs b/trunk_parser/src/ast.rs index 2ebaf33..48b0fdb 100644 --- a/trunk_parser/src/ast.rs +++ b/trunk_parser/src/ast.rs @@ -352,7 +352,7 @@ pub enum Expression { }, Closure { params: Vec, - uses: Vec, + uses: Vec, return_type: Option, 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>, diff --git a/trunk_parser/src/parser/mod.rs b/trunk_parser/src/parser/mod.rs index f197bf4..6a500f1 100644 --- a/trunk_parser/src/parser/mod.rs +++ b/trunk_parser/src/parser/mod.rs @@ -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 = Result; @@ -1144,9 +1144,19 @@ impl Parser { 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)) + 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);