Skip to content

Instantly share code, notes, and snippets.

@jamiebuilds
Last active January 7, 2020 00:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamiebuilds/86eb0b64bd4a18950307211cf8297fb0 to your computer and use it in GitHub Desktop.
Save jamiebuilds/86eb0b64bd4a18950307211cf8297fb0 to your computer and use it in GitHub Desktop.
let INDENT = { op: "indent" }
let OUTDENT = { op: "outdent" }
let NEWLINE = { op: "newline" }
let SPACE = { op: "space" }
function* printNode(node) {
if (node.type === "Program") {
for (let item of node.body) {
yield* printNode(item)
yield NEWLINE
}
} else if (node.type === 'Block') {
yield "{"
yield INDENT
for (let item of node.body) {
yield NEWLINE
yield* printNode(item)
}
yield OUTDENT
yield NEWLINE
yield "}"
} else if (node.type === 'ExpressionStatement') {
yield* printNode(node.expression)
yield ";"
} else if (node.type === 'BinaryExpression') {
yield* printNode(node.left)
yield SPACE
yield String(node.operator)
yield SPACE
yield* printNode(node.right)
} else if (node.type === 'Identifier') {
yield String(node.name)
} else {
throw new Error(`Unknown AST node type: ${node.type}`)
}
}
function print(ast, min = false) {
let res = ''
let indentation = 0
for (let item of printNode(ast)) {
if (item === OUTDENT) {
indentation = indentation - 1
} else if (item === INDENT) {
indentation = indentation + 1
} else if (item === NEWLINE) {
if (!min) {
res += "\n"
res += "\t".repeat(indentation)
}
} else if (item === SPACE) {
if (!min) {
res += " "
}
} else if (typeof item === "string") {
res += item
} else {
throw new Error("Unexpected yielded item")
}
}
return res
}
print({
type: "Block",
body: [
{
type: "ExpressionStatement",
expression: {
type: "BinaryExpression",
operator: "+",
left: { type: "Identifier", name: "a" },
right: { type: "Identifier", name: "b" }
}
}
]
}, false)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment