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.KtClass
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||||
|
|
||||||
class FileTranslator(val state: TranslationState, val file: KtFile) {
|
class FileTranslator(val state: TranslationState, val file: KtFile) {
|
||||||
@@ -21,15 +22,22 @@ class FileTranslator(val state: TranslationState, val file: KtFile) {
|
|||||||
is KtNamedFunction -> {
|
is KtNamedFunction -> {
|
||||||
val function = FunctionCodegen(state, declaration, codeBuilder)
|
val function = FunctionCodegen(state, declaration, codeBuilder)
|
||||||
state.functions.put(function.name, function)
|
state.functions.put(function.name, function)
|
||||||
|
|
||||||
}
|
}
|
||||||
is KtClass -> {
|
is KtClass -> {
|
||||||
val codegen = ClassCodegen(state, declaration, codeBuilder)
|
val codegen = ClassCodegen(state, declaration, codeBuilder)
|
||||||
state.classes.put(declaration.name!!, codegen)
|
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) {
|
for (clazz in state.classes.values) {
|
||||||
clazz.generate()
|
clazz.generate()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -311,13 +311,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
|
|
||||||
when (assignExpression) {
|
when (assignExpression) {
|
||||||
is LLVMVariable -> {
|
is LLVMVariable -> {
|
||||||
val allocVar = variableManager.getVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
val allocVar = variableManager.receiveVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
||||||
codeBuilder.allocVar(allocVar)
|
codeBuilder.allocVar(allocVar)
|
||||||
variableManager.addVariable(identifier.text, allocVar, scopeDepth)
|
variableManager.addVariable(identifier.text, allocVar, scopeDepth)
|
||||||
codeBuilder.copyVariableValue(assignExpression, allocVar)
|
codeBuilder.copyVariableValue(assignExpression, allocVar)
|
||||||
}
|
}
|
||||||
is LLVMConstant -> {
|
is LLVMConstant -> {
|
||||||
val newVar = variableManager.getVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
val newVar = variableManager.receiveVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
||||||
|
|
||||||
codeBuilder.addConstant(newVar, assignExpression)
|
codeBuilder.addConstant(newVar, assignExpression)
|
||||||
variableManager.addVariable(identifier.text, newVar, scopeDepth)
|
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) {
|
class TranslationState(val environment: KotlinCoreEnvironment, val bindingContext: BindingContext, val arm: Boolean) {
|
||||||
|
|
||||||
var functions = HashMap<String, FunctionCodegen>()
|
var functions = HashMap<String, FunctionCodegen>()
|
||||||
var classes = HashMap<String, ClassCodegen>()
|
|
||||||
val variableManager = VariableManager()
|
val variableManager = VariableManager()
|
||||||
|
var classes = HashMap<String, ClassCodegen>()
|
||||||
|
var properties = HashMap<String, PropertyCodegen>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun parseAndAnalyze(sources: List<String>, disposer: Disposable, arm: Boolean = false): TranslationState {
|
fun parseAndAnalyze(sources: List<String>, disposer: Disposable, arm: Boolean = false): TranslationState {
|
||||||
|
|||||||
@@ -24,7 +24,11 @@ class VariableManager {
|
|||||||
fileVariableCollectionTree.put(name, stack)
|
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
|
val ourVersion = variableVersion.getOrDefault(name, 0) + 1
|
||||||
variableVersion.put(name, ourVersion)
|
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}")
|
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 {
|
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
|
||||||
assert(!source.pointer)
|
assert(!source.pointer)
|
||||||
val target = getNewVariable(source.type, source.pointer, source.kotlinName)
|
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 =
|
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||||
LLVMExpression(LLVMBooleanType(), "icmp ne i1 $firstOp, $secondOp")
|
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"
|
"true" -> "1"
|
||||||
"false" -> "0"
|
"false" -> "0"
|
||||||
else -> throw IllegalArgumentException("Failed to parse boolean type")
|
else -> throw IllegalArgumentException("Failed to parse boolean type")
|
||||||
@@ -44,6 +44,7 @@ class LLVMBooleanType() : LLVMType() {
|
|||||||
|
|
||||||
override val align = 4
|
override val align = 4
|
||||||
override val size: Byte = 1
|
override val size: Byte = 1
|
||||||
|
override val defaultValue = "0"
|
||||||
|
|
||||||
override fun toString() = "i1"
|
override fun toString() = "i1"
|
||||||
}
|
}
|
||||||
@@ -25,4 +25,5 @@ class LLVMCharType() : LLVMType() {
|
|||||||
override val align = 1
|
override val align = 1
|
||||||
override val size: Byte = 1
|
override val size: Byte = 1
|
||||||
override fun toString(): String = "i8"
|
override fun toString(): String = "i8"
|
||||||
|
override val defaultValue = "0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,4 +21,5 @@ class LLVMDoubleType() : LLVMType() {
|
|||||||
override val align = 8
|
override val align = 8
|
||||||
override val size: Byte = 8
|
override val size: Byte = 8
|
||||||
override fun toString() = "double"
|
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
|
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||||
|
|
||||||
class LLVMFunctionType(type: KotlinType) : LLVMType() {
|
class LLVMFunctionType(type: KotlinType) : LLVMType() {
|
||||||
|
|
||||||
|
override val defaultValue = throw UnsupportedOperationException()
|
||||||
override val align: Int = 4
|
override val align: Int = 4
|
||||||
override val size: Byte = 4
|
override val size: Byte = 4
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ class LLVMIntType() : LLVMType() {
|
|||||||
|
|
||||||
override val align = 4
|
override val align = 4
|
||||||
override val size: Byte = 4
|
override val size: Byte = 4
|
||||||
|
override val defaultValue = "0"
|
||||||
|
|
||||||
override fun toString() = "i32"
|
override fun toString() = "i32"
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ import java.util.*
|
|||||||
|
|
||||||
class LLVMReferenceType(val type: String, val prefix: String = "") : LLVMType() {
|
class LLVMReferenceType(val type: String, val prefix: String = "") : LLVMType() {
|
||||||
|
|
||||||
|
override val defaultValue = throw UnsupportedOperationException()
|
||||||
override val align = 4
|
override val align = 4
|
||||||
override val size: Byte = 4
|
override val size: Byte = 4
|
||||||
override fun toString() = "%$prefix.$type"
|
override fun toString() = "%$prefix.$type"
|
||||||
|
|||||||
@@ -24,5 +24,7 @@ class LLVMShortType() : LLVMType() {
|
|||||||
|
|
||||||
override val size: Byte = 2
|
override val size: Byte = 2
|
||||||
override val align = 2
|
override val align = 2
|
||||||
|
override val defaultValue = "0"
|
||||||
|
|
||||||
override fun toString(): String = "i16"
|
override fun toString(): String = "i16"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ abstract class LLVMType() : Cloneable {
|
|||||||
|
|
||||||
abstract val align: Int
|
abstract val align: Int
|
||||||
abstract val size: Byte
|
abstract val size: Byte
|
||||||
|
abstract val defaultValue: String
|
||||||
}
|
}
|
||||||
|
|
||||||
fun parseLLVMType(type: String): LLVMType = when (type) {
|
fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||||
|
|||||||
@@ -4,5 +4,7 @@ class LLVMVoidType() : LLVMType() {
|
|||||||
|
|
||||||
override val align = 0
|
override val align = 0
|
||||||
override val size: Byte = 0
|
override val size: Byte = 0
|
||||||
|
override val defaultValue = throw UnsupportedOperationException()
|
||||||
|
|
||||||
override fun toString(): String = "void"
|
override fun toString(): String = "void"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user