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

parsley.internal.deepembedding.backend.ErrorEmbedding.scala Maven / Gradle / Ivy

There is a newer version: 5.0.0-M6
Show newest version
/* SPDX-FileCopyrightText: © 2022 Parsley Contributors 
 * SPDX-License-Identifier: BSD-3-Clause
 */
package parsley.internal.deepembedding.backend

import parsley.token.errors.{Hidden, Label}

import parsley.internal.deepembedding.singletons._
import parsley.internal.machine.instructions

private [deepembedding] final class ErrorLabel[A](val p: StrictParsley[A], private [ErrorLabel] val label: String) 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 = true)
    override def instr: instructions.Instr = new instructions.RelabelHints(label)
    override def instrNeedsLabel: Boolean = false
    override def handlerLabel(state: CodeGenState): Int = state.getLabelForRelabelError(label)
    final override def optimise: StrictParsley[A] = p match {
        case ct@CharTok(c) if ct.expected ne Hidden => new CharTok(c, Label(label)).asInstanceOf[StrictParsley[A]]
        case st@StringTok(s) if st.expected ne Hidden => new StringTok(s, Label(label)).asInstanceOf[StrictParsley[A]]
        case sat@Satisfy(f) if sat.expected ne Hidden => new Satisfy(f, Label(label)).asInstanceOf[StrictParsley[A]]
        // TODO: The hide property is required to be checked, but there is no test for it
        case ErrorLabel(p, label2) if label2.nonEmpty => ErrorLabel(p, label)
        case _ => this
    }

    // $COVERAGE-OFF$
    final override def pretty(p: String): String = s"$p.label($label)"
    // $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 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) {
    override val instr: instructions.Instr = instructions.PopHandlerAndState
    override def instrNeedsLabel: Boolean = false
    override def handlerLabel(state: CodeGenState): Int  = state.getLabel(instructions.AmendAndFail(partial))
    // $COVERAGE-OFF$
    final override def pretty(p: String): String = s"amend($p)"
    // $COVERAGE-ON$
}
private [deepembedding] final class ErrorEntrench[A](val p: StrictParsley[A]) extends ScopedUnary[A, A] {
    override def setup(label: Int): instructions.Instr = new instructions.PushHandler(label)
    override val instr: instructions.Instr = instructions.PopHandler
    override def instrNeedsLabel: Boolean = false
    override def handlerLabel(state: CodeGenState): Int  = state.getLabel(instructions.EntrenchAndFail)
    // $COVERAGE-OFF$
    final override def pretty(p: String): String = s"entrench($p)"
    // $COVERAGE-ON$
}
private [deepembedding] final class ErrorDislodge[A](val p: StrictParsley[A]) extends ScopedUnary[A, A] {
    override def setup(label: Int): instructions.Instr = new instructions.PushHandler(label)
    override val instr: instructions.Instr = instructions.PopHandler
    override def instrNeedsLabel: Boolean = false
    override def handlerLabel(state: CodeGenState): Int  = state.getLabel(instructions.DislodgeAndFail)
    // $COVERAGE-OFF$
    final override def pretty(p: String): String = s"dislodge($p)"
    // $COVERAGE-ON$
}

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 instrNeedsLabel: Boolean = false
    override def handlerLabel(state: CodeGenState): Int = state.getLabel(instructions.SetLexicalAndFail)

    // $COVERAGE-OFF$
    final override def pretty(p: String): String = s"$p.markAsToken"
    // $COVERAGE-ON$
}

private [deepembedding] final class VerifiedError[A](val p: StrictParsley[A], msggen: Either[A => scala.Seq[String], Option[A => String]])
    extends ScopedUnary[A, Nothing] {
    override def setup(label: Int): instructions.Instr = new instructions.PushHandlerAndState(label, saveHints = true, hideHints = true)
    override def instr: instructions.Instr = instructions.MakeVerifiedError(msggen)
    override def instrNeedsLabel: Boolean = false
    override def handlerLabel(state: CodeGenState): Int = state.getLabel(instructions.NoVerifiedError)

    // $COVERAGE-OFF$
    final override def pretty(p: String): String = s"verifiedError($p)"
    // $COVERAGE-ON$
}

private [backend] object ErrorLabel {
    def apply[A](p: StrictParsley[A], label: String): ErrorLabel[A] = new ErrorLabel(p, label)
    def unapply[A](self: ErrorLabel[A]): Some[(StrictParsley[A], String)] = Some((self.p, self.label))
}
private [backend] object ErrorExplain {
    def apply[A](p: StrictParsley[A], reason: String): ErrorExplain[A] = new ErrorExplain(p, reason)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy