translator: add plain function calls, C function support

This commit is contained in:
e5l
2016-07-11 18:01:10 +03:00
parent 83a41238e2
commit 33ff4f720a
9 changed files with 71 additions and 39 deletions
@@ -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()
@@ -0,0 +1,3 @@
package org.kotlinnative.translator.exceptions
class UnimplementedException() : Exception()
@@ -56,6 +56,10 @@ class LLVMBuilder {
llvmCode.appendln("ret i32 $llvmVariable")
}
fun addVoidReturn() {
llvmCode.appendln("ret void")
}
override fun toString(): String {
return llvmCode.toString()
}
@@ -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
}
@@ -2,10 +2,14 @@ package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.utils.FunctionArgument
fun LLVMDescriptorGenerate(name: String, argTypes: List<FunctionArgument>?, returnType: String) =
"define $returnType @$name(${argTypes?.mapIndexed { i: Int, s: FunctionArgument -> "${s.type} %tmp.${s.name}" }?.joinToString() ?: "" })"
fun LLVMFunctionDescriptor(name: String, argTypes: List<FunctionArgument>?, 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*"
}
@@ -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"
@@ -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"
}
@@ -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()
}
@@ -0,0 +1,7 @@
package org.kotlinnative.translator.llvm.types
class LLVMVoidType() : LLVMType() {
override fun toString(): String = "void"
}