language: prepare for struct support

This commit is contained in:
2023-11-06 21:37:27 -08:00
parent e3bfa3fbfc
commit 8c48c93663
18 changed files with 42 additions and 41 deletions

View File

@ -157,8 +157,8 @@ types:
type: List<ArgumentSpec> type: List<ArgumentSpec>
- name: block - name: block
type: Block? type: Block?
- name: native - name: nativeFunctionDescriptor
type: Native? type: NativeFunctionDescriptor?
LetDefinition: LetDefinition:
parent: Definition parent: Definition
namedElementValue: symbol namedElementValue: symbol
@ -303,7 +303,7 @@ types:
NoneLiteral: NoneLiteral:
parent: Expression parent: Expression
values: [] values: []
Native: NativeFunctionDescriptor:
parent: Node parent: Node
values: values:
- name: form - name: form

View File

@ -37,7 +37,7 @@ digraph A {
type_Break [shape=box,label="Break"] type_Break [shape=box,label="Break"]
type_Continue [shape=box,label="Continue"] type_Continue [shape=box,label="Continue"]
type_NoneLiteral [shape=box,label="NoneLiteral"] type_NoneLiteral [shape=box,label="NoneLiteral"]
type_Native [shape=box,label="Native"] type_NativeFunctionDescriptor [shape=box,label="NativeFunctionDescriptor"]
type_IndexedBy [shape=box,label="IndexedBy"] type_IndexedBy [shape=box,label="IndexedBy"]
type_Node -> type_Expression type_Node -> type_Expression
type_Node -> type_Symbol type_Node -> type_Symbol
@ -48,7 +48,7 @@ digraph A {
type_Node -> type_ArgumentSpec type_Node -> type_ArgumentSpec
type_Node -> type_ImportPath type_Node -> type_ImportPath
type_Node -> type_ForInItem type_Node -> type_ForInItem
type_Node -> type_Native type_Node -> type_NativeFunctionDescriptor
type_Expression -> type_LetAssignment type_Expression -> type_LetAssignment
type_Expression -> type_VarAssignment type_Expression -> type_VarAssignment
type_Expression -> type_SetAssignment type_Expression -> type_SetAssignment
@ -94,7 +94,7 @@ digraph A {
type_FunctionDefinition -> type_Symbol [style=dotted] type_FunctionDefinition -> type_Symbol [style=dotted]
type_FunctionDefinition -> type_ArgumentSpec [style=dotted] type_FunctionDefinition -> type_ArgumentSpec [style=dotted]
type_FunctionDefinition -> type_Block [style=dotted] type_FunctionDefinition -> type_Block [style=dotted]
type_FunctionDefinition -> type_Native [style=dotted] type_FunctionDefinition -> type_NativeFunctionDescriptor [style=dotted]
type_LetDefinition -> type_DefinitionModifiers [style=dotted] type_LetDefinition -> type_DefinitionModifiers [style=dotted]
type_LetDefinition -> type_Symbol [style=dotted] type_LetDefinition -> type_Symbol [style=dotted]
type_LetDefinition -> type_Expression [style=dotted] type_LetDefinition -> type_Expression [style=dotted]
@ -116,7 +116,7 @@ digraph A {
type_ForIn -> type_ForInItem [style=dotted] type_ForIn -> type_ForInItem [style=dotted]
type_ForIn -> type_Expression [style=dotted] type_ForIn -> type_Expression [style=dotted]
type_ForIn -> type_Block [style=dotted] type_ForIn -> type_Block [style=dotted]
type_Native -> type_Symbol [style=dotted] type_NativeFunctionDescriptor -> type_Symbol [style=dotted]
type_Native -> type_StringLiteral [style=dotted] type_NativeFunctionDescriptor -> type_StringLiteral [style=dotted]
type_IndexedBy -> type_Expression [style=dotted] type_IndexedBy -> type_Expression [style=dotted]
} }

View File

@ -6,18 +6,18 @@ import kotlinx.serialization.Serializable
@Serializable @Serializable
@SerialName("functionDefinition") @SerialName("functionDefinition")
class FunctionDefinition(override val modifiers: DefinitionModifiers, override val symbol: Symbol, val arguments: List<ArgumentSpec>, val block: Block?, val native: Native?) : Definition() { class FunctionDefinition(override val modifiers: DefinitionModifiers, override val symbol: Symbol, val arguments: List<ArgumentSpec>, val block: Block?, val nativeFunctionDescriptor: NativeFunctionDescriptor?) : Definition() {
override val type: NodeType = NodeType.FunctionDefinition override val type: NodeType = NodeType.FunctionDefinition
override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> = override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
visitor.visitAll(listOf(symbol), arguments, listOf(block), listOf(native)) visitor.visitAll(listOf(symbol), arguments, listOf(block), listOf(nativeFunctionDescriptor))
override fun <T> visit(visitor: NodeVisitor<T>): T = override fun <T> visit(visitor: NodeVisitor<T>): T =
visitor.visitFunctionDefinition(this) visitor.visitFunctionDefinition(this)
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other !is FunctionDefinition) return false if (other !is FunctionDefinition) return false
return other.modifiers == modifiers && other.symbol == symbol && other.arguments == arguments && other.block == block && other.native == native return other.modifiers == modifiers && other.symbol == symbol && other.arguments == arguments && other.block == block && other.nativeFunctionDescriptor == nativeFunctionDescriptor
} }
override fun hashCode(): Int { override fun hashCode(): Int {
@ -25,7 +25,7 @@ class FunctionDefinition(override val modifiers: DefinitionModifiers, override v
result = 31 * result + symbol.hashCode() result = 31 * result + symbol.hashCode()
result = 31 * result + arguments.hashCode() result = 31 * result + arguments.hashCode()
result = 31 * result + block.hashCode() result = 31 * result + block.hashCode()
result = 31 * result + native.hashCode() result = 31 * result + nativeFunctionDescriptor.hashCode()
result = 31 * result + type.hashCode() result = 31 * result + type.hashCode()
return result return result
} }

View File

@ -5,18 +5,18 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@Serializable @Serializable
@SerialName("native") @SerialName("nativeFunctionDescriptor")
class Native(val form: Symbol, val definitions: List<StringLiteral>) : Node() { class NativeFunctionDescriptor(val form: Symbol, val definitions: List<StringLiteral>) : Node() {
override val type: NodeType = NodeType.Native override val type: NodeType = NodeType.NativeFunctionDescriptor
override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> = override fun <T> visitChildren(visitor: NodeVisitor<T>): List<T> =
visitor.visitAll(listOf(form), definitions) visitor.visitAll(listOf(form), definitions)
override fun <T> visit(visitor: NodeVisitor<T>): T = override fun <T> visit(visitor: NodeVisitor<T>): T =
visitor.visitNative(this) visitor.visitNativeFunctionDescriptor(this)
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other !is Native) return false if (other !is NativeFunctionDescriptor) return false
return other.form == form && other.definitions == definitions return other.form == form && other.definitions == definitions
} }

View File

@ -65,7 +65,7 @@ class NodeCoalescer(val followChildren: Boolean = true, val handler: (Node) -> U
override fun visitLongLiteral(node: LongLiteral): Unit = override fun visitLongLiteral(node: LongLiteral): Unit =
handle(node) handle(node)
override fun visitNative(node: Native): Unit = override fun visitNativeFunctionDescriptor(node: NativeFunctionDescriptor): Unit =
handle(node) handle(node)
override fun visitNoneLiteral(node: NoneLiteral): Unit = override fun visitNoneLiteral(node: NoneLiteral): Unit =

View File

@ -50,7 +50,7 @@ interface NodeParser {
fun parseLongLiteral(): LongLiteral fun parseLongLiteral(): LongLiteral
fun parseNative(): Native fun parseNativeFunctionDescriptor(): NativeFunctionDescriptor
fun parseNoneLiteral(): NoneLiteral fun parseNoneLiteral(): NoneLiteral

View File

@ -36,7 +36,7 @@ fun NodeParser.parse(type: NodeType): Node =
NodeType.Break -> parseBreak() NodeType.Break -> parseBreak()
NodeType.Continue -> parseContinue() NodeType.Continue -> parseContinue()
NodeType.NoneLiteral -> parseNoneLiteral() NodeType.NoneLiteral -> parseNoneLiteral()
NodeType.Native -> parseNative() NodeType.NativeFunctionDescriptor -> parseNativeFunctionDescriptor()
NodeType.IndexedBy -> parseIndexedBy() NodeType.IndexedBy -> parseIndexedBy()
else -> throw RuntimeException("Unable to automatically parse type: ${type.name}") else -> throw RuntimeException("Unable to automatically parse type: ${type.name}")
} }

View File

@ -27,7 +27,7 @@ enum class NodeType(val parent: NodeType? = null) {
LetDefinition(Definition), LetDefinition(Definition),
ListLiteral(Expression), ListLiteral(Expression),
LongLiteral(Expression), LongLiteral(Expression),
Native(Node), NativeFunctionDescriptor(Node),
NoneLiteral(Expression), NoneLiteral(Expression),
Parentheses(Expression), Parentheses(Expression),
PrefixOperation(Expression), PrefixOperation(Expression),

View File

@ -44,7 +44,7 @@ interface NodeVisitor<T> {
fun visitLongLiteral(node: LongLiteral): T fun visitLongLiteral(node: LongLiteral): T
fun visitNative(node: Native): T fun visitNativeFunctionDescriptor(node: NativeFunctionDescriptor): T
fun visitNoneLiteral(node: NoneLiteral): T fun visitNoneLiteral(node: NoneLiteral): T

View File

@ -33,7 +33,7 @@ fun <T> NodeVisitor<T>.visit(node: Node): T =
is Break -> visitBreak(node) is Break -> visitBreak(node)
is Continue -> visitContinue(node) is Continue -> visitContinue(node)
is NoneLiteral -> visitNoneLiteral(node) is NoneLiteral -> visitNoneLiteral(node)
is Native -> visitNative(node) is NativeFunctionDescriptor -> visitNativeFunctionDescriptor(node)
is IndexedBy -> visitIndexedBy(node) is IndexedBy -> visitIndexedBy(node)
} }

View File

@ -12,8 +12,8 @@ repositories {
} }
dependencies { dependencies {
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.20")
implementation("org.jetbrains.kotlin:kotlin-serialization:1.9.10") implementation("org.jetbrains.kotlin:kotlin-serialization:1.9.20")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("com.charleskorn.kaml:kaml:0.55.0") implementation("com.charleskorn.kaml:kaml:0.55.0")
} }

