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())
|
println(FileTranslator(state, files[0]).generateCode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
|
|
||||||
private fun generateLoadArguments(function: KtNamedFunction) {
|
private fun generateLoadArguments(function: KtNamedFunction) {
|
||||||
args?.forEach {
|
args?.forEach {
|
||||||
val loadVariable = LLVMVariable("%${it.name}", it.type, it.name)
|
val loadVariable = LLVMVariable("%${it.name}", it.type, it.name, true)
|
||||||
codeBuilder.loadVariable(loadVariable)
|
codeBuilder.loadVariable(loadVariable)
|
||||||
variableManager.addVariable(it.name, loadVariable, 2)
|
variableManager.addVariable(it.name, loadVariable, 2)
|
||||||
}
|
}
|
||||||
@@ -142,7 +142,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
|
|
||||||
private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMVariable {
|
private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMVariable {
|
||||||
val node = expr.node
|
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? {
|
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 eq = identifier?.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
|
||||||
|
|
||||||
val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null
|
val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null
|
||||||
|
|
||||||
when (assignExpression) {
|
when (assignExpression) {
|
||||||
is LLVMVariable -> {
|
is LLVMVariable -> {
|
||||||
variableManager.addVariable(identifier!!.text, assignExpression, scopeDepth)
|
assignExpression.kotlinName = identifier!!.text
|
||||||
|
assignExpression.pointer = false
|
||||||
|
variableManager.addVariable(identifier.text, assignExpression, scopeDepth)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ class TranslationState(sources: List<String>, disposer: Disposable) {
|
|||||||
val messageCollector = GroupingMessageCollector(object : MessageCollector {
|
val messageCollector = GroupingMessageCollector(object : MessageCollector {
|
||||||
private var hasError = false
|
private var hasError = false
|
||||||
|
|
||||||
override fun hasErrors(): Boolean {
|
override fun hasErrors(): Boolean = hasError
|
||||||
return hasError
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
|
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
|
||||||
println("[report] $message")
|
println("[report] $message")
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ class LLVMBuilder {
|
|||||||
private var llvmCode: StringBuilder = StringBuilder()
|
private var llvmCode: StringBuilder = StringBuilder()
|
||||||
private var variableCount = 0
|
private var variableCount = 0
|
||||||
|
|
||||||
fun getNewVariable(type: LLVMType?): LLVMVariable {
|
fun getNewVariable(type: LLVMType?, pointer: Boolean = false): LLVMVariable {
|
||||||
variableCount++
|
variableCount++
|
||||||
return LLVMVariable("%var$variableCount", type)
|
return LLVMVariable("%var$variableCount", type, pointer = pointer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addLLVMCode(code: String) {
|
fun addLLVMCode(code: String) {
|
||||||
@@ -32,7 +32,7 @@ class LLVMBuilder {
|
|||||||
KtTokens.PLUS -> firstOp.type!!.operatorPlus(newVar, firstOp, secondOp)
|
KtTokens.PLUS -> firstOp.type!!.operatorPlus(newVar, firstOp, secondOp)
|
||||||
KtTokens.MINUS -> firstOp.type!!.operatorMinus(newVar, firstOp, secondOp)
|
KtTokens.MINUS -> firstOp.type!!.operatorMinus(newVar, firstOp, secondOp)
|
||||||
KtTokens.MUL -> firstOp.type!!.operatorTimes(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")
|
else -> throw UnsupportedOperationException("Unknown binary operator")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +41,21 @@ class LLVMBuilder {
|
|||||||
return newVar
|
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() {
|
fun clean() {
|
||||||
llvmCode = StringBuilder()
|
llvmCode = StringBuilder()
|
||||||
}
|
}
|
||||||
@@ -50,7 +65,7 @@ class LLVMBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addReturnOperator(llvmVariable: LLVMVariable) {
|
fun addReturnOperator(llvmVariable: LLVMVariable) {
|
||||||
llvmCode.appendln("ret i32 $llvmVariable")
|
llvmCode.appendln("ret ${llvmVariable.type} $llvmVariable")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addVoidReturn() {
|
fun addVoidReturn() {
|
||||||
@@ -58,30 +73,32 @@ class LLVMBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun loadVariable(llvmVariable: LLVMVariable) {
|
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) {
|
fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
|
||||||
llvmCode.appendln("$sourceVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.getAlign()}")
|
llvmCode.appendln("$sourceVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.align}")
|
||||||
llvmCode.appendln("store ${targetVariable.type} $targetVariable, ${targetVariable.type}* $sourceVariable, align ${targetVariable.type?.getAlign()}")
|
llvmCode.appendln("store ${sourceVariable.type} $targetVariable, ${targetVariable.getType()} $sourceVariable, align ${targetVariable.type?.align}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addVariableByValue(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
|
fun addVariableByValue(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
|
||||||
val tmp = getNewVariable(targetVariable.type)
|
val tmp = getNewVariable(targetVariable.type, pointer = true)
|
||||||
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("$tmp = alloca ${tmp.type}, align ${tmp.type?.align}")
|
||||||
llvmCode.appendln("$targetVariable = load ${targetVariable.type}, ${targetVariable.type}* $tmp, align ${targetVariable.type?.getAlign()}")
|
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 {
|
fun addConstant(sourceVariable: LLVMVariable): LLVMVariable {
|
||||||
val target = getNewVariable(sourceVariable.type)
|
val target = getNewVariable(sourceVariable.type, pointer = sourceVariable.pointer)
|
||||||
addVariableByValue(target, sourceVariable)
|
addVariableByValue(target, sourceVariable)
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package org.kotlinnative.translator.llvm
|
|||||||
|
|
||||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
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
|
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 fun toString(): String = "i8"
|
||||||
|
|
||||||
|
override val align = 1
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,5 +20,5 @@ class LLVMDoubleType() : LLVMType() {
|
|||||||
|
|
||||||
override fun toString() = "double"
|
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 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")
|
throw UnsupportedOperationException("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getAlign(): Int {
|
|
||||||
throw UnsupportedOperationException("not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
|
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
|
||||||
throw UnsupportedOperationException("not implemented")
|
throw UnsupportedOperationException("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString() = type
|
override fun toString() = type
|
||||||
|
|
||||||
|
override val align = -1
|
||||||
}
|
}
|
||||||
@@ -4,4 +4,5 @@ class LLVMShortType() : LLVMType() {
|
|||||||
|
|
||||||
override fun toString(): String = "i16"
|
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 operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException()
|
||||||
open fun operatorMinus(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) {
|
fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ package org.kotlinnative.translator.llvm.types
|
|||||||
|
|
||||||
class LLVMVoidType() : LLVMType() {
|
class LLVMVoidType() : LLVMType() {
|
||||||
|
|
||||||
override fun getAlign(): Int = 0
|
override val align = 0
|
||||||
|
|
||||||
override fun toString(): String = "void"
|
override fun toString(): String = "void"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user