translator: add plain function calls, C function support
This commit is contained in:
@@ -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()
|
||||
|
||||
+3
@@ -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*"
|
||||
}
|
||||
+9
-12
@@ -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"
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user