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}