translator: add while loops, fix for constant assignment, speaking markup for labels
This commit is contained in:
@@ -67,8 +67,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
private fun generateLoadArguments() {
|
||||
args?.forEach {
|
||||
val loadVariable = LLVMVariable("%${it.label}", it.type, it.label, false)
|
||||
codeBuilder.loadArgument(loadVariable)
|
||||
variableManager.addVariable(it.label, loadVariable, 2)
|
||||
val allocVar = codeBuilder.loadArgument(loadVariable)
|
||||
variableManager.addVariable(it.label, allocVar, 2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,11 +207,37 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth)
|
||||
KtTokens.VAL_KEYWORD -> evaluateValExpression(element, scopeDepth)
|
||||
KtTokens.VAR_KEYWORD -> evaluateValExpression(element, scopeDepth)
|
||||
KtTokens.IF_KEYWORD -> evaluateIfOperator(element, scopeDepth, false)
|
||||
KtTokens.IF_KEYWORD -> evaluateIfOperator(element, scopeDepth, containReturn = false)
|
||||
KtTokens.WHILE_KEYWORD -> evaluateWhileOperator(element, scopeDepth)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun evaluateWhileOperator(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
|
||||
var getBrackets = element.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||
val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||
getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||
val bodyExpression = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||
|
||||
return executeWhileBlock(condition.firstChild as KtBinaryExpression, bodyExpression.firstChild, scopeDepth)
|
||||
}
|
||||
|
||||
private fun executeWhileBlock(condition: KtBinaryExpression, bodyExpression: PsiElement, scopeDepth: Int): LLVMVariable? {
|
||||
val conditionLable = codeBuilder.getNewLabel(prefix = "while")
|
||||
val bodyLable = codeBuilder.getNewLabel(prefix = "while")
|
||||
val exitLable = codeBuilder.getNewLabel(prefix = "while")
|
||||
|
||||
codeBuilder.addUnconditionJump(conditionLable)
|
||||
codeBuilder.markWithLabel(conditionLable)
|
||||
val conditionResult = evaluateBinaryExpression(condition, scopeDepth + 1)
|
||||
|
||||
codeBuilder.addCondition(conditionResult, bodyLable, exitLable)
|
||||
evaluateCodeBlock(bodyExpression, bodyLable, conditionLable, scopeDepth + 1)
|
||||
codeBuilder.markWithLabel(exitLable)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun evaluateIfOperator(element: LeafPsiElement, scopeDepth: Int, containReturn: Boolean): LLVMVariable? {
|
||||
var getBrackets = element.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||
val condition = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||
@@ -231,9 +257,9 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
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()
|
||||
val thenLabel = codeBuilder.getNewLabel(prefix = "if")
|
||||
val elseLabel = codeBuilder.getNewLabel(prefix = "if")
|
||||
val endLabel = codeBuilder.getNewLabel(prefix = "if")
|
||||
|
||||
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
|
||||
codeBuilder.markWithLabel(thenLabel)
|
||||
@@ -249,10 +275,10 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
}
|
||||
|
||||
private fun executeIfBlock(condition: KtBinaryExpression, thenExpression: PsiElement, elseExpression: PsiElement?, scopeDepth: Int): LLVMVariable? {
|
||||
val conditionResult: LLVMVariable = evaluateBinaryExpression(condition, scopeDepth + 1)
|
||||
val thenLabel = codeBuilder.getNewLabel()
|
||||
val elseLabel = codeBuilder.getNewLabel()
|
||||
val endLabel = codeBuilder.getNewLabel()
|
||||
val conditionResult = evaluateBinaryExpression(condition, scopeDepth + 1)
|
||||
val thenLabel = codeBuilder.getNewLabel(prefix = "if")
|
||||
val elseLabel = codeBuilder.getNewLabel(prefix = "if")
|
||||
val endLabel = codeBuilder.getNewLabel(prefix = "if")
|
||||
|
||||
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
|
||||
|
||||
@@ -271,6 +297,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null
|
||||
|
||||
when (assignExpression) {
|
||||
//TODO resolving
|
||||
is LLVMVariable -> {
|
||||
assignExpression.kotlinName = identifier!!.text
|
||||
assignExpression.pointer = false
|
||||
@@ -278,6 +305,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
}
|
||||
is LLVMConstant -> {
|
||||
val newVar = variableManager.getVariable(identifier!!.text, LLVMIntType(), pointer = true)
|
||||
|
||||
codeBuilder.addConstant(newVar, assignExpression)
|
||||
variableManager.addVariable(identifier.text, newVar, scopeDepth)
|
||||
}
|
||||
@@ -288,7 +316,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
codeBuilder.addLLVMCode(assignExpression.call(result).toString())
|
||||
}
|
||||
else -> {
|
||||
codeBuilder.addAssignment(LLVMVariable("%${identifier!!.text}", null, identifier.text), assignExpression)
|
||||
codeBuilder.addAssignment(LLVMVariable("%${identifier!!.text}", LLVMIntType(), identifier.text), assignExpression)
|
||||
}
|
||||
}
|
||||
return null
|
||||
|
||||
@@ -28,7 +28,7 @@ class VariableManager {
|
||||
val ourVersion = variableVersion.getOrDefault(name, 0) + 1
|
||||
variableVersion.put(name, ourVersion)
|
||||
|
||||
return LLVMVariable("%managed.${name}.${ourVersion}", kotlinName = name, type = type, pointer = pointer)
|
||||
return LLVMVariable("%managed.$name.$ourVersion", kotlinName = name, type = type, pointer = pointer)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,14 +24,14 @@ 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++
|
||||
return LLVMVariable("%var$variableCount", type, kotlinName, pointer)
|
||||
}
|
||||
|
||||
fun getNewLabel(scope: LLVMScope = LLVMLocalScope()): LLVMLabel {
|
||||
fun getNewLabel(scope: LLVMScope = LLVMLocalScope(), prefix: String): LLVMLabel {
|
||||
labelCount++
|
||||
return LLVMLabel("label$labelCount", scope)
|
||||
return LLVMLabel("label.$prefix.$labelCount", scope)
|
||||
}
|
||||
|
||||
fun addLLVMCode(code: String) {
|
||||
@@ -117,36 +117,38 @@ class LLVMBuilder(val arm: Boolean) {
|
||||
llvmCode.appendln(code)
|
||||
}
|
||||
|
||||
fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true) {
|
||||
addVariableByRef(LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, true), llvmVariable, store)
|
||||
fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable {
|
||||
val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, true)
|
||||
addVariableByRef(allocVar, llvmVariable, store)
|
||||
return allocVar
|
||||
}
|
||||
|
||||
fun loadVariable(target: LLVMVariable, source: LLVMVariable) {
|
||||
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)
|
||||
}
|
||||
|
||||
fun allocVar(target: LLVMVariable) {
|
||||
llvmCode.appendln("$target = alloca ${target.type}, align ${target.type?.align!!}")
|
||||
llvmCode.appendln("$target = alloca ${target.type}, align ${target.type.align}")
|
||||
}
|
||||
|
||||
fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable, store: Boolean) {
|
||||
llvmCode.appendln("$targetVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.align}")
|
||||
llvmCode.appendln("$targetVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type.align}")
|
||||
|
||||
if (store) {
|
||||
llvmCode.appendln("store ${sourceVariable.getType()} $sourceVariable, ${targetVariable.getType()} $targetVariable, align ${targetVariable.type?.align}")
|
||||
llvmCode.appendln("store ${sourceVariable.getType()} $sourceVariable, ${targetVariable.getType()} $targetVariable, align ${targetVariable.type.align}")
|
||||
}
|
||||
}
|
||||
|
||||
fun addConstant(allocVariable: LLVMVariable, constantValue: LLVMConstant) {
|
||||
llvmCode.appendln("$allocVariable = alloca ${allocVariable.type}, align ${allocVariable.type?.align}")
|
||||
llvmCode.appendln("store ${allocVariable.type} $constantValue, ${allocVariable.getType()} $allocVariable, align ${allocVariable.type?.align}")
|
||||
llvmCode.appendln("$allocVariable = alloca ${allocVariable.type}, align ${allocVariable.type.align}")
|
||||
llvmCode.appendln("store ${allocVariable.type} $constantValue, ${allocVariable.getType()} $allocVariable, align ${allocVariable.type.align}")
|
||||
}
|
||||
|
||||
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
|
||||
assert(!source.pointer)
|
||||
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)
|
||||
return target
|
||||
}
|
||||
|
||||
@@ -3,4 +3,4 @@ package org.kotlinnative.translator.llvm
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
|
||||
class LLVMClassVariable(label: String, type: LLVMType? = null, val offset: Int = 0) : LLVMVariable(label, type)
|
||||
class LLVMClassVariable(label: String, type: LLVMType, val offset: Int = 0) : LLVMVariable(label, type)
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
open class LLVMVariable(val label: String, override val type: LLVMType? = null, var kotlinName: String? = null, override var pointer: Boolean = false) : LLVMSingleValue() {
|
||||
open class LLVMVariable(val label: String, override val type: LLVMType, var kotlinName: String? = null, override var pointer: Boolean = false) : LLVMSingleValue() {
|
||||
|
||||
override fun getType(): String = type.toString() + if (pointer) "*" else ""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user