translator: calls

This commit is contained in:
e5l
2016-07-13 16:53:35 +03:00
parent 607abc1887
commit 70270d35de
5 changed files with 55 additions and 39 deletions
@@ -7,6 +7,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses
import org.kotlinnative.translator.llvm.* import org.kotlinnative.translator.llvm.*
import org.kotlinnative.translator.llvm.types.LLVMIntType import org.kotlinnative.translator.llvm.types.LLVMIntType
import org.kotlinnative.translator.llvm.types.LLVMType import org.kotlinnative.translator.llvm.types.LLVMType
@@ -22,12 +23,12 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
val variableManager = state.variableManager val variableManager = state.variableManager
init { init {
val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function) val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!!
args = descriptor?.valueParameters?.map { args = descriptor.valueParameters.map {
LLVMVariable(it.name.toString(), LLVMMapStandardType(it.type.toString())) LLVMMapStandardType(it.name.toString(), it.type)
} }
returnType = LLVMMapStandardType(descriptor?.returnType.toString()) returnType = LLVMMapStandardType("", descriptor.returnType!!).type
} }
fun generate() { fun generate() {
@@ -121,23 +122,20 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
val function = expr.firstChild.firstChild.text val function = expr.firstChild.firstChild.text
if (state.functions.containsKey(function)) { if (state.functions.containsKey(function)) {
return evaluteFunctionCallExpression(expr) return evaluateFunctionCallExpression(expr)
} }
if (state.classes.containsKey(function)) { if (state.classes.containsKey(function)) {
return evaluteConstructorCallExpression(expr) return evaluateConstructorCallExpression(expr)
} }
return null return null
} }
private fun evaluteConstructorCallExpression(expr: KtCallExpression): LLVMSingleValue? { private fun evaluateConstructorCallExpression(expr: KtCallExpression): LLVMSingleValue? {
val function = expr.firstChild.firstChild val function = expr.firstChild.firstChild
val descriptor = state.classes[function.text] ?: return null val descriptor = state.classes[function.text] ?: return null
val names = parseArgList(expr val names = parseArgList(expr).mapIndexed { i: Int, s: String ->
.firstChild
.getNextSiblingIgnoringWhitespaceAndComments()
?.firstChild).mapIndexed { i: Int, s: String ->
LLVMVariable(s, descriptor.fields[i].type, pointer = descriptor.fields[i].pointer) LLVMVariable(s, descriptor.fields[i].type, pointer = descriptor.fields[i].pointer)
}.toList() }.toList()
@@ -151,34 +149,32 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
}) })
} }
private fun evaluteFunctionCallExpression(expr: KtCallExpression): LLVMSingleValue? { private fun evaluateFunctionCallExpression(expr: KtCallExpression): LLVMSingleValue? {
val function = expr.firstChild.firstChild val function = expr.firstChild.firstChild
val descriptor = state.functions[function.text] ?: return null val descriptor = state.functions[function.text] ?: return null
val names = parseArgList(expr val names = parseArgList(expr)
.firstChild
.getNextSiblingIgnoringWhitespaceAndComments()
?.firstChild)
return LLVMCall(descriptor.returnType, "@${descriptor.name}", descriptor.args?.mapIndexed { return LLVMCall(descriptor.returnType, "@${descriptor.name}", descriptor.args?.mapIndexed {
i: Int, variable: LLVMVariable -> i: Int, variable: LLVMVariable ->
LLVMVariable(names[i], variable.type) LLVMVariable(names[i], variable.type, pointer = variable.pointer)
} ?: listOf()) } ?: listOf())
} }
private fun parseArgList(argumentList: PsiElement?): List<String> { private fun parseArgList(expr: KtCallExpression): List<String> {
val args = ArrayList<String>() val args = expr.getValueArgumentsInParentheses()
val result = ArrayList<String>()
var currentArg = argumentList?.getNextSiblingIgnoringWhitespaceAndComments() for (arg in args) {
var text = (arg as KtValueArgument).text
if (text.startsWith("::")) {
text = "@${text.substring(2)}"
}
while (currentArg?.text != ")" && currentArg != null) { result.add(text)
args.add(currentArg.text)
currentArg = currentArg
.getNextSiblingIgnoringWhitespaceAndComments()
?.getNextSiblingIgnoringWhitespaceAndComments()
} }
return args
return result
} }
private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable { private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
@@ -28,7 +28,7 @@ class VariableManager {
val ourVersion = variableVersion.getOrDefault(name, 0) + 1 val ourVersion = variableVersion.getOrDefault(name, 0) + 1
variableVersion.put(name, ourVersion) variableVersion.put(name, ourVersion)
return LLVMVariable("%managed.$name.$ourVersion", kotlinName = name, type = type, pointer = pointer) return LLVMVariable("%managed.$name.$ourVersion", type, name, pointer)
} }
} }
@@ -4,8 +4,6 @@ import org.kotlinnative.translator.llvm.types.LLVMType
class LLVMExpression(val variableType: LLVMType, val llvmCode: String) : LLVMNode() { class LLVMExpression(val variableType: LLVMType, val llvmCode: String) : LLVMNode() {
override fun toString(): String { override fun toString(): String = llvmCode
return llvmCode
}
} }
@@ -1,5 +1,8 @@
package org.kotlinnative.translator.llvm package org.kotlinnative.translator.llvm
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.kotlinnative.translator.llvm.types.* import org.kotlinnative.translator.llvm.types.*
@@ -9,9 +12,10 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, returnTy
"${s.getType()} %${s.label}" "${s.getType()} %${s.label}"
}?.joinToString() }) ${ if (arm) "#0" else ""}" }?.joinToString() }) ${ if (arm) "#0" else ""}"
fun LLVMMapStandardType(type: String): LLVMType = when (type) { fun LLVMMapStandardType(name: String, type: KotlinType): LLVMVariable = when {
"Int" -> LLVMIntType() type.isFunctionType -> LLVMVariable(name, LLVMFunctionType(type), type.toString(), pointer = true)
"Double" -> LLVMDoubleType() type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString())
"Unit" -> LLVMVoidType() type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString())
else -> LLVMReferenceType("%$type*") type.isUnit() -> LLVMVariable("", LLVMVoidType())
else -> LLVMVariable(name, LLVMReferenceType("%$type"), name, pointer = true)
} }
@@ -1,5 +1,23 @@
package org.kotlinnative.translator.llvm.types package org.kotlinnative.translator.llvm.types
/** import org.jetbrains.kotlin.types.KotlinType
* Created by user on 7/13/16. import org.kotlinnative.translator.llvm.LLVMMapStandardType
*/ import org.kotlinnative.translator.llvm.LLVMVariable
import java.util.*
class LLVMFunctionType(type: KotlinType) : LLVMType() {
override val align: Int = 4
override val size: Byte = 4
val arguments: List<LLVMVariable>
val returnType: LLVMVariable
init {
val types = type.arguments.map { LLVMMapStandardType("", it.type) }.toList()
returnType = types.last()
arguments = types.dropLast(1)
}
override fun toString(): String =
"${returnType.type} (${arguments.map { it.getType() }.joinToString()})"
}