Skip to content

Instantly share code, notes, and snippets.

@iainireland
Created March 2, 2021 00:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iainireland/8e7541a95a7ec6900ce70fc44f9a3b76 to your computer and use it in GitHub Desktop.
Save iainireland/8e7541a95a7ec6900ce70fc44f9a3b76 to your computer and use it in GitHub Desktop.
RegExpBuiltinExec algorithm, renumbered
# 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