diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt index c4a940c732e..6a9c12f531b 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt @@ -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() } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 6c730563e65..61a4442dc8c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -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) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt new file mode 100644 index 00000000000..6cb214b9c71 --- /dev/null +++ b/translator/src/main/kotlin/org/kotlinnative/translator/PropertyCodegen.kt @@ -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())) + } + } + + +} \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index c0e26f3969c..8a4575f8104 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -23,8 +23,9 @@ import java.util.* class TranslationState(val environment: KotlinCoreEnvironment, val bindingContext: BindingContext, val arm: Boolean) { var functions = HashMap() - var classes = HashMap() val variableManager = VariableManager() + var classes = HashMap() + var properties = HashMap() } fun parseAndAnalyze(sources: List, disposer: Disposable, arm: Boolean = false): TranslationState { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt index f38fe35b257..c72be95ad4c 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt @@ -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) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index 6da8a8a8a19..a3cc1bba7b6 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -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) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt index c79056ff29d..c282bf2af95 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt @@ -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" } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt index b44795c9987..5ddbda01d76 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt @@ -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" } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt index 79b7db3f3bb..c360f0c39a9 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt @@ -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" } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt index c7de12cc1bf..de36ddf3dec 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt @@ -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 diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt index c5ff208cb35..eeed8b70b8f 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt @@ -39,6 +39,7 @@ class LLVMIntType() : LLVMType() { override val align = 4 override val size: Byte = 4 + override val defaultValue = "0" override fun toString() = "i32" } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt index 6c71c088188..07cc486c633 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt @@ -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" diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt index 3586e66af9f..6f8f99fce45 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt @@ -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" } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt index 05ffe0e0179..b9399ae90e8 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt @@ -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) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt index 4790c3674b0..6d5bb0ace54 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt @@ -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" }