View File

@ -414,8 +414,8 @@ class EvaluationVisitor(root: Scope, val stack: CallStack) : NodeVisitor<Any> {
topLevelUsedError("CompilationUnit", "CompilationUnitContext") topLevelUsedError("CompilationUnit", "CompilationUnitContext")
} }
override fun visitNative(node: Native): Any { override fun visitNativeFunctionDescriptor(node: NativeFunctionDescriptor): Any {
topLevelUsedError("Native", "FunctionContext") topLevelUsedError("NativeFunctionDescriptor", "FunctionContext")
} }
override fun visitNoneLiteral(node: NoneLiteral): Any = None override fun visitNoneLiteral(node: NoneLiteral): Any = None

View File

@ -5,10 +5,10 @@ import gay.pizza.pork.ast.gen.FunctionDefinition
class FunctionContext(val compilationUnitContext: CompilationUnitContext, val node: FunctionDefinition) : CallableFunction { class FunctionContext(val compilationUnitContext: CompilationUnitContext, val node: FunctionDefinition) : CallableFunction {
val name: String = "${compilationUnitContext.name} ${node.symbol.id}" val name: String = "${compilationUnitContext.name} ${node.symbol.id}"
private fun resolveMaybeNative(): CallableFunction? = if (node.native == null) { private fun resolveMaybeNative(): CallableFunction? = if (node.nativeFunctionDescriptor == null) {
null null
} else { } else {
val native = node.native!! val native = node.nativeFunctionDescriptor!!
val nativeFunctionProvider = val nativeFunctionProvider =
compilationUnitContext.evaluator.nativeFunctionProvider(native.form.id) compilationUnitContext.evaluator.nativeFunctionProvider(native.form.id)
nativeFunctionProvider.provideNativeFunction(native.definitions.map { it.text }, node.arguments, compilationUnitContext) nativeFunctionProvider.provideNativeFunction(native.definitions.map { it.text }, node.arguments, compilationUnitContext)

View File

@ -150,12 +150,12 @@ class JavaAutogen(val javaClass: Class<*>) {
multiple = false multiple = false
) )
}, },
native = asNative(functionDefinition), nativeFunctionDescriptor = asNative(functionDefinition),
block = null block = null
) )
private fun asNative(functionDefinition: JavaFunctionDefinition): Native = private fun asNative(functionDefinition: JavaFunctionDefinition): NativeFunctionDescriptor =
Native(Symbol("java"), functionDefinition.encode().map { StringLiteral(it) }) NativeFunctionDescriptor(Symbol("java"), functionDefinition.encode().map { StringLiteral(it) })
private fun discriminate(parameter: Parameter): String = private fun discriminate(parameter: Parameter): String =
parameter.type.simpleName.lowercase().replace("[]", "_array") parameter.type.simpleName.lowercase().replace("[]", "_array")

