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()
|
codeBuilder.addStartExpression()
|
||||||
generateLoadArguments()
|
generateLoadArguments()
|
||||||
expressionWalker(function.bodyExpression)
|
evaluateCodeBlock(function.bodyExpression, startLabel = null, finishLabel = null, scopeDepth = 0)
|
||||||
|
|
||||||
|
|
||||||
if (returnType is LLVMVoidType) {
|
if (returnType is LLVMVoidType) {
|
||||||
codeBuilder.addVoidReturn()
|
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) {
|
when (expr) {
|
||||||
is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1)
|
is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1)
|
||||||
is KtProperty -> evaluateLeafPsiElement(expr.firstChild as LeafPsiElement, scopeDepth)
|
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
|
val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||||
getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||||
val thenExpression = getBrackets.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)
|
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 conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1)
|
||||||
val thenLabel = codeBuilder.getNewLabel()
|
val thenLabel = codeBuilder.getNewLabel()
|
||||||
val elseLabel = codeBuilder.getNewLabel()
|
val elseLabel = codeBuilder.getNewLabel()
|
||||||
|
val endLabel = codeBuilder.getNewLabel()
|
||||||
|
|
||||||
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
|
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
|
||||||
|
|
||||||
|
evaluateCodeBlock(thenExpression, thenLabel, endLabel, scopeDepth + 1)
|
||||||
|
evaluateCodeBlock(elseExpression, elseLabel, endLabel, scopeDepth + 1)
|
||||||
|
|
||||||
|
codeBuilder.markWithLabel(endLabel)
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,8 +268,9 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
private fun evaluateReturnInstruction(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
|
private fun evaluateReturnInstruction(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
|
||||||
val next = element.getNextSiblingIgnoringWhitespaceAndComments()
|
val next = element.getNextSiblingIgnoringWhitespaceAndComments()
|
||||||
val retVar = evaluateExpression(next, scopeDepth) as LLVMSingleValue
|
val retVar = evaluateExpression(next, scopeDepth) as LLVMSingleValue
|
||||||
|
val retNativeValue = codeBuilder.receiveNativeValue(retVar)
|
||||||
|
|
||||||
codeBuilder.addReturnOperator(retVar)
|
codeBuilder.addReturnOperator(retNativeValue)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package org.kotlinnative.translator.llvm
|
|||||||
|
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.kotlinnative.translator.llvm.types.LLVMIntType
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||||
|
|
||||||
class LLVMBuilder {
|
class LLVMBuilder {
|
||||||
@@ -23,9 +24,9 @@ class LLVMBuilder {
|
|||||||
return LLVMVariable("%var$variableCount", type, kotlinName = kotlinName, pointer = pointer)
|
return LLVMVariable("%var$variableCount", type, kotlinName = kotlinName, pointer = pointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNewLabel(): LLVMLabel {
|
fun getNewLabel(scope: LLVMScope = LLVMLocalScope()): LLVMLabel {
|
||||||
labelCount++
|
labelCount++
|
||||||
return LLVMLabel("%label$labelCount")
|
return LLVMLabel("label$labelCount", scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addLLVMCode(code: String) {
|
fun addLLVMCode(code: String) {
|
||||||
@@ -97,6 +98,15 @@ class LLVMBuilder {
|
|||||||
llvmCode.appendln(code)
|
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) {
|
fun storeVariable(target: LLVMVariable, source: LLVMSingleValue) {
|
||||||
val code = "store ${source.type} $source, ${target.getType()} $target, align ${source.type?.align!!}"
|
val code = "store ${source.type} $source, ${target.getType()} $target, align ${source.type?.align!!}"
|
||||||
llvmCode.appendln(code)
|
llvmCode.appendln(code)
|
||||||
@@ -140,6 +150,10 @@ class LLVMBuilder {
|
|||||||
llvmCode.appendln("br ${condition.getType()} $condition, label $thenLabel, label $elseLabel")
|
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>) {
|
fun createClass(name: String, fields: List<LLVMVariable>) {
|
||||||
val code = "%class.$name = type { ${fields.map { it.type }.joinToString()} }"
|
val code = "%class.$name = type { ${fields.map { it.type }.joinToString()} }"
|
||||||
llvmCode.appendln(code)
|
llvmCode.appendln(code)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package org.kotlinnative.translator.llvm
|
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