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

parsley.internal.deepembedding.GeneralisedEmbedding.scala Maven / Gradle / Ivy

The newest version!
package parsley.internal.deepembedding

import ContOps.{result, ContAdapter}
import parsley.internal.machine.instructions

import scala.language.higherKinds

// Core Embedding
private [parsley] abstract class Singleton[A](pretty: String, instr: =>instructions.Instr) extends Parsley[A] {
    final override def findLetsAux[Cont[_, +_], R]
        (implicit ops: ContOps[Cont, R], seen: Set[Parsley[_]], state: LetFinderState): Cont[R, Unit] = result(())
    final override def preprocess[Cont[_, +_], R, A_ >: A](implicit ops: ContOps[Cont, R], seen: Set[Parsley[_]],
                                                                    lets: LetMap, recs: RecMap): Cont[R, Parsley[A_]] = result(this)
    final override def codeGen[Cont[_, +_], R](implicit ops: ContOps[Cont, R], instrs: InstrBuffer, state: CodeGenState): Cont[R, Unit] = {
        result(instrs += instr)
    }
    // $COVERAGE-OFF$
    final override def prettyASTAux[Cont[_, +_], R](implicit ops: ContOps[Cont, R]): Cont[R, String] = result(pretty)
    // $COVERAGE-ON$
}

private [deepembedding] abstract class Unary[A, B](__p: =>Parsley[A])(pretty: String => String, empty: =>Unary[A, B]) extends Parsley[B] {
    private lazy val _p = __p
    private [deepembedding] var p: Parsley[A] = _
    protected val childRepeats: Int = 1
    protected val numInstrs: Int
    final override def findLetsAux[Cont[_, +_], R]
        (implicit ops: ContOps[Cont, R], seen: Set[Parsley[_]], state: LetFinderState): Cont[R,Unit] = _p.findLets
    override def preprocess[Cont[_, +_], R, B_ >: B](implicit ops: ContOps[Cont, R], seen: Set[Parsley[_]],
                                                              lets: LetMap, recs: RecMap): Cont[R, Parsley[B_]] =
        for (p <- _p.optimised) yield empty.ready(p)
    private [deepembedding] def ready(p: Parsley[A]): this.type = {
        processed = true
        this.p = p
        size = p.size + numInstrs
        this
    }
    // $COVERAGE-OFF$
    final override def prettyASTAux[Cont[_, +_], R](implicit ops: ContOps[Cont, R]): Cont[R, String] = for (c <- p.prettyASTAux) yield pretty(c)
    // $COVERAGE-ON$
}

private [deepembedding] abstract class ScopedUnary[A, B](_p: =>Parsley[A], name: String, empty: =>ScopedUnary[A, B],
                                                         setup: Int => instructions.Instr, instr: instructions.Instr)
    extends Unary[A, B](_p)(c => s"$name($c)", empty) {
    final override val numInstrs = 2
    final override def codeGen[Cont[_, +_], R](implicit ops: ContOps[Cont, R], instrs: InstrBuffer, state: CodeGenState): Cont[R, Unit] = {
        val handler = state.freshLabel()
        instrs += setup(handler)
        p.codeGen |> {
            instrs += new instructions.Label(handler)
            instrs += instr
        }
    }
}

private [deepembedding] abstract class ScopedUnaryWithState[A, B](_p: =>Parsley[A], name: String, doesNotProduceHints: Boolean,
                                                                  empty: =>ScopedUnary[A, B], instr: instructions.Instr)
    extends ScopedUnary[A, B](_p, name, empty, new instructions.PushHandlerAndState(_, doesNotProduceHints, doesNotProduceHints), instr)

private [deepembedding] abstract class Binary[A, B, C](__left: =>Parsley[A], __right: =>Parsley[B])
                                                      (pretty: (String, String) => String, empty: =>Binary[A, B, C]) extends Parsley[C] {
    private lazy val _left = __left
    private lazy val _right = __right
    private [deepembedding] var left: Parsley[A] = _
    private [deepembedding] var right: Parsley[B] = _
    protected val numInstrs: Int
    protected val leftRepeats: Int = 1
    protected val rightRepeats: Int = 1
    final override def findLetsAux[Cont[_, +_], R]
        (implicit ops: ContOps[Cont, R], seen: Set[Parsley[_]], state: LetFinderState): Cont[R,Unit] = {
        _left.findLets >> _right.findLets
    }
    final override def preprocess[Cont[_, +_], R, C_ >: C](implicit ops: ContOps[Cont, R], seen: Set[Parsley[_]],
                                                                    lets: LetMap, recs: RecMap): Cont[R, Parsley[C_]] =
        for (left <- _left.optimised; right <- _right.optimised) yield {
            empty.ready(left, right)
        }
    private [deepembedding] def ready(left: Parsley[A], right: Parsley[B]): this.type = {
        processed = true
        this.left = left
        this.right = right
        size = leftRepeats * left.size + rightRepeats * right.size + numInstrs
        this
    }
    // $COVERAGE-OFF$
    final override def prettyASTAux[Cont[_, +_], R](implicit ops: ContOps[Cont, R]): Cont[R, String] = {
        for (l <- left.prettyASTAux; r <- right.prettyASTAux) yield pretty(l, r)
    }
    // $COVERAGE-ON$
}

private [deepembedding] abstract class Ternary[A, B, C, D](__first: =>Parsley[A], __second: =>Parsley[B], __third: =>Parsley[C])
                                                          (pretty: (String, String, String) => String, empty: =>Ternary[A, B, C, D]) extends Parsley[D] {
    private lazy val _first: Parsley[A] = __first
    private lazy val _second: Parsley[B] = __second
    private lazy val _third: Parsley[C] = __third
    private [deepembedding] var first: Parsley[A] = _
    private [deepembedding] var second: Parsley[B] = _
    private [deepembedding] var third: Parsley[C] = _
    protected val numInstrs: Int
    final override def findLetsAux[Cont[_, +_], R]
        (implicit ops: ContOps[Cont, R], seen: Set[Parsley[_]], state: LetFinderState): Cont[R, Unit] = {
        _first.findLets >> _second.findLets >> _third.findLets
    }
    final override def preprocess[Cont[_, +_], R, D_ >: D](implicit ops: ContOps[Cont, R], seen: Set[Parsley[_]],
                                                                    lets: LetMap, recs: RecMap): Cont[R, Parsley[D_]] =
        for (first <- _first.optimised; second <- _second.optimised; third <- _third.optimised) yield {
            empty.ready(first, second, third)
        }
    private [deepembedding] def ready(first: Parsley[A], second: Parsley[B], third: Parsley[C]): this.type = {
        processed = true
        this.first = first
        this.second = second
        this.third = third
        size = first.size + second.size + third.size + numInstrs
        this
    }
    // $COVERAGE-OFF$
    final override def prettyASTAux[Cont[_, +_], R](implicit ops: ContOps[Cont, R]): Cont[R, String] =
        for (f <- first.prettyASTAux; s <- second.prettyASTAux; t <- third.prettyASTAux) yield pretty(f, s, t)
    // $COVERAGE-ON$
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy