This commit is contained in:
2023-11-22 21:40:09 -08:00
parent 76290a401a
commit 2692e3c991
44 changed files with 669 additions and 0 deletions

7
bir/build.gradle.kts Normal file
View File

@ -0,0 +1,7 @@
plugins {
id("gay.pizza.pork.module")
}
dependencies {
implementation(project(":common"))
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrAccess(override val target: IrSymbol) : IrCodeElement, IrSymbolUser {
override fun crawl(block: (IrElement) -> Unit) {
block(target)
}
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrBreak(val target: IrSymbol) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(target)
}
}

View File

@ -0,0 +1,13 @@
package gay.pizza.pork.bir
data class IrCall(
override val target: IrSymbol,
val arguments: List<IrCodeElement>,
val variableArguments: List<IrCodeElement>?
) : IrCodeElement, IrSymbolUser {
override fun crawl(block: (IrElement) -> Unit) {
block(target)
arguments.forEach(block)
variableArguments?.forEach(block)
}
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrCodeBlock(val items: List<IrCodeElement>) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
items.forEach(block)
}
}

View File

@ -0,0 +1,3 @@
package gay.pizza.pork.bir
sealed interface IrCodeElement : IrElement

View File

@ -0,0 +1,13 @@
package gay.pizza.pork.bir
data class IrConditional(
val conditional: IrCodeElement,
val ifTrue: IrCodeElement,
val ifFalse: IrCodeElement
) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(conditional)
block(ifTrue)
block(ifFalse)
}
}

View File

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

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrContinue(override val target: IrSymbol) : IrCodeElement, IrSymbolUser {
override fun crawl(block: (IrElement) -> Unit) {
block(target)
}
}

View File

@ -0,0 +1,12 @@
package gay.pizza.pork.bir
data class IrDefinition(
override val symbol: IrSymbol,
val type: IrDefinitionType,
val code: IrCodeBlock
) : IrElement, IrSymbolOwner {
override fun crawl(block: (IrElement) -> Unit) {
block(symbol)
block(code)
}
}

View File

@ -0,0 +1,6 @@
package gay.pizza.pork.bir
enum class IrDefinitionType {
Variable,
Function
}

View File

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

View File

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

View File

@ -0,0 +1,21 @@
package gay.pizza.pork.bir
enum class IrInfixOp {
Add,
Subtract,
Multiply,
Divide,
Equals,
NotEquals,
EuclideanModulo,
Remainder,
Lesser,
Greater,
LesserEqual,
GreaterEqual,
BooleanAnd,
BooleanOr,
BinaryAnd,
BinaryOr,
BinaryExclusiveOr
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrList(val items: List<IrCodeElement>) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
items.forEach(block)
}
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrLoad(val symbol: IrSymbol) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(symbol)
}
}

View File

@ -0,0 +1,13 @@
package gay.pizza.pork.bir
data class IrLoop(
override val symbol: IrSymbol,
val condition: IrCodeElement,
val inner: IrCodeElement
) : IrCodeElement, IrSymbolOwner {
override fun crawl(block: (IrElement) -> Unit) {
block(symbol)
block(condition)
block(inner)
}
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrPrefix(val op: IrPrefixOp, val value: IrCodeElement) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
block(value)
}
}

View File

@ -0,0 +1,8 @@
package gay.pizza.pork.bir
enum class IrPrefixOp {
BooleanNot,
UnaryPlus,
UnaryMinus,
BinaryNot
}

View File

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

View File

@ -0,0 +1,11 @@
package gay.pizza.pork.bir
data class IrSlab(
val location: IrSlabLocation,
val definitions: List<IrDefinition>
) : IrElement {
override fun crawl(block: (IrElement) -> Unit) {
block(location)
definitions.forEach(block)
}
}

View File

@ -0,0 +1,8 @@
package gay.pizza.pork.bir
data class IrSlabLocation(
val form: String,
val path: String
) : IrElement {
override fun crawl(block: (IrElement) -> Unit) {}
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrStore(val symbol: IrSymbol, val value: IrCodeElement) : IrCodeElement {
override fun crawl(block: (IrElement) -> Unit) {
value.crawl(block)
}
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrSuffix(val op: IrSuffixOp, override val target: IrSymbol) : IrCodeElement, IrSymbolUser {
override fun crawl(block: (IrElement) -> Unit) {
block(target)
}
}

View File

@ -0,0 +1,6 @@
package gay.pizza.pork.bir
enum class IrSuffixOp {
Increment,
Decrement
}

View File

@ -0,0 +1,5 @@
package gay.pizza.pork.bir
data class IrSymbol(val id: UInt, val tag: IrSymbolTag) : IrElement {
override fun crawl(block: (IrElement) -> Unit) {}
}

View File

@ -0,0 +1,8 @@
package gay.pizza.pork.bir
class IrSymbolAssignment {
private var index = 0u
private fun nextSymbolId(): UInt = index++
fun next(tag: IrSymbolTag): IrSymbol = IrSymbol(nextSymbolId(), tag)
}

View File

@ -0,0 +1,40 @@
package gay.pizza.pork.bir
class IrSymbolGraph {
private val edges = mutableSetOf<Pair<IrSymbolUser, IrSymbolOwner>>()
private fun crawlForKnown(known: MutableMap<IrSymbol, IrSymbolOwner>, root: IrElement) {
if (root is IrSymbolOwner) {
known[root.symbol] = root
}
root.crawl { item ->
crawlForKnown(known, item)
}
}
private fun crawlForAssociations(known: Map<IrSymbol, IrSymbolOwner>, root: IrElement) {
if (root is IrSymbolUser) {
val what = known[root.target]
if (what != null) {
edges.add(root to what)
}
}
root.crawl { item ->
crawlForAssociations(known, item)
}
}
fun crawl(root: IrElement) {
val known = mutableMapOf<IrSymbol, IrSymbolOwner>()
crawlForKnown(known, root)
crawlForAssociations(known, root)
}
fun forEachEdge(block: (IrSymbolUser, IrSymbolOwner) -> Unit) {
for ((from, to) in edges) {
block(from, to)
}
}
}

View File

@ -0,0 +1,5 @@
package gay.pizza.pork.bir
sealed interface IrSymbolOwner : IrElement {
val symbol: IrSymbol
}

View File

@ -0,0 +1,8 @@
package gay.pizza.pork.bir
enum class IrSymbolTag {
Function,
Variable,
Local,
Loop
}

View File

@ -0,0 +1,5 @@
package gay.pizza.pork.bir
sealed interface IrSymbolUser : IrElement {
val target: IrSymbol
}

View File

@ -0,0 +1,7 @@
package gay.pizza.pork.bir
data class IrWorld(val slabs: List<IrSlab>) : IrElement {
override fun crawl(block: (IrElement) -> Unit) {
slabs.forEach(block)
}
}