use std::fmt;
use crate::source::Span;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Kw {
Module,
Param,
Params,
Use,
Fn,
Const,
Dim,
Type,
Import,
As,
Static,
Assert,
Optimizer,
Training,
Inference,
Effect,
Let,
Uses,
Init,
Axis,
Idx,
Ein,
Real,
Lambda,
}
impl Kw {
pub fn from_ident(s: &str) -> Option<Kw> {
Some(match s {
"module" => Kw::Module,
"param" => Kw::Param,
"params" => Kw::Params,
"use" => Kw::Use,
"fn" => Kw::Fn,
"const" => Kw::Const,
"dim" => Kw::Dim,
"type" => Kw::Type,
"import" => Kw::Import,
"as" => Kw::As,
"static" => Kw::Static,
"assert" => Kw::Assert,
"optimizer" => Kw::Optimizer,
"training" => Kw::Training,
"inference" => Kw::Inference,
"effect" => Kw::Effect,
"let" => Kw::Let,
"uses" => Kw::Uses,
"init" => Kw::Init,
"axis" => Kw::Axis,
"idx" => Kw::Idx,
"ein" => Kw::Ein,
"ℝ" | "Real" => Kw::Real,
"λ" => Kw::Lambda,
_ => return None,
})
}
pub fn text(self) -> &'static str {
match self {
Kw::Module => "module",
Kw::Param => "param",
Kw::Params => "params",
Kw::Use => "use",
Kw::Fn => "fn",
Kw::Const => "const",
Kw::Dim => "dim",
Kw::Type => "type",
Kw::Import => "import",
Kw::As => "as",
Kw::Static => "static",
Kw::Assert => "assert",
Kw::Optimizer => "optimizer",
Kw::Training => "training",
Kw::Inference => "inference",
Kw::Effect => "effect",
Kw::Let => "let",
Kw::Uses => "uses",
Kw::Init => "init",
Kw::Axis => "axis",
Kw::Idx => "idx",
Kw::Ein => "ein",
Kw::Real => "ℝ",
Kw::Lambda => "λ",
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Op {
Dot,
Star,
Slash,
Percent,
Plus,
Minus,
Caret,
EqEq,
Le,
Ge,
Lt,
Gt,
Eq,
Arrow,
Pipe,
Bar,
Tensor,
Compose,
Period,
Comma,
Colon,
LParen,
RParen,
LBracket,
RBracket,
LBrace,
RBrace,
Ellipsis,
DotDot,
}
impl Op {
pub fn text(self) -> &'static str {
match self {
Op::Dot => "·",
Op::Star => "*",
Op::Slash => "/",
Op::Percent => "%",
Op::Plus => "+",
Op::Minus => "-",
Op::Caret => "^",
Op::EqEq => "==",
Op::Le => "<=",
Op::Ge => ">=",
Op::Lt => "<",
Op::Gt => ">",
Op::Eq => "=",
Op::Arrow => "->",
Op::Pipe => "|>",
Op::Bar => "|",
Op::Tensor => "⊗",
Op::Compose => "∘",
Op::Period => ".",
Op::Comma => ",",
Op::Colon => ":",
Op::LParen => "(",
Op::RParen => ")",
Op::LBracket => "[",
Op::RBracket => "]",
Op::LBrace => "{",
Op::RBrace => "}",
Op::Ellipsis => "...",
Op::DotDot => "..",
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TokKind {
Ident(String),
Kw(Kw),
Nat(String),
Float(String),
Quantity { num: String, unit: String },
Str(String),
Op(Op),
Newline,
Eof,
}
impl fmt::Display for TokKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TokKind::Ident(s) => write!(f, "identifier `{s}`"),
TokKind::Kw(k) => write!(f, "`{}`", k.text()),
TokKind::Nat(s) | TokKind::Float(s) => write!(f, "number `{s}`"),
TokKind::Quantity { num, unit } => write!(f, "quantity `{num}{unit}`"),
TokKind::Str(s) => write!(f, "string {s:?}"),
TokKind::Op(o) => write!(f, "`{}`", o.text()),
TokKind::Newline => write!(f, "end of line"),
TokKind::Eof => write!(f, "end of file"),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Token {
pub kind: TokKind,
pub span: Span,
}