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..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 @@ -275,31 +275,31 @@ 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 BooleanType -> BooleanValue.FALSE + 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 BooleanType -> BooleanValue.TRUE + is RecordFormatType -> BlanksValue else -> TODO("Converting HiValValue to $this") } } 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") } } 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..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 @@ -1042,6 +1042,14 @@ data class DataStructValue(var value: String, private val optionalExternalLen: I } return newInstance } + + 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() + 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() }) } } +} + +internal 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 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 cf0d48e7e..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 @@ -402,4 +402,24 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { val expected = listOf("ok") assertEquals(expected, "smeup/MUDRNRAPU00225".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)) + } + + /** + * Data structures INZ(*HIVAL) values test + * @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/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 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