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

Feature/ls24003953/parm factor1 #606

Merged
merged 10 commits into from
Sep 11, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ class ExpressionEvaluation(
StringValue(s)
}
}
left is StringValue && right is BooleanValue -> {
val s = left.trimEndIfVarying() + right.asString().value
s.asValue()
}
else -> {
throw UnsupportedOperationException("I do not know how to sum $left and $right at ${expression.position}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ data class StringValue(var value: String, var varying: Boolean = false) : Abstra
else -> super.compareTo(other)
}

internal fun trimEndIfVarying() = if (varying) value.trimEnd() else value

override fun getWrappedString() = value
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,11 @@ data class CallStmt(
}
paramValuesAtTheEnd?.forEachIndexed { index, value ->
if (this.params.size > index) {
interpreter.assign(this.params[index].param.referred!!, value)
val currentParam = this.params[index]
interpreter.assign(currentParam.param.referred!!, value)

// If we also have a result field, assign to it
currentParam.result?.let { interpreter.assign(it, value) }
}
}
}
Expand Down Expand Up @@ -1107,6 +1111,7 @@ data class PlistStmt(

@Serializable
data class PlistParam(
val result: AssignableExpression?,
val param: ReferenceByName<AbstractDataDefinition>,
// TODO @Derived????
@Derived val dataDefinition: InStatementDataDefinition? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1186,20 +1186,22 @@ internal fun CsPARMContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()
if (paramName.contains(".")) {
val parts = paramName.split(".")
require(parts.isNotEmpty())
if (parts.size == 1) {
paramName = parts[0]
} else {
paramName = parts.last()
}
paramName = parts.last()
}
// initialization value valid only if there isn't a variable declaration
val initializationValue = if (this.cspec_fixed_standard_parts().len.asInt() == null) {
this.cspec_fixed_standard_parts().factor2Expression(conf)
} else {
null
}

val factor1Text = this.factor1.text.trim()
val factor1Position = this.factor1.toPosition(conf.considerPosition)
val result = if (factor1Text.isNotEmpty()) annidatedReferenceExpression(factor1Text, factor1Position) else null

val position = toPosition(conf.considerPosition)
return PlistParam(
result,
ReferenceByName(paramName),
this.cspec_fixed_standard_parts().toDataDefinition(
paramName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2459,4 +2459,16 @@ Test 6
val expected = listOf("ok")
assertEquals(expected, "EXCPCALLER".outputOf())
}

@Test
fun executePRSLTCALLER() {
val expected = listOf("(1,1)", "(0,0)", "(1,1,0,0,0)")
assertEquals(expected, "PRSLTCALLER".outputOf())
}

@Test
fun executePRSLTCALLERDUPLICATE() {
val expected = listOf("0", "0", "0", "1")
assertEquals(expected, "PRSLTCALLERDUPLICATE".outputOf())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* Called by PRSLTCALLER.rpgle
* Takes $A as parameter and updates it's value
C *ENTRY PLIST
C PARM $A 1
C PARM $B 1
C PARM $C 1
C EVAL $A = *ON
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* Called by PRSLTCALLERDUPLICATE.rpgle
C *ENTRY PLIST
C PARM $A 1
C PARM $B 1
C PARM $C 1
C EVAL $A = *ON
C EVAL $B = *OFF
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
* Called by PRSLTCALLERDUPLICATE.rpgle
C *ENTRY PLIST
C PARM $A 1
C PARM $B 1
C PARM $C 1
C EVAL $A = *ON
C EVAL $B = *OFF
C EVAL $A = *ON
21 changes: 21 additions & 0 deletions rpgJavaInterpreter-core/src/test/resources/PRSLTCALLER.rpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
* Helper declarations
D £DBG_Str S 512

* Call PRSLTCALLEE passing parameter $A bound with *IN35 and $B bound with *IN36
* If $A or $B get updated by PRSLTCALLEE, the new value must be
* bound to the factor 1 of the param (*IN35 or *IN36)
C CALL 'PRSLTCALLEE'
C *IN35 PARM *OFF $A 1 Should be updated
C *IN36 PARM *OFF $B 1 Should not be updated
C PARM *OFF $C 1 Should have no influence

* Updated value output
C EVAL £DBG_Str = '('+$A+','+*IN35+')'
C £DBG_Str DSPLY
* Not updated value output
C EVAL £DBG_Str = '('+$B+','+*IN36+')'
C £DBG_Str DSPLY
* No influence output
C EVAL £DBG_Str = '('+$A+','+*IN35+','+$B+','+
C *IN36+','+$C+')'
C £DBG_Str DSPLY
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
* Helper declarations
D £DBG_Str S 512

* A variant of PRSLTCALLER binding the same identifier (*IN35) to parameters $A and $B
* Assignment should happen sequentially from first to last on call exit

* Only update $A
C CALL 'PRSLTCALLEE'
C *IN35 PARM *OFF $A 1 Should be updated
C *IN35 PARM *OFF $B 1 Should not be updated
C PARM *OFF $C 1 Should have no influence

* $A is the last value updated output
C *IN35 DSPLY

* Update $A then $B
C CALL 'PRSLTCALLEE2'
C *IN35 PARM *OFF $A 1 Should be updated
C *IN35 PARM *OFF $B 1 Should be updated
C PARM *OFF $C 1 Should have no influence

* $B is the last value updated output
C *IN35 DSPLY

* Update $A then $B then $A again
C CALL 'PRSLTCALLEE3'
C *IN35 PARM *OFF $A 1 Should be updated
C *IN35 PARM *OFF $B 1 Should be updated
C PARM *OFF $C 1 Should have no influence

* Mixed update test
C *IN35 DSPLY

* Update $A then $B then $A again without duplicate binding
C CALL 'PRSLTCALLEE3'
C *IN35 PARM *OFF $A 1 Should be updated
C PARM *OFF $B 1 Should be updated
C PARM *OFF $C 1 Should have no influence

* Mixed update test
C *IN35 DSPLY