Index: src/js/string.js |
diff --git a/src/js/string.js b/src/js/string.js |
index c0587350cd6d4730183398c094c1db517c3c5e3e..1da5c5f766b979353a5e053518f31f41cf7fe635 100644 |
--- a/src/js/string.js |
+++ b/src/js/string.js |
@@ -9,21 +9,9 @@ |
// ------------------------------------------------------------------- |
// Imports |
-var ArrayJoin; |
-var GlobalRegExp = global.RegExp; |
var GlobalString = global.String; |
-var MaxSimple; |
-var MinSimple; |
var matchSymbol = utils.ImportNow("match_symbol"); |
-var replaceSymbol = utils.ImportNow("replace_symbol"); |
var searchSymbol = utils.ImportNow("search_symbol"); |
-var splitSymbol = utils.ImportNow("split_symbol"); |
- |
-utils.Import(function(from) { |
- ArrayJoin = from.ArrayJoin; |
- MaxSimple = from.MaxSimple; |
- MinSimple = from.MinSimple; |
-}); |
//------------------------------------------------------------------- |
@@ -58,154 +46,6 @@ function StringMatchJS(pattern) { |
return regexp[matchSymbol](subject); |
} |
-// ES#sec-getsubstitution |
-// GetSubstitution(matched, str, position, captures, replacement) |
-// Expand the $-expressions in the string and return a new string with |
-// the result. |
-function GetSubstitution(matched, string, position, captures, replacement) { |
- var matchLength = matched.length; |
- var stringLength = string.length; |
- var capturesLength = captures.length; |
- var tailPos = position + matchLength; |
- var result = ""; |
- var pos, expansion, peek, next, scaledIndex, advance, newScaledIndex; |
- |
- var next = %StringIndexOf(replacement, '$', 0); |
- if (next < 0) { |
- result += replacement; |
- return result; |
- } |
- |
- if (next > 0) result += %_SubString(replacement, 0, next); |
- |
- while (true) { |
- expansion = '$'; |
- pos = next + 1; |
- if (pos < replacement.length) { |
- peek = %_StringCharCodeAt(replacement, pos); |
- if (peek == 36) { // $$ |
- ++pos; |
- result += '$'; |
- } else if (peek == 38) { // $& - match |
- ++pos; |
- result += matched; |
- } else if (peek == 96) { // $` - prefix |
- ++pos; |
- result += %_SubString(string, 0, position); |
- } else if (peek == 39) { // $' - suffix |
- ++pos; |
- result += %_SubString(string, tailPos, stringLength); |
- } else if (peek >= 48 && peek <= 57) { |
- // Valid indices are $1 .. $9, $01 .. $09 and $10 .. $99 |
- scaledIndex = (peek - 48); |
- advance = 1; |
- if (pos + 1 < replacement.length) { |
- next = %_StringCharCodeAt(replacement, pos + 1); |
- if (next >= 48 && next <= 57) { |
- newScaledIndex = scaledIndex * 10 + ((next - 48)); |
- if (newScaledIndex < capturesLength) { |
- scaledIndex = newScaledIndex; |
- advance = 2; |
- } |
- } |
- } |
- if (scaledIndex != 0 && scaledIndex < capturesLength) { |
- var capture = captures.at(scaledIndex); |
- if (!IS_UNDEFINED(capture)) result += capture; |
- pos += advance; |
- } else { |
- result += '$'; |
- } |
- } else { |
- result += '$'; |
- } |
- } else { |
- result += '$'; |
- } |
- |
- // Go the the next $ in the replacement. |
- next = %StringIndexOf(replacement, '$', pos); |
- |
- // Return if there are no more $ characters in the replacement. If we |
- // haven't reached the end, we need to append the suffix. |
- if (next < 0) { |
- if (pos < replacement.length) { |
- result += %_SubString(replacement, pos, replacement.length); |
- } |
- return result; |
- } |
- |
- // Append substring between the previous and the next $ character. |
- if (next > pos) { |
- result += %_SubString(replacement, pos, next); |
- } |
- } |
- return result; |
-} |
- |
-// ES6, section 21.1.3.14 |
-function StringReplace(search, replace) { |
- CHECK_OBJECT_COERCIBLE(this, "String.prototype.replace"); |
- |
- // Decision tree for dispatch |
- // .. regexp search (in src/js/regexp.js, RegExpReplace) |
- // .... string replace |
- // ...... non-global search |
- // ........ empty string replace |
- // ........ non-empty string replace (with $-expansion) |
- // ...... global search |
- // ........ no need to circumvent last match info override |
- // ........ need to circument last match info override |
- // .... function replace |
- // ...... global search |
- // ...... non-global search |
- // .. string search |
- // .... special case that replaces with one single character |
- // ...... function replace |
- // ...... string replace (with $-expansion) |
- |
- if (!IS_NULL_OR_UNDEFINED(search)) { |
- var replacer = search[replaceSymbol]; |
- if (!IS_UNDEFINED(replacer)) { |
- return %_Call(replacer, search, this, replace); |
- } |
- } |
- |
- var subject = TO_STRING(this); |
- |
- search = TO_STRING(search); |
- |
- if (search.length == 1 && |
- subject.length > 0xFF && |
- IS_STRING(replace) && |
- %StringIndexOf(replace, '$', 0) < 0) { |
- // Searching by traversing a cons string tree and replace with cons of |
- // slices works only when the replaced string is a single character, being |
- // replaced by a simple string and only pays off for long strings. |
- return %StringReplaceOneCharWithString(subject, search, replace); |
- } |
- var start = %StringIndexOf(subject, search, 0); |
- if (start < 0) return subject; |
- var end = start + search.length; |
- |
- var result = %_SubString(subject, 0, start); |
- |
- // Compute the string to replace with. |
- if (IS_CALLABLE(replace)) { |
- result += replace(search, start, subject); |
- } else { |
- // In this case, we don't have any capture groups and can get away with |
- // faking the captures object by simply setting its length to 1. |
- const captures = { length: 1 }; |
- const matched = %_SubString(subject, start, end); |
- result += GetSubstitution(matched, subject, start, captures, |
- TO_STRING(replace)); |
- } |
- |
- return result + %_SubString(subject, end, subject.length); |
-} |
- |
- |
// ES6 21.1.3.15. |
function StringSearch(pattern) { |
CHECK_OBJECT_COERCIBLE(this, "String.prototype.search"); |
@@ -266,39 +106,6 @@ function StringSlice(start, end) { |
return %_SubString(s, start_i, end_i); |
} |
- |
-// ES6 21.1.3.17. |
-function StringSplitJS(separator, limit) { |
- CHECK_OBJECT_COERCIBLE(this, "String.prototype.split"); |
- |
- if (!IS_NULL_OR_UNDEFINED(separator)) { |
- var splitter = separator[splitSymbol]; |
- if (!IS_UNDEFINED(splitter)) { |
- return %_Call(splitter, separator, this, limit); |
- } |
- } |
- |
- var subject = TO_STRING(this); |
- limit = (IS_UNDEFINED(limit)) ? kMaxUint32 : TO_UINT32(limit); |
- |
- var length = subject.length; |
- var separator_string = TO_STRING(separator); |
- |
- if (limit === 0) return []; |
- |
- // ECMA-262 says that if separator is undefined, the result should |
- // be an array of size 1 containing the entire string. |
- if (IS_UNDEFINED(separator)) return [subject]; |
- |
- var separator_length = separator_string.length; |
- |
- // If the separator string is empty then return the elements in the subject. |
- if (separator_length === 0) return %StringToArray(subject, limit); |
- |
- return %StringSplit(subject, separator_string, limit); |
-} |
- |
- |
// ECMA-262, 15.5.4.16 |
function StringToLowerCaseJS() { |
CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase"); |
@@ -515,10 +322,8 @@ utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [ |
"concat", StringConcat, |
"match", StringMatchJS, |
"repeat", StringRepeat, |
- "replace", StringReplace, |
"search", StringSearch, |
"slice", StringSlice, |
- "split", StringSplitJS, |
"toLowerCase", StringToLowerCaseJS, |
"toLocaleLowerCase", StringToLocaleLowerCase, |
"toUpperCase", StringToUpperCaseJS, |
@@ -539,14 +344,4 @@ utils.InstallFunctions(GlobalString.prototype, DONT_ENUM, [ |
"sup", StringSup |
]); |
-// ------------------------------------------------------------------- |
-// Exports |
- |
-utils.Export(function(to) { |
- to.StringMatch = StringMatchJS; |
- to.StringReplace = StringReplace; |
- to.StringSlice = StringSlice; |
- to.StringSplit = StringSplitJS; |
-}); |
- |
}) |