From 5035362ee6d9cc311dfc907d09ae92de14560d0b Mon Sep 17 00:00:00 2001 From: Lachlan Sneff Date: Thu, 20 Aug 2020 01:41:24 -0400 Subject: [PATCH] Better floating point support for wgsl (#142) * Add custom consume_number function for consuming numbers into tokens to wgsl frontend * clippy --- src/front/wgsl.rs | 49 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/front/wgsl.rs b/src/front/wgsl.rs index 3c52952660..8ccdd41ad2 100644 --- a/src/front/wgsl.rs +++ b/src/front/wgsl.rs @@ -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()),