Skip to content

Commit

Permalink
Normative: Update GetSubstitution to match reality
Browse files Browse the repository at this point in the history
$nn patterns fall back to $n when there aren't at least nn captures

Fixes tc39gh-1426
  • Loading branch information
gibson042 committed Oct 9, 2019
1 parent 98813bc commit 356bbb4
Showing 1 changed file with 46 additions and 34 deletions.
80 changes: 46 additions & 34 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -29851,11 +29851,23 @@ <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. If _namedCaptures_ is not *undefined*, then
1. Set _namedCaptures_ to ? ToObject(_namedCaptures_).
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-45"></emu-xref>.
1. If _replaceablePattern_ is not empty,
1. Let _patternReplacement_ be the result of the &ldquo;Replacement text&rdquo; column of the corresponding row.
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 from _replacement_ at index _k_.
1. Set _k_ to _k_ + 1.
1. Return _result_.
</emu-alg>
<emu-table id="table-45" caption="Replacement Text Symbol Substitutions">
Expand Down Expand Up @@ -29918,68 +29930,68 @@ <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. 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. 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

0 comments on commit 356bbb4

Please sign in to comment.