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

parsley.internal.machine.errors.DefuncHints.scala Maven / Gradle / Ivy

The newest version!
package parsley.internal.machine.errors

import parsley.internal.errors.{ErrorItem, Desc}

import scala.collection.mutable
import scala.annotation.tailrec

private [machine] sealed abstract class DefuncHints(private [errors] val size: Int) {
    private var incorporatedAfter: Int = size
    private [errors] def nonEmpty: Boolean = size != 0
    private [errors] def isEmpty: Boolean = size == 0
    private [machine] def toExpectedsAndSize: (Set[ErrorItem], Int) = {
        implicit val state: HintState = new HintState
        collect(0)
        (state.mkSet, state.unexpectSize)
    }
    private [machine] def toSet: Set[ErrorItem] = toExpectedsAndSize._1
    @tailrec final private [errors] def collect(skipNext: Int)(implicit state: HintState): Unit = if (skipNext < incorporatedAfter) {
        // This error only needs to provide the first `skipNext` elements if we encounter it again
        incorporatedAfter = skipNext
        this match {
            case EmptyHints =>
            case self: PopHints => self.hints.collect(skipNext + 1)
            case self: ReplaceHint =>
                if (skipNext > 0) self.hints.collect(skipNext)
                else {
                    state += Desc(self.label)
                    self.hints.collect(skipNext+1)
                }
            case self: MergeHints =>
                if (self.oldHints.size < skipNext) self.newHints.collect(skipNext - self.oldHints.size)
                else {
                    self.oldHints.collectNonTail(skipNext)
                    self.newHints.collect(0)
                }
            case self: AddError =>
                if (skipNext - self.hints.size <= 0) self.err.collectHints()
                self.hints.collect(skipNext)
        }
    }
    final private def collectNonTail(skipNext: Int)(implicit state: HintState): Unit = collect(skipNext)
}

private [machine] case object EmptyHints extends DefuncHints(size = 0)

private [machine] case class PopHints private (hints: DefuncHints) extends DefuncHints(size = hints.size - 1)
private [machine] object PopHints {
    def apply(hints: DefuncHints): DefuncHints = if (hints.size > 1) new PopHints(hints) else EmptyHints
}

private [errors] case class ReplaceHint private (label: String, hints: DefuncHints) extends DefuncHints(size = hints.size)
private [machine] object ReplaceHint {
    def apply(label: String, hints: DefuncHints): DefuncHints = if (hints.nonEmpty) new ReplaceHint(label, hints) else hints
}

private [errors] case class MergeHints private (oldHints: DefuncHints, newHints: DefuncHints) extends DefuncHints(size = oldHints.size + newHints.size)
private [machine] object MergeHints {
    def apply(oldHints: DefuncHints, newHints: DefuncHints): DefuncHints = {
        if (oldHints.isEmpty) newHints
        else if (newHints.isEmpty) oldHints
        else new MergeHints(oldHints, newHints)
    }
}

private [machine] case class AddError(hints: DefuncHints, err: DefuncError) extends DefuncHints(size = hints.size + 1)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy