Support Elvis operator.

This commit is contained in:
Stephen Chung
2022-06-10 10:26:06 +08:00
parent 206318e14c
commit 0f1e51b1c9
7 changed files with 104 additions and 60 deletions

View File

@@ -420,6 +420,8 @@ pub enum Token {
Comma,
/// `.`
Period,
/// `?.`
Elvis,
/// `..`
ExclusiveRange,
/// `..=`
@@ -576,6 +578,7 @@ impl Token {
Underscore => "_",
Comma => ",",
Period => ".",
Elvis => "?.",
ExclusiveRange => "..",
InclusiveRange => "..=",
MapStart => "#{",
@@ -771,6 +774,7 @@ impl Token {
"_" => Underscore,
"," => Comma,
"." => Period,
"?." => Elvis,
".." => ExclusiveRange,
"..=" => InclusiveRange,
"#{" => MapStart,
@@ -877,11 +881,12 @@ impl Token {
use Token::*;
match self {
LexError(..) |
LexError(..) |
SemiColon | // ; - is unary
Colon | // #{ foo: - is unary
Comma | // ( ... , -expr ) - is unary
//Period |
//Elvis |
ExclusiveRange | // .. - is unary
InclusiveRange | // ..= - is unary
LeftBrace | // { -expr } - is unary
@@ -987,12 +992,12 @@ impl Token {
match self {
LeftBrace | RightBrace | LeftParen | RightParen | LeftBracket | RightBracket | Plus
| UnaryPlus | Minus | UnaryMinus | Multiply | Divide | Modulo | PowerOf | LeftShift
| RightShift | SemiColon | Colon | DoubleColon | Comma | Period | ExclusiveRange
| InclusiveRange | MapStart | Equals | LessThan | GreaterThan | LessThanEqualsTo
| GreaterThanEqualsTo | EqualsTo | NotEqualsTo | Bang | Pipe | Or | XOr | Ampersand
| And | PlusAssign | MinusAssign | MultiplyAssign | DivideAssign | LeftShiftAssign
| RightShiftAssign | AndAssign | OrAssign | XOrAssign | ModuloAssign
| PowerOfAssign => true,
| RightShift | SemiColon | Colon | DoubleColon | Comma | Period | Elvis
| ExclusiveRange | InclusiveRange | MapStart | Equals | LessThan | GreaterThan
| LessThanEqualsTo | GreaterThanEqualsTo | EqualsTo | NotEqualsTo | Bang | Pipe
| Or | XOr | Ampersand | And | PlusAssign | MinusAssign | MultiplyAssign
| DivideAssign | LeftShiftAssign | RightShiftAssign | AndAssign | OrAssign
| XOrAssign | ModuloAssign | PowerOfAssign => true,
_ => false,
}
@@ -2033,7 +2038,10 @@ fn get_next_token_inner(
('$', ..) => return Some((Token::Reserved("$".into()), start_pos)),
('?', '.') => return Some((Token::Reserved("?.".into()), start_pos)),
('?', '.') => {
eat_next(stream, pos);
return Some((Token::Elvis, start_pos));
}
('?', ..) => return Some((Token::Reserved("?".into()), start_pos)),
(ch, ..) if ch.is_whitespace() => (),