simplify parsing of float exponents

This commit is contained in:
Connor Skees 2021-07-20 11:28:47 -04:00
parent 2ec365ddfc
commit 584b42f00f
3 changed files with 49 additions and 40 deletions

View File

@ -5,7 +5,6 @@ use crate::{
error::SassResult, error::SassResult,
lexer::Lexer, lexer::Lexer,
parse::Stmt, parse::Stmt,
utils::eat_whole_number,
Token, Token,
}; };
@ -54,12 +53,12 @@ impl<'a, 'b> KeyframesSelectorParser<'a, 'b> {
} }
} }
'0'..='9' => { '0'..='9' => {
let mut num = eat_whole_number(self.parser.toks); let mut num = self.parser.parse_whole_number();
if let Some(Token { kind: '.', .. }) = self.parser.toks.peek() { if let Some(Token { kind: '.', .. }) = self.parser.toks.peek() {
self.parser.toks.next(); self.parser.toks.next();
num.push('.'); num.push('.');
num.push_str(&eat_whole_number(self.parser.toks)); num.push_str(&self.parser.parse_whole_number());
} }
self.parser.expect_char('%')?; self.parser.expect_char('%')?;

View File

@ -13,7 +13,7 @@ use crate::{
error::SassResult, error::SassResult,
lexer::Lexer, lexer::Lexer,
unit::Unit, unit::Unit,
utils::{eat_whole_number, is_name, IsWhitespace, ParsedNumber}, utils::{is_name, IsWhitespace, ParsedNumber},
value::{Number, SassFunction, SassMap, Value}, value::{Number, SassFunction, SassMap, Value},
Token, Token,
}; };
@ -363,9 +363,24 @@ impl<'a> Parser<'a> {
} }
} }
pub(crate) fn parse_whole_number(&mut self) -> String {
let mut buf = String::new();
while let Some(c) = self.toks.peek() {
if !c.kind.is_ascii_digit() {
break;
}
let tok = self.toks.next().unwrap();
buf.push(tok.kind);
}
buf
}
fn parse_number(&mut self, predicate: Predicate<'_>) -> SassResult<Spanned<ParsedNumber>> { fn parse_number(&mut self, predicate: Predicate<'_>) -> SassResult<Spanned<ParsedNumber>> {
let mut span = self.toks.peek().unwrap().pos; let mut span = self.toks.peek().unwrap().pos;
let mut whole = eat_whole_number(self.toks); let mut whole = self.parse_whole_number();
if self.toks.peek().is_none() || predicate(self) { if self.toks.peek().is_none() || predicate(self) {
return Ok(Spanned { return Ok(Spanned {
@ -379,7 +394,7 @@ impl<'a> Parser<'a> {
let dec_len = if next_tok.kind == '.' { let dec_len = if next_tok.kind == '.' {
self.toks.next(); self.toks.next();
let dec = eat_whole_number(self.toks); let dec = self.parse_whole_number();
if dec.is_empty() { if dec.is_empty() {
return Err(("Expected digit.", next_tok.pos()).into()); return Err(("Expected digit.", next_tok.pos()).into());
} }
@ -393,33 +408,42 @@ impl<'a> Parser<'a> {
let mut times_ten = String::new(); let mut times_ten = String::new();
let mut times_ten_is_postive = true; let mut times_ten_is_postive = true;
if let Some(Token { kind: 'e', .. }) | Some(Token { kind: 'E', .. }) = self.toks.peek() { if let Some(Token { kind: 'e', .. }) | Some(Token { kind: 'E', .. }) = self.toks.peek() {
if let Some(tok) = self.toks.peek_next() { if let Some(tok) = self.toks.peek_next() {
if tok.kind == '-' { match tok.kind {
self.toks.next(); '-' => {
times_ten_is_postive = false; self.toks.next();
self.toks.next();
times_ten_is_postive = false;
self.toks.next(); times_ten = self.parse_whole_number();
times_ten = eat_whole_number(self.toks);
if times_ten.is_empty() { if times_ten.is_empty() {
return Err(("Expected digit.", self.toks.peek().unwrap_or(tok).pos).into()); return Err(
} else if times_ten.len() > 2 { ("Expected digit.", self.toks.peek().unwrap_or(tok).pos).into()
return Err(( );
"Exponent too negative.", } else if times_ten.len() > 2 {
self.toks.peek().unwrap_or(tok).pos, return Err((
) "Exponent too negative.",
.into()); self.toks.peek().unwrap_or(tok).pos,
)
.into());
}
} }
} else if matches!(tok.kind, '0'..='9') { '0'..='9' => {
self.toks.next(); self.toks.next();
times_ten = eat_whole_number(self.toks); times_ten = self.parse_whole_number();
if times_ten.len() > 2 { if times_ten.len() > 2 {
return Err( return Err((
("Exponent too large.", self.toks.peek().unwrap_or(tok).pos).into() "Exponent too large.",
); self.toks.peek().unwrap_or(tok).pos,
)
.into());
}
} }
_ => {}
} }
} }
} }

View File

@ -1,5 +1,3 @@
use crate::lexer::Lexer;
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct ParsedNumber { pub(crate) struct ParsedNumber {
/// The full number excluding the decimal /// The full number excluding the decimal
@ -41,15 +39,3 @@ impl ParsedNumber {
} }
} }
} }
pub(crate) fn eat_whole_number(toks: &mut Lexer) -> String {
let mut buf = String::new();
while let Some(c) = toks.peek() {
if !c.kind.is_ascii_digit() {
break;
}
let tok = toks.next().unwrap();
buf.push(tok.kind);
}
buf
}