use logos::Logos;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Span {
pub start: usize,
pub end: usize,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Spanned {
pub token: Token,
pub span: Span,
}
#[derive(Logos, Debug, Clone, PartialEq)]
#[logos(skip r"[ \t]+")]
#[logos(skip(r"--[^\n]*", allow_greedy = true))]
pub enum Token {
#[token("do")]
Do,
#[token("let")]
Let,
#[token("in")]
In,
#[token("where")]
Where,
#[token("if")]
If,
#[token("then")]
Then,
#[token("else")]
Else,
#[token("case")]
Case,
#[token("of")]
Of,
#[token("guard")]
Guard,
#[token("not")]
Not,
#[token("mod")]
ModKw,
#[token("div")]
DivKw,
#[token("otherwise")]
Otherwise,
#[token("True")]
True,
#[token("False")]
False,
#[token("Nothing")]
Nothing,
#[regex(r"0x[0-9a-fA-F]+", |lex| i64::from_str_radix(&lex.slice()[2..], 16).ok())]
#[regex(r"[0-9]+", |lex| lex.slice().parse::<i64>().ok(), priority = 2)]
Int(i64),
#[regex(r"[0-9]+\.[0-9]+", |lex| lex.slice().parse::<f64>().ok())]
Float(f64),
#[regex(r#""([^"\\]|\\.)*""#, |lex| {
let s = lex.slice();
Some(s[1..s.len()-1].to_string())
})]
Str(String),
#[regex(r"[a-z_][a-zA-Z0-9_']*", |lex| lex.slice().to_string(), priority = 1)]
Ident(String),
#[regex(r"[A-Z][a-zA-Z0-9_']*", |lex| lex.slice().to_string())]
UpperIdent(String),
#[token("->")]
Arrow,
#[token("<-")]
LeftArrow,
#[token("=>")]
FatArrow,
#[token("::")]
DoubleColon,
#[token("..")]
DotDot,
#[token("==")]
EqEq,
#[token("/=")]
Neq,
#[token("<=")]
Lte,
#[token(">=")]
Gte,
#[token("&&")]
AndAnd,
#[token("||")]
OrOr,
#[token("++")]
PlusPlus,
#[token("+")]
Plus,
#[token("-")]
Minus,
#[token("*")]
Star,
#[token("/")]
Slash,
#[token("%")]
Percent,
#[token("<")]
Lt,
#[token(">")]
Gt,
#[token("=")]
Eq,
#[token(".")]
Dot,
#[token(",")]
Comma,
#[token(":")]
Colon,
#[token("|")]
Pipe,
#[token("\\")]
Backslash,
#[token("@")]
At,
#[token("&")]
Ampersand,
#[token("`")]
Backtick,
#[token("!")]
Bang,
#[token("(")]
LParen,
#[token(")")]
RParen,
#[token("[")]
LBracket,
#[token("]")]
RBracket,
#[token("{")]
LBrace,
#[token("}")]
RBrace,
Indent,
Dedent,
Newline,
Eof,
}
impl fmt::Display for Token {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Ident(s) | Self::UpperIdent(s) | Self::Str(s) => write!(f, "{s}"),
Self::Int(n) => write!(f, "{n}"),
Self::Float(n) => write!(f, "{n}"),
Self::Arrow => write!(f, "->"),
Self::LeftArrow => write!(f, "<-"),
Self::FatArrow => write!(f, "=>"),
Self::EqEq => write!(f, "=="),
Self::Neq => write!(f, "/="),
Self::AndAnd => write!(f, "&&"),
Self::OrOr => write!(f, "||"),
Self::PlusPlus => write!(f, "++"),
Self::DoubleColon => write!(f, "::"),
Self::DotDot => write!(f, ".."),
_ => write!(f, "{self:?}"),
}
}
}