translator: add prefix operators - increment, decrement
This commit is contained in:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user