diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 29ad1ac1c7b..f95bf58fbfe 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -30,20 +30,42 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } fun generate() { - generateDeclaration(function) + if (generateDeclaration(function)) { + return + } + codeBuilder.addStartExpression() expressionWalker(function.bodyExpression) + + if (returnType == "void") { + codeBuilder.addVoidReturn() + } + codeBuilder.addEndExpression() } - private fun generateDeclaration(function: KtNamedFunction) { - codeBuilder.addLLVMCode(LLVMDescriptorGenerate(function.fqName.toString(), args, returnType)) + private fun generateDeclaration(function: KtNamedFunction): Boolean { + var external = false + + var keyword = function.firstChild + while (keyword != null) { + if (keyword.text == "external") { + external = true + break + } + + keyword = keyword.getNextSiblingIgnoringWhitespaceAndComments() + } + + codeBuilder.addLLVMCode(LLVMFunctionDescriptor(function.fqName.toString(), args, returnType, external)) + return external } private fun expressionWalker(expr: PsiElement?) { when (expr) { is KtBlockExpression -> expressionWalker(expr.firstChild) is KtProperty -> evaluateLeafPsiElement(expr.firstChild as LeafPsiElement) + is KtCallExpression -> codeBuilder.addLLVMCode(evaluateCallExpression(expr).toString()) is PsiElement -> evaluateExpression(expr.firstChild) null -> return else -> UnsupportedOperationException() diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/exceptions/UnimplementedException.kt b/translator/src/main/kotlin/org/kotlinnative/translator/exceptions/UnimplementedException.kt new file mode 100644 index 00000000000..0906653fcd6 --- /dev/null +++ b/translator/src/main/kotlin/org/kotlinnative/translator/exceptions/UnimplementedException.kt @@ -0,0 +1,3 @@ +package org.kotlinnative.translator.exceptions + +class UnimplementedException() : Exception() 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 b8cc7c7a132..f0e1ec063fc 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -56,6 +56,10 @@ class LLVMBuilder { llvmCode.appendln("ret i32 $llvmVariable") } + fun addVoidReturn() { + llvmCode.appendln("ret void") + } + override fun toString(): String { return llvmCode.toString() } 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 e711857d9b2..f1b59b167d8 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt @@ -4,8 +4,6 @@ import org.kotlinnative.translator.llvm.types.LLVMType class LLVMVariable(val label: String, val type: LLVMType? = null) : LLVMNode() { - override fun toString(): String { - return label - } + override fun toString(): String = label } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt index ab93e42d785..a73c923115e 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -2,10 +2,14 @@ package org.kotlinnative.translator.llvm import org.kotlinnative.translator.utils.FunctionArgument -fun LLVMDescriptorGenerate(name: String, argTypes: List?, returnType: String) = - "define $returnType @$name(${argTypes?.mapIndexed { i: Int, s: FunctionArgument -> "${s.type} %tmp.${s.name}" }?.joinToString() ?: "" })" +fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnType: String, declare: Boolean = false) = + "${ if (declare) "declare" else "define"} $returnType @$name(${ + argTypes?.mapIndexed { i: Int, s: FunctionArgument -> "${s.type} %tmp.${s.name}" + }?.joinToString() ?: "" })" + fun LLVMMapStandardType(type: String) = when(type) { "Int" -> "i32" + "Unit" -> "void" else -> "%$type*" } \ No newline at end of file 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 b0c21d2834b..460d86215cd 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 @@ -6,20 +6,17 @@ import org.kotlinnative.translator.llvm.LLVMVariable class LLVMDoubleType() : LLVMType() { - override fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - //TODO switch by types: int + double = int - return LLVMExpression(LLVMDoubleType(), "fsub double i32 $firstOp, $secondOp") - } + //TODO switch by types: int + double = int + override fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = + LLVMExpression(LLVMDoubleType(), "fsub double i32 $firstOp, $secondOp") - override fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - //TODO switch by types: int + double = int - return LLVMExpression(LLVMDoubleType(), "fmul double i32 $firstOp, $secondOp") - } + //TODO switch by types: int + double = int + override fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = + LLVMExpression(LLVMDoubleType(), "fmul double i32 $firstOp, $secondOp") - override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - //TODO switch by types: int + double = int - return LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp") - } + //TODO switch by types: int + double = int + override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = + LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp") override fun toString(): String { return "double" 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 ea7e59b4a6b..1f9e1e88ecb 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 @@ -6,23 +6,18 @@ import org.kotlinnative.translator.llvm.LLVMVariable class LLVMIntType() : LLVMType() { - override fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - //TODO switch by types: int + double = int - return LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, $secondOp") - } + //TODO switch by types: int + double = int + override fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = + LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, $secondOp") - override fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - //TODO switch by types: int + double = int - return LLVMExpression(LLVMIntType(), "mul nsw i32 $firstOp, $secondOp") - } + //TODO switch by types: int + double = int + override fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = + LLVMExpression(LLVMIntType(), "mul nsw i32 $firstOp, $secondOp") - override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { - //TODO switch by types: int + double = int - return LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp") - } + //TODO switch by types: int + double = int + override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = + LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp") - override fun toString(): String { - return "i32" - } + override fun toString() = "i32" } \ No newline at end of file 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 af5e2634b70..4dac8131376 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 @@ -1,17 +1,19 @@ package org.kotlinnative.translator.llvm.types; import org.kotlinnative.translator.exceptions.TranslationException +import org.kotlinnative.translator.exceptions.UnimplementedException import org.kotlinnative.translator.llvm.LLVMExpression import org.kotlinnative.translator.llvm.LLVMVariable abstract class LLVMType() { - abstract fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression; - abstract fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression; - abstract fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression; + open fun operatorPlus(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() } -fun parseLLVMType(type: String): LLVMType = when(type) { +fun parseLLVMType(type: String): LLVMType = when (type) { "i32" -> LLVMIntType() + "Unit" -> LLVMVoidType() else -> throw TranslationException() } 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 new file mode 100644 index 00000000000..d633fe75c2d --- /dev/null +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMVoidType.kt @@ -0,0 +1,7 @@ +package org.kotlinnative.translator.llvm.types + +class LLVMVoidType() : LLVMType() { + + override fun toString(): String = "void" + +}