All Downloads are FREE. Search and download functionalities are using the official Maven repository.

parsley.internal.deepembedding.backend.debug.Debugged.scala Maven / Gradle / Ivy

There is a newer version: 5.0.0-M11
Show newest version
/*
 * Copyright 2020 Parsley Contributors 
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package parsley.internal.deepembedding.backend.debug

import parsley.debug.internal.{DebugContext, DivergenceContext}

import parsley.internal.deepembedding.ContOps
import parsley.internal.deepembedding.ContOps.{suspend, ContAdapter}
import parsley.internal.deepembedding.backend.{CodeGenState, StrictParsley, Unary}
import parsley.internal.deepembedding.backend.StrictParsley.InstrBuffer
import parsley.internal.deepembedding.frontend.LazyParsley
import parsley.internal.machine.instructions.{Label, Pop}
import parsley.internal.machine.instructions.debug.{AddAttemptAndLeave, DropSnapshot, EnterParser, TakeSnapshot}

// TODO: rename to TagFactory? this file can then be called Tags
// this should probably be split out into its own file as well
private [deepembedding] sealed abstract class DebugStrategy {
    def create[A](origin: LazyParsley[A], p: StrictParsley[A], userAssignedName: Option[String]): StrictParsley[A]
}

private [parsley] final class Debugging(dbgCtx: DebugContext) extends DebugStrategy {
    def create[A](origin: LazyParsley[A], p: StrictParsley[A], userAssignedName: Option[String]): StrictParsley[A] = {
        new Debugged(origin, p, userAssignedName)(dbgCtx)
    }
}

private [parsley] final class CheckDivergence(dtx: DivergenceContext) extends DebugStrategy {
    def create[A](origin: LazyParsley[A], p: StrictParsley[A], userAssignedName: Option[String]): StrictParsley[A] = {
        new DivergenceChecker(origin, p, userAssignedName)(dtx)
    }
}

// backend implementations
private [backend] final class Debugged[A](origin: LazyParsley[A], val p: StrictParsley[A], userAssignedName: Option[String])(dbgCtx: DebugContext)
    extends Unary[A, A] {
    override protected [backend] def codeGen[M[_, +_]: ContOps, R](producesResults: Boolean)(implicit instrs: InstrBuffer, state: CodeGenState): M[R, Unit] = {
        val handler = state.freshLabel()
        instrs += new EnterParser(handler, origin, userAssignedName)(dbgCtx)
        suspend[M, R, Unit](p.codeGen[M, R](producesResults = true)) |> {
            instrs += new Label(handler)
            instrs += new AddAttemptAndLeave(dbgCtx)
            if (!producesResults) instrs += Pop
        }
    }

    override protected def pretty(p: String): String = s"debugged($p)"
}

private [backend] final class DivergenceChecker[A](origin: LazyParsley[A], val p: StrictParsley[A], userAssignedName: Option[String])(dtx: DivergenceContext)
    extends Unary[A, A] {
    override protected [backend] def codeGen[M[_, +_]: ContOps, R](producesResults: Boolean)(implicit instrs: InstrBuffer, state: CodeGenState): M[R, Unit] = {
        val handler = state.freshLabel()
        instrs += new TakeSnapshot(handler, origin, userAssignedName)(dtx)
        suspend[M, R, Unit](p.codeGen[M, R](producesResults)) |> {
            instrs += new Label(handler)
            instrs += new DropSnapshot(dtx)
        }
    }

    override protected def pretty(p: String): String = p
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy