translator: add pointer modificator, fixes for stack allocation, refactoring
This commit is contained in:
@@ -21,4 +21,3 @@ fun main(args: Array<String>) {
|
||||
println(FileTranslator(state, files[0]).generateCode())
|
||||
}
|
||||
|
||||
|
||||
@@ -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, it.name)
|
||||
val loadVariable = LLVMVariable("%${it.name}", it.type, it.name, true)
|
||||
codeBuilder.loadVariable(loadVariable)
|
||||
variableManager.addVariable(it.name, loadVariable, 2)
|
||||
}
|
||||
@@ -142,7 +142,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
|
||||
private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMVariable {
|
||||
val node = expr.node
|
||||
return codeBuilder.addConstant(LLVMVariable(node.firstChildNode.text, LLVMIntType()))
|
||||
return codeBuilder.addConstant(LLVMVariable(node.firstChildNode.text, LLVMIntType(), pointer = false))
|
||||
}
|
||||
|
||||
private fun evaluatePsiElement(element: PsiElement, scopeDepth: Int): LLVMVariable? {
|
||||
@@ -168,9 +168,12 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
val eq = identifier?.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||
|
||||
val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null
|
||||
|
||||
when (assignExpression) {
|
||||
is LLVMVariable -> {
|
||||
variableManager.addVariable(identifier!!.text, assignExpression, scopeDepth)
|
||||
assignExpression.kotlinName = identifier!!.text
|
||||
assignExpression.pointer = false
|
||||
variableManager.addVariable(identifier.text, assignExpression, scopeDepth)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,7 @@ class TranslationState(sources: List<String>, disposer: Disposable) {
|
||||
val messageCollector = GroupingMessageCollector(object : MessageCollector {
|
||||
private var hasError = false
|
||||
|
||||
override fun hasErrors(): Boolean {
|
||||
return hasError
|
||||
}
|
||||
override fun hasErrors(): Boolean = hasError
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
|
||||
println("[report] $message")
|
||||
|
||||
@@ -9,9 +9,9 @@ class LLVMBuilder {
|
||||
private var llvmCode: StringBuilder = StringBuilder()
|
||||
private var variableCount = 0
|
||||
|
||||
fun getNewVariable(type: LLVMType?): LLVMVariable {
|
||||
fun getNewVariable(type: LLVMType?, pointer: Boolean = false): LLVMVariable {
|
||||
variableCount++
|
||||
return LLVMVariable("%var$variableCount", type)
|
||||
return LLVMVariable("%var$variableCount", type, pointer = pointer)
|
||||
}
|
||||
|
||||
fun addLLVMCode(code: String) {
|
||||
@@ -32,7 +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()
|
||||
KtTokens.EQ -> return moveVariableValue(secondOp, firstOp)
|
||||
else -> throw UnsupportedOperationException("Unknown binary operator")
|
||||
}
|
||||
|
||||
@@ -41,6 +41,21 @@ class LLVMBuilder {
|
||||
return newVar
|
||||
}
|
||||
|
||||
|
||||
private fun moveVariableValue(from: LLVMVariable, to: LLVMVariable): LLVMVariable {
|
||||
//%0 = load i32, i32* %y, align 4
|
||||
//store i32 %0, i32* %z, align 4
|
||||
//%1 = load i32, i32* %z, align 4
|
||||
llvmCode.appendln("VARIABLE from $from TO $to")
|
||||
/*
|
||||
val tmp1 = getNewVariable(from.type)
|
||||
val tmp2 = getNewVariable(to.type)
|
||||
llvmCode.appendln("$tmp1 = load ${tmp1.type}, ${tmp1.type}* $from, align ${tmp1.type?.align}")
|
||||
llvmCode.appendln("store ${tmp1.type} $tmp1, ${to.type}* $to, align ${to.type?.align}")
|
||||
llvmCode.appendln("$tmp2 = load ${tmp2.type}, ${tmp2.type}* $to, align ${to.type?.align}")*/
|
||||
return from
|
||||
}
|
||||
|
||||
fun clean() {
|
||||
llvmCode = StringBuilder()
|
||||
}
|
||||
@@ -50,7 +65,7 @@ class LLVMBuilder {
|
||||
}
|
||||
|
||||
fun addReturnOperator(llvmVariable: LLVMVariable) {
|
||||
llvmCode.appendln("ret i32 $llvmVariable")
|
||||
llvmCode.appendln("ret ${llvmVariable.type} $llvmVariable")
|
||||
}
|
||||
|
||||
fun addVoidReturn() {
|
||||
@@ -58,30 +73,32 @@ class LLVMBuilder {
|
||||
}
|
||||
|
||||
fun loadVariable(llvmVariable: LLVMVariable) {
|
||||
addVariableByRef(llvmVariable, LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName))
|
||||
addVariableByRef(llvmVariable, LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, true))
|
||||
}
|
||||
|
||||
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()}")
|
||||
llvmCode.appendln("$sourceVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.align}")
|
||||
llvmCode.appendln("store ${sourceVariable.type} $targetVariable, ${targetVariable.getType()} $sourceVariable, align ${targetVariable.type?.align}")
|
||||
}
|
||||
|
||||
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()}")
|
||||
val tmp = getNewVariable(targetVariable.type, pointer = true)
|
||||
|
||||
llvmCode.appendln("$tmp = alloca ${tmp.type}, align ${tmp.type?.align}")
|
||||
llvmCode.appendln("store ${tmp.type} $sourceVariable, ${tmp.getType()} $tmp, align ${tmp.type?.align}")
|
||||
llvmCode.appendln("$targetVariable = load ${targetVariable.type}, ${tmp.getType()} $tmp, align ${targetVariable.type?.align}")
|
||||
|
||||
}
|
||||
|
||||
fun addConstant(sourceVariable: LLVMVariable): LLVMVariable {
|
||||
val target = getNewVariable(sourceVariable.type)
|
||||
val target = getNewVariable(sourceVariable.type, pointer = sourceVariable.pointer)
|
||||
addVariableByValue(target, sourceVariable)
|
||||
return target
|
||||
}
|
||||
|
||||
|
||||
fun createClass(name: String, fields: List<LLVMVariable>) {
|
||||
val code = "@class.$name = type { ${ fields.map { it.type }.joinToString() } }"
|
||||
fun createClass(name: String, fields: List<LLVMVariable>) {
|
||||
val code = "@class.$name = type { ${fields.map { it.type }.joinToString()} }"
|
||||
llvmCode.appendln(code)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,10 @@ package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
open class LLVMVariable(val label: String, val type: LLVMType? = null, val kotlinName: String? = null) : LLVMNode() {
|
||||
open class LLVMVariable(val label: String, val type: LLVMType? = null, var kotlinName: String? = null, var pointer: Boolean = false) : LLVMNode() {
|
||||
|
||||
override fun toString(): String = label
|
||||
|
||||
fun getType(): String = type.toString() + if (pointer) "*" else ""
|
||||
|
||||
}
|
||||
@@ -4,4 +4,6 @@ class LLVMCharType() : LLVMType() {
|
||||
|
||||
override fun toString(): String = "i8"
|
||||
|
||||
override val align = 1
|
||||
|
||||
}
|
||||
|
||||
@@ -20,5 +20,5 @@ class LLVMDoubleType() : LLVMType() {
|
||||
|
||||
override fun toString() = "double"
|
||||
|
||||
override fun getAlign() = 8
|
||||
override val align = 8
|
||||
}
|
||||
@@ -20,5 +20,6 @@ class LLVMIntType() : LLVMType() {
|
||||
|
||||
override fun toString() = "i32"
|
||||
|
||||
override fun getAlign() = 4
|
||||
override val align = 4
|
||||
|
||||
}
|
||||
+2
-4
@@ -12,13 +12,11 @@ class LLVMReferenceType(val type: String) : LLVMType() {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun getAlign(): Int {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun toString() = type
|
||||
|
||||
override val align = -1
|
||||
}
|
||||
@@ -4,4 +4,5 @@ class LLVMShortType() : LLVMType() {
|
||||
|
||||
override fun toString(): String = "i16"
|
||||
|
||||
override val align = 1
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ abstract class LLVMType() {
|
||||
open fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException()
|
||||
|
||||
open fun getAlign(): Int = throw UnimplementedException()
|
||||
abstract val align: Int
|
||||
}
|
||||
|
||||
fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||
|
||||
@@ -2,7 +2,8 @@ package org.kotlinnative.translator.llvm.types
|
||||
|
||||
class LLVMVoidType() : LLVMType() {
|
||||
|
||||
override fun getAlign(): Int = 0
|
||||
override val align = 0
|
||||
|
||||
override fun toString(): String = "void"
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user