translator: fix constant types, labels without returns, add tests for while

This commit is contained in:
Alexey Stepanov
2016-07-15 11:43:05 +03:00
parent 303a6ffe46
commit cf5ae6312a
5 changed files with 25 additions and 10 deletions
@@ -21,6 +21,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
var returnType: LLVMVariable
var args = ArrayList<LLVMVariable>()
val variableManager = state.variableManager
val topLevel = 2
var wasReturnOnTopLevel = false
init {
val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!!
@@ -51,12 +53,10 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
codeBuilder.addStartExpression()
generateLoadArguments()
evaluateCodeBlock(function.bodyExpression)
evaluateCodeBlock(function.bodyExpression, scopeDepth = topLevel)
if (returnType.type is LLVMVoidType) {
codeBuilder.addVoidReturn()
}
if (!wasReturnOnTopLevel)
codeBuilder.addAnyReturn(returnType.type)
codeBuilder.addEndExpression()
}
@@ -98,16 +98,16 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
private fun generateLoadArguments() {
args.forEach(fun(it: LLVMVariable) {
if (it.type is LLVMFunctionType) {
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 1), 2)
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 1), topLevel)
return
}
if (it.type !is LLVMReferenceType || (it.type as LLVMReferenceType).isReturn) {
val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMLocalScope(), pointer = 0)
val allocVar = codeBuilder.loadArgument(loadVariable)
variableManager.addVariable(it.label, allocVar, 2)
variableManager.addVariable(it.label, allocVar, topLevel)
} else {
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 0), 2)
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMLocalScope(), pointer = 0), topLevel)
}
})
}
@@ -432,7 +432,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
copyVariable(assignExpression, allocVar)
}
is LLVMConstant -> {
val newVar = variableManager.receiveVariable(identifier!!.text, LLVMIntType(), LLVMLocalScope(), pointer = 1)
val newVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type!!, LLVMLocalScope(), pointer = 1)
codeBuilder.addConstant(newVar, assignExpression)
variableManager.addVariable(identifier.text, newVar, scopeDepth)
@@ -461,7 +461,9 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
codeBuilder.addReturnOperator(retNativeValue)
}
}
if (scopeDepth == topLevel + 2) {
wasReturnOnTopLevel = true
}
return null
}
}
@@ -97,6 +97,10 @@ class LLVMBuilder(val arm: Boolean) {
llvmLocalCode.appendln("ret void")
}
fun addAnyReturn(type: LLVMType, value: String = type.defaultValue){
llvmLocalCode.appendln("ret $type $value")
}
fun addStringConstant(variable: LLVMVariable, value: String) {
val type = variable.type as LLVMStringType
llvmGlobalCode.appendln("$variable = private unnamed_addr constant ${type.fullType()} c\"$value\\00\", align 1")
@@ -0,0 +1 @@
while_test_2(77)
@@ -0,0 +1 @@
78
@@ -0,0 +1,7 @@
fun while_test_2(x: Int): Int {
var a = x
while (2 < 3) {
a = x + 1
return a
}
}