Skip to content

Commit

Permalink
feat(debug): reworked ConsolePrettyPrinter with new methods
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mie6 committed Dec 28, 2024
1 parent d228dc1 commit 62b03c8
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@
*/
package parsley.debugger.frontend

import parsley.debugger.DebugTree
import parsley.debugger.frontend.internal.consolepretty.*
import java.io.{OutputStream, PrintStream}

private [frontend] sealed class ConsolePrettyPrinterImpl private[frontend] (ioF: String => Unit) extends ReusableFrontend {
override private [debugger] def process(input: => String, tree: => DebugTree): Unit = {
ioF(s"${tree.parserName}'s parse tree for input:\n\n$input\n\n")
ioF(tree.pretty + "\n")
}
}
import scala.annotation.tailrec

import parsley.debugger.{DebugTree, ParseAttempt}

/** A console pretty-printer for the debugger.
*
Expand All @@ -22,10 +18,60 @@ private [frontend] sealed class ConsolePrettyPrinterImpl private[frontend] (ioF:
*
* @since 5.0.0
*/
object ConsolePrettyPrinter extends ConsolePrettyPrinterImpl(println(_)) {
/** Create a string pretty-printer that takes an arbitrary impure string function.
object ConsolePrettyPrinter extends ConsolePrettyPrinter(Console.out) {
/** Create a string pretty-printer that outputs to an arbitrary place
*
* @since 5.0.0
*/
def apply(ioF: String => Unit): ReusableFrontend = new ConsolePrettyPrinterImpl(ioF)
def apply(out: OutputStream): ReusableFrontend = apply(new PrintStream(out))
/** Create a string pretty-printer that outputs to an arbitrary place
*
* @since 5.0.0
*/
def apply(out: PrintStream): ReusableFrontend = new ConsolePrettyPrinter(out)
}

private [frontend] sealed class ConsolePrettyPrinter private[frontend] (out: PrintStream) extends ReusableFrontend {
override private [debugger] def process(input: => String, tree: => DebugTree): Unit = {
out.println(s"${tree.parserName}'s parse tree for input:\n\n$input\n\n")
pretty(tree)
}

private def bury(str: String, withMark: Boolean, indents: Vector[String]): Unit = out.println {
if (indents.isEmpty) str
else if (withMark) s"${indents.init.mkString}+-$str"
else s"${indents.mkString}$str"
}

private def pretty(dt: DebugTree): Unit = pretty(dt, Vector.empty)

private def pretty(dt: DebugTree, indents: Vector[String]): Unit = {
val uname =
if (dt.parserName != dt.internalName)
s"${dt.parserName} (${dt.internalName}${if (dt.childNumber.isDefined) s" (${dt.childNumber.get})" else ""})"
else
s"${dt.internalName}${if (dt.childNumber.isDefined) s" (${dt.childNumber.get})" else ""}"
val results = dt.parseResults.map(printParseAttempt).mkString

bury(s"[ $uname ]: $results", withMark = true, indents)
printChildren(dt, indents, dt.nodeChildren.toList)
}

// Print a parse attempt in a human-readable way.
private def printParseAttempt(attempt: ParseAttempt): String = {
val status = if (attempt.success) s"Success - [ ${attempt.result.get} ]" else "Failure"
s"""(\"${attempt.rawInput}\" [${attempt.fromPos} -> ${attempt.toPos}], $status)"""
}

// Print all the children, remembering to add a blank indent for the last child.
@tailrec private def printChildren(dt: DebugTree, indents: Vector[String], children: List[(String, DebugTree)]): Unit = children match {
case List((_, t)) =>
bury("|", withMark = false, indents)
pretty(t, indents :+ " ")
case (_, t) :: xs =>
bury("|", withMark = false, indents)
pretty(t, indents :+ "| ")
printChildren(dt, indents, xs)
case Nil =>
}
}

This file was deleted.

0 comments on commit 62b03c8

Please sign in to comment.