Implement do while loop
This commit is contained in:
+20
-5
@@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -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"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user