Token: Add range operators, rename for consistency
This commit is contained in:
parent
34525ec77a
commit
1e5f7149d9
@ -8,8 +8,8 @@ Identifier = IDENTIFIER ;
|
||||
|
||||
(* # Expressions *)
|
||||
(* expression *)
|
||||
Block = '{' Expr? '}' ;
|
||||
Expr = Ignore ;
|
||||
Block = '{' Stmt* Expr? '}' ;
|
||||
Group = '(' Expr? ')' ;
|
||||
Primary = Item | Identifier | Literal
|
||||
| Block | Group | Branch ;
|
||||
@ -30,6 +30,7 @@ IgnoreOp = ';' ;
|
||||
AssignOp = '=' | "+=" | "-=" | "*=" | "/=" |
|
||||
"&=" | "|=" | "^=" |"<<=" |">>=" ;
|
||||
CompareOp = '<' | "<=" | "==" | "!=" | ">=" | '>' ;
|
||||
RangeOp = ".." | "..=" ;
|
||||
LogicOp = "&&" | "||" | "^^" ;
|
||||
|
||||
BitwiseOp = '&' | '|' | '^' ;
|
||||
|
@ -609,7 +609,7 @@ pub mod expression {
|
||||
/// (`*`, `/`, `%`)
|
||||
Factor {
|
||||
Mul := Type::Star,
|
||||
Div := Type::Div,
|
||||
Div := Type::Slash,
|
||||
Rem := Type::Rem,
|
||||
}
|
||||
/// (`+`, `-`)
|
||||
@ -619,8 +619,8 @@ pub mod expression {
|
||||
}
|
||||
/// (`<<`, `>>`)
|
||||
Shift {
|
||||
Lsh := Type::Lsh,
|
||||
Rsh := Type::Rsh,
|
||||
Lsh := Type::LtLt,
|
||||
Rsh := Type::GtGt,
|
||||
}
|
||||
/// (`&`, `|`, `^`)
|
||||
Bitwise {
|
||||
@ -632,14 +632,14 @@ pub mod expression {
|
||||
Logic {
|
||||
LogAnd := Type::AmpAmp,
|
||||
LogOr := Type::BarBar,
|
||||
LogXor := Type::CatEar,
|
||||
LogXor := Type::XorXor,
|
||||
}
|
||||
/// (`<`, `<=`, `==`, `!=`, `>=`, `>`)
|
||||
Compare {
|
||||
Less := Type::Lt,
|
||||
LessEq := Type::LtEq,
|
||||
Equal := Type::EqEq,
|
||||
NotEq := Type::NotEq,
|
||||
NotEq := Type::BangEq,
|
||||
GreaterEq := Type::GtEq,
|
||||
Greater := Type::Gt,
|
||||
}
|
||||
@ -647,15 +647,15 @@ pub mod expression {
|
||||
/// `&=`, `|=`, `^=`, `<<=`, `>>=`)
|
||||
Assign {
|
||||
Assign := Type::Eq,
|
||||
AddAssign := Type::AddEq,
|
||||
SubAssign := Type::SubEq,
|
||||
AddAssign := Type::PlusEq,
|
||||
SubAssign := Type::MinusEq,
|
||||
MulAssign := Type::StarEq,
|
||||
DivAssign := Type::DivEq,
|
||||
BitAndAssign := Type::AndEq,
|
||||
BitOrAssign := Type::OrEq,
|
||||
DivAssign := Type::SlashEq,
|
||||
BitAndAssign := Type::AmpEq,
|
||||
BitOrAssign := Type::BarEq,
|
||||
BitXorAssign := Type::XorEq,
|
||||
ShlAssign := Type::LshEq,
|
||||
ShrAssign := Type::RshEq,
|
||||
ShlAssign := Type::LtLtEq,
|
||||
ShrAssign := Type::GtGtEq,
|
||||
}
|
||||
/// (`;`)
|
||||
Ignore {
|
||||
|
@ -104,53 +104,55 @@ impl<'t> Lexer<'t> {
|
||||
}
|
||||
/// Evaluates punctuation rules
|
||||
pub fn punctuation(&mut self) -> Option<Token> {
|
||||
None.or_else(|| self.amp_amp())
|
||||
.or_else(|| self.bar_bar())
|
||||
.or_else(|| self.not_not())
|
||||
.or_else(|| self.cat_ear())
|
||||
.or_else(|| self.eq_eq())
|
||||
.or_else(|| self.gt_eq())
|
||||
.or_else(|| self.lt_eq())
|
||||
.or_else(|| self.not_eq())
|
||||
.or_else(|| self.lsh_eq())
|
||||
.or_else(|| self.rsh_eq())
|
||||
.or_else(|| self.star_eq())
|
||||
.or_else(|| self.div_eq())
|
||||
.or_else(|| self.rem_eq())
|
||||
.or_else(|| self.add_eq())
|
||||
.or_else(|| self.sub_eq())
|
||||
.or_else(|| self.and_eq())
|
||||
.or_else(|| self.or_eq())
|
||||
.or_else(|| self.xor_eq())
|
||||
.or_else(|| self.lsh())
|
||||
.or_else(|| self.rsh())
|
||||
.or_else(|| self.arrow())
|
||||
.or_else(|| self.fatarrow())
|
||||
.or_else(|| self.semi())
|
||||
.or_else(|| self.dot())
|
||||
.or_else(|| self.star())
|
||||
.or_else(|| self.div())
|
||||
.or_else(|| self.plus())
|
||||
.or_else(|| self.sub())
|
||||
.or_else(|| self.rem())
|
||||
.or_else(|| self.bang())
|
||||
.or_else(|| self.eq())
|
||||
.or_else(|| self.lt())
|
||||
.or_else(|| self.gt())
|
||||
.or_else(|| self.amp())
|
||||
.or_else(|| self.bar())
|
||||
.or_else(|| self.xor())
|
||||
.or_else(|| self.hash())
|
||||
.or_else(|| self.at())
|
||||
.or_else(|| self.colon())
|
||||
.or_else(|| self.backslash())
|
||||
.or_else(|| self.question())
|
||||
.or_else(|| self.comma())
|
||||
.or_else(|| self.tilde())
|
||||
.or_else(|| self.grave())
|
||||
None.or_else(|| self.amp_amp()) // &&
|
||||
.or_else(|| self.amp_eq()) // &=
|
||||
.or_else(|| self.amp()) // &
|
||||
.or_else(|| self.at()) // @
|
||||
.or_else(|| self.backslash()) // \
|
||||
.or_else(|| self.bang_bang()) // !!
|
||||
.or_else(|| self.bang_eq()) // !=
|
||||
.or_else(|| self.bang()) // !
|
||||
.or_else(|| self.bar_bar()) // ||
|
||||
.or_else(|| self.bar_eq()) // |=
|
||||
.or_else(|| self.bar()) // |
|
||||
.or_else(|| self.colon()) // :
|
||||
.or_else(|| self.comma()) // ,
|
||||
.or_else(|| self.dot_dot_eq()) // ..=
|
||||
.or_else(|| self.dot_dot()) // ..
|
||||
.or_else(|| self.dot()) // .
|
||||
.or_else(|| self.eq_eq()) // ==
|
||||
.or_else(|| self.fatarrow()) // =>
|
||||
.or_else(|| self.eq()) // =
|
||||
.or_else(|| self.grave()) // `
|
||||
.or_else(|| self.gt_eq()) // >=
|
||||
.or_else(|| self.gt_gt_eq()) // >>=
|
||||
.or_else(|| self.gt_gt()) // >>
|
||||
.or_else(|| self.gt()) // >
|
||||
.or_else(|| self.hash()) // #
|
||||
.or_else(|| self.lt_eq()) // <=
|
||||
.or_else(|| self.lt_lt_eq()) // <<=
|
||||
.or_else(|| self.lt_lt()) // <<
|
||||
.or_else(|| self.lt()) // <
|
||||
.or_else(|| self.minus_eq()) // -=
|
||||
.or_else(|| self.arrow()) // ->
|
||||
.or_else(|| self.minus()) // -
|
||||
.or_else(|| self.plus_eq()) // +=
|
||||
.or_else(|| self.plus()) // +
|
||||
.or_else(|| self.question()) // ?
|
||||
.or_else(|| self.rem_eq()) // %=
|
||||
.or_else(|| self.rem()) // %
|
||||
.or_else(|| self.semi()) // ;
|
||||
.or_else(|| self.slash_eq()) // /=
|
||||
.or_else(|| self.slash()) // /
|
||||
.or_else(|| self.star_eq()) // *=
|
||||
.or_else(|| self.star()) // *
|
||||
.or_else(|| self.tilde()) // ~
|
||||
.or_else(|| self.xor_eq()) // ^=
|
||||
.or_else(|| self.xor_xor()) // ^^
|
||||
.or_else(|| self.xor()) // ^
|
||||
}
|
||||
pub fn unary_op(&mut self) -> Option<Token> {
|
||||
self.bang().or_else(|| self.sub())
|
||||
self.bang().or_else(|| self.minus())
|
||||
}
|
||||
// functions for lexing individual tokens
|
||||
pub fn invalid(&mut self) -> Option<Token> {
|
||||
@ -204,11 +206,11 @@ impl<'t> Lexer<'t> {
|
||||
self.map_rule(|r| r.char(')'), Type::RParen)
|
||||
}
|
||||
// compound punctuation
|
||||
pub fn lsh(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("<<"), Type::Lsh)
|
||||
pub fn lt_lt(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("<<"), Type::LtLt)
|
||||
}
|
||||
pub fn rsh(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str(">>"), Type::Rsh)
|
||||
pub fn gt_gt(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str(">>"), Type::GtGt)
|
||||
}
|
||||
pub fn amp_amp(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("&&"), Type::AmpAmp)
|
||||
@ -216,11 +218,11 @@ impl<'t> Lexer<'t> {
|
||||
pub fn bar_bar(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("||"), Type::BarBar)
|
||||
}
|
||||
pub fn not_not(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("!!"), Type::NotNot)
|
||||
pub fn bang_bang(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("!!"), Type::BangBang)
|
||||
}
|
||||
pub fn cat_ear(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("^^"), Type::CatEar)
|
||||
pub fn xor_xor(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("^^"), Type::XorXor)
|
||||
}
|
||||
pub fn eq_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("=="), Type::EqEq)
|
||||
@ -231,38 +233,44 @@ impl<'t> Lexer<'t> {
|
||||
pub fn lt_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("<="), Type::LtEq)
|
||||
}
|
||||
pub fn not_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("!="), Type::NotEq)
|
||||
pub fn bang_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("!="), Type::BangEq)
|
||||
}
|
||||
pub fn star_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("*="), Type::StarEq)
|
||||
}
|
||||
pub fn div_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("/="), Type::DivEq)
|
||||
pub fn slash_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("/="), Type::SlashEq)
|
||||
}
|
||||
pub fn rem_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("%="), Type::RemEq)
|
||||
}
|
||||
pub fn add_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("+="), Type::AddEq)
|
||||
pub fn plus_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("+="), Type::PlusEq)
|
||||
}
|
||||
pub fn sub_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("-="), Type::SubEq)
|
||||
pub fn minus_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("-="), Type::MinusEq)
|
||||
}
|
||||
pub fn and_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("&="), Type::AndEq)
|
||||
pub fn amp_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("&="), Type::AmpEq)
|
||||
}
|
||||
pub fn or_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("|="), Type::OrEq)
|
||||
pub fn bar_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("|="), Type::BarEq)
|
||||
}
|
||||
pub fn xor_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("^="), Type::XorEq)
|
||||
}
|
||||
pub fn lsh_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("<<="), Type::LshEq)
|
||||
pub fn lt_lt_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("<<="), Type::LtLtEq)
|
||||
}
|
||||
pub fn rsh_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str(">>="), Type::RshEq)
|
||||
pub fn gt_gt_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str(">>="), Type::GtGtEq)
|
||||
}
|
||||
pub fn dot_dot_eq(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("..="), Type::DotDotEq)
|
||||
}
|
||||
pub fn dot_dot(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str(".."), Type::DotDot)
|
||||
}
|
||||
pub fn arrow(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.str("->"), Type::Arrow)
|
||||
@ -280,13 +288,13 @@ impl<'t> Lexer<'t> {
|
||||
pub fn star(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.char('*'), Type::Star)
|
||||
}
|
||||
pub fn div(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.char('/'), Type::Div)
|
||||
pub fn slash(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.char('/'), Type::Slash)
|
||||
}
|
||||
pub fn plus(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.char('+'), Type::Plus)
|
||||
}
|
||||
pub fn sub(&mut self) -> Option<Token> {
|
||||
pub fn minus(&mut self) -> Option<Token> {
|
||||
self.map_rule(|r| r.char('-'), Type::Minus)
|
||||
}
|
||||
pub fn rem(&mut self) -> Option<Token> {
|
||||
|
@ -90,11 +90,7 @@ mod lexer {
|
||||
|
||||
#[test]
|
||||
fn identifier() {
|
||||
assert_whole_input_is_token(
|
||||
"valid_identifier",
|
||||
Lexer::identifier,
|
||||
Type::Identifier,
|
||||
);
|
||||
assert_whole_input_is_token("valid_identifier", Lexer::identifier, Type::Identifier);
|
||||
assert_whole_input_is_token("_0", Lexer::identifier, Type::Identifier);
|
||||
assert_whole_input_is_token("_", Lexer::identifier, Type::Identifier);
|
||||
}
|
||||
@ -129,12 +125,7 @@ mod lexer {
|
||||
#[test]
|
||||
fn base16() {
|
||||
assert_has_type_and_range("0x1234", Lexer::integer, Type::Integer, 0..6);
|
||||
assert_has_type_and_range(
|
||||
"0x1234 \"hello\"",
|
||||
Lexer::integer,
|
||||
Type::Integer,
|
||||
0..6,
|
||||
);
|
||||
assert_has_type_and_range("0x1234 \"hello\"", Lexer::integer, Type::Integer, 0..6);
|
||||
}
|
||||
#[test]
|
||||
fn base10() {
|
||||
@ -186,7 +177,7 @@ mod lexer {
|
||||
"\" \\\"This is a quote\\\" \"",
|
||||
Lexer::string,
|
||||
Type::String,
|
||||
1..22
|
||||
1..22,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -254,14 +245,21 @@ mod lexer {
|
||||
use super::*;
|
||||
mod compound {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn lsh() {
|
||||
assert_whole_input_is_token("<<", Lexer::lsh, Type::Lsh)
|
||||
fn dot_dot() {
|
||||
assert_whole_input_is_token("..", Lexer::dot_dot, Type::DotDot)
|
||||
}
|
||||
#[test]
|
||||
fn rsh() {
|
||||
assert_whole_input_is_token(">>", Lexer::rsh, Type::Rsh)
|
||||
fn dot_dot_eq() {
|
||||
assert_whole_input_is_token("..=", Lexer::dot_dot_eq, Type::DotDotEq)
|
||||
}
|
||||
#[test]
|
||||
fn lt_lt() {
|
||||
assert_whole_input_is_token("<<", Lexer::lt_lt, Type::LtLt)
|
||||
}
|
||||
#[test]
|
||||
fn gt_gt() {
|
||||
assert_whole_input_is_token(">>", Lexer::gt_gt, Type::GtGt)
|
||||
}
|
||||
#[test]
|
||||
fn amp_amp() {
|
||||
@ -272,12 +270,12 @@ mod lexer {
|
||||
assert_whole_input_is_token("||", Lexer::bar_bar, Type::BarBar)
|
||||
}
|
||||
#[test]
|
||||
fn not_not() {
|
||||
assert_whole_input_is_token("!!", Lexer::not_not, Type::NotNot)
|
||||
fn bang_bang() {
|
||||
assert_whole_input_is_token("!!", Lexer::bang_bang, Type::BangBang)
|
||||
}
|
||||
#[test]
|
||||
fn cat_ear() {
|
||||
assert_whole_input_is_token("^^", Lexer::cat_ear, Type::CatEar)
|
||||
fn xor_xor() {
|
||||
assert_whole_input_is_token("^^", Lexer::xor_xor, Type::XorXor)
|
||||
}
|
||||
#[test]
|
||||
fn eq_eq() {
|
||||
@ -292,44 +290,44 @@ mod lexer {
|
||||
assert_whole_input_is_token("<=", Lexer::lt_eq, Type::LtEq)
|
||||
}
|
||||
#[test]
|
||||
fn not_eq() {
|
||||
assert_whole_input_is_token("!=", Lexer::not_eq, Type::NotEq)
|
||||
fn bang_eq() {
|
||||
assert_whole_input_is_token("!=", Lexer::bang_eq, Type::BangEq)
|
||||
}
|
||||
#[test]
|
||||
fn star_eq() {
|
||||
assert_whole_input_is_token("*=", Lexer::star_eq, Type::StarEq)
|
||||
}
|
||||
#[test]
|
||||
fn div_eq() {
|
||||
assert_whole_input_is_token("/=", Lexer::div_eq, Type::DivEq)
|
||||
fn slash_eq() {
|
||||
assert_whole_input_is_token("/=", Lexer::slash_eq, Type::SlashEq)
|
||||
}
|
||||
#[test]
|
||||
fn add_eq() {
|
||||
assert_whole_input_is_token("+=", Lexer::add_eq, Type::AddEq)
|
||||
fn plus_eq() {
|
||||
assert_whole_input_is_token("+=", Lexer::plus_eq, Type::PlusEq)
|
||||
}
|
||||
#[test]
|
||||
fn sub_eq() {
|
||||
assert_whole_input_is_token("-=", Lexer::sub_eq, Type::SubEq)
|
||||
fn minus_eq() {
|
||||
assert_whole_input_is_token("-=", Lexer::minus_eq, Type::MinusEq)
|
||||
}
|
||||
#[test]
|
||||
fn and_eq() {
|
||||
assert_whole_input_is_token("&=", Lexer::and_eq, Type::AndEq)
|
||||
fn amp_eq() {
|
||||
assert_whole_input_is_token("&=", Lexer::amp_eq, Type::AmpEq)
|
||||
}
|
||||
#[test]
|
||||
fn or_eq() {
|
||||
assert_whole_input_is_token("|=", Lexer::or_eq, Type::OrEq)
|
||||
fn bar_eq() {
|
||||
assert_whole_input_is_token("|=", Lexer::bar_eq, Type::BarEq)
|
||||
}
|
||||
#[test]
|
||||
fn xor_eq() {
|
||||
assert_whole_input_is_token("^=", Lexer::xor_eq, Type::XorEq)
|
||||
}
|
||||
#[test]
|
||||
fn lsh_eq() {
|
||||
assert_whole_input_is_token("<<=", Lexer::lsh_eq, Type::LshEq)
|
||||
fn lt_lt_eq() {
|
||||
assert_whole_input_is_token("<<=", Lexer::lt_lt_eq, Type::LtLtEq)
|
||||
}
|
||||
#[test]
|
||||
fn rsh_eq() {
|
||||
assert_whole_input_is_token(">>=", Lexer::rsh_eq, Type::RshEq)
|
||||
fn gt_gt_eq() {
|
||||
assert_whole_input_is_token(">>=", Lexer::gt_gt_eq, Type::GtGtEq)
|
||||
}
|
||||
}
|
||||
|
||||
@ -337,10 +335,11 @@ mod lexer {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn punctuation_class() {
|
||||
// go from least to most specific
|
||||
assert_whole_input_is_token(";", Lexer::punctuation, Type::Semi);
|
||||
assert_whole_input_is_token(".", Lexer::punctuation, Type::Dot);
|
||||
assert_whole_input_is_token("*", Lexer::punctuation, Type::Star);
|
||||
assert_whole_input_is_token("/", Lexer::punctuation, Type::Div);
|
||||
assert_whole_input_is_token("/", Lexer::punctuation, Type::Slash);
|
||||
assert_whole_input_is_token("+", Lexer::punctuation, Type::Plus);
|
||||
assert_whole_input_is_token("-", Lexer::punctuation, Type::Minus);
|
||||
assert_whole_input_is_token("%", Lexer::punctuation, Type::Rem);
|
||||
@ -359,6 +358,27 @@ mod lexer {
|
||||
assert_whole_input_is_token("~", Lexer::punctuation, Type::Tilde);
|
||||
assert_whole_input_is_token("`", Lexer::punctuation, Type::Grave);
|
||||
assert_whole_input_is_token("\\", Lexer::punctuation, Type::Backslash);
|
||||
assert_whole_input_is_token("<<", Lexer::punctuation, Type::LtLt);
|
||||
assert_whole_input_is_token(">>", Lexer::punctuation, Type::GtGt);
|
||||
assert_whole_input_is_token("&&", Lexer::punctuation, Type::AmpAmp);
|
||||
assert_whole_input_is_token("||", Lexer::punctuation, Type::BarBar);
|
||||
assert_whole_input_is_token("!!", Lexer::punctuation, Type::BangBang);
|
||||
assert_whole_input_is_token("^^", Lexer::punctuation, Type::XorXor);
|
||||
assert_whole_input_is_token("==", Lexer::punctuation, Type::EqEq);
|
||||
assert_whole_input_is_token(">=", Lexer::punctuation, Type::GtEq);
|
||||
assert_whole_input_is_token("<=", Lexer::punctuation, Type::LtEq);
|
||||
assert_whole_input_is_token("!=", Lexer::punctuation, Type::BangEq);
|
||||
assert_whole_input_is_token("*=", Lexer::punctuation, Type::StarEq);
|
||||
assert_whole_input_is_token("/=", Lexer::punctuation, Type::SlashEq);
|
||||
assert_whole_input_is_token("+=", Lexer::punctuation, Type::PlusEq);
|
||||
assert_whole_input_is_token("-=", Lexer::punctuation, Type::MinusEq);
|
||||
assert_whole_input_is_token("&=", Lexer::punctuation, Type::AmpEq);
|
||||
assert_whole_input_is_token("|=", Lexer::punctuation, Type::BarEq);
|
||||
assert_whole_input_is_token("^=", Lexer::punctuation, Type::XorEq);
|
||||
assert_whole_input_is_token("..", Lexer::punctuation, Type::DotDot);
|
||||
assert_whole_input_is_token("..=", Lexer::punctuation, Type::DotDotEq);
|
||||
assert_whole_input_is_token("<<=", Lexer::punctuation, Type::LtLtEq);
|
||||
assert_whole_input_is_token(">>=", Lexer::punctuation, Type::GtGtEq);
|
||||
}
|
||||
// individual functions below
|
||||
#[test]
|
||||
@ -374,8 +394,8 @@ mod lexer {
|
||||
assert_whole_input_is_token("*", Lexer::star, Type::Star)
|
||||
}
|
||||
#[test]
|
||||
fn div() {
|
||||
assert_whole_input_is_token("/", Lexer::div, Type::Div)
|
||||
fn slash() {
|
||||
assert_whole_input_is_token("/", Lexer::slash, Type::Slash)
|
||||
}
|
||||
#[test]
|
||||
fn plus() {
|
||||
@ -383,7 +403,7 @@ mod lexer {
|
||||
}
|
||||
#[test]
|
||||
fn minus() {
|
||||
assert_whole_input_is_token("-", Lexer::sub, Type::Minus)
|
||||
assert_whole_input_is_token("-", Lexer::minus, Type::Minus)
|
||||
}
|
||||
#[test]
|
||||
fn rem() {
|
||||
@ -406,11 +426,11 @@ mod lexer {
|
||||
assert_whole_input_is_token(">", Lexer::gt, Type::Gt)
|
||||
}
|
||||
#[test]
|
||||
fn and() {
|
||||
fn amp() {
|
||||
assert_whole_input_is_token("&", Lexer::amp, Type::Amp)
|
||||
}
|
||||
#[test]
|
||||
fn or() {
|
||||
fn bar() {
|
||||
assert_whole_input_is_token("|", Lexer::bar, Type::Bar)
|
||||
}
|
||||
#[test]
|
||||
|
@ -16,59 +16,59 @@ pub enum Type {
|
||||
Float,
|
||||
String,
|
||||
Character,
|
||||
// Delimiters
|
||||
LCurly,
|
||||
RCurly,
|
||||
LBrack,
|
||||
RBrack,
|
||||
LParen,
|
||||
RParen,
|
||||
// Compound punctuation
|
||||
Lsh,
|
||||
Rsh,
|
||||
AmpAmp,
|
||||
BarBar,
|
||||
NotNot,
|
||||
CatEar,
|
||||
EqEq,
|
||||
GtEq,
|
||||
LtEq,
|
||||
NotEq,
|
||||
StarEq,
|
||||
DivEq,
|
||||
RemEq,
|
||||
AddEq,
|
||||
SubEq,
|
||||
AndEq,
|
||||
OrEq,
|
||||
XorEq,
|
||||
LshEq,
|
||||
RshEq,
|
||||
Arrow,
|
||||
FatArrow,
|
||||
// Simple punctuation
|
||||
Semi,
|
||||
Dot,
|
||||
Star,
|
||||
Div,
|
||||
Plus,
|
||||
Minus,
|
||||
Rem,
|
||||
Bang,
|
||||
Eq,
|
||||
Lt,
|
||||
Gt,
|
||||
Amp,
|
||||
Bar,
|
||||
Xor,
|
||||
Hash,
|
||||
At,
|
||||
Colon,
|
||||
Backslash,
|
||||
Question,
|
||||
Comma,
|
||||
Tilde,
|
||||
Grave,
|
||||
// Delimiters and punctuation
|
||||
LCurly, // {
|
||||
RCurly, // }
|
||||
LBrack, // [
|
||||
RBrack, // ]
|
||||
LParen, // (
|
||||
RParen, // )
|
||||
Amp, // &
|
||||
AmpAmp, // &&
|
||||
AmpEq, // &=
|
||||
Arrow, // ->
|
||||
At, // @
|
||||
Backslash, // \
|
||||
Bang, // !
|
||||
BangBang, // !!
|
||||
BangEq, // !=
|
||||
Bar, // |
|
||||
BarBar, // ||
|
||||
BarEq, // |=
|
||||
Colon, // :
|
||||
Comma, // ,
|
||||
Dot, // .
|
||||
DotDot, // ..
|
||||
DotDotEq, // ..=
|
||||
Eq, // =
|
||||
EqEq, // ==
|
||||
FatArrow, // =>
|
||||
Grave, // `
|
||||
Gt, // >
|
||||
GtEq, // >=
|
||||
GtGt, // >>
|
||||
GtGtEq, // >>=
|
||||
Hash, // #
|
||||
Lt, // <
|
||||
LtEq, // <=
|
||||
LtLt, // <<
|
||||
LtLtEq, // <<=
|
||||
Minus, // -
|
||||
MinusEq, // -=
|
||||
Plus, // +
|
||||
PlusEq, // +=
|
||||
Question, // ?
|
||||
Rem, // %
|
||||
RemEq, // %=
|
||||
Semi, // ;
|
||||
Slash, // /
|
||||
SlashEq, // /=
|
||||
Star, // *
|
||||
StarEq, // *=
|
||||
Tilde, // ~
|
||||
Xor, // ^
|
||||
XorEq, // ^=
|
||||
XorXor, // ^^
|
||||
}
|
||||
|
||||
/// Represents a reserved word.
|
||||
|
@ -5,64 +5,66 @@ use std::fmt::Display;
|
||||
impl Display for Type {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Type::Invalid => Display::fmt("invalid", f),
|
||||
Type::Comment => Display::fmt("comment", f),
|
||||
Type::Identifier => Display::fmt("identifier", f),
|
||||
Type::Keyword(k) => Display::fmt(k, f),
|
||||
Type::Integer => Display::fmt("integer literal", f),
|
||||
Type::Float => Display::fmt("float literal", f),
|
||||
Type::String => Display::fmt("string literal", f),
|
||||
Type::Character => Display::fmt("char literal", f),
|
||||
Type::LCurly => Display::fmt("left curly", f),
|
||||
Type::RCurly => Display::fmt("right curly", f),
|
||||
Type::LBrack => Display::fmt("left brack", f),
|
||||
Type::RBrack => Display::fmt("right brack", f),
|
||||
Type::LParen => Display::fmt("left paren", f),
|
||||
Type::RParen => Display::fmt("right paren", f),
|
||||
Type::Lsh => Display::fmt("shift left", f),
|
||||
Type::Rsh => Display::fmt("shift right", f),
|
||||
Type::AmpAmp => Display::fmt("and-and", f),
|
||||
Type::BarBar => Display::fmt("or-or", f),
|
||||
Type::NotNot => Display::fmt("not-not", f),
|
||||
Type::CatEar => Display::fmt("cat-ears", f),
|
||||
Type::EqEq => Display::fmt("equal to", f),
|
||||
Type::GtEq => Display::fmt("greater than or equal to", f),
|
||||
Type::LtEq => Display::fmt("less than or equal to", f),
|
||||
Type::NotEq => Display::fmt("not equal to", f),
|
||||
Type::StarEq => Display::fmt("star-assign", f),
|
||||
Type::DivEq => Display::fmt("div-assign", f),
|
||||
Type::RemEq => Display::fmt("rem-assign", f),
|
||||
Type::AddEq => Display::fmt("add-assign", f),
|
||||
Type::SubEq => Display::fmt("sub-assign", f),
|
||||
Type::AndEq => Display::fmt("and-assign", f),
|
||||
Type::OrEq => Display::fmt("or-assign", f),
|
||||
Type::XorEq => Display::fmt("xor-assign", f),
|
||||
Type::LshEq => Display::fmt("shift left-assign", f),
|
||||
Type::RshEq => Display::fmt("shift right-assign", f),
|
||||
Type::Arrow => Display::fmt("arrow", f),
|
||||
Type::FatArrow => Display::fmt("fat arrow", f),
|
||||
Type::Semi => Display::fmt("ignore", f),
|
||||
Type::Dot => Display::fmt("dot", f),
|
||||
Type::Star => Display::fmt("star", f),
|
||||
Type::Div => Display::fmt("div", f),
|
||||
Type::Plus => Display::fmt("add", f),
|
||||
Type::Minus => Display::fmt("sub", f),
|
||||
Type::Rem => Display::fmt("rem", f),
|
||||
Type::Bang => Display::fmt("bang", f),
|
||||
Type::Eq => Display::fmt("assign", f),
|
||||
Type::Lt => Display::fmt("less than", f),
|
||||
Type::Gt => Display::fmt("greater than", f),
|
||||
Type::Amp => Display::fmt("and", f),
|
||||
Type::Bar => Display::fmt("or", f),
|
||||
Type::Xor => Display::fmt("xor", f),
|
||||
Type::Hash => Display::fmt("hash", f),
|
||||
Type::At => Display::fmt("at", f),
|
||||
Type::Colon => Display::fmt("colon", f),
|
||||
Type::Backslash => Display::fmt("backslash", f),
|
||||
Type::Question => Display::fmt("huh?", f),
|
||||
Type::Comma => Display::fmt("comma", f),
|
||||
Type::Tilde => Display::fmt("tilde", f),
|
||||
Type::Grave => Display::fmt("grave", f),
|
||||
Type::Invalid => "invalid".fmt(f),
|
||||
Type::Comment => "comment".fmt(f),
|
||||
Type::Identifier => "identifier".fmt(f),
|
||||
Type::Keyword(k) => k.fmt(f),
|
||||
Type::Integer => "integer literal".fmt(f),
|
||||
Type::Float => "float literal".fmt(f),
|
||||
Type::String => "string literal".fmt(f),
|
||||
Type::Character => "char literal".fmt(f),
|
||||
Type::LCurly => "left curly".fmt(f),
|
||||
Type::RCurly => "right curly".fmt(f),
|
||||
Type::LBrack => "left brack".fmt(f),
|
||||
Type::RBrack => "right brack".fmt(f),
|
||||
Type::LParen => "left paren".fmt(f),
|
||||
Type::RParen => "right paren".fmt(f),
|
||||
Type::Amp => "and".fmt(f),
|
||||
Type::AmpAmp => "and-and".fmt(f),
|
||||
Type::AmpEq => "and-assign".fmt(f),
|
||||
Type::Arrow => "arrow".fmt(f),
|
||||
Type::At => "at".fmt(f),
|
||||
Type::Backslash => "backslash".fmt(f),
|
||||
Type::Bang => "bang".fmt(f),
|
||||
Type::BangBang => "not-not".fmt(f),
|
||||
Type::BangEq => "not equal to".fmt(f),
|
||||
Type::Bar => "or".fmt(f),
|
||||
Type::BarBar => "or-or".fmt(f),
|
||||
Type::BarEq => "or-assign".fmt(f),
|
||||
Type::Colon => "colon".fmt(f),
|
||||
Type::Comma => "comma".fmt(f),
|
||||
Type::Dot => "dot".fmt(f),
|
||||
Type::DotDot => "exclusive range".fmt(f),
|
||||
Type::DotDotEq => "inclusive range".fmt(f),
|
||||
Type::Eq => "assign".fmt(f),
|
||||
Type::EqEq => "equal to".fmt(f),
|
||||
Type::FatArrow => "fat arrow".fmt(f),
|
||||
Type::Grave => "grave".fmt(f),
|
||||
Type::Gt => "greater than".fmt(f),
|
||||
Type::GtEq => "greater than or equal to".fmt(f),
|
||||
Type::GtGt => "shift right".fmt(f),
|
||||
Type::GtGtEq => "shift right-assign".fmt(f),
|
||||
Type::Hash => "hash".fmt(f),
|
||||
Type::Lt => "less than".fmt(f),
|
||||
Type::LtEq => "less than or equal to".fmt(f),
|
||||
Type::LtLt => "shift left".fmt(f),
|
||||
Type::LtLtEq => "shift left-assign".fmt(f),
|
||||
Type::Minus => "sub".fmt(f),
|
||||
Type::MinusEq => "sub-assign".fmt(f),
|
||||
Type::Plus => "add".fmt(f),
|
||||
Type::PlusEq => "add-assign".fmt(f),
|
||||
Type::Question => "huh?".fmt(f),
|
||||
Type::Rem => "rem".fmt(f),
|
||||
Type::RemEq => "rem-assign".fmt(f),
|
||||
Type::Semi => "ignore".fmt(f),
|
||||
Type::Slash => "div".fmt(f),
|
||||
Type::SlashEq => "div-assign".fmt(f),
|
||||
Type::Star => "star".fmt(f),
|
||||
Type::StarEq => "star-assign".fmt(f),
|
||||
Type::Tilde => "tilde".fmt(f),
|
||||
Type::Xor => "xor".fmt(f),
|
||||
Type::XorEq => "xor-assign".fmt(f),
|
||||
Type::XorXor => "cat-ears".fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,23 +72,23 @@ impl Display for Type {
|
||||
impl Display for Keyword {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Break => Display::fmt("break", f),
|
||||
Self::Continue => Display::fmt("continue", f),
|
||||
Self::Else => Display::fmt("else", f),
|
||||
Self::False => Display::fmt("false", f),
|
||||
Self::For => Display::fmt("for", f),
|
||||
Self::Fn => Display::fmt("fn", f),
|
||||
Self::If => Display::fmt("if", f),
|
||||
Self::In => Display::fmt("in", f),
|
||||
Self::Let => Display::fmt("let", f),
|
||||
Self::Return => Display::fmt("return", f),
|
||||
Self::True => Display::fmt("true", f),
|
||||
Self::While => Display::fmt("while", f),
|
||||
Self::Break => "break".fmt(f),
|
||||
Self::Continue => "continue".fmt(f),
|
||||
Self::Else => "else".fmt(f),
|
||||
Self::False => "false".fmt(f),
|
||||
Self::For => "for".fmt(f),
|
||||
Self::Fn => "fn".fmt(f),
|
||||
Self::If => "if".fmt(f),
|
||||
Self::In => "in".fmt(f),
|
||||
Self::Let => "let".fmt(f),
|
||||
Self::Return => "return".fmt(f),
|
||||
Self::True => "true".fmt(f),
|
||||
Self::While => "while".fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::str::FromStr for Keyword {
|
||||
type Err = ();
|
||||
type Err = (); // If an identifier isn't a keyword, that's okay.
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s {
|
||||
"break" => Self::Break,
|
||||
|
Loading…
Reference in New Issue
Block a user