From 422b8e640f00977177a5a7250a3c56009eed10c4 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sat, 26 Jun 2021 18:07:05 +0200 Subject: With expressions --- src/syntax/expr.rs | 18 +++++++++++++++++- src/syntax/token.rs | 3 +++ src/syntax/visit.rs | 6 ++++++ 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'src/syntax') diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 24850d65..62f02399 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -52,6 +52,8 @@ pub enum Expr { Call(CallExpr), /// A closure expression: `(x, y) => z`. Closure(ClosureExpr), + /// A with expression: `f with (x, y: 1)`. + With(WithExpr), /// A let expression: `let x = 1`. Let(LetExpr), /// An if-else expression: `if x { y } else { z }`. @@ -91,6 +93,7 @@ impl Expr { Self::Binary(ref v) => v.span, Self::Call(ref v) => v.span, Self::Closure(ref v) => v.span, + Self::With(ref v) => v.span, Self::Let(ref v) => v.span, Self::If(ref v) => v.span, Self::While(ref v) => v.span, @@ -383,7 +386,7 @@ pub enum Associativity { pub struct CallExpr { /// The source code location. pub span: Span, - /// The callee of the function. + /// The function to call. pub callee: Box, /// The arguments to the function. pub args: CallArgs, @@ -435,6 +438,19 @@ pub struct ClosureExpr { pub body: Rc, } +/// A with expression: `f with (x, y: 1)`. +/// +/// Applies arguments to a function. +#[derive(Debug, Clone, PartialEq)] +pub struct WithExpr { + /// The source code location. + pub span: Span, + /// The function to apply the arguments to. + pub callee: Box, + /// The arguments to apply to the function. + pub args: CallArgs, +} + /// A let expression: `let x = 1`. #[derive(Debug, Clone, PartialEq)] pub struct LetExpr { diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 254a56a2..3f07bb33 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -74,6 +74,8 @@ pub enum Token<'s> { And, /// The `or` operator. Or, + /// The `with` operator. + With, /// The none literal: `none`. None, /// The auto literal: `auto`. @@ -241,6 +243,7 @@ impl<'s> Token<'s> { Self::Not => "operator `not`", Self::And => "operator `and`", Self::Or => "operator `or`", + Self::With => "operator `with`", Self::None => "`none`", Self::Auto => "`auto`", Self::Let => "keyword `let`", diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs index a1a848ef..cf819ef0 100644 --- a/src/syntax/visit.rs +++ b/src/syntax/visit.rs @@ -99,6 +99,7 @@ visit! { Expr::Binary(e) => v.visit_binary(e), Expr::Call(e) => v.visit_call(e), Expr::Closure(e) => v.visit_closure(e), + Expr::With(e) => v.visit_with(e), Expr::Let(e) => v.visit_let(e), Expr::If(e) => v.visit_if(e), Expr::While(e) => v.visit_while(e), @@ -176,6 +177,11 @@ visit! { } } + fn visit_with(v, node: &WithExpr) { + v.visit_expr(&node.callee); + v.visit_args(&node.args); + } + fn visit_let(v, node: &LetExpr) { v.visit_binding(&node.binding); if let Some(init) = &node.init { -- cgit v1.2.3