From 4be78b789e10d456371a21ad8253aa9eb9fde5da Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Wed, 10 Aug 2016 13:26:23 +0300 Subject: [PATCH] translator: add not operator --- .../org/kotlinnative/translator/BlockCodegen.kt | 14 ++++++++++++-- .../translator/llvm/types/LLVMBooleanType.kt | 9 +++++++++ .../test/kotlin/tests/input/unary_operators_1.txt | 2 ++ .../test/kotlin/tests/kotlin/unary_operators_1.kt | 4 ++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt index ff73472e5a3..5c2822cc2ab 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/BlockCodegen.kt @@ -568,6 +568,13 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va KtTokens.PLUS -> { return addPrimitiveBinaryOperation(operator!!, operationReference, LLVMConstant("0", firstOp.type), firstOp) } + KtTokens.EXCL -> { + val firstNativeOp = codeBuilder.receiveNativeValue(firstOp) + val llvmExpression = addPrimitiveReferenceOperationByName("xor", LLVMConstant("true", LLVMBooleanType()), firstNativeOp) + val resultOp = codeBuilder.getNewVariable(llvmExpression.variableType) + codeBuilder.addAssignment(resultOp, llvmExpression) + return resultOp + } else -> throw UnsupportedOperationException() } } @@ -606,9 +613,12 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va return left } - fun addPrimitiveReferenceOperation(referenceName: KtSimpleNameExpression, firstOp: LLVMSingleValue, secondNativeOp: LLVMSingleValue): LLVMExpression { + fun addPrimitiveReferenceOperation(referenceName: KtSimpleNameExpression, firstOp: LLVMSingleValue, secondNativeOp: LLVMSingleValue): LLVMExpression + = addPrimitiveReferenceOperationByName(referenceName.getReferencedName(), firstOp, secondNativeOp) + + fun addPrimitiveReferenceOperationByName(operator: String, firstOp: LLVMSingleValue, secondNativeOp: LLVMSingleValue): LLVMExpression { val firstNativeOp = codeBuilder.receiveNativeValue(firstOp) - return when (referenceName.getReferencedName()) { + return when (operator) { "or" -> firstNativeOp.type!!.operatorOr(firstNativeOp, secondNativeOp) "xor" -> firstNativeOp.type!!.operatorXor(firstNativeOp, secondNativeOp) "and" -> firstNativeOp.type!!.operatorAnd(firstNativeOp, secondNativeOp) diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt index d978dc59073..cdbe57341be 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/types/LLVMBooleanType.kt @@ -37,6 +37,15 @@ class LLVMBooleanType() : LLVMType() { override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = LLVMExpression(LLVMBooleanType(), "icmp ne i1 $firstOp, $secondOp") + override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + LLVMExpression(LLVMBooleanType(), "or i1 $firstOp, $secondOp") + + override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + LLVMExpression(LLVMBooleanType(), "and i1 $firstOp, $secondOp") + + override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = + LLVMExpression(LLVMBooleanType(), "xor i1 $firstOp, $secondOp") + override fun equals(other: Any?): Boolean { return other is LLVMBooleanType } diff --git a/translator/src/test/kotlin/tests/input/unary_operators_1.txt b/translator/src/test/kotlin/tests/input/unary_operators_1.txt index 2e18cb0bbea..752ab97e7db 100644 --- a/translator/src/test/kotlin/tests/input/unary_operators_1.txt +++ b/translator/src/test/kotlin/tests/input/unary_operators_1.txt @@ -2,3 +2,5 @@ unary_operator_1_minus_Int(-5) == 5 unary_operator_1_minus_Int(5) == -5 unary_operator_1_plus_Int(-5) == -5 unary_operator_1_plus_Int(5) == 5 +unary_operator_1_not_Boolean(1) == 0 +unary_operator_1_not_Boolean(0) == 1 diff --git a/translator/src/test/kotlin/tests/kotlin/unary_operators_1.kt b/translator/src/test/kotlin/tests/kotlin/unary_operators_1.kt index eec10598eaf..c45d721e185 100644 --- a/translator/src/test/kotlin/tests/kotlin/unary_operators_1.kt +++ b/translator/src/test/kotlin/tests/kotlin/unary_operators_1.kt @@ -4,4 +4,8 @@ fun unary_operator_1_minus(x : Int): Int { fun unary_operator_1_plus(x : Int): Int { return x +} + +fun unary_operator_1_not(x : Boolean): Boolean { + return !x } \ No newline at end of file