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