Skip to content

Commit

Permalink
Restore GotoTopLevelException promotion logic
Browse files Browse the repository at this point in the history
  • Loading branch information
dom-apuliasoft committed Nov 25, 2024
1 parent 6e1914a commit 8e8c96c
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.smeup.rpgparser.interpreter

import com.smeup.rpgparser.execution.MainExecutionContext
import com.smeup.rpgparser.parsing.ast.Statement
import com.smeup.rpgparser.utils.indexOfTag
import com.smeup.rpgparser.utils.runIfNotEmpty
Expand Down Expand Up @@ -44,15 +43,6 @@ class GotoException private constructor(val tag: String) : ControlFlowException(
internal fun indexOfTaggedStatement(statements: List<Statement>) = statements.indexOfTag(tag)
}

/**
* Produce a scoped goto exception
*/
internal fun produceGotoInCurrentScope(tag: String): ControlFlowException {
val shouldLookupTopLevel = MainExecutionContext.getSubroutineStack().isEmpty()
val normalizedTag = tag.lowercase()
return if (shouldLookupTopLevel) GotoTopLevelException(normalizedTag) else GotoException(normalizedTag)
}

class InterpreterTimeoutException(val programName: String, val elapsed: Long, val expected: Long) : ControlFlowException() {
fun ratio(): Double = if (elapsed <= 0) 0.0 else elapsed.toDouble() / expected.toDouble()
override fun toString(): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import com.smeup.rpgparser.parsing.facade.SourceReference
import com.smeup.rpgparser.parsing.facade.dumpSource
import com.smeup.rpgparser.parsing.facade.relative
import com.smeup.rpgparser.parsing.parsetreetoast.RpgType
import com.smeup.rpgparser.parsing.parsetreetoast.error
import com.smeup.rpgparser.parsing.parsetreetoast.resolveAndValidate
import com.smeup.rpgparser.parsing.parsetreetoast.todo
import com.smeup.rpgparser.utils.ComparisonOperator.*
Expand Down Expand Up @@ -427,10 +428,15 @@ open class InternalInterpreter(
val unwrappedStatement = main.stmts.explode(true)

// Recursive deal with top level goto flow
while (throwable is GotoTopLevelException) {
while (throwable is GotoTopLevelException || throwable is GotoException) {
// We need to know the statement unwrapped in order to jump directly into a nested tag
val offset = throwable.indexOfTaggedStatement(unwrappedStatement)
require(0 <= offset && offset < unwrappedStatement.size) { "Offset $offset is not valid." }
val (offset, tag) = when (throwable) {
is GotoException -> Pair(throwable.indexOfTaggedStatement(unwrappedStatement), throwable.tag)
is GotoTopLevelException -> Pair(throwable.indexOfTaggedStatement(unwrappedStatement), throwable.tag)
else -> Pair(-1, "")
}
if (unwrappedStatement.size <= offset || offset < 0)
main.error("GOTO offset $offset is not valid. Cannot find TAG '$tag'")
throwable = kotlin.runCatching {
executeUnwrappedAt(unwrappedStatement, offset)
}.exceptionOrNull()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1911,7 +1911,7 @@ data class GotoStmt(val tag: String, override val position: Position? = null) :
get() = "GOTO"

override fun execute(interpreter: InterpreterCore) {
throw produceGotoInCurrentScope(tag)
throw GotoException(tag)
}
}

Expand All @@ -1935,7 +1935,7 @@ data class CabStmt(
SMALLER -> interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.TRUE, BooleanValue.FALSE)
else -> interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.FALSE, BooleanValue.TRUE)
}
if (comparisonResult.isVerified) throw produceGotoInCurrentScope(tag)
if (comparisonResult.isVerified) throw GotoException(tag)
}
}

Expand Down

0 comments on commit 8e8c96c

Please sign in to comment.