diff options
Diffstat (limited to 'rust/src/ast.rs')
| -rw-r--r-- | rust/src/ast.rs | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/rust/src/ast.rs b/rust/src/ast.rs index e70f323..29d548f 100644 --- a/rust/src/ast.rs +++ b/rust/src/ast.rs @@ -22,7 +22,13 @@ impl Display for Value { Value::Num(i) => write!(f, "{}", i), Value::Bool(b) => write!(f, "{}", b), Value::Sym(s) => write!(f, "{}", s), - Value::App(l, r) => write!(f, "({} {})", l, r), + Value::App(l, r) => { + if let App(l1, l2) = *l.clone() { + write!(f, "({} {} {})", l1, l2, r) + } else { + write!(f, "({} {})", l, r) + } + } Value::Lam(var, body) => write!(f, "(lam {} {})", var, body), Value::Def(var, value) => write!(f, "(def {} {})", var, value), Value::Let(var, value, body) => write!(f, "(let ({} {}) {})", var, value, body), @@ -71,3 +77,32 @@ impl Arbitrary for Value { .boxed() } } + +#[cfg(test)] +mod ast_tests { + + use super::{ + identifier, + Value::{self, *}, + }; + use proptest::collection::vec; + use proptest::prelude::*; + + fn any_sym() -> impl Strategy<Value = Value> { + identifier().prop_map(Sym) + } + + proptest! { + + #[test] + fn display_multiple_applications_as_a_sequence(atoms in vec("[a-z]".prop_map(Sym), 2..10)) { + let init = atoms.first().unwrap().clone(); + let value = atoms.iter().skip(1).fold(init, |acc, expr| { + Value::App(Box::new(acc.clone()), Box::new(expr.clone())) + }); + assert_eq!(value.to_string(), + format!("({})", + atoms.iter().map(|v| v.to_string()).collect::<Vec<String>>().join(" "))); + } + } +} |