View File

@ -213,10 +213,10 @@ class Parser(source: TokenSource, attribution: NodeAttribution) :
} }
expect(TokenType.RightParentheses) expect(TokenType.RightParentheses)
var native: Native? = null var native: NativeFunctionDescriptor? = null
var block: Block? = null var block: Block? = null
if (peek(TokenType.Native)) { if (peek(TokenType.Native)) {
native = parseNative() native = parseNativeFunctionDescriptor()
} else { } else {
block = parseBlock() block = parseBlock()
} }
@ -305,13 +305,13 @@ class Parser(source: TokenSource, attribution: NodeAttribution) :
LongLiteral(it.text.toLong()) LongLiteral(it.text.toLong())
} }
override fun parseNative(): Native = expect(NodeType.Native, TokenType.Native) { override fun parseNativeFunctionDescriptor(): NativeFunctionDescriptor = expect(NodeType.NativeFunctionDescriptor, TokenType.Native) {
val form = parseSymbol() val form = parseSymbol()
val definitions = mutableListOf<StringLiteral>() val definitions = mutableListOf<StringLiteral>()
while (peek(TokenType.Quote)) { while (peek(TokenType.Quote)) {
definitions.add(parseStringLiteral()) definitions.add(parseStringLiteral())
} }
Native(form, definitions) NativeFunctionDescriptor(form, definitions)
} }
override fun parseNoneLiteral(): NoneLiteral = expect(NodeType.NoneLiteral, TokenType.None) { override fun parseNoneLiteral(): NoneLiteral = expect(NodeType.NoneLiteral, TokenType.None) {

View File

@ -78,7 +78,7 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
append(node.value.toString()) append(node.value.toString())
} }
override fun visitNative(node: Native) { override fun visitNativeFunctionDescriptor(node: NativeFunctionDescriptor) {
append("native ") append("native ")
visit(node.form) visit(node.form)
append(" ") append(" ")
@ -208,8 +208,8 @@ class Printer(buffer: StringBuilder) : NodeVisitor<Unit> {
visit(node.block!!) visit(node.block!!)
} }
if (node.native != null) { if (node.nativeFunctionDescriptor != null) {
visit(node.native!!) visit(node.nativeFunctionDescriptor!!)
} }
} }

