translator: add global constants, default type value, codegen for KtProperty

This commit is contained in:
Alexey Stepanov
2016-07-14 10:51:25 +03:00
parent b7149c9341
commit 21d0e5f5ca
15 changed files with 68 additions and 6 deletions
@@ -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)
@@ -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"
}