@@ -14,6 +14,7 @@ extension Program where Input.Element: Hashable {
1414 // Registers
1515 var nextBoolRegister = BoolRegister ( 0 )
1616 var nextIntRegister = IntRegister ( 0 )
17+ var nextPositionRegister = PositionRegister ( 0 )
1718
1819 // Special addresses or instructions
1920 var failAddressToken : AddressToken ? = nil
@@ -73,6 +74,13 @@ extension Program.Builder {
7374 buildMoveImmediate ( uint, into: into)
7475 }
7576
77+ public mutating func buildMoveCurrentPosition(
78+ into: PositionRegister
79+ ) {
80+ instructions. append ( . init(
81+ . movePosition, . init( position: into) ) )
82+ }
83+
7684 public mutating func buildBranch( to t: AddressToken ) {
7785 instructions. append ( . init( . branch) )
7886 fixup ( to: t)
@@ -150,6 +158,14 @@ extension Program.Builder {
150158 . init( sequence: sequences. store ( . init( s) ) ) ) )
151159 }
152160
161+ public mutating func buildMatchSlice(
162+ lower: PositionRegister , upper: PositionRegister
163+ ) {
164+ instructions. append ( . init(
165+ . matchSlice,
166+ . init( pos: lower, pos2: upper) ) )
167+ }
168+
153169 public mutating func buildConsume(
154170 by p: @escaping Program . ConsumeFunction
155171 ) {
@@ -225,6 +241,7 @@ extension Program.Builder {
225241 regInfo. strings = strings. count
226242 regInfo. bools = nextBoolRegister. rawValue
227243 regInfo. ints = nextIntRegister. rawValue
244+ regInfo. positions = nextPositionRegister. rawValue
228245 regInfo. consumeFunctions = consumeFunctions. count
229246
230247 return Program (
@@ -311,6 +328,10 @@ extension Program.Builder {
311328 defer { nextIntRegister. rawValue += 1 }
312329 return nextIntRegister
313330 }
331+ public mutating func makePositionRegister( ) -> PositionRegister {
332+ defer { nextPositionRegister. rawValue += 1 }
333+ return nextPositionRegister
334+ }
314335
315336 // Allocate and initialize a register
316337 public mutating func makeIntRegister(
@@ -321,6 +342,15 @@ extension Program.Builder {
321342 return r
322343 }
323344
345+ // Allocate and initialize a register
346+ public mutating func makePositionRegister(
347+ initializingWithCurrentPosition: ( )
348+ ) -> PositionRegister {
349+ let r = makePositionRegister ( )
350+ self . buildMoveCurrentPosition ( into: r)
351+ return r
352+ }
353+
324354 // 'kill' or release allocated registers
325355 public mutating func kill( _ r: IntRegister ) {
326356 // TODO: Release/reuse registers, for now nop makes
@@ -332,15 +362,20 @@ extension Program.Builder {
332362 // reading the code easier
333363 buildNop ( " kill \( r) " )
334364 }
365+ public mutating func kill( _ r: PositionRegister ) {
366+ // TODO: Release/reuse registers, for now nop makes
367+ // reading the code easier
368+ buildNop ( " kill \( r) " )
369+ }
370+
371+ // TODO: A register-mapping helper struct, which could release
372+ // registers without monotonicity required
335373
336374 public mutating func makeConsumeFunction(
337375 _ f: @escaping Program . ConsumeFunction
338376 ) -> ConsumeFunctionRegister {
339377 defer { consumeFunctions. append ( f) }
340378 return ConsumeFunctionRegister ( consumeFunctions. count)
341379 }
342-
343- // TODO: consider releasing registers
344-
345380}
346381
0 commit comments