translator: add if expression version, refactoring to LLVMSingleValue

This commit is contained in:
Alexey Stepanov
2016-07-13 13:50:16 +03:00
parent faba4a8f3a
commit 8e03cebe9b
4 changed files with 42 additions and 17 deletions
@@ -74,7 +74,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
private fun evaluateCodeBlock(expr: PsiElement?, startLabel: LLVMLabel?, finishLabel: LLVMLabel?, scopeDepth: Int) { private fun evaluateCodeBlock(expr: PsiElement?, startLabel: LLVMLabel?, finishLabel: LLVMLabel?, scopeDepth: Int) {
codeBuilder.markWithLabel(startLabel) codeBuilder.markWithLabel(startLabel)
expressionWalker(expr, scopeDepth = scopeDepth) expressionWalker(expr, scopeDepth)
codeBuilder.addUnconditionJump(finishLabel ?: return) codeBuilder.addUnconditionJump(finishLabel ?: return)
} }
@@ -94,12 +94,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
expressionWalker(expr.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) expressionWalker(expr.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth)
} }
private fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMNode? { private fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? {
return when (expr) { return when (expr) {
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth) is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
is KtConstantExpression -> evaluateConstantExpression(expr) is KtConstantExpression -> evaluateConstantExpression(expr)
is KtCallExpression -> evaluateCallExpression(expr) is KtCallExpression -> evaluateCallExpression(expr)
is KtReferenceExpression -> evaluateReferenceExpression(expr) is KtReferenceExpression -> evaluateReferenceExpression(expr)
is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, true)
is PsiWhiteSpace -> null is PsiWhiteSpace -> null
is PsiElement -> evaluatePsiElement(expr, scopeDepth) is PsiElement -> evaluatePsiElement(expr, scopeDepth)
null -> null null -> null
@@ -107,12 +108,12 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
} }
} }
private fun evaluateReferenceExpression(expr: KtReferenceExpression): LLVMNode? { private fun evaluateReferenceExpression(expr: KtReferenceExpression): LLVMSingleValue? {
val variableName = expr.firstChild.text val variableName = expr.firstChild.text
return variableManager.getLLVMvalue(variableName) return variableManager.getLLVMvalue(variableName)
} }
private fun evaluateCallExpression(expr: KtCallExpression): LLVMNode? { private fun evaluateCallExpression(expr: KtCallExpression): LLVMSingleValue? {
val function = expr.firstChild.firstChild.text val function = expr.firstChild.firstChild.text
if (state.functions.containsKey(function)) { if (state.functions.containsKey(function)) {
@@ -126,7 +127,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
return null return null
} }
private fun evaluteConstructorCallExpression(expr: KtCallExpression): LLVMNode? { private fun evaluteConstructorCallExpression(expr: KtCallExpression): LLVMSingleValue? {
val function = expr.firstChild.firstChild val function = expr.firstChild.firstChild
val descriptor = state.classes[function.text] ?: return null val descriptor = state.classes[function.text] ?: return null
val names = parseArgList(expr val names = parseArgList(expr
@@ -146,7 +147,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
}) })
} }
private fun evaluteFunctionCallExpression(expr: KtCallExpression): LLVMNode? { private fun evaluteFunctionCallExpression(expr: KtCallExpression): LLVMSingleValue? {
val function = expr.firstChild.firstChild val function = expr.firstChild.firstChild
val descriptor = state.functions[function.text] ?: return null val descriptor = state.functions[function.text] ?: return null
@@ -177,8 +178,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
} }
private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable { private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
val left = evaluateExpression(expr.firstChild, scopeDepth) as LLVMSingleValue? ?: throw UnsupportedOperationException("Wrong binary exception") val left = evaluateExpression(expr.firstChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
val right = evaluateExpression(expr.lastChild, scopeDepth) as LLVMSingleValue? ?: throw UnsupportedOperationException("Wrong binary exception") val right = evaluateExpression(expr.lastChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
val operator = expr.operationToken val operator = expr.operationToken
return codeBuilder.addPrimitiveBinaryOperation(operator, left, right) return codeBuilder.addPrimitiveBinaryOperation(operator, left, right)
} }
@@ -202,12 +203,12 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth) KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth)
KtTokens.VAL_KEYWORD -> evaluateValExpression(element, scopeDepth) KtTokens.VAL_KEYWORD -> evaluateValExpression(element, scopeDepth)
KtTokens.VAR_KEYWORD -> evaluateValExpression(element, scopeDepth) KtTokens.VAR_KEYWORD -> evaluateValExpression(element, scopeDepth)
KtTokens.IF_KEYWORD -> evaluateIfExpression(element, scopeDepth) KtTokens.IF_KEYWORD -> evaluateIfOperator(element, scopeDepth, false)
else -> null else -> null
} }
} }
private fun evaluateIfExpression(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? { private fun evaluateIfOperator(element: LeafPsiElement, scopeDepth: Int, containReturn: Boolean): LLVMVariable? {
var getBrackets = element.getNextSiblingIgnoringWhitespaceAndComments() ?: return null var getBrackets = element.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
@@ -216,10 +217,34 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
val elseExpression = elseKeyword.getNextSiblingIgnoringWhitespaceAndComments() ?: return null val elseExpression = elseKeyword.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
return executeCondition(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, scopeDepth + 1) return when (containReturn) {
false -> executeIfBlock(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, scopeDepth + 1)
true -> executeIfExpression(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, scopeDepth + 1)
}
} }
private fun executeCondition(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, scopeDepth: Int): LLVMVariable? { private fun executeIfExpression(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, scopeDepth: Int): LLVMVariable? {
val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1)
val variable = codeBuilder.getNewVariable(LLVMIntType(), true)
codeBuilder.allocVar(variable)
val thenLabel = codeBuilder.getNewLabel()
val elseLabel = codeBuilder.getNewLabel()
val endLabel = codeBuilder.getNewLabel()
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
codeBuilder.markWithLabel(thenLabel)
val thenResultExpression = evaluateExpression(thenExpression, scopeDepth + 1)
codeBuilder.storeVariable(variable, thenResultExpression ?: return null)
codeBuilder.addUnconditionJump(endLabel)
codeBuilder.markWithLabel(elseLabel)
val elseResultExpression = evaluateExpression(elseExpression, scopeDepth + 1)
codeBuilder.storeVariable(variable, elseResultExpression ?: return null)
codeBuilder.addUnconditionJump(endLabel)
codeBuilder.markWithLabel(endLabel)
return variable
}
private fun executeIfBlock(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, scopeDepth: Int): LLVMVariable? {
val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1) val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1)
val thenLabel = codeBuilder.getNewLabel() val thenLabel = codeBuilder.getNewLabel()
val elseLabel = codeBuilder.getNewLabel() val elseLabel = codeBuilder.getNewLabel()
@@ -248,7 +273,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
variableManager.addVariable(identifier.text, assignExpression, scopeDepth) variableManager.addVariable(identifier.text, assignExpression, scopeDepth)
} }
is LLVMConstant -> { is LLVMConstant -> {
val newVar = variableManager.getVariable(identifier!!.text, type = LLVMIntType(), pointer = true) val newVar = variableManager.getVariable(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)
} }
@@ -26,7 +26,7 @@ class LLVMBuilder(val arm: Boolean) {
fun getNewVariable(type: LLVMType?, pointer: Boolean = false, kotlinName: String? = null): LLVMVariable { fun getNewVariable(type: LLVMType?, pointer: Boolean = false, kotlinName: String? = null): LLVMVariable {
variableCount++ variableCount++
return LLVMVariable("%var$variableCount", type, kotlinName = kotlinName, pointer = pointer) return LLVMVariable("%var$variableCount", type, kotlinName, pointer)
} }
fun getNewLabel(scope: LLVMScope = LLVMLocalScope()): LLVMLabel { fun getNewLabel(scope: LLVMScope = LLVMLocalScope()): LLVMLabel {
@@ -145,7 +145,7 @@ class LLVMBuilder(val arm: Boolean) {
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable { fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
assert(!source.pointer) assert(!source.pointer)
val target = getNewVariable(type = source.type, pointer = source.pointer, kotlinName = source.kotlinName) val target = getNewVariable(source.type, source.pointer, source.kotlinName)
val code = "$target = load ${target.type}, ${source.getType()} $source, align ${target.type?.align!!}" val code = "$target = load ${target.type}, ${source.getType()} $source, align ${target.type?.align!!}"
llvmCode.appendln(code) llvmCode.appendln(code)
return target return target
@@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.llvm.types.LLVMType import org.kotlinnative.translator.llvm.types.LLVMType
class LLVMCall(val returnType: LLVMType, val name: String, val arguments: List<LLVMVariable>) : LLVMNode() { class LLVMCall(val returnType: LLVMType, val name: String, val arguments: List<LLVMVariable>) : LLVMSingleValue(returnType) {
override fun toString(): String = override fun toString(): String =
"call $returnType $name(${arguments.joinToString { "${it.getType()} ${it.label}" }})" "call $returnType $name(${arguments.joinToString { "${it.getType()} ${it.label}" }})"
@@ -2,5 +2,5 @@ package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.llvm.types.LLVMType import org.kotlinnative.translator.llvm.types.LLVMType
class LLVMConstructorCall(val type: LLVMType, val call: (LLVMVariable) -> LLVMCall) : LLVMNode() class LLVMConstructorCall(override val type: LLVMType, val call: (LLVMVariable) -> LLVMCall) : LLVMSingleValue()