refactor consume_token fn body

This commit is contained in:
teoxoy
2022-04-17 20:02:18 +02:00
committed by Dzmitry Malyshau
parent 90b3c18fae
commit 0e2bb0194b
2 changed files with 41 additions and 56 deletions

View File

@@ -264,11 +264,11 @@ fn consume_number(input: &str) -> (Token, &str) {
) )
} }
fn consume_token(mut input: &str, generic: bool) -> (Token<'_>, &str) { fn consume_token(input: &str, generic: bool) -> (Token<'_>, &str) {
let mut chars = input.chars(); let mut chars = input.chars();
let cur = match chars.next() { let cur = match chars.next() {
Some(c) => c, Some(c) => c,
None => return (Token::End, input), None => return (Token::End, ""),
}; };
match cur { match cur {
':' | ';' | ',' => (Token::Separator(cur), chars.as_str()), ':' | ';' | ',' => (Token::Separator(cur), chars.as_str()),
@@ -282,108 +282,95 @@ fn consume_token(mut input: &str, generic: bool) -> (Token<'_>, &str) {
'@' => (Token::Attribute, chars.as_str()), '@' => (Token::Attribute, chars.as_str()),
'(' | ')' | '{' | '}' | '[' | ']' => (Token::Paren(cur), chars.as_str()), '(' | ')' | '{' | '}' | '[' | ']' => (Token::Paren(cur), chars.as_str()),
'<' | '>' => { '<' | '>' => {
input = chars.as_str(); let og_chars = chars.as_str();
let next = chars.next(); match chars.next() {
if next == Some('=') && !generic { Some('=') if !generic => (Token::LogicalOperation(cur), chars.as_str()),
(Token::LogicalOperation(cur), chars.as_str()) Some(c) if c == cur && !generic => {
} else if next == Some(cur) && !generic { let og_chars = chars.as_str();
input = chars.as_str(); match chars.next() {
if chars.next() == Some('=') { Some('=') => (Token::AssignmentOperation(cur), chars.as_str()),
(Token::AssignmentOperation(cur), chars.as_str()) _ => (Token::ShiftOperation(cur), og_chars),
} else {
(Token::ShiftOperation(cur), input)
} }
} else { }
(Token::Paren(cur), input) _ => (Token::Paren(cur), og_chars),
} }
} }
'0'..='9' => consume_number(input), '0'..='9' => consume_number(input),
'/' => { '/' => {
input = chars.as_str(); let og_chars = chars.as_str();
match chars.next() { match chars.next() {
Some('/') => { Some('/') => {
let _ = chars.position(is_comment_end); let _ = chars.position(is_comment_end);
(Token::Trivia, chars.as_str()) (Token::Trivia, chars.as_str())
} }
Some('*') => { Some('*') => {
input = chars.as_str();
let mut depth = 1; let mut depth = 1;
let mut prev = '\0'; let mut prev = None;
for c in &mut chars { for c in &mut chars {
match (prev, c) { match (prev, c) {
('*', '/') => { (Some('*'), '/') => {
prev = '\0'; prev = None;
depth -= 1; depth -= 1;
if depth == 0 { if depth == 0 {
break; return (Token::Trivia, chars.as_str());
} }
} }
('/', '*') => { (Some('/'), '*') => {
prev = '\0'; prev = None;
depth += 1; depth += 1;
} }
_ => { _ => {
prev = c; prev = Some(c);
} }
} }
} }
if depth > 0 { (Token::End, "")
(Token::UnterminatedBlockComment, input)
} else {
(Token::Trivia, chars.as_str())
}
} }
Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), Some('=') => (Token::AssignmentOperation(cur), chars.as_str()),
_ => (Token::Operation(cur), input), _ => (Token::Operation(cur), og_chars),
} }
} }
'-' => { '-' => {
let sub_input = chars.as_str(); let og_chars = chars.as_str();
match chars.next() { match chars.next() {
Some('>') => (Token::Arrow, chars.as_str()), Some('>') => (Token::Arrow, chars.as_str()),
Some('0'..='9' | '.') => consume_number(input), Some('0'..='9' | '.') => consume_number(input),
Some('-') => (Token::DecrementOperation, chars.as_str()), Some('-') => (Token::DecrementOperation, chars.as_str()),
Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), Some('=') => (Token::AssignmentOperation(cur), chars.as_str()),
_ => (Token::Operation(cur), sub_input), _ => (Token::Operation(cur), og_chars),
} }
} }
'+' => { '+' => {
input = chars.as_str(); let og_chars = chars.as_str();
match chars.next() { match chars.next() {
Some('+') => (Token::IncrementOperation, chars.as_str()), Some('+') => (Token::IncrementOperation, chars.as_str()),
Some('=') => (Token::AssignmentOperation(cur), chars.as_str()), Some('=') => (Token::AssignmentOperation(cur), chars.as_str()),
_ => (Token::Operation(cur), input), _ => (Token::Operation(cur), og_chars),
} }
} }
'*' | '%' | '^' => { '*' | '%' | '^' => {
input = chars.as_str(); let og_chars = chars.as_str();
if chars.next() == Some('=') { match chars.next() {
(Token::AssignmentOperation(cur), chars.as_str()) Some('=') => (Token::AssignmentOperation(cur), chars.as_str()),
} else { _ => (Token::Operation(cur), og_chars),
(Token::Operation(cur), input)
} }
} }
'~' => (Token::Operation(cur), chars.as_str()), '~' => (Token::Operation(cur), chars.as_str()),
'!' => { '=' | '!' => {
input = chars.as_str(); let og_chars = chars.as_str();
if chars.next() == Some('=') { match chars.next() {
(Token::LogicalOperation(cur), chars.as_str()) Some('=') => (Token::LogicalOperation(cur), chars.as_str()),
} else { _ => (Token::Operation(cur), og_chars),
(Token::Operation(cur), input)
} }
} }
'=' | '&' | '|' => { '&' | '|' => {
input = chars.as_str(); let og_chars = chars.as_str();
let next = chars.next(); match chars.next() {
if next == Some(cur) { Some(c) if c == cur => (Token::LogicalOperation(cur), chars.as_str()),
(Token::LogicalOperation(cur), chars.as_str()) Some('=') => (Token::AssignmentOperation(cur), chars.as_str()),
} else if next == Some('=') { _ => (Token::Operation(cur), og_chars),
(Token::AssignmentOperation(cur), chars.as_str())
} else {
(Token::Operation(cur), input)
} }
} }
_ if is_blankspace(cur) => { _ if is_blankspace(cur) => {

View File

@@ -70,7 +70,6 @@ pub enum Token<'a> {
DecrementOperation, DecrementOperation,
Arrow, Arrow,
Unknown(char), Unknown(char),
UnterminatedBlockComment,
Trivia, Trivia,
End, End,
} }
@@ -203,7 +202,6 @@ impl<'a> Error<'a> {
Token::DecrementOperation => "decrement operation".to_string(), Token::DecrementOperation => "decrement operation".to_string(),
Token::Arrow => "->".to_string(), Token::Arrow => "->".to_string(),
Token::Unknown(c) => format!("unknown ('{}')", c), Token::Unknown(c) => format!("unknown ('{}')", c),
Token::UnterminatedBlockComment => "unterminated block comment".to_string(),
Token::Trivia => "trivia".to_string(), Token::Trivia => "trivia".to_string(),
Token::End => "end".to_string(), Token::End => "end".to_string(),
} }