translator: Nullable types support

This commit is contained in:
e5l
2016-07-19 16:07:10 +03:00
parent 62e444c571
commit 75d386aede
5 changed files with 31 additions and 25 deletions
@@ -332,6 +332,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable
KtNodeTypes.INTEGER_CONSTANT -> LLVMIntType()
KtNodeTypes.FLOAT_CONSTANT -> LLVMDoubleType()
KtNodeTypes.CHARACTER_CONSTANT -> LLVMCharType()
KtNodeTypes.NULL -> LLVMNullType()
else -> throw IllegalArgumentException("Unknown type")
}
return LLVMConstant(node.firstChildNode.text, type, pointer = 0)
@@ -341,29 +342,11 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable
return when (element) {
is LeafPsiElement -> evaluateLeafPsiElement(element, scopeDepth)
is KtConstantExpression -> evaluateConstantExpression(element)
is KtTypeReference -> evaluateTypeReference(element)
KtTokens.INTEGER_LITERAL -> null
else -> null
}
}
private fun evaluateTypeReference(element: KtTypeReference): LLVMSingleValue? {
val type = element.typeElement
val operator = element.getNextSiblingIgnoringWhitespaceAndComments()
val value = operator?.getNextSiblingIgnoringWhitespaceAndComments() as KtConstantExpression
when (type) {
is KtUserType -> {
val i = 1
}
}
// return when (operator) {
// else -> throw UnsupportedOperationException()
// }
return null
}
private fun evaluateLeafPsiElement(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
return when (element.elementType) {
KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth)
@@ -451,7 +434,6 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable
private fun copyVariable(from: LLVMVariable, to: LLVMVariable) = when (from.type) {
is LLVMStringType -> codeBuilder.storeString(to, from, 0)
is LLVMReferenceType -> codeBuilder.copyVariableRef(to, from)
else -> codeBuilder.copyVariableValue(to, from)
}
@@ -474,8 +456,23 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable
}
}
is LLVMConstant -> {
val newVar = variableManager.receiveVariable(identifier, assignExpression.type!!, LLVMRegisterScope(), pointer = 1)
if (assignExpression.type is LLVMNullType) {
val reference = LLVMMapStandardType(identifier, variable.type)
if (state.classes.containsKey(variable.type.toString().dropLast(1))) {
(reference.type as LLVMReferenceType).prefix = "class"
}
codeBuilder.allocStackVar(reference)
reference.pointer += 1
codeBuilder.storeNull(reference)
val result = codeBuilder.loadAndGetVariable(reference)
variableManager.addVariable(identifier, result, scopeDepth)
return null
}
val newVar = variableManager.receiveVariable(identifier, assignExpression.type!!, LLVMRegisterScope(), pointer = 1)
codeBuilder.addConstant(newVar, assignExpression)
variableManager.addVariable(identifier, newVar, scopeDepth)
}
@@ -148,11 +148,16 @@ class LLVMBuilder(val arm: Boolean) {
localCode.appendln(getNewVariable(LLVMIntType()).toString() + " = add i1 0, 0 ; nop instruction")
}
fun storeVariable(target: LLVMVariable, source: LLVMSingleValue) {
fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) {
val code = "store ${source.getType()} $source, ${target.getType()} $target, align ${source.type?.align!!}"
localCode.appendln(code)
}
fun storeNull(result: LLVMVariable) {
val code = "store ${result.getType().dropLast(1)} null, ${result.getType()} $result, align $POINTER_SIZE"
localCode.appendln(code)
}
fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) {
val code = "$target = getelementptr inbounds ${source.type} $source, ${index.type} ${index.value}"
localCode.appendln(code)
@@ -167,10 +172,6 @@ class LLVMBuilder(val arm: Boolean) {
localCode.appendln("store ${target.type} $from, ${target.getType()} $target, align ${from.type.align}")
}
fun copyVariableRef(to: LLVMVariable, from: LLVMVariable) {
var i = 1
}
fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable {
val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = llvmVariable.pointer + 1)
addVariableByRef(allocVar, llvmVariable, store)
@@ -17,5 +17,6 @@ fun LLVMMapStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMR
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString(), scope)
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString(), scope)
type.isUnit() -> LLVMVariable("", LLVMVoidType(), "", scope)
type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType("${type.toString().dropLast(1)}"), name, scope, pointer = 1)
else -> LLVMVariable(name, LLVMReferenceType("$type"), name, scope, pointer = 1)
}
@@ -0,0 +1,7 @@
package org.kotlinnative.translator.llvm.types
class LLVMNullType() : LLVMType() {
override val align: Int = 0
override val size: Byte = 0
override val defaultValue: String = "0"
}