From c3c49f43ee0cfd47694dff937be421532af935ee Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Mon, 13 Mar 2023 20:13:37 +1100 Subject: [PATCH] includes --- inputs/passing/stringMethods/includes.ts | 21 +++++++++ valuescript_vm/src/string_methods.rs | 56 ++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 inputs/passing/stringMethods/includes.ts diff --git a/inputs/passing/stringMethods/includes.ts b/inputs/passing/stringMethods/includes.ts new file mode 100644 index 0000000..7e842ea --- /dev/null +++ b/inputs/passing/stringMethods/includes.ts @@ -0,0 +1,21 @@ +// test_output! [[true,true,true,true,true,true],[false,false,false,false]] + +export default function () { + const positive = [ + "foobar".includes("foo"), + "foobar".includes("bar"), + "foobar".includes("oob"), + "foobar".includes(""), + "foobar".includes("foobar"), + "foobar".includes("bar", 1), + ]; + + const negative = [ + "foobar".includes("baz"), + "foobar".includes("qux"), + "foobar".includes("oob", 4), + "foobar".includes("foo", 1), + ]; + + return [positive, negative]; +} diff --git a/valuescript_vm/src/string_methods.rs b/valuescript_vm/src/string_methods.rs index c244940..7a5769d 100644 --- a/valuescript_vm/src/string_methods.rs +++ b/valuescript_vm/src/string_methods.rs @@ -47,6 +47,7 @@ pub fn get_string_method(method: &str) -> Val { "codePointAt" => Val::Static(&CODE_POINT_AT), "concat" => Val::Static(&CONCAT), "endsWith" => Val::Static(&ENDS_WITH), + "includes" => Val::Static(&INCLUDES), _ => Val::Undefined, } } @@ -156,6 +157,61 @@ static ENDS_WITH: NativeFunction = NativeFunction { }, }; +static INCLUDES: NativeFunction = NativeFunction { + fn_: |this: &mut Val, params: Vec| -> Val { + match this { + Val::String(string_data) => { + let string_bytes = string_data.as_bytes(); + + let search_string = match params.get(0) { + Some(s) => s.val_to_string(), + _ => return Val::Bool(false), + }; + + let start_pos = match params.get(1) { + Some(p) => match p.to_index() { + // FIXME: to_index isn't quite right here + None => return Val::Bool(false), + Some(i) => i, + }, + _ => 0, + }; + + let search_bytes = search_string.as_bytes(); + + let search_length = search_bytes.len(); + + if search_length == 0 { + // TODO: Even if start_pos is out of bounds? + return Val::Bool(true); + } + + if start_pos + search_length > string_bytes.len() { + return Val::Bool(false); + } + + for i in start_pos..(string_bytes.len() - search_length + 1) { + let mut found = true; + + for j in 0..search_length { + if string_bytes[i + j] != search_bytes[j] { + found = false; + break; + } + } + + if found { + return Val::Bool(true); + } + } + + Val::Bool(false) + } + _ => std::panic!("Not implemented: exceptions/string indirection"), + } + }, +}; + fn unicode_at(bytes: &[u8], index: usize) -> Option { match code_point_at(bytes, index) { Some(code_point) => Some(