mirror of
https://github.com/GayPizzaSpecifications/pork.git
synced 2025-08-02 12:50:55 +00:00
language: implement let definitions
This commit is contained in:
parent
5d53381b82
commit
8f60039d6e
@ -137,6 +137,15 @@ types:
|
||||
type: Block?
|
||||
- name: native
|
||||
type: Native?
|
||||
LetDefinition:
|
||||
parent: Definition
|
||||
values:
|
||||
- name: modifiers
|
||||
type: DefinitionModifiers
|
||||
- name: symbol
|
||||
type: Symbol
|
||||
- name: value
|
||||
type: Expression
|
||||
If:
|
||||
parent: Expression
|
||||
values:
|
||||
|
@ -16,6 +16,7 @@ digraph A {
|
||||
type_FunctionCall [shape=box,label="FunctionCall"]
|
||||
type_ArgumentSpec [shape=box,label="ArgumentSpec"]
|
||||
type_FunctionDefinition [shape=box,label="FunctionDefinition"]
|
||||
type_LetDefinition [shape=box,label="LetDefinition"]
|
||||
type_If [shape=box,label="If"]
|
||||
type_ImportDeclaration [shape=box,label="ImportDeclaration"]
|
||||
type_IntegerLiteral [shape=box,label="IntegerLiteral"]
|
||||
@ -58,6 +59,7 @@ digraph A {
|
||||
type_Expression -> type_Break
|
||||
type_Expression -> type_Continue
|
||||
type_Definition -> type_FunctionDefinition
|
||||
type_Definition -> type_LetDefinition
|
||||
type_Declaration -> type_ImportDeclaration
|
||||
type_Definition -> type_Symbol [style=dotted]
|
||||
type_Definition -> type_DefinitionModifiers [style=dotted]
|
||||
@ -80,6 +82,9 @@ digraph A {
|
||||
type_FunctionDefinition -> type_ArgumentSpec [style=dotted]
|
||||
type_FunctionDefinition -> type_Block [style=dotted]
|
||||
type_FunctionDefinition -> type_Native [style=dotted]
|
||||
type_LetDefinition -> type_DefinitionModifiers [style=dotted]
|
||||
type_LetDefinition -> type_Symbol [style=dotted]
|
||||
type_LetDefinition -> type_Expression [style=dotted]
|
||||
type_If -> type_Expression [style=dotted]
|
||||
type_If -> type_Block [style=dotted]
|
||||
type_ImportDeclaration -> type_Symbol [style=dotted]
|
||||
|
30
ast/src/main/kotlin/gay/pizza/pork/ast/LetDefinition.kt
Normal file
30
ast/src/main/kotlin/gay/pizza/pork/ast/LetDefinition.kt
Normal file
@ -0,0 +1,30 @@
|
||||
// GENERATED CODE FROM PORK AST CODEGEN
|
||||
package gay.pizza.pork.ast
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
@SerialName("letDefinition")
|
||||
class LetDefinition(override val modifiers: DefinitionModifiers, override val symbol: Symbol, val value: Expression) : Definition() {
|
||||
override val type: NodeType = NodeType.LetDefinition
|
||||
|
||||
override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
|
||||
visitor.visitNodes(symbol, value)
|
||||
|
||||
override fun <T> visit(visitor: NodeVisitor<T>): T =
|
||||
visitor.visitLetDefinition(this)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is LetDefinition) return false
|
||||
return other.modifiers == modifiers && other.symbol == symbol && other.value == value
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = modifiers.hashCode()
|
||||
result = 31 * result + symbol.hashCode()
|
||||
result = 31 * result + value.hashCode()
|
||||
result = 31 * result + type.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
@ -41,6 +41,9 @@ class NodeCoalescer(val handler: (Node) -> Unit) : NodeVisitor<Unit> {
|
||||
override fun visitLetAssignment(node: LetAssignment): Unit =
|
||||
handle(node)
|
||||
|
||||
override fun visitLetDefinition(node: LetDefinition): Unit =
|
||||
handle(node)
|
||||
|
||||
override fun visitListLiteral(node: ListLiteral): Unit =
|
||||
handle(node)
|
||||
|
||||
|
@ -19,6 +19,7 @@ enum class NodeType(val parent: NodeType? = null) {
|
||||
InfixOperation(Expression),
|
||||
IntegerLiteral(Expression),
|
||||
LetAssignment(Expression),
|
||||
LetDefinition(Definition),
|
||||
ListLiteral(Expression),
|
||||
Native(Node),
|
||||
Parentheses(Expression),
|
||||
|
@ -28,6 +28,8 @@ interface NodeVisitor<T> {
|
||||
|
||||
fun visitLetAssignment(node: LetAssignment): T
|
||||
|
||||
fun visitLetDefinition(node: LetDefinition): T
|
||||
|
||||
fun visitListLiteral(node: ListLiteral): T
|
||||
|
||||
fun visitNative(node: Native): T
|
||||
|
@ -13,6 +13,7 @@ fun <T> NodeVisitor<T>.visit(node: Node): T =
|
||||
is BooleanLiteral -> visitBooleanLiteral(node)
|
||||
is FunctionCall -> visitFunctionCall(node)
|
||||
is FunctionDefinition -> visitFunctionDefinition(node)
|
||||
is LetDefinition -> visitLetDefinition(node)
|
||||
is If -> visitIf(node)
|
||||
is ImportDeclaration -> visitImportDeclaration(node)
|
||||
is IntegerLiteral -> visitIntegerLiteral(node)
|
||||
|
@ -39,6 +39,10 @@ class CompilationUnitContext(
|
||||
|
||||
private fun definitionValue(definition: Definition): Any = when (definition) {
|
||||
is FunctionDefinition -> FunctionContext(this, definition)
|
||||
is LetDefinition -> {
|
||||
EvaluationVisitor(internalScope.fork("let ${definition.symbol.id}"))
|
||||
.visit(definition.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun processAllImports() {
|
||||
|
@ -30,6 +30,10 @@ class EvaluationVisitor(root: Scope) : NodeVisitor<Any> {
|
||||
return value
|
||||
}
|
||||
|
||||
override fun visitLetDefinition(node: LetDefinition): Any {
|
||||
topLevelUsedError("LetDefinition", "CompilationUnitContext")
|
||||
}
|
||||
|
||||
override fun visitSymbolReference(node: SymbolReference): Any =
|
||||
currentScope.value(node.symbol.id)
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
let count = 5
|
||||
|
||||
export func main() {
|
||||
var x = 1
|
||||
while x <= 5 {
|
||||
while x <= count {
|
||||
println(x)
|
||||
x = x + 1
|
||||
x++
|
||||
}
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
||||
ImportDeclaration(form, components)
|
||||
}
|
||||
|
||||
private fun readFunctionDeclaration(): FunctionDefinition = within {
|
||||
private fun readDefinitionModifiers(): DefinitionModifiers {
|
||||
val modifiers = DefinitionModifiers(export = false)
|
||||
while (true) {
|
||||
val token = peek()
|
||||
@ -238,12 +238,16 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
||||
else -> break
|
||||
}
|
||||
}
|
||||
return modifiers
|
||||
}
|
||||
|
||||
private fun readFunctionDeclaration(modifiers: DefinitionModifiers): FunctionDefinition = within {
|
||||
expect(TokenType.Func)
|
||||
val name = readSymbolRaw()
|
||||
expect(TokenType.LeftParentheses)
|
||||
val arguments = collect(TokenType.RightParentheses, TokenType.Comma) {
|
||||
val symbol = readSymbolRaw()
|
||||
var multiple: Boolean = false
|
||||
var multiple = false
|
||||
if (next(TokenType.DotDotDot)) {
|
||||
multiple = true
|
||||
}
|
||||
@ -261,11 +265,21 @@ class Parser(source: PeekableSource<Token>, val attribution: NodeAttribution) {
|
||||
FunctionDefinition(modifiers, name, arguments, block, native)
|
||||
}
|
||||
|
||||
private fun readLetDefinition(modifiers: DefinitionModifiers): LetDefinition = within {
|
||||
val modifiers = readDefinitionModifiers()
|
||||
expect(TokenType.Let)
|
||||
val name = readSymbolRaw()
|
||||
expect(TokenType.Equals)
|
||||
val value = readExpression()
|
||||
LetDefinition(modifiers, name, value)
|
||||
}
|
||||
|
||||
private fun maybeReadDefinition(): Definition? {
|
||||
val modifiers = readDefinitionModifiers()
|
||||
val token = peek()
|
||||
return when (token.type) {
|
||||
TokenType.Export,
|
||||
TokenType.Func -> readFunctionDeclaration()
|
||||
TokenType.Func -> readFunctionDeclaration(modifiers)
|
||||
TokenType.Let -> readLetDefinition(modifiers)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,14 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
|
||||
visit(node.value)
|
||||
}
|
||||
|
||||
override fun visitLetDefinition(node: LetDefinition) {
|
||||
visitDefinitionModifiers(node.modifiers)
|
||||
append("let ")
|
||||
visit(node.symbol)
|
||||
append(" = ")
|
||||
visit(node.value)
|
||||
}
|
||||
|
||||
override fun visitSymbolReference(node: SymbolReference) {
|
||||
visit(node.symbol)
|
||||
}
|
||||
@ -152,10 +160,14 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
|
||||
visit(node.right)
|
||||
}
|
||||
|
||||
override fun visitFunctionDefinition(node: FunctionDefinition) {
|
||||
if (node.modifiers.export) {
|
||||
private fun visitDefinitionModifiers(modifiers: DefinitionModifiers) {
|
||||
if (modifiers.export) {
|
||||
append("export ")
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitFunctionDefinition(node: FunctionDefinition) {
|
||||
visitDefinitionModifiers(node.modifiers)
|
||||
append("func ")
|
||||
visit(node.symbol)
|
||||
append("(")
|
||||
|
Loading…
Reference in New Issue
Block a user