translator: add stack variable allocation, refactoring, llvmVariable starts storing Kotlin Name
This commit is contained in:
@@ -21,3 +21,4 @@ fun main(args: Array<String>) {
|
||||
println(FileTranslator(state, files[0]).generateCode())
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@ package org.kotlinnative.translator
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import org.kotlinnative.translator.utils.FunctionDescriptor
|
||||
import java.util.*
|
||||
|
||||
class FileTranslator(val state: TranslationState, val file: KtFile) {
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
|
||||
private fun generateLoadArguments(function: KtNamedFunction) {
|
||||
args?.forEach {
|
||||
val loadVariable = LLVMVariable("%${it.name}", it.type)
|
||||
val loadVariable = LLVMVariable("%${it.name}", it.type, it.name)
|
||||
codeBuilder.loadVariable(loadVariable)
|
||||
variableManager.addVariable(it.name, loadVariable, 2)
|
||||
}
|
||||
@@ -76,6 +76,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
when (expr) {
|
||||
is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1)
|
||||
is KtProperty -> evaluateLeafPsiElement(expr.firstChild as LeafPsiElement, scopeDepth)
|
||||
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
||||
is PsiElement -> evaluateExpression(expr.firstChild, scopeDepth + 1)
|
||||
null -> {
|
||||
variableManager.pullUpwardsLevel(scopeDepth)
|
||||
@@ -141,7 +142,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
|
||||
private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMVariable {
|
||||
val node = expr.node
|
||||
return LLVMVariable(node.firstChildNode.text, ::LLVMIntType.invoke())
|
||||
return codeBuilder.addConstant(LLVMVariable(node.firstChildNode.text, LLVMIntType()))
|
||||
}
|
||||
|
||||
private fun evaluatePsiElement(element: PsiElement, scopeDepth: Int): LLVMVariable? {
|
||||
@@ -168,9 +169,12 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
|
||||
val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null
|
||||
when (assignExpression) {
|
||||
is LLVMVariable -> variableManager.addVariable(identifier!!.text, assignExpression, scopeDepth);
|
||||
is LLVMVariable -> {
|
||||
variableManager.addVariable(identifier!!.text, assignExpression, scopeDepth)
|
||||
return null
|
||||
}
|
||||
}
|
||||
codeBuilder.addAssignment(LLVMVariable("%${identifier!!.text}"), assignExpression)
|
||||
codeBuilder.addAssignment(LLVMVariable("%${identifier!!.text}", null, identifier.text), assignExpression)
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.kotlinnative.translator.exceptions.TranslationException
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import org.kotlinnative.translator.utils.FunctionDescriptor
|
||||
import java.util.*
|
||||
|
||||
@@ -36,7 +35,7 @@ class TranslationState(sources: List<String>, disposer: Disposable) {
|
||||
private var hasError = false
|
||||
|
||||
override fun hasErrors(): Boolean {
|
||||
return hasError;
|
||||
return hasError
|
||||
}
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
|
||||
|
||||
@@ -16,9 +16,9 @@ class VariableManager {
|
||||
fileVariableCollectionTree.forEach { s, stack -> if (!stack.empty() && stack.peek().second >= level) stack.pop() else Unit }
|
||||
}
|
||||
|
||||
fun addVariable(name: String, variable: LLVMVariable, level: Int){
|
||||
val stack = fileVariableCollectionTree.getOrDefault(String, Stack<Pair<LLVMVariable, Int>>());
|
||||
stack.push(Pair(variable, level));
|
||||
fun addVariable(name: String, variable: LLVMVariable, level: Int) {
|
||||
val stack = fileVariableCollectionTree.getOrDefault(String, Stack<Pair<LLVMVariable, Int>>())
|
||||
stack.push(Pair(variable, level))
|
||||
fileVariableCollectionTree.put(name, stack)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ class LLVMBuilder {
|
||||
KtTokens.PLUS -> firstOp.type!!.operatorPlus(newVar, firstOp, secondOp)
|
||||
KtTokens.MINUS -> firstOp.type!!.operatorMinus(newVar, firstOp, secondOp)
|
||||
KtTokens.MUL -> firstOp.type!!.operatorTimes(newVar, firstOp, secondOp)
|
||||
KtTokens.EQ -> throw UnsupportedOperationException()
|
||||
else -> throw UnsupportedOperationException("Unknown binary operator")
|
||||
}
|
||||
|
||||
@@ -61,8 +62,25 @@ class LLVMBuilder {
|
||||
}
|
||||
|
||||
fun loadVariable(llvmVariable: LLVMVariable) {
|
||||
llvmCode.appendln("$llvmVariable.addr = alloca ${llvmVariable.type}, align ${llvmVariable.type?.getAlign()}")
|
||||
llvmCode.appendln("store ${llvmVariable.type} $llvmVariable, ${llvmVariable.type}* ${llvmVariable.type}.addr, align ${llvmVariable.type?.getAlign()}")
|
||||
addVariableByRef(llvmVariable, LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName))
|
||||
}
|
||||
|
||||
fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
|
||||
llvmCode.appendln("$sourceVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.getAlign()}")
|
||||
llvmCode.appendln("store ${targetVariable.type} $targetVariable, ${targetVariable.type}* ${sourceVariable}, align ${targetVariable.type?.getAlign()}")
|
||||
}
|
||||
|
||||
fun addVariableByValue(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
|
||||
val tmp = getNewVariable(targetVariable.type)
|
||||
llvmCode.appendln("$tmp = alloca ${tmp.type}, align ${tmp.type?.getAlign()}")
|
||||
llvmCode.appendln("store ${tmp.type} $sourceVariable, ${tmp.type}* ${tmp}, align ${tmp.type?.getAlign()}")
|
||||
llvmCode.appendln("$targetVariable = load ${targetVariable.type}, ${targetVariable.type}* $tmp, align ${targetVariable.type?.getAlign()}")
|
||||
}
|
||||
|
||||
fun addConstant(sourceVariable: LLVMVariable): LLVMVariable {
|
||||
val target = getNewVariable(sourceVariable.type)
|
||||
addVariableByValue(target, sourceVariable)
|
||||
return target
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
|
||||
@@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
class LLVMVariable(val label: String, val type: LLVMType? = null) : LLVMNode() {
|
||||
class LLVMVariable(val label: String, val type: LLVMType? = null, val kotlinName: String? = null) : LLVMNode() {
|
||||
|
||||
override fun toString(): String = label
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.kotlinnative.translator.utils.FunctionArgument
|
||||
fun LLVMFunctionDescriptor(name: String, argTypes: List<FunctionArgument>?, returnType: LLVMType, declare: Boolean = false) =
|
||||
"${if (declare) "declare" else "define"} $returnType @$name(${
|
||||
argTypes?.mapIndexed { i: Int, s: FunctionArgument ->
|
||||
"${s.type} %tmp.${s.name}"
|
||||
"${s.type} %${s.name}"
|
||||
}?.joinToString() ?: ""})"
|
||||
|
||||
fun LLVMMapStandardType(type: String): LLVMType = when (type) {
|
||||
|
||||
@@ -6,4 +6,4 @@ enum class LLVMTypes {
|
||||
int, double, float, char
|
||||
}
|
||||
|
||||
val typesMap = mapOf(Pair(LLVMTypes.int, ::LLVMIntType));
|
||||
val typesMap = mapOf(Pair(LLVMTypes.int, ::LLVMIntType))
|
||||
|
||||
Reference in New Issue
Block a user