translator: add do-while loops

This commit is contained in:
Alexey Stepanov
2016-07-18 09:18:49 +03:00
parent 260bb64d8f
commit fef7a3c463
3 changed files with 21 additions and 3 deletions
@@ -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)
@@ -0,0 +1,2 @@
do_while_test_1(5) == 6
do_while_test_1(57) == 68
@@ -0,0 +1,7 @@
fun do_while_test_1(x: Int): Int {
var t = x
do {
t = t + 1
} while (2 > 3)
return t
}