From 70270d35dea5e2b23a5b741700fcfc9608b27e67 Mon Sep 17 00:00:00 2001 From: e5l Date: Wed, 13 Jul 2016 16:53:35 +0300 Subject: [PATCH] translator: calls --- .../translator/FunctionCodegen.kt | 50 +++++++++---------- .../translator/VariableManager.kt | 2 +- .../translator/llvm/LLVMExpression.kt | 4 +- .../translator/llvm/generators.kt | 14 ++++-- .../translator/llvm/types/LLVMFunctionType.kt | 24 +++++++-- 5 files changed, 55 insertions(+), 39 deletions(-) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 3300e1488f1..9ffc1fc8240 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses import org.kotlinnative.translator.llvm.* import org.kotlinnative.translator.llvm.types.LLVMIntType import org.kotlinnative.translator.llvm.types.LLVMType @@ -22,12 +23,12 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val variableManager = state.variableManager init { - val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function) - args = descriptor?.valueParameters?.map { - LLVMVariable(it.name.toString(), LLVMMapStandardType(it.type.toString())) + val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!! + args = descriptor.valueParameters.map { + LLVMMapStandardType(it.name.toString(), it.type) } - returnType = LLVMMapStandardType(descriptor?.returnType.toString()) + returnType = LLVMMapStandardType("", descriptor.returnType!!).type } fun generate() { @@ -121,23 +122,20 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction val function = expr.firstChild.firstChild.text if (state.functions.containsKey(function)) { - return evaluteFunctionCallExpression(expr) + return evaluateFunctionCallExpression(expr) } if (state.classes.containsKey(function)) { - return evaluteConstructorCallExpression(expr) + return evaluateConstructorCallExpression(expr) } return null } - private fun evaluteConstructorCallExpression(expr: KtCallExpression): LLVMSingleValue? { + private fun evaluateConstructorCallExpression(expr: KtCallExpression): LLVMSingleValue? { val function = expr.firstChild.firstChild val descriptor = state.classes[function.text] ?: return null - val names = parseArgList(expr - .firstChild - .getNextSiblingIgnoringWhitespaceAndComments() - ?.firstChild).mapIndexed { i: Int, s: String -> + val names = parseArgList(expr).mapIndexed { i: Int, s: String -> LLVMVariable(s, descriptor.fields[i].type, pointer = descriptor.fields[i].pointer) }.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 descriptor = state.functions[function.text] ?: return null - val names = parseArgList(expr - .firstChild - .getNextSiblingIgnoringWhitespaceAndComments() - ?.firstChild) + val names = parseArgList(expr) return LLVMCall(descriptor.returnType, "@${descriptor.name}", descriptor.args?.mapIndexed { i: Int, variable: LLVMVariable -> - LLVMVariable(names[i], variable.type) + LLVMVariable(names[i], variable.type, pointer = variable.pointer) } ?: listOf()) } - private fun parseArgList(argumentList: PsiElement?): List { - val args = ArrayList() + private fun parseArgList(expr: KtCallExpression): List { + val args = expr.getValueArgumentsInParentheses() + val result = ArrayList() - 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) { - args.add(currentArg.text) - - currentArg = currentArg - .getNextSiblingIgnoringWhitespaceAndComments() - ?.getNextSiblingIgnoringWhitespaceAndComments() + result.add(text) } - return args + + return result } private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable { diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt index 807db2fe17c..f38fe35b257 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/VariableManager.kt @@ -28,7 +28,7 @@ class VariableManager { val ourVersion = variableVersion.getOrDefault(name, 0) + 1 variableVersion.put(name, ourVersion) - return LLVMVariable("%managed.$name.$ourVersion", kotlinName = name, type = type, pointer = pointer) + return LLVMVariable("%managed.$name.$ourVersion", type, name, pointer) } } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMExpression.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMExpression.kt index d9ccf052151..934fce48685 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMExpression.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMExpression.kt @@ -4,8 +4,6 @@ import org.kotlinnative.translator.llvm.types.LLVMType class LLVMExpression(val variableType: LLVMType, val llvmCode: String) : LLVMNode() { - override fun toString(): String { - return llvmCode - } + override fun toString(): String = llvmCode } \ 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 9083ecd47a5..4a7b201f7a7 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -1,5 +1,8 @@ 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.* @@ -9,9 +12,10 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List?, returnTy "${s.getType()} %${s.label}" }?.joinToString() }) ${ if (arm) "#0" else ""}" -fun LLVMMapStandardType(type: String): LLVMType = when (type) { - "Int" -> LLVMIntType() - "Double" -> LLVMDoubleType() - "Unit" -> LLVMVoidType() - else -> LLVMReferenceType("%$type*") +fun LLVMMapStandardType(name: String, type: KotlinType): LLVMVariable = when { + type.isFunctionType -> LLVMVariable(name, LLVMFunctionType(type), type.toString(), pointer = true) + type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString()) + type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString()) + type.isUnit() -> LLVMVariable("", LLVMVoidType()) + else -> LLVMVariable(name, LLVMReferenceType("%$type"), name, pointer = true) } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt index bd61a9da020..cfc2d23356f 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMFunctionType.kt @@ -1,5 +1,23 @@ package org.kotlinnative.translator.llvm.types -/** - * Created by user on 7/13/16. - */ +import org.jetbrains.kotlin.types.KotlinType +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 + 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()})" +}