From fef7a3c463b98e1751239a9481bf0f523b1f9fe5 Mon Sep 17 00:00:00 2001 From: Alexey Stepanov Date: Mon, 18 Jul 2016 09:18:49 +0300 Subject: [PATCH] translator: add do-while loops --- .../kotlinnative/translator/FunctionCodegen.kt | 15 ++++++++++++--- .../src/test/kotlin/tests/input/do_while_1.txt | 2 ++ .../src/test/kotlin/tests/kotlin/do_while_1.kt | 7 +++++++ 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 translator/src/test/kotlin/tests/input/do_while_1.txt create mode 100644 translator/src/test/kotlin/tests/kotlin/do_while_1.kt diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index ca9ed2d1eb7..52be6c583db 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments +import org.jetbrains.kotlin.psi.psiUtil.siblings import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getValueArgumentsInParentheses import org.jetbrains.kotlin.resolve.constants.TypedCompileTimeConstant @@ -124,6 +125,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction is KtProperty -> evaluateLeafPsiElement(expr.firstChild as LeafPsiElement, scopeDepth) is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth) is KtCallExpression -> evaluateCallExpression(expr, scopeDepth) + is KtDoWhileExpression -> evaluateDoWhileExpression(expr.firstChild, scopeDepth + 1) is PsiElement -> evaluateExpression(expr.firstChild, scopeDepth + 1) null -> { variableManager.pullUpwardsLevel(scopeDepth) @@ -135,6 +137,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction expressionWalker(expr.getNextSiblingIgnoringWhitespaceAndComments(), scopeDepth) } + private fun evaluateDoWhileExpression(element: PsiElement, scopeDepth: Int) { + val bodyExpression = element.getNextSiblingIgnoringWhitespaceAndComments() ?: return + val condition = bodyExpression.siblings(withItself = false).filter { it is KtContainerNode }.firstOrNull() ?: return + + executeWhileBlock(condition.firstChild as KtBinaryExpression, bodyExpression.firstChild, scopeDepth, checkConditionBeforeExecute = false) + } + private fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? { return when (expr) { is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth) @@ -356,15 +365,15 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction getBrackets = condition.getNextSiblingIgnoringWhitespaceAndComments() ?: return null val bodyExpression = getBrackets.getNextSiblingIgnoringWhitespaceAndComments() ?: return null - return executeWhileBlock(condition.firstChild as KtBinaryExpression, bodyExpression.firstChild, scopeDepth) + return executeWhileBlock(condition.firstChild as KtBinaryExpression, bodyExpression.firstChild, scopeDepth, checkConditionBeforeExecute = true) } - private fun executeWhileBlock(condition: KtBinaryExpression, bodyExpression: PsiElement, scopeDepth: Int): LLVMVariable? { + private fun executeWhileBlock(condition: KtBinaryExpression, bodyExpression: PsiElement, scopeDepth: Int, checkConditionBeforeExecute: Boolean): LLVMVariable? { val conditionLabel = codeBuilder.getNewLabel(prefix = "while") val bodyLabel = codeBuilder.getNewLabel(prefix = "while") val exitLabel = codeBuilder.getNewLabel(prefix = "while") - codeBuilder.addUnconditionalJump(conditionLabel) + codeBuilder.addUnconditionalJump(if (checkConditionBeforeExecute) conditionLabel else bodyLabel) codeBuilder.markWithLabel(conditionLabel) val conditionResult = evaluateBinaryExpression(condition, scopeDepth + 1) diff --git a/translator/src/test/kotlin/tests/input/do_while_1.txt b/translator/src/test/kotlin/tests/input/do_while_1.txt new file mode 100644 index 00000000000..8ed138d0b7c --- /dev/null +++ b/translator/src/test/kotlin/tests/input/do_while_1.txt @@ -0,0 +1,2 @@ +do_while_test_1(5) == 6 +do_while_test_1(57) == 68 \ No newline at end of file diff --git a/translator/src/test/kotlin/tests/kotlin/do_while_1.kt b/translator/src/test/kotlin/tests/kotlin/do_while_1.kt new file mode 100644 index 00000000000..528bf62c37b --- /dev/null +++ b/translator/src/test/kotlin/tests/kotlin/do_while_1.kt @@ -0,0 +1,7 @@ +fun do_while_test_1(x: Int): Int { + var t = x + do { + t = t + 1 + } while (2 > 3) + return t +} \ No newline at end of file