|
|
|
@@ -94,8 +94,11 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
val receiverName = expr.receiverExpression.text
|
|
|
|
|
val selectorExpr = expr.selectorExpression!!
|
|
|
|
|
|
|
|
|
|
val receiver = variableManager.getLLVMvalue(receiverName)
|
|
|
|
|
var receiver = variableManager.getLLVMvalue(receiverName)
|
|
|
|
|
if (receiver != null) {
|
|
|
|
|
if (receiver.pointer == 2) {
|
|
|
|
|
receiver = codeBuilder.loadAndGetVariable(receiver)
|
|
|
|
|
}
|
|
|
|
|
return evaluateMemberMethodOrField(receiver, selectorExpr.text, scopeDepth, expr.lastChild)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -110,7 +113,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
else -> throw UnsupportedOperationException()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun evaluatenameReferenceExpression(expr: KtNameReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? {
|
|
|
|
|
private fun evaluateNameReferenceExpression(expr: KtNameReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? {
|
|
|
|
|
val fieldName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)!!.name.toString()
|
|
|
|
|
val field = classScope!!.companionFieldsIndex[fieldName]
|
|
|
|
|
|
|
|
|
@@ -175,8 +178,8 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
|
|
|
|
|
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? = when (expr) {
|
|
|
|
|
is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
|
|
|
|
|
else -> if ((expr is KtNameReferenceExpression) && (classScope != null)) evaluatenameReferenceExpression(expr, scopeDepth + 1, classScope)
|
|
|
|
|
else variableManager.getLLVMvalue(expr.firstChild.text)
|
|
|
|
|
else -> if ((expr is KtNameReferenceExpression) && (classScope != null)) evaluateNameReferenceExpression(expr, scopeDepth + 1, classScope)
|
|
|
|
|
else variableManager.getLLVMvalue(expr.firstChild.text)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? {
|
|
|
|
@@ -275,12 +278,19 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
}).toList()
|
|
|
|
|
|
|
|
|
|
private fun evaluateConstructorCallExpression(function: LLVMVariable, names: List<LLVMSingleValue>): LLVMSingleValue? {
|
|
|
|
|
val store = codeBuilder.getNewVariable(function.type)
|
|
|
|
|
codeBuilder.allocStaticVar(store)
|
|
|
|
|
store.pointer++
|
|
|
|
|
|
|
|
|
|
val result = codeBuilder.getNewVariable(function.type)
|
|
|
|
|
result.pointer++
|
|
|
|
|
codeBuilder.allocStaticVar(result)
|
|
|
|
|
result.pointer += 1
|
|
|
|
|
result.pointer++
|
|
|
|
|
|
|
|
|
|
codeBuilder.storeVariable(result, store)
|
|
|
|
|
|
|
|
|
|
val args = ArrayList<LLVMSingleValue>()
|
|
|
|
|
args.add(result)
|
|
|
|
|
args.add(store)
|
|
|
|
|
args.addAll(names)
|
|
|
|
|
|
|
|
|
|
codeBuilder.addLLVMCode(LLVMCall(
|
|
|
|
@@ -316,46 +326,38 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
return executeBinaryExpression(operator, expr.operationReference, left, right, scopeDepth)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun executeBinaryExpression(operator: IElementType, referenceName: KtSimpleNameExpression?, left: LLVMSingleValue, right: LLVMSingleValue, scopeDepth: Int): LLVMVariable {
|
|
|
|
|
val result = addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
|
|
|
|
|
|
|
|
|
if (left.type is LLVMReferenceType && left.pointer > 0 && right.pointer > 0) {
|
|
|
|
|
variableManager.addVariable((left as LLVMVariable).kotlinName!!, result, scopeDepth)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
private fun executeBinaryExpression(operator: IElementType, referenceName: KtSimpleNameExpression?, left: LLVMSingleValue, right: LLVMSingleValue, scopeDepth: Int)
|
|
|
|
|
= addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
|
|
|
|
|
|
|
|
|
private fun evaluateElvisOperator(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
|
|
|
|
|
val left = evaluateExpression(expr.firstChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
|
|
|
|
|
val condition = left.type!!.operatorEq(left, LLVMVariable("", LLVMNullType()))
|
|
|
|
|
val lptr = codeBuilder.loadAndGetVariable(left as LLVMVariable)
|
|
|
|
|
|
|
|
|
|
val condition = lptr.type.operatorEq(lptr, LLVMVariable("", LLVMNullType()))
|
|
|
|
|
|
|
|
|
|
val conditionResult = codeBuilder.getNewVariable(condition.variableType)
|
|
|
|
|
codeBuilder.addAssignment(conditionResult, condition)
|
|
|
|
|
|
|
|
|
|
val elvisResult = codeBuilder.getNewVariable(left.type!!, pointer = left.pointer)
|
|
|
|
|
codeBuilder.allocStackVar(elvisResult)
|
|
|
|
|
elvisResult.pointer++
|
|
|
|
|
|
|
|
|
|
val thenLabel = codeBuilder.getNewLabel(prefix = "elvis")
|
|
|
|
|
val elseLabel = codeBuilder.getNewLabel(prefix = "elvis")
|
|
|
|
|
val endLabel = codeBuilder.getNewLabel(prefix = "elvis")
|
|
|
|
|
|
|
|
|
|
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
|
|
|
|
|
codeBuilder.addCondition(conditionResult, elseLabel, thenLabel)
|
|
|
|
|
|
|
|
|
|
codeBuilder.markWithLabel(thenLabel)
|
|
|
|
|
codeBuilder.storeVariable(elvisResult, left)
|
|
|
|
|
codeBuilder.addUnconditionalJump(endLabel)
|
|
|
|
|
|
|
|
|
|
codeBuilder.markWithLabel(elseLabel)
|
|
|
|
|
val right = evaluateExpression(expr.lastChild, scopeDepth + 1)
|
|
|
|
|
var right = evaluateExpression(expr.lastChild, scopeDepth + 1)
|
|
|
|
|
if (right != null) {
|
|
|
|
|
codeBuilder.storeVariable(elvisResult, right)
|
|
|
|
|
right = codeBuilder.loadAndGetVariable(right as LLVMVariable)
|
|
|
|
|
codeBuilder.storeVariable(left, right)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
codeBuilder.addUnconditionalJump(endLabel)
|
|
|
|
|
|
|
|
|
|
codeBuilder.markWithLabel(endLabel)
|
|
|
|
|
return elvisResult
|
|
|
|
|
return left
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun addPrimitiveBinaryOperation(operator: IElementType, referenceName: KtSimpleNameExpression?, firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMVariable {
|
|
|
|
@@ -371,7 +373,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
KtTokens.GTEQ -> firstOp.type!!.operatorGeq(firstNativeOp, secondNativeOp)
|
|
|
|
|
KtTokens.EQEQ ->
|
|
|
|
|
if (firstOp.type is LLVMReferenceType)
|
|
|
|
|
firstOp.type!!.operatorEq(firstOp, secondOp)
|
|
|
|
|
firstOp.type!!.operatorEq(firstNativeOp, secondOp)
|
|
|
|
|
else
|
|
|
|
|
firstOp.type!!.operatorEq(firstNativeOp, secondNativeOp)
|
|
|
|
|
KtTokens.EXCLEQ -> firstOp.type!!.operatorNeq(firstNativeOp, secondNativeOp)
|
|
|
|
@@ -385,10 +387,6 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
return result
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (firstOp.type is LLVMReferenceType && firstOp.pointer > 0 && secondOp.pointer > 0) {
|
|
|
|
|
return secondOp as LLVMVariable
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
val result = firstOp as LLVMVariable
|
|
|
|
|
codeBuilder.storeVariable(result, secondNativeOp)
|
|
|
|
|
return result
|
|
|
|
@@ -564,10 +562,6 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun copyVariable(from: LLVMVariable, to: LLVMVariable) = when (from.type) {
|
|
|
|
|
is LLVMStringType -> codeBuilder.storeString(to, from, 0)
|
|
|
|
|
else -> codeBuilder.copyVariableValue(to, from)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun evaluateValExpression(element: KtProperty, scopeDepth: Int): LLVMVariable? {
|
|
|
|
|
val variable = state.bindingContext.get(BindingContext.VARIABLE, element)!!
|
|
|
|
@@ -584,7 +578,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
allocVar.kotlinName = identifier
|
|
|
|
|
|
|
|
|
|
variableManager.addVariable(identifier, allocVar, scopeDepth)
|
|
|
|
|
copyVariable(assignExpression, allocVar)
|
|
|
|
|
codeBuilder.copyVariable(assignExpression, allocVar)
|
|
|
|
|
} else {
|
|
|
|
|
assignExpression.kotlinName = identifier
|
|
|
|
|
variableManager.addVariable(identifier, assignExpression, scopeDepth)
|
|
|
|
@@ -601,9 +595,8 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
reference.pointer += 1
|
|
|
|
|
|
|
|
|
|
codeBuilder.storeNull(reference)
|
|
|
|
|
val result = codeBuilder.loadAndGetVariable(reference)
|
|
|
|
|
|
|
|
|
|
variableManager.addVariable(identifier, result, scopeDepth)
|
|
|
|
|
variableManager.addVariable(identifier, reference, scopeDepth)
|
|
|
|
|
return null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -620,12 +613,16 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|
|
|
|
|
|
|
|
|
private fun evaluateReturnInstruction(element: PsiElement, scopeDepth: Int): LLVMVariable? {
|
|
|
|
|
val next = element.getNextSiblingIgnoringWhitespaceAndComments()
|
|
|
|
|
val retVar = evaluateExpression(next, scopeDepth)
|
|
|
|
|
var retVar = evaluateExpression(next, scopeDepth)
|
|
|
|
|
val type = retVar?.type ?: LLVMVoidType()
|
|
|
|
|
|
|
|
|
|
when (type) {
|
|
|
|
|
is LLVMReferenceType -> {
|
|
|
|
|
codeBuilder.storeVariable(returnType!!, retVar!!)
|
|
|
|
|
if (retVar!!.pointer == 2) {
|
|
|
|
|
retVar = codeBuilder.loadAndGetVariable(retVar as LLVMVariable)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
codeBuilder.storeVariable(returnType!!, retVar)
|
|
|
|
|
codeBuilder.addAnyReturn(LLVMVoidType())
|
|
|
|
|
}
|
|
|
|
|
is LLVMVoidType -> {
|
|
|
|
|