View File

@ -4,8 +4,8 @@ export func ffiStructDefine(items...)
export func ffiStructAllocate(struct) export func ffiStructAllocate(struct)
native ffi "internal" "ffiStructAllocate" native ffi "internal" "ffiStructAllocate"
export func ffiStructValue(struct, field, value) export func ffiStructValue(def, field, value)
native ffi "internal" "ffiStructValue" native ffi "internal" "ffiStructValue"
export func ffiStructBytes(struct, value) export func ffiStructBytes(def, value)
native ffi "internal" "ffiStructBytes" native ffi "internal" "ffiStructBytes"

View File

@ -76,6 +76,7 @@ enum class TokenType(vararg val properties: TokenTypeProperty) {
))), ))),
BlockComment(CharConsume(MatchedCharConsumer("/*", "*/")), CommentFamily), BlockComment(CharConsume(MatchedCharConsumer("/*", "*/")), CommentFamily),
LineComment(CharConsume(MatchedCharConsumer("//", "\n", AllowEofTermination)), CommentFamily), LineComment(CharConsume(MatchedCharConsumer("//", "\n", AllowEofTermination)), CommentFamily),
Struct(ManyChars("struct"), KeywordFamily),
EndOfFile; EndOfFile;
val promotions: List<Promotion> = val promotions: List<Promotion> =