compiler: full support for IR based compilation

This commit is contained in:
2023-11-23 21:48:10 -08:00
parent 2d88666f05
commit 8951c3cd60
32 changed files with 554 additions and 400 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -2,5 +2,6 @@ package gay.pizza.pork.bir
enum class IrDefinitionType {
Variable,
Function
CodeFunction,
NativeFunction
}

View File

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

View File

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

View File

@ -1,6 +1,10 @@
package gay.pizza.pork.bir
data class IrLoop(val symbol: IrSymbol, val condition: IrCodeElement, val inner: IrCodeElement) : IrCodeElement {
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)

View File

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

View File

@ -1,6 +1,6 @@
package gay.pizza.pork.bir
data class IrStore(val symbol: IrSymbol, val value: IrCodeElement) : IrCodeElement {
data class IrStore(override val target: IrSymbol, val value: IrCodeElement) : IrCodeElement, IrSymbolUser {
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,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,5 @@
package gay.pizza.pork.bir
sealed interface IrSymbolUser : IrElement {
val target: IrSymbol
}

View File

@ -0,0 +1,59 @@
package gay.pizza.pork.bir
interface IrVisitor<T> {
fun visitIrSlab(ir: IrSlab): T
fun visitIrSlabLocation(ir: IrSlabLocation): T
fun visitIrDefinition(ir: IrDefinition): T
fun visitIrSymbol(ir: IrSymbol): T
fun visitIrBeak(ir: IrBreak): T
fun visitIrCall(ir: IrCall): T
fun visitIrCodeBlock(ir: IrCodeBlock): T
fun visitIrConditional(ir: IrConditional): T
fun visitIrBooleanConstant(ir: IrBooleanConstant): T
fun visitIrIntegerConstant(ir: IrIntegerConstant): T
fun visitIrLongConstant(ir: IrLongConstant): T
fun visitIrDoubleConstant(ir: IrDoubleConstant): T
fun visitIrStringConstant(ir: IrStringConstant): T
fun visitIrNoneConstant(ir: IrNoneConstant): T
fun visitIrContinue(ir: IrContinue): T
fun visitIrInfix(ir: IrInfix): T
fun visitIrList(ir: IrList): T
fun visitIrLoad(ir: IrLoad): T
fun visitIrLoop(ir: IrLoop): T
fun visitIrPrefix(ir: IrPrefix): T
fun visitIrReturn(ir: IrReturn): T
fun visitIrStore(ir: IrStore): T
fun visitIrSuffix(ir: IrSuffix): T
fun visitIrWorld(ir: IrWorld): T
fun visitIrNativeDefinition(ir: IrNativeDefinition): T
fun visitIrFunctionArgument(ir: IrFunctionArgument): T
fun visit(ir: IrElement): T = when (ir) {
is IrBreak -> visitIrBeak(ir)
is IrCall -> visitIrCall(ir)
is IrCodeBlock -> visitIrCodeBlock(ir)
is IrConditional -> visitIrConditional(ir)
is IrBooleanConstant -> visitIrBooleanConstant(ir)
is IrDoubleConstant -> visitIrDoubleConstant(ir)
is IrIntegerConstant -> visitIrIntegerConstant(ir)
is IrLongConstant -> visitIrLongConstant(ir)
is IrNoneConstant -> visitIrNoneConstant(ir)
is IrStringConstant -> visitIrStringConstant(ir)
is IrContinue -> visitIrContinue(ir)
is IrInfix -> visitIrInfix(ir)
is IrList -> visitIrList(ir)
is IrLoad -> visitIrLoad(ir)
is IrLoop -> visitIrLoop(ir)
is IrPrefix -> visitIrPrefix(ir)
is IrReturn -> visitIrReturn(ir)
is IrStore -> visitIrStore(ir)
is IrSuffix -> visitIrSuffix(ir)
is IrDefinition -> visitIrDefinition(ir)
is IrSlab -> visitIrSlab(ir)
is IrSlabLocation -> visitIrSlabLocation(ir)
is IrSymbol -> visitIrSymbol(ir)
is IrWorld -> visitIrWorld(ir)
is IrNativeDefinition -> visitIrNativeDefinition(ir)
is IrFunctionArgument -> visitIrFunctionArgument(ir)
}
}

View File

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