diff --git a/CHANGELOG.md b/CHANGELOG.md index 48baa111..e57c50d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 0.2.35 +- Changed lambda `Term` with bind patterns to display as `let` terms. + ## 0.2.34 - Added `<=` and `>=` operators. (#451) diff --git a/Cargo.lock b/Cargo.lock index be5e144f..1680320a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -62,7 +62,7 @@ dependencies = [ [[package]] name = "bend-lang" -version = "0.2.34" +version = "0.2.35" dependencies = [ "TSPL", "clap", diff --git a/Cargo.toml b/Cargo.toml index 83062713..6cc9ecde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "bend-lang" description = "A high-level, massively parallel programming language" license = "Apache-2.0" -version = "0.2.34" +version = "0.2.35" edition = "2021" rust-version = "1.74" exclude = ["tests/"] diff --git a/src/fun/display.rs b/src/fun/display.rs index 5ca805f7..c888c293 100644 --- a/src/fun/display.rs +++ b/src/fun/display.rs @@ -1,6 +1,6 @@ use super::{Book, Definition, FanKind, Name, Num, Op, Pattern, Rule, Tag, Term}; use crate::maybe_grow; -use std::{fmt, ops::Deref}; +use std::{fmt, ops::Deref, sync::atomic::AtomicU64}; /* Some aux structures for things that are not so simple to display */ @@ -40,12 +40,27 @@ macro_rules! display { /* The actual display implementations */ +static NAMEGEN: AtomicU64 = AtomicU64::new(0); + +fn gen_fan_pat_name() -> Name { + let n = NAMEGEN.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + Name::new(format!("pat%{}", super::num_to_name(n))) +} + +fn namegen_reset() { + NAMEGEN.store(0, std::sync::atomic::Ordering::SeqCst); +} + impl fmt::Display for Term { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { maybe_grow(|| match self { - Term::Lam { tag, pat, bod } => { - write!(f, "{}λ{} {}", tag.display_padded(), pat, bod) - } + Term::Lam { tag, pat, bod } => match &**pat { + Pattern::Fan(_, _, _) => { + let name = gen_fan_pat_name(); + write!(f, "{}λ{name} let {} = {name}; {}", tag.display_padded(), pat, bod) + } + _ => write!(f, "{}λ{} {}", tag.display_padded(), pat, bod), + }, Term::Var { nam } => write!(f, "{nam}"), Term::Link { nam } => write!(f, "${nam}"), Term::Let { pat, val, nxt } => write!(f, "let {} = {}; {}", pat, val, nxt), @@ -199,6 +214,7 @@ impl Rule { impl fmt::Display for Definition { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + namegen_reset(); write!(f, "{}", DisplayJoin(|| self.rules.iter().map(|x| x.display(&self.name)), "\n")) } } @@ -279,6 +295,7 @@ impl Book { impl Definition { pub fn display_pretty(&self) -> impl fmt::Display + '_ { + namegen_reset(); display!("{}", DisplayJoin(|| self.rules.iter().map(|x| x.display_pretty(&self.name)), "\n")) } } @@ -298,9 +315,20 @@ impl Term { pub fn display_pretty(&self, tab: usize) -> impl fmt::Display + '_ { maybe_grow(|| { DisplayFn(move |f| match self { - Term::Lam { tag, pat, bod } => { - write!(f, "{}λ{} {}", tag.display_padded(), pat, bod.display_pretty(tab)) - } + Term::Lam { tag, pat, bod } => match &**pat { + Pattern::Fan(_, _, _) => { + let name = gen_fan_pat_name(); + write!( + f, + "{}λ{name} let {} = {name};\n{:tab$}{}", + tag.display_padded(), + pat, + "", + bod.display_pretty(tab), + ) + } + _ => write!(f, "{}λ{} {}", tag.display_padded(), pat, bod.display_pretty(tab)), + }, Term::Var { nam } => write!(f, "{nam}"), Term::Link { nam } => write!(f, "${nam}"), Term::Let { pat, val, nxt } => { diff --git a/tests/golden_tests/cli/desugar_pretty.args b/tests/golden_tests/cli/desugar_pretty.args new file mode 100644 index 00000000..8914eb4b --- /dev/null +++ b/tests/golden_tests/cli/desugar_pretty.args @@ -0,0 +1,3 @@ +desugar +tests/golden_tests/cli/desugar_pretty.bend +-p diff --git a/tests/golden_tests/cli/desugar_pretty.bend b/tests/golden_tests/cli/desugar_pretty.bend new file mode 100644 index 00000000..7e871895 --- /dev/null +++ b/tests/golden_tests/cli/desugar_pretty.bend @@ -0,0 +1,6 @@ +Foo (a,b) (c,d) = (+ (+ a b) (+ c d)) + +main = + @(x, y) + @{a b c} + (+ (+ x y) (+ a b)) diff --git a/tests/snapshots/cli__desugar_pretty.bend.snap b/tests/snapshots/cli__desugar_pretty.bend.snap new file mode 100644 index 00000000..bd6dca09 --- /dev/null +++ b/tests/snapshots/cli__desugar_pretty.bend.snap @@ -0,0 +1,17 @@ +--- +source: tests/golden_tests.rs +input_file: tests/golden_tests/cli/desugar_pretty.bend +--- +Warnings: +In definition 'Foo': + Definition is unused. + +(Foo) = + λa λb let (c, d) = a; + let (e, f) = b; + (+ (+ c d) (+ e f)) + +(main) = + λpat%a let (a, b) = pat%a; + λpat%b let {c d *} = pat%b; + (+ (+ a b) (+ c d))