translator: add if expressions, LLVMScope, fix return by variable, supporting block markup

This commit is contained in:
Alexey Stepanov
2016-07-13 11:49:09 +03:00
parent 3aa0d3021e
commit 8b81d9c38b
4 changed files with 49 additions and 8 deletions
@@ -37,7 +37,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
codeBuilder.addStartExpression()
generateLoadArguments()
expressionWalker(function.bodyExpression)
evaluateCodeBlock(function.bodyExpression, startLabel = null, finishLabel = null, scopeDepth = 0)
if (returnType is LLVMVoidType) {
codeBuilder.addVoidReturn()
@@ -71,7 +72,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
}
}
private fun expressionWalker(expr: PsiElement?, scopeDepth: Int = 0) {
private fun evaluateCodeBlock(expr: PsiElement?, startLabel: LLVMLabel?, finishLabel: LLVMLabel?, scopeDepth: Int) {
codeBuilder.markWithLabel(startLabel)
expressionWalker(expr, scopeDepth = scopeDepth)
codeBuilder.addUnconditionJump(finishLabel ?: return)
}
private fun expressionWalker(expr: PsiElement?, scopeDepth: Int) {
when (expr) {
is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1)
is KtProperty -> evaluateLeafPsiElement(expr.firstChild as LeafPsiElement, scopeDepth)
@@ -205,7 +212,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
val thenExpression = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
val elseExpression = thenExpression.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
val elseKeyword = thenExpression.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
val elseExpression = elseKeyword.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
return executeCondition(condition.firstChild as KtBinaryExpression, thenExpression.firstChild, elseExpression.firstChild, scopeDepth + 1)
@@ -215,9 +223,15 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1)
val thenLabel = codeBuilder.getNewLabel()
val elseLabel = codeBuilder.getNewLabel()
val endLabel = codeBuilder.getNewLabel()
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
evaluateCodeBlock(thenExpression, thenLabel, endLabel, scopeDepth + 1)
evaluateCodeBlock(elseExpression, elseLabel, endLabel, scopeDepth + 1)
codeBuilder.markWithLabel(endLabel)
return null
}
@@ -254,8 +268,9 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
private fun evaluateReturnInstruction(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
val next = element.getNextSiblingIgnoringWhitespaceAndComments()
val retVar = evaluateExpression(next, scopeDepth) as LLVMSingleValue
val retNativeValue = codeBuilder.receiveNativeValue(retVar)
codeBuilder.addReturnOperator(retVar)
codeBuilder.addReturnOperator(retNativeValue)
return null
}
}
@@ -2,6 +2,7 @@ package org.kotlinnative.translator.llvm
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KtTokens
import org.kotlinnative.translator.llvm.types.LLVMIntType
import org.kotlinnative.translator.llvm.types.LLVMType
class LLVMBuilder {
@@ -23,9 +24,9 @@ class LLVMBuilder {
return LLVMVariable("%var$variableCount", type, kotlinName = kotlinName, pointer = pointer)
}
fun getNewLabel(): LLVMLabel {
fun getNewLabel(scope: LLVMScope = LLVMLocalScope()): LLVMLabel {
labelCount++
return LLVMLabel("%label$labelCount")
return LLVMLabel("label$labelCount", scope)
}
fun addLLVMCode(code: String) {
@@ -97,6 +98,15 @@ class LLVMBuilder {
llvmCode.appendln(code)
}
fun markWithLabel(label: LLVMLabel?) {
if (label != null)
llvmCode.appendln("${label.label}:")
}
fun addNopInstruction() {
llvmCode.appendln(getNewVariable(LLVMIntType()).toString() + " = add i1 0, 0 ; nop instruction")
}
fun storeVariable(target: LLVMVariable, source: LLVMSingleValue) {
val code = "store ${source.type} $source, ${target.getType()} $target, align ${source.type?.align!!}"
llvmCode.appendln(code)
@@ -140,6 +150,10 @@ class LLVMBuilder {
llvmCode.appendln("br ${condition.getType()} $condition, label $thenLabel, label $elseLabel")
}
fun addUnconditionJump(label: LLVMLabel) {
llvmCode.appendln("br label $label")
}
fun createClass(name: String, fields: List<LLVMVariable>) {
val code = "%class.$name = type { ${fields.map { it.type }.joinToString()} }"
llvmCode.appendln(code)
@@ -1,6 +1,6 @@
package org.kotlinnative.translator.llvm
class LLVMLabel(val label: String) : LLVMNode() {
class LLVMLabel(val label: String, val scope: LLVMScope) : LLVMNode() {
override fun toString(): String = label
override fun toString(): String = "$scope$label"
}
@@ -0,0 +1,12 @@
package org.kotlinnative.translator.llvm
open class LLVMScope
class LLVMGlobalScope : LLVMScope() {
override fun toString() = "@"
}
class LLVMLocalScope : LLVMScope() {
override fun toString() = "%"
}