bobbylisp/src/trans/ast.rs

67 lines
1.6 KiB
Rust

use std::fmt::{Display, Formatter, Result as FmtResult};
use super::ty::Type;
#[derive(Clone, Debug)]
pub enum UnaryOp {
Neg,
Not,
}
#[derive(Clone, Debug)]
pub enum BinaryOp {
Add, Sub, Mul, Div, Mod,
Eq, Neq, Lt, Gt, Lte, Gte,
And, Or,
}
#[derive(Clone, Debug)]
pub enum Literal {
Num(i64), Str(String), Bool(bool),
}
/// Enum to represent internal expression
#[derive(Clone, Debug)]
pub enum Expr {
Lit(Literal),
Sym(String),
UnaryOp(UnaryOp, Box<Self>),
BinaryOp(BinaryOp, Box<Self>, Box<Self>),
Call(Box<Self>, Vec<Self>),
Lambda {
args: Vec<(String, Type)>,
body: Box<Self>,
},
}
impl Display for Expr {
fn fmt(&self, f: &mut Formatter) -> FmtResult {
match self {
Expr::Lit(l) => match l {
Literal::Num(n) => write!(f, "{}", n),
Literal::Str(s) => write!(f, "\"{}\"", s),
Literal::Bool(b) => write!(f, "{}", b),
},
Expr::Sym(s) => write!(f, "{}", s),
Expr::UnaryOp(op, e) => write!(f, "({:?} {})", op, e),
Expr::BinaryOp(op, e1, e2) => write!(f, "({:?} {} {})", op, e1, e2),
Expr::Call(c, args) => {
write!(f, "({}", c)?;
for arg in args {
write!(f, " {}", arg)?;
}
write!(f, ")")
},
Expr::Lambda { args, body } => {
write!(f, "(lambda ")?;
for (name, ty) in args {
write!(f, "[{} {}]", name, ty)?;
}
write!(f, " {})", body)
},
}
}
}