translator: plain classes and types
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtUserType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
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.LLVMVariable
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
import org.kotlinnative.translator.llvm.types.parseLLVMType
|
||||
import java.util.*
|
||||
|
||||
class ClassCodegen(val state: TranslationState, val clazz: KtClass, val codeBuilder: LLVMBuilder) {
|
||||
|
||||
var native = false
|
||||
|
||||
fun generate() {
|
||||
val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException()
|
||||
|
||||
if (descriptor.kind == ClassKind.ANNOTATION_CLASS) {
|
||||
return
|
||||
}
|
||||
|
||||
native = isNative(descriptor.annotations)
|
||||
|
||||
generateBody()
|
||||
}
|
||||
|
||||
private fun generateBody() {
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
offset++
|
||||
}
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
private fun getNativeType(field: KtParameter): LLVMType? {
|
||||
for (annotation in field.annotationEntries) {
|
||||
val annotationDescriptor = state.bindingContext.get(BindingContext.ANNOTATION, annotation)
|
||||
val type = annotationDescriptor?.type.toString()
|
||||
if (type == "Native") {
|
||||
return parseLLVMType(annotationDescriptor!!.argumentValue("type").toString())
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun isNative(annotations: Annotations?): Boolean {
|
||||
annotations ?: return false
|
||||
|
||||
for (i in annotations) {
|
||||
if (i.type.toString() == "Native") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
@@ -27,8 +28,12 @@ class FileTranslator(val state: TranslationState, val file: KtFile) {
|
||||
|
||||
function.generate()
|
||||
}
|
||||
is KtClass -> {
|
||||
ClassCodegen(state, declaration, codeBuilder).generate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
}
|
||||
|
||||
fun generate() {
|
||||
if (generateDeclaration(function)) {
|
||||
if (generateDeclaration()) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
codeBuilder.addEndExpression()
|
||||
}
|
||||
|
||||
private fun generateDeclaration(function: KtNamedFunction): Boolean {
|
||||
private fun generateDeclaration(): Boolean {
|
||||
var external = false
|
||||
|
||||
var keyword = function.firstChild
|
||||
@@ -179,7 +179,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
}
|
||||
|
||||
private fun evaluateReturnInstruction(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
|
||||
var next = element.getNextSiblingIgnoringWhitespaceAndComments()
|
||||
val next = element.getNextSiblingIgnoringWhitespaceAndComments()
|
||||
val retVar = evaluateExpression(next, scopeDepth) as LLVMVariable
|
||||
|
||||
codeBuilder.addReturnOperator(retVar)
|
||||
|
||||
@@ -72,8 +72,8 @@ class TranslationState(sources: List<String>, disposer: Disposable) {
|
||||
}
|
||||
|
||||
override fun reportEnvironmentErrors() {
|
||||
var files = environment.configuration.jvmClasspathRoots
|
||||
var runtimes = files.map { it.canonicalFile }.filter { it.name == PathUtil.KOTLIN_JAVA_RUNTIME_JAR && it.exists() }
|
||||
val files = environment.configuration.jvmClasspathRoots
|
||||
val runtimes = files.map { it.canonicalFile }.filter { it.name == PathUtil.KOTLIN_JAVA_RUNTIME_JAR && it.exists() }
|
||||
collector.report(CompilerMessageSeverity.ERROR, runtimes.joinToString { it.path }, CompilerMessageLocation.NO_LOCATION)
|
||||
println(runtimes.joinToString { it.toString() })
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class VariableManager {
|
||||
private var globalVariableCollection = HashMap<String, LLVMVariable>()
|
||||
|
||||
fun getLLVMvalue(variableName: String): LLVMVariable? {
|
||||
return fileVariableCollectionTree.get(variableName)?.peek()?.first ?: globalVariableCollection.get(variableName)
|
||||
return fileVariableCollectionTree[variableName]?.peek()?.first ?: globalVariableCollection[variableName]
|
||||
}
|
||||
|
||||
fun pullUpwardsLevel(level: Int) {
|
||||
|
||||
@@ -41,10 +41,6 @@ class LLVMBuilder {
|
||||
return newVar
|
||||
}
|
||||
|
||||
fun addAssignment(llvmVariable: LLVMNode, assignExpression: LLVMNode) {
|
||||
llvmCode.appendln("$llvmVariable = $assignExpression")
|
||||
}
|
||||
|
||||
fun clean() {
|
||||
llvmCode = StringBuilder()
|
||||
}
|
||||
@@ -67,13 +63,13 @@ class LLVMBuilder {
|
||||
|
||||
fun addVariableByRef(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
|
||||
llvmCode.appendln("$sourceVariable = alloca ${sourceVariable.type}, align ${sourceVariable.type?.getAlign()}")
|
||||
llvmCode.appendln("store ${targetVariable.type} $targetVariable, ${targetVariable.type}* ${sourceVariable}, align ${targetVariable.type?.getAlign()}")
|
||||
llvmCode.appendln("store ${targetVariable.type} $targetVariable, ${targetVariable.type}* $sourceVariable, align ${targetVariable.type?.getAlign()}")
|
||||
}
|
||||
|
||||
fun addVariableByValue(targetVariable: LLVMVariable, sourceVariable: LLVMVariable) {
|
||||
val tmp = getNewVariable(targetVariable.type)
|
||||
llvmCode.appendln("$tmp = alloca ${tmp.type}, align ${tmp.type?.getAlign()}")
|
||||
llvmCode.appendln("store ${tmp.type} $sourceVariable, ${tmp.type}* ${tmp}, align ${tmp.type?.getAlign()}")
|
||||
llvmCode.appendln("store ${tmp.type} $sourceVariable, ${tmp.type}* $tmp, align ${tmp.type?.getAlign()}")
|
||||
llvmCode.appendln("$targetVariable = load ${targetVariable.type}, ${targetVariable.type}* $tmp, align ${targetVariable.type?.getAlign()}")
|
||||
}
|
||||
|
||||
@@ -83,9 +79,12 @@ class LLVMBuilder {
|
||||
return target
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return llvmCode.toString()
|
||||
|
||||
fun createClass(name: String, fields: List<LLVMVariable>) {
|
||||
val code = "@class.$name = type { ${ fields.map { it.type }.joinToString() } }"
|
||||
llvmCode.appendln(code)
|
||||
}
|
||||
|
||||
override fun toString() = llvmCode.toString()
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
class LLVMCall(val returnType: LLVMType, val name: String, val arguments: List<LLVMVariable>) : LLVMNode() {
|
||||
|
||||
override fun toString(): String {
|
||||
return "call $returnType $name(${arguments.joinToString { "${it.type} ${it.label}" }})"
|
||||
}
|
||||
override fun toString(): String =
|
||||
"call $returnType $name(${arguments.joinToString { "${it.type} ${it.label}" }})"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
|
||||
class LLVMClassVariable(label: String, type: LLVMType? = null, offset: Int = 0) : LLVMVariable(label, type)
|
||||
@@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
class LLVMVariable(val label: String, val type: LLVMType? = null, val kotlinName: String? = null) : LLVMNode() {
|
||||
open class LLVMVariable(val label: String, val type: LLVMType? = null, val kotlinName: String? = null) : LLVMNode() {
|
||||
|
||||
override fun toString(): String = label
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
class LLVMCharType() : LLVMType() {
|
||||
|
||||
override fun toString(): String = "i8"
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
class LLVMShortType() : LLVMType() {
|
||||
|
||||
override fun toString(): String = "i16"
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package org.kotlinnative.translator.llvm.types;
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.exceptions.TranslationException
|
||||
import org.kotlinnative.translator.exceptions.UnimplementedException
|
||||
@@ -11,11 +11,13 @@ abstract class LLVMType() {
|
||||
open fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression = throw UnimplementedException()
|
||||
|
||||
abstract fun getAlign(): Int
|
||||
open fun getAlign(): Int = throw UnimplementedException()
|
||||
}
|
||||
|
||||
fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||
"i32" -> LLVMIntType()
|
||||
"i16" -> LLVMShortType()
|
||||
"i8" -> LLVMCharType()
|
||||
"Unit" -> LLVMVoidType()
|
||||
else -> throw TranslationException()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user