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.impl.source.tree.LeafPsiElement
|
||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.cfg.UnreachableCode
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
|
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
|
||||||
@@ -54,6 +55,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|||||||
when (expr) {
|
when (expr) {
|
||||||
is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1)
|
is KtBlockExpression -> expressionWalker(expr.firstChild, scopeDepth + 1)
|
||||||
is KtProperty -> evaluateValExpression(expr, scopeDepth)
|
is KtProperty -> evaluateValExpression(expr, scopeDepth)
|
||||||
|
is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth)
|
||||||
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
||||||
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
|
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
|
||||||
is KtDoWhileExpression -> evaluateDoWhileExpression(expr.firstChild, scopeDepth + 1)
|
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? {
|
private fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? {
|
||||||
return when (expr) {
|
return when (expr) {
|
||||||
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
|
||||||
|
is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth)
|
||||||
is KtConstantExpression -> evaluateConstantExpression(expr)
|
is KtConstantExpression -> evaluateConstantExpression(expr)
|
||||||
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
|
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
|
||||||
is KtWhenExpression -> evaluateWhenExpression(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)
|
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)
|
private fun executeBinaryExpression(operator: IElementType, referenceName: KtSimpleNameExpression?, left: LLVMSingleValue, right: LLVMSingleValue)
|
||||||
= addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
= addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class ProjectTranslator(val files: List<KtFile>, val state: TranslationState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateProjectBody() {
|
private fun generateProjectBody() {
|
||||||
with (state) {
|
with(state) {
|
||||||
properties.values.map { it.generate() }
|
properties.values.map { it.generate() }
|
||||||
objects.values.map { it.generate() }
|
objects.values.map { it.generate() }
|
||||||
classes.values.map { it.generate() }
|
classes.values.map { it.generate() }
|
||||||
|
|||||||
@@ -36,12 +36,17 @@ class LLVMIntType() : LLVMType() {
|
|||||||
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||||
LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp")
|
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 =
|
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||||
LLVMExpression(LLVMBooleanType(), "icmp slt i32 $firstOp, $secondOp")
|
LLVMExpression(LLVMBooleanType(), "icmp slt i32 $firstOp, $secondOp")
|
||||||
|
|
||||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression {
|
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||||
return LLVMExpression(LLVMBooleanType(), "icmp sgt i32 $firstOp, $secondOp")
|
LLVMExpression(LLVMBooleanType(), "icmp sgt i32 $firstOp, $secondOp")
|
||||||
}
|
|
||||||
|
|
||||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||||
LLVMExpression(LLVMBooleanType(), "icmp sle i32 $firstOp, $secondOp")
|
LLVMExpression(LLVMBooleanType(), "icmp sle i32 $firstOp, $secondOp")
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ class LLVMLongType() : LLVMType() {
|
|||||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||||
LLVMExpression(LLVMBooleanType(), "icmp slt i64 $firstOp, $secondOp")
|
LLVMExpression(LLVMBooleanType(), "icmp slt i64 $firstOp, $secondOp")
|
||||||
|
|
||||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression {
|
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||||
return LLVMExpression(LLVMBooleanType(), "icmp sgt i64 $firstOp, $secondOp")
|
LLVMExpression(LLVMBooleanType(), "icmp sgt i64 $firstOp, $secondOp")
|
||||||
}
|
|
||||||
|
|
||||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||||
LLVMExpression(LLVMBooleanType(), "icmp sle i64 $firstOp, $secondOp")
|
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 operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||||
open fun operatorShr(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 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
|
open fun parseArg(inputArg: String) = inputArg
|
||||||
|
|
||||||
fun makeClone() = clone()
|
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