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

parsley.internal.machine.instructions.TokenNumericInstrs.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2020 Parsley Contributors 
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package parsley.internal.machine.instructions

import parsley.token.descriptions.numeric.PlusSignPresence

import parsley.internal.deepembedding.Sign.{CombinedType, DoubleType, IntType, SignType}
import parsley.internal.errors.{ExpectItem, ExpectRaw}
import parsley.internal.machine.Context
import parsley.internal.machine.XAssert._
import parsley.internal.machine.errors.ExpectedError

private [internal] final class TokenSign(ty: SignType, plusPresence: PlusSignPresence) extends Instr {
    val neg: Any => Any = ty match {
        case IntType => ((x: IntType.resultType) => -x).asInstanceOf[Any => Any]
        case DoubleType => ((x: DoubleType.resultType) => -x).asInstanceOf[Any => Any]
        case CombinedType => ((x: CombinedType.resultType) => x.fold(n => Left(-n), n => Right(-n))).asInstanceOf[Any => Any]
    }
    val pos = (x: Any) => x

    private [this] val expecteds: Set[ExpectItem] =
        if (plusPresence ne PlusSignPresence.Illegal) Set(new ExpectRaw("+"), new ExpectRaw("-"))
        else                                          Set(new ExpectRaw("-"))

    override def apply(ctx: Context): Unit = {
        ensureRegularInstruction(ctx)
        // This could be simplified, but the "fail" branches need to be duplicated...
        if (ctx.moreInput && ctx.peekChar == '-') {
            ctx.fastUncheckedConsumeChars(1)
            ctx.pushAndContinue(neg)
        }
        else if ((plusPresence ne PlusSignPresence.Illegal) && ctx.moreInput && ctx.peekChar == '+') {
            ctx.fastUncheckedConsumeChars(1)
            ctx.pushAndContinue(pos)
        }
        else if (plusPresence eq PlusSignPresence.Required) {
            ctx.fail(new ExpectedError(ctx.offset, ctx.line, ctx.col, expecteds, 1))
        }
        else {
            ctx.pushError(new ExpectedError(ctx.offset, ctx.line, ctx.col, expecteds, 1))
            ctx.addErrorToHintsAndPop()
            ctx.pushAndContinue(pos)
        }
    }

    // $COVERAGE-OFF$
    override def toString: String = "TokenSign"
    // $COVERAGE-ON$
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy