diff --git a/translator/src/main/kotlin/main.kt b/translator/src/main/kotlin/main.kt index 3fb59218284..150924f27eb 100644 --- a/translator/src/main/kotlin/main.kt +++ b/translator/src/main/kotlin/main.kt @@ -21,4 +21,3 @@ fun main(args: Array) { println(FileTranslator(state, files[0]).generateCode()) } - \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 3b04a1162f5..91b6e1c9d18 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -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 } } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index cb91155c99f..28eca133767 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -34,9 +34,7 @@ class TranslationState(sources: List, 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") diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index 572d9d1d7ed..dc58c09573b 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -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) { - val code = "@class.$name = type { ${ fields.map { it.type }.joinToString() } }" + fun createClass(name: String, fields: List) { + val code = "@class.$name = type { ${fields.map { it.type }.joinToString()} }" llvmCode.appendln(code) } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt index 31962fcb005..1276f8edf7a 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt @@ -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 "" + } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt index dab55442870..d7f693fbca9 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMCharType.kt @@ -4,4 +4,6 @@ class LLVMCharType() : LLVMType() { override fun toString(): String = "i8" + override val align = 1 + } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt index 5df7b170031..09008e62575 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMDoubleType.kt @@ -20,5 +20,5 @@ class LLVMDoubleType() : LLVMType() { override fun toString() = "double" - override fun getAlign() = 8 + override val align = 8 } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt index b4fc963f892..8861b15862f 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMIntType.kt @@ -20,5 +20,6 @@ class LLVMIntType() : LLVMType() { override fun toString() = "i32" - override fun getAlign() = 4 + override val align = 4 + } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt index c80146dce64..0b4a94c3b8d 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMReferenceType.kt @@ -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 } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt index 249a4bd7aed..bb7249ee78a 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMShortType.kt @@ -4,4 +4,5 @@ class LLVMShortType() : LLVMType() { override fun toString(): String = "i16" + override val align = 1 } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt index fabc36c1db7..01beb25005e 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMType.kt @@ -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) { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt index 5544f2636bf..55612dbd882 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt @@ -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" }