Skip to content

Commit 7af91d6

Browse files
natecook1000hamishknight
authored andcommitted
Add a clearThrough instruction
This will let us fix lookahead assertions that have leftover save points in the subpattern on success, and also allow us to implement atomic groups.
1 parent 3eb9985 commit 7af91d6

File tree

3 files changed

+26
-2
lines changed

3 files changed

+26
-2
lines changed

Sources/_StringProcessing/Engine/Instruction.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,13 @@ extension Instruction {
228228
/// Precondition: There is a save point to remove
229229
case clear
230230

231+
/// Remove save points up to and including the operand
232+
///
233+
/// Operand: instruction address to look for
234+
///
235+
/// Precondition: The operand is in the save point list
236+
case clearThrough
237+
231238
/// View the most recently saved point
232239
///
233240
/// UNIMPLEMENTED

Sources/_StringProcessing/Engine/MEBuilder.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ extension MEProgram.Builder {
153153
mutating func buildClear() {
154154
instructions.append(.init(.clear))
155155
}
156+
mutating func buildClearThrough(_ t: AddressToken) {
157+
instructions.append(.init(.clearThrough))
158+
fixup(to: t)
159+
}
156160
mutating func buildRestore() {
157161
instructions.append(.init(.restore))
158162
}
@@ -317,7 +321,7 @@ extension MEProgram.Builder {
317321
case .condBranchZeroElseDecrement:
318322
payload = .init(addr: addr, int: inst.payload.int)
319323

320-
case .branch, .save, .saveAddress, .call:
324+
case .branch, .save, .saveAddress, .call, .clearThrough:
321325
payload = .init(addr: addr)
322326

323327
case .splitSaving:

Sources/_StringProcessing/Engine/Processor.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ extension Processor {
250250
}
251251
let (opcode, payload) = fetch().destructure
252252

253+
OpCodeSwitch:
253254
switch opcode {
254255
case .invalid:
255256
fatalError("Invalid program")
@@ -323,9 +324,21 @@ extension Processor {
323324
if let _ = savePoints.popLast() {
324325
controller.step()
325326
} else {
326-
fatalError("TODO: What should we do here?")
327+
// TODO: What should we do here?
328+
fatalError("Invalid code: Tried to clear save points when empty")
327329
}
328330

331+
case .clearThrough:
332+
let addr = payload.addr
333+
while let sp = savePoints.popLast() {
334+
if sp.pc == addr {
335+
controller.step()
336+
break OpCodeSwitch
337+
}
338+
}
339+
// TODO: What should we do here?
340+
fatalError("Invalid code: Tried to clear save points when empty")
341+
329342
case .peek:
330343
fatalError()
331344

0 commit comments

Comments
 (0)