translator: add prefix operators - increment, decrement

This commit is contained in:
Alexey Stepanov
2016-07-22 15:20:27 +03:00
parent f8e4a296e2
commit a05307724c
7 changed files with 94 additions and 7 deletions
@@ -5,6 +5,7 @@ import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.cfg.UnreachableCode
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
@@ -54,6 +55,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
when (expr) {
is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1)
is KtProperty -> evaluateValExpression(expr, scopeDepth)
is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth)
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
is KtDoWhileExpression -> evaluateDoWhileExpression(expr.firstChild, scopeDepth + 1)
@@ -79,6 +81,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
private fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? {
return when (expr) {
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth)
is KtConstantExpression -> evaluateConstantExpression(expr)
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
is KtWhenExpression -> evaluateWhenExpression(expr, scopeDepth)
@@ -393,6 +396,42 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
return executeBinaryExpression(operator, expr.operationReference, left, right)
}
private fun evaluatePostfixExpression(expr: KtPostfixExpression, scopeDepth: Int): LLVMSingleValue? {
val operator = expr.operationToken
val left = evaluateExpression(expr.baseExpression, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
return executePostfixExpression(operator, expr.operationReference, left as LLVMVariable)
}
private fun executePostfixExpression(operator: IElementType?, operationReference: KtSimpleNameExpression, left: LLVMVariable): LLVMSingleValue?
= addPrimitivePostfixOperation(operator, operationReference, left)
private fun addPrimitivePostfixOperation(operator: IElementType?, operationReference: KtSimpleNameExpression, firstOp: LLVMVariable): LLVMSingleValue? {
val firstNativeOp = codeBuilder.receiveNativeValue(firstOp)
when (operator) {
KtTokens.PLUSPLUS, KtTokens.MINUSMINUS -> {
val oldValue = codeBuilder.getNewVariable(firstOp.type, firstOp.pointer)
codeBuilder.allocStackPointedVarAsValue(oldValue)
codeBuilder.copyVariable(firstOp, oldValue)
val llvmExpression = when (operator) {
KtTokens.PLUSPLUS -> firstOp.type.operatorInc(firstNativeOp)
KtTokens.MINUSMINUS -> firstOp.type.operatorDec(firstNativeOp)
else -> throw IllegalAccessError()
}
val resultOp = codeBuilder.getNewVariable(llvmExpression.variableType)
codeBuilder.addAssignment(resultOp, llvmExpression)
codeBuilder.storeVariable(firstOp, resultOp)
return oldValue
}
else -> throw UnsupportedOperationException()
}
}
private fun executeBinaryExpression(operator: IElementType, referenceName: KtSimpleNameExpression?, left: LLVMSingleValue, right: LLVMSingleValue)
= addPrimitiveBinaryOperation(operator, referenceName, left, right)
@@ -40,7 +40,7 @@ class ProjectTranslator(val files: List<KtFile>, val state: TranslationState) {
}
private fun generateProjectBody() {
with (state) {
with(state) {
properties.values.map { it.generate() }
objects.values.map { it.generate() }
classes.values.map { it.generate() }
@@ -36,12 +36,17 @@ class LLVMIntType() : LLVMType() {
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp")
override fun operatorInc(firstOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, 1")
override fun operatorDec(firstOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, 1")
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMBooleanType(), "icmp slt i32 $firstOp, $secondOp")
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression {
return LLVMExpression(LLVMBooleanType(), "icmp sgt i32 $firstOp, $secondOp")
}
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMBooleanType(), "icmp sgt i32 $firstOp, $secondOp")
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMBooleanType(), "icmp sle i32 $firstOp, $secondOp")
@@ -39,9 +39,9 @@ class LLVMLongType() : LLVMType() {
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMBooleanType(), "icmp slt i64 $firstOp, $secondOp")
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression {
return LLVMExpression(LLVMBooleanType(), "icmp sgt i64 $firstOp, $secondOp")
}
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMBooleanType(), "icmp sgt i64 $firstOp, $secondOp")
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
LLVMExpression(LLVMBooleanType(), "icmp sle i64 $firstOp, $secondOp")
@@ -21,6 +21,8 @@ abstract class LLVMType() : Cloneable {
open fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
open fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
open fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
open fun operatorInc(firstOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
open fun operatorDec(firstOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
open fun parseArg(inputArg: String) = inputArg
fun makeClone() = clone()
@@ -0,0 +1,6 @@
postfix_1_plus_before_Int(20) == 20
postfix_1_plus_after_Int(20) == 21
postfix_1_plus_inside_Int(20) == 21
postfix_1_minus_before_Int(20) == 20
postfix_1_minus_after_Int(20) == 19
postfix_1_minus_inside_Int(20) == 19
@@ -0,0 +1,35 @@
fun postfix_1_plus_before(x: Int): Int {
var xx = x
val z = xx++
return z
}
fun postfix_1_plus_after(x: Int): Int {
var xx = x
val z = xx++
return xx
}
fun postfix_1_plus_inside(x: Int): Int {
var xx = x
xx++
return xx
}
fun postfix_1_minus_before(x: Int): Int {
var xx = x
val z = xx--
return z
}
fun postfix_1_minus_after(x: Int): Int {
var xx = x
val z = xx--
return xx
}
fun postfix_1_minus_inside(x: Int): Int {
var xx = x
xx--
return xx
}