Skip to content

Commit

Permalink
Merge b36b976 into e49be36
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat authored Jul 16, 2020
2 parents e49be36 + b36b976 commit bfcfa01
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 76 deletions.
45 changes: 23 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 9 additions & 19 deletions boa/src/builtins/number/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,18 +361,8 @@ impl Number {

#[allow(clippy::wrong_self_convention)]
pub(crate) fn to_native_string(x: f64) -> String {
if x == -0. {
return "0".to_owned();
} else if x.is_nan() {
return "NaN".to_owned();
} else if x.is_infinite() && x.is_sign_positive() {
return "Infinity".to_owned();
} else if x.is_infinite() && x.is_sign_negative() {
return "-Infinity".to_owned();
}

// FIXME: This is not spec compliant.
format!("{}", x)
let mut buffer = ryu_js::Buffer::new();
buffer.format(x).to_string()
}

/// `Number.prototype.toString( [radix] )`
Expand Down Expand Up @@ -400,6 +390,13 @@ impl Number {
.throw_range_error("radix must be an integer at least 2 and no greater than 36");
}

// 5. If radixNumber = 10, return ! ToString(x).
// This part should use exponential notations for long integer numbers commented tests
if radix == 10 {
// return Ok(to_value(format!("{}", Self::to_number(this).to_num())));
return Ok(Value::from(Self::to_native_string(x)));
}

if x == -0. {
return Ok(Value::from("0"));
} else if x.is_nan() {
Expand All @@ -410,13 +407,6 @@ impl Number {
return Ok(Value::from("-Infinity"));
}

// 5. If radixNumber = 10, return ! ToString(x).
// This part should use exponential notations for long integer numbers commented tests
if radix == 10 {
// return Ok(to_value(format!("{}", Self::to_number(this).to_num())));
return Ok(Value::from(Self::to_native_string(x)));
}

// This is a Optimization from the v8 source code to print values that can fit in a single character
// Since the actual num_to_string allocates a 2200 bytes buffer for actual conversion
// I am not sure if this part is effective as the v8 equivalent https://chromium.googlesource.com/v8/v8/+/refs/heads/master/src/builtins/number.tq#53
Expand Down
47 changes: 14 additions & 33 deletions boa/src/builtins/number/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,49 +328,30 @@ fn to_string() {
}

#[test]
#[ignore]
// This tests fail for now since the Rust's default formatting for exponential format does not match the js spec.
// https://github.com/jasonwilliams/boa/pull/381#discussion_r422458544
fn num_to_string_exponential() {
let realm = Realm::create();
let mut engine = Interpreter::new(realm);

assert_eq!("0", forward(&mut engine, "(0).toString()"));
assert_eq!("0", forward(&mut engine, "(-0).toString()"));
assert_eq!(
String::from("111111111111111110000"),
forward(&mut engine, "Number(111111111111111111111).toString()")
);
assert_eq!(
String::from("1.1111111111111111e+21"),
forward(&mut engine, "Number(1111111111111111111111).toString()")
);
assert_eq!(
String::from("1.1111111111111111e+22"),
forward(&mut engine, "Number(11111111111111111111111).toString()")
);
assert_eq!(
String::from("1e-7"),
forward(&mut engine, "Number(0.0000001).toString()")
);
assert_eq!(
String::from("1.2e-7"),
forward(&mut engine, "Number(0.00000012).toString()")
);
assert_eq!(
String::from("1.23e-7"),
forward(&mut engine, "Number(0.000000123).toString()")
);
assert_eq!(
String::from("1e-8"),
forward(&mut engine, "Number(0.00000001).toString()")
"111111111111111110000",
forward(&mut engine, "(111111111111111111111).toString()")
);
assert_eq!(
String::from("1.2e-8"),
forward(&mut engine, "Number(0.000000012).toString()")
"1.1111111111111111e+21",
forward(&mut engine, "(1111111111111111111111).toString()")
);
assert_eq!(
String::from("1.23e-8"),
forward(&mut engine, "Number(0.0000000123).toString()")
"1.1111111111111111e+22",
forward(&mut engine, "(11111111111111111111111).toString()")
);
assert_eq!("1e-7", forward(&mut engine, "(0.0000001).toString()"));
assert_eq!("1.2e-7", forward(&mut engine, "(0.00000012).toString()"));
assert_eq!("1.23e-7", forward(&mut engine, "(0.000000123).toString()"));
assert_eq!("1e-8", forward(&mut engine, "(0.00000001).toString()"));
assert_eq!("1.2e-8", forward(&mut engine, "(0.000000012).toString()"));
assert_eq!("1.23e-8", forward(&mut engine, "(0.0000000123).toString()"));
}

#[test]
Expand Down
21 changes: 19 additions & 2 deletions boa/src/builtins/value/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ pub(crate) fn log_string_from(x: &Value, print_internals: bool) -> String {
match v.borrow().data {
ObjectData::String(ref string) => format!("String {{ \"{}\" }}", string),
ObjectData::Boolean(boolean) => format!("Boolean {{ {} }}", boolean),
ObjectData::Number(rational) => {
if rational.is_sign_negative() && rational == 0.0 {
"Number { -0 }".to_string()
} else {
let mut buffer = ryu_js::Buffer::new();
format!("Number {{ {} }}", buffer.format(rational))
}
}
ObjectData::Array => {
let len = i32::from(
&v.borrow()
Expand Down Expand Up @@ -185,7 +193,16 @@ impl Display for Value {
}
}

/// This is different from the ECMAScript compliant number to string, in the printing of `-0`.
///
/// This function prints `-0` as `-0` instead of pasitive `0` as the specification says.
/// This is done to make it easer for the user of the REPL to identify what is a `-0` vs `0`,
/// since the REPL is not bound to the ECMAScript specification we can do this.
fn format_rational(v: f64, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buffer = ryu_js::Buffer::new();
write!(f, "{}", buffer.format(v))
if v.is_sign_negative() && v == 0.0 {
f.write_str("-0")
} else {
let mut buffer = ryu_js::Buffer::new();
write!(f, "{}", buffer.format(v))
}
}

0 comments on commit bfcfa01

Please sign in to comment.