-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPrinter.scala
52 lines (46 loc) · 1.96 KB
/
Printer.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import scala.collection.mutable.StringBuilder
import fansi.*
object Printer {
def print(ast: AST, useColor: UseColor): String = {
def loop(ast: AST)(using IdentLevel, Depth)(using StringBuilder, UseColor): StringBuilder =
ast match {
case AST.Node(name, span, values) =>
val color = Colorful.Hue(Depth.current)
val openParen = Colorful(plainOpenParen, color, Bold.On)
val closeParen = Colorful(plainCloseParen, color, Bold.On)
if (span.length >= 80) {
append(ident, name, openParen)
values.zipWithIndex.foreach { (ast, idx) =>
append(newline)
loop(ast)(using IdentLevel.current + 1, Depth.current + 1)
appendWhen(idx < values.size - 1)(", ")
}
append(newline, ident, closeParen)
} else {
append(ident, name, openParen)
values.zipWithIndex.foreach { (ast, idx) =>
loop(ast)(using IdentLevel.zero, Depth.current + 1)
appendWhen(idx < values.size - 1)(", ")
}
append(closeParen)
}
case AST.Singleton(name) => append(ident, Colorful(name, Color.LightRed))
case AST.Text(value) => append(ident, Colorful(s""""$value"""", Color.Green))
case AST.Number(value) => append(ident, Colorful(value, Color.LightMagenta))
}
loop(ast)(using IdentLevel.zero, Depth.zero)(using StringBuilder(), useColor).result()
}
private val newline = System.lineSeparator()
private val plainOpenParen = "("
private val plainCloseParen = ")"
private def ident(using level: IdentLevel) = " " * level.value
private def append(values: String | Char*)(using acc: StringBuilder) = {
values.foreach {
case str: String => acc.append(str)
case char: Char => acc.append(char)
}
acc
}
private def appendWhen(cond: Boolean)(values: String | Char*)(using acc: StringBuilder) =
if (cond) append(values*) else acc
}