Implement do while loop

This commit is contained in:
Ivan Kylchik
2020-04-15 14:37:13 +03:00
parent 1e82975a7c
commit 2c93c46b84
2 changed files with 22 additions and 5 deletions
@@ -107,6 +107,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
is IrTypeOperatorCall -> interpretTypeOperatorCall(this) is IrTypeOperatorCall -> interpretTypeOperatorCall(this)
is IrBranch -> interpretBranch(this) is IrBranch -> interpretBranch(this)
is IrWhileLoop -> interpretWhile(this) is IrWhileLoop -> interpretWhile(this)
is IrDoWhileLoop -> interpretDoWhile(this)
is IrWhen -> interpretWhen(this) is IrWhen -> interpretWhen(this)
is IrBreak -> interpretBreak(this) is IrBreak -> interpretBreak(this)
is IrContinue -> interpretContinue(this) is IrContinue -> interpretContinue(this)
@@ -444,13 +445,26 @@ class IrInterpreter(irModule: IrModuleFragment) {
} }
private suspend fun interpretWhile(expression: IrWhileLoop): ExecutionResult { private suspend fun interpretWhile(expression: IrWhileLoop): ExecutionResult {
var executionResult: ExecutionResult
while (true) { while (true) {
executionResult = expression.condition.interpret().check { return it } expression.condition.interpret().check { return it }
val condition = stack.popReturnValue().asBooleanOrNull() if (stack.popReturnValue().asBooleanOrNull() != true) break
if (condition != true) break else expression.body?.interpret()?.check { return it } ?: return Next expression.body?.interpret()?.check { return it }
} }
return executionResult return Next
}
private suspend fun interpretDoWhile(expression: IrDoWhileLoop): ExecutionResult {
do {
// pool from body must be seen to condition expression, so must create temp frame here
stack.newFrame(asSubFrame = true) {
expression.body?.interpret()?.check { return@newFrame it }
expression.condition.interpret().check { return@newFrame it }
Next
}.check { return it }
if (stack.popReturnValue().asBooleanOrNull() != true) break
} while (true)
return Next
} }
private suspend fun interpretWhen(expression: IrWhen): ExecutionResult { private suspend fun interpretWhen(expression: IrWhen): ExecutionResult {
@@ -707,6 +721,7 @@ class IrInterpreter(irModule: IrModuleFragment) {
private suspend fun interpretComposite(expression: IrComposite): ExecutionResult { private suspend fun interpretComposite(expression: IrComposite): ExecutionResult {
return when (expression.origin) { return when (expression.origin) {
IrStatementOrigin.DESTRUCTURING_DECLARATION -> interpretStatements(expression.statements) IrStatementOrigin.DESTRUCTURING_DECLARATION -> interpretStatements(expression.statements)
null -> interpretStatements(expression.statements) // is null for body of do while loop
else -> TODO("${expression.origin} not implemented") else -> TODO("${expression.origin} not implemented")
} }
} }
@@ -139,4 +139,6 @@ private class FrameContainer(current: Frame = InterpreterFrame()) {
fun pushReturnValue(state: State) = getTopFrame().pushReturnValue(state) fun pushReturnValue(state: State) = getTopFrame().pushReturnValue(state)
fun popReturnValue() = getTopFrame().popReturnValue() fun popReturnValue() = getTopFrame().popReturnValue()
fun peekReturnValue() = getTopFrame().peekReturnValue() fun peekReturnValue() = getTopFrame().peekReturnValue()
override fun toString() = frameEntryPoint ?: "Not defined"
} }