Better floating point support for wgsl (#142)

* Add custom consume_number function for consuming numbers into tokens to wgsl frontend

* clippy
This commit is contained in:
Lachlan Sneff
2020-08-20 01:41:24 -04:00
committed by GitHub
parent bd276bf4a4
commit 5035362ee6

View File

@@ -44,6 +44,28 @@ mod lex {
input.split_at(pos)
}
fn consume_number(input: &str) -> (&str, &str) {
let mut is_first_char = true;
let mut right_after_exponent = false;
let mut what = |c| {
if is_first_char {
is_first_char = false;
c == '-' || c >= '0' && c <= '9' || c == '.'
} else if c == 'e' || c == 'E' {
right_after_exponent = true;
true
} else if right_after_exponent {
right_after_exponent = false;
c >= '0' && c <= '9' || c == '-'
} else {
c >= '0' && c <= '9' || c == '.'
}
};
let pos = input.find(|c| !what(c)).unwrap_or_else(|| input.len());
input.split_at(pos)
}
pub fn consume_token(mut input: &str) -> (Token<'_>, &str) {
input = input.trim_start();
let mut chars = input.chars();
@@ -60,7 +82,17 @@ mod lex {
(Token::Separator(cur), input)
}
}
';' | ',' | '.' => (Token::Separator(cur), chars.as_str()),
';' | ',' => (Token::Separator(cur), chars.as_str()),
'.' => {
let og_chars = chars.as_str();
match chars.next() {
Some('0'..='9') => {
let (number, rest) = consume_number(input);
(Token::Number(number), rest)
}
_ => (Token::Separator(cur), og_chars),
}
}
'(' | ')' | '{' | '}' => (Token::Paren(cur), chars.as_str()),
'<' | '>' => {
input = chars.as_str();
@@ -87,7 +119,7 @@ mod lex {
}
}
'0'..='9' => {
let (number, rest) = consume_any(input, |c| (c >= '0' && c <= '9' || c == '.'));
let (number, rest) = consume_number(input);
(Token::Number(number), rest)
}
'a'..='z' | 'A'..='Z' | '_' => {
@@ -106,11 +138,14 @@ mod lex {
}
}
'-' => {
input = chars.as_str();
if chars.next() == Some('>') {
(Token::Arrow, chars.as_str())
} else {
(Token::Operation(cur), input)
let og_chars = chars.as_str();
match chars.next() {
Some('>') => (Token::Arrow, chars.as_str()),
Some('0'..='9') | Some('.') => {
let (number, rest) = consume_number(input);
(Token::Number(number), rest)
}
_ => (Token::Operation(cur), og_chars),
}
}
'+' | '*' | '/' | '%' | '^' => (Token::Operation(cur), chars.as_str()),