Skip to content

Commit

Permalink
Merge Check, Hint, and Handler stacks (#212)
Browse files Browse the repository at this point in the history
* Moved handler pop to the handlers

* removed CheckStack

* Removed HintStack

* Simplified RestoreAndPushHandler

* reused another handler

* renaming

* refactored

* remove qualified
  • Loading branch information
j-mie6 authored Aug 15, 2023
1 parent 43d6a39 commit 523e0ff
Show file tree
Hide file tree
Showing 17 changed files with 145 additions and 186 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ private [backend] object Choice {
(implicit instrs: InstrBuffer, state: CodeGenState): M[R, Unit] = {
val handler = state.freshLabel()
val skip = state.freshLabel()
instrs += new instructions.PushHandlerAndState(handler, saveHints = true, hideHints = false)
// FIXME: check this, this is the only one that uses this instruction, and I think it was a mistake
instrs += new instructions.PushHandlerAndStateAndClearHints(handler)
suspend(p.codeGen[M, R]) >> {
instrs += new instructions.JumpAndPopState(skip)
instrs += new instructions.Label(handler)
Expand All @@ -119,7 +120,7 @@ private [backend] object Choice {
(implicit instrs: InstrBuffer, state: CodeGenState): M[R, Unit] = {
val handler = state.freshLabel()
val skip = state.freshLabel()
instrs += new instructions.PushHandlerAndCheck(handler, saveHints = true)
instrs += new instructions.PushHandlerAndClearHints(handler)
suspend(p.codeGen[M, R]) >> {
instrs += new instructions.JumpAndPopCheck(skip)
instrs += new instructions.Label(handler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,17 @@ import parsley.internal.deepembedding.singletons._
import parsley.internal.machine.instructions

private [deepembedding] final class ErrorLabel[A](val p: StrictParsley[A], private val labels: scala.Seq[String]) extends ScopedUnary[A, A] {
// This needs to save the hints because label should relabel only the hints generated _within_ its context, then merge with the originals after
override def setup(label: Int): instructions.Instr = new instructions.PushHandlerAndCheck(label, saveHints = true)
override def setup(label: Int): instructions.Instr = new instructions.PushHandler(label) // was AndClearHints
override def instr: instructions.Instr = new instructions.RelabelHints(labels)
override def instrNeedsLabel: Boolean = false
override def handlerLabel(state: CodeGenState): Int = state.getLabelForRelabelError(labels)
// don't need to be limited to not hidden when the thing can never internally generate hints
final override def optimise: StrictParsley[A] = p match {
case CharTok(c) /*if ct.expected ne Hidden */ => new CharTok(c, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case SupplementaryCharTok(c) /*if ct.expected ne Hidden */ => new SupplementaryCharTok(c, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case StringTok(s) /*if st.expected ne Hidden */ => new StringTok(s, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case Satisfy(f) /*if sat.expected ne Hidden */ => new Satisfy(f, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case UniSatisfy(f) /*if sat.expected ne Hidden */ => new UniSatisfy(f, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case CharTok(c) => new CharTok(c, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case SupplementaryCharTok(c) => new SupplementaryCharTok(c, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case StringTok(s) => new StringTok(s, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case Satisfy(f) => new Satisfy(f, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case UniSatisfy(f) => new UniSatisfy(f, Label(labels: _*)).asInstanceOf[StrictParsley[A]]
case ErrorLabel(p, label2) if label2.nonEmpty => ErrorLabel(p, labels)
case _ => this
}
Expand All @@ -32,8 +31,7 @@ private [deepembedding] final class ErrorLabel[A](val p: StrictParsley[A], priva
// $COVERAGE-ON$
}
private [deepembedding] final class ErrorHide[A](val p: StrictParsley[A]) extends ScopedUnary[A, A] {
// This needs to save the hints because label should hints only the hints generated _within_ its context, then merge with the originals after
override def setup(label: Int): instructions.Instr = new instructions.PushHandlerAndCheck(label, saveHints = true)
override def setup(label: Int): instructions.Instr = new instructions.PushHandler(label)
override def instr: instructions.Instr = instructions.HideHints
override def instrNeedsLabel: Boolean = false
override def handlerLabel(state: CodeGenState): Int = state.getLabel(instructions.HideErrorAndFail)
Expand All @@ -43,16 +41,16 @@ private [deepembedding] final class ErrorHide[A](val p: StrictParsley[A]) extend
// $COVERAGE-ON$
}
private [deepembedding] final class ErrorExplain[A](val p: StrictParsley[A], reason: String) extends ScopedUnary[A, A] {
override def setup(label: Int): instructions.Instr = new instructions.PushHandlerAndCheck(label, saveHints = false)
override def instr: instructions.Instr = instructions.PopHandlerAndCheck
override def setup(label: Int): instructions.Instr = new instructions.PushHandler(label)
override def instr: instructions.Instr = instructions.PopHandler
override def instrNeedsLabel: Boolean = false
override def handlerLabel(state: CodeGenState): Int = state.getLabelForApplyReason(reason)
// $COVERAGE-OFF$
final override def pretty(p: String): String = s"$p.explain($reason)"
// $COVERAGE-ON$
}

private [deepembedding] final class ErrorAmend[A](val p: StrictParsley[A], partial: Boolean) extends ScopedUnaryWithState[A, A](false) {
private [deepembedding] final class ErrorAmend[A](val p: StrictParsley[A], partial: Boolean) extends ScopedUnaryWithState[A, A] {
override val instr: instructions.Instr = instructions.PopHandlerAndState
override def instrNeedsLabel: Boolean = false
override def handlerLabel(state: CodeGenState): Int = state.getLabel(instructions.AmendAndFail(partial))
Expand Down Expand Up @@ -82,8 +80,8 @@ private [deepembedding] final class ErrorDislodge[A](n: Int, val p: StrictParsle
private [deepembedding] final class ErrorLexical[A](val p: StrictParsley[A]) extends ScopedUnary[A, A] {
// This needs to save the hints because error label will relabel the first hint, which because the list is ordered would be the hints that came _before_
// entering labels context. Instead label should relabel the first hint generated _within_ its context, then merge with the originals after
override def setup(label: Int): instructions.Instr = new instructions.PushHandlerAndCheck(label, saveHints = false)
override def instr: instructions.Instr = instructions.PopHandlerAndCheck
override def setup(label: Int): instructions.Instr = new instructions.PushHandler(label)
override def instr: instructions.Instr = instructions.PopHandler
override def instrNeedsLabel: Boolean = false
override def handlerLabel(state: CodeGenState): Int = state.getLabel(instructions.SetLexicalAndFail)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ private [backend] abstract class ScopedUnary[A, B] extends Unary[A, B] {
}
}

private [backend] abstract class ScopedUnaryWithState[A, B](doesNotProduceHints: Boolean) extends ScopedUnary[A, B] {
override def setup(label: Int): instructions.Instr = new instructions.PushHandlerAndState(label, doesNotProduceHints, doesNotProduceHints)
private [backend] abstract class ScopedUnaryWithState[A, B] extends ScopedUnary[A, B] {
override def setup(label: Int): instructions.Instr = new instructions.PushHandlerAndState(label)
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ private [backend] sealed abstract class ManyLike[A, B](name: String, unit: B) ex
val body = state.freshLabel()
val handler = state.freshLabel()
preamble(instrs)
instrs += new instructions.PushHandlerIterative(handler)
instrs += new instructions.PushHandler(handler)
instrs += new instructions.Label(body)
suspend(p.codeGen[M, R]) |> {
instrs += new instructions.Label(handler)
Expand Down Expand Up @@ -66,7 +66,7 @@ private [deepembedding] final class ChainPost[A](p: StrictParsley[A], op: Strict
val body = state.freshLabel()
val handler = state.freshLabel()
suspend(p.codeGen[M, R]) >> {
instrs += new instructions.PushHandlerIterative(handler)
instrs += new instructions.PushHandler(handler)
instrs += new instructions.Label(body)
suspend(op.codeGen[M, R]) |> {
instrs += new instructions.Label(handler)
Expand All @@ -83,7 +83,7 @@ private [deepembedding] final class ChainPre[A](p: StrictParsley[A], op: StrictP
val body = state.freshLabel()
val handler = state.freshLabel()
instrs += new instructions.Push(identity[Any] _)
instrs += new instructions.PushHandlerIterative(handler)
instrs += new instructions.PushHandler(handler)
instrs += new instructions.Label(body)
suspend(op.codeGen[M, R]) >> {
instrs += new instructions.Label(handler)
Expand All @@ -102,7 +102,7 @@ private [deepembedding] final class Chainl[A, B](init: StrictParsley[B], p: Stri
val body = state.freshLabel()
val handler = state.freshLabel()
suspend(init.codeGen[M, R]) >> {
instrs += new instructions.PushHandlerIterative(handler)
instrs += new instructions.PushHandler(handler)
instrs += new instructions.Label(body)
op.codeGen[M, R] >>
suspend(p.codeGen[M, R]) |> {
Expand All @@ -120,13 +120,14 @@ private [deepembedding] final class Chainr[A, B](p: StrictParsley[A], op: Strict
def inlinable: Boolean = false
override def codeGen[M[_, +_]: ContOps, R](implicit instrs: InstrBuffer, state: CodeGenState): M[R, Unit]= {
val body = state.freshLabel()
val handler1 = state.getLabel(instructions.ChainrWholeHandler)
// handler1 is where the check offset is kept
val handler1 = state.getLabel(instructions.Refail)
val handler2 = state.freshLabel()
instrs += new instructions.Push(identity[Any] _)
instrs += new instructions.PushHandlerIterative(handler1)
instrs += new instructions.PushHandler(handler1)
instrs += new instructions.Label(body)
suspend(p.codeGen[M, R]) >> {
instrs += new instructions.PushHandlerIterative(handler2)
instrs += new instructions.PushHandler(handler2)
suspend(op.codeGen[M, R]) |> {
instrs += new instructions.ChainrJump(body)
instrs += new instructions.Label(handler2)
Expand All @@ -145,10 +146,10 @@ private [deepembedding] final class SepEndBy1[A, B](p: StrictParsley[A], sep: St
val handler1 = state.freshLabel()
val handler2 = state.freshLabel()
instrs += new instructions.Fresh(mutable.ListBuffer.empty[Any])
instrs += new instructions.PushHandlerIterative(handler1)
instrs += new instructions.PushHandler(handler1)
instrs += new instructions.Label(body)
suspend(p.codeGen[M, R]) >> {
instrs += new instructions.PushHandlerIterative(handler2)
instrs += new instructions.PushHandler(handler2)
suspend(sep.codeGen[M, R]) |> {
instrs += new instructions.SepEndBy1Jump(body)
instrs += new instructions.Label(handler2)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import parsley.internal.deepembedding.singletons._
import parsley.internal.machine.instructions

import StrictParsley.InstrBuffer
private [deepembedding] final class Attempt[A](val p: StrictParsley[A]) extends ScopedUnaryWithState[A, A](false) {
private [deepembedding] final class Attempt[A](val p: StrictParsley[A]) extends ScopedUnaryWithState[A, A] {
override val instr: instructions.Instr = instructions.PopHandlerAndState
override def instrNeedsLabel: Boolean = false
override def handlerLabel(state: CodeGenState): Int = state.getLabel(instructions.RestoreAndFail)
Expand All @@ -28,7 +28,7 @@ private [deepembedding] final class Attempt[A](val p: StrictParsley[A]) extends
final override def pretty(p: String): String = s"attempt($p)"
// $COVERAGE-ON$
}
private [deepembedding] final class Look[A](val p: StrictParsley[A]) extends ScopedUnaryWithState[A, A](true) {
private [deepembedding] final class Look[A](val p: StrictParsley[A]) extends ScopedUnaryWithState[A, A] {
override val instr: instructions.Instr = instructions.RestoreHintsAndState
override def instrNeedsLabel: Boolean = false
override def handlerLabel(state: CodeGenState): Int = state.getLabel(instructions.PopStateRestoreHintsAndFail)
Expand All @@ -43,7 +43,7 @@ private [deepembedding] final class NotFollowedBy[A](val p: StrictParsley[A]) ex
}*/
final override def codeGen[M[_, +_]: ContOps, R](implicit instrs: InstrBuffer, state: CodeGenState): M[R, Unit] = {
val handler = state.freshLabel()
instrs += new instructions.PushHandlerAndState(handler, saveHints = true, hideHints = true)
instrs += new instructions.PushHandlerAndState(handler)
suspend[M, R, Unit](p.codeGen) |> {
instrs += instructions.NegLookFail
instrs += new instructions.Label(handler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ private [backend] sealed abstract class FilterLike[A, B] extends StrictParsley[B
val handler1 = state.getLabel(instructions.PopStateAndFail)
val handler2 = state.getLabel(instructions.AmendAndFail(false))
val jumpLabel = state.freshLabel()
instrs += new instructions.PushHandlerAndState(handler1, saveHints = false, hideHints = false)
instrs += new instructions.PushHandlerAndState(handler1)
suspend(p.codeGen[M, R]) >> {
instrs += instr(handler2, jumpLabel)
suspend(err.codeGen[M, R]) |> {
Expand Down
Loading

0 comments on commit 523e0ff

Please sign in to comment.