use types::*;
pub trait Show {
fn show(&self, buf: &mut String);
}
impl Show for Stmt {
fn show(&self, buf: &mut String) {
match *self {
Stmt::Let(ref p, _, _, ref e) => {
p.show(buf);
buf.push_str(" = ");
e.show(buf);
}
Stmt::Expr(ref e) =>
e.show(buf),
}
buf.push_str(";\n");
}
}
impl Show for Pat {
fn show(&self, buf: &mut String) {
match *self {
Pat::Var(ref i) => buf.push_str(i),
Pat::Tuple(ref ps) => {
buf.push_str("(");
for (n, t) in ps.iter().enumerate() {
if n > 0 {
buf.push_str(", ");
}
t.show(buf);
}
buf.push_str(")");
}
}
}
}
impl Show for Value {
fn show(&self, buf: &mut String) {
match *self {
Value::Unit => buf.push_str("()"),
Value::Lit(ref l) => l.show(buf),
Value::Tuple(ref ts) => {
buf.push_str("(");
for (n, t) in ts.iter().enumerate() {
if n > 0 {
buf.push_str(", ");
}
t.show(buf);
}
buf.push_str(")");
}
Value::Closure(ref p, ref e, _) => {
buf.push_str("(\\");
p.show(buf);
buf.push_str(".");
e.show(buf);
buf.push_str(")");
}
}
}
}
impl Show for Literal {
fn show(&self, buf: &mut String) {
match *self {
Literal::Int(i) =>
buf.push_str(&format!("{}", i)),
}
}
}
impl Show for Expr {
fn show(&self, buf: &mut String) {
match *self {
Expr::Var(ref v) => buf.push_str(v),
Expr::Lit(ref l) => l.show(buf),
Expr::Fn(ref p, ref e) => {
buf.push_str("fn ");
p.show(buf);
buf.push_str(" => ");
e.show(buf);
}
Expr::App(ref e1, ref e2) => {
buf.push_str("(");
e1.show(buf);
buf.push_str(")(");
e2.show(buf);
buf.push_str(")");
}
Expr::Do(ref ss) => {
buf.push_str("do\n");
for s in ss.iter() {
s.show(buf);
}
buf.push_str("end\n");
}
Expr::Tuple(ref ts) => {
buf.push_str("(");
for (n, t) in ts.iter().enumerate() {
if n > 0 {
buf.push_str(", ");
}
t.show(buf);
}
buf.push_str(")");
}
}
}
}
pub fn show<S: Show>(s: &S) -> String {
let mut buf = String::new();
s.show(&mut buf);
buf
}