translator: add if expressions, LLVMScope, fix return by variable, supporting block markup
This commit is contained in:
@@ -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() = "%"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user