Skip to content

Commit

Permalink
Merge pull request #21 from j-mie6/refactor
Browse files Browse the repository at this point in the history
Fixed specific operator and keyword attempt bug
  • Loading branch information
j-mie6 authored Dec 31, 2020
2 parents 30eded5 + 257dfbb commit 3934d87
Show file tree
Hide file tree
Showing 10 changed files with 653 additions and 1,160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ private [parsley] final class CharTok(private [CharTok] val c: Char, val expecte
extends SingletonExpect[Char](s"char($c)", new CharTok(c, _), instructions.CharTok(c, expected))

private [parsley] final class StringTok(private [StringTok] val s: String, val expected: UnsafeOption[String] = null)
extends SingletonExpect[String](s"string($s)", new StringTok(s, _), new instructions.StringTok(s, expected)) {
extends SingletonExpect[String](s"string($s)", new StringTok(s, _), instructions.StringTok(s, expected)) {
override def optimise: Parsley[String] = s match {
case "" => new Pure("")
case _ => this
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ private [parsley] final class <*>[A, B](_pf: =>Parsley[A => B], _px: =>Parsley[A
// pure f <*> p = f <$> p
case Pure(f) => right match {
case ct@CharTok(c) => result(instrs += instructions.CharTokFastPerform[Char, B](c, f.asInstanceOf[Char => B], ct.expected))
case st@StringTok(s) => result(instrs += new instructions.StringTokFastPerform(s, f.asInstanceOf[String => B], st.expected))
case st@StringTok(s) => result(instrs += instructions.StringTokFastPerform(s, f.asInstanceOf[String => B], st.expected))
case _ =>
right.codeGen |>
(instrs += new instructions.Perform(f))
Expand Down Expand Up @@ -131,7 +131,7 @@ private [deepembedding] sealed abstract class Seq[A, B](_discard: =>Parsley[A],
final protected def codeGenSeq[Cont[_, +_]: ContOps](default: =>Cont[Unit, Unit])(implicit instrs: InstrBuffer,
state: CodeGenState): Cont[Unit, Unit] = (result, discard) match {
case (Pure(x), ct@CharTok(c)) => ContOps.result(instrs += instructions.CharTokFastPerform[Char, B](c, _ => x, ct.expected))
case (Pure(x), st@StringTok(s)) => ContOps.result(instrs += new instructions.StringTokFastPerform(s, _ => x, st.expected))
case (Pure(x), st@StringTok(s)) => ContOps.result(instrs += instructions.StringTokFastPerform(s, _ => x, st.expected))
case (Pure(x), st@Satisfy(f)) => ContOps.result(instrs += new instructions.SatisfyExchange(f, x, st.expected))
case (Pure(x), v) =>
v.codeGen |>
Expand Down
41 changes: 33 additions & 8 deletions src/main/scala/parsley/internal/instructions/Context.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Stack.{drop, isEmpty, mkString, map, push}
import parsley.{Failure, Result, Success}
import parsley.internal.UnsafeOption

import scala.annotation.tailrec
import scala.annotation.{tailrec, switch}

// Private internals
private [instructions] final class Frame(val ret: Int, val instrs: Array[Instr]) {
Expand Down Expand Up @@ -75,14 +75,12 @@ final class Context private [parsley] (private [instructions] var instrs: Array[
@tailrec @inline private [parsley] def runParser[A](): Result[A] = {
//println(this)
if (status eq Failed) Failure(errorMessage)
else if (pc < instrs.length)
{
else if (pc < instrs.length) {
instrs(pc)(this)
runParser[A]()
}
else if (isEmpty(calls)) Success(stack.peek[A])
else
{
else {
ret()
runParser[A]()
}
Expand All @@ -100,8 +98,7 @@ final class Context private [parsley] (private [instructions] var instrs: Array[
instrs = newInstrs
pc = at
depth += 1
if (expected != null && errorOverride == null)
{
if (expected != null && errorOverride == null) {
overrideDepth = depth
errorOverride = expected
}
Expand All @@ -116,6 +113,15 @@ final class Context private [parsley] (private [instructions] var instrs: Array[
adjustErrorOverride()
}

private [instructions] def catchNoConsumed(handler: =>Unit): Unit = {
if (offset != checkStack.head) fail()
else {
status = Good
handler
}
checkStack = checkStack.tail
}

private def adjustErrors(e: UnsafeOption[String]): Unit = {
if (offset > erroffset) {
erroffset = offset
Expand All @@ -130,7 +136,11 @@ final class Context private [parsley] (private [instructions] var instrs: Array[
adjustErrorOverride()
}

private [instructions] def fail(expected: UnsafeOption[String], unexpected: String): Unit = {
private [instructions] def failWithMessage(expected: UnsafeOption[String], msg: String): Unit = {
this.fail(expected)
this.raw ::= msg
}
private [instructions] def unexpectedFail(expected: UnsafeOption[String], unexpected: String): Unit = {
this.fail(expected)
this.unexpected = unexpected
this.unexpectAnyway = true
Expand Down Expand Up @@ -187,6 +197,21 @@ final class Context private [parsley] (private [instructions] var instrs: Array[
private [instructions] def inc(): Unit = pc += 1
private [instructions] def nextChar: Char = input(offset)
private [instructions] def moreInput: Boolean = offset < inputsz
private [instructions] def updatePos(c: Char) = (c: @switch) match {
case '\n' => line += 1; col = 1
case '\t' => col += 4 - ((col - 1) & 3)
case _ => col += 1
}
private [instructions] def consumeChar(): Char = {
val c = nextChar
updatePos(c)
offset += 1
c
}
private [instructions] def fastUncheckedConsumeChars(n: Int) = {
offset += n
col += n
}
private [instructions] def pushHandler(label: Int): Unit = handlers = push(handlers, new Handler(depth, label, stack.usize))
private [instructions] def pushCheck(): Unit = checkStack = push(checkStack, offset)
private [instructions] def saveState(): Unit = states = push(states, new State(offset, line, col, regs))
Expand Down
Loading

0 comments on commit 3934d87

Please sign in to comment.