use std::fmt::Display;
use crate::{
syntax::lexer::token::{Kw, NumLit, Sym, TokenKind},
util::data::bitset::BitSet,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Tt {
Kw(Kw),
Ident,
SysIdent,
Sym(Sym),
Num(NumLit),
Str,
Eof,
}
impl Tt {
pub fn from_kind(kind: &TokenKind) -> Option<Tt> {
match kind {
TokenKind::Kw(kw) => Some(Tt::Kw(*kw)),
TokenKind::Ident(_) => Some(Tt::Ident),
TokenKind::SysIdent(_) => Some(Tt::SysIdent),
TokenKind::Sym(sym) => Some(Tt::Sym(*sym)),
TokenKind::Num(num_lit) => Some(Tt::Num(*num_lit)),
TokenKind::Str(_) => Some(Tt::Str),
TokenKind::Comment => None,
TokenKind::Error => None,
}
}
}
impl Display for Tt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Tt::Kw(kw) => write!(f, "keyword '{kw}'"),
Tt::Ident => write!(f, "identifier"),
Tt::SysIdent => write!(f, "system identifier"),
Tt::Sym(sym) => write!(f, "symbol '{sym}'"),
Tt::Num(_) => write!(f, "number"),
Tt::Str => write!(f, "string"),
Tt::Eof => write!(f, "end-of-file"),
}
}
}
impl From<Kw> for Tt {
fn from(value: Kw) -> Self {
Tt::Kw(value)
}
}
impl From<Sym> for Tt {
fn from(value: Sym) -> Self {
Tt::Sym(value)
}
}
impl From<NumLit> for Tt {
fn from(value: NumLit) -> Self {
Tt::Num(value)
}
}
#[derive(Debug, Clone, Copy)]
pub struct TtSet {
set: BitSet<3>,
}
impl Default for TtSet {
fn default() -> Self {
Self::new()
}
}
impl TtSet {
pub const fn new() -> Self {
Self { set: BitSet::new() }
}
pub const fn inherit(mut self, other: TtSet) -> Self {
self.set.union(other.set);
self
}
pub const fn ty_idx(ty: Tt) -> usize {
match ty {
Tt::Ident => 0,
Tt::SysIdent => 1,
Tt::Str => 2,
Tt::Eof => 3,
Tt::Num(NumLit::Int) => 4,
Tt::Num(NumLit::Real) => 5,
Tt::Num(NumLit::Repeated) => 6,
Tt::Num(NumLit::Mixed) => 7,
Tt::Kw(kw) => 8 + kw as usize,
Tt::Sym(sym) => 8 + Kw::__Last as usize + sym as usize,
}
}
pub const fn add(&mut self, ty: Tt) {
self.set.add(Self::ty_idx(ty));
}
pub const fn contains(&self, ty: Tt) -> bool {
self.set.contains(Self::ty_idx(ty))
}
pub const fn tys(mut self, tys: &[Tt]) -> Self {
let mut i = 0;
while i < tys.len() {
self.add(tys[i]);
i += 1;
}
self
}
pub const fn kws(mut self, kws: &[Kw]) -> Self {
let mut i = 0;
while i < kws.len() {
self.add(Tt::Kw(kws[i]));
i += 1;
}
self
}
pub const fn syms(mut self, syms: &[Sym]) -> Self {
let mut i = 0;
while i < syms.len() {
self.add(Tt::Sym(syms[i]));
i += 1;
}
self
}
}