Skip to main content

mest_core/
hir.rs

1use std::fmt;
2
3use chumsky::span::SimpleSpan;
4use derive_more::From;
5use itertools::Itertools;
6
7use crate::ast::{BinOp, Ident, Literal, UnaryOp};
8
9#[derive(Debug, Clone, Copy, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
10pub struct TypeVar(pub u64);
11
12#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
13pub enum Type {
14    Var(TypeVar),
15    Arrow(Box<Type>, Box<Type>),
16    Int,
17    Float,
18    Bool,
19    Tuple(Vec<Type>),
20}
21
22#[derive(Debug, Clone)]
23pub struct TExpr<'bump> {
24    pub kind: &'bump TExprKind<'bump>,
25    pub span: SimpleSpan,
26    pub ty: Type,
27}
28
29#[derive(Debug, Clone)]
30pub enum TExprKind<'bump> {
31    Literal(Literal),
32    Ident(Ident),
33    If {
34        cond: TExpr<'bump>,
35        then_expr: TExpr<'bump>,
36        else_expr: TExpr<'bump>,
37    },
38    BinOp {
39        op: BinOp,
40        lhs: TExpr<'bump>,
41        rhs: TExpr<'bump>,
42    },
43    UnaryOp {
44        op: UnaryOp,
45        rhs: TExpr<'bump>,
46    },
47    Let {
48        name: Ident,
49        value: TExpr<'bump>,
50        body: TExpr<'bump>,
51        rec: bool,
52    },
53    Match {
54        scrutinee: TExpr<'bump>,
55        arms: &'bump [(TPat<'bump>, TExpr<'bump>)],
56    },
57    Lambda {
58        param: Ident,
59        param_ty: Type,
60        body: TExpr<'bump>,
61    },
62    App {
63        func: TExpr<'bump>,
64        arg: TExpr<'bump>,
65    },
66}
67
68#[derive(Debug, Clone)]
69pub enum TPat<'bump> {
70    Wildcard,
71    Var(Ident, Type),
72    Lit(Literal),
73    Or(&'bump TPat<'bump>, &'bump TPat<'bump>),
74}
75
76impl fmt::Display for TypeVar {
77    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78        write!(f, "α<{}>", self.0)
79    }
80}
81
82impl fmt::Display for Type {
83    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84        match self {
85            Type::Var(type_var) => write!(f, "{}", type_var),
86            Type::Arrow(from, to) => write!(f, "({}) -> {}", from, to),
87            Type::Int => write!(f, "Int"),
88            Type::Float => write!(f, "Float"),
89            Type::Bool => write!(f, "Bool"),
90            Type::Tuple(items) => write!(f, "({})", items.iter().format(",")),
91        }
92    }
93}