Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normative: Update GetSubstitution to match reality #1732

Closed
87 changes: 50 additions & 37 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -29817,12 +29817,25 @@ <h1>Runtime Semantics: GetSubstitution ( _matched_, _str_, _position_, _captures
1. Assert: _position_ &le; _stringLength_.
1. Assert: _captures_ is a possibly empty List of Strings.
1. Assert: Type(_replacement_) is String.
1. Let _replacementLength_ be the number of code units in _replacement_.
1. Let _tailPos_ be _position_ + _matchLength_.
1. Let _m_ be the number of elements in _captures_.
1. Let _result_ be the String value derived from _replacement_ by copying code unit elements from _replacement_ to _result_ while performing replacements as specified in <emu-xref href="#table-45"></emu-xref>. These `$` replacements are done left-to-right, and, once such a replacement is performed, the new replacement text is not subject to further replacements.
1. Let _result_ be the empty String.
1. Let _k_ be 0.
1. Repeat, while _k_ &lt; _replacementLength_
1. Let _replaceablePattern_ be the longest sequence of consecutive code units from _replacement_ beginning with the code unit at index _k_ such that _replaceablePattern_ matches the &ldquo;Code units&rdquo; column of a row in <emu-xref href="#table-getsubstitution-replacements"></emu-xref>, or the empty String if there is no such sequence.
gibson042 marked this conversation as resolved.
Show resolved Hide resolved
1. If _replaceablePattern_ is not empty, then
1. Let _patternReplacement_ be the result of the &ldquo;Replacement text&rdquo; column of the corresponding row.
1. ReturnIfAbrupt(_patternReplacement_).
1. Set _result_ to the string-concatenation of _result_ and _patternReplacement_.
1. Let _patternLength_ be the number of code units in _replaceablePattern_.
1. Set _k_ to _k_ + _patternLength_.
1. Else,
1. Set _result_ to the string-concatenation of _result_ and the code unit at index _k_ within _replacement_.
1. Set _k_ to _k_ + 1.
1. Return _result_.
</emu-alg>
<emu-table id="table-45" caption="Replacement Text Symbol Substitutions">
<emu-table id="table-getsubstitution-replacements" caption="Replacement Text Symbol Substitutions" oldids="table-45">
<table>
<tbody>
<tr>
Expand Down Expand Up @@ -29882,69 +29895,69 @@ <h1>Runtime Semantics: GetSubstitution ( _matched_, _str_, _position_, _captures
</tr>
<tr>
<td>
0x0024, N
<br>
Where
<br>
0x0031 &le; N &le; 0x0039
0x0024, 0x0030
</td>
<td>
`$n` where
<br>
`n` is one of `1 2 3 4 5 6 7 8 9` and `$n` is not followed by a decimal digit
`$0`
</td>
<td>
The _n_<sup>th</sup> element of _captures_, where _n_ is a single digit in the range 1 to 9. If _n_ &le; _m_ and the _n_<sup>th</sup> element of _captures_ is *undefined*, use the empty String instead. If _n_ &gt; _m_, no replacement is done.
`$0`
</td>
</tr>
<tr>
<td>
0x0024, N, N
<br>
Where
0x0024, N
<br>
0x0030 &le; N &le; 0x0039
where 0x0031 &le; N &le; 0x0039
</td>
<td>
`$nn` where
<br>
`n` is one of `0 1 2 3 4 5 6 7 8 9`
`$`_n_
where _n_ is an expansion of |NonZeroDigit|
</td>
<td>
The _nn_<sup>th</sup> element of _captures_, where _nn_ is a two-digit decimal number in the range 01 to 99. If _nn_ &le; _m_ and the _nn_<sup>th</sup> element of _captures_ is *undefined*, use the empty String instead. If _nn_ is 00 or _nn_ &gt; _m_, no replacement is done.
If the MV of _n_ &gt; _m_, the replacement is the matched code units (equivalent to no replacement).
<br>
Otherwise, if the element in _captures_ at index equal to the MV of _n_ minus 1 is *undefined*, the replacement is the empty String.
<br>
Otherwise, the replacement is the element in _captures_ at index equal to the MV of _n_ minus 1.
</td>
</tr>
<tr>
<td>
0x0024, 0x003C
0x0024, N1, N2
<br>
where 0x0030 &le; N1 &le; 0x0039 and 0x0030 &le; N2 &le; 0x0039
</td>
<td>
`$&lt;`
`$`_nn_
where _nn_ is a two-element expansion of |DecimalDigits|
</td>
<td>
<emu-alg>
1. If _namedCaptures_ is *undefined*, the replacement text is the String *"$&lt;"*.
1. Else,
1. Assert: Type(_namedCaptures_) is Object.
1. Scan until the next `>` U+003E (GREATER-THAN SIGN).
1. If none is found, the replacement text is the String *"$&lt;"*.
1. Else,
1. Let _groupName_ be the enclosed substring.
1. Let _capture_ be ? Get(_namedCaptures_, _groupName_).
1. If _capture_ is *undefined*, replace the text through `>` with the empty string.
1. Otherwise, replace the text through `>` with ? ToString(_capture_).
</emu-alg>
If _nn_ is `00` or the MV of _nn_ &gt; _m_, the replacement is the string-concatenation of the replacement for the first two matched code units (i.e., a replacement specified by one of the two preceding rows) and the remaining matched code units (i.e., a single |DecimalDigit|).
<br>
Otherwise, if the element in _captures_ at index equal to the MV of _nn_ minus 1 is *undefined*, the replacement is the empty String.
<br>
Otherwise, the replacement is the element in _captures_ at index equal to the MV of _nn_ minus 1.
</td>
</tr>
<tr>
<td>
0x0024
0x0024, 0x003C, any sequence of code units not containing 0x003E, 0x003E
</td>
<td>
`$` in any context that does not match any of the above.
`$&lt;` _groupName_ `>`
where _groupName_ is a sequence of code units that does not contain a `>` U+003E (GREATER-THAN SIGN)
</td>
<td>
`$`
<emu-alg>
1. Set _groupName_ to the String value whose code units are the code units of _groupName_.
1. If _namedCaptures_ is *undefined*, then
1. The replacement is the string-concatenation of the String `"$&lt;"`, ! GetSubstitution(_matched_, _str_, _position_, _captures_, _namedCaptures_, _groupName_), and the String `">"`.
1. Else,
1. Assert: Type(_namedCaptures_) is Object.
1. Let _capture_ be ? Get(_namedCaptures_, _groupName_).
1. If _capture_ is *undefined*, the replacement is the empty String. Otherwise, the replacement is ? ToString(_capture_).
</emu-alg>
</td>
</tr>
</tbody>
Expand Down Expand Up @@ -32641,7 +32654,7 @@ <h1>%RegExpStringIteratorPrototype%.next ( )</h1>
1. Else,
1. If _global_ is *true*, then
1. Let _matchStr_ be ? ToString(? Get(_match_, *"0"*)).
1. If _matchStr_ is the empty string, then
1. If _matchStr_ is the empty String, then
1. Let _thisIndex_ be ? ToLength(? Get(_R_, *"lastIndex"*)).
1. Let _nextIndex_ be ! AdvanceStringIndex(_S_, _thisIndex_, _fullUnicode_).
1. Perform ? Set(_R_, *"lastIndex"*, _nextIndex_, *true*).
Expand Down