diff options
author | Kesse Jones <kjonesfc@outlook.com> | 2020-04-16 13:15:03 -0300 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-16 18:47:24 +0200 |
commit | b0b204822f817607c9dbebf5790d57de04801d92 (patch) | |
tree | b1a76479473edc1685f540bec86c54596081c5ca /Libraries | |
parent | 60d1ef6af492530d581d1c532e2c1e1f3868d220 (diff) | |
download | serenity-b0b204822f817607c9dbebf5790d57de04801d92.zip |
LibJS: Add String.prototype.substring
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibJS/Runtime/StringPrototype.cpp | 48 | ||||
-rw-r--r-- | Libraries/LibJS/Runtime/StringPrototype.h | 1 | ||||
-rw-r--r-- | Libraries/LibJS/Tests/String.prototype.substring.js | 19 |
3 files changed, 68 insertions, 0 deletions
diff --git a/Libraries/LibJS/Runtime/StringPrototype.cpp b/Libraries/LibJS/Runtime/StringPrototype.cpp index 560cbb3084..c75f9ab1ba 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -56,6 +56,7 @@ StringPrototype::StringPrototype() put_native_function("trimStart", trim_start, 0); put_native_function("trimEnd", trim_end, 0); put_native_function("concat", concat, 1); + put_native_function("substring", substring, 2); } StringPrototype::~StringPrototype() @@ -326,4 +327,51 @@ Value StringPrototype::concat(Interpreter& interpreter) return js_string(interpreter, builder.to_string()); } +Value StringPrototype::substring(Interpreter& interpreter) +{ + auto* this_object = interpreter.this_value().to_object(interpreter.heap()); + if (!this_object) + return {}; + + auto& string = this_object->to_string().as_string()->string(); + + if (interpreter.argument_count() == 0) + return js_string(interpreter, string); + + i32 string_length = static_cast<i32>(string.length()); + i32 index_start = interpreter.argument(0).to_number().to_i32(); + i32 index_end = string_length; + + if (index_start > string_length) + index_start = string_length; + else if (index_start < 0) + index_start = 0; + + if (interpreter.argument_count() >= 2) { + index_end = interpreter.argument(1).to_number().to_i32(); + + if (index_end > string_length) + index_end = string_length; + else if (index_end < 0) + index_end = 0; + } + + if (index_start == index_end) + return js_string(interpreter, String("")); + + if (index_start > index_end) { + if (interpreter.argument_count() == 1) { + return js_string(interpreter, String("")); + } else { + i32 temp_index_start = index_start; + index_start = index_end; + index_end = temp_index_start; + } + } + + auto part_length = index_end - index_start; + auto string_part = string.substring(index_start, part_length); + return js_string(interpreter, string_part); +} + } diff --git a/Libraries/LibJS/Runtime/StringPrototype.h b/Libraries/LibJS/Runtime/StringPrototype.h index 76f5a0c70c..2f2eb9a872 100644 --- a/Libraries/LibJS/Runtime/StringPrototype.h +++ b/Libraries/LibJS/Runtime/StringPrototype.h @@ -47,6 +47,7 @@ private: static Value to_string(Interpreter&); static Value pad_start(Interpreter&); static Value pad_end(Interpreter&); + static Value substring(Interpreter&); static Value length_getter(Interpreter&); diff --git a/Libraries/LibJS/Tests/String.prototype.substring.js b/Libraries/LibJS/Tests/String.prototype.substring.js new file mode 100644 index 0000000000..134906a3b0 --- /dev/null +++ b/Libraries/LibJS/Tests/String.prototype.substring.js @@ -0,0 +1,19 @@ +load("test-common.js"); + +try { + assert(String.prototype.substring.length === 2); + assert("hello friends".substring() === "hello friends"); + assert("hello friends".substring(1) === "ello friends"); + assert("hello friends".substring(0, 5) === "hello"); + assert("hello friends".substring(13, 6) === "friends"); + assert("hello friends".substring('', 5) === "hello"); + assert("hello friends".substring(3, 3) === ""); + assert("hello friends".substring(-1, 13) === "hello friends"); + assert("hello friends".substring(0, 50) === "hello friends"); + assert("hello friends".substring(0, "5") === "hello"); + assert("hello friends".substring("6", "13") === "friends"); + + console.log("PASS"); +} catch (err) { + console.log("FAIL: " + err); +} |