Skip to content

Commit

Permalink
flatMap now inherits the overflows property from the root parser
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mie6 committed Jul 10, 2023
1 parent 4cdbaeb commit 66974b6
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ private [deepembedding] abstract class ContOps[Cont[_, +_]] {
def map[R, A, B](c: Cont[R, A], f: A => B): Cont[R, B]
def flatMap[R, A, B](c: Cont[R, A], f: A => Cont[R, B]): Cont[R, B]
def suspend[R, A](x: =>Cont[R, A]): Cont[R, A]
def isStackSafe: Boolean
// $COVERAGE-OFF$
// This needs to be lazy, because I'm an idiot when I use it
def `then`[R, A, B](c: Cont[R, A], k: =>Cont[R, B]): Cont[R, B] = flatMap[R, A, B](c, _ => k)
Expand Down Expand Up @@ -52,6 +53,7 @@ private [deepembedding] object Cont {
override def flatMap[R, A, B](mx: Impl[R, A], f: A => Impl[R, B]): Impl[R, B] = k => new Thunk(() => mx(x => f(x)(k)))
override def suspend[R, A](x: =>Impl[R, A]): Impl[R, A] = k => new Thunk(() => x(k))
override def `then`[R, A, B](mx: Impl[R, A], my: =>Impl[R, B]): Impl[R, B] = k => new Thunk(() => mx(_ => my(k)))
override def isStackSafe: Boolean = true
}
}

Expand All @@ -64,5 +66,6 @@ private [deepembedding] object Id {
override def flatMap[R, A, B](c: Impl[R, A], f: A => Impl[R, B]): Impl[R, B] = f(c)
override def suspend[R, A](x: =>Impl[R, A]): Impl[R, A] = x
override def as[R, A, B](c: Impl[R, A], x: =>B): Impl[R, B] = x
override def isStackSafe: Boolean = false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ private [deepembedding] final class >>=[A, B](val p: StrictParsley[A], private [
}
override def codeGen[M[_, +_]: ContOps, R](implicit instrs: InstrBuffer, state: CodeGenState): M[R, Unit] = {
suspend(p.codeGen[M, R]) |> {
instrs += instructions.DynCall[A](x => f(x).demandCalleeSave(state.numRegs).instrs)
instrs += instructions.DynCall[A] { x =>
val p = f(x)
p.demandCalleeSave(state.numRegs)
if (implicitly[ContOps[M]].isStackSafe) p.overflows()
p.instrs
}
}
}
// $COVERAGE-OFF$
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@ private [parsley] abstract class LazyParsley[+A] private [deepembedding] {
*
* @param numRegs the number of registers the parent uses (these must be saved)
*/
private [deepembedding] def demandCalleeSave(numRegs: Int): this.type = {
numRegsUsedByParent = numRegs
this
}
private [deepembedding] def demandCalleeSave(numRegs: Int): Unit = numRegsUsedByParent = numRegs

// Internals
// To ensure that stack-overflow cannot occur during the processing of particularly
Expand Down

0 comments on commit 66974b6

Please sign in to comment.