| Index: src/js/string.js
|
| diff --git a/src/js/string.js b/src/js/string.js
|
| index 5d87ffce9ec9bd937b8eaad62f99f7029d34dfc4..3a9254c7130858b24ea3177a3eb5d818149fa513 100644
|
| --- a/src/js/string.js
|
| +++ b/src/js/string.js
|
| @@ -10,7 +10,6 @@
|
| // Imports
|
|
|
| var ArrayJoin;
|
| -var GetSubstitution;
|
| var GlobalRegExp = global.RegExp;
|
| var GlobalString = global.String;
|
| var MaxSimple;
|
| @@ -22,7 +21,6 @@ var splitSymbol = utils.ImportNow("split_symbol");
|
|
|
| utils.Import(function(from) {
|
| ArrayJoin = from.ArrayJoin;
|
| - GetSubstitution = from.GetSubstitution;
|
| MaxSimple = from.MaxSimple;
|
| MinSimple = from.MinSimple;
|
| });
|
| @@ -60,6 +58,90 @@ 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) {
|
|
|