From 084f8cd6195372368799acf20a11ba6eb35a4472 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 8 Jul 2024 16:18:19 +0200 Subject: [PATCH 1/8] Add test case --- .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 10 ++++++++++ .../src/test/resources/smeup/MUDRNRAPU00226.rpgle | 14 ++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00226.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 6e662ed1d..4a0adce45 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 @@ -392,4 +392,14 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { val expected = listOf("ok") assertEquals(expected, "smeup/MUDRNRAPU00224".outputOf(configuration = smeupConfig)) } + + /** + * Comptime DS with EXTNAME resolution and data structures INZ(*HIVAL) + * @see #LS24003257 + */ + @Test + fun executeMUDRNRAPU00226() { + val expected = listOf("ok") + assertEquals(expected, "smeup/MUDRNRAPU00226".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00226.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00226.rpgle new file mode 100644 index 000000000..8ff46e925 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00226.rpgle @@ -0,0 +1,14 @@ + D £DBG_Str S 2 + D B£SLOT E DS EXTNAME(B£SLOT0F) INZ + + D CSDS DS + D CSNR 5S 0 + + D CSLOTS S LIKE(B£SLOT) DIM(200) INZ(*HIVAL) + D CSLOTADS DS + + D CSLOTA LIKE(CSDS) INZ(*HIVAL) + D DIM(%ELEM(CSLOTS)) ASCEND + + C EVAL £DBG_Str='ok' + C £DBG_Str DSPLY \ No newline at end of file From 4a3bb7aaa8abac708a082919db561079c69ca139 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 8 Jul 2024 16:18:34 +0200 Subject: [PATCH 2/8] Add coercing rules --- .../smeup/rpgparser/interpreter/coercing.kt | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt index 1f4c89147..ce92d7250 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt @@ -275,31 +275,29 @@ fun coerce(value: Value, type: Type): Value { } fun Type.lowValue(): Value { - when (this) { - is NumberType -> { - return computeLowValue(this) - } - is StringType -> { - return computeLowValue(this) - } - is ArrayType -> { - return createArrayValue(this.element, this.nElements) { coerce(LowValValue, this.element) } + return when (this) { + is NumberType -> computeLowValue(this) + is StringType -> computeLowValue(this) + is ArrayType -> createArrayValue(this.element, this.nElements) { coerce(LowValValue, this.element) } + is DataStructureType -> { + val fields = this.fields.associateWith { field -> field.type.lowValue() } + DataStructValue.fromFields(fields) } + is RecordFormatType -> BlanksValue else -> TODO("Converting LowValValue to $this") } } fun Type.hiValue(): Value { - when (this) { - is NumberType -> { - return computeHiValue(this) - } - is StringType -> { - return computeHiValue(this) - } - is ArrayType -> { - return createArrayValue(this.element, this.nElements) { coerce(HiValValue, this.element) } + return when (this) { + is NumberType -> computeHiValue(this) + is StringType -> computeHiValue(this) + is ArrayType -> createArrayValue(this.element, this.nElements) { coerce(HiValValue, this.element) } + is DataStructureType -> { + val fields = this.fields.associateWith { field -> field.type.hiValue() } + DataStructValue.fromFields(fields) } + is RecordFormatType -> BlanksValue else -> TODO("Converting HiValValue to $this") } } From 07953f8f5c3a92fe87963e3531c6514f42e1877c Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 8 Jul 2024 16:19:15 +0200 Subject: [PATCH 3/8] Add DataStructValue construction by fields --- .../com/smeup/rpgparser/interpreter/values.kt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt index 15c5fa9a1..13558df7f 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt @@ -1042,6 +1042,14 @@ data class DataStructValue(var value: String, private val optionalExternalLen: I } return newInstance } + + fun fromFields(fields: Map): DataStructValue { + val size = fields.entries.fold(0) { acc, entry -> acc + entry.key.type.size } + val newInstance = blank(size) + val fieldDefinitions = fields.map { it.key }.toFieldDefinitions() + fields.onEachIndexed { index, entry -> newInstance.set(fieldDefinitions[index], entry.value) } + return newInstance + } } override fun toString(): String { @@ -1196,4 +1204,20 @@ data class OccurableDataStructValue(val occurs: Int) : Value { this.values.putAll(values.mapValues { it.value.copy() }) } } +} + +fun List.toFieldDefinitions(): List { + var start = 0 + val definitions = this.map { + val newOffset = start + it.type.size + val fieldDef = FieldDefinition( + name = it.name, + type = it.type, + calculatedStartOffset = start, + calculatedEndOffset = start + newOffset + ) + start = newOffset + fieldDef + } + return definitions } \ No newline at end of file From 139390a5ddee1d866764270de80d59eae55eee19 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 8 Jul 2024 16:19:38 +0200 Subject: [PATCH 4/8] Add missing types in toDataStructureValue --- .../com/smeup/rpgparser/interpreter/data_definitions.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/data_definitions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/data_definitions.kt index b70b73f47..e0feb4727 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/data_definitions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/data_definitions.kt @@ -321,6 +321,13 @@ fun Type.toDataStructureValue(value: Value): StringValue { return StringValue("1") return StringValue("0") } + is DataStructureType -> { + return when (value) { + is DataStructValue -> value.asString() + else -> TODO("Not implemented") + } + } + is RecordFormatType -> return StringValue.blank(this.size) else -> TODO("Conversion to data struct value not implemented for $this") } } From 2a1fd016cbad0f10b0c5819d91257c9dd59e48b8 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 9 Jul 2024 12:15:52 +0200 Subject: [PATCH 5/8] Use internal visibility for new functions --- .../src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt index 13558df7f..47f294b6f 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt @@ -1043,7 +1043,7 @@ data class DataStructValue(var value: String, private val optionalExternalLen: I return newInstance } - fun fromFields(fields: Map): DataStructValue { + internal fun fromFields(fields: Map): DataStructValue { val size = fields.entries.fold(0) { acc, entry -> acc + entry.key.type.size } val newInstance = blank(size) val fieldDefinitions = fields.map { it.key }.toFieldDefinitions() @@ -1206,7 +1206,7 @@ data class OccurableDataStructValue(val occurs: Int) : Value { } } -fun List.toFieldDefinitions(): List { +internal fun List.toFieldDefinitions(): List { var start = 0 val definitions = this.map { val newOffset = start + it.type.size From 02c0387a0fe34ac92d120c903c4faa50640ba348 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 9 Jul 2024 16:17:06 +0200 Subject: [PATCH 6/8] Add test case asserting proper values --- .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 10 ++++++++++ .../src/test/resources/smeup/MUDRNRAPU00227.rpgle | 9 +++++++++ 2 files changed, 19 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00227.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 f7f097982..3fb0cd57d 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 @@ -412,4 +412,14 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { val expected = listOf("ok") assertEquals(expected, "smeup/MUDRNRAPU00226".outputOf(configuration = smeupConfig)) } + + /** + * Comptime DS with EXTNAME resolution and data structures INZ(*HIVAL) + * @see #LS24003257 + */ + @Test + fun executeMUDRNRAPU00227() { + val expected = listOf("9991\uFFFF\uFFFF99999") + assertEquals(expected, "smeup/MUDRNRAPU00227".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00227.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00227.rpgle new file mode 100644 index 000000000..951ded1ce --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MUDRNRAPU00227.rpgle @@ -0,0 +1,9 @@ + D £DBG_Str S 2 + D CSDS DS + D NUM 3S 0 + D BOOL N 0 + D STR LIKE(£DBG_Str) + D NUM2 5S 0 + + D OUT S LIKE(CSDS) INZ(*HIVAL) + C OUT DSPLY \ No newline at end of file From b424847362b3a55ea108b3dc7a2be1ac74c381fc Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 9 Jul 2024 16:17:36 +0200 Subject: [PATCH 7/8] Add support for boolean to hiValue and lowValue coercion --- .../src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt index ce92d7250..3300bb231 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/coercing.kt @@ -283,6 +283,7 @@ fun Type.lowValue(): Value { val fields = this.fields.associateWith { field -> field.type.lowValue() } DataStructValue.fromFields(fields) } + is BooleanType -> BooleanValue.FALSE is RecordFormatType -> BlanksValue else -> TODO("Converting LowValValue to $this") } @@ -297,6 +298,7 @@ fun Type.hiValue(): Value { val fields = this.fields.associateWith { field -> field.type.hiValue() } DataStructValue.fromFields(fields) } + is BooleanType -> BooleanValue.TRUE is RecordFormatType -> BlanksValue else -> TODO("Converting HiValValue to $this") } From 6547185f8b5395b8ec42e713de020e7000667f8a Mon Sep 17 00:00:00 2001 From: Domenico Date: Wed, 10 Jul 2024 09:37:07 +0200 Subject: [PATCH 8/8] Update errata test description --- .../com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3fb0cd57d..e208727d4 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 @@ -414,7 +414,7 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { } /** - * Comptime DS with EXTNAME resolution and data structures INZ(*HIVAL) + * Data structures INZ(*HIVAL) values test * @see #LS24003257 */ @Test