Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/nw23001440/omitted parameter on program call #405

Merged
merged 8 commits into from
Jan 26, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class SymbolTable : ISymbolTable {
}

override fun dataDefinitionByName(dataName: String): AbstractDataDefinition? {
return names[dataName.toUpperCase()] ?: parentSymbolTable?.let { (parentSymbolTable as SymbolTable).names[dataName.toUpperCase()] }
return names[dataName.uppercase()] ?: parentSymbolTable?.let { (parentSymbolTable as SymbolTable).names[dataName.uppercase()] }
}

override operator fun set(data: AbstractDataDefinition, value: Value): Value? {
Expand All @@ -100,7 +100,7 @@ class SymbolTable : ISymbolTable {
require(data.type.canBeAssigned(value)) {
"Value $value cannot be assigned to data: $data"
}
names[data.name.toUpperCase()] = data
names[data.name.uppercase()] = data
return values.put(data, value.forType(data.type))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,13 @@ class InterpreterStatus(
var lastDBFile: DBFile? = null
val dbFileMap = DBFileMap()
fun indicator(key: IndicatorKey) = indicators[key] ?: BooleanValue.FALSE
fun getVar(abstractDataDefinition: AbstractDataDefinition): Value = symbolTable[abstractDataDefinition]
fun getVar(abstractDataDefinition: AbstractDataDefinition): Value {
val tmpValue = symbolTable[abstractDataDefinition]
if (tmpValue is VoidValue) {
throw IllegalArgumentException("Void value for ${abstractDataDefinition.name}")
}
return tmpValue
}
}

open class InternalInterpreter(
Expand Down Expand Up @@ -130,9 +136,7 @@ open class InternalInterpreter(

override fun dataDefinitionByName(name: String) = globalSymbolTable.dataDefinitionByName(name)

override operator fun get(data: AbstractDataDefinition): Value {
return globalSymbolTable[data]
}
override operator fun get(data: AbstractDataDefinition) = globalSymbolTable[data]

override operator fun get(dataName: String) = globalSymbolTable[dataName]

Expand Down Expand Up @@ -273,7 +277,14 @@ open class InternalInterpreter(
if (value != null) {
set(it, coerce(value, it.type))
if (it is DataDefinition) {
it.defaultValue = globalSymbolTable[it].copy()
try {
val tmpValue = globalSymbolTable[it]
if (tmpValue !is VoidValue) {
it.defaultValue = tmpValue.copy()
}
} catch (exc: IllegalArgumentException) {
it.defaultValue = null
}
}
executeMutes(it.muteAnnotations, compilationUnit, "(data definition)")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,23 @@ class RpgProgram(val cu: CompilationUnit, val name: String = "<UNNAMED RPG PROGR
}

override fun execute(systemInterface: SystemInterface, params: LinkedHashMap<String, Value>): List<Value> {
require(params.keys.toSet() == params().asSequence().map { it.name }.toSet()) {
"Expected params: ${params().asSequence().map { it.name }.joinToString(", ")}"
val expectedKeys = params().asSequence().map { it.name }.toSet()

if (expectedKeys.size <= params.size) {
require(params.keys.toSet() == params().asSequence().map { it.name }.toSet()) {
"Expected params: ${params().asSequence().map { it.name }.joinToString(", ")}"
}
} else {
require(params().asSequence().map { it.name }.toSet().all { it in expectedKeys }) {
"Expected params: ${params().asSequence().map { it.name }.joinToString(", ")}"
}

// Set not passed params to VoidValue
params().forEach {
if (it.name !in params.keys) {
params[it.name] = VoidValue
}
}
}
this.systemInterface = systemInterface
logHandlers.log(ProgramInterpretationLogStart(name, params))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1038,17 +1038,18 @@ fun areEquals(value1: Value, value2: Value): Boolean {

@Serializable
object VoidValue : Value {

override fun asString(): StringValue {
TODO("Not yet implemented")
override fun toString(): String {
return "VoidValue"
}

override fun assignableTo(expectedType: Type): Boolean {
TODO("Not yet implemented")
return true
}

override fun copy(): Value {
TODO("Not yet implemented")
override fun copy(): VoidValue = this

override fun asString(): StringValue {
return StringValue(this.toString())
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,9 @@ data class CallStmt(
null
}
paramValuesAtTheEnd?.forEachIndexed { index, value ->
interpreter.assign(this.params[index].param.referred!!, value)
if (this.params.size > index) {
interpreter.assign(this.params[index].param.referred!!, value)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.test.BeforeTest
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue

open class SmeupInterpreterTest : AbstractTest() {
Expand Down Expand Up @@ -208,4 +209,14 @@ open class SmeupInterpreterTest : AbstractTest() {
val expected = listOf("A50_AR1(10) A50_AR2(40)")
assertEquals(expected, "smeup/T02_A50_P03".outputOf())
}

@Test
fun executeT10_A60_P04() {
val expected = listOf<String>("C10_P1: MULANGT102")
assertEquals(expected, "smeup/T10_A60_P04".outputOf())

assertFailsWith<Exception> {
"smeup/T10_A60_P04F".outputOf()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
D C10_P1 S 50
D C10_P2 S 2 0
D C10_P3 S 50
*
D B10_A50 S 50
*---------------------------------------------------------------------
C *ENTRY PLIST
C PARM C10_P1
C PARM C10_P2
C PARM C10_P3
*
C IF C10_P2=1
C EVAL C10_P1 ='C10_P1: '+%TRIMR(C10_P1)
C EVAL C10_P2 = 2
C ENDIF
*
C SETON LR
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
**************************************************************************
D £DBG_Str S 2560 Stringa
*
D A60_P1 S 50 INZ('MULANGT10')
D A60_P2 S 2 0
D A60_P3 S 50
C CLEAR A60_P3
C CALL 'MULANGTC10'
C PARM A60_P1
C PARM 1 A60_P2
C EVAL £DBG_Str=%TRIM(A60_P1)+%CHAR(A60_P2)
C £DBG_Str DSPLY
*
C SETON LR
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
**************************************************************************
D £DBG_Str S 2560 Stringa
*
D A60_P1 S 10 INZ('MULANGT10')
D A60_P2 S 2 0
D A60_P3 S 50
C CLEAR A60_P3
C CLEAR A60_P2
C CALL 'MULANGTC10'
C PARM A60_P1
C EVAL £DBG_Str='THIS SHOULD BE UNREACHABLE'
C £DBG_Str DSPLY
C*
C SETON LR
Loading