kind_tree/concrete/
pat.rs

1//! All of the definitons of patterns are described
2//! here. It's really useful to split between patterns
3//! and expressions in order to restrict even more because
4//! not all of the expressions can be turned into patterns.
5
6use std::fmt::{Display, Error, Formatter};
7
8use kind_span::Range;
9
10use crate::symbol::{Ident, QualifiedIdent};
11
12// Really useful thin layer on ident.
13#[derive(Clone, Debug, Hash, PartialEq, Eq)]
14pub struct PatIdent(pub Ident);
15
16#[derive(Clone, Debug, Hash, PartialEq, Eq)]
17pub enum PatKind {
18    /// Name of a variable
19    Var(PatIdent),
20    /// Application of a constructor
21    App(QualifiedIdent, Vec<Box<Pat>>),
22    /// 60 bit unsigned integer
23    U60(u64),
24    /// 120 bit unsigned integer
25    U120(u128),
26    /// 60 bit floating point number
27    F60(u64),
28    /// Pair
29    Pair(Box<Pat>, Box<Pat>),
30    /// List
31    List(Vec<Pat>),
32    /// Str
33    Str(String),
34    ///
35    Char(char),
36    /// Wildcard
37    Hole,
38}
39
40/// Describes a single `pattern`
41#[derive(Clone, Debug, Hash, PartialEq, Eq)]
42pub struct Pat {
43    pub data: PatKind,
44    pub range: Range,
45}
46
47impl Display for Pat {
48    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
49        use PatKind::*;
50        match &self.data {
51            Var(name) => write!(f, "{}", name.0),
52            App(head, spine) => write!(
53                f,
54                "({}{})",
55                head,
56                spine.iter().map(|x| format!(" {}", x)).collect::<String>()
57            ),
58            List(vec) => write!(
59                f,
60                "[{}]",
61                vec.iter()
62                    .map(|x| format!("{}", x))
63                    .collect::<Vec<String>>()
64                    .join(" ")
65            ),
66            Str(str) => write!(f, "\"{}\"", str),
67            U60(num) => write!(f, "{}", num),
68            U120(num) => write!(f, "{}u120", num),
69            F60(_num) => todo!(),
70            Char(chr) => write!(f, "\'{}\'", chr),
71            Pair(fst, snd) => write!(f, "({}, {})", fst, snd),
72            Hole => write!(f, "_"),
73        }
74    }
75}
76
77impl Pat {
78    pub fn var(name: Ident) -> Box<Pat> {
79        Box::new(Pat {
80            range: name.range,
81            data: PatKind::Var(PatIdent(name)),
82        })
83    }
84}