mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-03 05:10:55 +00:00
Define node visitor order based on parsing order.
This commit is contained in:
parent
900e3f1a1c
commit
941b201549
@ -3,11 +3,11 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||||||
plugins {
|
plugins {
|
||||||
application
|
application
|
||||||
|
|
||||||
kotlin("jvm") version "1.9.0"
|
kotlin("jvm") version "1.9.10"
|
||||||
kotlin("plugin.serialization") version "1.9.0"
|
kotlin("plugin.serialization") version "1.9.10"
|
||||||
|
|
||||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||||
id("org.graalvm.buildtools.native") version "0.9.23"
|
id("org.graalvm.buildtools.native") version "0.9.25"
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@ -22,9 +22,8 @@ java {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.jetbrains.kotlin:kotlin-bom")
|
implementation("org.jetbrains.kotlin:kotlin-bom")
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
|
||||||
implementation("com.github.ajalt.clikt:clikt:4.2.0")
|
implementation("com.github.ajalt.clikt:clikt:4.2.0")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0-RC")
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
tasks.withType<KotlinCompile> {
|
||||||
|
@ -3,18 +3,18 @@ package gay.pizza.pork.ast
|
|||||||
import gay.pizza.pork.ast.nodes.*
|
import gay.pizza.pork.ast.nodes.*
|
||||||
|
|
||||||
class NodeCoalescer(val handler: (Node) -> Unit) : NodeVisitor<Unit> {
|
class NodeCoalescer(val handler: (Node) -> Unit) : NodeVisitor<Unit> {
|
||||||
override fun visitDefine(node: Define) = handler(node)
|
override fun visitIntLiteral(node: IntLiteral): Unit = handler(node)
|
||||||
override fun visitFunctionCall(node: FunctionCall) = handler(node)
|
override fun visitStringLiteral(node: StringLiteral): Unit = handler(node)
|
||||||
override fun visitReference(node: SymbolReference) = handler(node)
|
override fun visitBooleanLiteral(node: BooleanLiteral): Unit = handler(node)
|
||||||
override fun visitIf(node: If) = handler(node)
|
override fun visitListLiteral(node: ListLiteral): Unit = handler(node)
|
||||||
override fun visitSymbol(node: Symbol) = handler(node)
|
override fun visitSymbol(node: Symbol): Unit = handler(node)
|
||||||
override fun visitLambda(node: Lambda) = handler(node)
|
override fun visitFunctionCall(node: FunctionCall): Unit = handler(node)
|
||||||
override fun visitIntLiteral(node: IntLiteral) = handler(node)
|
override fun visitDefine(node: Define): Unit = handler(node)
|
||||||
override fun visitBooleanLiteral(node: BooleanLiteral) = handler(node)
|
override fun visitSymbolReference(node: SymbolReference): Unit = handler(node)
|
||||||
override fun visitListLiteral(node: ListLiteral) = handler(node)
|
override fun visitLambda(node: Lambda): Unit = handler(node)
|
||||||
override fun visitStringLiteral(node: StringLiteral) = handler(node)
|
override fun visitParentheses(node: Parentheses): Unit = handler(node)
|
||||||
override fun visitParentheses(node: Parentheses) = handler(node)
|
override fun visitPrefixOperation(node: PrefixOperation): Unit = handler(node)
|
||||||
override fun visitPrefixOperation(node: PrefixOperation) = handler(node)
|
override fun visitIf(node: If): Unit = handler(node)
|
||||||
override fun visitInfixOperation(node: InfixOperation) = handler(node)
|
override fun visitInfixOperation(node: InfixOperation): Unit = handler(node)
|
||||||
override fun visitProgram(node: Program) = handler(node)
|
override fun visitProgram(node: Program): Unit = handler(node)
|
||||||
}
|
}
|
||||||
|
@ -3,47 +3,44 @@ package gay.pizza.pork.ast
|
|||||||
import gay.pizza.pork.ast.nodes.*
|
import gay.pizza.pork.ast.nodes.*
|
||||||
|
|
||||||
interface NodeVisitor<T> {
|
interface NodeVisitor<T> {
|
||||||
fun visitDefine(node: Define): T
|
|
||||||
fun visitFunctionCall(node: FunctionCall): T
|
|
||||||
fun visitReference(node: SymbolReference): T
|
|
||||||
fun visitIf(node: If): T
|
|
||||||
fun visitSymbol(node: Symbol): T
|
|
||||||
fun visitLambda(node: Lambda): T
|
|
||||||
|
|
||||||
fun visitIntLiteral(node: IntLiteral): T
|
fun visitIntLiteral(node: IntLiteral): T
|
||||||
|
fun visitStringLiteral(node: StringLiteral): T
|
||||||
fun visitBooleanLiteral(node: BooleanLiteral): T
|
fun visitBooleanLiteral(node: BooleanLiteral): T
|
||||||
fun visitListLiteral(node: ListLiteral): T
|
fun visitListLiteral(node: ListLiteral): T
|
||||||
fun visitStringLiteral(node: StringLiteral): T
|
fun visitSymbol(node: Symbol): T
|
||||||
|
fun visitFunctionCall(node: FunctionCall): T
|
||||||
|
fun visitDefine(node: Define): T
|
||||||
|
fun visitSymbolReference(node: SymbolReference): T
|
||||||
|
fun visitLambda(node: Lambda): T
|
||||||
fun visitParentheses(node: Parentheses): T
|
fun visitParentheses(node: Parentheses): T
|
||||||
fun visitPrefixOperation(node: PrefixOperation): T
|
fun visitPrefixOperation(node: PrefixOperation): T
|
||||||
|
fun visitIf(node: If): T
|
||||||
fun visitInfixOperation(node: InfixOperation): T
|
fun visitInfixOperation(node: InfixOperation): T
|
||||||
|
|
||||||
fun visitProgram(node: Program): T
|
fun visitProgram(node: Program): T
|
||||||
|
|
||||||
fun visitExpression(node: Expression): T = when (node) {
|
fun visitExpression(node: Expression): T = when (node) {
|
||||||
is IntLiteral -> visitIntLiteral(node)
|
is IntLiteral -> visitIntLiteral(node)
|
||||||
|
is StringLiteral -> visitStringLiteral(node)
|
||||||
is BooleanLiteral -> visitBooleanLiteral(node)
|
is BooleanLiteral -> visitBooleanLiteral(node)
|
||||||
is ListLiteral -> visitListLiteral(node)
|
is ListLiteral -> visitListLiteral(node)
|
||||||
is StringLiteral -> visitStringLiteral(node)
|
|
||||||
is Parentheses -> visitParentheses(node)
|
|
||||||
is InfixOperation -> visitInfixOperation(node)
|
|
||||||
is PrefixOperation -> visitPrefixOperation(node)
|
|
||||||
is Define -> visitDefine(node)
|
|
||||||
is Lambda -> visitLambda(node)
|
|
||||||
is FunctionCall -> visitFunctionCall(node)
|
is FunctionCall -> visitFunctionCall(node)
|
||||||
is SymbolReference -> visitReference(node)
|
is Define -> visitDefine(node)
|
||||||
|
is SymbolReference -> visitSymbolReference(node)
|
||||||
|
is Lambda -> visitLambda(node)
|
||||||
|
is Parentheses -> visitParentheses(node)
|
||||||
|
is PrefixOperation -> visitPrefixOperation(node)
|
||||||
is If -> visitIf(node)
|
is If -> visitIf(node)
|
||||||
|
is InfixOperation -> visitInfixOperation(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun visit(node: Node): T = when (node) {
|
fun visit(node: Node): T = when (node) {
|
||||||
is Expression -> visitExpression(node)
|
|
||||||
is Symbol -> visitSymbol(node)
|
is Symbol -> visitSymbol(node)
|
||||||
|
is Expression -> visitExpression(node)
|
||||||
is Program -> visitProgram(node)
|
is Program -> visitProgram(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun visitNodes(vararg nodes: Node?): List<T> =
|
fun visitNodes(vararg nodes: Node?): List<T> =
|
||||||
nodes.filterNotNull().map { visit(it) }
|
nodes.asSequence().filterNotNull().map { visit(it) }.toList()
|
||||||
|
|
||||||
fun visitAll(vararg nodeLists: List<Node>): List<T> =
|
fun visitAll(vararg nodeLists: List<Node>): List<T> =
|
||||||
nodeLists.asSequence().flatten().map { visit(it) }.toList()
|
nodeLists.asSequence().flatten().map { visit(it) }.toList()
|
||||||
|
@ -20,10 +20,37 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitDefine(node: Define) {
|
override fun visitIntLiteral(node: IntLiteral) {
|
||||||
visit(node.symbol)
|
append(node.value.toString())
|
||||||
append(" = ")
|
}
|
||||||
visit(node.value)
|
|
||||||
|
override fun visitStringLiteral(node: StringLiteral) {
|
||||||
|
append("\"")
|
||||||
|
append(StringEscape.escape(node.text))
|
||||||
|
append("\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitBooleanLiteral(node: BooleanLiteral) {
|
||||||
|
if (node.value) {
|
||||||
|
append("true")
|
||||||
|
} else {
|
||||||
|
append("false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitListLiteral(node: ListLiteral) {
|
||||||
|
append("[")
|
||||||
|
for ((index, item) in node.items.withIndex()) {
|
||||||
|
visit(item)
|
||||||
|
if (index != node.items.size - 1) {
|
||||||
|
append(", ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
append("]")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSymbol(node: Symbol) {
|
||||||
|
append(node.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionCall(node: FunctionCall) {
|
override fun visitFunctionCall(node: FunctionCall) {
|
||||||
@ -38,24 +65,16 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> {
|
|||||||
append(")")
|
append(")")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitReference(node: SymbolReference) {
|
override fun visitDefine(node: Define) {
|
||||||
|
visit(node.symbol)
|
||||||
|
append(" = ")
|
||||||
|
visit(node.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSymbolReference(node: SymbolReference) {
|
||||||
visit(node.symbol)
|
visit(node.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitIf(node: If) {
|
|
||||||
append("if ")
|
|
||||||
visit(node.condition)
|
|
||||||
append(" then ")
|
|
||||||
visit(node.thenExpression)
|
|
||||||
if (node.elseExpression != null) {
|
|
||||||
append(" else ")
|
|
||||||
visit(node.elseExpression)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSymbol(node: Symbol) {
|
|
||||||
append(node.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitLambda(node: Lambda) {
|
override fun visitLambda(node: Lambda) {
|
||||||
append("{")
|
append("{")
|
||||||
@ -87,35 +106,6 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> {
|
|||||||
append("}")
|
append("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitIntLiteral(node: IntLiteral) {
|
|
||||||
append(node.value.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitBooleanLiteral(node: BooleanLiteral) {
|
|
||||||
if (node.value) {
|
|
||||||
append("true")
|
|
||||||
} else {
|
|
||||||
append("false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitListLiteral(node: ListLiteral) {
|
|
||||||
append("[")
|
|
||||||
for ((index, item) in node.items.withIndex()) {
|
|
||||||
visit(item)
|
|
||||||
if (index != node.items.size - 1) {
|
|
||||||
append(", ")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
append("]")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitStringLiteral(node: StringLiteral) {
|
|
||||||
append("\"")
|
|
||||||
append(StringEscape.escape(node.text))
|
|
||||||
append("\"")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitParentheses(node: Parentheses) {
|
override fun visitParentheses(node: Parentheses) {
|
||||||
append("(")
|
append("(")
|
||||||
visit(node.expression)
|
visit(node.expression)
|
||||||
@ -127,6 +117,17 @@ class Printer(private val buffer: StringBuilder) : NodeVisitor<Unit> {
|
|||||||
visit(node.expression)
|
visit(node.expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitIf(node: If) {
|
||||||
|
append("if ")
|
||||||
|
visit(node.condition)
|
||||||
|
append(" then ")
|
||||||
|
visit(node.thenExpression)
|
||||||
|
if (node.elseExpression != null) {
|
||||||
|
append(" else ")
|
||||||
|
visit(node.elseExpression)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitInfixOperation(node: InfixOperation) {
|
override fun visitInfixOperation(node: InfixOperation) {
|
||||||
visit(node.left)
|
visit(node.left)
|
||||||
append(" ")
|
append(" ")
|
||||||
|
@ -5,49 +5,12 @@ import gay.pizza.pork.ast.nodes.*
|
|||||||
import gay.pizza.pork.util.StringEscape
|
import gay.pizza.pork.util.StringEscape
|
||||||
|
|
||||||
class DartCompiler : NodeVisitor<String> {
|
class DartCompiler : NodeVisitor<String> {
|
||||||
override fun visitDefine(node: Define): String =
|
|
||||||
"final ${visit(node.symbol)} = ${visit(node.value)};"
|
|
||||||
|
|
||||||
override fun visitFunctionCall(node: FunctionCall): String =
|
|
||||||
"${visit(node.symbol)}(${node.arguments.joinToString(", ") { visit(it) }})"
|
|
||||||
|
|
||||||
override fun visitReference(node: SymbolReference): String =
|
|
||||||
visit(node.symbol)
|
|
||||||
|
|
||||||
override fun visitIf(node: If): String = buildString {
|
|
||||||
append("if (")
|
|
||||||
append(visit(node.condition))
|
|
||||||
append(") {")
|
|
||||||
append(visit(node.thenExpression))
|
|
||||||
append("}")
|
|
||||||
if (node.elseExpression != null) {
|
|
||||||
append(" else {")
|
|
||||||
append(visit(node.elseExpression))
|
|
||||||
append("}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSymbol(node: Symbol): String =
|
|
||||||
node.id
|
|
||||||
|
|
||||||
override fun visitLambda(node: Lambda): String = buildString {
|
|
||||||
append("(${node.arguments.joinToString(", ") { visit(it) }}) {")
|
|
||||||
appendLine()
|
|
||||||
for ((index, expression) in node.expressions.withIndex()) {
|
|
||||||
val code = visit(expression)
|
|
||||||
if (index == node.expressions.size - 1) {
|
|
||||||
append("return ");
|
|
||||||
}
|
|
||||||
append(code)
|
|
||||||
append(";")
|
|
||||||
}
|
|
||||||
appendLine()
|
|
||||||
append("}")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitIntLiteral(node: IntLiteral): String =
|
override fun visitIntLiteral(node: IntLiteral): String =
|
||||||
node.value.toString()
|
node.value.toString()
|
||||||
|
|
||||||
|
override fun visitStringLiteral(node: StringLiteral): String =
|
||||||
|
"\"" + StringEscape.escape(node.text) + "\""
|
||||||
|
|
||||||
override fun visitBooleanLiteral(node: BooleanLiteral): String =
|
override fun visitBooleanLiteral(node: BooleanLiteral): String =
|
||||||
node.value.toString()
|
node.value.toString()
|
||||||
|
|
||||||
@ -63,8 +26,32 @@ class DartCompiler : NodeVisitor<String> {
|
|||||||
append("]")
|
append("]")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitStringLiteral(node: StringLiteral): String =
|
override fun visitSymbol(node: Symbol): String =
|
||||||
"\"" + StringEscape.escape(node.text) + "\""
|
node.id
|
||||||
|
|
||||||
|
override fun visitFunctionCall(node: FunctionCall): String =
|
||||||
|
"${visit(node.symbol)}(${node.arguments.joinToString(", ") { visit(it) }})"
|
||||||
|
|
||||||
|
override fun visitDefine(node: Define): String =
|
||||||
|
"final ${visit(node.symbol)} = ${visit(node.value)};"
|
||||||
|
|
||||||
|
override fun visitSymbolReference(node: SymbolReference): String =
|
||||||
|
visit(node.symbol)
|
||||||
|
|
||||||
|
override fun visitLambda(node: Lambda): String = buildString {
|
||||||
|
append("(${node.arguments.joinToString(", ") { visit(it) }}) {")
|
||||||
|
appendLine()
|
||||||
|
for ((index, expression) in node.expressions.withIndex()) {
|
||||||
|
val code = visit(expression)
|
||||||
|
if (index == node.expressions.size - 1) {
|
||||||
|
append("return ");
|
||||||
|
}
|
||||||
|
append(code)
|
||||||
|
append(";")
|
||||||
|
}
|
||||||
|
appendLine()
|
||||||
|
append("}")
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitParentheses(node: Parentheses): String =
|
override fun visitParentheses(node: Parentheses): String =
|
||||||
"(${visit(node.expression)})"
|
"(${visit(node.expression)})"
|
||||||
@ -72,6 +59,19 @@ class DartCompiler : NodeVisitor<String> {
|
|||||||
override fun visitPrefixOperation(node: PrefixOperation): String =
|
override fun visitPrefixOperation(node: PrefixOperation): String =
|
||||||
"${node.op.token}${visit(node.expression)}"
|
"${node.op.token}${visit(node.expression)}"
|
||||||
|
|
||||||
|
override fun visitIf(node: If): String = buildString {
|
||||||
|
append("if (")
|
||||||
|
append(visit(node.condition))
|
||||||
|
append(") {")
|
||||||
|
append(visit(node.thenExpression))
|
||||||
|
append("}")
|
||||||
|
if (node.elseExpression != null) {
|
||||||
|
append(" else {")
|
||||||
|
append(visit(node.elseExpression))
|
||||||
|
append("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitInfixOperation(node: InfixOperation): String =
|
override fun visitInfixOperation(node: InfixOperation): String =
|
||||||
"${visit(node.left)} ${node.op.token} ${visit(node.right)}"
|
"${visit(node.left)} ${node.op.token} ${visit(node.right)}"
|
||||||
|
|
||||||
|
@ -5,42 +5,12 @@ import gay.pizza.pork.ast.nodes.*
|
|||||||
import gay.pizza.pork.util.StringEscape
|
import gay.pizza.pork.util.StringEscape
|
||||||
|
|
||||||
class KotlinCompiler : NodeVisitor<String> {
|
class KotlinCompiler : NodeVisitor<String> {
|
||||||
override fun visitDefine(node: Define): String =
|
|
||||||
"val ${visit(node.symbol)} = ${visit(node.value)}"
|
|
||||||
|
|
||||||
override fun visitFunctionCall(node: FunctionCall): String =
|
|
||||||
"${visit(node.symbol)}(${node.arguments.joinToString(", ") { visit(it) }})"
|
|
||||||
|
|
||||||
override fun visitReference(node: SymbolReference): String =
|
|
||||||
visit(node.symbol)
|
|
||||||
|
|
||||||
override fun visitIf(node: If): String = buildString {
|
|
||||||
append("if (")
|
|
||||||
append(visit(node.condition))
|
|
||||||
append(") {")
|
|
||||||
append(visit(node.thenExpression))
|
|
||||||
append("}")
|
|
||||||
if (node.elseExpression != null) {
|
|
||||||
append(" else {")
|
|
||||||
append(visit(node.elseExpression))
|
|
||||||
append("}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSymbol(node: Symbol): String =
|
|
||||||
node.id
|
|
||||||
|
|
||||||
override fun visitLambda(node: Lambda): String = buildString {
|
|
||||||
append("{ ${node.arguments.joinToString(", ") { visit(it) }} ->")
|
|
||||||
appendLine()
|
|
||||||
append(visitAll(node.expressions).joinToString("\n"))
|
|
||||||
appendLine()
|
|
||||||
append("}")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitIntLiteral(node: IntLiteral): String =
|
override fun visitIntLiteral(node: IntLiteral): String =
|
||||||
node.value.toString()
|
node.value.toString()
|
||||||
|
|
||||||
|
override fun visitStringLiteral(node: StringLiteral): String =
|
||||||
|
"\"" + StringEscape.escape(node.text) + "\""
|
||||||
|
|
||||||
override fun visitBooleanLiteral(node: BooleanLiteral): String =
|
override fun visitBooleanLiteral(node: BooleanLiteral): String =
|
||||||
node.value.toString()
|
node.value.toString()
|
||||||
|
|
||||||
@ -56,8 +26,25 @@ class KotlinCompiler : NodeVisitor<String> {
|
|||||||
append(")")
|
append(")")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitStringLiteral(node: StringLiteral): String =
|
override fun visitSymbol(node: Symbol): String =
|
||||||
"\"" + StringEscape.escape(node.text) + "\""
|
node.id
|
||||||
|
|
||||||
|
override fun visitFunctionCall(node: FunctionCall): String =
|
||||||
|
"${visit(node.symbol)}(${node.arguments.joinToString(", ") { visit(it) }})"
|
||||||
|
|
||||||
|
override fun visitDefine(node: Define): String =
|
||||||
|
"val ${visit(node.symbol)} = ${visit(node.value)}"
|
||||||
|
|
||||||
|
override fun visitSymbolReference(node: SymbolReference): String =
|
||||||
|
visit(node.symbol)
|
||||||
|
|
||||||
|
override fun visitLambda(node: Lambda): String = buildString {
|
||||||
|
append("{ ${node.arguments.joinToString(", ") { visit(it) }} ->")
|
||||||
|
appendLine()
|
||||||
|
append(visitAll(node.expressions).joinToString("\n"))
|
||||||
|
appendLine()
|
||||||
|
append("}")
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitParentheses(node: Parentheses): String =
|
override fun visitParentheses(node: Parentheses): String =
|
||||||
"(${visit(node.expression)})"
|
"(${visit(node.expression)})"
|
||||||
@ -65,6 +52,19 @@ class KotlinCompiler : NodeVisitor<String> {
|
|||||||
override fun visitPrefixOperation(node: PrefixOperation): String =
|
override fun visitPrefixOperation(node: PrefixOperation): String =
|
||||||
"${node.op.token}${visit(node.expression)}"
|
"${node.op.token}${visit(node.expression)}"
|
||||||
|
|
||||||
|
override fun visitIf(node: If): String = buildString {
|
||||||
|
append("if (")
|
||||||
|
append(visit(node.condition))
|
||||||
|
append(") {")
|
||||||
|
append(visit(node.thenExpression))
|
||||||
|
append("}")
|
||||||
|
if (node.elseExpression != null) {
|
||||||
|
append(" else {")
|
||||||
|
append(visit(node.elseExpression))
|
||||||
|
append("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitInfixOperation(node: InfixOperation): String =
|
override fun visitInfixOperation(node: InfixOperation): String =
|
||||||
"${visit(node.left)} ${node.op.token} ${visit(node.right)}"
|
"${visit(node.left)} ${node.op.token} ${visit(node.right)}"
|
||||||
|
|
||||||
|
@ -6,37 +6,27 @@ import gay.pizza.pork.ast.nodes.*
|
|||||||
class Evaluator(root: Scope) : NodeVisitor<Any> {
|
class Evaluator(root: Scope) : NodeVisitor<Any> {
|
||||||
private var currentScope: Scope = root
|
private var currentScope: Scope = root
|
||||||
|
|
||||||
override fun visitDefine(node: Define): Any {
|
override fun visitIntLiteral(node: IntLiteral): Any = node.value
|
||||||
val value = visit(node.value)
|
override fun visitStringLiteral(node: StringLiteral): Any = node.text
|
||||||
currentScope.define(node.symbol.id, value)
|
override fun visitBooleanLiteral(node: BooleanLiteral): Any = node.value
|
||||||
return value
|
override fun visitListLiteral(node: ListLiteral): Any = node.items.map { visit(it) }
|
||||||
}
|
|
||||||
|
override fun visitSymbol(node: Symbol): Any = None
|
||||||
|
|
||||||
override fun visitFunctionCall(node: FunctionCall): Any {
|
override fun visitFunctionCall(node: FunctionCall): Any {
|
||||||
val arguments = node.arguments.map { visit(it) }
|
val arguments = node.arguments.map { visit(it) }
|
||||||
return currentScope.call(node.symbol.id, Arguments(arguments))
|
return currentScope.call(node.symbol.id, Arguments(arguments))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitReference(node: SymbolReference): Any =
|
override fun visitDefine(node: Define): Any {
|
||||||
|
val value = visit(node.value)
|
||||||
|
currentScope.define(node.symbol.id, value)
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSymbolReference(node: SymbolReference): Any =
|
||||||
currentScope.value(node.symbol.id)
|
currentScope.value(node.symbol.id)
|
||||||
|
|
||||||
override fun visitIf(node: If): Any {
|
|
||||||
val condition = visit(node.condition)
|
|
||||||
return if (condition == true) {
|
|
||||||
visit(node.thenExpression)
|
|
||||||
} else {
|
|
||||||
if (node.elseExpression != null) {
|
|
||||||
visit(node.elseExpression)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSymbol(node: Symbol): Any {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitLambda(node: Lambda): CallableFunction {
|
override fun visitLambda(node: Lambda): CallableFunction {
|
||||||
return CallableFunction { arguments ->
|
return CallableFunction { arguments ->
|
||||||
currentScope = currentScope.fork()
|
currentScope = currentScope.fork()
|
||||||
@ -55,11 +45,6 @@ class Evaluator(root: Scope) : NodeVisitor<Any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitIntLiteral(node: IntLiteral): Any = node.value
|
|
||||||
override fun visitBooleanLiteral(node: BooleanLiteral): Any = node.value
|
|
||||||
override fun visitListLiteral(node: ListLiteral): Any = node.items.map { visit(it) }
|
|
||||||
override fun visitStringLiteral(node: StringLiteral): Any = node.text
|
|
||||||
|
|
||||||
override fun visitParentheses(node: Parentheses): Any = visit(node.expression)
|
override fun visitParentheses(node: Parentheses): Any = visit(node.expression)
|
||||||
|
|
||||||
override fun visitPrefixOperation(node: PrefixOperation): Any {
|
override fun visitPrefixOperation(node: PrefixOperation): Any {
|
||||||
@ -74,6 +59,19 @@ class Evaluator(root: Scope) : NodeVisitor<Any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitIf(node: If): Any {
|
||||||
|
val condition = visit(node.condition)
|
||||||
|
return if (condition == true) {
|
||||||
|
visit(node.thenExpression)
|
||||||
|
} else {
|
||||||
|
if (node.elseExpression != null) {
|
||||||
|
visit(node.elseExpression)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitInfixOperation(node: InfixOperation): Any {
|
override fun visitInfixOperation(node: InfixOperation): Any {
|
||||||
val left = visit(node.left)
|
val left = visit(node.left)
|
||||||
val right = visit(node.right)
|
val right = visit(node.right)
|
||||||
|
@ -77,7 +77,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
|||||||
Parentheses(expression)
|
Parentheses(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readNegation(): PrefixOperation = within {
|
private fun readPrefixOperation(): PrefixOperation = within {
|
||||||
expect(TokenType.Negation) {
|
expect(TokenType.Negation) {
|
||||||
PrefixOperation(PrefixOperator.Negate, readExpression())
|
PrefixOperation(PrefixOperator.Negate, readExpression())
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TokenType.Negation -> {
|
TokenType.Negation -> {
|
||||||
readNegation()
|
readPrefixOperation()
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenType.If -> {
|
TokenType.If -> {
|
||||||
|
Loading…
Reference in New Issue
Block a user