Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions src/prettyPrinter/PrettyPrinter.cj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cjcj.prettyPrinter

public class PrettyPrinter {
public PrettyPrinter(let tabSize!: Int64 = 4) {}
private var indentation: Int64 = 0
private let builder: StringBuilder = StringBuilder()

Expand All @@ -13,13 +14,10 @@ public class PrettyPrinter {
}

public func append(val: String): Unit {
val.runes().forEach(
{
r =>
builder.append(r)
if (r == r"\n") {
builder.append(StringBuilder(r' ', 4 * indentation))
}
val.runes().forEach({
r => builder.append(r)
if (r == r"\n") {
builder.append(StringBuilder(r' ', tabSize * indentation))
}
)
}
Expand Down
110 changes: 110 additions & 0 deletions src/prettyPrinter/YamlPrinter.cj
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package cjcj.prettyPrinter

import cjcj.scanner.{Token, TokenKind}
import std.ast.Position

public interface YamlPrintable {
func yamlPrint(printer: YamlPrinter): Unit
}

public class YamlPrinter {
private var indentation: Int64 = 0
private let printer: PrettyPrinter = PrettyPrinter(tabSize: 2)
private var atObjectStart: Bool = true
private var atListItemStart: Bool = false

private func printlnIfNeeded(): Unit {
if (atObjectStart) {
atObjectStart = false
if (atListItemStart) {
atListItemStart = false
printer.indent()
}
} else {
printer.append("\n")
}
}

public func printObject(key: String, obj: YamlPrintable): Unit {
printlnIfNeeded()
printer.append(key + ":")
printer.indent()
printer.append("\n")
atObjectStart = true
obj.yamlPrint(this)
atObjectStart = false
printer.unindent()
}

public func printOptionalObject<T>(key: String, obj: ?T): Unit where T <: YamlPrintable {
if (let Some(o) <- obj) {
printObject(key, o)
} else {
printlnIfNeeded()
printer.append(key + ": null")
}
}

public func printList<T>(key: String, objs: Iterable<T>): Unit where T <: YamlPrintable {
printlnIfNeeded()
if (objs.iterator().isEmpty()) {
printer.append(key + ": []")
return
}
printer.append(key + ":")
objs.iterator().forEach(
{
o =>
printer.append("\n- ")
atObjectStart = true
atListItemStart = true
o.yamlPrint(this)
if (atListItemStart) {
printer.append("{}")
atListItemStart = false
} else {
printer.unindent()
}
atObjectStart = false
}
)
}

public func print(key: String, token: Token): Unit {
print(key, token.value)
printPosition(token.pos)
}

public func print(key: String, value: ToString, enforceQuoting!: Bool = false): Unit {
let valueString = value.toString()
let formattedValue = if (!enforceQuoting && valueString.runes().all({r => r.isAsciiNumberOrLetter()})) {
valueString
} else if (valueString.contains("\n") || valueString.contains("\t") || valueString.contains("'")) {
'\"${valueString.replace("\\", "\\\\").replace("\n", "\\n").replace("\t", "\\t").replace('"', '\\"')}\"'
} else {
"'${valueString}'"
}
printRaw(key, formattedValue)
}

public func printLiteral(key: String, literal: Token): Unit {
match (literal.kind) {
case TokenKind.STRING_LITERAL => print(key, literal.value, enforceQuoting: true)
case _ => print(key, literal.value)
}
printPosition(literal.pos)
}

private func printRaw(key: String, rawValue: String): Unit {
printlnIfNeeded()
printer.append("${key}: ${rawValue}")
}

private func printPosition(pos: Position): Unit {
printer.append(" # Position: ${pos.line}:${pos.column}")
}

public func toString(): String {
printer.toString()
}
}
53 changes: 52 additions & 1 deletion src/visitor/Decls.cj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package cjcj.visitor

import cjcj.prettyPrinter.PrettyPrinter
import cjcj.prettyPrinter.{PrettyPrinter, YamlPrinter}
import cjcj.scanner.Token
import cjcj.scanner.TokenKind
import std.collection.ArrayList
Expand Down Expand Up @@ -87,6 +87,16 @@ public abstract class Decl <: Node & Equatable<Decl> {
}
}

public open override func yamlPrint(printer: YamlPrinter): Unit {
if (keyword.kind != TokenKind.ILLEGAL) {
printer.print("keyword", keyword)
}
if (keyword.kind != TokenKind.ILLEGAL) {
printer.print("identifier", identifier)
}
printer.printOptionalObject("declType", declType)
}

public override operator func ==(other: Decl) {
id == other.id
}
Expand Down Expand Up @@ -140,6 +150,12 @@ public open class VarDecl <: Decl {
ini.prettyPrint(printer)
}
}

public override func yamlPrint(printer: YamlPrinter): Unit {
printer.print("type", "VarDecl")
super.yamlPrint(printer)
printer.printOptionalObject("initializer", initializer)
}
}

public open class MainDecl <: Decl {
Expand Down Expand Up @@ -177,6 +193,13 @@ public open class MainDecl <: Decl {
block_.prettyPrint(printer)
}

public override func yamlPrint(printer: YamlPrinter): Unit {
printer.print("type", "MainDecl")
super.yamlPrint(printer)
printer.printOptionalObject("param", param)
printer.printObject("block", block)
}

public mut prop block: Block {
get() {
block_
Expand Down Expand Up @@ -222,6 +245,13 @@ public class FuncParam <: Decl {
paramType.prettyPrint(printer)
}

public override func yamlPrint(printer: YamlPrinter): Unit {
printer.print("type", "FuncParam")
super.yamlPrint(printer)
printer.print("name", name)
printer.printObject("paramType", paramType)
}

public mut prop paramType: TypeNode {
get() {
paramType_
Expand Down Expand Up @@ -287,6 +317,13 @@ public open class FuncDecl <: Decl {
}
}

public override func yamlPrint(printer: YamlPrinter): Unit {
printer.print("type", "FuncDecl")
super.yamlPrint(printer)
printer.printList("params", params)
printer.printOptionalObject("block", block)
}

public mut prop block: ?Block {
get() {
block_
Expand Down Expand Up @@ -331,6 +368,13 @@ public open class ClassDecl <: Decl {
body.prettyPrint(printer)
}

public override func yamlPrint(printer: YamlPrinter): Unit {
printer.print("type", "ClassDecl")
super.yamlPrint(printer)
printer.printList("superTypes", superTypes)
printer.printObject("body", body)
}

public open override func traverse<R>(v: Visitor<R>): R {
v.visit(this)
}
Expand Down Expand Up @@ -374,6 +418,13 @@ public open class InterfaceDecl <: Decl {
body.prettyPrint(printer)
}

public override func yamlPrint(printer: YamlPrinter): Unit {
printer.print("type", "InterfaceDecl")
super.yamlPrint(printer)
printer.printList("superTypes", superTypes)
printer.printObject("body", body)
}

public open override func traverse<R>(v: Visitor<R>): R {
v.visit(this)
}
Expand Down
Loading