Enhanced indention support.

This commit is contained in:
Alex Zenla 2023-09-02 19:38:27 -07:00
parent 62ba662a91
commit 04c78c35e0
Signed by: alex
GPG Key ID: C0780728420EBFE5
2 changed files with 58 additions and 21 deletions

View File

@ -1,23 +1,24 @@
package gay.pizza.pork.ast package gay.pizza.pork.ast
import gay.pizza.pork.ast.nodes.* import gay.pizza.pork.ast.nodes.*
import gay.pizza.pork.util.IndentPrinter
import gay.pizza.pork.util.StringEscape import gay.pizza.pork.util.StringEscape
class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> { class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
private var indent = 0 private val out = IndentPrinter(buffer)
private var autoIndentState = false
private fun append(text: String) { private fun append(text: String) {
buffer.append(text) if (autoIndentState) {
out.emitIndent()
autoIndentState = false
}
out.append(text)
} }
private fun appendLine() { private fun appendLine() {
buffer.appendLine() out.appendLine()
} autoIndentState = true
private fun indent() {
repeat(indent) {
append(" ")
}
} }
override fun visitIntLiteral(node: IntLiteral) { override fun visitIntLiteral(node: IntLiteral) {
@ -40,11 +41,17 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> {
override fun visitListLiteral(node: ListLiteral) { override fun visitListLiteral(node: ListLiteral) {
append("[") append("[")
for ((index, item) in node.items.withIndex()) { if (node.items.isNotEmpty()) {
visit(item) out.increaseIndent()
if (index != node.items.size - 1) { appendLine()
append(", ") for ((index, item) in node.items.withIndex()) {
visit(item)
if (index != node.items.size - 1) {
append(",")
}
appendLine()
} }
out.decreaseIndent()
} }
append("]") append("]")
} }
@ -91,18 +98,16 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> {
append(" ") append(" ")
} }
append("in") append("in")
indent++ out.increaseIndent()
for (expression in node.expressions) { for (expression in node.expressions) {
appendLine() appendLine()
indent()
visit(expression) visit(expression)
} }
if (node.expressions.isNotEmpty()) { if (node.expressions.isNotEmpty()) {
appendLine() appendLine()
} }
indent-- out.decreaseIndent()
indent()
append("}") append("}")
} }
@ -120,11 +125,18 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> {
override fun visitIf(node: If) { override fun visitIf(node: If) {
append("if ") append("if ")
visit(node.condition) visit(node.condition)
append(" then ") append(" then")
out.increaseIndent()
appendLine()
visit(node.thenExpression) visit(node.thenExpression)
out.decreaseIndent()
if (node.elseExpression != null) { if (node.elseExpression != null) {
append(" else ") appendLine()
append("else")
out.increaseIndent()
appendLine()
visit(node.elseExpression) visit(node.elseExpression)
out.decreaseIndent()
} }
} }
@ -138,7 +150,7 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> {
override fun visitProgram(node: Program) { override fun visitProgram(node: Program) {
for (expression in node.expressions) { for (expression in node.expressions) {
indent() out.emitIndent()
visit(expression) visit(expression)
appendLine() appendLine()
} }

View File

@ -0,0 +1,25 @@
package gay.pizza.pork.util
class IndentPrinter(
val buffer: StringBuilder = StringBuilder(),
val indent: String = " "
) : Appendable by buffer, CharSequence by buffer {
private var indentLevel: Int = 0
private var indentLevelText: String = ""
fun emitIndent() {
append(indentLevelText)
}
fun increaseIndent() {
indentLevel++
indentLevelText = indent.repeat(indentLevel)
}
fun decreaseIndent() {
indentLevel--
indentLevelText = indent.repeat(indentLevel)
}
override fun toString(): String = buffer.toString()
}