language: implement proper virtual machine support

This commit is contained in:
2023-11-28 05:23:48 -08:00
parent 8951c3cd60
commit f2ff23e9be
55 changed files with 312 additions and 63 deletions

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrBreak(val target: IrSymbol) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(target)

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrCall(
override val target: IrSymbol,
val arguments: List<IrCodeElement>,

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrCodeBlock(val items: List<IrCodeElement>) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
items.forEach(block)

View File

@ -1,3 +1,6 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
sealed interface IrCodeElement : IrElement

View File

@ -0,0 +1,31 @@
package gay.pizza.pork.bir
interface IrCodeVisitor<T> : IrVisitor<T> {
override fun visitIrDefinition(ir: IrDefinition): T {
codeOnlyError("IrDefinition")
}
override fun visitIrSlab(ir: IrSlab): T {
codeOnlyError("IrSlab")
}
override fun visitIrSlabLocation(ir: IrSlabLocation): T {
codeOnlyError("IrSlabLocation")
}
override fun visitIrWorld(ir: IrWorld): T {
codeOnlyError("IrWorld")
}
override fun visitIrSymbol(ir: IrSymbol): T {
codeOnlyError("IrSymbol")
}
override fun visitIrFunctionArgument(ir: IrFunctionArgument): T {
codeOnlyError("IrFunctionArgument")
}
private fun codeOnlyError(type: String): Nothing {
throw RuntimeException("This visitor targets only code, and $type is not a code element.")
}
}

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrConditional(
val conditional: IrCodeElement,
val ifTrue: IrCodeElement,

View File

@ -1,12 +1,26 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
sealed interface IrConstant : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {}
}
@Serializable
data class IrIntegerConstant(val value: Int) : IrConstant
@Serializable
data class IrLongConstant(val value: Long) : IrConstant
@Serializable
data class IrDoubleConstant(val value: Double) : IrConstant
@Serializable
data class IrStringConstant(val value: String) : IrConstant
@Serializable
data class IrBooleanConstant(val value: Boolean) : IrConstant
@Serializable
data object IrNoneConstant : IrConstant

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrContinue(override val target: IrSymbol) : IrCodeElement, IrSymbolUser {
override fun crawl(block: (IrElement) -> Unit) {
block(target)

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrDefinition(
override val symbol: IrSymbol,
val type: IrDefinitionType,

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
enum class IrDefinitionType {
Variable,
CodeFunction,

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
sealed interface IrElement {
fun crawl(block: (IrElement) -> Unit)
}

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrFunctionArgument(override val symbol: IrSymbol) : IrSymbolOwner {
override fun crawl(block: (IrElement) -> Unit) {}
}

View File

@ -0,0 +1,11 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrIndex(val data: IrCodeElement, val index: IrCodeElement) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(data)
block(index)
}
}

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrInfix(val op: IrInfixOp, val left: IrCodeElement, val right: IrCodeElement) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(left)

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
enum class IrInfixOp {
Add,
Subtract,

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrList(val items: List<IrCodeElement>) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
items.forEach(block)

View File

@ -0,0 +1,10 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrListSize(val list: IrCodeElement) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(list)
}
}

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrLoad(override val target: IrSymbol) : IrCodeElement, IrSymbolUser {
override fun crawl(block: (IrElement) -> Unit) {
block(target)

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrLoop(
override val symbol: IrSymbol,
val condition: IrCodeElement,

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrNativeDefinition(val form: String, val definitions: List<String>) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {}
}

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrPrefix(val op: IrPrefixOp, val value: IrCodeElement) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(value)

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
enum class IrPrefixOp {
BooleanNot,
UnaryPlus,

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrReturn(val from: IrSymbol, val value: IrCodeElement) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(from)

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrSlab(
val location: IrSlabLocation,
val definitions: List<IrDefinition>

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrSlabLocation(
val form: String,
val path: String

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrStore(override val target: IrSymbol, val value: IrCodeElement) : IrCodeElement, IrSymbolUser {
override fun crawl(block: (IrElement) -> Unit) {
value.crawl(block)

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrSuffix(val op: IrSuffixOp, override val target: IrSymbol) : IrCodeElement, IrSymbolUser {
override fun crawl(block: (IrElement) -> Unit) {
block(target)

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
enum class IrSuffixOp {
Increment,
Decrement

View File

@ -1,5 +1,24 @@
package gay.pizza.pork.bir
data class IrSymbol(val id: UInt, val tag: IrSymbolTag) : IrElement {
import kotlinx.serialization.Serializable
@Serializable
data class IrSymbol(val id: UInt, val tag: IrSymbolTag, val name: String? = null) : IrElement {
override fun crawl(block: (IrElement) -> Unit) {}
override fun equals(other: Any?): Boolean {
if (other !is IrSymbol) return false
return other.id == id && other.tag == tag
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + tag.hashCode()
return result
}
val friendlyName: String
get() = if (name != null) {
"$id $tag $name"
} else "$id $tag"
}

View File

@ -4,5 +4,6 @@ class IrSymbolAssignment {
private var index = 0u
private fun nextSymbolId(): UInt = index++
fun next(tag: IrSymbolTag): IrSymbol = IrSymbol(nextSymbolId(), tag)
fun next(tag: IrSymbolTag, name: String? = null): IrSymbol =
IrSymbol(id = nextSymbolId(), tag = tag, name = name)
}

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
sealed interface IrSymbolOwner : IrElement {
val symbol: IrSymbol
}

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
enum class IrSymbolTag {
Function,
Variable,

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
sealed interface IrSymbolUser : IrElement {
val target: IrSymbol
}

View File

@ -27,6 +27,8 @@ interface IrVisitor<T> {
fun visitIrWorld(ir: IrWorld): T
fun visitIrNativeDefinition(ir: IrNativeDefinition): T
fun visitIrFunctionArgument(ir: IrFunctionArgument): T
fun visitIrIndex(ir: IrIndex): T
fun visitIrListSize(ir: IrListSize): T
fun visit(ir: IrElement): T = when (ir) {
is IrBreak -> visitIrBeak(ir)
@ -55,5 +57,7 @@ interface IrVisitor<T> {
is IrWorld -> visitIrWorld(ir)
is IrNativeDefinition -> visitIrNativeDefinition(ir)
is IrFunctionArgument -> visitIrFunctionArgument(ir)
is IrIndex -> visitIrIndex(ir)
is IrListSize -> visitIrListSize(ir)
}
}

View File

@ -1,5 +1,8 @@
package gay.pizza.pork.bir
import kotlinx.serialization.Serializable
@Serializable
data class IrWorld(val slabs: List<IrSlab>) : IrElement {
override fun crawl(block: (IrElement) -> Unit) {
slabs.forEach(block)