You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
5.9 KiB
Rust

use std::fmt;
/// A single syntactic element.
#[derive(Debug, Clone)]
pub struct Token {
pub kind: Kind,
pub pos: Position,
/// raw text
pub raw: String,
}
#[derive(Debug, Clone)]
pub struct Position {
pub file: String,
pub line: usize,
pub col: usize,
}
impl fmt::Display for Token {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}: \"{}\"", self.kind, self.raw)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Kind {
Ident,
OBrace,
CBrace,
OBracket,
CBracket,
OParen,
CParen,
Comma,
Semi,
Eq,
EqEq,
Bang,
BangEq,
Gt,
GtGt,
GtEq,
GtGtEq,
Lt,
LtLt,
LtEq,
LtLtEq,
Amp,
AmpAmp,
AmpEq,
AmpAmpEq,
Pipe,
PipePipe,
PipeEq,
PipePipeEq,
Caret,
CaretEq,
Plus,
PlusEq,
Minus,
MinusEq,
Asterisk,
AsteriskAsterisk,
AsteriskEq,
AsteriskAsteriskEq,
Slash,
SlashEq,
Percent,
PercentEq,
DependKeyword,
IncludeKeyword,
TargetKeyword,
SetKeyword,
SourceKeyword,
TypeKeyword,
StringLiteral,
IntLiteral,
Comment,
}
impl Kind {
pub fn is_start_of_lhs_expr(&self) -> bool {
match self {
Kind::Ident => true,
Kind::IntLiteral => true,
Kind::StringLiteral => true,
_ => false
}
}
pub fn is_start_of_expr(&self) -> bool {
match self {
k if k.is_start_of_lhs_expr() => true,
Kind::Minus => true,
_ => false
}
}
pub fn is_assignment_op(&self) -> bool {
match self {
Kind::Eq => true,
Kind::PlusEq => true,
Kind::MinusEq => true,
Kind::AsteriskEq => true,
Kind::AsteriskAsteriskEq => true,
Kind::SlashEq => true,
Kind::PercentEq => true,
Kind::GtGtEq => true,
Kind::LtLtEq => true,
Kind::PipeEq => true,
Kind::AmpEq => true,
Kind::CaretEq => true,
_ => false,
}
}
/// If this token is a binary operator, return its precedence value when
/// interpreted as such. See `operator-precedence.txt` for details.
pub fn binary_op_precedence(&self) -> Option<u32> {
match self {
Kind::Eq => Some(2),
Kind::PlusEq => Some(2),
Kind::MinusEq => Some(2),
Kind::AsteriskEq => Some(2),
Kind::AsteriskAsteriskEq => Some(2),
Kind::SlashEq => Some(2),
Kind::PercentEq => Some(2),
Kind::AmpEq => Some(2),
Kind::PipeEq => Some(2),
Kind::CaretEq => Some(2),
Kind::GtGtEq => Some(2),
Kind::LtLtEq => Some(2),
Kind::PipePipe => Some(3),
Kind::AmpAmp => Some(4),
Kind::EqEq => Some(5),
Kind::BangEq => Some(5),
Kind::Gt => Some(5),
Kind::GtEq => Some(5),
Kind::Lt => Some(5),
Kind::LtEq => Some(5),
Kind::Pipe => Some(6),
Kind::Caret => Some(7),
Kind::Amp => Some(8),
Kind::GtGt => Some(9),
Kind::LtLt => Some(9),
Kind::Plus => Some(10),
Kind::Minus => Some(10),
Kind::Asterisk => Some(11),
Kind::Slash => Some(11),
Kind::Percent => Some(11),
Kind::AsteriskAsterisk => Some(12),
_ => None,
}
}
}
impl fmt::Display for Kind {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"{}",
match self {
Kind::Ident => "ident",
Kind::OBrace => "obrace",
Kind::CBrace => "cbrace",
Kind::OBracket => "obracket",
Kind::CBracket => "cbracket",
Kind::OParen => "oparen",
Kind::CParen => "cparen",
Kind::Comma => "comma",
Kind::Semi => "semi",
Kind::Eq => "eq",
Kind::EqEq => "eqeq",
Kind::Bang => "bang",
Kind::BangEq => "bangeq",
Kind::Gt => "gt",
Kind::GtGt => "gtgt",
Kind::GtEq => "gteq",
Kind::GtGtEq => "gtgteq",
Kind::Lt => "lt",
Kind::LtLt => "ltlt",
Kind::LtEq => "lteq",
Kind::LtLtEq => "ltlteq",
Kind::Amp => "amp",
Kind::AmpAmp => "ampamp",
Kind::AmpEq => "ampeq",
Kind::AmpAmpEq => "ampampeq",
Kind::Pipe => "pipe",
Kind::PipePipe => "pipepipe",
Kind::PipeEq => "pipeeq",
Kind::PipePipeEq => "pipepipeeq",
Kind::Caret => "caret",
Kind::CaretEq => "careteq",
Kind::Plus => "plus",
Kind::PlusEq => "pluseq",
Kind::Minus => "minus",
Kind::MinusEq => "minuseq",
Kind::Asterisk => "asterisk",
Kind::AsteriskAsterisk => "asteriskasterisk",
Kind::AsteriskEq => "asteriskeq",
Kind::AsteriskAsteriskEq => "asteriskasteriskeq",
Kind::Slash => "slash",
Kind::SlashEq => "slasheq",
Kind::Percent => "percent",
Kind::PercentEq => "percenteq",
Kind::DependKeyword => "keyword",
Kind::IncludeKeyword => "keyword",
Kind::SetKeyword => "keyword",
Kind::SourceKeyword => "keyword",
Kind::TargetKeyword => "keyword",
Kind::TypeKeyword => "keyword",
Kind::StringLiteral => "string",
Kind::IntLiteral => "int",
Kind::Comment => "comment",
}
)
}
}