vm: a functional virtual machine, mostly

This commit is contained in:
2023-11-21 04:04:44 -08:00
parent 4c50d48e1e
commit 5540918e7c
39 changed files with 323 additions and 84 deletions

View File

@ -6,5 +6,6 @@ import kotlinx.serialization.Serializable
data class CompiledWorld(
val constantPool: ConstantPool,
val symbolTable: SymbolTable,
val code: List<Op>
val code: List<Op>,
val annotations: List<OpAnnotation>
)

View File

@ -1,3 +1,21 @@
package gay.pizza.pork.bytecode
class Constant(val id: UInt, val value: ByteArray)
import kotlinx.serialization.Serializable
@Serializable
data class Constant(val id: UInt, val tag: ConstantTag, val value: ByteArray) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
other as Constant
if (id != other.id) return false
if (!value.contentEquals(other.value)) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + value.contentHashCode()
return result
}
}

View File

@ -3,4 +3,4 @@ package gay.pizza.pork.bytecode
import kotlinx.serialization.Serializable
@Serializable
data class ConstantPool(val constants: List<ByteArray>)
data class ConstantPool(val constants: List<Constant>)

View File

@ -0,0 +1,8 @@
package gay.pizza.pork.bytecode
import kotlinx.serialization.Serializable
@Serializable
enum class ConstantTag {
String
}

View File

@ -3,16 +3,16 @@ package gay.pizza.pork.bytecode
class MutableConstantPool {
private val pool = mutableListOf<Constant>()
fun assign(content: ByteArray): UInt {
fun assign(tag: ConstantTag, content: ByteArray): UInt {
for (constant in pool) {
if (constant.value.contentEquals(content)) {
if (constant.value.contentEquals(content) && tag == constant.tag) {
return constant.id
}
}
val id = pool.size.toUInt()
pool.add(Constant(id, content))
pool.add(Constant(id = id, tag = tag, value = content))
return id
}
fun all(): List<Constant> = pool
fun build(): ConstantPool = ConstantPool(pool)
}

View File

@ -0,0 +1,6 @@
package gay.pizza.pork.bytecode
import kotlinx.serialization.Serializable
@Serializable
data class OpAnnotation(val inst: UInt, val text: String)

View File

@ -30,14 +30,16 @@ enum class Opcode(val id: UByte) {
BinaryAnd(28u),
BinaryOr(29u),
BinaryXor(30u),
List(31u),
Integer(32u),
Double(33u),
Call(34u),
EuclideanModulo(35u),
Remainder(36u),
Index(37u),
ScopeIn(38u),
ScopeOut(39u),
ListMake(31u),
ListSize(32u),
Integer(33u),
Double(34u),
Call(35u),
EuclideanModulo(36u),
Remainder(37u),
Index(38u),
ScopeIn(39u),
ScopeOut(40u),
ReturnAddress(41u),
End(255u),
}

View File

@ -5,4 +5,13 @@ import kotlinx.serialization.Serializable
@Serializable
data class SymbolTable(
val symbols: List<SymbolInfo>
)
) {
fun lookup(inst: UInt): Pair<SymbolInfo, UInt>? {
val symbol = symbols.firstOrNull {
(inst >= it.offset) && inst < (it.offset + it.size)
} ?: return null
val rel = inst - symbol.offset
return symbol to rel
}
}