From 0e21b813632cda50aefa6c65dc7011ba83d6ae14 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 20 Jun 2024 12:20:28 +0200 Subject: [PATCH 1/5] Add test case --- .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 10 ++++++++++ .../src/test/resources/smeup/MUDRNRAPU00219.rpgle | 5 +++++ 2 files changed, 15 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00219.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt index a26f0d5f3..678a6b17b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt @@ -342,4 +342,14 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { val expected = listOf("ok") assertEquals(expected, "smeup/MUDRNRAPU00218".outputOf(configuration = smeupConfig)) } + + /** + * Reassign value to pointer variable + * @see #LS24003047 + */ + @Test + fun executeMUDRNRAPU00219() { + val expected = listOf("ok") + assertEquals(expected, "smeup/MUDRNRAPU00219".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00219.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00219.rpgle new file mode 100644 index 000000000..d1c20b6f2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00219.rpgle @@ -0,0 +1,5 @@ + D £DBG_Str S 2 + D SRIG_PTR S * Inz(*Null) + C EVAL SRIG_PTR = *NULL + C EVAL £DBG_Str='ok' + C £DBG_Str DSPLY \ No newline at end of file From 3855c1bdb3f60ecd43d68cf1b4a8d6fd1f0193d5 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 20 Jun 2024 12:20:56 +0200 Subject: [PATCH 2/5] Add support for *NULL --- .../main/kotlin/com/smeup/rpgparser/interpreter/Evaluator.kt | 1 + .../com/smeup/rpgparser/interpreter/ExpressionEvaluation.kt | 2 ++ .../kotlin/com/smeup/rpgparser/parsing/ast/expressions.kt | 5 +++++ .../smeup/rpgparser/parsing/parsetreetoast/expressions.kt | 1 + 4 files changed, 9 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/Evaluator.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/Evaluator.kt index 7378eed34..06b584cf4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/Evaluator.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/Evaluator.kt @@ -95,5 +95,6 @@ interface Evaluator { fun eval(expression: ParmsExpr): Value fun eval(expression: OpenExpr): Value fun eval(expression: SizeExpr): Value + fun eval(expression: NullValExpr): Value fun eval(expression: MockExpression): Value } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ExpressionEvaluation.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ExpressionEvaluation.kt index 583ad4117..67ce080ac 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ExpressionEvaluation.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ExpressionEvaluation.kt @@ -823,6 +823,8 @@ class ExpressionEvaluation( } } + override fun eval(expression: NullValExpr): Value = proxyLogging(expression) { NullValue } + override fun eval(expression: MockExpression): Value { MainExecutionContext.getConfiguration().jarikoCallback.onMockExpression(expression) return NullValue diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/expressions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/expressions.kt index 44fe8054b..19fa5578e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/expressions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/expressions.kt @@ -148,6 +148,11 @@ data class JulFormatExpr(override val position: Position? = null) : FigurativeCo override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } +@Serializable +data class NullValExpr(override val position: Position? = null) : FigurativeConstantRef(position) { + override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) +} + // / // / Comparisons // / diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/expressions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/expressions.kt index 1394a734e..0047aa001 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/expressions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/expressions.kt @@ -158,6 +158,7 @@ internal fun RpgParser.IdentifierContext.toAst(conf: ToAstConfiguration = ToAstC "*OFF" -> OffRefExpr(toPosition(conf.considerPosition)) "*ISO" -> IsoFormatExpr(toPosition(conf.considerPosition)) "*JUL" -> JulFormatExpr(toPosition(conf.considerPosition)) + "*NULL" -> NullValExpr(toPosition(conf.considerPosition)) else -> variableExpression(conf) } } From ce0955fdc28c6ae5057a9a9f9d50997f53a5307b Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 20 Jun 2024 12:21:08 +0200 Subject: [PATCH 3/5] Add pointer type --- .../smeup/rpgparser/interpreter/typesystem.kt | 17 ++++++++++++----- .../parsing/parsetreetoast/data_definitions.kt | 6 +++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/typesystem.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/typesystem.kt index b546257ea..86beee412 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/typesystem.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/typesystem.kt @@ -218,17 +218,24 @@ data class NumberType(val entireDigits: Int, val decimalDigits: Int, val rpgType constructor(entireDigits: Int, decimalDigits: Int, rpgType: RpgType) : this(entireDigits, decimalDigits, rpgType.rpgType) init { - if (rpgType == RpgType.INTEGER.rpgType || rpgType == RpgType.UNSIGNED.rpgType) { - require(entireDigits <= 20) { "Integer or Unsigned integer can have only length up to 20. Value specified: $this" } - require(decimalDigits == 0) + if (rpgType == RpgType.INTEGER.rpgType || rpgType == RpgType.UNSIGNED.rpgType || rpgType == RpgType.POINTER.rpgType) { + require(entireDigits <= MAX_INTEGER_DIGITS) { + "Integer or Unsigned integer can have only length up to 20. Value specified: $this" + } + require(decimalDigits == INTEGER_DECIMAL_DIGITS) } } + companion object { + const val MAX_INTEGER_DIGITS = 20 + const val INTEGER_DECIMAL_DIGITS = 0 + } + override val size: Int get() { return when (rpgType) { RpgType.PACKED.rpgType -> ceil((numberOfDigits + 1).toDouble() / 2.toFloat()).toInt() - RpgType.INTEGER.rpgType, RpgType.UNSIGNED.rpgType -> { + RpgType.INTEGER.rpgType, RpgType.UNSIGNED.rpgType, RpgType.POINTER.rpgType -> { when (entireDigits) { in 1..3 -> 1 in 4..5 -> 2 @@ -249,7 +256,7 @@ data class NumberType(val entireDigits: Int, val decimalDigits: Int, val rpgType } val integer: Boolean - get() = decimalDigits == 0 + get() = decimalDigits == INTEGER_DECIMAL_DIGITS val decimal: Boolean get() = !integer val numberOfDigits: Int diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt index cc04e1fec..a1e86eca1 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt @@ -37,7 +37,8 @@ enum class RpgType(val rpgType: String) { INTEGER("I"), UNSIGNED("U"), BINARY("B"), - UNLIMITED_STRING("0") + UNLIMITED_STRING("0"), + POINTER("*") } /** @@ -446,6 +447,9 @@ internal fun RpgParser.DspecContext.toAst( RpgType.UNLIMITED_STRING.rpgType -> { UnlimitedStringType } + RpgType.POINTER.rpgType -> { + NumberType(NumberType.MAX_INTEGER_DIGITS, NumberType.INTEGER_DECIMAL_DIGITS, RpgType.POINTER.rpgType) + } else -> todo("Unknown type: <${this.DATA_TYPE().text}>", conf) } From f8d5a82e1fe641a3ab96a0be14c94651001557c8 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 20 Jun 2024 12:21:24 +0200 Subject: [PATCH 4/5] Add NullValExpr to serialization.kt --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/serialization.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/serialization.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/serialization.kt index 58c83d86d..5e8b93188 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/serialization.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/serialization.kt @@ -165,6 +165,7 @@ private val modules = SerializersModule { subclass(MinusExpr::class) subclass(MultExpr::class) subclass(NotExpr::class) + subclass(NullValExpr::class) subclass(NumberOfElementsExpr::class) subclass(OnRefExpr::class) subclass(OffRefExpr::class) From f230f9bc77b79a549b9b0465bcbbeeb4b9e0953d Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 25 Jun 2024 12:31:37 +0200 Subject: [PATCH 5/5] Move conflicting test case --- .../com/smeup/rpgparser/smeup/MULANGT50FileAccess1Test.kt | 4 ++-- .../src/test/resources/smeup/MUDRNRAPU00220.rpgle | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1Test.kt index 359e99dee..08674c2a0 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1Test.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1Test.kt @@ -40,8 +40,8 @@ open class MULANGT50FileAccess1Test : MULANGTTest() { * @see #LS24002987 */ @Test - fun executeMUDRNRAPU00219() { + fun executeMUDRNRAPU00220() { val expected = listOf("ok") - assertEquals(expected, "smeup/MUDRNRAPU00219".outputOf(configuration = smeupConfig)) + assertEquals(expected, "smeup/MUDRNRAPU00220".outputOf(configuration = smeupConfig)) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00220.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00220.rpgle index e69de29bb..a78caf1ce 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00220.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00220.rpgle @@ -0,0 +1,7 @@ + D £DBG_Str S 2 + D STR132 S 132 + FPRT132 O F 132 PRINTER OFLIND(*INOG) USROPN + OPRT132 E RIGA 1 + O STR132 + C EVAL £DBG_Str='ok' + C £DBG_Str DSPLY \ No newline at end of file