mest-core 0.4.0

Core language library for the Mest programming language
Documentation
use std::fmt;

use chumsky::span::SimpleSpan;
use derive_more::From;
use itertools::Itertools;

use crate::ast::{BinOp, Ident, Literal, UnaryOp};

#[derive(Debug, Clone, Copy, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TypeVar(pub u64);

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Type {
    Var(TypeVar),
    Arrow(Box<Type>, Box<Type>),
    Int,
    Float,
    Bool,
    Tuple(Vec<Type>),
}

#[derive(Debug, Clone)]
pub struct TExpr<'bump> {
    pub kind: &'bump TExprKind<'bump>,
    pub span: SimpleSpan,
    pub ty: Type,
}

#[derive(Debug, Clone)]
pub enum TExprKind<'bump> {
    Literal(Literal),
    Ident(Ident),
    If {
        cond: TExpr<'bump>,
        then_expr: TExpr<'bump>,
        else_expr: TExpr<'bump>,
    },
    BinOp {
        op: BinOp,
        lhs: TExpr<'bump>,
        rhs: TExpr<'bump>,
    },
    UnaryOp {
        op: UnaryOp,
        rhs: TExpr<'bump>,
    },
    Let {
        name: Ident,
        value: TExpr<'bump>,
        body: TExpr<'bump>,
        rec: bool,
    },
    Match {
        scrutinee: TExpr<'bump>,
        arms: &'bump [(TPat<'bump>, TExpr<'bump>)],
    },
    Lambda {
        param: Ident,
        param_ty: Type,
        body: TExpr<'bump>,
    },
    App {
        func: TExpr<'bump>,
        arg: TExpr<'bump>,
    },
}

#[derive(Debug, Clone)]
pub enum TPat<'bump> {
    Wildcard,
    Var(Ident, Type),
    Lit(Literal),
    Or(&'bump TPat<'bump>, &'bump TPat<'bump>),
}

impl fmt::Display for TypeVar {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "α<{}>", self.0)
    }
}

impl fmt::Display for Type {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Type::Var(type_var) => write!(f, "{}", type_var),
            Type::Arrow(from, to) => write!(f, "({}) -> {}", from, to),
            Type::Int => write!(f, "Int"),
            Type::Float => write!(f, "Float"),
            Type::Bool => write!(f, "Bool"),
            Type::Tuple(items) => write!(f, "({})", items.iter().format(",")),
        }
    }
}