work
This commit is contained in:
+69
-37
@@ -3,17 +3,26 @@ use std::{iter::Peekable, str::CharIndices};
|
||||
|
||||
def_tokens! {
|
||||
symbol {
|
||||
'=' => Equal,
|
||||
':' => Colon,
|
||||
';' => Semicolon,
|
||||
'{' => OpenCurly,
|
||||
'}' => CloseCurly,
|
||||
'(' => OpenParen,
|
||||
')' => CloseParen,
|
||||
'-' => Dash,
|
||||
'+' => Plus,
|
||||
'*' => Asterisk,
|
||||
'/' => Slash,
|
||||
Equal: "=",
|
||||
Colon: ":",
|
||||
Semicolon: ";",
|
||||
Plus: "+",
|
||||
Dash: "-",
|
||||
Asterisk: "*",
|
||||
Slash: "/",
|
||||
OpenParen: "(",
|
||||
CloseParen: ")",
|
||||
OpenSquare: "[",
|
||||
CloseSquare: "]",
|
||||
OpenCurly: "{",
|
||||
CloseCurly: "}",
|
||||
Arrow: "->",
|
||||
DoubleArrow: "=>",
|
||||
PlusEqual: "+=",
|
||||
DashEqual: "-=",
|
||||
AsteriskEqual: "*=",
|
||||
SlashEqual: "/=",
|
||||
DoubleColon: "::",
|
||||
}
|
||||
keyword {
|
||||
Let: "let",
|
||||
@@ -22,6 +31,7 @@ def_tokens! {
|
||||
Loop: "loop",
|
||||
While: "while",
|
||||
For: "for",
|
||||
Match: "match",
|
||||
}
|
||||
other {
|
||||
Ident(String),
|
||||
@@ -55,13 +65,53 @@ impl Iterator for Tokens<'_> {
|
||||
end: i,
|
||||
file: self.file,
|
||||
};
|
||||
if let Some(inner) = from_char(c) {
|
||||
return Some(Spanned { inner, span });
|
||||
}
|
||||
if c.is_whitespace() {
|
||||
return self.next();
|
||||
}
|
||||
macro_rules! then {
|
||||
(_ => $def:expr, $($char:expr => $to:expr,)*) => {
|
||||
match self.chars.peek() {
|
||||
$(Some((_, $char)) => {
|
||||
self.chars.next();
|
||||
$to
|
||||
},)*
|
||||
_ => $def,
|
||||
}
|
||||
};
|
||||
}
|
||||
let inner = match c {
|
||||
'(' => Token::OpenParen,
|
||||
')' => Token::CloseParen,
|
||||
'[' => Token::OpenSquare,
|
||||
']' => Token::CloseSquare,
|
||||
'{' => Token::OpenCurly,
|
||||
'}' => Token::CloseCurly,
|
||||
'+' => then! {
|
||||
_ => Token::Plus,
|
||||
'=' => Token::PlusEqual,
|
||||
},
|
||||
'-' => then! {
|
||||
_ => Token::Dash,
|
||||
'=' => Token::DashEqual,
|
||||
'>' => Token::Arrow,
|
||||
},
|
||||
'*' => then! {
|
||||
_ => Token::Asterisk,
|
||||
'=' => Token::AsteriskEqual,
|
||||
},
|
||||
'/' => then! {
|
||||
_ => Token::Slash,
|
||||
'=' => Token::SlashEqual,
|
||||
},
|
||||
':' => then! {
|
||||
_ => Token::Colon,
|
||||
':' => Token::DoubleColon,
|
||||
},
|
||||
';' => Token::Semicolon,
|
||||
'=' => then! {
|
||||
_ => Token::Equal,
|
||||
'>' => Token::DoubleArrow,
|
||||
},
|
||||
'0'..='9' => {
|
||||
let mut s = c.to_string();
|
||||
while let Some((i, c)) = self.chars.peek()
|
||||
@@ -105,23 +155,11 @@ impl Iterator for Tokens<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! expand_sym_names {
|
||||
({
|
||||
$($sym_char:expr => $sym_name:ident,)*
|
||||
}) => {
|
||||
$($sym_name,)*
|
||||
};
|
||||
({
|
||||
$($sym_char:expr => $sym_res:tt,)*
|
||||
}) => {
|
||||
expand_sym_names!($sym_res)
|
||||
};
|
||||
}
|
||||
use expand_sym_names;
|
||||
|
||||
macro_rules! def_tokens {
|
||||
{
|
||||
symbol $syms:tt
|
||||
symbol {
|
||||
$($sym_name:ident: $sym_str:expr,)*
|
||||
}
|
||||
keyword {
|
||||
$($kw_name:ident: $kw_str:expr,)*
|
||||
}
|
||||
@@ -131,16 +169,10 @@ macro_rules! def_tokens {
|
||||
} => {
|
||||
#[derive(PartialEq)]
|
||||
pub enum Token {
|
||||
$($syms,)*
|
||||
$($sym_name,)*
|
||||
$($kw_name,)*
|
||||
$($other_name($data),)*
|
||||
}
|
||||
fn from_char(c: char) -> Option<Token> {
|
||||
match c {
|
||||
$($sym_char => Some(Token::$sym_res),)*
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
fn from_str(s: String) -> Token {
|
||||
match s.as_str() {
|
||||
$($kw_str => Token::$kw_name,)*
|
||||
@@ -150,7 +182,7 @@ macro_rules! def_tokens {
|
||||
impl std::fmt::Display for Token {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
$(Token::$sym_res => write!(f, "{}", $sym_char),)*
|
||||
$(Token::$sym_name => write!(f, "{}", $sym_str),)*
|
||||
$(Token::$kw_name => write!(f, $kw_str),)*
|
||||
$(Token::$other_name(v) => write!(f, "{v}"),)*
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user