translator: fields generation, parsing var(val) type reference

This commit is contained in:
e5l
2016-07-19 14:02:00 +03:00
parent 452fbe65b2
commit 73d93c34ae
2 changed files with 39 additions and 27 deletions
@@ -1,5 +1,6 @@
package org.kotlinnative.translator
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtNamedFunction
@@ -13,7 +14,6 @@ import java.util.*
class ClassCodegen(val state: TranslationState, val variableManager: VariableManager, val clazz: KtClass, val codeBuilder: LLVMBuilder) {
val annotation: Boolean
val plain: Boolean = false // TODO
val fields = ArrayList<LLVMVariable>()
val fieldsIndex = HashMap<String, LLVMClassVariable>()
val type: LLVMType = LLVMReferenceType(clazz.name.toString(), "class", byRef = true)
@@ -24,22 +24,29 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan
val descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException()
val parameterList = clazz.getPrimaryConstructorParameterList()?.parameters ?: listOf()
annotation = descriptor.kind == ClassKind.ANNOTATION_CLASS
size = indexFields(descriptor, parameterList)
}
private fun indexFields(descriptor: ClassDescriptor, parameters: MutableList<KtParameter>): Int {
if (annotation) {
return 0
}
var offset = 0
var currentSize = 0
annotation = descriptor.kind == ClassKind.ANNOTATION_CLASS
if (!annotation) {
for (field in parameterList) {
val item = resolveType(field)
item.offset = offset
for (field in parameters) {
val item = resolveType(field)
item.offset = offset
fields.add(item)
fieldsIndex[item.label] = item
fields.add(item)
fieldsIndex[item.label] = item
currentSize += type.size
offset++
}
currentSize += type.size
offset++
}
when (descriptor.kind) {
ClassKind.ENUM_CLASS -> {
val item = LLVMClassVariable("enum_item", LLVMEnumItemType())
@@ -51,7 +58,7 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan
}
}
size = currentSize
return currentSize
}
fun generate() {
@@ -124,7 +124,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable
private fun expressionWalker(expr: PsiElement?, scopeDepth: Int) {
when (expr) {
is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1)
is KtProperty -> evaluateLeafPsiElement(expr.firstChild as LeafPsiElement, scopeDepth)
is KtProperty -> evaluateValExpression(expr, scopeDepth)
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
is KtDoWhileExpression -> evaluateDoWhileExpression(expr.firstChild, scopeDepth + 1)
@@ -348,20 +348,25 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable
}
private fun evaluateTypeReference(element: KtTypeReference): LLVMSingleValue? {
val type = element.typeElement as KtUserType
val type = element.typeElement
val operator = element.getNextSiblingIgnoringWhitespaceAndComments()
val value = operator?.getNextSiblingIgnoringWhitespaceAndComments() as KtConstantExpression
return when (operator) {
else -> throw UnsupportedOperationException()
when (type) {
is KtUserType -> {
val i = 1
}
}
// return when (operator) {
// else -> throw UnsupportedOperationException()
// }
return null
}
private fun evaluateLeafPsiElement(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
return when (element.elementType) {
KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element, scopeDepth)
KtTokens.VAL_KEYWORD -> evaluateValExpression(element, scopeDepth)
KtTokens.VAR_KEYWORD -> evaluateValExpression(element, scopeDepth)
KtTokens.IF_KEYWORD -> evaluateIfOperator(element, scopeDepth, containReturn = false)
KtTokens.WHILE_KEYWORD -> evaluateWhileOperator(element, scopeDepth)
else -> null
@@ -450,29 +455,29 @@ class FunctionCodegen(val state: TranslationState, val variableManager: Variable
else -> codeBuilder.copyVariableValue(to, from)
}
private fun evaluateValExpression(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
val identifier = element.getNextSiblingIgnoringWhitespaceAndComments()
val eq = identifier?.getNextSiblingIgnoringWhitespaceAndComments() ?: return null
private fun evaluateValExpression(element: KtProperty, scopeDepth: Int): LLVMVariable? {
val variable = state.bindingContext.get(BindingContext.VARIABLE, element)!!
val identifier = variable.name.toString()
val assignExpression = evaluateExpression(eq.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) ?: return null
val assignExpression = evaluateExpression(element.delegateExpressionOrInitializer, scopeDepth) ?: return null
when (assignExpression) {
is LLVMVariable -> {
if (assignExpression.pointer == 0) {
val allocVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type, LLVMRegisterScope(), pointer = 0)
val allocVar = variableManager.receiveVariable(identifier, assignExpression.type, LLVMRegisterScope(), pointer = 0)
codeBuilder.allocStackVar(allocVar)
allocVar.pointer++
variableManager.addVariable(identifier.text, allocVar, scopeDepth)
variableManager.addVariable(identifier, allocVar, scopeDepth)
copyVariable(assignExpression, allocVar)
} else {
variableManager.addVariable(identifier!!.text, assignExpression, scopeDepth)
variableManager.addVariable(identifier, assignExpression, scopeDepth)
}
}
is LLVMConstant -> {
val newVar = variableManager.receiveVariable(identifier!!.text, assignExpression.type!!, LLVMRegisterScope(), pointer = 1)
val newVar = variableManager.receiveVariable(identifier, assignExpression.type!!, LLVMRegisterScope(), pointer = 1)
codeBuilder.addConstant(newVar, assignExpression)
variableManager.addVariable(identifier.text, newVar, scopeDepth)
variableManager.addVariable(identifier, newVar, scopeDepth)
}
else -> {
throw UnsupportedOperationException()