translator: add global constants, default type value, codegen for KtProperty
This commit is contained in:
@@ -3,6 +3,7 @@ package org.kotlinnative.translator
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
|
||||
class FileTranslator(val state: TranslationState, val file: KtFile) {
|
||||
@@ -21,15 +22,22 @@ class FileTranslator(val state: TranslationState, val file: KtFile) {
|
||||
is KtNamedFunction -> {
|
||||
val function = FunctionCodegen(state, declaration, codeBuilder)
|
||||
state.functions.put(function.name, function)
|
||||
|
||||
}
|
||||
is KtClass -> {
|
||||
val codegen = ClassCodegen(state, declaration, codeBuilder)
|
||||
state.classes.put(declaration.name!!, codegen)
|
||||
}
|
||||
is KtProperty -> {
|
||||
val property = PropertyCodegen(state, declaration, codeBuilder)
|
||||
state.properties.put(declaration.name!!, property)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (property in state.properties.values) {
|
||||
property.generate()
|
||||
}
|
||||
|
||||
for (clazz in state.classes.values) {
|
||||
clazz.generate()
|
||||
}
|
||||
|
||||
@@ -311,13 +311,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
|
||||
when (assignExpression) {
|
||||
is LLVMVariable -> {
|
||||
val allocVar = variableManager.getVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
||||
val allocVar = variableManager.receiveVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
||||
codeBuilder.allocVar(allocVar)
|
||||
variableManager.addVariable(identifier.text, allocVar, scopeDepth)
|
||||
codeBuilder.copyVariableValue(assignExpression, allocVar)
|
||||
}
|
||||
is LLVMConstant -> {
|
||||
val newVar = variableManager.getVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
||||
val newVar = variableManager.receiveVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
||||
|
||||
codeBuilder.addConstant(newVar, assignExpression)
|
||||
variableManager.addVariable(identifier.text, newVar, scopeDepth)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMMapStandardType
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
|
||||
|
||||
class PropertyCodegen(val state: TranslationState, val property: KtProperty, val codeBuilder: LLVMBuilder) {
|
||||
private val variableManager = state.variableManager
|
||||
|
||||
companion object PropertyState {
|
||||
|
||||
}
|
||||
|
||||
fun generate() {
|
||||
val varInfo = state.bindingContext.get(BindingContext.VARIABLE, property)?.compileTimeInitializer ?: return
|
||||
|
||||
val kotlinType = varInfo.type
|
||||
val value = varInfo.value
|
||||
//[TODO] compile time initizializer
|
||||
if (kotlinType.nameIfStandardType != null) {
|
||||
val variableType = LLVMMapStandardType(property.name ?: return, kotlinType).type
|
||||
val variable = LLVMVariable("@" + property.name, variableType, property.name.toString(), pointer = true)
|
||||
variableManager.addGlobalVariable(property.name.toString(), variable)
|
||||
codeBuilder.declareGlovalVariable(variable, variableType.parseArg(value.toString()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -23,8 +23,9 @@ import java.util.*
|
||||
class TranslationState(val environment: KotlinCoreEnvironment, val bindingContext: BindingContext, val arm: Boolean) {
|
||||
|
||||
var functions = HashMap<String, FunctionCodegen>()
|
||||
var classes = HashMap<String, ClassCodegen>()
|
||||
val variableManager = VariableManager()
|
||||
var classes = HashMap<String, ClassCodegen>()
|
||||
var properties = HashMap<String, PropertyCodegen>()
|
||||
}
|
||||
|
||||
fun parseAndAnalyze(sources: List<String>, disposer: Disposable, arm: Boolean = false): TranslationState {
|
||||
|
||||
@@ -24,7 +24,11 @@ class VariableManager {
|
||||
fileVariableCollectionTree.put(name, stack)
|
||||
}
|
||||
|
||||
fun getVariable(name: String, type: LLVMType, pointer: Boolean): LLVMVariable {
|
||||
fun addGlobalVariable(name: String, variable: LLVMVariable) {
|
||||
globalVariableCollection.put(name, variable)
|
||||
}
|
||||
|
||||
fun receiveVariable(name: String, type: LLVMType, pointer: Boolean): LLVMVariable {
|
||||
val ourVersion = variableVersion.getOrDefault(name, 0) + 1
|
||||
variableVersion.put(name, ourVersion)
|
||||
|
||||
|
||||
@@ -152,6 +152,10 @@ class LLVMBuilder(val arm: Boolean) {
|
||||
llvmCode.appendln("store ${allocVariable.type} $constantValue, ${allocVariable.getType()} $allocVariable, align ${allocVariable.type.align}")
|
||||
}
|
||||
|
||||
fun declareGlovalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) {
|
||||
llvmCode.appendln("$variable = global ${variable.type} $defaultValue, align ${variable.type.align}")
|
||||
}
|
||||
|
||||
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
|
||||
assert(!source.pointer)
|
||||
val target = getNewVariable(source.type, source.pointer, source.kotlinName)
|
||||
|
||||
+2
-1
@@ -36,7 +36,7 @@ class LLVMBooleanType() : LLVMType() {
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne i1 $firstOp, $secondOp")
|
||||
|
||||
override fun parseArg(inputArg: String) = when(inputArg.toLowerCase()){
|
||||
override fun parseArg(inputArg: String) = when (inputArg.toLowerCase()) {
|
||||
"true" -> "1"
|
||||
"false" -> "0"
|
||||
else -> throw IllegalArgumentException("Failed to parse boolean type")
|
||||
@@ -44,6 +44,7 @@ class LLVMBooleanType() : LLVMType() {
|
||||
|
||||
override val align = 4
|
||||
override val size: Byte = 1
|
||||
override val defaultValue = "0"
|
||||
|
||||
override fun toString() = "i1"
|
||||
}
|
||||
@@ -25,4 +25,5 @@ class LLVMCharType() : LLVMType() {
|
||||
override val align = 1
|
||||
override val size: Byte = 1
|
||||
override fun toString(): String = "i8"
|
||||
override val defaultValue = "0"
|
||||
}
|
||||
|
||||
@@ -21,4 +21,5 @@ class LLVMDoubleType() : LLVMType() {
|
||||
override val align = 8
|
||||
override val size: Byte = 8
|
||||
override fun toString() = "double"
|
||||
override val defaultValue = "0.0"
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import org.kotlinnative.translator.llvm.LLVMMapStandardType
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
|
||||
class LLVMFunctionType(type: KotlinType) : LLVMType() {
|
||||
|
||||
override val defaultValue = throw UnsupportedOperationException()
|
||||
override val align: Int = 4
|
||||
override val size: Byte = 4
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ class LLVMIntType() : LLVMType() {
|
||||
|
||||
override val align = 4
|
||||
override val size: Byte = 4
|
||||
override val defaultValue = "0"
|
||||
|
||||
override fun toString() = "i32"
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import java.util.*
|
||||
|
||||
class LLVMReferenceType(val type: String, val prefix: String = "") : LLVMType() {
|
||||
|
||||
override val defaultValue = throw UnsupportedOperationException()
|
||||
override val align = 4
|
||||
override val size: Byte = 4
|
||||
override fun toString() = "%$prefix.$type"
|
||||
|
||||
@@ -24,5 +24,7 @@ class LLVMShortType() : LLVMType() {
|
||||
|
||||
override val size: Byte = 2
|
||||
override val align = 2
|
||||
override val defaultValue = "0"
|
||||
|
||||
override fun toString(): String = "i16"
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ abstract class LLVMType() : Cloneable {
|
||||
|
||||
abstract val align: Int
|
||||
abstract val size: Byte
|
||||
abstract val defaultValue: String
|
||||
}
|
||||
|
||||
fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||
|
||||
@@ -4,5 +4,7 @@ class LLVMVoidType() : LLVMType() {
|
||||
|
||||
override val align = 0
|
||||
override val size: Byte = 0
|
||||
override val defaultValue = throw UnsupportedOperationException()
|
||||
|
||||
override fun toString(): String = "void"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user