Skip to content

Commit

Permalink
Fix: account for legacy octal literals and add tests for number parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
RDambrosio016 committed Sep 26, 2020
1 parent 82cd3c1 commit 6e54c82
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions rslint_parser/src/numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ pub(crate) fn parse_js_num(num: String) -> Option<JsNum> {
_ => (10, num.as_str())
};

if radix == 10 && raw.starts_with("0") {
// account for legacy octal literals
if let Some(parsed) = parse_radix(raw.as_bytes(), 8).ok() {
return Some(JsNum::Float(parsed));
}
}

let bigint = if raw.get(raw.len() - 1..raw.len()) == Some("n") {
raw = raw.split_at(raw.len() - 1).0;
true
Expand All @@ -32,3 +39,94 @@ pub(crate) fn parse_js_num(num: String) -> Option<JsNum> {
Some(JsNum::Float(parse_radix::<f64, _>(raw.as_bytes(), radix as u8).ok()?))
}
}

#[cfg(test)]
mod tests {
use crate::{parse_expr, ast::{Expr, LiteralKind}};
use num_bigint::ToBigInt;

macro_rules! assert_float {
($literal:literal, $value:expr) => {
let parsed = parse_expr($literal, 0);
if let Expr::Literal(literal) = parsed.tree() {
assert_eq!(literal.into_number(), Some($value));
} else {
panic!("Parsed expression is not a literal");
}
};
}

macro_rules! assert_bigint {
($literal:literal, $value:expr) => {
let parsed = parse_expr($literal, 0);
if let Expr::Literal(literal) = parsed.tree() {
let val = ($value as u64).to_bigint().unwrap();
assert_eq!(literal.kind(), LiteralKind::BigInt(val));
} else {
panic!("Parsed expression is not a literal");
}
};
}

#[test]
fn base_10_float() {
assert_float!("1234", 1234.0);
assert_float!("0", 0.0);
assert_float!("9e999", f64::INFINITY);
assert_float!("9e-999", 0.0);
}

#[test]
fn base_16_float() {
assert_float!("0xFF", 255.0);
assert_float!("0XFF", 255.0);
assert_float!("0x0", 0.0);
assert_float!("0xABC", 2748.0);
assert_float!("0XABC", 2748.0);
}

#[test]
fn base_2_float() {
assert_float!("0b0000", 0.0);
assert_float!("0B0000", 0.0);
assert_float!("0b11111111", 255.0);
assert_float!("0B11111111", 255.0);
}

#[test]
fn base_8_float() {
assert_float!("0o77", 63.0);
assert_float!("0O77", 63.0);
assert_float!("0o0", 0.0);
assert_float!("0O0", 0.0);
}

#[test]
fn base_8_legacy_float() {
assert_float!("051", 41.0);
assert_float!("058", 58.0);
}

#[test]
fn base_10_bigint() {
assert_bigint!("1010n", 1010);
assert_bigint!("0n", 0);
assert_bigint!("9007199254740991n", 9007199254740991);
}

#[test]
fn base_16_bigint() {
assert_bigint!("0xffn", 255);
assert_bigint!("0XFFn", 255);
assert_bigint!("0x1fffffffffffffn", 9007199254740991);
assert_bigint!("0X1fffffffffffffn", 9007199254740991);
}

#[test]
fn base_2_bigint() {
assert_bigint!("0b0n", 0);
assert_bigint!("0B0n", 0);
assert_bigint!("0b11111111111111111111111111111111111111111111111111111n", 9007199254740991);
assert_bigint!("0B11111111111111111111111111111111111111111111111111111n", 9007199254740991);
}
}

0 comments on commit 6e54c82

Please sign in to comment.