This repository has been archived by the owner on Feb 16, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: modular compiler backend, new llvm backend
- Loading branch information
1 parent
8d59af2
commit a886eaf
Showing
34 changed files
with
293 additions
and
473 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
plugins { | ||
kotlin("multiplatform") | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
kotlin { | ||
jvm() | ||
mingwX64() | ||
linuxX64() | ||
iosArm64() | ||
macosX64() | ||
js().browser() | ||
|
||
sourceSets { | ||
val commonMain by getting { | ||
dependencies { | ||
api(project(":analysis")) | ||
api(project(":frontend")) | ||
} | ||
} | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
backend/common/src/commonMain/kotlin/SeleneCompilerBackend.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package me.gabriel.selene.backend.common | ||
|
||
interface SeleneCompilerBackend { | ||
fun compile( | ||
module: SeleneCompilerModule | ||
): String | ||
} |
13 changes: 13 additions & 0 deletions
13
backend/common/src/commonMain/kotlin/SeleneCompilerModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package me.gabriel.selene.backend.common | ||
|
||
import me.gabriel.selene.analysis.SymbolRepository | ||
import me.gabriel.selene.analysis.signature.Signatures | ||
import me.gabriel.selene.frontend.parsing.SyntaxTree | ||
|
||
data class SeleneCompilerModule( | ||
val name: String, | ||
val symbols: SymbolRepository, | ||
val signatures: Signatures, | ||
val astTree: SyntaxTree, | ||
val stdlib: Boolean | ||
) |
5 changes: 5 additions & 0 deletions
5
backend/common/src/commonMain/kotlin/intrinsic/IntrinsicFunction.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package me.gabriel.selene.backend.common.intrinsic | ||
|
||
abstract class IntrinsicFunction( | ||
val name: String | ||
) |
7 changes: 7 additions & 0 deletions
7
backend/common/src/commonMain/kotlin/intrinsic/IntrinsicFunctionExecutor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package me.gabriel.selene.backend.common.intrinsic | ||
|
||
abstract class IntrinsicFunctionExecutor<T : IntrinsicFunction>( | ||
val function: T | ||
) { | ||
abstract fun execute(): String | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
plugins { | ||
kotlin("multiplatform") | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
} | ||
|
||
kotlin { | ||
jvm() | ||
mingwX64() | ||
linuxX64() | ||
iosArm64() | ||
macosX64() | ||
js().browser() | ||
|
||
sourceSets { | ||
val commonMain by getting { | ||
dependencies { | ||
implementation(project(":ryujin")) | ||
implementation(project(":backend:common")) | ||
} | ||
} | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
backend/llvm/src/commonMain/kotlin/DragonCompilerBackend.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package me.gabriel.selene.backend.llvm | ||
|
||
import me.gabriel.ryujin.transcript.DefaultDragonIrTranscriber | ||
import me.gabriel.ryujin.transcript.DragonIrTranscriber | ||
import me.gabriel.selene.backend.common.SeleneCompilerBackend | ||
import me.gabriel.selene.backend.common.SeleneCompilerModule | ||
import me.gabriel.selene.backend.llvm.session.SeleneDragonCompilingSession | ||
|
||
class DragonCompilerBackend: SeleneCompilerBackend { | ||
var irTranscriber: DragonIrTranscriber = DefaultDragonIrTranscriber() | ||
|
||
override fun compile(module: SeleneCompilerModule): String { | ||
// TODO: remove | ||
if (module.stdlib) return "" | ||
|
||
val session = SeleneDragonCompilingSession(module) | ||
val dragonModule = session.compile() | ||
return irTranscriber.transcribe(dragonModule) | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
backend/llvm/src/commonMain/kotlin/session/SeleneDragonCompilingSession.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package me.gabriel.selene.backend.llvm.session | ||
|
||
import me.gabriel.ryujin.DragonModule | ||
import me.gabriel.ryujin.dsl.FunctionScopeDsl | ||
import me.gabriel.ryujin.dsl.ModuleScopeDsl | ||
import me.gabriel.ryujin.dsl.ryujinModule | ||
import me.gabriel.ryujin.struct.Constant | ||
import me.gabriel.ryujin.struct.Value | ||
import me.gabriel.ryujin.struct.Void | ||
import me.gabriel.selene.backend.common.SeleneCompilerModule | ||
import me.gabriel.selene.backend.llvm.util.addPointerToStructs | ||
import me.gabriel.selene.backend.llvm.util.asDragonType | ||
import me.gabriel.selene.frontend.parsing.FunctionNode | ||
import me.gabriel.selene.frontend.parsing.NumberNode | ||
import me.gabriel.selene.frontend.parsing.ReturnNode | ||
import me.gabriel.selene.frontend.parsing.SyntaxTreeNode | ||
|
||
class SeleneDragonCompilingSession( | ||
val module: SeleneCompilerModule | ||
) { | ||
private val dsl = ryujinModule {} | ||
private val root = module.astTree.root | ||
|
||
// todo: remove | ||
var developmentMode: Boolean = true | ||
|
||
fun compile(): DragonModule { | ||
return ryujinModule { | ||
generateModuleLevelDeclarations() | ||
} | ||
} | ||
|
||
private fun ModuleScopeDsl.generateModuleLevelDeclarations() { | ||
for (child in root.getChildren()) { | ||
when (child) { | ||
is FunctionNode -> generateFunction(child) | ||
else -> if (developmentMode) continue else error("Unsupported module-level node: $child") | ||
} | ||
} | ||
} | ||
|
||
private fun ModuleScopeDsl.generateFunction(node: FunctionNode) { | ||
val returnType = addPointerToStructs(node.returnType.asDragonType()) | ||
val parameterTypes = node.parameters.map { addPointerToStructs(it.type.asDragonType()) } | ||
|
||
function( | ||
name = node.name, | ||
returnType = returnType, | ||
parameters = parameterTypes, | ||
) { | ||
for (instruction in node.body.getChildren()) { | ||
generateInstruction(instruction) | ||
} | ||
} | ||
} | ||
|
||
private fun FunctionScopeDsl.generateInstruction(node: SyntaxTreeNode): Value? { | ||
return when (node) { | ||
is ReturnNode -> generateReturn(node) | ||
is NumberNode -> generateNumber(node) | ||
else -> error("Unsupported AST tree node instruction: ${node::class.simpleName}") | ||
} | ||
} | ||
|
||
private fun FunctionScopeDsl.generateReturn(node: ReturnNode): Value? { | ||
val value = generateInstruction(node.expression) | ||
`return`(value ?: Void) | ||
return null | ||
} | ||
|
||
private fun FunctionScopeDsl.generateNumber(node: NumberNode): Value { | ||
return Constant.Number( | ||
type = node.type.asDragonType(), | ||
value = node.value | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package me.gabriel.selene.backend.llvm.util | ||
|
||
import me.gabriel.ryujin.struct.DragonType | ||
import me.gabriel.selene.frontend.SeleneType | ||
|
||
fun SeleneType.asDragonType(): DragonType = when (this) { | ||
SeleneType.String -> DragonType.Pointer(DragonType.Int8) | ||
SeleneType.Void -> DragonType.Void | ||
SeleneType.Any -> DragonType.Int32 | ||
SeleneType.Int8 -> DragonType.Int8 | ||
SeleneType.Int16 -> DragonType.Int16 | ||
SeleneType.Int32 -> DragonType.Int32 | ||
SeleneType.Int64 -> DragonType.Int64 | ||
SeleneType.Float32 -> DragonType.Float32 | ||
SeleneType.Float64 -> DragonType.Float64 | ||
SeleneType.Boolean -> DragonType.Int1 | ||
is SeleneType.FixedArray -> DragonType.Array( | ||
type = this.baseType.asDragonType(), | ||
length = this.length | ||
) | ||
is SeleneType.DynamicArray -> DragonType.Pointer(this.baseType.asDragonType()) | ||
is SeleneType.Struct -> DragonType.Struct( | ||
name = this.identifier, | ||
types = this.fields.values.map { addPointerToStructs(it.asDragonType()) } | ||
) | ||
is SeleneType.Mutable -> this.baseType.asDragonType() | ||
is SeleneType.Lambda -> DragonType.Ptr | ||
else -> error("Unsupported LLVM type $this") | ||
} | ||
|
||
|
||
fun addPointerToStructs(returnType: DragonType): DragonType { | ||
return when (returnType) { | ||
is DragonType.Struct, is DragonType.Array -> DragonType.Pointer(returnType) | ||
else -> returnType | ||
} | ||
} |
Oops, something went wrong.