From 11e77f36bda5483ef123fe9d62555d2d432e69ca Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Mon, 13 Mar 2023 14:02:35 +1100 Subject: [PATCH] endsWith --- inputs/passing/stringMethods/endsWith.ts | 16 +++++++++ valuescript_vm/src/string_methods.rs | 43 ++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 inputs/passing/stringMethods/endsWith.ts diff --git a/inputs/passing/stringMethods/endsWith.ts b/inputs/passing/stringMethods/endsWith.ts new file mode 100644 index 0000000..56111ac --- /dev/null +++ b/inputs/passing/stringMethods/endsWith.ts @@ -0,0 +1,16 @@ +// test_output! [true,false,true,true,true,true,false,true,true,false] + +export default function () { + return [ + "hello".endsWith("lo"), + "hello".endsWith("l"), + "hello".endsWith("o"), + "hello".endsWith(""), + "hello".endsWith("hello"), + "Cats are the best!".endsWith("best!"), + "Cats are the best!".endsWith("best"), + "Cats are the best!".endsWith("best", 17), + "Is this a question?".endsWith("?"), + "Is this a question?".endsWith("question"), + ]; +} diff --git a/valuescript_vm/src/string_methods.rs b/valuescript_vm/src/string_methods.rs index ec545cb..81d19ec 100644 --- a/valuescript_vm/src/string_methods.rs +++ b/valuescript_vm/src/string_methods.rs @@ -48,6 +48,7 @@ pub fn get_string_method(method: &str) -> Val { // "codePointAt" => Val::Static(&CODE_POINT_AT), "concat" => Val::Static(&CONCAT), + "endsWith" => Val::Static(&ENDS_WITH), _ => Val::Undefined, } } @@ -114,6 +115,48 @@ static CONCAT: NativeFunction = NativeFunction { }, }; +static ENDS_WITH: 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 end_pos = match params.get(1) { + Some(p) => match p.to_index() { + None => return Val::Bool(false), + Some(i) => std::cmp::min(i, string_bytes.len()), + }, + _ => string_bytes.len(), + }; + + let search_bytes = search_string.as_bytes(); + + let search_length = search_bytes.len(); + + if search_length > end_pos { + return Val::Bool(false); + } + + let start_index = end_pos - search_length; + + for i in 0..search_length { + if string_bytes[start_index + i] != search_bytes[i] { + return Val::Bool(false); + } + } + + Val::Bool(true) + } + _ => 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(