Skip to content

Commit

Permalink
add Number.isInteger and support \uNNNN syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Jul 30, 2024
1 parent 66a5d77 commit f3fe12b
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 4 deletions.
15 changes: 15 additions & 0 deletions crates/dash_lexer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,21 @@ impl<'a, 'interner> Lexer<'a, 'interner> {
}
};
}
b'u' => {
self.advance();
let Some(hex) = self.input.get(self.idx..self.idx + 4) else {
self.create_error(Error::UnexpectedEof);
return;
};

let Some(escaped) = u32::from_str_radix(hex, 16).ok().and_then(char::from_u32) else {
self.create_error(Error::InvalidEscapeSequence(self.span()));
return;
};

lexeme.as_mut().unwrap().to_mut().push(escaped);
self.advance_n(4);
}
other if !other.is_ascii() => {
// if the escaped character is non-ascii, decode UTF-8
let (c, len) = util::next_char_in_bytes(&self.input.as_bytes()[self.idx..]);
Expand Down
1 change: 1 addition & 0 deletions crates/dash_middle/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ pub mod sym {
isNaN,
eval,
isSafeInteger,
isInteger,
EPSILON,
MAX_SAFE_INTEGER,
MAX_VALUE,
Expand Down
19 changes: 16 additions & 3 deletions crates/dash_vm/src/js_std/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::throw;
use crate::util::intern_f64;
use crate::value::function::native::CallContext;
use crate::value::ops::conversions::ValueConversion;
use crate::value::primitive::{Number, MAX_SAFE_INTEGERF, MIN_SAFE_INTEGERF};
use crate::value::primitive::{Number, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER};
use crate::value::{boxed, Value, ValueContext};

pub fn constructor(cx: CallContext) -> Result<Value, Value> {
Expand Down Expand Up @@ -57,13 +57,26 @@ pub fn is_nan(cx: CallContext) -> Result<Value, Value> {
Ok(Value::Boolean(num.is_nan()))
}

fn as_integer(f: f64) -> Option<i64> {
(f.trunc() == f && f.is_finite()).then(|| f as i64)
}

pub fn is_safe_integer(cx: CallContext) -> Result<Value, Value> {
let num = match cx.args.first() {
Some(Value::Number(Number(n))) => n,
Some(&Value::Number(Number(n))) => n,
_ => return Ok(Value::Boolean(false)),
};
let is_safe = as_integer(num).is_some_and(|n| (MIN_SAFE_INTEGER..=MAX_SAFE_INTEGER).contains(&n));

Ok(Value::Boolean(is_safe))
}

Ok(Value::Boolean(*num <= MAX_SAFE_INTEGERF && *num >= MIN_SAFE_INTEGERF))
pub fn is_integer(cx: CallContext) -> Result<Value, Value> {
let num = match cx.args.first() {
Some(&Value::Number(Number(n))) => n,
_ => return Ok(Value::Boolean(false)),
};
Ok(Value::Boolean(as_integer(num).is_some()))
}

pub fn to_fixed(cx: CallContext) -> Result<Value, Value> {
Expand Down
1 change: 1 addition & 0 deletions crates/dash_vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ impl Vm {
(sym::isFinite, scope.statics.number_is_finite.clone()),
(sym::isNaN, scope.statics.number_is_nan.clone()),
(sym::isSafeInteger, scope.statics.number_is_safe_integer.clone()),
(sym::isInteger, scope.statics.number_is_integer.clone()),
],
[],
[
Expand Down
2 changes: 2 additions & 0 deletions crates/dash_vm/src/statics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ pub struct Statics {
pub number_is_finite: Handle,
pub number_is_nan: Handle,
pub number_is_safe_integer: Handle,
pub number_is_integer: Handle,
pub number_to_fixed: Handle,
pub boolean_ctor: Handle,
pub boolean_tostring: Handle,
Expand Down Expand Up @@ -353,6 +354,7 @@ impl Statics {
number_is_finite: function(gc, sym::isFinite, js_std::number::is_finite),
number_is_nan: function(gc, sym::isNaN, js_std::number::is_nan),
number_is_safe_integer: function(gc, sym::isSafeInteger, js_std::number::is_safe_integer),
number_is_integer: function(gc, sym::isInteger, js_std::number::is_integer),
number_to_fixed: function(gc, sym::toFixed, js_std::number::to_fixed),
boolean_valueof: function(gc, sym::valueOf, js_std::boolean::value_of),
string_tostring: function(gc, sym::toString, js_std::string::to_string),
Expand Down
3 changes: 2 additions & 1 deletion crates/dash_vm/src/value/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ use super::ops::conversions::{PreferredType, ValueConversion};
use super::string::JsString;
use super::{Typeof, Unrooted, Value};

pub const MAX_SAFE_INTEGER: u64 = 9007199254740991u64;
pub const MIN_SAFE_INTEGER: i64 = -9007199254740991i64;
pub const MAX_SAFE_INTEGER: i64 = 9007199254740991i64;
pub const MAX_SAFE_INTEGERF: f64 = 9007199254740991f64;
pub const MIN_SAFE_INTEGERF: f64 = -9007199254740991f64;

Expand Down

0 comments on commit f3fe12b

Please sign in to comment.