core: implement isNaN and Number functions. Involves updating to_number function in Value. Note: this varies a little from the ECMA spec such as not allowing spaces in numbers (i.e. ' 5' => NaN). No definitive reference for this but was found experimentally. Same with not supporting 'Infinity'
This commit is contained in:
parent
38c66b5b8d
commit
463d0fc352
|
@ -63,9 +63,36 @@ pub fn boolean<'gc>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn number<'gc>(
|
||||||
|
_avm: &mut Avm1<'gc>,
|
||||||
|
_action_context: &mut ActionContext<'_, 'gc, '_>,
|
||||||
|
_this: GcCell<'gc, Object<'gc>>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Value<'gc> {
|
||||||
|
if let Some(val) = args.get(0) {
|
||||||
|
Value::Number(val.as_number())
|
||||||
|
} else {
|
||||||
|
Value::Number(0.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_nan<'gc>(
|
||||||
|
_avm: &mut Avm1<'gc>,
|
||||||
|
_action_context: &mut ActionContext<'_, 'gc, '_>,
|
||||||
|
_this: GcCell<'gc, Object<'gc>>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Value<'gc> {
|
||||||
|
if let Some(val) = args.get(0) {
|
||||||
|
Value::Bool(val.as_number().is_nan())
|
||||||
|
} else {
|
||||||
|
Value::Bool(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_globals<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<'gc> {
|
pub fn create_globals<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<'gc> {
|
||||||
let mut globals = Object::object(gc_context);
|
let mut globals = Object::object(gc_context);
|
||||||
|
|
||||||
|
globals.force_set_function("isNaN", is_nan, gc_context, EnumSet::empty());
|
||||||
globals.force_set_function("Boolean", boolean, gc_context, EnumSet::empty());
|
globals.force_set_function("Boolean", boolean, gc_context, EnumSet::empty());
|
||||||
globals.force_set(
|
globals.force_set(
|
||||||
"Math",
|
"Math",
|
||||||
|
@ -73,7 +100,9 @@ pub fn create_globals<'gc>(gc_context: MutationContext<'gc, '_>) -> Object<'gc>
|
||||||
EnumSet::empty(),
|
EnumSet::empty(),
|
||||||
);
|
);
|
||||||
globals.force_set_function("getURL", getURL, gc_context, EnumSet::empty());
|
globals.force_set_function("getURL", getURL, gc_context, EnumSet::empty());
|
||||||
|
globals.force_set_function("Number", number, gc_context, EnumSet::empty());
|
||||||
globals.force_set_function("random", random, gc_context, EnumSet::empty());
|
globals.force_set_function("random", random, gc_context, EnumSet::empty());
|
||||||
|
|
||||||
globals.force_set("NaN", Value::Number(std::f64::NAN), EnumSet::empty());
|
globals.force_set("NaN", Value::Number(std::f64::NAN), EnumSet::empty());
|
||||||
globals.force_set(
|
globals.force_set(
|
||||||
"Infinity",
|
"Infinity",
|
||||||
|
@ -178,4 +207,48 @@ mod tests {
|
||||||
&[] => Value::Bool(false)
|
&[] => Value::Bool(false)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test_std!(is_nan_function, is_nan, 19,
|
||||||
|
&[Value::Bool(true)] => Value::Bool(false),
|
||||||
|
&[Value::Bool(false)] => Value::Bool(false),
|
||||||
|
&[Value::Number(10.0)] => Value::Bool(false),
|
||||||
|
&[Value::Number(-10.0)] => Value::Bool(false),
|
||||||
|
&[Value::Number(0.0)] => Value::Bool(false),
|
||||||
|
&[Value::Number(std::f64::INFINITY)] => Value::Bool(false),
|
||||||
|
&[Value::Number(std::f64::NAN)] => Value::Bool(true),
|
||||||
|
&[Value::String("".to_string())] => Value::Bool(false),
|
||||||
|
&[Value::String("Hello".to_string())] => Value::Bool(true),
|
||||||
|
&[Value::String(" ".to_string())] => Value::Bool(true),
|
||||||
|
&[Value::String(" 5 ".to_string())] => Value::Bool(true),
|
||||||
|
&[Value::String("0".to_string())] => Value::Bool(false),
|
||||||
|
&[Value::String("1".to_string())] => Value::Bool(false),
|
||||||
|
&[Value::String("Infinity".to_string())] => Value::Bool(true),
|
||||||
|
&[Value::String("100a".to_string())] => Value::Bool(true),
|
||||||
|
&[Value::String("0x10".to_string())] => Value::Bool(false),
|
||||||
|
&[Value::String("0xhello".to_string())] => Value::Bool(true),
|
||||||
|
&[Value::String("123e-1".to_string())] => Value::Bool(false),
|
||||||
|
&[] => Value::Bool(true)
|
||||||
|
);
|
||||||
|
|
||||||
|
test_std!(number_function, number, 19,
|
||||||
|
&[Value::Bool(true)] => Value::Number(1.0),
|
||||||
|
&[Value::Bool(false)] => Value::Number(0.0),
|
||||||
|
&[Value::Number(10.0)] => Value::Number(10.0),
|
||||||
|
&[Value::Number(-10.0)] => Value::Number(-10.0),
|
||||||
|
&[Value::Number(0.0)] => Value::Number(0.0),
|
||||||
|
&[Value::Number(std::f64::INFINITY)] => Value::Number(std::f64::INFINITY),
|
||||||
|
&[Value::Number(std::f64::NAN)] => Value::Number(std::f64::NAN),
|
||||||
|
&[Value::String("".to_string())] => Value::Number(0.0),
|
||||||
|
&[Value::String("Hello".to_string())] => Value::Number(std::f64::NAN),
|
||||||
|
&[Value::String(" ".to_string())] => Value::Number(std::f64::NAN),
|
||||||
|
&[Value::String(" 5 ".to_string())] => Value::Number(std::f64::NAN),
|
||||||
|
&[Value::String("0".to_string())] => Value::Number(0.0),
|
||||||
|
&[Value::String("1".to_string())] => Value::Number(1.0),
|
||||||
|
&[Value::String("Infinity".to_string())] => Value::Number(std::f64::NAN),
|
||||||
|
&[Value::String("100a".to_string())] => Value::Number(std::f64::NAN),
|
||||||
|
&[Value::String("0x10".to_string())] => Value::Number(16.0),
|
||||||
|
&[Value::String("0xhello".to_string())] => Value::Number(std::f64::NAN),
|
||||||
|
&[Value::String("123e-1".to_string())] => Value::Number(12.3),
|
||||||
|
&[] => Value::Number(0.0)
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,18 @@ impl<'gc> Value<'gc> {
|
||||||
Value::Bool(false) => 0.0,
|
Value::Bool(false) => 0.0,
|
||||||
Value::Bool(true) => 1.0,
|
Value::Bool(true) => 1.0,
|
||||||
Value::Number(v) => *v,
|
Value::Number(v) => *v,
|
||||||
Value::String(v) => v.parse().unwrap_or(NAN), // TODO(Herschel): Handle Infinity/etc.?
|
Value::String(v) => match v.as_str() {
|
||||||
|
v if v.starts_with("0x") => {
|
||||||
|
let parsed = i64::from_str_radix(&v[2..], 16);
|
||||||
|
if parsed.is_ok() {
|
||||||
|
parsed.unwrap_or_default() as f64
|
||||||
|
} else {
|
||||||
|
std::f64::NAN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"" => 0.0,
|
||||||
|
_ => v.parse().unwrap_or(NAN),
|
||||||
|
},
|
||||||
Value::Object(_object) => {
|
Value::Object(_object) => {
|
||||||
log::error!("Unimplemented: Object ToNumber");
|
log::error!("Unimplemented: Object ToNumber");
|
||||||
0.0
|
0.0
|
||||||
|
|
Loading…
Reference in New Issue