Display lambda bind patterns as lets

This commit is contained in:
imaqtkatt 2024-06-06 11:35:47 -03:00
parent 2bb1a8a7be
commit be7248638d
7 changed files with 66 additions and 9 deletions

View File

@ -1,5 +1,8 @@
# Changelog # Changelog
## 0.2.35
- Changed lambda `Term` with bind patterns to display as `let` terms.
## 0.2.34 ## 0.2.34
- Added `<=` and `>=` operators. (#451) - Added `<=` and `>=` operators. (#451)

2
Cargo.lock generated
View File

@ -62,7 +62,7 @@ dependencies = [
[[package]] [[package]]
name = "bend-lang" name = "bend-lang"
version = "0.2.34" version = "0.2.35"
dependencies = [ dependencies = [
"TSPL", "TSPL",
"clap", "clap",

View File

@ -2,7 +2,7 @@
name = "bend-lang" name = "bend-lang"
description = "A high-level, massively parallel programming language" description = "A high-level, massively parallel programming language"
license = "Apache-2.0" license = "Apache-2.0"
version = "0.2.34" version = "0.2.35"
edition = "2021" edition = "2021"
rust-version = "1.74" rust-version = "1.74"
exclude = ["tests/"] exclude = ["tests/"]

View File

@ -1,6 +1,6 @@
use super::{Book, Definition, FanKind, Name, Num, Op, Pattern, Rule, Tag, Term}; use super::{Book, Definition, FanKind, Name, Num, Op, Pattern, Rule, Tag, Term};
use crate::maybe_grow; 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 */ /* Some aux structures for things that are not so simple to display */
@ -40,12 +40,27 @@ macro_rules! display {
/* The actual display implementations */ /* 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 { impl fmt::Display for Term {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
maybe_grow(|| match self { maybe_grow(|| match self {
Term::Lam { tag, pat, bod } => { Term::Lam { tag, pat, bod } => match &**pat {
write!(f, "{}λ{} {}", tag.display_padded(), pat, bod) 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::Var { nam } => write!(f, "{nam}"),
Term::Link { nam } => write!(f, "${nam}"), Term::Link { nam } => write!(f, "${nam}"),
Term::Let { pat, val, nxt } => write!(f, "let {} = {}; {}", pat, val, nxt), Term::Let { pat, val, nxt } => write!(f, "let {} = {}; {}", pat, val, nxt),
@ -199,6 +214,7 @@ impl Rule {
impl fmt::Display for Definition { impl fmt::Display for Definition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
namegen_reset();
write!(f, "{}", DisplayJoin(|| self.rules.iter().map(|x| x.display(&self.name)), "\n")) write!(f, "{}", DisplayJoin(|| self.rules.iter().map(|x| x.display(&self.name)), "\n"))
} }
} }
@ -279,6 +295,7 @@ impl Book {
impl Definition { impl Definition {
pub fn display_pretty(&self) -> impl fmt::Display + '_ { pub fn display_pretty(&self) -> impl fmt::Display + '_ {
namegen_reset();
display!("{}", DisplayJoin(|| self.rules.iter().map(|x| x.display_pretty(&self.name)), "\n")) 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 + '_ { pub fn display_pretty(&self, tab: usize) -> impl fmt::Display + '_ {
maybe_grow(|| { maybe_grow(|| {
DisplayFn(move |f| match self { DisplayFn(move |f| match self {
Term::Lam { tag, pat, bod } => { Term::Lam { tag, pat, bod } => match &**pat {
write!(f, "{}λ{} {}", tag.display_padded(), pat, bod.display_pretty(tab)) 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::Var { nam } => write!(f, "{nam}"),
Term::Link { nam } => write!(f, "${nam}"), Term::Link { nam } => write!(f, "${nam}"),
Term::Let { pat, val, nxt } => { Term::Let { pat, val, nxt } => {

View File

@ -0,0 +1,3 @@
desugar
tests/golden_tests/cli/desugar_pretty.bend
-p

View File

@ -0,0 +1,6 @@
Foo (a,b) (c,d) = (+ (+ a b) (+ c d))
main =
@(x, y)
@{a b c}
(+ (+ x y) (+ a b))

View File

@ -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))