Don't support charAt, charCodeAt

This commit is contained in:
Andrew Morris
2023-03-13 13:35:07 +11:00
parent d33d93bd34
commit fe730a613a
3 changed files with 15 additions and 92 deletions

View File

@@ -1,18 +0,0 @@
// test_output! [["","f","o","o",""],["f","f","o"]]
export default function () {
return [
[
"foo".charAt(-1),
"foo".charAt(0),
"foo".charAt(1),
"foo".charAt(2),
"foo".charAt(3),
],
[
"foo".charAt(0 / 0), // (0/0 is NaN, keyword not implemented yet)
"foo".charAt(-0.9),
"foo".charAt([1] as any),
],
];
}

View File

@@ -1,18 +0,0 @@
// test_output! [[NaN,102,111,111,NaN],[102,102,111]]
export default function () {
return [
[
"foo".charCodeAt(-1),
"foo".charCodeAt(0),
"foo".charCodeAt(1),
"foo".charCodeAt(2),
"foo".charCodeAt(3),
],
[
"foo".charCodeAt(0 / 0), // (0/0 is NaN, keyword not implemented yet)
"foo".charCodeAt(-0.9),
"foo".charCodeAt([1] as any),
],
];
}

View File

@@ -31,8 +31,21 @@ pub fn op_sub_string(string_data: &Rc<String>, subscript: &Val) -> Val {
pub fn get_string_method(method: &str) -> Val {
match method {
"at" => Val::Static(&AT),
"charAt" => Val::Static(&CHAR_AT),
"charCodeAt" => Val::Static(&CHAR_CODE_AT),
//
// Not supported: charAt, charCodeAt.
//
// These methods are inherently about utf16, which is not how strings work in ValueScript. They
// also have some particularly strange behavior, like:
//
// "foo".charAt(NaN) // "f"
//
// Usually we include JavaScript behavior as much as possible, but since strings are utf8,
// there's more license to reinterpret strings and leave out things like this which aren't
// desirable.
//
// "charAt" => Val::Static(&CHAR_AT),
// "charCodeAt" => Val::Static(&CHAR_CODE_AT),
//
"codePointAt" => Val::Static(&CODE_POINT_AT),
_ => Val::Undefined,
}
@@ -59,33 +72,6 @@ static AT: NativeFunction = NativeFunction {
},
};
static CHAR_AT: NativeFunction = NativeFunction {
fn_: |this: &mut Val, params: Vec<Val>| -> Val {
match this {
Val::String(string_data) => match byte_at(string_data, params.get(0)) {
Some(byte) => match std::char::from_u32(byte as u32) {
Some(c) => Val::String(Rc::new(c.to_string())),
None => Val::String(Rc::new(String::from(""))),
},
None => Val::String(Rc::new(String::from(""))),
},
_ => std::panic!("Not implemented: exceptions/string indirection"),
}
},
};
static CHAR_CODE_AT: NativeFunction = NativeFunction {
fn_: |this: &mut Val, params: Vec<Val>| -> Val {
match this {
Val::String(string_data) => match byte_at(string_data, params.get(0)) {
Some(byte) => Val::Number(byte as f64),
None => Val::Number(std::f64::NAN),
},
_ => std::panic!("Not implemented: exceptions/string indirection"),
}
},
};
static CODE_POINT_AT: NativeFunction = NativeFunction {
fn_: |this: &mut Val, params: Vec<Val>| -> Val {
match this {
@@ -152,30 +138,3 @@ fn code_point_at(bytes: &[u8], index: usize) -> Option<u32> {
Some(value)
}
fn byte_at(string: &String, index_param: Option<&Val>) -> Option<u8> {
let mut index = match index_param {
Some(i) => i.to_number(),
_ => 0 as f64,
};
if index.is_nan() {
index = 0 as f64;
}
index = index.trunc();
if index < 0_f64 {
return None;
}
let index_usize = index as usize;
let string_bytes = string.as_bytes();
if index_usize >= string_bytes.len() {
return None;
}
Some(string_bytes[index_usize])
}