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 returnType: LLVMVariable
var args = ArrayList<LLVMVariable>() var args = ArrayList<LLVMVariable>()
val variableManager = state.variableManager val variableManager = state.variableManager
val topLevel = 2
var wasReturnOnTopLevel = false
init { init {
val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!! val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!!
@@ -51,12 +53,10 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
codeBuilder.addStartExpression() codeBuilder.addStartExpression()
generateLoadArguments() generateLoadArguments()
evaluateCodeBlock(function.bodyExpression) evaluateCodeBlock(function.bodyExpression, scopeDepth = topLevel)
if (!wasReturnOnTopLevel)
if (returnType.type is LLVMVoidType) { codeBuilder.addAnyReturn(returnType.type)
codeBuilder.addVoidReturn()
}
codeBuilder.addEndExpression() codeBuilder.addEndExpression()
} }
@@ -98,16 +98,16 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
private fun generateLoadArguments() { private fun generateLoadArguments() {
args.forEach(fun(it: LLVMVariable) { args.forEach(fun(it: LLVMVariable) {
if (it.type is LLVMFunctionType) { 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 return
} }
if (it.type !is LLVMReferenceType || (it.type as LLVMReferenceType).isReturn) { if (it.type !is LLVMReferenceType || (it.type as LLVMReferenceType).isReturn) {
val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMLocalScope(), pointer = 0) val loadVariable = LLVMVariable("${it.label}", it.type, it.label, LLVMLocalScope(), pointer = 0)
val allocVar = codeBuilder.loadArgument(loadVariable) val allocVar = codeBuilder.loadArgument(loadVariable)
variableManager.addVariable(it.label, allocVar, 2) variableManager.addVariable(it.label, allocVar, topLevel)
} else { } 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) copyVariable(assignExpression, allocVar)
} }
is LLVMConstant -> { 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) codeBuilder.addConstant(newVar, assignExpression)
variableManager.addVariable(identifier.text, newVar, scopeDepth) variableManager.addVariable(identifier.text, newVar, scopeDepth)
@@ -461,7 +461,9 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
codeBuilder.addReturnOperator(retNativeValue) codeBuilder.addReturnOperator(retNativeValue)
} }
} }
if (scopeDepth == topLevel + 2) {
wasReturnOnTopLevel = true
}
return null return null
} }
} }
@@ -97,6 +97,10 @@ class LLVMBuilder(val arm: Boolean) {
llvmLocalCode.appendln("ret void") llvmLocalCode.appendln("ret void")
} }
fun addAnyReturn(type: LLVMType, value: String = type.defaultValue){
llvmLocalCode.appendln("ret $type $value")
}
fun addStringConstant(variable: LLVMVariable, value: String) { fun addStringConstant(variable: LLVMVariable, value: String) {
val type = variable.type as LLVMStringType val type = variable.type as LLVMStringType
llvmGlobalCode.appendln("$variable = private unnamed_addr constant ${type.fullType()} c\"$value\\00\", align 1") 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
}
}