diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-03-03 17:53:40 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-03-03 17:53:40 +0100 |
| commit | c94a18833f23d2b57de1b87971458fd54b56d088 (patch) | |
| tree | 9e1ed55cfca15aef6d39ced50a3a5b14d2800aae /src/pretty.rs | |
| parent | 4d90a066f197264341eff6bf67e8c06cae434eb4 (diff) | |
Closures and function definitions 🚀
Supports:
- Closure syntax: `(x, y) => z`
- Shorthand for a single argument: `x => y`
- Function syntax: `let f(x) = y`
- Capturing of variables from the environment
- Error messages for too few / many passed arguments
Does not support:
- Named arguments
- Variadic arguments with `..`
Diffstat (limited to 'src/pretty.rs')
| -rw-r--r-- | src/pretty.rs | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/pretty.rs b/src/pretty.rs index 86919ac8..3f420548 100644 --- a/src/pretty.rs +++ b/src/pretty.rs @@ -219,6 +219,7 @@ impl Pretty for Expr { Self::Unary(v) => v.pretty(p), Self::Binary(v) => v.pretty(p), Self::Call(v) => v.pretty(p), + Self::Closure(v) => v.pretty(p), Self::Let(v) => v.pretty(p), Self::If(v) => v.pretty(p), Self::While(v) => v.pretty(p), @@ -383,6 +384,15 @@ impl Pretty for ExprArg { } } +impl Pretty for ExprClosure { + fn pretty(&self, p: &mut Printer) { + p.push('('); + p.join(self.params.iter(), ", ", |item, p| item.pretty(p)); + p.push_str(") => "); + self.body.pretty(p); + } +} + impl Pretty for ExprLet { fn pretty(&self, p: &mut Printer) { p.push_str("let "); @@ -529,8 +539,11 @@ impl Pretty for TemplateFunc { impl Pretty for ValueFunc { fn pretty(&self, p: &mut Printer) { - p.push_str("<function "); - p.push_str(self.name()); + p.push_str("<function"); + if let Some(name) = self.name() { + p.push(' '); + p.push_str(name); + } p.push('>'); } } @@ -720,8 +733,12 @@ mod tests { roundtrip("#v(1, 2)[*Ok*]"); roundtrip("#v(1, f[2])"); + // Closures. + roundtrip("{(a, b) => a + b}"); + // Keywords. roundtrip("#let x = 1 + 2"); + test_parse("#let f(x) = y", "#let f = (x) => y"); test_parse("#if x [y] #else [z]", "#if x [y] else [z]"); roundtrip("#while x {y}"); roundtrip("#for x in y {z}"); @@ -777,8 +794,14 @@ mod tests { "[*<node example>]", ); - // Function and arguments. - test_value(ValueFunc::new("nil", |_, _| Value::None), "<function nil>"); + // Function. + test_value(ValueFunc::new(None, |_, _| Value::None), "<function>"); + test_value( + ValueFunc::new(Some("nil".into()), |_, _| Value::None), + "<function nil>", + ); + + // Arguments. test_value( ValueArgs { span: Span::ZERO, |
