Skip to content

Commit

Permalink
Declaration based compilation units.
Browse files Browse the repository at this point in the history
  • Loading branch information
azenla committed Sep 3, 2023
1 parent 04c78c3 commit b1f9e02
Show file tree
Hide file tree
Showing 26 changed files with 255 additions and 306 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ Very WIP. Like VERY.

```pork
/* fibonacci sequence */
fib = { n in
fn fib(n) {
if n == 0
then 0
else if n == 1
then 1
else fib(n - 1) + fib(n - 2)
}
result = fib(20)
println(result)
fn main() {
result = fib(20)
println(result)
}
```

## Usage
Expand Down
17 changes: 0 additions & 17 deletions examples/commented.pork

This file was deleted.

8 changes: 5 additions & 3 deletions examples/fib.pork
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/* fibonacci sequence */
fib = { n in
fn fib(n) {
if n == 0
then 0
else if n == 1
then 1
else fib(n - 1) + fib(n - 2)
}

result = fib(20)
println(result)
fn main() {
result = fib(20)
println(result)
}
106 changes: 54 additions & 52 deletions examples/syntax.pork
Original file line number Diff line number Diff line change
@@ -1,53 +1,55 @@
three = 3
two = 2

calculateSimple = { in
(50 + three) * two
}

calculateComplex = { in
three + two + 50
}

multiply = { a, b in
a * b
}

// calculates the result
calculateSimpleResult = calculateSimple()
calculateComplexResult = calculateComplex()
multiplyResult = multiply(50, 50)

list = [10, 20, 30]
trueValue = true
falseValue = false

invert = { value in
!value
}

notEqual = { a, b in
a != b
fn main() {
three = 3
two = 2

calculateSimple = { in
(50 + three) * two
}

calculateComplex = { in
three + two + 50
}

multiply = { a, b in
a * b
}

// calculates the result
calculateSimpleResult = calculateSimple()
calculateComplexResult = calculateComplex()
multiplyResult = multiply(50, 50)

list = [10, 20, 30]
trueValue = true
falseValue = false

invert = { value in
!value
}

notEqual = { a, b in
a != b
}

equal = { a, b in
a == b
}

results = [
calculateSimpleResult,
calculateComplexResult,
multiplyResult,
list,
trueValue,
falseValue,
invert(true),
invert(false),
equal(5, 5),
equal(5, 6),
notEqual(5, 5),
notEqual(5, 6)
]

println("results:")
println(results)
}

equal = { a, b in
a == b
}

results = [
calculateSimpleResult,
calculateComplexResult,
multiplyResult,
list,
trueValue,
falseValue,
invert(true),
invert(false),
equal(5, 5),
equal(5, 6),
notEqual(5, 5),
notEqual(5, 6)
]

println("results:")
println(results)
5 changes: 4 additions & 1 deletion src/main/kotlin/gay/pizza/pork/ast/NodeCoalescer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ class NodeCoalescer(val handler: (Node) -> Unit) : NodeVisitor<Unit> {
override fun visitPrefixOperation(node: PrefixOperation): Unit = handle(node)
override fun visitIf(node: If): Unit = handle(node)
override fun visitInfixOperation(node: InfixOperation): Unit = handle(node)
override fun visitProgram(node: Program): Unit = handle(node)
override fun visitFunctionDeclaration(node: FunctionDeclaration): Unit = handle(node)
override fun visitBlock(node: Block): Unit = handle(node)

override fun visitCompilationUnit(node: CompilationUnit): Unit = handle(node)

private fun handle(node: Node) {
handler(node)
Expand Down
7 changes: 5 additions & 2 deletions src/main/kotlin/gay/pizza/pork/ast/NodeType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ enum class NodeType(val parent: NodeType? = null) {
Node,
Symbol(Node),
Expression(Node),
Program(Node),
Declaration(Node),
Block(Node),
CompilationUnit(Node),
IntLiteral(Expression),
BooleanLiteral(Expression),
ListLiteral(Expression),
Expand All @@ -16,7 +18,8 @@ enum class NodeType(val parent: NodeType? = null) {
InfixOperation(Expression),
SymbolReference(Expression),
FunctionCall(Expression),
If(Expression);
If(Expression),
FunctionDeclaration(Declaration);

val parents: Set<NodeType>

Expand Down
13 changes: 11 additions & 2 deletions src/main/kotlin/gay/pizza/pork/ast/NodeVisitor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ interface NodeVisitor<T> {
fun visitPrefixOperation(node: PrefixOperation): T
fun visitIf(node: If): T
fun visitInfixOperation(node: InfixOperation): T
fun visitProgram(node: Program): T
fun visitFunctionDeclaration(node: FunctionDeclaration): T
fun visitBlock(node: Block): T

fun visitCompilationUnit(node: CompilationUnit): T

fun visitExpression(node: Expression): T = when (node) {
is IntLiteral -> visitIntLiteral(node)
Expand All @@ -33,10 +36,16 @@ interface NodeVisitor<T> {
is InfixOperation -> visitInfixOperation(node)
}

fun visitDeclaration(node: Declaration): T = when (node) {
is FunctionDeclaration -> visitFunctionDeclaration(node)
}

fun visit(node: Node): T = when (node) {
is Symbol -> visitSymbol(node)
is Expression -> visitExpression(node)
is Program -> visitProgram(node)
is CompilationUnit -> visitCompilationUnit(node)
is Block -> visitBlock(node)
is Declaration -> visitDeclaration(node)
}

fun visitNodes(vararg nodes: Node?): List<T> =
Expand Down
36 changes: 31 additions & 5 deletions src/main/kotlin/gay/pizza/pork/ast/Printer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
visit(node.symbol)
}


override fun visitLambda(node: Lambda) {
append("{")
if (node.arguments.isNotEmpty()) {
Expand Down Expand Up @@ -148,10 +147,37 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
visit(node.right)
}

override fun visitProgram(node: Program) {
for (expression in node.expressions) {
out.emitIndent()
visit(expression)
override fun visitFunctionDeclaration(node: FunctionDeclaration) {
append("fn ")
visit(node.symbol)
append("(")
for ((index, argument) in node.arguments.withIndex()) {
visit(argument)
if (index + 1 != node.arguments.size) {
append(", ")
}
}
append(") ")
visit(node.block)
}

override fun visitBlock(node: Block) {
append("{")
if (node.expressions.isNotEmpty()) {
out.increaseIndent()
for (expression in node.expressions) {
appendLine()
visit(expression)
}
out.decreaseIndent()
appendLine()
}
append("}")
}

override fun visitCompilationUnit(node: CompilationUnit) {
for (declaration in node.declarations) {
visit(declaration)
appendLine()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
@SerialName("program")
class Program(val expressions: List<Expression>) : Node() {
override val type: NodeType = NodeType.Program
@SerialName("block")
class Block(val expressions: List<Expression>) : Node() {
override val type: NodeType = NodeType.Block

override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
visitor.visitAll(expressions)

override fun equals(other: Any?): Boolean {
if (other !is Program) return false
if (other !is Block) return false
return other.expressions == expressions
}

Expand Down
26 changes: 26 additions & 0 deletions src/main/kotlin/gay/pizza/pork/ast/nodes/CompilationUnit.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package gay.pizza.pork.ast.nodes

import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.ast.NodeVisitor
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
@SerialName("compilationUnit")
class CompilationUnit(val declarations: List<Declaration>) : Node() {
override val type: NodeType = NodeType.CompilationUnit

override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
visitor.visitAll(declarations)

override fun equals(other: Any?): Boolean {
if (other !is CompilationUnit) return false
return other.declarations == declarations
}

override fun hashCode(): Int {
var result = declarations.hashCode()
result = 31 * result + type.hashCode()
return result
}
}
6 changes: 6 additions & 0 deletions src/main/kotlin/gay/pizza/pork/ast/nodes/Declaration.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package gay.pizza.pork.ast.nodes

import kotlinx.serialization.Serializable

@Serializable
sealed class Declaration : Node()
28 changes: 28 additions & 0 deletions src/main/kotlin/gay/pizza/pork/ast/nodes/FunctionDeclaration.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package gay.pizza.pork.ast.nodes

import gay.pizza.pork.ast.NodeType
import gay.pizza.pork.ast.NodeVisitor
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
@SerialName("functionDeclaration")
class FunctionDeclaration(val symbol: Symbol, val arguments: List<Symbol>, val block: Block) : Declaration() {
override val type: NodeType = NodeType.FunctionDeclaration

override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
visitor.visitNodes(symbol)

override fun equals(other: Any?): Boolean {
if (other !is FunctionDeclaration) return false
return other.symbol == symbol && other.arguments == arguments && other.block == block
}

override fun hashCode(): Int {
var result = symbol.hashCode()
result = 31 * result + symbol.hashCode()
result = 31 * result + arguments.hashCode()
result = 31 * result + block.hashCode()
return result
}
}
4 changes: 2 additions & 2 deletions src/main/kotlin/gay/pizza/pork/cli/AttributeCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class AttributeCommand : CliktCommand(help = "Attribute AST", name = "attribute"
override fun run() {
val frontend = FileFrontend(path)
val attribution = TokenNodeAttribution()
val program = frontend.parse(attribution)
val compilationUnit = frontend.parse(attribution)

val coalescer = NodeCoalescer { node ->
val tokens = attribution.assembleTokens(node)
Expand All @@ -22,6 +22,6 @@ class AttributeCommand : CliktCommand(help = "Attribute AST", name = "attribute"
println("token $token")
}
}
coalescer.visit(program)
coalescer.visit(compilationUnit)
}
}
16 changes: 0 additions & 16 deletions src/main/kotlin/gay/pizza/pork/cli/GenerateDartCommand.kt

This file was deleted.

Loading

0 comments on commit b1f9e02

Please sign in to comment.