translator: add class methods calls

This commit is contained in:
Alexey Stepanov
2016-07-18 16:04:02 +03:00
parent e8ceffc79d
commit 3080970362
3 changed files with 20 additions and 11 deletions
@@ -19,7 +19,7 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan
val native: Boolean val native: Boolean
val fields = ArrayList<LLVMVariable>() val fields = ArrayList<LLVMVariable>()
val fieldsIndex = HashMap<String, LLVMClassVariable>() val fieldsIndex = HashMap<String, LLVMClassVariable>()
val type: LLVMType = LLVMReferenceType(clazz.name.toString(), "class", align = 8, byRef = true, uncopyable = true) val type: LLVMType = LLVMReferenceType(clazz.name.toString(), "class", byRef = true)
val size: Int val size: Int
var methods = HashMap<String, FunctionCodegen>() var methods = HashMap<String, FunctionCodegen>()
@@ -67,7 +67,6 @@ class ClassCodegen(val state: TranslationState, val variableManager: VariableMan
val classVal = LLVMVariable("classvariable.this", type, pointer = 1) val classVal = LLVMVariable("classvariable.this", type, pointer = 1)
variableManager.addVariable("this", classVal, 0); variableManager.addVariable("this", classVal, 0);
for (function in methods.values) { for (function in methods.values) {
function.generate(classVal) function.generate(classVal)
} }
} }
@@ -16,7 +16,7 @@ import org.kotlinnative.translator.llvm.types.*
import java.util.* import java.util.*
class FunctionCodegen(val state: TranslationState, val variableManager : VariableManager, val function: KtNamedFunction, val codeBuilder: LLVMBuilder) { class FunctionCodegen(val state: TranslationState, val variableManager: VariableManager, val function: KtNamedFunction, val codeBuilder: LLVMBuilder) {
var name = function.fqName.toString() var name = function.fqName.toString()
var returnType: LLVMVariable var returnType: LLVMVariable
@@ -100,7 +100,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager : Variabl
private fun generateLoadArguments() { private fun generateLoadArguments() {
args.forEach(fun(it: LLVMVariable) { args.forEach(fun(it: LLVMVariable) {
if (it.type is LLVMFunctionType || (it.type is LLVMReferenceType && (it.type as LLVMReferenceType).uncopyable)) { if (it.type is LLVMFunctionType || (it.type is LLVMReferenceType && (it.type as LLVMReferenceType).byRef)) {
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 1), topLevel) variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 1), topLevel)
return return
} }
@@ -154,7 +154,7 @@ class FunctionCodegen(val state: TranslationState, val variableManager : Variabl
is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr) is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr)
is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth) is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth)
is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, true) is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, true)
is KtDotQualifiedExpression -> evaluateDotExpression(expr) is KtDotQualifiedExpression -> evaluateDotExpression(expr, scopeDepth)
is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr) is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr)
is PsiWhiteSpace -> null is PsiWhiteSpace -> null
is PsiElement -> evaluatePsiElement(expr, scopeDepth) is PsiElement -> evaluatePsiElement(expr, scopeDepth)
@@ -178,18 +178,28 @@ class FunctionCodegen(val state: TranslationState, val variableManager : Variabl
return LLVMMapStandardType(expr.text.substring(2), kotlinType, LLVMVariableScope()) return LLVMMapStandardType(expr.text.substring(2), kotlinType, LLVMVariableScope())
} }
private fun evaluateDotExpression(expr: KtDotQualifiedExpression): LLVMSingleValue? { private fun evaluateDotExpression(expr: KtDotQualifiedExpression, scopeDepth: Int): LLVMSingleValue? {
val receiverName = expr.receiverExpression.text val receiverName = expr.receiverExpression.text
val selectorName = expr.selectorExpression!!.text val selectorName = expr.selectorExpression!!.text
val receiver = variableManager.getLLVMvalue(receiverName)!! val receiver = variableManager.getLLVMvalue(receiverName)!!
val clazz = state.classes[(receiver.type as LLVMReferenceType).type]!! val clazz = state.classes[(receiver.type as LLVMReferenceType).type]!!
val field = clazz.fieldsIndex[selectorName]!! val field = clazz.fieldsIndex[selectorName]
if (field != null) {
val result = codeBuilder.getNewVariable(field.type, pointer = 1)
codeBuilder.loadClassField(result, receiver, field.offset)
return result
} else {
val methodName = clazz.clazz.name.toString() + '.' + selectorName.substringBefore('(')
val method = clazz.methods[methodName]!!
val returnType = clazz.methods[methodName]!!.returnType.type
val result = codeBuilder.getNewVariable(field.type, pointer = 1) val names = parseArgList(expr.lastChild as KtCallExpression, scopeDepth)
codeBuilder.loadClassField(result, receiver, field.offset) return evaluateFunctionCallExpression(LLVMVariable(methodName, returnType, scope = LLVMRegisterScope()), names, method.args)
return result
}
} }
fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, scope: Int): LLVMSingleValue? { fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, scope: Int): LLVMSingleValue? {
@@ -2,7 +2,7 @@ package org.kotlinnative.translator.llvm.types
import java.util.* import java.util.*
class LLVMReferenceType(val type: String, var prefix: String = "", override val align: Int = 4, var byRef: Boolean = false, val uncopyable: Boolean = false) : LLVMType() { class LLVMReferenceType(val type: String, var prefix: String = "", override val align: Int = 4, var byRef: Boolean = false) : LLVMType() {
override val defaultValue: String = "" override val defaultValue: String = ""