translator: call fixes, constructors stub
This commit is contained in:
@@ -10,48 +10,71 @@ import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||
import org.kotlinnative.translator.exceptions.TranslationException
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMClassVariable
|
||||
import org.kotlinnative.translator.llvm.LLVMFunctionDescriptor
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMVoidType
|
||||
import org.kotlinnative.translator.llvm.types.parseLLVMType
|
||||
import java.util.*
|
||||
|
||||
class ClassCodegen(val state: TranslationState, val clazz: KtClass, val codeBuilder: LLVMBuilder) {
|
||||
|
||||
var native = false
|
||||
val annotation: Boolean
|
||||
val native: Boolean
|
||||
val fields = ArrayList<LLVMVariable>()
|
||||
val size: Int
|
||||
|
||||
fun generate() {
|
||||
init {
|
||||
val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException()
|
||||
val parameterList = clazz.getPrimaryConstructorParameterList()!!.parameters
|
||||
|
||||
if (descriptor.kind == ClassKind.ANNOTATION_CLASS) {
|
||||
return
|
||||
var offset = 0
|
||||
var currentSize = 0
|
||||
annotation = descriptor.kind == ClassKind.ANNOTATION_CLASS
|
||||
|
||||
if (!annotation) {
|
||||
for (field in parameterList) {
|
||||
val type = getNativeType(field) ?: parseLLVMType((field.typeReference?.typeElement as KtUserType).referencedName!!)
|
||||
val field = LLVMClassVariable(field.name!!, type, offset)
|
||||
fields.add(field)
|
||||
|
||||
currentSize += type.size
|
||||
offset++
|
||||
}
|
||||
}
|
||||
|
||||
native = isNative(descriptor.annotations)
|
||||
|
||||
generateBody()
|
||||
size = currentSize
|
||||
}
|
||||
|
||||
private fun generateBody() {
|
||||
fun generate() {
|
||||
if (annotation) {
|
||||
return
|
||||
}
|
||||
|
||||
generateStruct()
|
||||
generateDefaultConstructor()
|
||||
}
|
||||
|
||||
private fun generateStruct() {
|
||||
val name = clazz.name!!
|
||||
val fields = getFields()
|
||||
|
||||
codeBuilder.createClass(name, fields)
|
||||
}
|
||||
|
||||
private fun getFields(): List<LLVMVariable> {
|
||||
val fields = ArrayList<LLVMVariable>()
|
||||
val parameterList = clazz.getPrimaryConstructorParameterList()!!.parameters
|
||||
var offset = 0
|
||||
private fun generateDefaultConstructor() {
|
||||
codeBuilder.addLLVMCode(LLVMFunctionDescriptor(clazz.name!!, fields, LLVMVoidType()))
|
||||
|
||||
for (field in parameterList) {
|
||||
val type = getNativeType(field) ?: parseLLVMType((field.typeReference?.typeElement as KtUserType).referencedName!!)
|
||||
val field = LLVMClassVariable(field.name!!, type, offset)
|
||||
fields.add(field)
|
||||
codeBuilder.addStartExpression()
|
||||
generateLoadArguments()
|
||||
codeBuilder.addEndExpression()
|
||||
}
|
||||
|
||||
offset++
|
||||
private fun generateLoadArguments() {
|
||||
fields.forEach {
|
||||
val loadVariable = LLVMVariable("%${it.label}", it.type, it.label)
|
||||
codeBuilder.loadVariable(loadVariable)
|
||||
}
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
private fun getNativeType(field: KtParameter): LLVMType? {
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.utils.FunctionDescriptor
|
||||
|
||||
class FileTranslator(val state: TranslationState, val file: KtFile) {
|
||||
|
||||
@@ -21,18 +20,24 @@ class FileTranslator(val state: TranslationState, val file: KtFile) {
|
||||
when (declaration) {
|
||||
is KtNamedFunction -> {
|
||||
val function = FunctionCodegen(state, declaration, codeBuilder)
|
||||
state.functions.put(function.name, FunctionDescriptor(
|
||||
function.returnType,
|
||||
function.args?.map { it.type }?.toList() ?: listOf()
|
||||
))
|
||||
state.functions.put(function.name, function)
|
||||
|
||||
function.generate()
|
||||
}
|
||||
is KtClass -> {
|
||||
ClassCodegen(state, declaration, codeBuilder).generate()
|
||||
val codegen = ClassCodegen(state, declaration, codeBuilder)
|
||||
state.classes.put(declaration.name!!, codegen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (clazz in state.classes.values) {
|
||||
clazz.generate()
|
||||
}
|
||||
|
||||
for (function in state.functions.values) {
|
||||
function.generate()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import org.kotlinnative.translator.llvm.*
|
||||
import org.kotlinnative.translator.llvm.types.LLVMIntType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMVoidType
|
||||
import org.kotlinnative.translator.utils.FunctionArgument
|
||||
import java.util.*
|
||||
|
||||
|
||||
@@ -19,13 +18,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
|
||||
var name = function.fqName.toString()
|
||||
var returnType: LLVMType
|
||||
var args: List<FunctionArgument>?
|
||||
var args: List<LLVMVariable>?
|
||||
val variableManager = state.variableManager
|
||||
|
||||
init {
|
||||
val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)
|
||||
args = descriptor?.valueParameters?.map {
|
||||
FunctionArgument(LLVMMapStandardType(it.type.toString()), it.name.toString())
|
||||
LLVMVariable(it.name.toString(), LLVMMapStandardType(it.type.toString()))
|
||||
}
|
||||
|
||||
returnType = LLVMMapStandardType(descriptor?.returnType.toString())
|
||||
@@ -37,7 +36,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
}
|
||||
|
||||
codeBuilder.addStartExpression()
|
||||
generateLoadArguments(function)
|
||||
generateLoadArguments()
|
||||
expressionWalker(function.bodyExpression)
|
||||
|
||||
if (returnType is LLVMVoidType) {
|
||||
@@ -64,11 +63,11 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
return external
|
||||
}
|
||||
|
||||
private fun generateLoadArguments(function: KtNamedFunction) {
|
||||
private fun generateLoadArguments() {
|
||||
args?.forEach {
|
||||
val loadVariable = LLVMVariable("%${it.name}", it.type, it.name, true)
|
||||
val loadVariable = LLVMVariable("%${it.label}", it.type, it.label, true)
|
||||
codeBuilder.loadVariable(loadVariable)
|
||||
variableManager.addVariable(it.name, loadVariable, 2)
|
||||
variableManager.addVariable(it.label, loadVariable, 2)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,14 +106,35 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
}
|
||||
|
||||
private fun evaluateCallExpression(expr: KtCallExpression): LLVMNode? {
|
||||
val function = expr.firstChild.firstChild.text
|
||||
|
||||
if (state.functions.containsKey(function)) {
|
||||
return evaluteFunctionCallExpression(expr)
|
||||
}
|
||||
|
||||
if (state.classes.containsKey(function)) {
|
||||
return evaluteConstructorCallExpression(expr)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun evaluteConstructorCallExpression(expr: KtCallExpression): LLVMNode? {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun evaluteFunctionCallExpression(expr: KtCallExpression): LLVMNode? {
|
||||
val function = expr.firstChild.firstChild
|
||||
|
||||
val descriptor = state.functions[function.text] ?: return null
|
||||
val names = parseArgList(expr
|
||||
.firstChild
|
||||
.getNextSiblingIgnoringWhitespaceAndComments()
|
||||
?.firstChild)
|
||||
|
||||
return LLVMCall(descriptor.returnType, "@${function.text}", descriptor.argTypes.mapIndexed { i: Int, type: LLVMType -> LLVMVariable(names[i], type) })
|
||||
return LLVMCall(descriptor.returnType, "@${function.text}", descriptor.args?.mapIndexed {
|
||||
i: Int, variable: LLVMVariable -> LLVMVariable(names[i], variable.type)
|
||||
} ?: listOf())
|
||||
}
|
||||
|
||||
private fun parseArgList(argumentList: PsiElement?): List<String> {
|
||||
|
||||
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.kotlinnative.translator.exceptions.TranslationException
|
||||
import org.kotlinnative.translator.utils.FunctionDescriptor
|
||||
import java.util.*
|
||||
|
||||
|
||||
@@ -26,7 +25,9 @@ class TranslationState(sources: List<String>, disposer: Disposable) {
|
||||
|
||||
val environment: KotlinCoreEnvironment
|
||||
val bindingContext: BindingContext
|
||||
var functions = HashMap<String, FunctionDescriptor>()
|
||||
var functions = HashMap<String, FunctionCodegen>()
|
||||
var classes = HashMap<String, ClassCodegen>()
|
||||
|
||||
val variableManager = VariableManager()
|
||||
|
||||
init {
|
||||
|
||||
@@ -4,8 +4,7 @@ import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
open class LLVMVariable(val label: String, val type: LLVMType? = null, var kotlinName: String? = null, var pointer: Boolean = false) : LLVMNode() {
|
||||
|
||||
override fun toString(): String = label
|
||||
|
||||
fun getType(): String = type.toString() + if (pointer) "*" else ""
|
||||
|
||||
override fun toString(): String = label
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.*
|
||||
import org.kotlinnative.translator.utils.FunctionArgument
|
||||
|
||||
|
||||
fun LLVMFunctionDescriptor(name: String, argTypes: List<FunctionArgument>?, returnType: LLVMType, declare: Boolean = false) =
|
||||
fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, returnType: LLVMType, declare: Boolean = false) =
|
||||
"${if (declare) "declare" else "define"} $returnType @$name(${
|
||||
argTypes?.mapIndexed { i: Int, s: FunctionArgument ->
|
||||
"${s.type} %${s.name}"
|
||||
}?.joinToString() ?: ""})"
|
||||
argTypes?.mapIndexed { i: Int, s: LLVMVariable ->
|
||||
"${s.type} %${s.label}"
|
||||
}?.joinToString() })"
|
||||
|
||||
fun LLVMMapStandardType(type: String): LLVMType = when (type) {
|
||||
"Int" -> LLVMIntType()
|
||||
|
||||
@@ -3,7 +3,7 @@ package org.kotlinnative.translator.llvm.types
|
||||
class LLVMCharType() : LLVMType() {
|
||||
|
||||
override fun toString(): String = "i8"
|
||||
|
||||
override val align = 1
|
||||
|
||||
override val size: Byte = 1
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class LLVMDoubleType() : LLVMType() {
|
||||
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression =
|
||||
LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp")
|
||||
|
||||
override fun toString() = "double"
|
||||
|
||||
override val align = 8
|
||||
override val size: Byte = 8
|
||||
override fun toString() = "double"
|
||||
}
|
||||
@@ -18,8 +18,8 @@ class LLVMIntType() : LLVMType() {
|
||||
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression =
|
||||
LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp")
|
||||
|
||||
override fun toString() = "i32"
|
||||
|
||||
override val align = 4
|
||||
override val size: Byte = 4
|
||||
|
||||
override fun toString() = "i32"
|
||||
}
|
||||
+2
-14
@@ -1,22 +1,10 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
|
||||
class LLVMReferenceType(val type: String) : LLVMType() {
|
||||
override fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
override val align = 4
|
||||
override val size: Byte = 4
|
||||
|
||||
override fun toString() = type
|
||||
|
||||
override val align = -1
|
||||
}
|
||||
@@ -2,7 +2,8 @@ package org.kotlinnative.translator.llvm.types
|
||||
|
||||
class LLVMShortType() : LLVMType() {
|
||||
|
||||
override fun toString(): String = "i16"
|
||||
|
||||
override val size: Byte = 2
|
||||
override val align = 1
|
||||
|
||||
override fun toString(): String = "i16"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
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
|
||||
@@ -12,6 +11,7 @@ abstract class LLVMType() {
|
||||
open fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException()
|
||||
|
||||
abstract val align: Int
|
||||
abstract val size: Byte
|
||||
}
|
||||
|
||||
fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||
@@ -19,5 +19,5 @@ fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||
"i16" -> LLVMShortType()
|
||||
"i8" -> LLVMCharType()
|
||||
"Unit" -> LLVMVoidType()
|
||||
else -> throw TranslationException()
|
||||
else -> LLVMReferenceType(type)
|
||||
}
|
||||
|
||||
@@ -5,5 +5,6 @@ class LLVMVoidType() : LLVMType() {
|
||||
override val align = 0
|
||||
|
||||
override fun toString(): String = "void"
|
||||
override val size: Byte = 0
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package org.kotlinnative.translator.utils
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
data class FunctionArgument(val type: LLVMType, val name: String)
|
||||
|
||||
data class FunctionDescriptor(val returnType: LLVMType, val argTypes: List<LLVMType>)
|
||||
Reference in New Issue
Block a user