diff --git a/Sources/_StringProcessing/Engine/Processor.swift b/Sources/_StringProcessing/Engine/Processor.swift
index 8f777ad33..a67e621db 100644
--- a/Sources/_StringProcessing/Engine/Processor.swift
+++ b/Sources/_StringProcessing/Engine/Processor.swift
@@ -94,6 +94,22 @@ extension Processor {
assert(currentPosition >= start)
assert(currentPosition <= end)
}
+
+ mutating func reset(newPosition: Position)
+ {
+ self.controller = Controller(pc: 0)
+ self.currentPosition = newPosition
+
+ self.registers.reset(bounds.upperBound)
+ for idx in storedCaptures.indices {
+ storedCaptures[idx] = .init()
+ }
+
+ self.savePoints.removeAll(keepingCapacity: true)
+ self.callStack.removeAll(keepingCapacity: true)
+ self.state = .inProgress
+ self.failureReason = nil
+ }
}
extension Processor {
diff --git a/Sources/_StringProcessing/Engine/Registers.swift b/Sources/_StringProcessing/Engine/Registers.swift
index bc17f1215..e9ea3c4a9 100644
--- a/Sources/_StringProcessing/Engine/Registers.swift
+++ b/Sources/_StringProcessing/Engine/Registers.swift
@@ -18,6 +18,8 @@ struct SentinelValue: Hashable, CustomStringConvertible {
extension Processor {
/// Our register file
struct Registers {
+ var info: MEProgram.RegisterInfo
+
// currently, these are static readonly
var elements: [Element]
@@ -114,7 +116,7 @@ extension Processor.Registers {
_ program: MEProgram,
_ sentinel: Input.Index
) {
- let info = program.registerInfo
+ self.info = program.registerInfo
self.elements = program.staticElements
assert(elements.count == info.elements)
@@ -156,6 +158,26 @@ extension Processor.Registers {
self.savePointAddresses = Array(repeating: 0, count: info.savePointAddresses)
}
+
+ mutating func reset(_ sentinel: Input.Index) {
+ // note: Is there any issue with the program transform functions holding
+ // state and not getting reset here? Do we care?
+ func clear(_ xs: inout [T], _ v: T) {
+ for idx in xs.indices {
+ xs[idx] = v
+ }
+ }
+
+ clear(&self.bools, false)
+ clear(&self.ints, 0)
+ clear(&self.floats, 0)
+ clear(&self.positions, sentinel)
+ clear(&self.values, SentinelValue())
+ clear(&self.instructionAddresses, 0)
+ clear(&self.classStackAddresses, 0)
+ clear(&self.positionStackAddresses, 0)
+ clear(&self.savePointAddresses, 0)
+ }
}
extension MEProgram {
diff --git a/Sources/_StringProcessing/Executor.swift b/Sources/_StringProcessing/Executor.swift
index 532a41256..520145ca1 100644
--- a/Sources/_StringProcessing/Executor.swift
+++ b/Sources/_StringProcessing/Executor.swift
@@ -27,7 +27,47 @@ struct Executor {
) throws -> Regex