use std::collections::HashMap;
pub type Ident = String;
pub type Env = HashMap<Ident, Value>;
#[derive(Debug, Clone)]
pub enum Stmt {
Let(Pat, Option<Type>, Vec<Pat>, Expr),
Expr(Expr),
}
#[derive(Debug, Clone)]
pub enum Pat {
Var(Ident),
Tuple(Vec<Pat>),
}
impl Pat {
pub fn mk_var<S: Into<String>>(s: S) -> Pat {
Pat::Var(s.into())
}
pub fn mk_tuple(pats: Vec<Pat>) -> Pat {
Pat::Tuple(pats)
}
}
#[derive(Debug, Clone)]
pub enum Type {
Prim(PrimType),
Arr(Box<Type>, Box<Type>),
}
#[derive(Debug, Clone)]
pub enum PrimType {
Unit,
Nat,
}
#[derive(Debug, Clone)]
pub enum Expr {
Var(Ident),
Lit(Literal),
Fn(Box<Pat>, Box<Expr>),
App(Box<Expr>, Box<Expr>),
Do(Vec<Stmt>),
Tuple(Vec<Expr>),
}
#[derive(Debug, Clone)]
pub enum Value {
Closure(Pat, Expr, Box<Env>),
Lit(Literal),
Tuple(Vec<Value>),
Unit,
}
#[derive(Debug, Clone)]
pub enum Literal {
Int(i64),
}
impl Expr {
pub fn mk_fn(p: Pat, e: Expr) -> Expr {
Expr::Fn(Box::new(p), Box::new(e))
}
pub fn mk_app(e1: Expr, e2: Expr) -> Expr {
Expr::App(Box::new(e1), Box::new(e2))
}
pub fn mk_var<S: Into<String>>(s: S) -> Expr {
Expr::Var(s.into())
}
pub fn mk_tuple(es: Vec<Expr>) -> Expr {
Expr::Tuple(es)
}
}