Created
March 2, 2021 00:40
-
-
Save iainireland/8e7541a95a7ec6900ce70fc44f9a3b76 to your computer and use it in GitHub Desktop.
RegExpBuiltinExec algorithm, renumbered
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 1.1.4.1.1 Runtime Semantics: RegExpBuiltinExec ( R, S ) | |
The abstract operation RegExpBuiltinExec with arguments R and S performs the following steps: | |
1. Assert: _R_ is an initialized RegExp instance. | |
2. Assert: Type(_S_) is String. | |
3. Let _length_ be the number of code units in _S_. | |
4. Let _lastIndex_ be ? ToLength(? Get(_R_, `"lastIndex"`)). | |
5. Let _flags_ be _R_.[[OriginalFlags]]. | |
6. If _flags_ contains `"g"`, let _global_ be *true*, else let _global_ be *false*. | |
7. If _flags_ contains `"y"`, let _sticky_ be *true*, else let _sticky_ be *false*. | |
8. If _flags_ contains `"d"`, let _hasIndices_ be *true*, else let _hasIndices_ be *false*. | |
9. If _global_ is *false* and _sticky_ is *false*, set _lastIndex_ to 0. | |
10. Let _matcher_ be _R_.[[RegExpMatcher]]. | |
11. If _flags_ contains `"u"`, let _fullUnicode_ be *true*, else let _fullUnicode_ be *false*. | |
12. Let _matchSucceeded_ be *false*. | |
13. Let _Input_ be a List consisting of all of the characters, in order, of _S_. If _fullUnicode_ is *true*, each character is a code unit, otherwise each character is a code point. | |
14. Repeat, while _matchSucceeded_ is *false* | |
a. If _lastIndex_ > _length_, then | |
i. If _global_ is *true* or _sticky_ is *true*, then | |
1. Perform ? Set(_R_, `"lastIndex"`, 0, *true*). | |
ii. Return *null*. | |
b. Let _r_ be _matcher_(_Input_, _lastIndex_). | |
c. If _r_ is _failure_, then | |
i. If _sticky_ is *true*, then | |
1. Perform ? Set(_R_, `"lastIndex"`, 0, *true*). | |
2. Return *null*. | |
ii. Set _lastIndex_ to AdvanceStringIndex(_S_, _lastIndex_, _fullUnicode_). | |
d. Else, | |
i. Assert: _r_ is a State. | |
ii. Set _matchSucceeded_ to *true*. | |
15. Let _e_ be _r_'s _endIndex_ value. | |
16. If _fullUnicode_ is *true*, set _e_ to ! GetStringIndex(_S_, _Input_, _e_) | |
17. If _global_ is *true* or _sticky_ is *true*, then | |
a. Perform ? Set(_R_, `"lastIndex"`, _e_, *true*). | |
18. Let _n_ be the number of elements in _r_'s _captures_ List. (This is the same value as 22.2.2.1's _NcapturingParens_.) | |
19. Assert: _n_ < 2<sup>32</sup>-1. | |
20. Let _A_ be ! ArrayCreate(_n_ + 1). | |
21. Assert: The value of _A_'s `"length"` property is _n_ + 1. | |
22. Perform ! CreateDataProperty(_A_, `"index"`, _lastIndex_). | |
23. Perform ! CreateDataProperty(_A_, `"input"`, _S_). | |
24. Let _match_ be the Match { [[StartIndex]]: _lastIndex_, [[EndIndex]]: _e_ }. | |
25. let _indices_ be a new empty List. | |
26. let _groupNames_ be a new empty List. | |
27. Add _match_ as the last element of _indices_. | |
28. Let _matchedValue_ be ! GetMatchString(_S_, _match_). | |
29. Perform ! CreateDataProperty(_A_, `"0"`, _matchedValue_). | |
30. If _R_ contains any |GroupName|, then | |
a. Let _groups_ be ObjectCreate(*null*). | |
b. Let _hasGroups_ be *true*. | |
31. Else, | |
a. Let _groups_ be *undefined*. | |
b. Let _hasGroups_ be *false*. | |
32. Perform ! CreateDataProperty(_A_, `"groups"`, _groups_). | |
33. For each integer _i_ such that _i_ < 0 and _i_ <= _n_, in ascending order, do | |
a. Let _captureI_ be _i_<sup>th</sup> element of _r_'s _captures_ List. | |
b. If _captureI_ is *undefined*, then | |
i. Let _capturedValue_ be *undefined*. | |
ii. Append *undefined* to _indices_. | |
c. Else, | |
i. Let _captureStart_ be _captureI_'s _ex_. | |
ii. Let _captureEnd_ be _captureI_'s _endIndex_. | |
iii. If _fullUnicode_ is *true*, then | |
1. Set _captureStart_ to ! GetStringIndex(_S_, _Input_, _captureStart_). | |
2. Set _captureEnd_ to ! GetStringIndex(_S_, _Input_, _captureEnd_). | |
iv. Let _capture_ be the Match { [[StartIndex]]: _captureStart_, [[EndIndex]:: _captureEnd_ }. | |
v. Let _capturedValue_ be ! GetMatchString(_S_, _capture_). | |
vi. Append _capture_ to _indices_. | |
d. Perform ! CreateDataProperty(_A_, ! ToString(_i_), _capturedValue_). | |
e. If the _i_th capture of _R_ was defined with a |GroupName|, then | |
i. Let _s_ be the StringValue of the corresponding |RegExpIdentifierName|. | |
ii. Perform ! CreateDataProperty(_groups_, _s_, _capturedValue_). | |
iii. Append _s_ to _groupNames_. | |
f. Else, | |
i. Append *undefined* to _groupNames_. | |
34. If _hasIndices_ is *true*, then | |
a. Let _indicesArray_ be ! MakeIndicesArray(_S_, _indices_, _groupNames_, _hasGroups_). | |
b. Perform ! CreateDataProperty(_A_, `"indices"`, _indicesArray_). | |
35. Return _A_. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment