Show name of user-defined functions in representation 🦋

This commit is contained in:
Laurenz 2021-03-03 18:15:33 +01:00
parent c94a18833f
commit 1cfc3c72b5
5 changed files with 31 additions and 17 deletions

View File

@ -401,7 +401,8 @@ impl Eval for ExprClosure {
visitor.finish()
};
Value::Func(ValueFunc::new(None, move |ctx, args| {
let name = self.name.as_ref().map(|id| id.to_string());
Value::Func(ValueFunc::new(name, move |ctx, args| {
// Don't leak the scopes from the call site. Instead, we use the
// scope of captured variables we collected earlier.
let prev = std::mem::take(&mut ctx.scopes);

View File

@ -190,13 +190,13 @@ fn primary(p: &mut Parser) -> Option<Expr> {
// Arrow means this is closure's lone parameter.
if p.eat_if(Token::Arrow) {
return expr(p).map(|body| {
Expr::Closure(ExprClosure {
span: ident.span.join(body.span()),
params: Rc::new(vec![ident]),
body: Rc::new(body),
})
});
let body = expr(p)?;
return Some(Expr::Closure(ExprClosure {
span: ident.span.join(body.span()),
name: None,
params: Rc::new(vec![ident]),
body: Rc::new(body),
}));
}
Some(Expr::Ident(ident))
@ -263,13 +263,13 @@ pub fn parenthesized(p: &mut Parser) -> Option<Expr> {
// Arrow means this is closure's parameter list.
if p.eat_if(Token::Arrow) {
let params = params(p, items);
return expr(p).map(|body| {
Expr::Closure(ExprClosure {
span: span.join(body.span()),
params: Rc::new(params),
body: Rc::new(body),
})
});
let body = expr(p)?;
return Some(Expr::Closure(ExprClosure {
span: span.join(body.span()),
name: None,
params: Rc::new(params),
body: Rc::new(body),
}));
}
// Find out which kind of collection this is.
@ -509,6 +509,7 @@ fn expr_let(p: &mut Parser) -> Option<Expr> {
let body = init?;
init = Some(Expr::Closure(ExprClosure {
span: binding.span.join(body.span()),
name: Some(binding.clone()),
params: Rc::new(params),
body: Rc::new(body),
}));

View File

@ -27,7 +27,7 @@ pub enum Expr {
Binary(ExprBinary),
/// An invocation of a function: `f(x, y)`.
Call(ExprCall),
/// A closure expression: `(x, y) => { z }`.
/// A closure expression: `(x, y) => z`.
Closure(ExprClosure),
/// A let expression: `let x = 1`.
Let(ExprLet),
@ -414,11 +414,15 @@ impl ExprArg {
}
}
/// A closure expression: `(x, y) => { z }`.
/// A closure expression: `(x, y) => z`.
#[derive(Debug, Clone, PartialEq)]
pub struct ExprClosure {
/// The source code location.
pub span: Span,
/// The name of the closure.
///
/// This only exists if you use the function syntax sugar: `let f(x) = y`.
pub name: Option<Ident>,
/// The parameter bindings.
pub params: Rc<Vec<Ident>>,
/// The body of the closure.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -48,3 +48,11 @@
---
// Templates.
{[*{"H" + "i"} there*]}
---
// Functions
#let f(x) = x
{box} \
{f} \
{() => none} \