From 04c78c35e009bc134eaae08007dedb94c6ab23ef Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Sat, 2 Sep 2023 19:38:27 -0700 Subject: [PATCH] Enhanced indention support. --- src/main/kotlin/gay/pizza/pork/ast/Printer.kt | 54 +++++++++++-------- .../gay/pizza/pork/util/IndentPrinter.kt | 25 +++++++++ 2 files changed, 58 insertions(+), 21 deletions(-) create mode 100644 src/main/kotlin/gay/pizza/pork/util/IndentPrinter.kt diff --git a/src/main/kotlin/gay/pizza/pork/ast/Printer.kt b/src/main/kotlin/gay/pizza/pork/ast/Printer.kt index 435ba53..cd74d99 100644 --- a/src/main/kotlin/gay/pizza/pork/ast/Printer.kt +++ b/src/main/kotlin/gay/pizza/pork/ast/Printer.kt @@ -1,23 +1,24 @@ package gay.pizza.pork.ast import gay.pizza.pork.ast.nodes.* +import gay.pizza.pork.util.IndentPrinter import gay.pizza.pork.util.StringEscape -class Printer(private val buffer: StringBuilder) : NodeVisitor { - private var indent = 0 +class Printer(buffer: StringBuilder) : NodeVisitor { + private val out = IndentPrinter(buffer) + private var autoIndentState = false private fun append(text: String) { - buffer.append(text) + if (autoIndentState) { + out.emitIndent() + autoIndentState = false + } + out.append(text) } private fun appendLine() { - buffer.appendLine() - } - - private fun indent() { - repeat(indent) { - append(" ") - } + out.appendLine() + autoIndentState = true } override fun visitIntLiteral(node: IntLiteral) { @@ -40,11 +41,17 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor { override fun visitListLiteral(node: ListLiteral) { append("[") - for ((index, item) in node.items.withIndex()) { - visit(item) - if (index != node.items.size - 1) { - append(", ") + if (node.items.isNotEmpty()) { + out.increaseIndent() + appendLine() + for ((index, item) in node.items.withIndex()) { + visit(item) + if (index != node.items.size - 1) { + append(",") + } + appendLine() } + out.decreaseIndent() } append("]") } @@ -91,18 +98,16 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor { append(" ") } append("in") - indent++ + out.increaseIndent() for (expression in node.expressions) { appendLine() - indent() visit(expression) } if (node.expressions.isNotEmpty()) { appendLine() } - indent-- - indent() + out.decreaseIndent() append("}") } @@ -120,11 +125,18 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor { override fun visitIf(node: If) { append("if ") visit(node.condition) - append(" then ") + append(" then") + out.increaseIndent() + appendLine() visit(node.thenExpression) + out.decreaseIndent() if (node.elseExpression != null) { - append(" else ") + appendLine() + append("else") + out.increaseIndent() + appendLine() visit(node.elseExpression) + out.decreaseIndent() } } @@ -138,7 +150,7 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor { override fun visitProgram(node: Program) { for (expression in node.expressions) { - indent() + out.emitIndent() visit(expression) appendLine() } diff --git a/src/main/kotlin/gay/pizza/pork/util/IndentPrinter.kt b/src/main/kotlin/gay/pizza/pork/util/IndentPrinter.kt new file mode 100644 index 0000000..21ee2cd --- /dev/null +++ b/src/main/kotlin/gay/pizza/pork/util/IndentPrinter.kt @@ -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() +}