use std::fmt::{Display, Error, Formatter};
use kind_span::Range;
use crate::symbol::{Ident, QualifiedIdent};
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct PatIdent(pub Ident);
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum PatKind {
Var(PatIdent),
App(QualifiedIdent, Vec<Box<Pat>>),
U60(u64),
U120(u128),
F60(u64),
Pair(Box<Pat>, Box<Pat>),
List(Vec<Pat>),
Str(String),
Char(char),
Hole,
}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Pat {
pub data: PatKind,
pub range: Range,
}
impl Display for Pat {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
use PatKind::*;
match &self.data {
Var(name) => write!(f, "{}", name.0),
App(head, spine) => write!(
f,
"({}{})",
head,
spine.iter().map(|x| format!(" {}", x)).collect::<String>()
),
List(vec) => write!(
f,
"[{}]",
vec.iter()
.map(|x| format!("{}", x))
.collect::<Vec<String>>()
.join(" ")
),
Str(str) => write!(f, "\"{}\"", str),
U60(num) => write!(f, "{}", num),
U120(num) => write!(f, "{}u120", num),
F60(_num) => todo!(),
Char(chr) => write!(f, "\'{}\'", chr),
Pair(fst, snd) => write!(f, "({}, {})", fst, snd),
Hole => write!(f, "_"),
}
}
}
impl Pat {
pub fn var(name: Ident) -> Box<Pat> {
Box::new(Pat {
range: name.range,
data: PatKind::Var(PatIdent(name)),
})
}
}