@@ -13,13 +13,12 @@ public struct Skip: Pattern {
1313 @inlinable
1414 public func createInstructions( _ instructions: inout Instructions ) throws {
1515 instructions. append ( . skip)
16- instructions. append ( . jump( offset: 1 ) ) // dummy
1716 }
1817}
1918
2019import SE0270_RangeSet
2120
22- extension MutableCollection where Self: RandomAccessCollection , Index == Int {
21+ extension MutableCollection where Self: RandomAccessCollection , Self : RangeReplaceableCollection , Index == Int {
2322 @usableFromInline
2423 mutating func replaceSkips< Input> ( ) where Element == Instruction < Input > {
2524 for i in self . indices {
@@ -33,7 +32,7 @@ extension MutableCollection where Self: RandomAccessCollection, Index == Int {
3332
3433 @usableFromInline
3534 mutating func setupSkip< Input> ( at skipIndex: Index ) where Element == Instruction < Input > {
36- let searchablesStartAt = skipIndex + 2
35+ let searchablesStartAt = skipIndex + 1
3736 switch self [ searchablesStartAt] {
3837 case let . checkIndex( function, atIndexOffset: 0 ) :
3938 self [ skipIndex] = . search { input, index in
@@ -42,7 +41,7 @@ extension MutableCollection where Self: RandomAccessCollection, Index == Int {
4241 }
4342 self [ searchablesStartAt] = . choice( offset: - 1 , atIndexOffset: 1 )
4443 case . checkIndex( _, atIndexOffset: _) :
45- fatalError ( " Cannot see a valid reason for a `.checkIndex` with a non-zero offset to be located right after a `.skip` instruction. Correct me if I'm wrong. " )
44+ fatalError ( " Cannot see a valid reason for a `.checkIndex` with a non-zero offset to be located right after a `.skip` instruction. " ) // Correct me if I'm wrong.
4645 case let . checkElement( test) :
4746 self [ skipIndex] = . search { input, index in
4847 input [ index... ] . firstIndex ( where: test)
@@ -75,14 +74,14 @@ extension MutableCollection where Self: RandomAccessCollection, Index == Int {
7574 }
7675 default :
7776 self [ skipIndex] = . choice( offset: 0 , atIndexOffset: + 1 )
78- self . placeSkipCommit ( dummyIsAt : skipIndex + 1 , startSearchFrom: skipIndex + 2 )
77+ self . placeSkipCommit ( startSearchFrom: skipIndex + 1 )
7978 return
8079 }
81- self . placeSkipCommit ( dummyIsAt : skipIndex + 1 , startSearchFrom: skipIndex + 3 )
80+ self . placeSkipCommit ( startSearchFrom: skipIndex + 2 )
8281 }
8382
8483 @usableFromInline
85- mutating func placeSkipCommit< Input> ( dummyIsAt dummyIndex : Index , startSearchFrom: Index )
84+ mutating func placeSkipCommit< Input> ( startSearchFrom: Index )
8685 where Element == Instruction < Input > {
8786 var i = startSearchFrom
8887 loop: while true {
@@ -97,17 +96,48 @@ extension MutableCollection where Self: RandomAccessCollection, Index == Int {
9796 } else {
9897 i += offset
9998 }
100- case let . jump( offset) :
99+ case let . jump( offset) where offset > 0 : // If we jump backwards we are likely to enter an infinite loop.
101100 i += offset
102- case . elementEquals, . checkElement, . checkIndex, . moveIndex, . captureStart, . captureEnd, . call:
101+ case . elementEquals, . checkElement, . checkIndex, . moveIndex, . captureStart, . captureEnd, . call, . jump :
103102 i += 1
104103 case . commit, . choiceEnd, . return, . match, . skip, . search:
105- moveSubranges ( RangeSet ( dummyIndex ..< ( dummyIndex + 1 ) ) , to: i)
106- self [ i - 1 ] = . commit
104+ insertInstructions ( . commit, at: i)
107105 return
108106 case . fail, . openCall:
109107 fatalError ( )
110108 }
111109 }
112110 }
111+
112+ /// Inserts new instructions at `location`. Adjusts the offsets of other instructions accordingly.
113+ @usableFromInline
114+ mutating func insertInstructions< Input> ( _ newInstructions: Element ... , at location: Index )
115+ where Element == Instruction < Input > {
116+ insert ( contentsOf: newInstructions, at: location)
117+ let insertedRange = location ..< ( location + newInstructions. count + 1 )
118+ for i in startIndex ..< insertedRange. lowerBound {
119+ switch self [ i] {
120+ case let . call( offset) where offset > ( location - i) :
121+ self [ i] = . call( offset: offset + newInstructions. count)
122+ case let . jump( offset) where offset > ( location - i) :
123+ self [ i] = . jump( offset: offset + newInstructions. count)
124+ case let . choice( offset, atIndexOffset) where offset > ( location - i) :
125+ self [ i] = . choice( offset: offset + newInstructions. count, atIndexOffset: atIndexOffset)
126+ default :
127+ break
128+ }
129+ }
130+ for i in insertedRange. upperBound ..< endIndex {
131+ switch self [ i] {
132+ case let . call( offset) where offset < ( location - i) :
133+ self [ i] = . call( offset: offset - newInstructions. count)
134+ case let . jump( offset) where offset < ( location - i) :
135+ self [ i] = . jump( offset: offset - newInstructions. count)
136+ case let . choice( offset, atIndexOffset) where offset < ( location - i) :
137+ self [ i] = . choice( offset: offset - newInstructions. count, atIndexOffset: atIndexOffset)
138+ default :
139+ break
140+ }
141+ }
142+ }
113143}
0 commit comments