From 4ba36b16e307f50f26f77965f4a9f0318bd86b4d Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Mon, 15 Jan 2024 15:24:15 +0000 Subject: [PATCH 001/423] add test executeT02_A40_P5 --- .../evaluation/SmeupInterpreterTest.kt | 7 +++++ .../src/test/resources/smeup/T02_A40_P5.rpgle | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P5.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 5b0e76c22..13d12d23d 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -71,6 +71,13 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T02_A40".outputOf()) } + @Test + fun executeT02_A40_P5() { + val expected = listOf("333,zz") + //assertASTCanBeProduced("smeup/T02_A40_P5", printTree = true) + assertEquals(expected, "smeup/T02_A40_P5".outputOf()) + } + @Test fun executeT04_A20() { val expected = listOf("CALL_1(MULANGT04 , 1, MULANGTB10: MULANGT04 chiamata 1 ) CALL_2(MULANGT04 , 3, MULANGTB10: MULANGT04 chiamata 1 )") diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P5.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P5.rpgle new file mode 100644 index 000000000..107630733 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P5.rpgle @@ -0,0 +1,27 @@ + D £DBG_Str S 50 + D £DBG_Pas S 3 + * + D A40_DS1 DS 30 + D DS1_FL1 2 + D DS1_FL4 3 0 + * + D A40_DS5 DS + D DS5_FL1 LIKE(DS1_FL4) + D DS5_FL2 LIKE(DS1_FL1) + * + C EXSR T02_A40_P05 + * + C SETON LR + * + * DS with LIKE in the fields + C T02_A40_P05 BEGSR + * + C EVAL £DBG_Pas='P05' + C EVAL DS5_FL1 = 333 + C EVAL DS5_FL2 = 'zz' + C EVAL £DBG_Str=%EDITC(DS5_FL1:'X') + C +','+%TRIMR(DS5_FL2) + C £DBG_Str DSPLY + * + C ENDSR + * From 6c2ae3d68b456cc92c3f0b7fb9a125de31cfa02f Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Wed, 17 Jan 2024 14:24:09 +0100 Subject: [PATCH 002/423] First implementation for omitted parameters on program call --- .../smeup/rpgparser/interpreter/program.kt | 132 +++++++++++------- .../smeup/rpgparser/parsing/ast/statements.kt | 4 +- .../evaluation/SmeupInterpreterTest.kt | 15 ++ .../src/test/resources/smeup/MULANGTC10.rpgle | 17 +++ .../test/resources/smeup/T10_A60_P04.rpgle | 13 ++ 5 files changed, 132 insertions(+), 49 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC10.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt index a637dc27c..88aca1dd4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt @@ -79,40 +79,68 @@ class RpgProgram(val cu: CompilationUnit, val name: String = "): List { + /* require(params.keys.toSet() == params().asSequence().map { it.name }.toSet()) { "Expected params: ${params().asSequence().map { it.name }.joinToString(", ")}" } - this.systemInterface = systemInterface - logHandlers.log(ProgramInterpretationLogStart(name, params)) - val changedInitialValues: List - val elapsed = measureTimeMillis { - interpreter.setInterpretationContext(object : InterpretationContext { - private var iDataWrapUpChoice: DataWrapUpChoice? = null - override val currentProgramName: String - get() = name - override fun shouldReinitialize() = false - override var dataWrapUpChoice: DataWrapUpChoice? - get() = iDataWrapUpChoice - set(value) { - iDataWrapUpChoice = value - } - }) - for (pv in params) { - val expectedType = params().find { it.name == pv.key }!!.type - val coercedValue = coerce(pv.value, expectedType) - require(coercedValue.assignableTo(expectedType)) { - "param ${pv.key} was expected to have type $expectedType. It has value: $coercedValue" + val expectedKeys = params().asSequence().map { it.name }.toSet() + require(params().asSequence().map { it.name }.toSet().all {it in expectedKeys}) { + "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 if (expectedKeys.size > params.size) { + require(params().asSequence().map { it.name }.toSet().all { it in expectedKeys }) { + "Expected params: ${params().asSequence().map { it.name }.joinToString(", ")}" + + params().forEach { + if (!params.contains(it.name)) { + //params.put(it.name, ); + } } } - if (!initialized) { - initialized = true - val caller = if (MainExecutionContext.getProgramStack().isNotEmpty()) { - MainExecutionContext.getProgramStack().peek() - } else { - null + } + + + this.systemInterface = systemInterface + logHandlers.log(ProgramInterpretationLogStart(name, params)) + val changedInitialValues: List + val elapsed = measureTimeMillis { + interpreter.setInterpretationContext(object : InterpretationContext { + private var iDataWrapUpChoice: DataWrapUpChoice? = null + override val currentProgramName: String + get() = name + + override fun shouldReinitialize() = false + override var dataWrapUpChoice: DataWrapUpChoice? + get() = iDataWrapUpChoice + set(value) { + iDataWrapUpChoice = value + } + }) + + for (pv in params) { + val expectedType = params().find { it.name == pv.key }!!.type + val coercedValue = coerce(pv.value, expectedType) + require(coercedValue.assignableTo(expectedType)) { + "param ${pv.key} was expected to have type $expectedType. It has value: $coercedValue" + } } - val activationGroupType = cu.activationGroupType() ?: when (caller) { + if (!initialized) { + initialized = true + val caller = if (MainExecutionContext.getProgramStack().isNotEmpty()) { + MainExecutionContext.getProgramStack().peek() + } else { + null + } + val activationGroupType = cu.activationGroupType() ?: when (caller) { // for main program, which does not have a caller, activation group is fixed by config null -> NamedActivationGroup(MainExecutionContext.getConfiguration().defaultActivationGroupName) @@ -120,34 +148,42 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " - interpreter.assign(this.params[index].param.referred!!, value) + if (this.params.size > index) { + interpreter.assign(this.params[index].param.referred!!, value) + } } } } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index eabbef1d6..3ac8e79af 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -178,6 +178,15 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T40_A10_P07".outputOf()) } + @Test + fun executeT20_A10_P05() { + val expected = listOf( + "1", + "0" + ) + assertEquals(expected, "smeup/T20_A10_P05".outputOf()) + } + @Test fun executeT40_A10_P03D() { val expected = listOf( @@ -185,4 +194,10 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T40_A10_P03D".outputOf()) } + + @Test + fun executeT10_A60_P04() { + val expected = emptyList() + assertEquals(expected, "smeup/T10_A60_P04".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC10.rpgle new file mode 100644 index 000000000..b71335e7b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC10.rpgle @@ -0,0 +1,17 @@ + D B10_P1 S 10 + D B10_P2 S 2 0 + D B10_P3 S 50 + * + D B10_A50 S 50 + *--------------------------------------------------------------------- + C *ENTRY PLIST + C PARM B10_P1 + C PARM B10_P2 + C PARM B10_P3 + * + C IF B10_P2=1 + C EVAL B10_A50 ='MULANGTB10: '+%TRIMR(B10_P1) + C +' chiamata '+%CHAR(B10_P2) + C ENDIF + * + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle new file mode 100644 index 000000000..a287da53c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle @@ -0,0 +1,13 @@ + ************************************************************************** + 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 CALL 'MULANGTC10' + C PARM A60_P1 + C PARM 1 A60_P2 + C EVAL £DBG_Str='CALL('+A60_P1+', ' + C +%CHAR(A60_P2) + C +', '+A60_P3+') ' \ No newline at end of file From c37844f8d7c9246676184c8c883b9251d226f287 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 17 Jan 2024 15:36:29 +0000 Subject: [PATCH 003/423] add SPLAT_ALL_INDICATORS for *IN implementation --- .../src/main/antlr/RpgLexer.g4 | 2 ++ .../src/main/antlr/RpgParser.g4 | 1 + .../interpreter/ExpressionEvaluation.kt | 17 +++++++++++++++-- .../smeup/rpgparser/parsing/ast/indicators.kt | 4 +--- .../rpgparser/parsing/parsetreetoast/misc.kt | 5 +++++ .../rpgparser/evaluation/InterpreterTest.kt | 7 +++++++ .../src/test/resources/MOVEAIN.rpgle | 13 +++++++++++++ 7 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/MOVEAIN.rpgle diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 index 764f54437..cacccaf10 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 @@ -316,6 +316,7 @@ SPLAT_FILE: '*'[fF][iI][lL][eE]; SPLAT_GETIN: '*'[gG][eE][tT][iI][nN]; SPLAT_HIVAL: '*'[hH][iI][vV][aA][lL]; SPLAT_INIT: '*'[iI][nN][iI][tT]; +SPLAT_ALL_INDICATORS: '*' [iI] [nN] [ ] [ ]; SPLAT_INDICATOR : ( '*' [iI] [nN] [0-9] [0-9] | '*' [iI] [nN] [a-zA-Z] [a-zA-Z] | '*' [iI] [nN] '(' [0-9] [0-9] ')' ); @@ -1032,6 +1033,7 @@ CS_Factor2_SPLAT_GETIN : SPLAT_GETIN {35+6<= getCharPositionInLine() && getCharP CS_Factor2_SPLAT_HIVAL : SPLAT_HIVAL {35+6<= getCharPositionInLine() && getCharPositionInLine()<=48}? -> type(SPLAT_HIVAL); CS_Factor2_SPLAT_INIT : SPLAT_INIT {35+5<= getCharPositionInLine() && getCharPositionInLine()<=48}? -> type(SPLAT_INIT); CS_Factor2_SPLAT_INDICATOR : SPLAT_INDICATOR {35+4<= getCharPositionInLine() && getCharPositionInLine()<=48}? -> type(SPLAT_INDICATOR); +CS_Factor2_SPLAT_ALL_INDICATORS : SPLAT_ALL_INDICATORS {35+4<= getCharPositionInLine() && getCharPositionInLine()<=48}? -> type(SPLAT_ALL_INDICATORS); CS_Factor2_SPLAT_INZSR : SPLAT_INZSR {35+6<= getCharPositionInLine() && getCharPositionInLine()<=48}? -> type(SPLAT_INZSR); CS_Factor2_SPLAT_IN : SPLAT_IN {35+3<= getCharPositionInLine() && getCharPositionInLine()<=48}? -> type(SPLAT_IN); CS_Factor2_SPLAT_JOBRUN : SPLAT_JOBRUN {35+7<= getCharPositionInLine() && getCharPositionInLine()<=48}? -> type(SPLAT_JOBRUN); diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index 8d7c243e7..601d94e5a 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -2581,6 +2581,7 @@ SPLAT_ALL | SPLAT_HIVAL | SPLAT_INIT | SPLAT_INDICATOR + | SPLAT_ALL_INDICATORS | SPLAT_INZSR | SPLAT_IN | SPLAT_JOBRUN 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 57d876596..7d9f012aa 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 @@ -29,6 +29,7 @@ import java.math.MathContext import java.math.RoundingMode import java.time.temporal.ChronoUnit import java.time.ZoneId +import java.util.HashMap import kotlin.math.abs import kotlin.math.sqrt @@ -676,8 +677,20 @@ class ExpressionEvaluation( override fun eval(expression: AssignmentExpr) = throw RuntimeException("AssignmentExpr should be handled by the interpreter: $expression") - override fun eval(expression: GlobalIndicatorExpr) = - throw RuntimeException("PredefinedGlobalIndicatorExpr should be handled by the interpreter: $expression") + override fun eval(expression: GlobalIndicatorExpr): Value { + + for (i in 1..99) + if (interpreterStatus.indicators[i] == null) + interpreterStatus.indicators[i] = BooleanValue(false) + val ret = interpreterStatus.indicators.map { it.value } + return StringValue( + ret.map { + if (it.value) { + 1 } else { + 0 + } + }.joinToString { it.toString() }) + } override fun eval(expression: ParmsExpr): Value { return IntValue(interpreterStatus.params.toLong()) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt index 652239edf..a95dc634d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt @@ -22,9 +22,7 @@ data class IndicatorExpr(val index: IndicatorKey, override val position: Positio @Serializable data class GlobalIndicatorExpr(override val position: Position? = null) : AssignableExpression(position) { - override fun size(): Int { - TODO("not implemented") // To change body of created functions use File | Settings | File Templates. - } + override fun size(): Int = 99 override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index dcd4189c7..a489f75ed 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -667,6 +667,11 @@ internal fun SymbolicConstantsContext.toAst(conf: ToAstConfiguration = ToAstConf position = position ) } + this.SPLAT_ALL_INDICATORS() != null -> { + GlobalIndicatorExpr( + position = position + ) + } this.SPLAT_ALL() != null -> { val content: LiteralContext = this.parent.getChild(1) as LiteralContext AllExpr(content.toAst(conf), position) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index f70d2ec78..73d41a937 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2202,4 +2202,11 @@ Test 6 val expected = listOf("A1_OK", "A2_OK", "A3_OK", "N1_OK", "N2_OK", "N3_OK", "DS_OK", "DSA1_OK", "DSA2_OK") assertEquals(expected, "RESET01".outputOf()) } + + @Test + fun executeMOVEAIN() { + val expected = listOf("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000") + assertASTCanBeProduced("MOVEAIN", printTree = true) + assertEquals(expected, "MOVEAIN".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/MOVEAIN.rpgle b/rpgJavaInterpreter-core/src/test/resources/MOVEAIN.rpgle new file mode 100644 index 000000000..2254cbfe2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/MOVEAIN.rpgle @@ -0,0 +1,13 @@ + D* £DBG_Ind S 99 + D £DBG_Sch S 1 DIM(99) + * + C MOVEL *ON *IN44 + C SETON 88 + C* MOVEA(P) *IN £DBG_Ind + C MOVEA(P) *IN £DBG_Sch + * Expected: + * '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000' + * + C* £DBG_Ind DSPLY + C £DBG_Sch DSPLY + C SETON LR \ No newline at end of file From 7c7c7806d14f84a5823803396f931546d2c02b5b Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:53:18 +0000 Subject: [PATCH 004/423] remove GlobalIndicatorExpr separator --- .../interpreter/ExpressionEvaluation.kt | 3 +-- .../rpgparser/evaluation/InterpreterTest.kt | 5 +++-- .../src/test/resources/MOVEAIN.rpgle | 20 ++++++++++++------- 3 files changed, 17 insertions(+), 11 deletions(-) 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 7d9f012aa..ba4c58f05 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 @@ -29,7 +29,6 @@ import java.math.MathContext import java.math.RoundingMode import java.time.temporal.ChronoUnit import java.time.ZoneId -import java.util.HashMap import kotlin.math.abs import kotlin.math.sqrt @@ -689,7 +688,7 @@ class ExpressionEvaluation( 1 } else { 0 } - }.joinToString { it.toString() }) + }.joinToString(separator = "") { it.toString() }) } override fun eval(expression: ParmsExpr): Value { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 73d41a937..d1a6143df 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2205,8 +2205,9 @@ Test 6 @Test fun executeMOVEAIN() { - val expected = listOf("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000") - assertASTCanBeProduced("MOVEAIN", printTree = true) + val expected = listOf( + "111000000000000000000000000000000000000000010000000000000000000000000000000000000000000100000000000", + "001000000000000000000000000000000000000000010000000000000000000000000000000000000000000100000000000") assertEquals(expected, "MOVEAIN".outputOf()) } } diff --git a/rpgJavaInterpreter-core/src/test/resources/MOVEAIN.rpgle b/rpgJavaInterpreter-core/src/test/resources/MOVEAIN.rpgle index 2254cbfe2..12fcd9bf6 100644 --- a/rpgJavaInterpreter-core/src/test/resources/MOVEAIN.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/MOVEAIN.rpgle @@ -1,13 +1,19 @@ - D* £DBG_Ind S 99 - D £DBG_Sch S 1 DIM(99) + D £DBG_Ind S 99 * C MOVEL *ON *IN44 + C MOVE *ON *IN03 C SETON 88 - C* MOVEA(P) *IN £DBG_Ind - C MOVEA(P) *IN £DBG_Sch + C SETON 0102 + C MOVEA(P) *IN £DBG_Ind * Expected: - * '000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000' + * '111000000000000000000000000000000000000000010000000000000000000000000000000000000000000100000000000' + C £DBG_Ind DSPLY + * + C SETOFF 0102 + C* MOVEL '1' *IN03 + C MOVEA(P) *IN £DBG_Ind + * Expected: + * '000000000000000000000000000000000000000000010000000000000000000000000000000000000000000100000000000' + C £DBG_Ind DSPLY * - C* £DBG_Ind DSPLY - C £DBG_Sch DSPLY C SETON LR \ No newline at end of file From 2b7efbde4953178e25955ae93907bcfecb4ecdb7 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Thu, 18 Jan 2024 10:53:11 +0000 Subject: [PATCH 005/423] add executeT15_A50 --- .../evaluation/SmeupInterpreterTest.kt | 66 +++++ .../src/test/resources/smeup/T15_A50.rpgle | 260 ++++++++++++++++++ 2 files changed, 326 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T15_A50.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 474bda400..7ac9180b7 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -193,4 +193,70 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T40_A10_P03D".outputOf()) } + + @Test + fun executeT15_A50() { + val expected = listOf( + // P1 + "A( 123.456000 / 123.456000 / 123.456000" + +" / 123.456000 / 123.456000 / 123.456" + +"000 / 123.456000 / 123.456000 / 12" + +"3.456000 / 123.456000 / 123.456000 / " + +"123.456000 / 123.456000 / 123.456000 / " + +" 123.456000 / 123.456000 / 000000123456000 / " + +" 123456000) B( .000123 / .000123 / " + +" .000123 / .000123 / .000123 / " + +" .000123 / .000123 / .000123 " + +" / .000123 / .000123 / .000" + +"123 / .000123 / .000123 / " + +" .000123 / .000123 / .000123 / 000000000" + +"000123 / 123) C( 12,345.000000 / 12,345" + +".000000 / 12345.000000 / 12345.000000 / 12,345." + +"000000 / 12,345.000000 / 12345.000000 / 1" + +"2345.000000 / 12,345.000000 / 12,345.000000 / " + +" 12345.000000 / 12345.000000 / 12,345.000000 " + +"/ 12,345.000000 / 12345.000000 / 12345.00000" + +"0 / 000012345000000 / 12345000000)" + , // P2 + "1( .00 123,456 123,456 1,234.56 1,234.56) 2( " + +"123,456 123,456 1,234.56 1,234.56) 3( .00 123456 123456 " + +"1234.56 1234.56) 4( 123456 123456 1234.56 1234.56)" + , // P3 + "A( .00 123,456 123,456CR 1,234.56 1,234.56CR) B(" + +" 123,456 123,456CR 1,234.56 1,234.56CR) C( " + +" .00 123456 123456CR 1234.56 1234.56CR) D( 1" + +"23456 123456CR 1234.56 1234.56CR)" + , // P4 + "K( 123,456 123,456- 1,234.56 1,234.56-) J( " + +".00 123,456 123,456- 1,234.56 1,234.56-) L( .00 123" + +"456 123456- 1234.56 1234.56-) M( 123456 123456- 1" + +"234.56 1234.56-)" + , // P5 + "N( .00 123,456 -123,456 1,234.56 -1,234.56) O( " + +" 123,456 -123,456 1,234.56 -1,234.56) P( .00 12" + +"3456 -123456 1234.56 -1234.56) Q( 123456 -123456 " + +"1234.56 -1234.56)" + , // P6 + "X(0000000123456012345O0123456012345O) Y( 0/00/00 12/34/56 12" + +"/34/56 12/34/56 12/34/56) Z( 123456 123456 123456 1234" + +"56)" + , // P8 + " 123.456000 / 123.456000 / 123.456000 /" + +" 123.456000 / 123.456000 / 123.45600" + +"0 / 123.456000 / 123.456000 / 123." + +"456000 / 123.456000 / 123.456000 / 12" + +"3.456000 / 123.456000 / 123.456000 / " + +" 123.456000 / 123.456000 / 000000123456000 / " + +"123456000" + , // P9 + " 123.456000 / 123.456000 / 123.456000 /" + +" 123.456000 / 123.456000 / 123.45600" + +"0 / 123.456000 / 123.456000 / 123." + +"456000 / 123.456000 / 123.456000 / 12" + +"3.456000 / 123.456000 / 123.456000 / " + +" 123.456000 / 123.456000 / 000000123456000 / " + +"123456000" + ) + assertEquals(expected, "smeup/T15_A50".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A50.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A50.rpgle new file mode 100644 index 000000000..e9eca98f4 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A50.rpgle @@ -0,0 +1,260 @@ + D £DBG_Pas S 3 + D £DBG_Str S 2000 + * + D A50_N156 S 15P 6 + D A50_A1 S LIKE(£DBG_Str) + D A50_N70 S 7P 0 Inz(0123456) + D A50_N60 S 7S 0 Inz(-0123456) + D A50_N72 S 7P 2 Inz(01234.56) + D A50_N62 S 7S 2 Inz(-01234.56) + D NNN S 6 0 INZ(100000) + * + C EVAL £DBG_Str='' + C EXSR SEZ_A50 + * + C SETON LR + ************************************************************** + C SEZ_A50 BEGSR + OA* A£.BIFN(EDITC ) + D* %EDITC tutti gli EDITC di una variabile con valori diversi + C EVAL £DBG_Pas='P01' + C EVAL £DBG_Str='' + C EVAL A50_N156=123,456 + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' A(' + C EXSR SEZ_A50_A + C EVAL £DBG_Str=%TRIM(£DBG_Str)+%TRIMR(A50_A1)+') ' + C EVAL A50_N156=0,000123 + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' B(' + C EXSR SEZ_A50_A + C EVAL £DBG_Str=%TRIM(£DBG_Str)+%TRIMR(A50_A1)+') ' + C EVAL A50_N156=12345,00 + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' C(' + C EXSR SEZ_A50_A + C EVAL £DBG_Str=%TRIM(£DBG_Str)+%TRIMR(A50_A1)+') ' + * Expected: + *'A( 123.456000 / 123.456000 / 123.456000' + *' / 123.456000 / 123.456000 / 123.456' + *'000 / 123.456000 / 123.456000 / 12' + *'3.456000 / 123.456000 / 123.456000 / ' + *'123.456000 / 123.456000 / 123.456000 / ' + *' 123.456000 / 123.456000 / 000000123456000 / ' + *' 123456000) B( .000123 / .000123 / ' + *' .000123 / .000123 / .000123 / ' + *' .000123 / .000123 / .000123 ' + *' / .000123 / .000123 / .000' + *'123 / .000123 / .000123 / ' + *' .000123 / .000123 / .000123 / 000000000' + *'000123 / 123) C( 12,345.000000 / 12,345' + *'.000000 / 12345.000000 / 12345.000000 / 12,345.' + *'000000 / 12,345.000000 / 12345.000000 / 1' + *'2345.000000 / 12,345.000000 / 12,345.000000 / ' + *' 12345.000000 / 12345.000000 / 12,345.000000 ' + *'/ 12,345.000000 / 12345.000000 / 12345.00000' + *'0 / 000012345000000 / 12345000000) ' + * + C £DBG_Str DSPLY + OA* A£.BIFN(EDITC ) + D* %EDITC formato codice 1,2,3,4 + C EVAL £DBG_Pas='P02' + C EVAL £DBG_Str= + C '1('+%EDITC(0000.00:'1') + C +%EDITC(A50_N70:'1') + C +%EDITC(A50_N60:'1') + C +%EDITC(A50_N72:'1') + C +%EDITC(A50_N62:'1')+') ' + C +'2('+%EDITC(0000.00:'2') + C +%EDITC(A50_N70:'2') + C +%EDITC(A50_N60:'2') + C +%EDITC(A50_N72:'2') + C +%EDITC(A50_N62:'2')+') ' + C +'3('+%EDITC(0000.00:'3') + C +%EDITC(A50_N70:'3') + C +%EDITC(A50_N60:'3') + C +%EDITC(A50_N72:'3') + C +%EDITC(A50_N62:'3')+') ' + C +'4('+%EDITC(0000.00:'4') + C +%EDITC(A50_N70:'4') + C +%EDITC(A50_N60:'4') + C +%EDITC(A50_N72:'4') + C +%EDITC(A50_N62:'4')+') ' + * Expected: + *'1( .00 123,456 123,456 1,234.56 1,234.56) 2( ' + *'123,456 123,456 1,234.56 1,234.56) 3( .00 123456 123456 ' + *'1234.56 1234.56) 4( 123456 123456 1234.56 1234.56) ' + * + C £DBG_Str DSPLY + OA* A£.BIFN(EDITC ) + D* %EDITC formato codice A,B,C,D + C EVAL £DBG_Pas='P03' + C EVAL £DBG_Str= + C 'A('+%EDITC(0000.00:'A') + C +%EDITC(A50_N70:'A') + C +%EDITC(A50_N60:'A') + C +%EDITC(A50_N72:'A') + C +%EDITC(A50_N62:'A')+') ' + C +'B('+%EDITC(0000.00:'B') + C +%EDITC(A50_N70:'B') + C +%EDITC(A50_N60:'B') + C +%EDITC(A50_N72:'B') + C +%EDITC(A50_N62:'B')+') ' + C +'C('+%EDITC(0000.00:'C') + C +%EDITC(A50_N70:'C') + C +%EDITC(A50_N60:'C') + C +%EDITC(A50_N72:'C') + C +%EDITC(A50_N62:'C')+') ' + C +'D('+%EDITC(0000.00:'D') + C +%EDITC(A50_N70:'D') + C +%EDITC(A50_N60:'D') + C +%EDITC(A50_N72:'D') + C +%EDITC(A50_N62:'D')+') ' + * Expected: + *'A( .00 123,456 123,456CR 1,234.56 1,234.56CR) B(' + *' 123,456 123,456CR 1,234.56 1,234.56CR) C( ' + *' .00 123456 123456CR 1234.56 1234.56CR) D( 1' + *'23456 123456CR 1234.56 1234.56CR) ' + * + C £DBG_Str DSPLY + OA* A£.BIFN(EDITC ) + D* %EDITC formato codice K,J,L,M + C EVAL £DBG_Pas='P04' + C EVAL £DBG_Str= + C 'K('+%EDITC(0000.00:'K') + C +%EDITC(A50_N70:'J') + C +%EDITC(A50_N60:'J') + C +%EDITC(A50_N72:'J') + C +%EDITC(A50_N62:'J')+') ' + C +'J('+%EDITC(0000.00:'J') + C +%EDITC(A50_N70:'J') + C +%EDITC(A50_N60:'J') + C +%EDITC(A50_N72:'J') + C +%EDITC(A50_N62:'J')+') ' + C +'L('+%EDITC(0000.00:'L') + C +%EDITC(A50_N70:'L') + C +%EDITC(A50_N60:'L') + C +%EDITC(A50_N72:'L') + C +%EDITC(A50_N62:'L')+') ' + C +'M('+%EDITC(0000.00:'M') + C +%EDITC(A50_N70:'M') + C +%EDITC(A50_N60:'M') + C +%EDITC(A50_N72:'M') + C +%EDITC(A50_N62:'M')+') ' + * Expected: + *'K( 123,456 123,456- 1,234.56 1,234.56-) J( ' + *'.00 123,456 123,456- 1,234.56 1,234.56-) L( .00 123' + *'456 123456- 1234.56 1234.56-) M( 123456 123456- 1' + *'234.56 1234.56-) ' + * + C £DBG_Str DSPLY + OA* A£.BIFN(EDITC ) + D* %EDITC formato codice N,O,P,Q + C EVAL £DBG_Pas='P05' + C EVAL £DBG_Str= + C 'N('+%EDITC(0000.00:'N') + C +%EDITC(A50_N70:'N') + C +%EDITC(A50_N60:'N') + C +%EDITC(A50_N72:'N') + C +%EDITC(A50_N62:'N')+') ' + C +'O('+%EDITC(0000.00:'O') + C +%EDITC(A50_N70:'O') + C +%EDITC(A50_N60:'O') + C +%EDITC(A50_N72:'O') + C +%EDITC(A50_N62:'O')+') ' + C +'P('+%EDITC(0000.00:'P') + C +%EDITC(A50_N70:'P') + C +%EDITC(A50_N60:'P') + C +%EDITC(A50_N72:'P') + C +%EDITC(A50_N62:'P')+') ' + C +'Q('+%EDITC(0000.00:'Q') + C +%EDITC(A50_N70:'Q') + C +%EDITC(A50_N60:'Q') + C +%EDITC(A50_N72:'Q') + C +%EDITC(A50_N62:'Q')+') ' + * Expected: + *'N( .00 123,456 -123,456 1,234.56 -1,234.56) O( ' + *' 123,456 -123,456 1,234.56 -1,234.56) P( .00 12' + *'3456 -123456 1234.56 -1234.56) Q( 123456 -123456 ' + *'1234.56 -1234.56) ' + * + C £DBG_Str DSPLY + OA* A£.BIFN(EDITC ) + D* %EDITC formato codice X,Y,Z + C EVAL £DBG_Pas='P06' + C EVAL £DBG_Str= + C 'X('+%EDITC(0000.00:'X') + C +%EDITC(A50_N70:'X') + C +%EDITC(A50_N60:'X') + C +%EDITC(A50_N72:'X') + C +%EDITC(A50_N62:'X')+') ' + C +'Y('+%EDITC(0000.00:'Y') + C +%EDITC(A50_N70:'Y') + C +%EDITC(A50_N60:'Y') + C +%EDITC(A50_N72:'Y') + C +%EDITC(A50_N62:'Y')+') ' + C +'Z('+%EDITC(0000.00:'Z') + C +%EDITC(A50_N70:'Z') + C +%EDITC(A50_N60:'Z') + C +%EDITC(A50_N72:'Z') + C +%EDITC(A50_N62:'Z')+') ' + * Expected: + *'X(0000000123456012345O0123456012345O) Y( 0/00/00 12/34/56 12' + *'/34/56 12/34/56 12/34/56) Z( 123456 123456 123456 1234' + *'56) ' + * + C £DBG_Str DSPLY + OA* A£.BIFN(EDITC ) + D* %EDITC Tutti editc di una variabile + C EVAL £DBG_Pas='P08' + C EVAL A50_N156=123,456 + C EXSR SEZ_A50_A + C EVAL £DBG_Str=%TRIMR(A50_A1) + * Expected: + *' 123.456000 / 123.456000 / 123.456000 /' + *' 123.456000 / 123.456000 / 123.45600' + *'0 / 123.456000 / 123.456000 / 123.' + *'456000 / 123.456000 / 123.456000 / 12' + *'3.456000 / 123.456000 / 123.456000 / ' + *' 123.456000 / 123.456000 / 000000123456000 / ' + *'123456000 ' + * + C £DBG_Str DSPLY + OA* A£.BIFN(EDITC ) + D* %EDITC Tutti editc di una variabile (100.000 volte) + C EVAL £DBG_Pas='P09' + C EVAL A50_N156=123,456 + C DO NNN + C EXSR SEZ_A50_A + C ENDDO + C EVAL £DBG_Str=%TRIMR(A50_A1) + * Expected: + *' 123.456000 / 123.456000 / 123.456000 /' + *' 123.456000 / 123.456000 / 123.45600' + *'0 / 123.456000 / 123.456000 / 123.' + *'456000 / 123.456000 / 123.456000 / 12' + *'3.456000 / 123.456000 / 123.456000 / ' + *' 123.456000 / 123.456000 / 000000123456000 / ' + *'123456000 ' + C £DBG_Str DSPLY + * + C ENDSR + ************************************************************** + C SEZ_A50_A BEGSR + C EVAL A50_A1= + C %EDITC(A50_N156:'1')+' / ' + C +%EDITC(A50_N156:'2')+' / ' + C +%EDITC(A50_N156:'3')+' / ' + C +%EDITC(A50_N156:'4')+' / ' + C +%EDITC(A50_N156:'A')+' / ' + C +%EDITC(A50_N156:'B')+' / ' + C +%EDITC(A50_N156:'C')+' / ' + C +%EDITC(A50_N156:'D')+' / ' + C +%EDITC(A50_N156:'J')+' / ' + C +%EDITC(A50_N156:'K')+' / ' + C +%EDITC(A50_N156:'L')+' / ' + C +%EDITC(A50_N156:'M')+' / ' + C +%EDITC(A50_N156:'N')+' / ' + C +%EDITC(A50_N156:'O')+' / ' + C +%EDITC(A50_N156:'P')+' / ' + C +%EDITC(A50_N156:'Q')+' / ' + C +%EDITC(A50_N156:'X')+' / ' + C +%EDITC(A50_N156:'Z') + C ENDSR \ No newline at end of file From 42a1ec4cf35d98e761f002ac6df09491b2cf46c9 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 18 Jan 2024 12:35:09 +0100 Subject: [PATCH 006/423] Bump develop-SNAPSHOT version --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 6c861e067..da46df8d7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,6 +19,6 @@ FlightRecorderOptions=stackdepth=64 kotlinVersion=1.8.20 serializationVersion=1.5.0 jvmVersion=11 -reloadVersion=v1.3.2 +reloadVersion=develop-SNAPSHOT jarikoGroupId=io.github.smeup.jariko -jarikoVersion=v1.3.0 +jarikoVersion=develop-SNAPSHOT From eb755341b68669d85b95edf3e4b904cc3873ce23 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 18 Jan 2024 17:20:46 +0100 Subject: [PATCH 007/423] Throw exception when using an not valorized input parameter --- .../rpgparser/interpreter/SymbolTable.kt | 4 +- .../interpreter/internal_interpreter.kt | 21 ++- .../smeup/rpgparser/interpreter/program.kt | 130 ++++++++---------- .../com/smeup/rpgparser/interpreter/values.kt | 13 +- .../evaluation/SmeupInterpreterTest.kt | 11 ++ .../src/test/resources/smeup/MULANGTC10.rpgle | 18 +-- .../test/resources/smeup/T10_A60_P04.rpgle | 9 +- .../test/resources/smeup/T10_A60_P04F.rpgle | 14 ++ 8 files changed, 118 insertions(+), 102 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04F.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt index a9faccc64..e97a3c434 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt @@ -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? { @@ -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)) } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 5ba3c0642..6c9d26e32 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -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( @@ -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] @@ -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)") } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt index 88aca1dd4..7af659232 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt @@ -79,17 +79,6 @@ class RpgProgram(val cu: CompilationUnit, val name: String = "): List { - /* - 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() - require(params().asSequence().map { it.name }.toSet().all {it in expectedKeys}) { - "Expected params: ${params().asSequence().map { it.name }.joinToString(", ")}" - } - */ - val expectedKeys = params().asSequence().map { it.name }.toSet() if (expectedKeys.size <= params.size) { @@ -99,48 +88,45 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " params.size) { require(params().asSequence().map { it.name }.toSet().all { it in expectedKeys }) { "Expected params: ${params().asSequence().map { it.name }.joinToString(", ")}" + } - params().forEach { - if (!params.contains(it.name)) { - //params.put(it.name, ); - } + params().forEach() { + if (it.name in params.keys == false) { + params.put(it.name, VoidValue) } } } - - - this.systemInterface = systemInterface - logHandlers.log(ProgramInterpretationLogStart(name, params)) - val changedInitialValues: List - val elapsed = measureTimeMillis { - interpreter.setInterpretationContext(object : InterpretationContext { - private var iDataWrapUpChoice: DataWrapUpChoice? = null - override val currentProgramName: String - get() = name - - override fun shouldReinitialize() = false - override var dataWrapUpChoice: DataWrapUpChoice? - get() = iDataWrapUpChoice - set(value) { - iDataWrapUpChoice = value - } - }) - - for (pv in params) { - val expectedType = params().find { it.name == pv.key }!!.type - val coercedValue = coerce(pv.value, expectedType) - require(coercedValue.assignableTo(expectedType)) { - "param ${pv.key} was expected to have type $expectedType. It has value: $coercedValue" + this.systemInterface = systemInterface + logHandlers.log(ProgramInterpretationLogStart(name, params)) + val changedInitialValues: List + val elapsed = measureTimeMillis { + interpreter.setInterpretationContext(object : InterpretationContext { + private var iDataWrapUpChoice: DataWrapUpChoice? = null + override val currentProgramName: String + get() = name + override fun shouldReinitialize() = false + override var dataWrapUpChoice: DataWrapUpChoice? + get() = iDataWrapUpChoice + set(value) { + iDataWrapUpChoice = value } + }) + + for (pv in params) { + val expectedType = params().find { it.name == pv.key }!!.type + val coercedValue = coerce(pv.value, expectedType) + require(coercedValue.assignableTo(expectedType)) { + "param ${pv.key} was expected to have type $expectedType. It has value: $coercedValue" } - if (!initialized) { - initialized = true - val caller = if (MainExecutionContext.getProgramStack().isNotEmpty()) { - MainExecutionContext.getProgramStack().peek() - } else { - null - } - val activationGroupType = cu.activationGroupType() ?: when (caller) { + } + if (!initialized) { + initialized = true + val caller = if (MainExecutionContext.getProgramStack().isNotEmpty()) { + MainExecutionContext.getProgramStack().peek() + } else { + null + } + val activationGroupType = cu.activationGroupType() ?: when (caller) { // for main program, which does not have a caller, activation group is fixed by config null -> NamedActivationGroup(MainExecutionContext.getConfiguration().defaultActivationGroupName) @@ -148,42 +134,34 @@ class RpgProgram(val cu: CompilationUnit, val name: String = "("C10_P1: MULANGT102") + assertEquals(expected, "smeup/T10_A60_P04".outputOf()) + + assertFailsWith { + "smeup/T10_A60_P04F".outputOf() + } + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC10.rpgle index b71335e7b..7e105cfc6 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC10.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC10.rpgle @@ -1,17 +1,17 @@ - D B10_P1 S 10 - D B10_P2 S 2 0 - D B10_P3 S 50 + 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 B10_P1 - C PARM B10_P2 - C PARM B10_P3 + C PARM C10_P1 + C PARM C10_P2 + C PARM C10_P3 * - C IF B10_P2=1 - C EVAL B10_A50 ='MULANGTB10: '+%TRIMR(B10_P1) - C +' chiamata '+%CHAR(B10_P2) + C IF C10_P2=1 + C EVAL C10_P1 ='C10_P1: '+%TRIMR(C10_P1) + C EVAL C10_P2 = 2 C ENDIF * C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle index a287da53c..31da38c3f 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle @@ -1,13 +1,14 @@ ************************************************************************** D £DBG_Str S 2560 Stringa * - D A60_P1 S 10 INZ('MULANGT10') + 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='CALL('+A60_P1+', ' - C +%CHAR(A60_P2) - C +', '+A60_P3+') ' \ No newline at end of file + C EVAL £DBG_Str=%TRIM(A60_P1)+%CHAR(A60_P2) + C £DBG_Str DSPLY + * + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04F.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04F.rpgle new file mode 100644 index 000000000..4be8bd7bf --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04F.rpgle @@ -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 \ No newline at end of file From 0b4dd8414b91f2e018aca5afeda7b593287f2e1b Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 18 Jan 2024 17:47:17 +0100 Subject: [PATCH 008/423] Merge with develop --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 2e8448a7c..f992dbef9 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -122,7 +122,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT16_A70() { - val expected = listOf("A70_AR1(10) A70_AR2(20) A70_DS1(30) A70_AR3(10)") + val expected = listOf("A70_AR1(10) A70_AR2(20) A70_DS1(30) A70_AR3(10) A70_AR4(40)") assertEquals(expected, "smeup/T16_A70".outputOf()) } From f1f0705eef95b2f1bdaa51a3e6d3cac883ab5907 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 18 Jan 2024 17:55:59 +0100 Subject: [PATCH 009/423] Small fixes --- .../kotlin/com/smeup/rpgparser/interpreter/program.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt index 7af659232..f83af59fd 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt @@ -85,14 +85,15 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " params.size) { + } else { require(params().asSequence().map { it.name }.toSet().all { it in expectedKeys }) { "Expected params: ${params().asSequence().map { it.name }.joinToString(", ")}" } - params().forEach() { - if (it.name in params.keys == false) { - params.put(it.name, VoidValue) + // Set not passed params to VoidValue + params().forEach { + if (it.name !in params.keys) { + params[it.name] = VoidValue } } } From 76f27e7f196ed2612d3bebfaa2615372084d1c19 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 23 Jan 2024 07:50:41 +0000 Subject: [PATCH 010/423] change the formatAs function structure of DecimalValues --- .../smeup/rpgparser/interpreter/formatting.kt | 398 +++++++++++++----- 1 file changed, 300 insertions(+), 98 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index 5ede1c704..8e1a1d163 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -10,29 +10,272 @@ import java.util.* import com.smeup.rpgparser.interpreter.DecEdit.* internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, padChar: Char = ' '): StringValue { - fun signumChar(empty: Boolean) = (if (this.value < ZERO) "-" else if (empty) "" else " ") - fun commas(t: NumberType) = if (t.entireDigits <= 3) 0 else t.entireDigits / 3 - fun points(t: NumberType) = if (t.decimalDigits > 0) 1 else 0 - fun nrOfPunctuationsIn(t: NumberType): Int = commas(t) + points(t) + // https://www.ibm.com/docs/en/i/7.3?topic=80-edtcde-edit-code-keyword-display-files + + var cfgCommasDisplayed = false + var cfgDecimalPointDisplayed = false + var cfgSign = "" + var cfgBlankValueOfQDECFMT = "" + var cfgIValueOfQDECFMT = "" + var cfgJValueOfQDECFMT = "" + var cfgLeadingZeroSuppress = false + var cfgPadChar = padChar + var cfgPositiveSignAtBeginning = false + + var padStartLength = 0 + var padEndLength = 0 + var retValue = "" + + val t = (type as NumberType) + + fun decEditToString(): String { + return when(decedit) { + DOT -> "." + COMMA -> "," + else -> "" + } + } + + fun thousandSeparators(): Int { + //val valueString = this.value.toString() + //val integers = valueString.split(decEditToString())[0].length + //return if (integers <= 3) 0 else integers / 3 + return if (t.entireDigits <= 3) 0 else (t.entireDigits / 3) - 1 + } + + fun decimalSeparators() = if (t.decimalDigits > 0) 1 else 0 + + fun getPadStartLength(): Int { + var tot = 0 + if (cfgCommasDisplayed) { + tot += thousandSeparators() + } + if (cfgDecimalPointDisplayed) { + tot += decimalSeparators() + } + if(cfgSign.isNotEmpty() && cfgPositiveSignAtBeginning) { + if (this.value >= ZERO) { + tot += cfgSign.length + } + } + tot += t.decimalDigits + t.entireDigits + return tot + } + + fun getPadEndLength(): Int { + var tot = 0 + if(cfgSign.isNotEmpty()) { + tot += cfgSign.length + } + return tot + } + + fun setCfg() { + when (format) { + "1" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "2" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "3" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "4" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "A" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "CR" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "B" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "CR" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "C" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "CR" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "D" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "CR" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "J" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "N" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = true + } + "K" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "O" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = true + } + "L"-> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "P" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = true + } + "M" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + "Q" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = true + } + + "W", "Y", "Z" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = false + cfgSign = "" + cfgBlankValueOfQDECFMT = "" + cfgIValueOfQDECFMT = "" + cfgJValueOfQDECFMT = "" + cfgLeadingZeroSuppress = true + cfgPositiveSignAtBeginning = false + } + else -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = false + cfgSign = "-" + cfgBlankValueOfQDECFMT = "0" + cfgIValueOfQDECFMT = "0" + cfgJValueOfQDECFMT = "0" + cfgLeadingZeroSuppress = false + cfgPadChar = '0' + cfgPositiveSignAtBeginning = true + } + + } + } fun standardDecimalFormat(type: NumberType, locale: Locale) = DecimalFormat(decimalPattern(type), DecimalFormatSymbolsRepository.getSymbols(locale)).format(this.value.abs()) - // The functions below correspond to the EDITC parameter, one function per value - fun f1(decedit: DecEdit): String { + + fun getStandardFormat(): String { if (type !is NumberType) throw UnsupportedOperationException("Unsupported type for %EDITC: $type") return when (decedit) { COMMA -> { - standardDecimalFormat(type, Locale.ITALY).padStart(type.size + nrOfPunctuationsIn(type), padChar) + standardDecimalFormat(type, Locale.ITALY) } ZERO_COMMA -> { if (this.value.abs() < BigDecimal.ONE) { buildString { append("0") append(standardDecimalFormat(type, Locale.ITALY)) - }.padStart(type.size + nrOfPunctuationsIn(type), padChar) + } } else { - standardDecimalFormat(type, Locale.ITALY).padStart(type.size + nrOfPunctuationsIn(type), padChar) + standardDecimalFormat(type, Locale.ITALY) } } ZERO_DOT -> { @@ -40,37 +283,28 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, buildString { append("0") append(standardDecimalFormat(type, Locale.US)) - }.padStart(type.size + nrOfPunctuationsIn(type), padChar) + } } else { - standardDecimalFormat(type, Locale.US).padStart(type.size + nrOfPunctuationsIn(type), padChar) + standardDecimalFormat(type, Locale.US) } } DOT -> { - standardDecimalFormat(type, Locale.US).padStart(type.size + nrOfPunctuationsIn(type), padChar) + standardDecimalFormat(type, Locale.US) } } } - fun f2(decedit: DecEdit): String { - if (this.value.isZero()) { - return "".padStart(type.size + nrOfPunctuationsIn(type as NumberType)) - } else { - return f1(decedit) - } - } - fun italianDecimalformatWithNoThounsandsSeparator(type: NumberType) = DecimalFormat(buildString { append("#"); append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.italianSymbols).format(this.value.abs()) fun usDecimalformatWithNoThounsandsSeparator(type: NumberType) = DecimalFormat(buildString { append("#"); append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.usSymbols).format(this.value.abs()) - fun f3(decedit: DecEdit): String { + fun getItalianFormat(): String { if (type !is NumberType) throw UnsupportedOperationException("Unsupported type for %EDITC: $type") return when (decedit) { COMMA -> { italianDecimalformatWithNoThounsandsSeparator(type) - .padStart(type.size + points(type), padChar) } ZERO_COMMA -> { if (this.value.abs() < BigDecimal.ONE) { @@ -78,10 +312,8 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, append("0") append(standardDecimalFormat(type, Locale.ITALY)) } - .padStart(type.size + points(type), padChar) } else { italianDecimalformatWithNoThounsandsSeparator(type) - .padStart(type.size + points(type), padChar) } } ZERO_DOT -> { @@ -90,10 +322,8 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, append("0") append(standardDecimalFormat(type, Locale.US)) } - .padStart(type.size + points(type), padChar) } else { usDecimalformatWithNoThounsandsSeparator(type) - .padStart(type.size + points(type), padChar) } } DOT -> { @@ -102,59 +332,11 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.usSymbols) .format(this.value.abs()) - .padStart(type.size + points(type), padChar) } } } - fun f4(decedit: DecEdit): String { - if (this.value.isZero()) { - return "".padStart(type.size + points(type as NumberType)) - } else - return f3(decedit) - } - - fun fA(decedit: DecEdit): String { - return if (this.value < ZERO) { - f1(decedit) + "CR" - } else { - f1(decedit) - } - } - - fun fB(decedit: DecEdit): String = fA(decedit) - - fun fC(decedit: DecEdit): String { - return if (this.value < ZERO) { - f3(decedit) + "CR" - } else { - f3(decedit) - } - } - - fun fD(decedit: DecEdit): String { - return if (this.value < ZERO) { - f3(decedit) + "CR" - } else { - f3(decedit) - } - } - - fun fJ(decedit: DecEdit): String = f1(decedit) + signumChar(true) - - fun fK(decedit: DecEdit): String = f2(decedit) + signumChar(true) - - fun fL(decedit: DecEdit): String = f3(decedit) + signumChar(true) - - fun fM(decedit: DecEdit): String = f4(decedit) + signumChar(true) - - fun fN(decedit: DecEdit): String = signumChar(false) + f1(decedit) - - fun fO(decedit: DecEdit): String = signumChar(false) + f2(decedit) - - fun fP(decedit: DecEdit): String = signumChar(false) + f3(decedit) - - fun fQ(decedit: DecEdit): String = signumChar(false) + f4(decedit) + // The functions below correspond to the EDITC parameter, one function per value fun toBlnk(c: Char) = if (c == '0') ' ' else c @@ -169,39 +351,59 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } } - fun handleInitialZero(decedit: DecEdit): String { + fun removeLeadingZeros(num: String): String { + for (i in 0 until num.length) { + if (num[i] != '0') { + return num.substring(i) + } + } + return "0" + } + + fun handleInitialZero(): String { return if (this.value.isZero()) { "" } else { - f1(decedit).replace(".", "").replace(",", "").trim() + retValue.replace(".", "").replace(",", "").trim() } } -// fun fX(decedit: DecEdit) = value.unscaledValue().abs().toString().padStart(type.size, '0') - fun fX(decedit: DecEdit) = handleInitialZero(decedit).padStart(type.size, '0') + fun fX(): String { + return handleInitialZero() + } + + fun fZ(): String { + val a = handleInitialZero() + val b = removeLeadingZeros(a) + val c = b.padStart(padStartLength, cfgPadChar) + return c + } + + setCfg() + if (cfgCommasDisplayed) { + retValue = getStandardFormat() + } else { + retValue = getItalianFormat() + } + + if (cfgSign != "No sign" && this.value < ZERO) { + retValue += cfgSign + } - fun fZ(decedit: DecEdit) = handleInitialZero(decedit).padStart(type.size) + padStartLength = getPadStartLength() + retValue = retValue.padStart(padStartLength, cfgPadChar) + + if (!cfgPositiveSignAtBeginning) { + padEndLength = getPadEndLength() + retValue = retValue.padEnd(padEndLength + padStartLength, cfgPadChar) + } return when (format) { - "1" -> StringValue(f1(decedit)) - "2" -> StringValue(f2(decedit)) - "3" -> StringValue(f3(decedit)) - "4" -> StringValue(f4(decedit)) - "A" -> StringValue(fA(decedit)) - "B" -> StringValue(fB(decedit)) - "C" -> StringValue(fC(decedit)) - "D" -> StringValue(fD(decedit)) - "X" -> StringValue(fX(decedit)) - "J" -> StringValue(fJ(decedit)) - "K" -> StringValue(fK(decedit)) - "L" -> StringValue(fL(decedit)) - "M" -> StringValue(fM(decedit)) - "N" -> StringValue(fN(decedit)) - "O" -> StringValue(fO(decedit)) - "P" -> StringValue(fP(decedit)) - "Q" -> StringValue(fQ(decedit)) + "1", "2", "3", "4", "A", "B", "C", "D", + "J", "K", "L", "M", "N", "O", "P", "Q" -> StringValue(retValue) + "X" -> StringValue(fX()) "Y" -> StringValue(fY()) - "Z" -> StringValue(fZ(decedit)) + "Z" -> StringValue(fZ()) else -> throw UnsupportedOperationException("Unsupported format for %EDITC: $format") } } From aa876b4bd7da87a6c8ff0023ffd7c7f56d68df12 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:21:19 +0000 Subject: [PATCH 011/423] Add temporary documentation --- .../smeup/rpgparser/interpreter/formatting.kt | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index 8e1a1d163..325a6474d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -10,7 +10,35 @@ import java.util.* import com.smeup.rpgparser.interpreter.DecEdit.* internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, padChar: Char = ' '): StringValue { - // https://www.ibm.com/docs/en/i/7.3?topic=80-edtcde-edit-code-keyword-display-files + // %EDITC documentation: https://www.ibm.com/docs/en/i/7.3?topic=80-edtcde-edit-code-keyword-display-files + + // The total length of the %EDITC resulting string is calculated as follows: + // length of the field (no matter how many decimal there are) + // + potential number of separators (thousands and decimal) even if the real length of the decimal doesn't require separators + // + if sign is displayed: number of char of the sign on the right even if it's positive + // For example: if we assign 1234567 in a field defined "7S 0" with edit code 1 + // the resulting string will be: '1,234,567' where: + // - the total length will be 9 + // - the field length will be 7: 7 chars for the integer part (1234567) + 0 chars for the decimal part + // - the separators to include in the calculation of the length in this case will be 2 + // - the sign length will be 0 + + // String representation anomalies: https://www.mcpressonline.com/programming/rpg/converting-numeric-to-character-and-character-to-numeric + + // Notes about anomalies: + // - If the amount is too big for the defined field it must be trunked on the left must be trunked on the left + // for integer part and on the right for the decimal part. + // For example: if we assign -123456.239 in a field defined "7S 2" with edit code A, + // the resulting string will be: '34,567.23CR' where: + // - the total length will be 11 + // - the field length will be 7: 5 chars for the integer part (34567) + 2 chars for the decimal part (23) + // - the separators to include in the calculation of the length in this case will be only 2 + // - the sign length will be 2 + // - The spaces reserved for the sign, must be padded at the end of the returned string, while the rest + // (length of the field + potential separators + edit code char) must be padded at the beginning of the returned string + // + // As we can see, the same field defined as numeric 7 might have different resulting string + var cfgCommasDisplayed = false var cfgDecimalPointDisplayed = false @@ -20,7 +48,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, var cfgJValueOfQDECFMT = "" var cfgLeadingZeroSuppress = false var cfgPadChar = padChar - var cfgPositiveSignAtBeginning = false var padStartLength = 0 var padEndLength = 0 @@ -46,18 +73,13 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, fun decimalSeparators() = if (t.decimalDigits > 0) 1 else 0 fun getPadStartLength(): Int { - var tot = 0 + var tot = 1 // char for the edit code if (cfgCommasDisplayed) { tot += thousandSeparators() } if (cfgDecimalPointDisplayed) { tot += decimalSeparators() } - if(cfgSign.isNotEmpty() && cfgPositiveSignAtBeginning) { - if (this.value >= ZERO) { - tot += cfgSign.length - } - } tot += t.decimalDigits + t.entireDigits return tot } @@ -80,7 +102,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "2" -> { cfgCommasDisplayed = true @@ -90,7 +111,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "3" -> { cfgCommasDisplayed = false @@ -100,7 +120,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "4" -> { cfgCommasDisplayed = false @@ -110,7 +129,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "A" -> { cfgCommasDisplayed = true @@ -120,7 +138,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "B" -> { cfgCommasDisplayed = true @@ -130,7 +147,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "C" -> { cfgCommasDisplayed = false @@ -140,7 +156,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "D" -> { cfgCommasDisplayed = false @@ -150,7 +165,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "J" -> { cfgCommasDisplayed = true @@ -160,7 +174,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "N" -> { cfgCommasDisplayed = true @@ -170,7 +183,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = true } "K" -> { cfgCommasDisplayed = true @@ -180,7 +192,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "O" -> { cfgCommasDisplayed = true @@ -190,7 +201,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = true } "L"-> { cfgCommasDisplayed = false @@ -200,7 +210,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "P" -> { cfgCommasDisplayed = false @@ -210,7 +219,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = true } "M" -> { cfgCommasDisplayed = false @@ -220,7 +228,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } "Q" -> { cfgCommasDisplayed = false @@ -230,7 +237,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = true } "W", "Y", "Z" -> { @@ -241,7 +247,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "" cfgJValueOfQDECFMT = "" cfgLeadingZeroSuppress = true - cfgPositiveSignAtBeginning = false } else -> { cfgCommasDisplayed = false @@ -252,7 +257,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgJValueOfQDECFMT = "0" cfgLeadingZeroSuppress = false cfgPadChar = '0' - cfgPositiveSignAtBeginning = true } } @@ -393,10 +397,10 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, padStartLength = getPadStartLength() retValue = retValue.padStart(padStartLength, cfgPadChar) - if (!cfgPositiveSignAtBeginning) { - padEndLength = getPadEndLength() - retValue = retValue.padEnd(padEndLength + padStartLength, cfgPadChar) - } + + padEndLength = getPadEndLength() + retValue = retValue.padEnd(padEndLength + padStartLength, cfgPadChar) + return when (format) { "1", "2", "3", "4", "A", "B", "C", "D", From 72ad6fde091d7bbd80b25e0d8fa59dca683ff83f Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 23 Jan 2024 12:05:04 +0000 Subject: [PATCH 012/423] implement a performance improvement required in the code review --- .../interpreter/ExpressionEvaluation.kt | 17 +++++------------ .../smeup/rpgparser/parsing/ast/indicators.kt | 2 +- 2 files changed, 6 insertions(+), 13 deletions(-) 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 ba4c58f05..977bea098 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 @@ -677,18 +677,11 @@ class ExpressionEvaluation( throw RuntimeException("AssignmentExpr should be handled by the interpreter: $expression") override fun eval(expression: GlobalIndicatorExpr): Value { - - for (i in 1..99) - if (interpreterStatus.indicators[i] == null) - interpreterStatus.indicators[i] = BooleanValue(false) - val ret = interpreterStatus.indicators.map { it.value } - return StringValue( - ret.map { - if (it.value) { - 1 } else { - 0 - } - }.joinToString(separator = "") { it.toString() }) + val value = StringBuilder() + for (i in IndicatorType.Predefined.range) { + value.append(if (interpreterStatus.indicators[i] == null) "0" else if (interpreterStatus.indicators[i]!!.value) "1" else "0") + } + return StringValue(value.toString()) } override fun eval(expression: ParmsExpr): Value { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt index a95dc634d..c2285745a 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt @@ -22,7 +22,7 @@ data class IndicatorExpr(val index: IndicatorKey, override val position: Positio @Serializable data class GlobalIndicatorExpr(override val position: Position? = null) : AssignableExpression(position) { - override fun size(): Int = 99 + override fun size(): Int = IndicatorType.Predefined.range.last override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } From 5756c22623cf567e2c79a84da8a297b935ba4d3b Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:20:29 +0000 Subject: [PATCH 013/423] change decimal formatting --- .../smeup/rpgparser/interpreter/formatting.kt | 186 ++++++++++++------ 1 file changed, 123 insertions(+), 63 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index 325a6474d..7dfb10e4e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -48,50 +48,34 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, var cfgJValueOfQDECFMT = "" var cfgLeadingZeroSuppress = false var cfgPadChar = padChar - - var padStartLength = 0 - var padEndLength = 0 - var retValue = "" + var cfgSignPosition = true // true = begin, false = end val t = (type as NumberType) - fun decEditToString(): String { - return when(decedit) { - DOT -> "." - COMMA -> "," - else -> "" - } - } + var wrkTotalLength = 0 + + var retValue = "" fun thousandSeparators(): Int { - //val valueString = this.value.toString() - //val integers = valueString.split(decEditToString())[0].length - //return if (integers <= 3) 0 else integers / 3 - return if (t.entireDigits <= 3) 0 else (t.entireDigits / 3) - 1 + val ts = (t.entireDigits / 3) - 1 + return if (ts < 0) 0 else ts } fun decimalSeparators() = if (t.decimalDigits > 0) 1 else 0 - fun getPadStartLength(): Int { - var tot = 1 // char for the edit code + fun getWrkTotalLength(): Int { + var tot = 0 if (cfgCommasDisplayed) { tot += thousandSeparators() } if (cfgDecimalPointDisplayed) { tot += decimalSeparators() } + tot += cfgSign.length tot += t.decimalDigits + t.entireDigits return tot } - fun getPadEndLength(): Int { - var tot = 0 - if(cfgSign.isNotEmpty()) { - tot += cfgSign.length - } - return tot - } - fun setCfg() { when (format) { "1" -> { @@ -102,6 +86,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true + cfgSignPosition = false } "2" -> { cfgCommasDisplayed = true @@ -111,6 +96,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true + cfgSignPosition = false } "3" -> { cfgCommasDisplayed = false @@ -120,6 +106,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true + cfgSignPosition = false } "4" -> { cfgCommasDisplayed = false @@ -129,6 +116,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true + cfgSignPosition = false } "A" -> { cfgCommasDisplayed = true @@ -138,6 +126,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true + cfgSignPosition = false } "B" -> { cfgCommasDisplayed = true @@ -147,6 +136,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true + cfgSignPosition = false } "C" -> { cfgCommasDisplayed = false @@ -156,6 +146,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true + cfgSignPosition = false } "D" -> { cfgCommasDisplayed = false @@ -165,6 +156,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true + cfgSignPosition = false } "J" -> { cfgCommasDisplayed = true @@ -174,15 +166,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true - } - "N" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" - cfgLeadingZeroSuppress = true + cfgSignPosition = false } "K" -> { cfgCommasDisplayed = true @@ -192,15 +176,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true - } - "O" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" - cfgLeadingZeroSuppress = true + cfgSignPosition = false } "L"-> { cfgCommasDisplayed = false @@ -210,24 +186,48 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true + cfgSignPosition = false } - "P" -> { + "M" -> { cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "-" + cfgBlankValueOfQDECFMT = "Blanks" + cfgIValueOfQDECFMT = "Blanks" + cfgJValueOfQDECFMT = "Blanks" + cfgLeadingZeroSuppress = true + cfgSignPosition = false + } + "N" -> { + cfgCommasDisplayed = true + cfgDecimalPointDisplayed = true + cfgSign = "-" cfgBlankValueOfQDECFMT = ".00|0" cfgIValueOfQDECFMT = ",00|0" cfgJValueOfQDECFMT = ",00|0" cfgLeadingZeroSuppress = true + cfgSignPosition = true } - "M" -> { - cfgCommasDisplayed = false + + "O" -> { + cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "-" cfgBlankValueOfQDECFMT = "Blanks" cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true + cfgSignPosition = true + } + "P" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = true + cfgSign = "-" + cfgBlankValueOfQDECFMT = ".00|0" + cfgIValueOfQDECFMT = ",00|0" + cfgJValueOfQDECFMT = ",00|0" + cfgLeadingZeroSuppress = true + cfgSignPosition = true } "Q" -> { cfgCommasDisplayed = false @@ -237,8 +237,8 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "Blanks" cfgJValueOfQDECFMT = "Blanks" cfgLeadingZeroSuppress = true + cfgSignPosition = true } - "W", "Y", "Z" -> { cfgCommasDisplayed = false cfgDecimalPointDisplayed = false @@ -247,6 +247,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgIValueOfQDECFMT = "" cfgJValueOfQDECFMT = "" cfgLeadingZeroSuppress = true + cfgSignPosition = false } else -> { cfgCommasDisplayed = false @@ -257,11 +258,50 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgJValueOfQDECFMT = "0" cfgLeadingZeroSuppress = false cfgPadChar = '0' + cfgSignPosition = false } } } + fun decEditToString(): String { + return when(decedit) { + DOT -> "." + COMMA -> "," + else -> "" + } + } + + fun trunkAmount() { + var workValue = retValue + var workIntPart = "" + var workDecPart = "" + + val splitChar = decEditToString() + val parts = workValue.split(splitChar) + + workIntPart = parts[0] + + if (parts.size > 1) + workDecPart = parts[1] + + // trunk int part + if (workIntPart.length > t.entireDigits && t.entireDigits > 0) { + val startIndexToRemove = workIntPart.length - t.entireDigits + workIntPart = workIntPart.substring(startIndexToRemove) + } + + // trunk dec part + if (workDecPart.length > t.decimalDigits) { + val lastIndexToRemove = workDecPart.length - t.decimalDigits + workDecPart = workDecPart.substring(0, lastIndexToRemove) + } + + workValue = workIntPart + splitChar + workDecPart + + retValue = workValue + } + fun standardDecimalFormat(type: NumberType, locale: Locale) = DecimalFormat(decimalPattern(type), DecimalFormatSymbolsRepository.getSymbols(locale)).format(this.value.abs()) @@ -298,17 +338,17 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } } - fun italianDecimalformatWithNoThounsandsSeparator(type: NumberType) = + fun italianDecimalFormatWithNoThousandsSeparator(type: NumberType) = DecimalFormat(buildString { append("#"); append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.italianSymbols).format(this.value.abs()) - fun usDecimalformatWithNoThounsandsSeparator(type: NumberType) = + fun usDecimalFormatWithNoThousandsSeparator(type: NumberType) = DecimalFormat(buildString { append("#"); append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.usSymbols).format(this.value.abs()) fun getItalianFormat(): String { if (type !is NumberType) throw UnsupportedOperationException("Unsupported type for %EDITC: $type") return when (decedit) { COMMA -> { - italianDecimalformatWithNoThounsandsSeparator(type) + italianDecimalFormatWithNoThousandsSeparator(type) } ZERO_COMMA -> { if (this.value.abs() < BigDecimal.ONE) { @@ -317,7 +357,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, append(standardDecimalFormat(type, Locale.ITALY)) } } else { - italianDecimalformatWithNoThounsandsSeparator(type) + italianDecimalFormatWithNoThousandsSeparator(type) } } ZERO_DOT -> { @@ -327,7 +367,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, append(standardDecimalFormat(type, Locale.US)) } } else { - usDecimalformatWithNoThounsandsSeparator(type) + usDecimalFormatWithNoThousandsSeparator(type) } } DOT -> { @@ -342,16 +382,16 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, // The functions below correspond to the EDITC parameter, one function per value - fun toBlnk(c: Char) = if (c == '0') ' ' else c + fun toBlank(c: Char) = if (c == '0') ' ' else c fun fY(): String { var stringN = this.value.abs().unscaledValue().toString().trim() return if (type.elementSize() <= 6) { stringN = stringN.padStart(6, '0') - "${toBlnk(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}".padStart(type.size + 2) + "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}".padStart(type.size + 2) } else { stringN = stringN.padStart(8, '0') - "${toBlnk(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}${stringN[6]}${stringN[7]}".padStart(type.size + 2) + "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}${stringN[6]}${stringN[7]}".padStart(type.size + 2) } } @@ -379,27 +419,47 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, fun fZ(): String { val a = handleInitialZero() val b = removeLeadingZeros(a) - val c = b.padStart(padStartLength, cfgPadChar) + val c = b.padStart(wrkTotalLength, cfgPadChar) return c } + // set edit code configuration setCfg() + + // parse to local format if (cfgCommasDisplayed) { retValue = getStandardFormat() } else { retValue = getItalianFormat() } - if (cfgSign != "No sign" && this.value < ZERO) { - retValue += cfgSign - } + // get total length + wrkTotalLength = getWrkTotalLength() + + // trunk overflow digits + trunkAmount() - padStartLength = getPadStartLength() - retValue = retValue.padStart(padStartLength, cfgPadChar) + // append sign + if (cfgSign.isNotEmpty()) { + if (this.value < ZERO) { + if (cfgSignPosition) { + retValue = cfgSign + retValue + } else { + retValue += cfgSign + } + } else { + if (cfgSignPosition) { + retValue = cfgPadChar.toString().repeat(cfgSign.length) + retValue + } else { + retValue += cfgPadChar.toString().repeat(cfgSign.length) + } + } + } + // padding start + retValue = retValue.padStart(wrkTotalLength, cfgPadChar) - padEndLength = getPadEndLength() - retValue = retValue.padEnd(padEndLength + padStartLength, cfgPadChar) + // check final size return when (format) { From bf6d486cfcebec0f9e8fb016362ec00ecb5b507d Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 24 Jan 2024 17:50:03 +0100 Subject: [PATCH 014/423] Fix Expression.type for NumberLiteral When expression is an instance of NumberLiteral and the literal is zero, the type returned from Expression.type is a NumberType with precision always zero --- .../smeup/rpgparser/interpreter/typesystem.kt | 2 +- .../rpgparser/parsing/ast/expressions.kt | 13 ++++++++++-- .../parsing/parsetreetoast/expressions.kt | 21 ++++++++++++++++--- .../rpgparser/parsing/parsetreetoast/misc.kt | 2 +- .../rpgparser/parsing/ast/ExpressionsTest.kt | 20 +++++++++++++++++- 5 files changed, 50 insertions(+), 8 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 3b0edb602..664e5f5bd 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 @@ -281,7 +281,7 @@ fun Expression.type(): Type { NumberType(BigDecimal.valueOf(this.value).precision(), decimalDigits = 0) } is RealLiteral -> { - NumberType(this.value.precision() - this.value.scale(), this.value.scale()) + NumberType(this.precision - this.value.scale(), this.value.scale()) } is ArrayAccessExpr -> { val type = this.array.type().asArray() 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 a2f800cf9..bcbf1683b 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 @@ -39,12 +39,21 @@ abstract class Expression(@Transient override val position: Position? = null) : abstract class NumberLiteral(@Transient override val position: Position? = null) : Expression(position) @Serializable -data class IntLiteral(val value: Long, override val position: Position? = null) : NumberLiteral(position) { +data class IntLiteral( + val value: Long, + override val position: Position? = null, + val precision: Int = BigDecimal(value).precision() +) : NumberLiteral(position) { override fun render() = value.toString() override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } @Serializable -data class RealLiteral(@Contextual val value: BigDecimal, override val position: Position? = null) : NumberLiteral(position) { +data class RealLiteral( + @Contextual val value: BigDecimal, + override val position: Position? = null, + val precision: Int = value.precision() +) : NumberLiteral(position) { + override fun render() = value.toString() override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } 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 5c8a91953..7e5b2c840 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 @@ -98,7 +98,7 @@ internal fun RpgParser.NumberContext.toAst(conf: ToAstConfiguration = ToAstConfi text.contains(',') -> { text.toRealLiteral(position, Locale.ITALIAN) } - else -> IntLiteral(text.toLong(), position) + else -> text.toIntLiteral(position) } } @@ -106,9 +106,24 @@ fun String.toRealLiteral(position: Position?, locale: Locale): RealLiteral { val nf = NumberFormat.getNumberInstance(locale) val formatter = nf as DecimalFormat formatter.isParseBigDecimal = true + val bd = (formatter.parse(this) as BigDecimal) + // in case of zero precision returned by big decimal il always 1 + val precision = if (bd.toDouble() == 0.0) { + this.replace(Regex("[^0-9]"), "").length + } else { + bd.precision() + } + return RealLiteral(value = bd, position = position, precision = precision) +} - val bd = formatter.parse(this) as BigDecimal - return RealLiteral(bd, position) +fun String.toIntLiteral(position: Position?): IntLiteral { + val value = this.toLong() + val precision = if (value == 0L) { + this.replace(Regex("[^0-9]"), "").length + } else { + BigDecimal(value).precision() + } + return IntLiteral(value = value, position = position, precision = precision) } internal fun RpgParser.IdentifierContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Expression { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index a489f75ed..100ba2ed7 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -647,7 +647,7 @@ fun literalToNumber( value.toRealLiteral(position, Locale.ITALIAN) } else -> { - IntLiteral(value.toLong(), position) + value.toIntLiteral(position) } } } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ExpressionsTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ExpressionsTest.kt index 8e1384258..0670002ad 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ExpressionsTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ExpressionsTest.kt @@ -1,9 +1,11 @@ package com.smeup.rpgparser.parsing.ast -import com.smeup.rpgparser.* +import com.smeup.rpgparser.assertExpressionCanBeParsed +import com.smeup.rpgparser.dataRef import com.smeup.rpgparser.parsing.parsetreetoast.ToAstConfiguration import com.smeup.rpgparser.parsing.parsetreetoast.toAst import com.strumenta.kolasu.model.ReferenceByName +import java.math.BigDecimal import kotlin.test.Ignore import kotlin.test.assertEquals import org.junit.Test as test @@ -144,4 +146,20 @@ class ExpressionsTest { @test fun parseIndicatorsInParenthesis() { assertExpressionCanBeParsed("X=*IN(01)") } + + @test fun intLiteralParsingNumberWithPrecision() { + assertEquals(IntLiteral(value = 100, precision = 3), expression("100")) + } + + @test fun intLiteralParsingZeroWithPrecision() { + assertEquals(IntLiteral(value = 0, precision = 3), expression("000")) + } + + @test fun realLiteralParsingNumberWithPrecision() { + assertEquals(RealLiteral(value = BigDecimal("100.00"), precision = 5), expression("100.00")) + } + + @test fun realLiteralParsingZeroWithPrecision() { + assertEquals(RealLiteral(value = BigDecimal("0.00"), precision = 3), expression("0.00")) + } } From 316fc0f2c17b8fc20a8ff22852554a08d890f79c Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 24 Jan 2024 17:57:01 +0100 Subject: [PATCH 015/423] Change literalToNumber return type to NumberLiteral because more explicative --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 100ba2ed7..a38efaee4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -630,7 +630,7 @@ internal fun FactorContentContext.toAst(conf: ToAstConfiguration): Expression { fun literalToNumber( text: String, position: Position? -): Expression { +): NumberLiteral { // fix minus at right val value = if (text.endsWith('-')) { "-" + text.replaceFirst("-", "") From e40121ba325603041e1741855f2674bfd03ab407 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 24 Jan 2024 17:57:41 +0100 Subject: [PATCH 016/423] Refactor RpgParser.NumberContext.toAst as suggested by TODO --- .../parsing/parsetreetoast/expressions.kt | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) 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 7e5b2c840..ab2c6dcd6 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 @@ -85,21 +85,7 @@ internal fun RpgParser.LiteralContext.toAst(conf: ToAstConfiguration = ToAstConf internal fun RpgParser.NumberContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): NumberLiteral { val position = this.toPosition(conf.considerPosition) require(this.NumberPart().isEmpty()) { "Number not empty $position" } - val text = (this.MINUS()?.text ?: "") + this.NUMBER().text - - // When assigning a value to a numeric field we could either use - // a comma or a dot as decimal separators - - // TODO Rifattorizzare con literalToNumber(text, position) - return when { - text.contains('.') -> { - text.toRealLiteral(position, Locale.US) - } - text.contains(',') -> { - text.toRealLiteral(position, Locale.ITALIAN) - } - else -> text.toIntLiteral(position) - } + return literalToNumber(this.text, position) } fun String.toRealLiteral(position: Position?, locale: Locale): RealLiteral { From c2a424309ad811280e4881d21c31c0017c5f9da8 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 25 Jan 2024 13:29:11 +0100 Subject: [PATCH 017/423] Merge with develop and restored the NullValue class for managing unassign variables on program calls. --- .../interpreter/internal_interpreter.kt | 4 +-- .../smeup/rpgparser/interpreter/program.kt | 4 +-- .../com/smeup/rpgparser/interpreter/values.kt | 29 ++++++++++++++----- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 6c9d26e32..69403a002 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -69,7 +69,7 @@ class InterpreterStatus( fun indicator(key: IndicatorKey) = indicators[key] ?: BooleanValue.FALSE fun getVar(abstractDataDefinition: AbstractDataDefinition): Value { val tmpValue = symbolTable[abstractDataDefinition] - if (tmpValue is VoidValue) { + if (tmpValue is NullValue) { throw IllegalArgumentException("Void value for ${abstractDataDefinition.name}") } return tmpValue @@ -279,7 +279,7 @@ open class InternalInterpreter( if (it is DataDefinition) { try { val tmpValue = globalSymbolTable[it] - if (tmpValue !is VoidValue) { + if (tmpValue !is NullValue) { it.defaultValue = tmpValue.copy() } } catch (exc: IllegalArgumentException) { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt index f83af59fd..36ba8e840 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt @@ -90,10 +90,10 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " Date: Mon, 29 Jan 2024 08:18:19 +0000 Subject: [PATCH 018/423] add tests --- .../evaluation/SmeupInterpreterTest.kt | 12 +++++++ .../test/resources/smeup/T40_A10_P01.rpgle | 34 +++++++++++++++++++ .../src/test/resources/smeup/test_tony.rpgle | 21 ++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P01.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/test_tony.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 228668e79..628d83869 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -208,4 +208,16 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("A50_AR1(10) A50_AR2(40)") assertEquals(expected, "smeup/T02_A50_P03".outputOf()) } + + @Test + fun executeT40_A10_P01() { + val expected = listOf("") + assertEquals(expected, "smeup/T40_A10_P01".outputOf(configuration = smeupConfig)) + } + + @Test + fun executeTestTony() { + val expected = listOf("") + assertEquals(expected, "smeup/test_tony".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P01.rpgle new file mode 100644 index 000000000..6877a6118 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P01.rpgle @@ -0,0 +1,34 @@ + D A10_DS_P01 E DS EXTNAME(MULANGTF) INZ + * + D A10_DS_P04 E DS EXTNAME(MULANGTF) INZ + D PREFIX(P4:2) + * + D £DBG_Str S 2580 + * + C EVAL £DBG_Str='Lunghezza: ' + C +%CHAR(%LEN(A10_DS_P01)) + C +' Contenuto: ' + C +MLSYST + C +'-'+MLLIBR + C +'-'+MLFILE + C +'-'+MLTIPO + C +'-'+MLPROG + C +'-'+MLPSEZ + C +'-'+MLPPAS + C +'-'+MLPDES + C +'-'+MLSQIN + C +'-'+MLSQFI + C +'-'+MLAAAT + C +'-'+MLAAVA + C +'-'+%CHAR(MLNNAT) + C +'-'+%CHAR(MLNNVA) + C +'-'+MLINDI + C +'-'+%CHAR(MLTEES) + C +'-'+MLUSES + C +'-'+%CHAR(MLDTES) + C +'-'+%CHAR(MLORES) + C +'-'+MLASLA + C +'-'+%CHAR(MLASNR) + * + C £DBG_Str DSPLY + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/test_tony.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/test_tony.rpgle new file mode 100644 index 000000000..1a9e16f66 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/test_tony.rpgle @@ -0,0 +1,21 @@ + FMULANGTF IF E DISK + D A10_DS_P04 E DS EXTNAME(MULANGTF) INZ PREFIX(P4:2) + * + D MYDS DS + D MLPROG + D MLPSEZ + * + D £DBG_Str S 50 + * + C READ MULANGTF 50 + * + C *IN50 IFEQ *OFF + C EVAL £DBG_Str= + C ' MYDS('+MYDS+')' + C +' MLPROG('+MLPROG+')' + C +' MLPSEZ('+MLPSEZ+')' + C +' P4PROG('+P4PROG+')' + C £DBG_Str DSPLY + C ENDIF + * + C SETON LR \ No newline at end of file From 9ed7884a498dc47bac8604ccbd0cbb8fdafe84d6 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 29 Jan 2024 13:13:49 +0100 Subject: [PATCH 019/423] Add test --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T10_A20_P19.rpgle | 10 ++++++++++ 2 files changed, 16 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f992dbef9..3ece39f49 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -219,4 +219,10 @@ open class SmeupInterpreterTest : AbstractTest() { "smeup/T10_A60_P04F".outputOf() } } + + @Test + fun executeT10_A20_P19() { + val expected = listOf("1020") + assertEquals(expected, "smeup/T10_A20_P19".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19.rpgle new file mode 100644 index 000000000..d8a460192 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19.rpgle @@ -0,0 +1,10 @@ + D £DBG_Str S 50 VARYING + D A20_AR1 S 2 0 DIM(2) + *************************************************************************** + C Z-ADD 10 A20_AR1(1) + C Z-ADD 20 A20_AR1(2) + C EVAL £DBG_Str=%CHAR(A20_AR1(1)) + C +%CHAR(A20_AR1(2)) + * EXPECTED: 1020 + C £DBG_Str DSPLY + C SETON LR \ No newline at end of file From a6a45e45814a8b8ac44606e1f9a7179a00f70be4 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Mon, 29 Jan 2024 14:52:31 +0000 Subject: [PATCH 020/423] change decimal formatting --- .../smeup/rpgparser/interpreter/formatting.kt | 275 +++++++++++------- 1 file changed, 166 insertions(+), 109 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index 7dfb10e4e..45e2f5e8e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -43,9 +43,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, var cfgCommasDisplayed = false var cfgDecimalPointDisplayed = false var cfgSign = "" - var cfgBlankValueOfQDECFMT = "" - var cfgIValueOfQDECFMT = "" - var cfgJValueOfQDECFMT = "" + var cfgBlankValueOfZero = false var cfgLeadingZeroSuppress = false var cfgPadChar = padChar var cfgSignPosition = true // true = begin, false = end @@ -53,11 +51,14 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, val t = (type as NumberType) var wrkTotalLength = 0 + val decValue = this.value var retValue = "" fun thousandSeparators(): Int { - val ts = (t.entireDigits / 3) - 1 + val quotient = t.entireDigits / 3 + val reminder = t.entireDigits % 3 + val ts = if (reminder == 0) quotient - 1 else quotient return if (ts < 0) 0 else ts } @@ -71,7 +72,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, if (cfgDecimalPointDisplayed) { tot += decimalSeparators() } - tot += cfgSign.length + tot += if(cfgSign.isNotEmpty()) cfgSign.length else 0 tot += t.decimalDigits + t.entireDigits return tot } @@ -82,9 +83,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -92,9 +91,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" + cfgBlankValueOfZero = true cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -102,9 +99,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -112,9 +107,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" + cfgBlankValueOfZero = true cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -122,9 +115,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "CR" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -132,9 +123,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "CR" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" + cfgBlankValueOfZero = true cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -142,9 +131,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "CR" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -152,9 +139,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "CR" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" + cfgBlankValueOfZero = true cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -162,9 +147,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "-" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -172,9 +155,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "-" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" + cfgBlankValueOfZero = true cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -182,9 +163,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "-" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -192,9 +171,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "-" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" + cfgBlankValueOfZero = true cfgLeadingZeroSuppress = true cfgSignPosition = false } @@ -202,9 +179,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "-" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = true } @@ -213,9 +188,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = true cfgDecimalPointDisplayed = true cfgSign = "-" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" + cfgBlankValueOfZero = true cfgLeadingZeroSuppress = true cfgSignPosition = true } @@ -223,9 +196,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "-" - cfgBlankValueOfQDECFMT = ".00|0" - cfgIValueOfQDECFMT = ",00|0" - cfgJValueOfQDECFMT = ",00|0" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = true } @@ -233,34 +204,35 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "-" - cfgBlankValueOfQDECFMT = "Blanks" - cfgIValueOfQDECFMT = "Blanks" - cfgJValueOfQDECFMT = "Blanks" + cfgBlankValueOfZero = true cfgLeadingZeroSuppress = true cfgSignPosition = true } - "W", "Y", "Z" -> { + "X" -> { cfgCommasDisplayed = false cfgDecimalPointDisplayed = false cfgSign = "" - cfgBlankValueOfQDECFMT = "" - cfgIValueOfQDECFMT = "" - cfgJValueOfQDECFMT = "" + cfgBlankValueOfZero = false + cfgLeadingZeroSuppress = false + cfgSignPosition = false + cfgPadChar = '0' + } + "Y" -> { + cfgCommasDisplayed = false + cfgDecimalPointDisplayed = false + cfgSign = "" + cfgBlankValueOfZero = false cfgLeadingZeroSuppress = true cfgSignPosition = false } - else -> { + "Z" -> { cfgCommasDisplayed = false cfgDecimalPointDisplayed = false - cfgSign = "-" - cfgBlankValueOfQDECFMT = "0" - cfgIValueOfQDECFMT = "0" - cfgJValueOfQDECFMT = "0" - cfgLeadingZeroSuppress = false - cfgPadChar = '0' + cfgSign = "" + cfgBlankValueOfZero = true + cfgLeadingZeroSuppress = true cfgSignPosition = false } - } } @@ -277,8 +249,8 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, var workIntPart = "" var workDecPart = "" - val splitChar = decEditToString() - val parts = workValue.split(splitChar) + val decimalSeparator = decEditToString() + val parts = workValue.split(decimalSeparator) workIntPart = parts[0] @@ -297,23 +269,22 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, workDecPart = workDecPart.substring(0, lastIndexToRemove) } - workValue = workIntPart + splitChar + workDecPart + workValue = workIntPart + if (workDecPart.isEmpty()) "" else decimalSeparator + workDecPart retValue = workValue } fun standardDecimalFormat(type: NumberType, locale: Locale) = - DecimalFormat(decimalPattern(type), DecimalFormatSymbolsRepository.getSymbols(locale)).format(this.value.abs()) + DecimalFormat(decimalPattern(type), DecimalFormatSymbolsRepository.getSymbols(locale)).format(decValue.abs()) fun getStandardFormat(): String { - if (type !is NumberType) throw UnsupportedOperationException("Unsupported type for %EDITC: $type") return when (decedit) { COMMA -> { standardDecimalFormat(type, Locale.ITALY) } ZERO_COMMA -> { - if (this.value.abs() < BigDecimal.ONE) { + if (decValue.abs() < BigDecimal.ONE) { buildString { append("0") append(standardDecimalFormat(type, Locale.ITALY)) @@ -323,7 +294,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } } ZERO_DOT -> { - if (this.value.abs() < BigDecimal.ONE) { + if (decValue.abs() < BigDecimal.ONE) { buildString { append("0") append(standardDecimalFormat(type, Locale.US)) @@ -339,19 +310,18 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } fun italianDecimalFormatWithNoThousandsSeparator(type: NumberType) = - DecimalFormat(buildString { append("#"); append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.italianSymbols).format(this.value.abs()) + DecimalFormat(buildString { append("#"); append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.italianSymbols).format(decValue.abs()) fun usDecimalFormatWithNoThousandsSeparator(type: NumberType) = - DecimalFormat(buildString { append("#"); append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.usSymbols).format(this.value.abs()) + DecimalFormat(buildString { append("#"); append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.usSymbols).format(decValue.abs()) fun getItalianFormat(): String { - if (type !is NumberType) throw UnsupportedOperationException("Unsupported type for %EDITC: $type") return when (decedit) { COMMA -> { italianDecimalFormatWithNoThousandsSeparator(type) } ZERO_COMMA -> { - if (this.value.abs() < BigDecimal.ONE) { + if (decValue.abs() < BigDecimal.ONE) { buildString { append("0") append(standardDecimalFormat(type, Locale.ITALY)) @@ -361,7 +331,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } } ZERO_DOT -> { - if (this.value.abs() < BigDecimal.ONE) { + if (decValue.abs() < BigDecimal.ONE) { buildString { append("0") append(standardDecimalFormat(type, Locale.US)) @@ -375,26 +345,11 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, append("#") append(decimalsFormatString(type)) }, DecimalFormatSymbolsRepository.usSymbols) - .format(this.value.abs()) + .format(decValue.abs()) } } } - // The functions below correspond to the EDITC parameter, one function per value - - fun toBlank(c: Char) = if (c == '0') ' ' else c - - fun fY(): String { - var stringN = this.value.abs().unscaledValue().toString().trim() - return if (type.elementSize() <= 6) { - stringN = stringN.padStart(6, '0') - "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}".padStart(type.size + 2) - } else { - stringN = stringN.padStart(8, '0') - "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}${stringN[6]}${stringN[7]}".padStart(type.size + 2) - } - } - fun removeLeadingZeros(num: String): String { for (i in 0 until num.length) { if (num[i] != '0') { @@ -404,25 +359,101 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, return "0" } - fun handleInitialZero(): String { - return if (this.value.isZero()) { - "" - } else { - retValue.replace(".", "").replace(",", "").trim() - } + // The functions below correspond to the EDITC parameter, one function per value + fun toBlank(c: Char) = if (c == '0') ' ' else c + + fun f1(): String { + return retValue + } + + fun f2(): String { + return retValue + } + + fun f3(): String { + return retValue + } + + fun f4(): String { + return retValue + } + + fun fA(): String { + return retValue + } + + fun fB(): String { + return retValue + } + + fun fC(): String { + return retValue + } + + fun fD(): String { + return retValue + } + + fun fJ(): String { + return retValue + } + + fun fK(): String { + return retValue + } + + fun fL(): String { + return retValue + } + + fun fM(): String { + return retValue + } + + fun fN(): String { + return retValue + } + + fun fO(): String { + return retValue + } + + fun fP(): String { + return retValue + } + + fun fQ(): String { + return retValue } fun fX(): String { - return handleInitialZero() + if (decValue < ZERO) { + retValue = retValue.substring(0, retValue.length - 1) + 'O' + } + return retValue + } + + fun fY(): String { + var stringN = decValue.abs().unscaledValue().toString().trim() + val yLen = stringN.length + return if (yLen <= 6) { + stringN = stringN.padStart(6, '0') + "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}".padStart(wrkTotalLength + 2) + } else { + stringN = stringN.padStart(8, '0') + "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}${stringN[6]}${stringN[7]}".padStart(wrkTotalLength + 2) + } } fun fZ(): String { - val a = handleInitialZero() - val b = removeLeadingZeros(a) - val c = b.padStart(wrkTotalLength, cfgPadChar) - return c + return retValue } + + // ************** + // starts here !! + // ************** + // set edit code configuration setCfg() @@ -441,7 +472,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, // append sign if (cfgSign.isNotEmpty()) { - if (this.value < ZERO) { + if (decValue < ZERO) { if (cfgSignPosition) { retValue = cfgSign + retValue } else { @@ -456,16 +487,42 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } } + // remove the decimal separator + if (!cfgDecimalPointDisplayed) { + val decimalSeparator = decEditToString() + retValue = retValue.replace(decimalSeparator, "") + } + + // suppress leading zeros + if (cfgLeadingZeroSuppress) { + retValue = removeLeadingZeros(retValue) + } + // padding start retValue = retValue.padStart(wrkTotalLength, cfgPadChar) - // check final size - + // replace blanks in 0 + if (cfgBlankValueOfZero && decValue.isZero()) + retValue = " ".repeat(wrkTotalLength) return when (format) { - "1", "2", "3", "4", "A", "B", "C", "D", - "J", "K", "L", "M", "N", "O", "P", "Q" -> StringValue(retValue) + "1" -> StringValue(f1()) + "2" -> StringValue(f2()) + "3" -> StringValue(f3()) + "4" -> StringValue(f4()) + "A" -> StringValue(fA()) + "B" -> StringValue(fB()) + "C" -> StringValue(fC()) + "D" -> StringValue(fD()) "X" -> StringValue(fX()) + "J" -> StringValue(fJ()) + "K" -> StringValue(fK()) + "L" -> StringValue(fL()) + "M" -> StringValue(fM()) + "N" -> StringValue(fN()) + "O" -> StringValue(fO()) + "P" -> StringValue(fP()) + "Q" -> StringValue(fQ()) "Y" -> StringValue(fY()) "Z" -> StringValue(fZ()) else -> throw UnsupportedOperationException("Unsupported format for %EDITC: $format") From a8d11e68be84be7b90e5893842c6ad30bac19d18 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:56:52 +0000 Subject: [PATCH 021/423] Fix lint errors, corrected the wrong test BIFEDITC_J --- .../smeup/rpgparser/interpreter/formatting.kt | 42 +------ .../rpgparser/evaluation/InterpreterTest.kt | 6 +- .../evaluation/SmeupInterpreterTest.kt | 109 ++++++++---------- 3 files changed, 57 insertions(+), 100 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index 45e2f5e8e..5c1bb6aec 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -39,7 +39,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, // // As we can see, the same field defined as numeric 7 might have different resulting string - var cfgCommasDisplayed = false var cfgDecimalPointDisplayed = false var cfgSign = "" @@ -72,7 +71,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, if (cfgDecimalPointDisplayed) { tot += decimalSeparators() } - tot += if(cfgSign.isNotEmpty()) cfgSign.length else 0 + tot += if (cfgSign.isNotEmpty()) cfgSign.length else 0 tot += t.decimalDigits + t.entireDigits return tot } @@ -159,7 +158,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, cfgLeadingZeroSuppress = true cfgSignPosition = false } - "L"-> { + "L" -> { cfgCommasDisplayed = false cfgDecimalPointDisplayed = true cfgSign = "-" @@ -237,47 +236,16 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } fun decEditToString(): String { - return when(decedit) { + return when (decedit) { DOT -> "." COMMA -> "," else -> "" } } - fun trunkAmount() { - var workValue = retValue - var workIntPart = "" - var workDecPart = "" - - val decimalSeparator = decEditToString() - val parts = workValue.split(decimalSeparator) - - workIntPart = parts[0] - - if (parts.size > 1) - workDecPart = parts[1] - - // trunk int part - if (workIntPart.length > t.entireDigits && t.entireDigits > 0) { - val startIndexToRemove = workIntPart.length - t.entireDigits - workIntPart = workIntPart.substring(startIndexToRemove) - } - - // trunk dec part - if (workDecPart.length > t.decimalDigits) { - val lastIndexToRemove = workDecPart.length - t.decimalDigits - workDecPart = workDecPart.substring(0, lastIndexToRemove) - } - - workValue = workIntPart + if (workDecPart.isEmpty()) "" else decimalSeparator + workDecPart - - retValue = workValue - } - fun standardDecimalFormat(type: NumberType, locale: Locale) = DecimalFormat(decimalPattern(type), DecimalFormatSymbolsRepository.getSymbols(locale)).format(decValue.abs()) - fun getStandardFormat(): String { return when (decedit) { COMMA -> { @@ -449,7 +417,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, return retValue } - // ************** // starts here !! // ************** @@ -467,9 +434,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, // get total length wrkTotalLength = getWrkTotalLength() - // trunk overflow digits - trunkAmount() - // append sign if (cfgSign.isNotEmpty()) { if (decValue < ZERO) { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index d1a6143df..e63b17690 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -973,9 +973,9 @@ Test 6 @Test fun executeBIFEDITC_J() { - assertEquals(listOf("x 123,456 123,456- 1,234.56X", - "x 1,234.56- .00X", - "x 1,234.50X"), + assertEquals(listOf("x 123,456 123,456- 1,234.56 X", + "x 1,234.56- .00 X", + "x 1,234.50 X"), outputOf("BIFEDITC_J")) } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 432964ee1..4d885a68a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -208,64 +208,57 @@ open class SmeupInterpreterTest : AbstractTest() { fun executeT15_A50() { val expected = listOf( // P1 - "A( 123.456000 / 123.456000 / 123.456000" - +" / 123.456000 / 123.456000 / 123.456" - +"000 / 123.456000 / 123.456000 / 12" - +"3.456000 / 123.456000 / 123.456000 / " - +"123.456000 / 123.456000 / 123.456000 / " - +" 123.456000 / 123.456000 / 000000123456000 / " - +" 123456000) B( .000123 / .000123 / " - +" .000123 / .000123 / .000123 / " - +" .000123 / .000123 / .000123 " - +" / .000123 / .000123 / .000" - +"123 / .000123 / .000123 / " - +" .000123 / .000123 / .000123 / 000000000" - +"000123 / 123) C( 12,345.000000 / 12,345" - +".000000 / 12345.000000 / 12345.000000 / 12,345." - +"000000 / 12,345.000000 / 12345.000000 / 1" - +"2345.000000 / 12,345.000000 / 12,345.000000 / " - +" 12345.000000 / 12345.000000 / 12,345.000000 " - +"/ 12,345.000000 / 12345.000000 / 12345.00000" - +"0 / 000012345000000 / 12345000000)" - , // P2 - "1( .00 123,456 123,456 1,234.56 1,234.56) 2( " - +"123,456 123,456 1,234.56 1,234.56) 3( .00 123456 123456 " - +"1234.56 1234.56) 4( 123456 123456 1234.56 1234.56)" - , // P3 - "A( .00 123,456 123,456CR 1,234.56 1,234.56CR) B(" - +" 123,456 123,456CR 1,234.56 1,234.56CR) C( " - +" .00 123456 123456CR 1234.56 1234.56CR) D( 1" - +"23456 123456CR 1234.56 1234.56CR)" - , // P4 - "K( 123,456 123,456- 1,234.56 1,234.56-) J( " - +".00 123,456 123,456- 1,234.56 1,234.56-) L( .00 123" - +"456 123456- 1234.56 1234.56-) M( 123456 123456- 1" - +"234.56 1234.56-)" - , // P5 - "N( .00 123,456 -123,456 1,234.56 -1,234.56) O( " - +" 123,456 -123,456 1,234.56 -1,234.56) P( .00 12" - +"3456 -123456 1234.56 -1234.56) Q( 123456 -123456 " - +"1234.56 -1234.56)" - , // P6 - "X(0000000123456012345O0123456012345O) Y( 0/00/00 12/34/56 12" - +"/34/56 12/34/56 12/34/56) Z( 123456 123456 123456 1234" - +"56)" - , // P8 - " 123.456000 / 123.456000 / 123.456000 /" - +" 123.456000 / 123.456000 / 123.45600" - +"0 / 123.456000 / 123.456000 / 123." - +"456000 / 123.456000 / 123.456000 / 12" - +"3.456000 / 123.456000 / 123.456000 / " - +" 123.456000 / 123.456000 / 000000123456000 / " - +"123456000" - , // P9 - " 123.456000 / 123.456000 / 123.456000 /" - +" 123.456000 / 123.456000 / 123.45600" - +"0 / 123.456000 / 123.456000 / 123." - +"456000 / 123.456000 / 123.456000 / 12" - +"3.456000 / 123.456000 / 123.456000 / " - +" 123.456000 / 123.456000 / 000000123456000 / " - +"123456000" + "A( 123.456000 / 123.456000 / 123.456000" + + " / 123.456000 / 123.456000 / 123.456" + + "000 / 123.456000 / 123.456000 / 12" + + "3.456000 / 123.456000 / 123.456000 / " + + "123.456000 / 123.456000 / 123.456000 / " + + " 123.456000 / 123.456000 / 000000123456000 / " + + " 123456000) B( .000123 / .000123 / " + + " .000123 / .000123 / .000123 / " + + " .000123 / .000123 / .000123 " + + " / .000123 / .000123 / .000" + + "123 / .000123 / .000123 / " + + " .000123 / .000123 / .000123 / 000000000" + + "000123 / 123) C( 12,345.000000 / 12,345" + + ".000000 / 12345.000000 / 12345.000000 / 12,345." + + "000000 / 12,345.000000 / 12345.000000 / 1" + + "2345.000000 / 12,345.000000 / 12,345.000000 / " + + " 12345.000000 / 12345.000000 / 12,345.000000 " + + "/ 12,345.000000 / 12345.000000 / 12345.00000" + + "0 / 000012345000000 / 12345000000)", // P2 + "1( .00 123,456 123,456 1,234.56 1,234.56) 2( " + + "123,456 123,456 1,234.56 1,234.56) 3( .00 123456 123456 " + + "1234.56 1234.56) 4( 123456 123456 1234.56 1234.56)", // P3 + "A( .00 123,456 123,456CR 1,234.56 1,234.56CR) B(" + + " 123,456 123,456CR 1,234.56 1,234.56CR) C( " + + " .00 123456 123456CR 1234.56 1234.56CR) D( 1" + + "23456 123456CR 1234.56 1234.56CR)", // P4 + "K( 123,456 123,456- 1,234.56 1,234.56-) J( " + + ".00 123,456 123,456- 1,234.56 1,234.56-) L( .00 123" + + "456 123456- 1234.56 1234.56-) M( 123456 123456- 1" + + "234.56 1234.56-)", // P5 + "N( .00 123,456 -123,456 1,234.56 -1,234.56) O( " + + " 123,456 -123,456 1,234.56 -1,234.56) P( .00 12" + + "3456 -123456 1234.56 -1234.56) Q( 123456 -123456 " + + "1234.56 -1234.56)", // P6 + "X(0000000123456012345O0123456012345O) Y( 0/00/00 12/34/56 12" + + "/34/56 12/34/56 12/34/56) Z( 123456 123456 123456 1234" + + "56)", // P8 + " 123.456000 / 123.456000 / 123.456000 /" + + " 123.456000 / 123.456000 / 123.45600" + + "0 / 123.456000 / 123.456000 / 123." + + "456000 / 123.456000 / 123.456000 / 12" + + "3.456000 / 123.456000 / 123.456000 / " + + " 123.456000 / 123.456000 / 000000123456000 / " + + "123456000", // P9 + " 123.456000 / 123.456000 / 123.456000 /" + + " 123.456000 / 123.456000 / 123.45600" + + "0 / 123.456000 / 123.456000 / 123." + + "456000 / 123.456000 / 123.456000 / 12" + + "3.456000 / 123.456000 / 123.456000 / " + + " 123.456000 / 123.456000 / 000000123456000 / " + + "123456000" ) assertEquals(expected, "smeup/T15_A50".outputOf()) } From 0ffbae4a1052559a72b99c2287553fe5bdf4a332 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 30 Jan 2024 11:03:52 +0000 Subject: [PATCH 022/423] corrected the wrong test MUTE09_02 and MUTE09_02_COMMA, change edit code Y --- .../smeup/rpgparser/interpreter/formatting.kt | 45 ++++++++++++++++--- .../test/resources/overlay/MUTE09_02.rpgle | 4 +- .../resources/overlay/MUTE09_02_COMMA.rpgle | 4 +- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index 5c1bb6aec..c5d3200cc 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -403,14 +403,49 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, fun fY(): String { var stringN = decValue.abs().unscaledValue().toString().trim() - val yLen = stringN.length - return if (yLen <= 6) { - stringN = stringN.padStart(6, '0') - "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}".padStart(wrkTotalLength + 2) + + val testLen = + if(decValue.isZero()) { + wrkTotalLength } else { + stringN.length + } + + if (testLen <= 2) { + throw UnsupportedOperationException("Unsupported format for %EDITC: $format") + } else if (testLen == 3) { + // "nn⁄n" + stringN = stringN.padStart(3, '0') + stringN = "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}".padStart(wrkTotalLength + 2) + } else if (testLen == 4) { + // "nn⁄nn" + stringN = stringN.padStart(4, '0') + stringN = "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}".padStart(wrkTotalLength + 2) + } else if (testLen == 5) { + // "nn⁄nn⁄n" + stringN = stringN.padStart(5, '0') + stringN = "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}".padStart(wrkTotalLength + 2) + } else if (testLen == 6) { + // "nn⁄nn⁄nn" + stringN = stringN.padStart(6, '0') + stringN = "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}".padStart(wrkTotalLength + 2) + } else if (testLen == 7) { + // "nnn⁄nn⁄nn" + stringN = stringN.padStart(7, '0') + stringN = "${toBlank(stringN[0])}${stringN[1]}${stringN[2]}/${stringN[3]}${stringN[4]}/${stringN[5]}${stringN[6]}".padStart(wrkTotalLength + 2) + } else if (testLen == 8) { + // "nnn⁄nn⁄nn" stringN = stringN.padStart(8, '0') - "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}${stringN[6]}${stringN[7]}".padStart(wrkTotalLength + 2) + stringN = "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}${stringN[6]}${stringN[7]}".padStart(wrkTotalLength + 2) + } else if (testLen == 9) { + // "nnn⁄nn⁄nnnn" + stringN = stringN.padStart(9, '0') + stringN = "${toBlank(stringN[0])}${stringN[1]}${stringN[2]}/${stringN[3]}${stringN[4]}/${stringN[5]}${stringN[6]}${stringN[7]}${stringN[8]}".padStart(wrkTotalLength + 2) + } else { + throw UnsupportedOperationException("Unsupported format for %EDITC: $format") } + + return stringN } fun fZ(): String { diff --git a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02.rpgle b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02.rpgle index 0cdc647f0..6c98d6be7 100644 --- a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02.rpgle @@ -461,11 +461,11 @@ C EVAL S1=%EDITC(V1:'4') MU* VAL1(S1) VAL2(' .000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'A') - MU* VAL1(S1) VAL2(' .000000 ') COMP(EQ) + MU* VAL1(S1) VAL2(' ') COMP(EQ) C EVAL S1=%EDITC(V1:'B') MU* VAL1(S1) VAL2(' .000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'C') - MU* VAL1(S1) VAL2(' .000000 ') COMP(EQ) + MU* VAL1(S1) VAL2(' ') COMP(EQ) C EVAL S1=%EDITC(V1:'D') MU* VAL1(S1) VAL2(' .000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'J') diff --git a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02_COMMA.rpgle b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02_COMMA.rpgle index 2316fde39..8e52bd0ee 100644 --- a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02_COMMA.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02_COMMA.rpgle @@ -461,11 +461,11 @@ C EVAL S1=%EDITC(V1:'4') MU* VAL1(S1) VAL2(' ,000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'A') - MU* VAL1(S1) VAL2(' ,000000 ') COMP(EQ) + MU* VAL1(S1) VAL2(' ') COMP(EQ) C EVAL S1=%EDITC(V1:'B') MU* VAL1(S1) VAL2(' ,000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'C') - MU* VAL1(S1) VAL2(' ,000000 ') COMP(EQ) + MU* VAL1(S1) VAL2(' ') COMP(EQ) C EVAL S1=%EDITC(V1:'D') MU* VAL1(S1) VAL2(' ,000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'J') From f7952e25e4f3ece36094f7ed8f07f229ad1d0850 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 30 Jan 2024 13:51:17 +0000 Subject: [PATCH 023/423] add ZERO_DOT and ZERO_COMMA in the function decEditToString used to determine the decimal separator --- .../main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index c5d3200cc..955083a8d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -237,8 +237,8 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, fun decEditToString(): String { return when (decedit) { - DOT -> "." - COMMA -> "," + DOT, ZERO_DOT -> "." + COMMA, ZERO_COMMA -> "," else -> "" } } From 4609a7d086784644f53c2ecddb1584d024bb795d Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 30 Jan 2024 16:48:44 +0000 Subject: [PATCH 024/423] add exception for not supported edit code X with negative numbers, removed unsupported cases from RPGLE source files, fixed wrong tests --- .../smeup/rpgparser/interpreter/formatting.kt | 175 ++++++++++-------- .../evaluation/SmeupInterpreterTest.kt | 2 +- .../test/resources/overlay/MUTE09_02.rpgle | 7 - .../resources/overlay/MUTE09_02_COMMA.rpgle | 7 - .../test/resources/overlay/MUTE09_06.rpgle | 11 +- .../src/test/resources/smeup/T15_A50.rpgle | 3 +- 6 files changed, 105 insertions(+), 100 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index 955083a8d..43cab672b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -235,7 +235,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } } - fun decEditToString(): String { + fun getDecimalSeparator(): String { return when (decedit) { DOT, ZERO_DOT -> "." COMMA, ZERO_COMMA -> "," @@ -318,101 +318,174 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } } - fun removeLeadingZeros(num: String): String { - for (i in 0 until num.length) { - if (num[i] != '0') { - return num.substring(i) + fun removeLeadingZeros() { + if (decedit == DOT || decedit == COMMA) { + val workValue = retValue + if (cfgLeadingZeroSuppress) { + var exec = false + for (i in 0 until workValue.length) { + if (workValue[i] != '0') { + retValue = workValue.substring(i) + exec = true + break + } + } + if (!exec) { + retValue = "0" + } } } - return "0" } // The functions below correspond to the EDITC parameter, one function per value fun toBlank(c: Char) = if (c == '0') ' ' else c + fun appendSign() { + if (cfgSign.isNotEmpty()) { + if (decValue < ZERO) { + if (cfgSignPosition) { + retValue = cfgSign + retValue + } else { + retValue += cfgSign + } + } else { + if (cfgSignPosition) { + retValue = cfgPadChar.toString().repeat(cfgSign.length) + retValue + } else { + retValue += cfgPadChar.toString().repeat(cfgSign.length) + } + } + } + } + + fun removeDecimalSeparator() { + if (!cfgDecimalPointDisplayed) { + val decimalSeparator = getDecimalSeparator() + retValue = retValue.replace(decimalSeparator, "") + } + } + + fun addPadding() { + retValue = retValue.padStart(wrkTotalLength, cfgPadChar) + } + + fun replaceZeroWithBlank() { + if (cfgBlankValueOfZero && decValue.isZero()) + retValue = " ".repeat(wrkTotalLength) + } + fun f1(): String { + // parse to local format + if (cfgCommasDisplayed) { + retValue = getStandardFormat() + } else { + retValue = getItalianFormat() + } + + // get total length + wrkTotalLength = getWrkTotalLength() + + // append sign + appendSign() + + // remove the decimal separator + removeDecimalSeparator() + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding() + + // replace 0 with blank + replaceZeroWithBlank() + return retValue } fun f2(): String { - return retValue + return f1() } fun f3(): String { - return retValue + return f1() } fun f4(): String { - return retValue + return f1() } fun fA(): String { - return retValue + return f1() } fun fB(): String { - return retValue + return f1() } fun fC(): String { - return retValue + return f1() } fun fD(): String { - return retValue + return f1() } fun fJ(): String { - return retValue + return f1() } fun fK(): String { - return retValue + return f1() } fun fL(): String { - return retValue + return f1() } fun fM(): String { - return retValue + return f1() } fun fN(): String { - return retValue + return f1() } fun fO(): String { - return retValue + return f1() } fun fP(): String { - return retValue + return f1() } fun fQ(): String { - return retValue + return f1() } fun fX(): String { + retValue = f1() if (decValue < ZERO) { - retValue = retValue.substring(0, retValue.length - 1) + 'O' + throw UnsupportedOperationException("Unsupported format for %EDITC: $format with negative values") } return retValue } fun fY(): String { + // get total length + wrkTotalLength = getWrkTotalLength() + var stringN = decValue.abs().unscaledValue().toString().trim() val testLen = - if(decValue.isZero()) { + if (decValue.isZero()) { wrkTotalLength } else { stringN.length } if (testLen <= 2) { - throw UnsupportedOperationException("Unsupported format for %EDITC: $format") + throw UnsupportedOperationException("Unsupported format for %EDITC: $format with value length < 3") } else if (testLen == 3) { // "nn⁄n" stringN = stringN.padStart(3, '0') @@ -433,23 +506,22 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, // "nnn⁄nn⁄nn" stringN = stringN.padStart(7, '0') stringN = "${toBlank(stringN[0])}${stringN[1]}${stringN[2]}/${stringN[3]}${stringN[4]}/${stringN[5]}${stringN[6]}".padStart(wrkTotalLength + 2) - } else if (testLen == 8) { + } else if (testLen == 8) { // "nnn⁄nn⁄nn" stringN = stringN.padStart(8, '0') stringN = "${toBlank(stringN[0])}${stringN[1]}/${stringN[2]}${stringN[3]}/${stringN[4]}${stringN[5]}${stringN[6]}${stringN[7]}".padStart(wrkTotalLength + 2) - } else if (testLen == 9) { + } else if (testLen == 9) { // "nnn⁄nn⁄nnnn" stringN = stringN.padStart(9, '0') stringN = "${toBlank(stringN[0])}${stringN[1]}${stringN[2]}/${stringN[3]}${stringN[4]}/${stringN[5]}${stringN[6]}${stringN[7]}${stringN[8]}".padStart(wrkTotalLength + 2) } else { - throw UnsupportedOperationException("Unsupported format for %EDITC: $format") + throw UnsupportedOperationException("Unsupported format for %EDITC: $format with value length > 9") } - return stringN } fun fZ(): String { - return retValue + return f1() } // ************** @@ -459,51 +531,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, // set edit code configuration setCfg() - // parse to local format - if (cfgCommasDisplayed) { - retValue = getStandardFormat() - } else { - retValue = getItalianFormat() - } - - // get total length - wrkTotalLength = getWrkTotalLength() - - // append sign - if (cfgSign.isNotEmpty()) { - if (decValue < ZERO) { - if (cfgSignPosition) { - retValue = cfgSign + retValue - } else { - retValue += cfgSign - } - } else { - if (cfgSignPosition) { - retValue = cfgPadChar.toString().repeat(cfgSign.length) + retValue - } else { - retValue += cfgPadChar.toString().repeat(cfgSign.length) - } - } - } - - // remove the decimal separator - if (!cfgDecimalPointDisplayed) { - val decimalSeparator = decEditToString() - retValue = retValue.replace(decimalSeparator, "") - } - - // suppress leading zeros - if (cfgLeadingZeroSuppress) { - retValue = removeLeadingZeros(retValue) - } - - // padding start - retValue = retValue.padStart(wrkTotalLength, cfgPadChar) - - // replace blanks in 0 - if (cfgBlankValueOfZero && decValue.isZero()) - retValue = " ".repeat(wrkTotalLength) - return when (format) { "1" -> StringValue(f1()) "2" -> StringValue(f2()) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 4d885a68a..9d62f8cad 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -242,7 +242,7 @@ open class SmeupInterpreterTest : AbstractTest() { " 123,456 -123,456 1,234.56 -1,234.56) P( .00 12" + "3456 -123456 1234.56 -1234.56) Q( 123456 -123456 " + "1234.56 -1234.56)", // P6 - "X(0000000123456012345O0123456012345O) Y( 0/00/00 12/34/56 12" + + "X(00000001234560123456) Y( 0/00/00 12/34/56 12" + "/34/56 12/34/56 12/34/56) Z( 123456 123456 123456 1234" + "56)", // P8 " 123.456000 / 123.456000 / 123.456000 /" + diff --git a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02.rpgle b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02.rpgle index 6c98d6be7..2cbdc0f9d 100644 --- a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02.rpgle @@ -139,11 +139,6 @@ * segno: a sinistra MU* VAL1(S1) VAL2('-9010.548970 ') COMP(EQ) C EVAL S1=%EDITC(V1:'Q') - * 'X' : Separatore migliaia: no - * separatore decimale: no - * segno: no - MU* VAL1(S1) VAL2('9010548970 ') COMP(EQ) - C EVAL S1=%EDITC(V1:'X') * 'Z' : Separatore migliaia: no * separatore decimale: no * segno: no @@ -384,8 +379,6 @@ C EVAL S1=%EDITC(V2:'P') MU* VAL1(S1) VAL2('-1234 ') COMP(EQ) C EVAL S1=%EDITC(V2:'Q') - MU* VAL1(S1) VAL2('1234 ') COMP(EQ) - C EVAL S1=%EDITC(V2:'X') MU* VAL1(S1) VAL2('1234 ') COMP(EQ) C EVAL S1=%EDITC(V2:'Z') ** diff --git a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02_COMMA.rpgle b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02_COMMA.rpgle index 8e52bd0ee..15a666db2 100644 --- a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02_COMMA.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_02_COMMA.rpgle @@ -139,11 +139,6 @@ * segno: a sinistra MU* VAL1(S1) VAL2('-9010,548970 ') COMP(EQ) C EVAL S1=%EDITC(V1:'Q') - * 'X' : Separatore migliaia: no - * separatore decimale: no - * segno: no - MU* VAL1(S1) VAL2('9010548970 ') COMP(EQ) - C EVAL S1=%EDITC(V1:'X') * 'Z' : Separatore migliaia: no * separatore decimale: no * segno: no @@ -384,8 +379,6 @@ C EVAL S1=%EDITC(V2:'P') MU* VAL1(S1) VAL2('-1234 ') COMP(EQ) C EVAL S1=%EDITC(V2:'Q') - MU* VAL1(S1) VAL2('1234 ') COMP(EQ) - C EVAL S1=%EDITC(V2:'X') MU* VAL1(S1) VAL2('1234 ') COMP(EQ) C EVAL S1=%EDITC(V2:'Z') ** diff --git a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_06.rpgle b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_06.rpgle index b9728e211..474aec52e 100644 --- a/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_06.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/overlay/MUTE09_06.rpgle @@ -135,11 +135,6 @@ * segno: a sinistra MU* VAL1(S1) VAL2('-9010,548970 ') COMP(EQ) C EVAL S1=%EDITC(V1:'Q') - * 'X' : Separatore migliaia: no - * separatore decimale: no - * segno: no - MU* VAL1(S1) VAL2('9010548970 ') COMP(EQ) - C EVAL S1=%EDITC(V1:'X') * 'Z' : Separatore migliaia: no * separatore decimale: no * segno: no @@ -380,8 +375,6 @@ C EVAL S1=%EDITC(V2:'P') MU* VAL1(S1) VAL2('-1234 ') COMP(EQ) C EVAL S1=%EDITC(V2:'Q') - MU* VAL1(S1) VAL2('1234 ') COMP(EQ) - C EVAL S1=%EDITC(V2:'X') MU* VAL1(S1) VAL2('1234 ') COMP(EQ) C EVAL S1=%EDITC(V2:'Z') ** @@ -457,11 +450,11 @@ C EVAL S1=%EDITC(V1:'4') MU* VAL1(S1) VAL2(' 0,000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'A') - MU* VAL1(S1) VAL2(' 0,000000 ') COMP(EQ) + MU* VAL1(S1) VAL2(' ') COMP(EQ) C EVAL S1=%EDITC(V1:'B') MU* VAL1(S1) VAL2(' 0,000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'C') - MU* VAL1(S1) VAL2(' 0,000000 ') COMP(EQ) + MU* VAL1(S1) VAL2(' ') COMP(EQ) C EVAL S1=%EDITC(V1:'D') MU* VAL1(S1) VAL2(' 0,000000 ') COMP(EQ) C EVAL S1=%EDITC(V1:'J') diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A50.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A50.rpgle index e9eca98f4..e15b720b0 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A50.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A50.rpgle @@ -182,9 +182,8 @@ C EVAL £DBG_Str= C 'X('+%EDITC(0000.00:'X') C +%EDITC(A50_N70:'X') - C +%EDITC(A50_N60:'X') C +%EDITC(A50_N72:'X') - C +%EDITC(A50_N62:'X')+') ' + C +') ' C +'Y('+%EDITC(0000.00:'Y') C +%EDITC(A50_N70:'Y') C +%EDITC(A50_N60:'Y') From 1de916096f0dc895b214e303bd1efb687f32332b Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:06:22 +0000 Subject: [PATCH 025/423] refactoring DecimalValue.formatAs: removed cfg* flags and implemented the operations inside the functions --- .../smeup/rpgparser/interpreter/formatting.kt | 594 ++++++++++-------- 1 file changed, 340 insertions(+), 254 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index 43cab672b..f1b6ef953 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -10,48 +10,10 @@ import java.util.* import com.smeup.rpgparser.interpreter.DecEdit.* internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, padChar: Char = ' '): StringValue { - // %EDITC documentation: https://www.ibm.com/docs/en/i/7.3?topic=80-edtcde-edit-code-keyword-display-files - - // The total length of the %EDITC resulting string is calculated as follows: - // length of the field (no matter how many decimal there are) - // + potential number of separators (thousands and decimal) even if the real length of the decimal doesn't require separators - // + if sign is displayed: number of char of the sign on the right even if it's positive - // For example: if we assign 1234567 in a field defined "7S 0" with edit code 1 - // the resulting string will be: '1,234,567' where: - // - the total length will be 9 - // - the field length will be 7: 7 chars for the integer part (1234567) + 0 chars for the decimal part - // - the separators to include in the calculation of the length in this case will be 2 - // - the sign length will be 0 - - // String representation anomalies: https://www.mcpressonline.com/programming/rpg/converting-numeric-to-character-and-character-to-numeric - - // Notes about anomalies: - // - If the amount is too big for the defined field it must be trunked on the left must be trunked on the left - // for integer part and on the right for the decimal part. - // For example: if we assign -123456.239 in a field defined "7S 2" with edit code A, - // the resulting string will be: '34,567.23CR' where: - // - the total length will be 11 - // - the field length will be 7: 5 chars for the integer part (34567) + 2 chars for the decimal part (23) - // - the separators to include in the calculation of the length in this case will be only 2 - // - the sign length will be 2 - // - The spaces reserved for the sign, must be padded at the end of the returned string, while the rest - // (length of the field + potential separators + edit code char) must be padded at the beginning of the returned string - // - // As we can see, the same field defined as numeric 7 might have different resulting string - - var cfgCommasDisplayed = false - var cfgDecimalPointDisplayed = false - var cfgSign = "" - var cfgBlankValueOfZero = false - var cfgLeadingZeroSuppress = false - var cfgPadChar = padChar - var cfgSignPosition = true // true = begin, false = end val t = (type as NumberType) - var wrkTotalLength = 0 val decValue = this.value - var retValue = "" fun thousandSeparators(): Int { @@ -64,175 +26,7 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, fun decimalSeparators() = if (t.decimalDigits > 0) 1 else 0 fun getWrkTotalLength(): Int { - var tot = 0 - if (cfgCommasDisplayed) { - tot += thousandSeparators() - } - if (cfgDecimalPointDisplayed) { - tot += decimalSeparators() - } - tot += if (cfgSign.isNotEmpty()) cfgSign.length else 0 - tot += t.decimalDigits + t.entireDigits - return tot - } - - fun setCfg() { - when (format) { - "1" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "2" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "3" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = true - cfgSign = "" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "4" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = true - cfgSign = "" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "A" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "CR" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "B" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "CR" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "C" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = true - cfgSign = "CR" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "D" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = true - cfgSign = "CR" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "J" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "K" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "L" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "M" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "N" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = true - } - - "O" -> { - cfgCommasDisplayed = true - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = true - } - "P" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = true - } - "Q" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = true - cfgSign = "-" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = true - } - "X" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = false - cfgSign = "" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = false - cfgSignPosition = false - cfgPadChar = '0' - } - "Y" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = false - cfgSign = "" - cfgBlankValueOfZero = false - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - "Z" -> { - cfgCommasDisplayed = false - cfgDecimalPointDisplayed = false - cfgSign = "" - cfgBlankValueOfZero = true - cfgLeadingZeroSuppress = true - cfgSignPosition = false - } - } + return t.decimalDigits + t.entireDigits } fun getDecimalSeparator(): String { @@ -321,7 +115,6 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, fun removeLeadingZeros() { if (decedit == DOT || decedit == COMMA) { val workValue = retValue - if (cfgLeadingZeroSuppress) { var exec = false for (i in 0 until workValue.length) { if (workValue[i] != '0') { @@ -333,15 +126,13 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, if (!exec) { retValue = "0" } - } } } // The functions below correspond to the EDITC parameter, one function per value fun toBlank(c: Char) = if (c == '0') ' ' else c - fun appendSign() { - if (cfgSign.isNotEmpty()) { + fun appendSign(cfgSign: String, cfgSignPosition: Boolean, cfgPadChar: Char) { if (decValue < ZERO) { if (cfgSignPosition) { retValue = cfgSign + retValue @@ -355,47 +146,54 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue += cfgPadChar.toString().repeat(cfgSign.length) } } - } } fun removeDecimalSeparator() { - if (!cfgDecimalPointDisplayed) { - val decimalSeparator = getDecimalSeparator() - retValue = retValue.replace(decimalSeparator, "") - } + val decimalSeparator = getDecimalSeparator() + retValue = retValue.replace(decimalSeparator, "") } - fun addPadding() { + fun addPadding(cfgPadChar: Char) { retValue = retValue.padStart(wrkTotalLength, cfgPadChar) } fun replaceZeroWithBlank() { - if (cfgBlankValueOfZero && decValue.isZero()) + if (decValue.isZero()) retValue = " ".repeat(wrkTotalLength) } fun f1(): String { // parse to local format - if (cfgCommasDisplayed) { - retValue = getStandardFormat() - } else { - retValue = getItalianFormat() - } + retValue = getStandardFormat() // get total length wrkTotalLength = getWrkTotalLength() + wrkTotalLength += thousandSeparators() + wrkTotalLength += decimalSeparators() - // append sign - appendSign() + // suppress leading zeros + removeLeadingZeros() - // remove the decimal separator - removeDecimalSeparator() + // padding start + addPadding(padChar) + + return retValue + } + + fun f2(): String { + // parse to local format + retValue = getStandardFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += thousandSeparators() + wrkTotalLength += decimalSeparators() // suppress leading zeros removeLeadingZeros() // padding start - addPadding() + addPadding(padChar) // replace 0 with blank replaceZeroWithBlank() @@ -403,71 +201,348 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, return retValue } - fun f2(): String { - return f1() - } - fun f3(): String { - return f1() + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += decimalSeparators() + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + return retValue } fun f4(): String { - return f1() + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += decimalSeparators() + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + // replace 0 with blank + replaceZeroWithBlank() + + return retValue } fun fA(): String { - return f1() + // parse to local format + retValue = getStandardFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += thousandSeparators() + wrkTotalLength += decimalSeparators() + val cfgSign = "CR" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, false, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + return retValue } fun fB(): String { - return f1() + // parse to local format + retValue = getStandardFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += thousandSeparators() + wrkTotalLength += decimalSeparators() + val cfgSign = "CR" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, false, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + // replace 0 with blank + replaceZeroWithBlank() + + return retValue } fun fC(): String { - return f1() + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += decimalSeparators() + val cfgSign = "CR" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, false, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + return retValue } fun fD(): String { - return f1() + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += decimalSeparators() + val cfgSign = "CR" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, false, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + // replace 0 with blank + replaceZeroWithBlank() + + return retValue } fun fJ(): String { - return f1() + // parse to local format + retValue = getStandardFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += thousandSeparators() + wrkTotalLength += decimalSeparators() + val cfgSign = "-" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, false, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + return retValue } fun fK(): String { - return f1() + // parse to local format + retValue = getStandardFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += thousandSeparators() + wrkTotalLength += decimalSeparators() + val cfgSign = "-" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, false, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + // replace 0 with blank + replaceZeroWithBlank() + + return retValue } fun fL(): String { - return f1() + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += decimalSeparators() + val cfgSign = "-" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, false, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + return retValue } fun fM(): String { - return f1() + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += decimalSeparators() + val cfgSign = "-" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, false, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + // replace 0 with blank + replaceZeroWithBlank() + + return retValue } fun fN(): String { - return f1() + // parse to local format + retValue = getStandardFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += thousandSeparators() + wrkTotalLength += decimalSeparators() + val cfgSign = "-" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, true, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + return retValue } fun fO(): String { - return f1() + // parse to local format + retValue = getStandardFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += thousandSeparators() + wrkTotalLength += decimalSeparators() + val cfgSign = "-" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, true, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + // replace 0 with blank + replaceZeroWithBlank() + + return retValue } fun fP(): String { - return f1() + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += decimalSeparators() + val cfgSign = "-" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, true, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + return retValue } fun fQ(): String { - return f1() + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + wrkTotalLength += decimalSeparators() + val cfgSign = "-" + wrkTotalLength += cfgSign.length + + // append sign + appendSign(cfgSign, true, padChar) + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + // replace 0 with blank + replaceZeroWithBlank() + + return retValue } fun fX(): String { - retValue = f1() if (decValue < ZERO) { throw UnsupportedOperationException("Unsupported format for %EDITC: $format with negative values") } + + // parse to local format + retValue = getItalianFormat() + + // get total length + wrkTotalLength = getWrkTotalLength() + + // remove the decimal separator + removeDecimalSeparator() + + // padding start + addPadding('0') + return retValue } @@ -521,15 +596,26 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, } fun fZ(): String { - return f1() - } + // parse to local format + retValue = getItalianFormat() - // ************** - // starts here !! - // ************** + // get total length + wrkTotalLength = getWrkTotalLength() - // set edit code configuration - setCfg() + // remove the decimal separator + removeDecimalSeparator() + + // suppress leading zeros + removeLeadingZeros() + + // padding start + addPadding(padChar) + + // replace 0 with blank + replaceZeroWithBlank() + + return retValue + } return when (format) { "1" -> StringValue(f1()) From 49d2b9363a2572c09c090435919ae2afa9380f85 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:14:04 +0000 Subject: [PATCH 026/423] move cfgSign declaration position --- .../smeup/rpgparser/interpreter/formatting.kt | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt index f1b6ef953..12cdeef53 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/formatting.kt @@ -243,10 +243,10 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getStandardFormat() // get total length + val cfgSign = "CR" wrkTotalLength = getWrkTotalLength() wrkTotalLength += thousandSeparators() wrkTotalLength += decimalSeparators() - val cfgSign = "CR" wrkTotalLength += cfgSign.length // append sign @@ -266,10 +266,10 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getStandardFormat() // get total length + val cfgSign = "CR" wrkTotalLength = getWrkTotalLength() wrkTotalLength += thousandSeparators() wrkTotalLength += decimalSeparators() - val cfgSign = "CR" wrkTotalLength += cfgSign.length // append sign @@ -292,9 +292,9 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getItalianFormat() // get total length + val cfgSign = "CR" wrkTotalLength = getWrkTotalLength() wrkTotalLength += decimalSeparators() - val cfgSign = "CR" wrkTotalLength += cfgSign.length // append sign @@ -314,9 +314,9 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getItalianFormat() // get total length + val cfgSign = "CR" wrkTotalLength = getWrkTotalLength() wrkTotalLength += decimalSeparators() - val cfgSign = "CR" wrkTotalLength += cfgSign.length // append sign @@ -339,10 +339,10 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getStandardFormat() // get total length + val cfgSign = "-" wrkTotalLength = getWrkTotalLength() wrkTotalLength += thousandSeparators() wrkTotalLength += decimalSeparators() - val cfgSign = "-" wrkTotalLength += cfgSign.length // append sign @@ -362,10 +362,10 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getStandardFormat() // get total length + val cfgSign = "-" wrkTotalLength = getWrkTotalLength() wrkTotalLength += thousandSeparators() wrkTotalLength += decimalSeparators() - val cfgSign = "-" wrkTotalLength += cfgSign.length // append sign @@ -388,9 +388,9 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getItalianFormat() // get total length + val cfgSign = "-" wrkTotalLength = getWrkTotalLength() wrkTotalLength += decimalSeparators() - val cfgSign = "-" wrkTotalLength += cfgSign.length // append sign @@ -410,9 +410,9 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getItalianFormat() // get total length + val cfgSign = "-" wrkTotalLength = getWrkTotalLength() wrkTotalLength += decimalSeparators() - val cfgSign = "-" wrkTotalLength += cfgSign.length // append sign @@ -435,10 +435,10 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getStandardFormat() // get total length + val cfgSign = "-" wrkTotalLength = getWrkTotalLength() wrkTotalLength += thousandSeparators() wrkTotalLength += decimalSeparators() - val cfgSign = "-" wrkTotalLength += cfgSign.length // append sign @@ -458,10 +458,10 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getStandardFormat() // get total length + val cfgSign = "-" wrkTotalLength = getWrkTotalLength() wrkTotalLength += thousandSeparators() wrkTotalLength += decimalSeparators() - val cfgSign = "-" wrkTotalLength += cfgSign.length // append sign @@ -484,9 +484,9 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getItalianFormat() // get total length + val cfgSign = "-" wrkTotalLength = getWrkTotalLength() wrkTotalLength += decimalSeparators() - val cfgSign = "-" wrkTotalLength += cfgSign.length // append sign @@ -506,9 +506,9 @@ internal fun DecimalValue.formatAs(format: String, type: Type, decedit: DecEdit, retValue = getItalianFormat() // get total length + val cfgSign = "-" wrkTotalLength = getWrkTotalLength() wrkTotalLength += decimalSeparators() - val cfgSign = "-" wrkTotalLength += cfgSign.length // append sign From 7c69b5e34f2ed72c9d3e85f6f61566e9b3c532d8 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 31 Jan 2024 12:50:28 +0100 Subject: [PATCH 027/423] Fixed `Z-ADD` for T10_A20_P19. --- .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 5 +++-- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 3 +++ .../src/test/resources/smeup/T10_A20_P19F.rpgle | 10 ++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19F.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index a38efaee4..5a8f8ebba 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1378,10 +1378,11 @@ internal fun CsMOVELContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( internal fun CsZ_ADDContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): ZAddStmt { val position = toPosition(conf.considerPosition) - val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("Z-ADD operation requires factor 2: ${this.text} - ${position.atLine()}") val name = this.cspec_fixed_standard_parts().result.text + val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("Z-ADD operation requires factor 2: ${this.text} - ${position.atLine()}") + val resultExpression = annidatedReferenceExpression(name, position) val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(name, position, conf) - return ZAddStmt(DataRefExpr(ReferenceByName(name), position), dataDefinition, expression, position) + return ZAddStmt(resultExpression, dataDefinition, expression, position) } internal fun CsMULTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MultStmt { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 3ece39f49..e5deaeea6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -224,5 +224,8 @@ open class SmeupInterpreterTest : AbstractTest() { fun executeT10_A20_P19() { val expected = listOf("1020") assertEquals(expected, "smeup/T10_A20_P19".outputOf()) + assertFailsWith { + "smeup/T10_A20_P19F".outputOf() + } } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19F.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19F.rpgle new file mode 100644 index 000000000..c649bebe6 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19F.rpgle @@ -0,0 +1,10 @@ + D £DBG_Str S 50 VARYING + D A20_AR1 S 2 0 DIM(2) + *************************************************************************** + C Z-ADD 10 A20_AR1(1 + C Z-ADD 20 A20_AR12) + C EVAL £DBG_Str=%CHAR(A20_AR1(1)) + C +%CHAR(A20_AR1(2)) + * EXPECTED: 1020 + C £DBG_Str DSPLY + C SETON LR \ No newline at end of file From e32c6964146794415140eb7bb79da96a526a091c Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 31 Jan 2024 13:50:31 +0100 Subject: [PATCH 028/423] Improved solution. --- .../rpgparser/parsing/parsetreetoast/misc.kt | 31 ++++++++++++++++++- .../evaluation/SmeupInterpreterTest.kt | 1 + 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 5a8f8ebba..c3a052c5e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -966,6 +966,26 @@ private fun annidatedReferenceExpression( return expr as AssignableExpression } +private fun makeArrayAccessExpression(text: String, position: Position?): AssignableExpression { + var expr: Expression = text.indexOf("(").let { + val varName = if (it == -1) text else text.substring(0, it) + DataRefExpr(ReferenceByName(varName), position) + } + + val indexText = text.substring(text.indexOf("(") + 1, text.lastIndexOf(")")) + val indexValue = indexText.toLongOrNull() + + val indexExpression = + if (indexValue == null) { + DataRefExpr(ReferenceByName(indexText), computeNewPosition(position, text)) + } else { + IntLiteral(indexValue, computeNewPosition(position, text)) + } + expr = ArrayAccessExpr(expr, indexExpression) + + return expr +} + private fun computeNewPosition(position: Position?, text: String) = if (position == null) { null @@ -1380,7 +1400,16 @@ internal fun CsZ_ADDContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( val position = toPosition(conf.considerPosition) val name = this.cspec_fixed_standard_parts().result.text val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("Z-ADD operation requires factor 2: ${this.text} - ${position.atLine()}") - val resultExpression = annidatedReferenceExpression(name, position) + + // Result Field could be an array, array element, field, subfield, or table name. (https://www.ibm.com/docs/en/i/7.5?topic=codes-z-add-zero-add) + // The REGEX to check if it is an array element is: ^[a-zA-z£_]+[a-zA-Z0-9£_]*(\(0\)|(\([1-9]+[0-9]*\)))$. You can test and improve it with https://www.regex101.com. + val resultExpression = when { + // TODO Add cases for array, subfield, table name. + // ARRAY ELEMENT + name.matches(Regex("^[a-zA-z£_]+[a-zA-Z0-9£_]*(\\(0\\)|(\\([1-9]+[0-9]*\\)))\$")) -> makeArrayAccessExpression(name, position) + // FIELD + else -> DataRefExpr(ReferenceByName(name), position) + } val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(name, position, conf) return ZAddStmt(resultExpression, dataDefinition, expression, position) } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index e5deaeea6..2d2333ce3 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -224,6 +224,7 @@ open class SmeupInterpreterTest : AbstractTest() { fun executeT10_A20_P19() { val expected = listOf("1020") assertEquals(expected, "smeup/T10_A20_P19".outputOf()) + assertFailsWith { "smeup/T10_A20_P19F".outputOf() } From 5649662832ee49ccfb5a91298038825f700334a4 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 31 Jan 2024 14:42:54 +0100 Subject: [PATCH 029/423] Add tests --- .../rpgparser/interpreter/JarikoCallbackTest.kt | 14 ++++++++++++++ .../src/test/resources/ERROR11.rpgle | 6 ++++++ 2 files changed, 20 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/ERROR11.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt index f31d2826a..4ecc05607 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt @@ -397,6 +397,16 @@ class JarikoCallbackTest : AbstractTest() { executeSourceLineTest("ERROR10") } + @Test + fun executeERROR11CallBackTest() { + executePgmCallBackTest("ERROR11", SourceReferenceType.Program, "ERROR11", listOf(5)) + } + + @Test + fun executeERROR11SourceLineTest() { + executeSourceLineTest("ERROR11") + } + /** * This test simulates what a precompiler might do throws the use of the beforeParsing callback * In ERROR01.rpgle I will comment C specification to avoid a division by zero errors @@ -489,6 +499,10 @@ class JarikoCallbackTest : AbstractTest() { } } + /** + * Verify that the sourceLine is correctly set in case of error. + * ErrorEvent must contain a reference of an absolute line of the source code + * */ private fun executeSourceLineTest(pgm: String) { lateinit var lines: List val errorEvents = mutableListOf() diff --git a/rpgJavaInterpreter-core/src/test/resources/ERROR11.rpgle b/rpgJavaInterpreter-core/src/test/resources/ERROR11.rpgle new file mode 100644 index 000000000..b5f730c58 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/ERROR11.rpgle @@ -0,0 +1,6 @@ + V* ============================================================== + D* Missing implementation of the DOWLE opcode + D* + V* ============================================================== + C $B DOWLE 13 + C ENDDO \ No newline at end of file From 5cf54755bbbcdf144fec6c46017a46ecafdb6975 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 31 Jan 2024 14:44:30 +0100 Subject: [PATCH 030/423] Fix issue. It is good practice to use the ParserRuleContext.todo and ParserRuleContext.error extension functions for a better error handling --- .../com/smeup/rpgparser/parsing/parsetreetoast/statements.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 2aaf6ff52..166579e15 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -54,7 +54,7 @@ internal fun BlockContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) this.begindow() != null -> this.begindow().toAst(blockContext = this, conf = conf) this.forstatement() != null -> this.forstatement().toAst(conf) this.begindou() != null -> this.begindou().toAst(blockContext = this, conf = conf) - else -> TODO(this.text.toString() + " " + toPosition(conf.considerPosition)) + else -> todo(message = "Missing composite statement implementation for this block: ${this.text}", conf = conf) } } From 167a91886973d67e2ba2957d127943668b669fa8 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:32:50 +0000 Subject: [PATCH 031/423] remove test_tony temporary test --- .../evaluation/SmeupInterpreterTest.kt | 6 ------ .../src/test/resources/smeup/test_tony.rpgle | 21 ------------------- 2 files changed, 27 deletions(-) delete mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/test_tony.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 80d1988ae..73c3cb542 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -216,12 +216,6 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T40_A10_P01".outputOf(configuration = smeupConfig)) } - @Test - fun executeTestTony() { - val expected = listOf("") - assertEquals(expected, "smeup/test_tony".outputOf(configuration = smeupConfig)) - } - @Test fun executeT10_A60_P04() { val expected = listOf("C10_P1: MULANGT102") diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/test_tony.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/test_tony.rpgle deleted file mode 100644 index 1a9e16f66..000000000 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/test_tony.rpgle +++ /dev/null @@ -1,21 +0,0 @@ - FMULANGTF IF E DISK - D A10_DS_P04 E DS EXTNAME(MULANGTF) INZ PREFIX(P4:2) - * - D MYDS DS - D MLPROG - D MLPSEZ - * - D £DBG_Str S 50 - * - C READ MULANGTF 50 - * - C *IN50 IFEQ *OFF - C EVAL £DBG_Str= - C ' MYDS('+MYDS+')' - C +' MLPROG('+MLPROG+')' - C +' MLPSEZ('+MLPSEZ+')' - C +' P4PROG('+P4PROG+')' - C £DBG_Str DSPLY - C ENDIF - * - C SETON LR \ No newline at end of file From 640b8071114c786e6142bcfaf4e20f3eb9d7a4fb Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 1 Feb 2024 09:18:13 +0100 Subject: [PATCH 032/423] Improved solution. --- .../rpgparser/parsing/parsetreetoast/misc.kt | 32 +------------------ 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index c3a052c5e..2cf1e20b2 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -966,26 +966,6 @@ private fun annidatedReferenceExpression( return expr as AssignableExpression } -private fun makeArrayAccessExpression(text: String, position: Position?): AssignableExpression { - var expr: Expression = text.indexOf("(").let { - val varName = if (it == -1) text else text.substring(0, it) - DataRefExpr(ReferenceByName(varName), position) - } - - val indexText = text.substring(text.indexOf("(") + 1, text.lastIndexOf(")")) - val indexValue = indexText.toLongOrNull() - - val indexExpression = - if (indexValue == null) { - DataRefExpr(ReferenceByName(indexText), computeNewPosition(position, text)) - } else { - IntLiteral(indexValue, computeNewPosition(position, text)) - } - expr = ArrayAccessExpr(expr, indexExpression) - - return expr -} - private fun computeNewPosition(position: Position?, text: String) = if (position == null) { null @@ -1400,18 +1380,8 @@ internal fun CsZ_ADDContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( val position = toPosition(conf.considerPosition) val name = this.cspec_fixed_standard_parts().result.text val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("Z-ADD operation requires factor 2: ${this.text} - ${position.atLine()}") - - // Result Field could be an array, array element, field, subfield, or table name. (https://www.ibm.com/docs/en/i/7.5?topic=codes-z-add-zero-add) - // The REGEX to check if it is an array element is: ^[a-zA-z£_]+[a-zA-Z0-9£_]*(\(0\)|(\([1-9]+[0-9]*\)))$. You can test and improve it with https://www.regex101.com. - val resultExpression = when { - // TODO Add cases for array, subfield, table name. - // ARRAY ELEMENT - name.matches(Regex("^[a-zA-z£_]+[a-zA-Z0-9£_]*(\\(0\\)|(\\([1-9]+[0-9]*\\)))\$")) -> makeArrayAccessExpression(name, position) - // FIELD - else -> DataRefExpr(ReferenceByName(name), position) - } val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(name, position, conf) - return ZAddStmt(resultExpression, dataDefinition, expression, position) + return ZAddStmt(this.cspec_fixed_standard_parts().result.toAst(conf), dataDefinition, expression, position) } internal fun CsMULTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MultStmt { From 70b022fd1305e6b9aa2e9bed6aee50944595ba25 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 1 Feb 2024 11:00:01 +0100 Subject: [PATCH 033/423] Removed unhelpful test --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 4 ---- .../src/test/resources/smeup/T10_A20_P19F.rpgle | 10 ---------- 2 files changed, 14 deletions(-) delete mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19F.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 2d2333ce3..3ece39f49 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -224,9 +224,5 @@ open class SmeupInterpreterTest : AbstractTest() { fun executeT10_A20_P19() { val expected = listOf("1020") assertEquals(expected, "smeup/T10_A20_P19".outputOf()) - - assertFailsWith { - "smeup/T10_A20_P19F".outputOf() - } } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19F.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19F.rpgle deleted file mode 100644 index c649bebe6..000000000 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P19F.rpgle +++ /dev/null @@ -1,10 +0,0 @@ - D £DBG_Str S 50 VARYING - D A20_AR1 S 2 0 DIM(2) - *************************************************************************** - C Z-ADD 10 A20_AR1(1 - C Z-ADD 20 A20_AR12) - C EVAL £DBG_Str=%CHAR(A20_AR1(1)) - C +%CHAR(A20_AR1(2)) - * EXPECTED: 1020 - C £DBG_Str DSPLY - C SETON LR \ No newline at end of file From c02dddcb7391a0215f2cc116354484bc2720d1a9 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 1 Feb 2024 11:03:45 +0100 Subject: [PATCH 034/423] Changed `UnsupportedOperationException` to `this.todo` --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 2cf1e20b2..d8102479e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1379,7 +1379,7 @@ internal fun CsMOVELContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( internal fun CsZ_ADDContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): ZAddStmt { val position = toPosition(conf.considerPosition) val name = this.cspec_fixed_standard_parts().result.text - val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("Z-ADD operation requires factor 2: ${this.text} - ${position.atLine()}") + val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: this.todo(message = "Z-ADD operation requires factor 2: ${this.text} - ${position.atLine()}", conf) val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(name, position, conf) return ZAddStmt(this.cspec_fixed_standard_parts().result.toAst(conf), dataDefinition, expression, position) } From 5f4f2dec1d37652aa7d46e10e7db3838b8d4d477 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 1 Feb 2024 16:33:33 +0100 Subject: [PATCH 035/423] Fixed SCAN when is passed a literal as Factor 1. --- .../smeup/rpgparser/parsing/ast/statements.kt | 1 + .../rpgparser/parsing/parsetreetoast/misc.kt | 7 ++- .../evaluation/SmeupInterpreterTest.kt | 10 ++++ .../test/resources/smeup/T15_A20_P04-06.rpgle | 46 +++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T15_A20_P04-06.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 27a513566..d1532c8b0 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1618,6 +1618,7 @@ data class ScanStmt( } while (index >= 0) if (occurrences.isEmpty()) { interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.FALSE, BooleanValue.FALSE) + interpreter.assign(target, IntValue(0)) } else { interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.FALSE, BooleanValue.TRUE) if (target.type().isArray()) { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index d8102479e..d89d7dd80 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1326,6 +1326,8 @@ private fun FactorContext.toIndexedExpression(conf: ToAstConfiguration): Pair { + fun String.isLiteral(): Boolean { return (startsWith('\'') && endsWith('\'')) } + val baseStringTokens = this.split(":") val startPosition = when (baseStringTokens.size) { @@ -1334,7 +1336,10 @@ private fun String.toIndexedExpression(position: Position?): Pair null } val reference = baseStringTokens[0] - return DataRefExpr(ReferenceByName(reference), position) to startPosition + return when { + reference.isLiteral() -> StringLiteral(reference.trim('\''), position) + else -> DataRefExpr(ReferenceByName(reference), position) + } to startPosition } internal fun CsMOVEAContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MoveAStmt { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 3ece39f49..29e819686 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -225,4 +225,14 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("1020") assertEquals(expected, "smeup/T10_A20_P19".outputOf()) } + + @Test + fun executeT15_A20_P04_06() { + val expected = listOf( + "RicercaDaPos01(1)_Trovato(1); RicercaDaPos02(5)_Trovato(1); RicercaDaPos05(5)_Trovato(1); RicercaDaPos07(0)_Trovato(0);", + "RicercaDaPos01(5)_Trovato(1); RicercaDaPos01(1)_Trovato(1); RicercaDaPos01(5)_Trovato(1);", + "RicercaDaPos01(2)_Trovato(1);" + ) + assertEquals(expected, "smeup/T15_A20_P04-06".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A20_P04-06.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A20_P04-06.rpgle new file mode 100644 index 000000000..2e9768445 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A20_P04-06.rpgle @@ -0,0 +1,46 @@ + D A20_A20A S 20 INZ('!ABC!ABCDEF') + D A20_N20R S 2 0 + D £DBG_Str S 100 VARYING + + C SETOFF 202122 + C '!':1 SCAN A20_A20A A20_N20R 20 + C EVAL £DBG_Str='RicercaDaPos01(' + C +%CHAR(A20_N20R) + C +')_Trovato('+%CHAR(*IN20)+');' + C '!':1 SCAN A20_A20A:2 A20_N20R 21 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' RicercaDaPos02('+%CHAR(A20_N20R) + C +')_Trovato('+%CHAR(*IN21)+');' + C '!':1 SCAN A20_A20A:5 A20_N20R 22 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' RicercaDaPos05('+%CHAR(A20_N20R) + C +')_Trovato('+%CHAR(*IN22)+');' + C SETOFF 20 + C '!':1 SCAN A20_A20A:7 A20_N20R 20 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' RicercaDaPos07('+%CHAR(A20_N20R) + C +')_Trovato('+%CHAR(*IN20)+');' + C £DBG_Str DSPLY + + C SETOFF 202122 + C '!ABCD' SCAN A20_A20A A20_N20R 20 + C EVAL £DBG_Str='RicercaDaPos01(' + C +%CHAR(A20_N20R) + C +')_Trovato('+%CHAR(*IN20)+');' + C '!ABCD':2 SCAN A20_A20A A20_N20R 21 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' RicercaDaPos01('+%CHAR(A20_N20R) + C +')_Trovato('+%CHAR(*IN21)+');' + C '!ABCD':5 SCAN A20_A20A A20_N20R 22 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' RicercaDaPos01('+%CHAR(A20_N20R) + C +')_Trovato('+%CHAR(*IN22)+');' + C £DBG_Str DSPLY + + + C SETOFF 20 + C '!':1 SCAN '?!/' NW20_N20 2 0 20 + C EVAL £DBG_Str='RicercaDaPos01(' + C +%CHAR(NW20_N20) + C +')_Trovato('+%CHAR(*IN20)+');' + C £DBG_Str DSPLY \ No newline at end of file From 7b6df7b7071ecdae1634d361eb2023c2ac742166 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 2 Feb 2024 15:00:55 +0000 Subject: [PATCH 036/423] fix StringType length size in case of varying, fix duplicated fields in DS definition, wrong size of "entireDigits" of packed fields in metadata json file Note: I modified the file MULANGTF manually but the wrong size of "entireDigits" of packed fields in metadata json file will require an addition bug fixing activity to be definitely resolved. In fact, there is an external program that generates metadata json files. --- .../com/smeup/rpgparser/interpreter/data_definitions.kt | 2 +- .../kotlin/com/smeup/rpgparser/interpreter/typesystem.kt | 2 +- .../rpgparser/parsing/parsetreetoast/data_definitions.kt | 8 +++++++- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 2 +- .../src/test/resources/smeup/T40_A10_P01.rpgle | 2 +- .../src/test/resources/smeup/metadata/MULANGTF.json | 4 ++-- 6 files changed, 13 insertions(+), 7 deletions(-) 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 7221e378a..815d5f67a 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 @@ -120,7 +120,7 @@ enum class ParamOption(val keyword: String) { * PREFIX node * */ @Serializable -data class Prefix(private val prefix: String, private val numCharsReplaced: Int?) { +data class Prefix(internal val prefix: String, private val numCharsReplaced: Int?) { /** * Apply replacement rules and returns value converted 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 664e5f5bd..26690a014 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 @@ -113,7 +113,7 @@ data class OccurableDataStructureType(val dataStructureType: DataStructureType, @Serializable data class StringType(val length: Int, val varying: Boolean = false) : Type() { override val size: Int - get() = length + get() = if (varying) length + 2 else length // varying type get 2 additional bytes containing the size of the data /** * Creates an instance of StringType in according to [FeatureFlag.UnlimitedStringTypeFlag] 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 b77cbf70c..729d0e8ce 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 @@ -1009,6 +1009,10 @@ internal fun RpgParser.Dcl_dsContext.getKeywordExtName() = this.keyword().first internal fun RpgParser.Keyword_extnameContext.getExtName() = file_name.text +internal fun RpgParser.Dcl_dsContext.getKeywordPrefix() = this.keyword().firstOrNull { it.keyword_prefix() != null }?.keyword_prefix() + +internal fun RpgParser.Keyword_prefixContext.getPrefixName() = prefix.text + internal fun RpgParser.Dcl_dsContext.toAstWithExtName( conf: ToAstConfiguration = ToAstConfiguration(), fileDefinitions: Map> @@ -1016,7 +1020,9 @@ internal fun RpgParser.Dcl_dsContext.toAstWithExtName( return { val keywordExtName = getKeywordExtName() val extName = keywordExtName.getExtName() - val dataDefinitions = fileDefinitions.filter { it.key.name == extName }.values.flatten() + val keywordPrefix = getKeywordPrefix() + val prefixName = keywordPrefix?.getPrefixName() + val dataDefinitions = fileDefinitions.filter { it.key.name == extName && ((keywordPrefix == null && it.key.prefix == null) || (keywordPrefix != null && it.key.prefix != null && it.key.prefix is Prefix && it.key.prefix!!.prefix == prefixName)) }.values.flatten() if (dataDefinitions.isEmpty()) { keywordExtName.error(message = "Datadefinition $extName not found", conf = conf) } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 73c3cb542..17139458d 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -212,7 +212,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT40_A10_P01() { - val expected = listOf("") + val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - - - - - - -.000000000-.000000000- -0- -0-0- -0") assertEquals(expected, "smeup/T40_A10_P01".outputOf(configuration = smeupConfig)) } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P01.rpgle index 6877a6118..4a9388630 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P01.rpgle @@ -3,7 +3,7 @@ D A10_DS_P04 E DS EXTNAME(MULANGTF) INZ D PREFIX(P4:2) * - D £DBG_Str S 2580 + D £DBG_Str S 2595 * C EVAL £DBG_Str='Lunghezza: ' C +%CHAR(%LEN(A10_DS_P01)) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MULANGTF.json b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MULANGTF.json index 936e72860..ba01e547e 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MULANGTF.json +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MULANGTF.json @@ -103,7 +103,7 @@ "fieldName": "MLNNAT", "type": { "type": "com.smeup.rpgparser.interpreter.NumberType", - "entireDigits": 30, + "entireDigits": 21, "decimalDigits": 9, "rpgType": "P" } @@ -112,7 +112,7 @@ "fieldName": "MLNNVA", "type": { "type": "com.smeup.rpgparser.interpreter.NumberType", - "entireDigits": 30, + "entireDigits": 21, "decimalDigits": 9, "rpgType": "P" } From f0259a65f6bfbca559b01833ef0391fe279e52b3 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 2 Feb 2024 16:55:39 +0100 Subject: [PATCH 037/423] First idea about fix. --- .../parsing/parsetreetoast/expressions.kt | 6 +++++ .../evaluation/SmeupInterpreterTest.kt | 9 +++++++ .../test/resources/smeup/T03_A10_P09-10.rpgle | 27 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle 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 ab2c6dcd6..950d9c874 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 @@ -44,6 +44,7 @@ fun RpgParser.ExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfigurat this.MULT() != null || this.MULT_NOSPACE() != null -> MultExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) this.DIV() != null -> DivExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) this.EXP() != null -> ExpExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) + this.indicator() != null -> (this.children[0] as RpgParser.IndicatorContext).toAst(conf) // FIXME it is rather ugly that we have to do this: we should get a different parse tree here this.children.size == 3 && this.children[0].text == "(" && this.children[2].text == ")" && this.children[1] is RpgParser.ExpressionContext -> (this.children[1] as RpgParser.ExpressionContext).toAst(conf) @@ -51,6 +52,11 @@ fun RpgParser.ExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfigurat } } +internal fun RpgParser.IndicatorContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): IndicatorExpr { + // TODO: + return IndicatorExpr(1) +} + internal fun RpgParser.LiteralContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): StringLiteral { /* diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 3ece39f49..a2617dd67 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -225,4 +225,13 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("1020") assertEquals(expected, "smeup/T10_A20_P19".outputOf()) } + + @Test + fun executeT03_A10_P09_10() { + val expected = listOf( + "I(15)=0 I(15)=1 I(15)=0", + "*IN(n)->000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ) + assertEquals(expected, "smeup/T03_A10_P09-10".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle new file mode 100644 index 000000000..3babff444 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle @@ -0,0 +1,27 @@ + D $IND S 2 0 + D £DBG_Str S 110 VARYING + + D* Indicatori come array con indice n *IN(n) + C SETOFF 15 + C EVAL $IND=15 + C EVAL £DBG_Str='I('+%CHAR($IND)+')=' + C +%CHAR(*IN($IND)) + C £DBG_Str DSPLY + + C EVAL *IN($IND)=*ON + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' I('+%CHAR($IND)+')=' + C +%CHAR(*IN($IND)) + C EVAL *IN($IND)=*OFF + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' I('+%CHAR($IND)+')=' + C +%CHAR(*IN($IND)) + C £DBG_Str DSPLY + D Indicatori come array con indice n *IN(n) + C EVAL £DBG_Str='*IN(n)->' + C EVAL $IND=1 + C DO 99 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +%CHAR(*IN($IND)) + C ENDDO + C £DBG_Str DSPLY From ed2bfead76db5150b2ccf11ef250772b0683b67c Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 5 Feb 2024 15:29:44 +0100 Subject: [PATCH 038/423] Add draft of *IN() implementation --- .../rpgparser/interpreter/ExpressionEvaluation.kt | 8 ++++++-- .../com/smeup/rpgparser/parsing/ast/indicators.kt | 13 +++++++++++-- .../parsing/parsetreetoast/expressions.kt | 14 ++++++++------ .../smeup/rpgparser/evaluation/InterpreterTest.kt | 6 ++++++ .../src/test/resources/INDIC01.rpgle | 15 +++++++++++++++ 5 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/INDIC01.rpgle 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 977bea098..fce6cd237 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 @@ -27,8 +27,8 @@ import com.strumenta.kolasu.model.specificProcess import java.math.BigDecimal import java.math.MathContext import java.math.RoundingMode -import java.time.temporal.ChronoUnit import java.time.ZoneId +import java.time.temporal.ChronoUnit import kotlin.math.abs import kotlin.math.sqrt @@ -418,7 +418,11 @@ class ExpressionEvaluation( } override fun eval(expression: OffRefExpr) = BooleanValue.FALSE - override fun eval(expression: IndicatorExpr) = interpreterStatus.indicator(expression.index) + override fun eval(expression: IndicatorExpr): BooleanValue { + // if index is passed through expression, it means that it is a dynamic indicator + val runtimeIndex = expression.indexExpression?.evalWith(this)?.asInt()?.value?.toInt() ?: expression.index + return interpreterStatus.indicator(runtimeIndex) + } override fun eval(expression: FunctionCall): Value { val functionToCall = expression.function.name val function = systemInterface.findFunction(interpreterStatus.symbolTable, functionToCall) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt index c2285745a..450939bb2 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt @@ -8,12 +8,21 @@ import kotlinx.serialization.Serializable // *IN01..*IN99 and *INLR *INRT @Serializable -data class IndicatorExpr(val index: IndicatorKey, override val position: Position? = null) : - AssignableExpression(position) { +data class IndicatorExpr( + val index: IndicatorKey, + override val position: Position? = null, + val indexExpression: Expression? = null +) : AssignableExpression(position) { constructor(dataWrapUpChoice: DataWrapUpChoice, position: Position? = null) : this(index = dataWrapUpChoice.name.toIndicatorKey(), position = position) + /** + * Constructor for *IN where the index is an expression + * */ + constructor(index: Expression, position: Position?) : + this(index = 0, position = position, indexExpression = index) + override fun size(): Int = 1 override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } 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 950d9c874..8535d94ac 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 @@ -44,17 +44,19 @@ fun RpgParser.ExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfigurat this.MULT() != null || this.MULT_NOSPACE() != null -> MultExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) this.DIV() != null -> DivExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) this.EXP() != null -> ExpExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) - this.indicator() != null -> (this.children[0] as RpgParser.IndicatorContext).toAst(conf) - // FIXME it is rather ugly that we have to do this: we should get a different parse tree here - this.children.size == 3 && this.children[0].text == "(" && this.children[2].text == ")" - && this.children[1] is RpgParser.ExpressionContext -> (this.children[1] as RpgParser.ExpressionContext).toAst(conf) + this.indicator() != null -> this.indicator().toAst(conf) else -> todo(conf = conf) } } internal fun RpgParser.IndicatorContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): IndicatorExpr { - // TODO: - return IndicatorExpr(1) + // manage *IN( + if (this.children[0].text == "*IN" && this.children[1].text == "(") { + val index: Expression = (this.children[2].getChild(0) as RpgParser.ExpressionContext).toAst(conf = conf) + return IndicatorExpr(index = index, position = toPosition(conf.considerPosition)) + } else { + todo(conf = conf) + } } internal fun RpgParser.LiteralContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): StringLiteral { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index d1a6143df..9813d7657 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2210,4 +2210,10 @@ Test 6 "001000000000000000000000000000000000000000010000000000000000000000000000000000000000000100000000000") assertEquals(expected, "MOVEAIN".outputOf()) } + + @Test + fun executeINDIC01() { + val expected = listOf("0", "1") + assertEquals(expected, "INDIC01".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/INDIC01.rpgle b/rpgJavaInterpreter-core/src/test/resources/INDIC01.rpgle new file mode 100644 index 000000000..14235d43c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/INDIC01.rpgle @@ -0,0 +1,15 @@ + D $IND S 2 0 + D MSG S 10 VARYING + + C EVAL $IND=15 + + * Turn off the indicator 15 and display the value of the indicator + C SETOFF 15 + C EVAL MSG=%CHAR(*IN($IND)) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator 15 and display the value of the indicator + C SETON 15 + C EVAL MSG=%CHAR(*IN($IND)) + * Expected: 1 + C MSG DSPLY \ No newline at end of file From cabff95c9e1f848c23907db6952b67213a0a33f2 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 5 Feb 2024 15:54:20 +0100 Subject: [PATCH 039/423] Created test --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 7 +++++++ .../src/test/resources/smeup/T02_A60_P02.rpgle | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 45ecaf266..b793bcc5c 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -284,4 +284,11 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("1020") assertEquals(expected, "smeup/T10_A20_P19".outputOf()) } + + @Test + fun executeT02_A60_P02() { +// assertASTCanBeProduced("smeup/T02_A60_P02") + val expected = listOf("Res(A*B+C)=246; Res(A * B + C)=246") + assertEquals(expected, "smeup/T02_A60_P02".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P02.rpgle new file mode 100644 index 000000000..d5104a9a0 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P02.rpgle @@ -0,0 +1,10 @@ + D SCALA S 3 0 + D A60_N30B S 3 0 + D £DBG_Str S 100 VARYING + C EVAL SCALA=10 + C EVAL A60_N30B=24*SCALA+6 + C EVAL £DBG_Str='Res(A*B+C)='+%CHAR(A60_N30B) + C EVAL A60_N30B = 24 * SCALA + 6 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +'; Res(A * B + C)='+%CHAR(A60_N30B) + C £DBG_Str DSPLY \ No newline at end of file From 2b4c370409ba5ace6580e02a899bab18be9cc270 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 5 Feb 2024 15:57:58 +0100 Subject: [PATCH 040/423] Revert a piece of code removed by error --- .../com/smeup/rpgparser/parsing/parsetreetoast/expressions.kt | 3 +++ 1 file changed, 3 insertions(+) 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 8535d94ac..96957ed45 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 @@ -45,6 +45,9 @@ fun RpgParser.ExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfigurat this.DIV() != null -> DivExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) this.EXP() != null -> ExpExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) this.indicator() != null -> this.indicator().toAst(conf) + // FIXME it is rather ugly that we have to do this: we should get a different parse tree here + this.children.size == 3 && this.children[0].text == "(" && this.children[2].text == ")" + && this.children[1] is RpgParser.ExpressionContext -> (this.children[1] as RpgParser.ExpressionContext).toAst(conf) else -> todo(conf = conf) } } From 9c42c45c53559bc42c0b4fba4f944d1acf142381 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 5 Feb 2024 16:34:57 +0100 Subject: [PATCH 041/423] Created a case where the start point is higher than length of word. --- .../com/smeup/rpgparser/evaluation/InterpreterTest.kt | 2 +- rpgJavaInterpreter-core/src/test/resources/SCANTEST.rpgle | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index d1a6143df..f35866816 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -1104,7 +1104,7 @@ Test 6 @Test fun executeSCANTEST() { - assertEquals(listOf("0", "4", "1", "5", "0"), "SCANTEST".outputOf()) + assertEquals(listOf("0", "4", "1", "5", "0", "0"), "SCANTEST".outputOf()) } @Test diff --git a/rpgJavaInterpreter-core/src/test/resources/SCANTEST.rpgle b/rpgJavaInterpreter-core/src/test/resources/SCANTEST.rpgle index 2a7fce4d6..242fd0b36 100644 --- a/rpgJavaInterpreter-core/src/test/resources/SCANTEST.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/SCANTEST.rpgle @@ -31,5 +31,12 @@ * Expected 0 because the search starts from 2nd character * for three characters: 'r. ' C dsply Msg + ********************************************************************* + * Test with start higher than length of word. + C EVAL $$SVAR='Dr. Doolittle' + C EVAL $BRACK=%SCAN('e':$$SVAR:14) + C Eval Msg = %CHAR($BRACK) + * Expected 0 the value of start higher than length of word. + C dsply Msg ********************************************************************* C SETON LR From e0f315f2b3de60e2bee08e96a964adcf9c11575f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 7 Feb 2024 11:55:39 +0100 Subject: [PATCH 042/423] Fixed access to *IN with a dynamic expression --- .../src/main/antlr/RpgLexer.g4 | 3 ++- .../rpgparser/interpreter/internal_interpreter.kt | 3 ++- .../parsing/parsetreetoast/expressions.kt | 13 ++++++++++++- .../rpgparser/parsing/parsetreetoast/misc.kt | 15 +++++++++++---- .../src/test/resources/smeup/T03_A10_P09-10.rpgle | 9 ++++----- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 index cacccaf10..0184c5bc3 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 @@ -319,7 +319,8 @@ SPLAT_INIT: '*'[iI][nN][iI][tT]; SPLAT_ALL_INDICATORS: '*' [iI] [nN] [ ] [ ]; SPLAT_INDICATOR : ( '*' [iI] [nN] [0-9] [0-9] | '*' [iI] [nN] [a-zA-Z] [a-zA-Z] - | '*' [iI] [nN] '(' [0-9] [0-9] ')' ); + | '*' [iI] [nN] '(' [0-9] [0-9] ')' + | '*' [iI] [nN] '(' [§£#@$a-zA-Z]+ ')' ); SPLAT_INZSR: '*'[iI][nN][zZ][sS][rR]; SPLAT_IN: '*'[iI][nN]; SPLAT_INPUT: '*'[iI][nN][pP][uU][tT]; diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 69403a002..b225dc9a4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -843,8 +843,9 @@ open class InternalInterpreter( return value } is IndicatorExpr -> { + val index = target.indexExpression?.let { eval(it).asInt().value.toInt() } ?: target.index val coercedValue = coerce(value, BooleanType) - indicators[target.index] = coercedValue.asBoolean() + indicators[index] = coercedValue.asBoolean() return coercedValue } is GlobalIndicatorExpr -> { 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 96957ed45..2a025f162 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 @@ -58,7 +58,8 @@ internal fun RpgParser.IndicatorContext.toAst(conf: ToAstConfiguration = ToAstCo val index: Expression = (this.children[2].getChild(0) as RpgParser.ExpressionContext).toAst(conf = conf) return IndicatorExpr(index = index, position = toPosition(conf.considerPosition)) } else { - todo(conf = conf) + val index = text.uppercase(Locale.getDefault()).removePrefix("*IN").toInt() + return IndicatorExpr(index = index, position = toPosition(conf.considerPosition)) } } @@ -140,6 +141,7 @@ internal fun RpgParser.IdentifierContext.toAst(conf: ToAstConfiguration = ToAstC private fun RpgParser.IdentifierContext.variableExpression(conf: ToAstConfiguration): Expression { return when { + this.text.dynamicIndicatorIndex(toPosition(conf.considerPosition)) != null -> IndicatorExpr(this.text.dynamicIndicatorIndex(toPosition(conf.considerPosition))!!, toPosition(conf.considerPosition)) this.text.indicatorIndex() != null -> IndicatorExpr(this.text.indicatorIndex()!!, toPosition(conf.considerPosition)) this.multipart_identifier() != null -> this.multipart_identifier().toAst(conf) else -> DataRefExpr(variable = ReferenceByName(this.text), position = toPosition(conf.considerPosition)) @@ -189,6 +191,15 @@ internal fun RpgParser.Multipart_identifier_elementContext.toAst(conf: ToAstConf } } +internal fun String.dynamicIndicatorIndex(position: Position?): Expression? { + val uCaseIndicatorString = this.toUpperCase() + return when { + uCaseIndicatorString.matches(Regex("\\*IN\\([§£#@\$a-zA-Z]+\\)")) -> + DataRefExpr(ReferenceByName(uCaseIndicatorString.removePrefix("*IN(").removeSuffix(")")), position) + else -> null + } +} + internal fun String.indicatorIndex(): Int? { val uCaseIndicatorString = this.toUpperCase() return when { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index d8102479e..4d5980966 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1587,10 +1587,17 @@ internal fun TargetContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() ReferenceByName(this.getFieldName()), toPosition(conf.considerPosition) ) - is IndicatorTargetContext -> IndicatorExpr( - this.indic.text.indicatorIndex()!!, - toPosition(conf.considerPosition) - ) + is IndicatorTargetContext -> { + if (this.indic.text.matches(Regex("\\*IN\\([§£#@\$a-zA-Z]+\\)"))) { + val index: Expression = DataRefExpr(ReferenceByName(this.indic.text.removePrefix("*IN(").removeSuffix(")")), toPosition(conf.considerPosition)) + return IndicatorExpr(index = index, position = toPosition(conf.considerPosition)) + } + + return IndicatorExpr( + this.indic.text.indicatorIndex()!!, + toPosition(conf.considerPosition) + ) + } is GlobalIndicatorTargetContext -> GlobalIndicatorExpr( toPosition(conf.considerPosition) ) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle index 3babff444..f7cdf8071 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle @@ -6,18 +6,17 @@ C EVAL $IND=15 C EVAL £DBG_Str='I('+%CHAR($IND)+')=' C +%CHAR(*IN($IND)) - C £DBG_Str DSPLY - C EVAL *IN($IND)=*ON C EVAL £DBG_Str=%TRIM(£DBG_Str) C +' I('+%CHAR($IND)+')=' C +%CHAR(*IN($IND)) C EVAL *IN($IND)=*OFF C EVAL £DBG_Str=%TRIM(£DBG_Str) - C +' I('+%CHAR($IND)+')=' - C +%CHAR(*IN($IND)) + C +' I('+%CHAR($IND)+')=' + C +%CHAR(*IN($IND)) C £DBG_Str DSPLY - D Indicatori come array con indice n *IN(n) + + D* Indicatori come array con indice n *IN(n) C EVAL £DBG_Str='*IN(n)->' C EVAL $IND=1 C DO 99 From 4409cb95d700ad3f440674dc0c04ecbc2b2bc1aa Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 7 Feb 2024 12:15:22 +0100 Subject: [PATCH 043/423] Add test --- .../src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt | 5 +++++ .../src/test/resources/QILEGEN/CP\302\24701.rpgle" | 5 +++++ rpgJavaInterpreter-core/src/test/resources/TSTCPY08.rpgle | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 "rpgJavaInterpreter-core/src/test/resources/QILEGEN/CP\302\24701.rpgle" create mode 100644 rpgJavaInterpreter-core/src/test/resources/TSTCPY08.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt index 4f9257c63..5e3a182a6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt @@ -437,6 +437,11 @@ class CopyTest { testCpyInclusion("TSTCPY07", "I am copy with .api extension") } + @Test + fun `includeCP§01`() { + testCpyInclusion("TSTCPY08", "Hi I am QILEGEN,CP§01") + } + @Test fun includeNotFoundCopy() { var catchedErrorEvent: ErrorEvent? = null diff --git "a/rpgJavaInterpreter-core/src/test/resources/QILEGEN/CP\302\24701.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/CP\302\24701.rpgle" new file mode 100644 index 000000000..adb366464 --- /dev/null +++ "b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/CP\302\24701.rpgle" @@ -0,0 +1,5 @@ + V* ============================================================== + D* 07/02/24 v1.r1 lanmam + V* ============================================================== + C EVAL MSGCPY='Hi I am QILEGEN,CP§01' + C MSGCPY DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/TSTCPY08.rpgle b/rpgJavaInterpreter-core/src/test/resources/TSTCPY08.rpgle new file mode 100644 index 000000000..972237e10 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/TSTCPY08.rpgle @@ -0,0 +1,5 @@ + V* ============================================================== + D* Program that includes a copy with this character § in the name + V* ============================================================== + D MSGCPY S 30 + T > /COPY QILEGEN,CP§01 \ No newline at end of file From b56bd1be6ae9d56129f87eec639125cb03f11043 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 7 Feb 2024 12:18:00 +0100 Subject: [PATCH 044/423] Fix pattern used to convert a String in an instance of CopyId --- .../src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt index 75881b075..5532c9be2 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt @@ -91,7 +91,7 @@ private fun String.includesCopy( } @JvmField -val PATTERN: Pattern = Pattern.compile(".{6}/(?:COPY|INCLUDE)\\s+((?:\\w|£|\\$|,)+)|(.{6}\\*.+)", Pattern.CASE_INSENSITIVE) +val PATTERN: Pattern = Pattern.compile(".{6}/(?:COPY|INCLUDE)\\s+((?:\\w|£|\\$|§|,)+)|(.{6}\\*.+)", Pattern.CASE_INSENSITIVE) fun String.copyId(): CopyId { return when { From 867efb0a59ae07875258fec264ecc9316673144b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 8 Feb 2024 12:49:54 +0100 Subject: [PATCH 045/423] Fixed parsing. Now is considered the argument as an expression, and not only a DataRefExpr. --- .../src/main/antlr/RpgLexer.g4 | 4 +- .../src/main/antlr/RpgParser.g4 | 1 + .../parsing/parsetreetoast/expressions.kt | 14 +- .../rpgparser/parsing/parsetreetoast/misc.kt | 17 +-- .../rpgparser/evaluation/InterpreterTest.kt | 8 +- .../src/test/resources/INDIC01.rpgle | 128 +++++++++++++++++- .../src/test/resources/INDIC02.rpgle | 82 +++++++++++ 7 files changed, 225 insertions(+), 29 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/INDIC02.rpgle diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 index 0184c5bc3..d07bcd760 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 @@ -318,9 +318,7 @@ SPLAT_HIVAL: '*'[hH][iI][vV][aA][lL]; SPLAT_INIT: '*'[iI][nN][iI][tT]; SPLAT_ALL_INDICATORS: '*' [iI] [nN] [ ] [ ]; SPLAT_INDICATOR : ( '*' [iI] [nN] [0-9] [0-9] - | '*' [iI] [nN] [a-zA-Z] [a-zA-Z] - | '*' [iI] [nN] '(' [0-9] [0-9] ')' - | '*' [iI] [nN] '(' [§£#@$a-zA-Z]+ ')' ); + | '*' [iI] [nN] [a-zA-Z] [a-zA-Z] ); SPLAT_INZSR: '*'[iI][nN][zZ][sS][rR]; SPLAT_IN: '*'[iI][nN]; SPLAT_INPUT: '*'[iI][nN][pP][uU][tT]; diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index 601d94e5a..d5a1d2705 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -2646,5 +2646,6 @@ target: | bif_subarr #subarrTarget | container=idOrKeyword DOT fieldName=idOrKeyword #qualifiedTarget | indic=SPLAT_INDICATOR #indicatorTarget + | base=SPLAT_IN OPEN_PAREN index=expression CLOSE_PAREN #indexedIndicatorTarget | SPLAT_IN #globalIndicatorTarget ; 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 2a025f162..676c6937e 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 @@ -54,7 +54,7 @@ fun RpgParser.ExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfigurat internal fun RpgParser.IndicatorContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): IndicatorExpr { // manage *IN( - if (this.children[0].text == "*IN" && this.children[1].text == "(") { + if (this.children[0].text.uppercase() == "*IN" && this.children[1].text == "(") { val index: Expression = (this.children[2].getChild(0) as RpgParser.ExpressionContext).toAst(conf = conf) return IndicatorExpr(index = index, position = toPosition(conf.considerPosition)) } else { @@ -141,7 +141,6 @@ internal fun RpgParser.IdentifierContext.toAst(conf: ToAstConfiguration = ToAstC private fun RpgParser.IdentifierContext.variableExpression(conf: ToAstConfiguration): Expression { return when { - this.text.dynamicIndicatorIndex(toPosition(conf.considerPosition)) != null -> IndicatorExpr(this.text.dynamicIndicatorIndex(toPosition(conf.considerPosition))!!, toPosition(conf.considerPosition)) this.text.indicatorIndex() != null -> IndicatorExpr(this.text.indicatorIndex()!!, toPosition(conf.considerPosition)) this.multipart_identifier() != null -> this.multipart_identifier().toAst(conf) else -> DataRefExpr(variable = ReferenceByName(this.text), position = toPosition(conf.considerPosition)) @@ -191,20 +190,9 @@ internal fun RpgParser.Multipart_identifier_elementContext.toAst(conf: ToAstConf } } -internal fun String.dynamicIndicatorIndex(position: Position?): Expression? { - val uCaseIndicatorString = this.toUpperCase() - return when { - uCaseIndicatorString.matches(Regex("\\*IN\\([§£#@\$a-zA-Z]+\\)")) -> - DataRefExpr(ReferenceByName(uCaseIndicatorString.removePrefix("*IN(").removeSuffix(")")), position) - else -> null - } -} - internal fun String.indicatorIndex(): Int? { val uCaseIndicatorString = this.toUpperCase() return when { - uCaseIndicatorString.startsWith("*IN(") && this.endsWith(")") -> - uCaseIndicatorString.removePrefix("*IN(").removeSuffix(")").toIndicatorKey() uCaseIndicatorString.startsWith("*IN") -> this.substring("*IN".length).toIndicatorKey() else -> null diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index f902876e7..22e5b41c8 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1592,16 +1592,13 @@ internal fun TargetContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() ReferenceByName(this.getFieldName()), toPosition(conf.considerPosition) ) - is IndicatorTargetContext -> { - if (this.indic.text.matches(Regex("\\*IN\\([§£#@\$a-zA-Z]+\\)"))) { - val index: Expression = DataRefExpr(ReferenceByName(this.indic.text.removePrefix("*IN(").removeSuffix(")")), toPosition(conf.considerPosition)) - return IndicatorExpr(index = index, position = toPosition(conf.considerPosition)) - } - - return IndicatorExpr( - this.indic.text.indicatorIndex()!!, - toPosition(conf.considerPosition) - ) + is IndicatorTargetContext -> IndicatorExpr( + this.indic.text.indicatorIndex()!!, + toPosition(conf.considerPosition) + ) + is IndexedIndicatorTargetContext -> { + val index: Expression = this.index.toAst(conf = conf) + return IndicatorExpr(index = index, position = toPosition(conf.considerPosition)) } is GlobalIndicatorTargetContext -> GlobalIndicatorExpr( toPosition(conf.considerPosition) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 511334991..1425e8d06 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2213,7 +2213,13 @@ Test 6 @Test fun executeINDIC01() { - val expected = listOf("0", "1") + val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1") assertEquals(expected, "INDIC01".outputOf()) } + + @Test + fun executeINDIC02() { + val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1") + assertEquals(expected, "INDIC02".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/INDIC01.rpgle b/rpgJavaInterpreter-core/src/test/resources/INDIC01.rpgle index 14235d43c..c2bec7a38 100644 --- a/rpgJavaInterpreter-core/src/test/resources/INDIC01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/INDIC01.rpgle @@ -1,15 +1,139 @@ + * + * WORKING WITH INDICATOR 15 AND EXPRESSIONS + * + D $IND S 2 0 + D $I S 2 0 D MSG S 10 VARYING C EVAL $IND=15 + C EVAL $I=1 - * Turn off the indicator 15 and display the value of the indicator + * WITH SINGLE PARENTHESIS + * Turn off the indicator and display the value C SETOFF 15 C EVAL MSG=%CHAR(*IN($IND)) * Expected: 0 C MSG DSPLY - * Turn on the indicator 15 and display the value of the indicator + * Turn on the indicator and display the value C SETON 15 C EVAL MSG=%CHAR(*IN($IND)) * Expected: 1 + C MSG DSPLY + + + * WITH DOUBLE PARENTHESIS + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN(($IND))) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C SETON 15 + C EVAL MSG=%CHAR(*IN(($IND))) + * Expected: 1 + C MSG DSPLY + + + * WITH ASSIGNMENT + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN($IND)) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C EVAL *IN($IND)=*ON + C EVAL MSG=%CHAR(*IN($IND)) + * Expected: 1 + C MSG DSPLY + + + * WITH ASSIGNMENT AND DOUBLE PARENTHESIS + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN(($IND))) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C EVAL *IN(($IND))=*ON + C EVAL MSG=%CHAR(*IN(($IND))) + * Expected: 1 + C MSG DSPLY + + + * WITH ASSIGNMENT NUMERIC EXPRESSION AFTER VARIABLE + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN($IND+1-1)) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C EVAL *IN($IND+1-1)=*ON + C EVAL MSG=%CHAR(*IN($IND+1-1)) + * Expected: 1 + C MSG DSPLY + + + * WITH ASSIGNMENT NUMERIC EXPRESSION BEFORE VARIABLE + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN(1-1+$IND)) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C EVAL *IN(1-1+$IND)=*ON + C EVAL MSG=%CHAR(*IN(1-1+$IND)) + * Expected: 1 + C MSG DSPLY + + + * WITH ASSIGNMENT VARIABLES EXPRESSION, AFTER $IND + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN($IND+$I-$I)) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C EVAL *IN($IND+$I-$I)=*ON + C EVAL MSG=%CHAR(*IN($IND+$I-$I)) + * Expected: 1 + C MSG DSPLY + + + * WITH ASSIGNMENT VARIABLES EXPRESSION, BEFORE $IND + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN($I-$I+$IND)) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C EVAL *IN($I-$I+$IND)=*ON + C EVAL MSG=%CHAR(*IN($I-$I+$IND)) + * Expected: 1 + C MSG DSPLY + + + * WITH ASSIGNMENT MISC EXPRESSION, AFTER $IND + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN($IND+1-$I)) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C EVAL *IN($IND+1-$I)=*ON + C EVAL MSG=%CHAR(*IN($IND+1-$I)) + * Expected: 1 + C MSG DSPLY + + + * WITH ASSIGNMENT MISC EXPRESSION, BEFORE $IND + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN($I-1+$IND)) + * Expected: 0 + C MSG DSPLY + * Turn on the indicator and display the value + C EVAL *IN($I-1+$IND)=*ON + C EVAL MSG=%CHAR(*IN($I-1+$IND)) + * Expected: 1 C MSG DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/INDIC02.rpgle b/rpgJavaInterpreter-core/src/test/resources/INDIC02.rpgle new file mode 100644 index 000000000..682c907a0 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/INDIC02.rpgle @@ -0,0 +1,82 @@ + * + * WORKING WITH INDICATOR 15 AND DIRECT ACCESS + * + + D MSG S 10 VARYING + + * WITHOUT PARENTHESIS + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN15) + * Expected: 0 + C MSG DSPLY + * Turn off the indicator and display the value + C SETON 15 + C EVAL MSG=%CHAR(*IN15) + * Expected: 1 + C MSG DSPLY + + + * WITH PARENTHESIS + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN(15)) + * Expected: 0 + C MSG DSPLY + * Turn off the indicator and display the value + C SETON 15 + C EVAL MSG=%CHAR(*IN(15)) + * Expected: 1 + C MSG DSPLY + + + * WITH DOUBLE PARENTHESIS + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN((15))) + * Expected: 0 + C MSG DSPLY + * Turn off the indicator and display the value + C SETON 15 + C EVAL MSG=%CHAR(*IN((15))) + * Expected: 1 + C MSG DSPLY + + + * WITHOUT PARENTHESIS AND ASSIGNMENT + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN15) + * Expected: 0 + C MSG DSPLY + * Turn off the indicator and display the value + C EVAL *IN15=*ON + C EVAL MSG=%CHAR(*IN15) + * Expected: 1 + C MSG DSPLY + + + * WITH PARENTHESIS AND ASSIGNMENT + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN(15)) + * Expected: 0 + C MSG DSPLY + * Turn off the indicator and display the value + C EVAL *IN(15)=*ON + C EVAL MSG=%CHAR(*IN(15)) + * Expected: 1 + C MSG DSPLY + + + * WITH DOUBLE PARENTHESIS AND ASSIGNMENT + * Turn off the indicator and display the value + C SETOFF 15 + C EVAL MSG=%CHAR(*IN((15))) + * Expected: 0 + C MSG DSPLY + * Turn off the indicator and display the value + C EVAL *IN((15))=*ON + C EVAL MSG=%CHAR(*IN((15))) + * Expected: 1 + C MSG DSPLY \ No newline at end of file From b97ca19368fa2ee1b17cd397f7bb04159503d0e1 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Thu, 8 Feb 2024 14:45:35 +0000 Subject: [PATCH 046/423] fix CALL statement with variable field which belong to a DS with QUALIFIED keyword --- .../rpgparser/parsing/parsetreetoast/misc.kt | 31 ++++++- .../evaluation/SmeupInterpreterTest.kt | 16 +++- .../src/test/resources/smeup/MULANGTC30.rpgle | 12 +++ .../{T10_A60_P04.rpgle => T10_A60_P02.rpgle} | 0 ...{T10_A60_P04F.rpgle => T10_A60_P02F.rpgle} | 0 .../resources/smeup/T10_A60_P04-P07.rpgle | 88 +++++++++++++++++++ 6 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC30.rpgle rename rpgJavaInterpreter-core/src/test/resources/smeup/{T10_A60_P04.rpgle => T10_A60_P02.rpgle} (100%) rename rpgJavaInterpreter-core/src/test/resources/smeup/{T10_A60_P04F.rpgle => T10_A60_P02F.rpgle} (100%) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04-P07.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index d89d7dd80..1af5c184f 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -944,10 +944,24 @@ private fun annidatedReferenceExpression( val index = text.uppercase(Locale.getDefault()).removePrefix("*IN").toInt() return IndicatorExpr(index, position) } - var expr: Expression = text.indexOf("(").let { - val varName = if (it == -1) text else text.substring(0, it) - DataRefExpr(ReferenceByName(varName), position) + + var expr: Expression + if (text.contains(".")) { + val parts = text.split(".") + require(parts.isNotEmpty()) + val varName = if (parts.size == 1) { + parts[0] + } else { + parts.last() + } + expr = DataRefExpr(ReferenceByName(varName), position) + } else { + expr = text.indexOf("(").let { + val varName = if (it == -1) text else text.substring(0, it) + DataRefExpr(ReferenceByName(varName), position) + } } + if (text.contains("(")) { // TODO support annidated parenthesis, if necessary if (text.substring(text.indexOf("(") + 1).contains("(")) { @@ -1036,7 +1050,16 @@ internal fun CsPLISTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( } internal fun CsPARMContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): PlistParam { - val paramName = this.cspec_fixed_standard_parts().result.text + var paramName = this.cspec_fixed_standard_parts().result.text + if (paramName.contains(".")) { + val parts = paramName.split(".") + require(parts.isNotEmpty()) + if (parts.size == 1) { + paramName = parts[0] + } else { + 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) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index ba2eda66f..98c3f80bf 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -276,12 +276,12 @@ open class SmeupInterpreterTest : AbstractTest() { } @Test - fun executeT10_A60_P04() { + fun executeT10_A60_P02() { val expected = listOf("C10_P1: MULANGT102") - assertEquals(expected, "smeup/T10_A60_P04".outputOf()) + assertEquals(expected, "smeup/T10_A60_P02".outputOf()) assertFailsWith { - "smeup/T10_A60_P04F".outputOf() + "smeup/T10_A60_P02F".outputOf() } } @@ -300,4 +300,14 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T15_A20_P04-06".outputOf()) } + + @Test + fun executeT10_A60_P04_P07() { + val expected = listOf( + "CALL(MULANGTC30, 4 , 0)", + "CALL(MULANGTC30, 5 , 0)", + "CALL(MULANGTC30, 6 , 0)", + "CALL(MULANGTC30, 7 , 0)") + assertEquals(expected, "smeup/T10_A60_P04-P07".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC30.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC30.rpgle new file mode 100644 index 000000000..2c28d281c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/MULANGTC30.rpgle @@ -0,0 +1,12 @@ + D B10_P1 S 10 + D B10_P2 S 50 + * + D B10_A50 S 50 + *--------------------------------------------------------------------- + C *ENTRY PLIST + C PARM B10_P1 + C PARM B10_A50 B10_P2 + * + C EVAL B10_A50 ='PASSO: '+%TRIMR(B10_P1) + * + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P02.rpgle similarity index 100% rename from rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04.rpgle rename to rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04F.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P02F.rpgle similarity index 100% rename from rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04F.rpgle rename to rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P02F.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04-P07.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04-P07.rpgle new file mode 100644 index 000000000..5bd30e27b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P04-P07.rpgle @@ -0,0 +1,88 @@ + ************************************************************************** + D £DBG_Str S 50 Stringa + D £DBG_Pas S 50 Stringa + * + * T10_A60 + * with QUALIFIED keyword + D A60PDS DS QUALIFIED + D A60PGM 10 + D A60P4 10 + D A60P5 50 + * without QUALIFIED keyword + D A60_PDS DS + D A60_PGM 10 + D A60_P4 10 + D A60_P5 50 + * + C EXSR SEZ_T10_A60 + * + C SETON LR + *--------------------------------------------------------------- + RD* Errori programma MULANGT10 sezione A60 + *--------------------------------------------------------------* + C SEZ_T10_A60 BEGSR + * + OA* A£.CDOP(CALL;DS) + D* CALL a PGM in DS con parametri in input, risultato no indicatore + C EVAL *IN37=*OFF + C EVAL £DBG_Pas='P04' + C EVAL A60PDS.A60P4='4' + C EVAL A60PDS.A60P5=' ' + C EVAL A60PDS.A60PGM='MULANGTC30' + C CALL A60PDS.A60PGM + C PARM A60PDS.A60P4 + C PARM A60PDS.A60P5 + C EVAL £DBG_Str='CALL('+A60PDS.A60PGM+', ' + C +%CHAR(A60PDS.A60P4)+', ' + C +%CHAR(*IN37) + C +') ' + C £DBG_Str DSPLY + * + OA* A£.CDOP(CALL;DS) + D* CALL a PGM in DS con parametri in input, risultato si indicatore + C EVAL *IN37=*OFF + C EVAL £DBG_Pas='P05' + C EVAL A60PDS.A60P4='5' + C EVAL A60PDS.A60P5=' ' + C EVAL A60PDS.A60PGM='MULANGTC30' + C CALL A60PDS.A60PGM 37 + C PARM A60PDS.A60P4 + C PARM A60PDS.A60P5 + C EVAL £DBG_Str='CALL('+A60PDS.A60PGM+', ' + C +%CHAR(A60PDS.A60P4)+', ' + C +%CHAR(*IN37) + C +') ' + C £DBG_Str DSPLY + * + OA* A£.CDOP(CALL;DS) + D* CALL a PGM in DS con parametri in input, risultato no indicatore + C EVAL *IN37=*OFF + C EVAL £DBG_Pas='P06' + C EVAL A60_P4='6' + C EVAL A60_P5=' ' + C EVAL A60_PGM='MULANGTC30' + C CALL A60_PGM + C PARM A60_P4 + C PARM A60_P5 + C EVAL £DBG_Str='CALL('+A60_PGM+', ' + C +%CHAR(A60_P4)+', ' + C +%CHAR(*IN37) + C +') ' + C £DBG_Str DSPLY + * + OA* A£.CDOP(CALL;DS) + D* CALL a PGM in DS con parametri in input, risultato si indicatore + C EVAL *IN37=*OFF + C EVAL £DBG_Pas='P07' + C EVAL A60_P4='7' + C EVAL A60_P5=' ' + C EVAL A60_PGM='MULANGTC30' + C CALL A60_PGM 37 + C PARM A60_P4 + C PARM A60_P5 + C EVAL £DBG_Str='CALL('+A60_PGM+', ' + C +%CHAR(A60_P4)+', ' + C +%CHAR(*IN37) + C +') ' + C £DBG_Str DSPLY + C ENDSR From 51fe6bb5cab7d6b42cd81c6246342fd06868a4e3 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Feb 2024 12:24:06 +0100 Subject: [PATCH 047/423] Add test cases --- .../rpgparser/video/VideoInterpeterTest.kt | 35 ++ .../src/test/resources/video/FILEDEF.rpgle | 12 + .../video/metadata/B\302\243DIR40V.json" | 589 ++++++++++++++++++ 3 files changed, 636 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle create mode 100644 "rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40V.json" diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt new file mode 100644 index 000000000..7e9e1c764 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt @@ -0,0 +1,35 @@ +package com.smeup.rpgparser.video + +import com.smeup.dbnative.DBNativeAccessConfig +import com.smeup.rpgparser.AbstractTest +import com.smeup.rpgparser.execution.Configuration +import com.smeup.rpgparser.execution.ReloadConfig +import com.smeup.rpgparser.execution.SimpleReloadConfig +import kotlin.test.BeforeTest +import kotlin.test.DefaultAsserter.assertTrue +import kotlin.test.Test + +class VideoInterpeterTest : AbstractTest() { + + lateinit var configuration: Configuration + + @BeforeTest + fun setUp() { + configuration = Configuration() + val path = javaClass.getResource("/video/metadata")!!.path + val reloadConfig = SimpleReloadConfig(metadataPath = path, connectionConfigs = listOf()) + configuration.reloadConfig = ReloadConfig( + nativeAccessConfig = DBNativeAccessConfig(emptyList()), + metadataProducer = { dbFile: String -> reloadConfig.getMetadata(dbFile = dbFile) }) + } + + @Test + fun executeFILEDEF() { + // I want to check the compilation unit + configuration.jarikoCallback.afterAstCreation = { ast -> + assertTrue(message = "file video B£DIR40V should be defined", ast.hasFileDefinition("B£DIR40V")) + assertTrue(message = "field £RASDI should be defined", ast.hasAnyDataDefinition("£RASDI")) + } + "video/FILEDEF".outputOf(configuration = configuration) + } +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle b/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle new file mode 100644 index 000000000..46d31db47 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle @@ -0,0 +1,12 @@ + V* ============================================================== + D* 06/02/24 + D* Test the file video metadata loading + V* ============================================================== + + + FB£DIR40V CF E WORKSTN USROPN + F INFDS(DSSF01) + + + + \ No newline at end of file diff --git "a/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40V.json" "b/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40V.json" new file mode 100644 index 000000000..213216f20 --- /dev/null +++ "b/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40V.json" @@ -0,0 +1,589 @@ +{ + "name": "B£DIR40V", + "tableName": "CALBAS0F", + "recordFormat": "", + "fields": [ + { + "fieldName": "*IN02", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "*IN21", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "*IN22", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "*IN60", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "*IN61", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "*IN62", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "*IN63", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "*IN64", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "£RASDI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 15, + "varying": false + } + }, + { + "fieldName": "£PDSNP", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "£PDSJN", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "£PDSNU", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$TPOG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 12, + "varying": false + } + }, + { + "fieldName": "W$TPRI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 12, + "varying": false + } + }, + { + "fieldName": "W$TRGG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 3, + "varying": false + } + }, + { + "fieldName": "W£TRGG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$RISG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 15, + "varying": false + } + }, + { + "fieldName": "W£RISG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$DAIN", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$DAFI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$MESV", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 76, + "varying": false + } + }, + { + "fieldName": "£RASDI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 15, + "varying": false + } + }, + { + "fieldName": "£PDSNP", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "£PDSJN", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "£PDSNU", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$TRGG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 3, + "varying": false + } + }, + { + "fieldName": "W£TRGG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$RISG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 15, + "varying": false + } + }, + { + "fieldName": "W£RISG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$PERI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 8, + "varying": false + } + }, + { + "fieldName": "W$GSET", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$SEAN", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 2, + "decimalDigits": 0, + "rpgType": "S" + } + }, + { + "fieldName": "W$NURI", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 2, + "decimalDigits": 0, + "rpgType": "S" + } + }, + { + "fieldName": "W$PLAV", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 3, + "decimalDigits": 0, + "rpgType": "S" + } + }, + { + "fieldName": "W$ORRI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W£ORRI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 40, + "varying": false + } + }, + { + "fieldName": "W$ECRI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$PEUT", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 5, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$ORUT", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W£ORUT", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 40, + "varying": false + } + }, + { + "fieldName": "W$ECUT", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$COCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 2, + "varying": false + } + }, + { + "fieldName": "W£COCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$ORCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W£ORCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 40, + "varying": false + } + }, + { + "fieldName": "W$ECCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$OI01", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF01", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$HTOT", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 6, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI02", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF02", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$HNET", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 6, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI03", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF03", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$HNTO", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 6, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI04", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF04", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI05", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF05", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W§CFCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 25, + "varying": false + } + }, + { + "fieldName": "W$CFCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 9, + "decimalDigits": 3, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI06", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF06", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$TOCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 9, + "decimalDigits": 3, + "rpgType": "S" + } + }, + { + "fieldName": "W$TU01", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU02", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU03", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU04", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU05", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU06", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + } + ], + "accessFields": [] +} \ No newline at end of file From 14690ec85a2272f3f66ebc3e92f05b3a552586ff Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Feb 2024 14:44:52 +0100 Subject: [PATCH 048/423] Fix: validation errors in DataDefinition creation were hidden Doc: add kotlin doc in all suggested methods for the error handling --- .../rpgparser/interpreter/data_definitions.kt | 7 ++- .../parsing/parsetreetoast/errors.kt | 61 ++++++++++++++++++- .../rpgparser/video/VideoInterpeterTest.kt | 11 ++-- 3 files changed, 72 insertions(+), 7 deletions(-) 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 815d5f67a..3493a5e49 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 @@ -22,6 +22,7 @@ import com.smeup.rpgparser.parsing.ast.MuteAnnotation import com.smeup.rpgparser.parsing.ast.MuteAnnotationResolved import com.smeup.rpgparser.parsing.facade.MutesMap import com.smeup.rpgparser.parsing.parsetreetoast.RpgType +import com.smeup.rpgparser.parsing.parsetreetoast.require import com.smeup.rpgparser.parsing.parsetreetoast.toAst import com.strumenta.kolasu.model.* import kotlinx.serialization.SerialName @@ -179,7 +180,7 @@ data class DataDefinition( @Transient var defaultValue: Value? = null ) : AbstractDataDefinition( - name = name.apply { require(this.trim().isNotEmpty()) { "name cannot be empty" } }, + name = name, type = type, position = position, const = const) { @@ -187,6 +188,10 @@ data class DataDefinition( override fun isArray() = type is ArrayType fun isCompileTimeArray() = type is ArrayType && type.compileTimeArray() + init { + this.require(name.trim().isNotEmpty(), { "name cannot be empty" }) + } + @Deprecated("The start offset should be calculated before defining the FieldDefinition") fun startOffset(fieldDefinition: FieldDefinition): Int { var start = 0 diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/errors.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/errors.kt index 9824edd4b..3e2c3c17e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/errors.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/errors.kt @@ -54,6 +54,16 @@ internal fun notImplementOperationException(message: String): IllegalStateExcept internal fun getAstCreationErrors() = MainExecutionContext.getAttributes() .getOrPut("com.smeup.rpgparser.parsing.parsetreetoast.getAstCreationErrors") { mutableListOf() } as MutableList +/** + * This function is used to throw an error with a specific message and cause. + * It is a natural replacement for the throw keyword in order to link the error to the ast node. + * + * @param message The error message to be used. It is nullable and defaults to null. + * @param cause The Throwable that caused the error. It is nullable and defaults to null. + * @return Nothing. This function always throws an exception. + * @throws AstResolutionError if the cause is an instance of AstResolutionError. + * @throws IllegalStateException with the error message and cause. + */ internal fun Node.error(message: String? = null, cause: Throwable? = null): Nothing { val position = this.position?.adaptInFunctionOf(getProgramNameToCopyBlocks().second) if (cause != null && cause is AstResolutionError) { @@ -72,6 +82,14 @@ internal fun Node.error(message: String? = null, cause: Throwable? = null): Noth } } +/** + * This function is used to throw a not implemented operation exception with a specific message. + * It is a natural replacement for the TODO inline function in order to link the error to the ast node. + * + * @param message The error message to be used. It is nullable and defaults to null. + * @return Nothing. This function always throws an exception. + * @throws IllegalStateException with the error message and the position where the error occurred. + */ internal fun Node.todo(message: String? = null): Nothing { val pref = message?.let { "$message at " @@ -86,6 +104,27 @@ internal fun Node.todo(message: String? = null): Nothing { } } +/** + * This function is used to check if a certain condition is met and throw an error if it's not. + * It is a natural replacement for the "require" kotlin function in order to link the error to the ast node. + * + * @param value The condition to be checked. It is a boolean value. + * @param lazyMessage A lambda function that generates the error message. It is invoked only if the condition is not met. + * @throws IllegalStateException with the error message generated by the lazyMessage function if the condition is not met. + */ +internal fun Node.require(value: Boolean, lazyMessage: () -> String) { + if (!value) { + this.error(message = lazyMessage.invoke()) + } +} + +/** + * This function is used to throw a not implemented operation exception with a specific message. + * It is a natural replacement for the TODO inline function in order to link the error to the parse tree node. + * + * @param message The error message to be used. It is nullable and defaults to null. + * param conf The configuration to be used to consider the position. It is a ToAstConfiguration. + */ internal fun ParserRuleContext.todo(message: String? = null, conf: ToAstConfiguration): Nothing { val pref = message?.let { "$message at" @@ -94,7 +133,13 @@ internal fun ParserRuleContext.todo(message: String? = null, conf: ToAstConfigur val myMessage = "$pref $position ${this.javaClass.name}" throw notImplementOperationException(myMessage).fireErrorEvent(toPosition(conf.considerPosition)) } - +/** + * This function is used to throw an error with a specific message and cause. + * It is a natural replacement for the throw keyword in order to link the error to the parse tree node. + * @param message The error message to be used. It is nullable and defaults to null. + * @param cause The Throwable that caused the error. It is nullable and defaults to null. + * @param conf The configuration to be used to consider the position. It is a ToAstConfiguration. + */ internal fun ParserRuleContext.error(message: String? = null, cause: Throwable? = null, conf: ToAstConfiguration): Nothing { val pref = message?.let { "$message at: " @@ -110,6 +155,20 @@ internal fun ParserRuleContext.error(message: String? = null, cause: Throwable? }.fireErrorEvent(toPosition(conf.considerPosition)) } +/** + * This function is used to check if a certain condition is met and throw an error if it's not. + * It is a natural replacement for the "require" kotlin function in order to link the error to parse tree node. + * + * @param value The condition to be checked. It is a boolean value. + * @param lazyMessage A lambda function that generates the error message. It is invoked only if the condition is not met. + * @param conf The configuration to be used to consider the position. It is a ToAstConfiguration. + */ +internal fun ParserRuleContext.require(value: Boolean, lazyMessage: () -> String, conf: ToAstConfiguration) { + if (!value) { + this.error(message = lazyMessage.invoke(), conf = conf) + } +} + internal fun checkAstCreationErrors(phase: AstHandlingPhase) { if (getAstCreationErrors().isNotEmpty()) { if (MainExecutionContext.getConfiguration().options?.toAstConfiguration?.afterPhaseErrorContinue?.invoke(phase) != true) { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt index 7e9e1c764..3b72a2e02 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt @@ -5,9 +5,10 @@ import com.smeup.rpgparser.AbstractTest import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig +import com.smeup.rpgparser.interpreter.InterpreterCore import kotlin.test.BeforeTest -import kotlin.test.DefaultAsserter.assertTrue import kotlin.test.Test +import kotlin.test.assertNotNull class VideoInterpeterTest : AbstractTest() { @@ -25,11 +26,11 @@ class VideoInterpeterTest : AbstractTest() { @Test fun executeFILEDEF() { - // I want to check the compilation unit - configuration.jarikoCallback.afterAstCreation = { ast -> - assertTrue(message = "file video B£DIR40V should be defined", ast.hasFileDefinition("B£DIR40V")) - assertTrue(message = "field £RASDI should be defined", ast.hasAnyDataDefinition("£RASDI")) + lateinit var interpreter: InterpreterCore + configuration.jarikoCallback.onInterpreterCreation = { it -> + interpreter = it } "video/FILEDEF".outputOf(configuration = configuration) + assertNotNull(message = "field £RASDI should be defined", actual = interpreter["£RASDI"]) } } \ No newline at end of file From e5a71573dc19174b46cd87d5d39682f8f52e1de6 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Feb 2024 17:01:26 +0100 Subject: [PATCH 049/423] =?UTF-8?q?Remove=20indicators=20from=20B=C2=A3DIR?= =?UTF-8?q?40V=20metadata?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../video/metadata/B\302\243DIR40V.json" | 64 ------------------- 1 file changed, 64 deletions(-) diff --git "a/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40V.json" "b/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40V.json" index 213216f20..2b8bb634f 100644 --- "a/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40V.json" +++ "b/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40V.json" @@ -3,70 +3,6 @@ "tableName": "CALBAS0F", "recordFormat": "", "fields": [ - { - "fieldName": "*IN02", - "type": { - "type": "com.smeup.rpgparser.interpreter.StringType", - "length": 1, - "varying": false - } - }, - { - "fieldName": "*IN21", - "type": { - "type": "com.smeup.rpgparser.interpreter.StringType", - "length": 1, - "varying": false - } - }, - { - "fieldName": "*IN22", - "type": { - "type": "com.smeup.rpgparser.interpreter.StringType", - "length": 1, - "varying": false - } - }, - { - "fieldName": "*IN60", - "type": { - "type": "com.smeup.rpgparser.interpreter.StringType", - "length": 1, - "varying": false - } - }, - { - "fieldName": "*IN61", - "type": { - "type": "com.smeup.rpgparser.interpreter.StringType", - "length": 1, - "varying": false - } - }, - { - "fieldName": "*IN62", - "type": { - "type": "com.smeup.rpgparser.interpreter.StringType", - "length": 1, - "varying": false - } - }, - { - "fieldName": "*IN63", - "type": { - "type": "com.smeup.rpgparser.interpreter.StringType", - "length": 1, - "varying": false - } - }, - { - "fieldName": "*IN64", - "type": { - "type": "com.smeup.rpgparser.interpreter.StringType", - "length": 1, - "varying": false - } - }, { "fieldName": "£RASDI", "type": { From 804344db287e618874e7d6f09265e0d8f2e128ed Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Feb 2024 17:03:06 +0100 Subject: [PATCH 050/423] Add FileDefinition.fileType property --- .../rpgparser/interpreter/data_definitions.kt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) 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 3493a5e49..34aaa4bba 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 @@ -135,16 +135,29 @@ data class Prefix(internal val prefix: String, private val numCharsReplaced: Int } } +enum class FileType(val keyword: String?) { + DB(null), VIDEO("C"); + + companion object { + fun getByKeyword(keyword: String): FileType { + return FileType.values().firstOrNull() { + it.keyword == keyword + } ?: DB + } + } +} + @Serializable data class FileDefinition private constructor( override val name: String, override val position: Position?, val prefix: Prefix?, - val justExtName: Boolean + val justExtName: Boolean, + val fileType: FileType ) : Node(position), Named { companion object { - operator fun invoke(name: String, position: Position? = null, prefix: Prefix? = null, justExtName: Boolean = false): FileDefinition { - return FileDefinition(name.toUpperCase(), position, prefix, justExtName) + operator fun invoke(name: String, position: Position? = null, prefix: Prefix? = null, justExtName: Boolean = false, fileType: FileType = FileType.DB): FileDefinition { + return FileDefinition(name.uppercase(), position, prefix, justExtName, fileType) } } From c17b6561e643dbb7a554f68b64da9cec89f1b5b8 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Feb 2024 17:04:40 +0100 Subject: [PATCH 051/423] Change Fspec_fixedContext.toAst implementation in order to create the FileDefinition by passing the new fileType property --- .../rpgparser/parsing/parsetreetoast/data_definitions.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 729d0e8ce..1929df51c 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 @@ -23,8 +23,6 @@ import com.smeup.rpgparser.utils.asInt import com.strumenta.kolasu.mapping.toPosition import com.strumenta.kolasu.model.Position import java.math.BigDecimal -import java.util.* -import kotlin.collections.HashMap import kotlin.math.max enum class RpgType(val rpgType: String) { @@ -88,6 +86,7 @@ fun RpgParser.Dcl_dsContext.elementSizeOf(fieldsList: FieldsList = this.calculat internal fun RpgParser.Fspec_fixedContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): FileDefinition { val prefixContexts = this.fs_keyword().mapNotNull { it.keyword_prefix() } + val prefix: Prefix? = if (prefixContexts.isNotEmpty()) { Prefix( prefix = prefixContexts[0].prefix.text, @@ -99,7 +98,8 @@ internal fun RpgParser.Fspec_fixedContext.toAst(conf: ToAstConfiguration = ToAst val fileDefinition = FileDefinition( name = this.FS_RecordName().text.trim(), position = this.toPosition(conf.considerPosition), - prefix = prefix + prefix = prefix, + fileType = FileType.getByKeyword(this.FS_Type().text.trim()) ) val rename = this.fs_keyword().mapNotNull { it.keyword_rename() } if (rename.isNotEmpty()) { From 6fd6603a14712fd2b8d8f305d0bb4d59f4a19d9e Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Feb 2024 17:14:09 +0100 Subject: [PATCH 052/423] Include DataDefinition related the record format only when fileType is FileType.DB --- .../rpgparser/parsing/parsetreetoast/misc.kt | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 738651324..5cae93963 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -175,13 +175,16 @@ private fun FileDefinition.toDataDefinitions(): List { // explicitStartOffset and explicitEndOffsets set to zero are wanted FieldDefinition(name = it.name, type = it.type, explicitStartOffset = 0, explicitEndOffset = 0, position = it.position) } - val recordFormatDefinition = DataDefinition( - name = metadata.recordFormat, - type = RecordFormatType, - position = position, - fields = fieldsDefinition - ) - dataDefinitions.add(recordFormatDefinition) + // record format possibly for file video is unuseful + if (fileType == FileType.DB) { + val recordFormatDefinition = DataDefinition( + name = metadata.recordFormat, + type = RecordFormatType, + position = position, + fields = fieldsDefinition + ) + dataDefinitions.add(recordFormatDefinition) + } return dataDefinitions } From 9a0494efdeed7dbfa6cd1d09ef0155f8fa05871b Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Feb 2024 17:15:35 +0100 Subject: [PATCH 053/423] Add in DbFileMap only FileDefinition of type FileType.DB --- .../com/smeup/rpgparser/interpreter/internal_interpreter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index b225dc9a4..919c77fb6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -210,7 +210,7 @@ open class InternalInterpreter( val start = System.currentTimeMillis() MainExecutionContext.log(SymbolTableIniLogStart(programName = interpretationContext.currentProgramName)) // TODO verify if these values should be reinitialised or not - compilationUnit.fileDefinitions.forEach { + compilationUnit.fileDefinitions.filter { it.fileType == FileType.DB }.forEach { status.dbFileMap.add(it) } From 6562e7f52570a211310ef94e9eeb2c7bacf3da02 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 6 Feb 2024 17:16:48 +0100 Subject: [PATCH 054/423] Fix test because after the program execution the symboltable is cleaned and then the test caused false positives --- .../com/smeup/rpgparser/video/VideoInterpeterTest.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt index 3b72a2e02..0d6d1b906 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt @@ -5,10 +5,9 @@ import com.smeup.rpgparser.AbstractTest import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig -import com.smeup.rpgparser.interpreter.InterpreterCore import kotlin.test.BeforeTest +import kotlin.test.DefaultAsserter import kotlin.test.Test -import kotlin.test.assertNotNull class VideoInterpeterTest : AbstractTest() { @@ -26,11 +25,9 @@ class VideoInterpeterTest : AbstractTest() { @Test fun executeFILEDEF() { - lateinit var interpreter: InterpreterCore - configuration.jarikoCallback.onInterpreterCreation = { it -> - interpreter = it + configuration.jarikoCallback.onExitPgm = { _, symbolTable, _ -> + DefaultAsserter.assertNotNull(message = "field £RASDI should be defined", actual = symbolTable["£RASDI"]) } "video/FILEDEF".outputOf(configuration = configuration) - assertNotNull(message = "field £RASDI should be defined", actual = interpreter["£RASDI"]) } } \ No newline at end of file From ce1d78de8a715ec66cc0ef277609bb75a368061d Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 7 Feb 2024 12:03:04 +0100 Subject: [PATCH 055/423] make test more significant --- .../src/test/resources/video/FILEDEF.rpgle | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle b/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle index 46d31db47..93b21431e 100644 --- a/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle @@ -7,6 +7,13 @@ FB£DIR40V CF E WORKSTN USROPN F INFDS(DSSF01) + D WFUND1 DS + D WSDATA 8 0 + D W$PERI + + O E RIGA 1 + O W$PERI 11 + \ No newline at end of file From c8790867a2d4d3743cb56c04330c273f58699bc7 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 12:11:48 +0100 Subject: [PATCH 056/423] FieldInfo.explicitElementType now can be assumed from knownDataDefinitions. This allows to retrieve the type from other fields previously defined, for example fields already defined with same name in file. --- .../interpreter/compile_time_interpreter.kt | 4 ++-- .../parsing/parsetreetoast/data_definitions.kt | 18 +++++++++++------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 91316c8aa..99ae1f880 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -120,7 +120,7 @@ open class BaseCompileTimeInterpreter( it.dcl_ds() != null -> { val name = it.dcl_ds().name if (name == declName) { - val fieldsList = it.dcl_ds().calculateFieldInfos() + val fieldsList = it.dcl_ds().calculateFieldInfos(knownDataDefinitions) return it.dcl_ds().type( it.dcl_ds().declaredSize(), fieldsList).numberOfElements() @@ -163,7 +163,7 @@ open class BaseCompileTimeInterpreter( it.dcl_ds() != null -> { val name = it.dcl_ds().name if (name == declName) { - return it.dcl_ds().elementSizeOf() + return it.dcl_ds().elementSizeOf(knownDataDefinitions) } } } 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 1929df51c..c6e445a22 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 @@ -70,7 +70,8 @@ private fun inferDsSizeFromFieldLines(fieldsList: FieldsList): Int { return maxEnd } -fun RpgParser.Dcl_dsContext.elementSizeOf(fieldsList: FieldsList = this.calculateFieldInfos()): Int { +internal fun RpgParser.Dcl_dsContext.elementSizeOf(knownDataDefinitions: Collection): Int { + val fieldsList = this.calculateFieldInfos(knownDataDefinitions) val toPosition = if (this.nameIsInFirstLine) { this.TO_POSITION().text } else { @@ -700,11 +701,11 @@ internal fun RpgParser.Parm_fixedContext.calculateExplicitElementType(arraySizeD } } -fun RpgParser.Dcl_dsContext.calculateFieldInfos(): FieldsList { +internal fun RpgParser.Dcl_dsContext.calculateFieldInfos(knownDataDefinitions: Collection): FieldsList { val caughtErrors = mutableListOf() val fieldsList = FieldsList(this.parm_fixed().mapNotNull { kotlin.runCatching { - it.toFieldInfo() + it.toFieldInfo(knownDataDefinitions = knownDataDefinitions) }.onFailure { caughtErrors.add(it) }.getOrNull() @@ -729,7 +730,7 @@ fun RpgParser.Dcl_dsContext.calculateFieldInfos(): FieldsList { return fieldsList } -private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = ToAstConfiguration()): FieldInfo { +private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = ToAstConfiguration(), knownDataDefinitions: Collection): FieldInfo { var overlayInfo: FieldInfo.OverlayInfo? = null val overlay = this.keyword().find { it.keyword_overlay() != null } // Set the SORTA order @@ -769,7 +770,7 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = T return FieldInfo(this.name, overlayInfo = overlayInfo, explicitStartOffset = this.explicitStartOffset(), explicitEndOffset = if (explicitStartOffset() != null) this.explicitEndOffset() else null, - explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf), + explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(this.name, ignoreCase = true) }?.type, arraySizeDeclared = this.arraySizeDeclared(conf), arraySizeDeclaredOnThisField = this.arraySizeDeclared(conf), initializationValue = initializationValue, @@ -935,14 +936,17 @@ class FieldsList(val fields: List) { fun isNotEmpty() = fields.isNotEmpty() } -internal fun RpgParser.Dcl_dsContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): DataDefinition { +internal fun RpgParser.Dcl_dsContext.toAst( + conf: ToAstConfiguration = ToAstConfiguration(), + knownDataDefinitions: Collection +): DataDefinition { val initializationValue: Expression? = null val size = this.declaredSize() // Calculating information about the DS and its fields is full of interdependecies // therefore we do that in steps - val fieldsList = calculateFieldInfos() + val fieldsList = calculateFieldInfos(knownDataDefinitions) val type: Type = this.type(size, fieldsList, conf) val inz = this.keyword().asSequence().firstOrNull { it.keyword_inz() != null } From db9b17d472860eebf2e4a26738d05199f43fe93d Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 12:13:12 +0100 Subject: [PATCH 057/423] Fix test: calculateFieldInfos expects a collection of AbstractDataDefinition --- .../kotlin/com/smeup/rpgparser/parsing/RpgParserDataStruct.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/RpgParserDataStruct.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/RpgParserDataStruct.kt index 47fc8ce20..3fbf37654 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/RpgParserDataStruct.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/RpgParserDataStruct.kt @@ -344,7 +344,7 @@ open class RpgParserDataStruct : AbstractTest() { val r = assertCanBeParsed("struct/STRUCT_08", withMuteSupport = true) for (stat in r.statement()) { stat.dcl_ds()?.apply { - val fieldsList = calculateFieldInfos() + val fieldsList = calculateFieldInfos(emptyList()) actualDSTypes[stat.dcl_ds().name] = this.type(this.declaredSize(), fieldsList) } } From 334a20dc86bbc8a06cf3eb90cdb4d9922f4db972 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 12:18:21 +0100 Subject: [PATCH 058/423] Fix: by passing to RpgParser.Dcl_dsContext.toAst the knownDataDefinitions, we can get the fields type also for DS fields not explicitly defined. Feat: refactor removeDuplicatedDataDefinition in order to link the validation error to position in the source code --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 5cae93963..5ea2e886a 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -505,7 +505,7 @@ private fun StatementContext.toDataDefinitionProvider( kotlin.runCatching { try { this.dcl_ds() - .toAst(conf) + .toAst(conf = conf, knownDataDefinitions = knownDataDefinitions.values) .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) // these errors can be caught because they don't introduce sneaky errors } catch (e: CannotRetrieveDataStructureElementSizeException) { @@ -1959,7 +1959,7 @@ internal fun List.removeDuplicatedDataDefinition dataDefinitionMap[it.name] = it true } else { - require(dataDefinition.type == it.type) { + it.require(dataDefinition.type == it.type) { "Incongruous definitions of ${it.name}: ${dataDefinition.type} vs ${it.type}" } false From bb2e7698e562f083fcdcf88d6816e39e4cdee1ca Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 12:20:19 +0100 Subject: [PATCH 059/423] Move the validation of all data definition into ast resolution. This allows us to intercept these error before the program execution --- .../com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt index 9975d73ca..59a740860 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt @@ -194,6 +194,8 @@ private fun CompilationUnit.resolve() { pp.param.tryToResolveRecursively(position = pp.position, cu = this) } } + + this.allDataDefinitions } // try to resolve a Data reference through recursive search in parent compilation unit From 65cb75588d8c15ab041643996463eb3dbb8a97d5 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 12:20:51 +0100 Subject: [PATCH 060/423] Improve test related file video --- .../rpgparser/video/VideoInterpeterTest.kt | 4 +++- .../src/test/resources/video/FILEDEF.rpgle | 18 ++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt index 0d6d1b906..cb2c5cd0d 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt @@ -8,6 +8,7 @@ import com.smeup.rpgparser.execution.SimpleReloadConfig import kotlin.test.BeforeTest import kotlin.test.DefaultAsserter import kotlin.test.Test +import kotlin.test.assertEquals class VideoInterpeterTest : AbstractTest() { @@ -28,6 +29,7 @@ class VideoInterpeterTest : AbstractTest() { configuration.jarikoCallback.onExitPgm = { _, symbolTable, _ -> DefaultAsserter.assertNotNull(message = "field £RASDI should be defined", actual = symbolTable["£RASDI"]) } - "video/FILEDEF".outputOf(configuration = configuration) + val expected = listOf("W\$PERI:12", "£RASDI:HELLO_WORLD") + assertEquals(expected = expected, actual = "video/FILEDEF".outputOf(configuration = configuration)) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle b/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle index 93b21431e..6b5da06b2 100644 --- a/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/video/FILEDEF.rpgle @@ -7,12 +7,26 @@ FB£DIR40V CF E WORKSTN USROPN F INFDS(DSSF01) + D MSG S 50 VARYING + D WFUND1 DS D WSDATA 8 0 + * This field definition is assumed by B£DIR40V D W$PERI - O E RIGA 1 - O W$PERI 11 + C EVAL W$PERI=12 + C EVAL MSG='W$PERI:' + %CHAR(W$PERI) + * EXPECTED: W$PERI:12 + C MSG DSPLY + + * This field is defined in B£DIR40V + C EVAL £RASDI='HELLO_WORLD' + C EVAL MSG='£RASDI:' + %CHAR(£RASDI) + * EXPECTED: £RASDI=:HELLO_WORLD + C MSG DSPLY + + + From 69b474e330be7b5a3f4818c2fe3f2926901c5003 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 14:27:26 +0100 Subject: [PATCH 061/423] Add test case related the handling error improving --- rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle b/rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle new file mode 100644 index 000000000..8952c1db1 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle @@ -0,0 +1,7 @@ + V* ============================================================== + D* Better displaying of lexical errors + D* + V* ============================================================== + + D WFUND1 DS + D \ No newline at end of file From dbdf3383097f626ebb06b08a4170101265fcbb89 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 14:33:25 +0100 Subject: [PATCH 062/423] Remove unhelpful errors. Add test. Add doc. Fix typo. --- .../rpgparser/parsing/facade/RpgParserFacade.kt | 2 +- .../rpgparser/interpreter/JarikoCallbackTest.kt | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/RpgParserFacade.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/RpgParserFacade.kt index e8e62c8af..0f917e1f7 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/RpgParserFacade.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/RpgParserFacade.kt @@ -552,7 +552,7 @@ private fun List.fireErrorEvents() { MainExecutionContext.getParsingProgramStack().peek().name } val copyBlocks = programName?.let { MainExecutionContext.getParsingProgramStack().peek().copyBlocks } - groupByLine().forEach { errorEntry -> + this.filter { !it.message.matches(Regex("Recognition exception: null|Error nod found")) }.groupByLine().forEach { errorEntry -> ErrorEvent( error = IllegalStateException(errorEntry.value[0].message), errorEventSource = ErrorEventSource.Parser, diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt index 4ecc05607..7b0894df6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt @@ -407,6 +407,11 @@ class JarikoCallbackTest : AbstractTest() { executeSourceLineTest("ERROR11") } + @Test + fun executeERROR12CallBackTest() { + executePgmCallBackTest("ERROR12", SourceReferenceType.Program, "ERROR12", listOf(7)) + } + /** * This test simulates what a precompiler might do throws the use of the beforeParsing callback * In ERROR01.rpgle I will comment C specification to avoid a division by zero errors @@ -478,6 +483,15 @@ class JarikoCallbackTest : AbstractTest() { assertNotNull(catchedError) } + /** + * This function is used to test the execution of a program and validate the error handling mechanism. + * It expects the program to fail and checks if the error events are correctly captured. + * + * @param pgm The name of the program to be executed. + * @param sourceReferenceType The expected type of the source reference (Program or Copy) where the error is expected to occur. + * @param sourceId The expected identifier of the source where the error is expected to occur. + * @param lines The list of line numbers where the errors are expected. + */ private fun executePgmCallBackTest(pgm: String, sourceReferenceType: SourceReferenceType, sourceId: String, lines: List) { val errorEvents = mutableListOf() runCatching { @@ -500,7 +514,7 @@ class JarikoCallbackTest : AbstractTest() { } /** - * Verify that the sourceLine is correctly set in case of error. + * Verify that the sourceLine is properly set in case of error. * ErrorEvent must contain a reference of an absolute line of the source code * */ private fun executeSourceLineTest(pgm: String) { From 1e105cdb6269a8bbdfee3c4d9611dc1c7ac29f39 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 14:45:08 +0100 Subject: [PATCH 063/423] Fix forced error --- rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle b/rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle index 8952c1db1..d5ef995cc 100644 --- a/rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/ERROR12.rpgle @@ -4,4 +4,4 @@ V* ============================================================== D WFUND1 DS - D \ No newline at end of file + D WSDATA 8 0 \ No newline at end of file From bd3278637ba1fe152fade16c5fde2a7f5b5c61d9 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 8 Feb 2024 15:35:22 +0100 Subject: [PATCH 064/423] Add FeaturesFactory.getJarikoVersionVersion --- .../rpgparser/interpreter/IFeaturesFactory.kt | 47 +++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/IFeaturesFactory.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/IFeaturesFactory.kt index 0150716c3..74c5ab7df 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/IFeaturesFactory.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/IFeaturesFactory.kt @@ -17,9 +17,8 @@ @file:JvmName("StandardFeaturesFactory") package com.smeup.rpgparser.interpreter -import java.lang.IllegalArgumentException -import kotlin.reflect.full.createInstance import com.smeup.rpgparser.parsing.parsetreetoast.RpgType +import kotlin.reflect.full.createInstance /** * Allows to enable features @@ -56,6 +55,33 @@ object FeaturesFactory { ?.let { it.readText() } } + /** + * Retrieves the version information of Jariko. + * + * This function reads the version file content and parses it into a JarikoVersion object. + * The version file content is expected to be in the format of "Version: version, Branch: branch, Revision: revision, Buildtime: buildtime". + * If the version file content is null a default JarikoVersion object is returned with all properties set to "UNKNOWN". + * + * @return A JarikoVersion object representing the version information of Jariko. + */ + fun getJarikoVersionVersion(): JarikoVersion { + return versionFileContent?.let { content -> + val props = mutableMapOf() + content.split("\n").forEach { + if (it.startsWith("Version") || it.startsWith("Branch") || it.startsWith("Revision") || it.startsWith("Buildtime")) { + val (key, value) = it.split(": ") + props[key] = value.trim() + } + } + JarikoVersion( + version = props["Version"] ?: "", + branch = props["Branch"] ?: "", + revision = props["Revision"] ?: "", + buildtime = props["Buildtime"] ?: "" + ) + } ?: JarikoVersion() + } + private val factory: IFeaturesFactory by lazy { dumpVersion() val property = System.getProperty("jariko.featuresFactory", System.getProperty("featuresFactory", "")) @@ -111,4 +137,19 @@ enum class FeatureFlag { val property = System.getProperty(getPropertyName(), "0") return property.lowercase().matches(Regex("1|on|true")) } -} \ No newline at end of file +} + +/** + * Data class representing the version information of Jariko. + * + * @property version The version of Jariko. Defaults to "UNKNOWN" if not specified. + * @property branch The branch of the source code. Defaults to "UNKNOWN" if not specified. + * @property revision The revision of the source code. Defaults to "UNKNOWN" if not specified. + * @property buildtime The build time of the source code. Defaults to "UNKNOWN" if not specified. + */ +data class JarikoVersion( + val version: String = "UNKNOWN", + val branch: String = "UNKNOWN", + val revision: String = "UNKNOWN", + val buildtime: String = "UNKNOWN" +) \ No newline at end of file From 37db62e70684da86ca840723e255f6d0763a6121 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 9 Feb 2024 12:19:22 +0100 Subject: [PATCH 065/423] Add test --- .../evaluation/SmeupInterpreterTest.kt | 14 +++++ .../test/resources/smeup/T12_A04_P07_12.rpgle | 55 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P07_12.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f060f8edc..e5daccbe2 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -319,4 +319,18 @@ open class SmeupInterpreterTest : AbstractTest() { "CALL(MULANGTC30, 7 , 0)") assertEquals(expected, "smeup/T10_A60_P04-P07".outputOf()) } + + @Test + fun executeT12_A04_P07_12() { + val expected = listOf( + "CNT(100001)", + "CNT(100000)", + "CNT(100001)", + "CNT(100000)", + "CNT(100001)", + "CNT(100000)", + + ) + assertEquals(expected, "smeup/T12_A04_P07_12".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P07_12.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P07_12.rpgle new file mode 100644 index 000000000..710489b65 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P07_12.rpgle @@ -0,0 +1,55 @@ + D A04_N50_LIM S 6 0 INZ(100000) + D A04_N50_CNT S LIKE(A04_N50_LIM) + D £DBG_Str S 100 VARYING + + *--------------------------------------------------------------- + RD* Errori programma MULANGT12 sezione A04 + *--------------------------------------------------------------* + OA* A£.CDOP(DOWEQ;ENDDO) + D* DOWEQ + C EVAL A04_N50_CNT = A04_N50_LIM + C A04_N50_CNT DOWEQ A04_N50_LIM + C EVAL A04_N50_CNT = A04_N50_CNT + 1 + C ENDDO + C EVAL £DBG_Str='CNT('+%CHAR(A04_N50_CNT)+')' + C £DBG_Str DSPLY + OA* A£.CDOP(DOWNE;ENDDO) + D* DOWNE + C EVAL A04_N50_CNT = 0 + C A04_N50_CNT DOWNE A04_N50_LIM + C EVAL A04_N50_CNT = A04_N50_CNT + 1 + C ENDDO + C EVAL £DBG_Str='CNT('+%CHAR(A04_N50_CNT)+')' + C £DBG_Str DSPLY + OA* A£.CDOP(DOWGE;ENDDO) + D* DOWGE + C EVAL A04_N50_CNT = 0 + C A04_N50_LIM DOWGE A04_N50_CNT + C EVAL A04_N50_CNT = A04_N50_CNT + 1 + C ENDDO + C EVAL £DBG_Str='CNT('+%CHAR(A04_N50_CNT)+')' + C £DBG_Str DSPLY + OA* A£.CDOP(DOWGT;ENDDO) + D* DOWGT + C EVAL A04_N50_CNT = 0 + C A04_N50_LIM DOWGT A04_N50_CNT + C EVAL A04_N50_CNT = A04_N50_CNT + 1 + C ENDDO + C EVAL £DBG_Str='CNT('+%CHAR(A04_N50_CNT)+')' + C £DBG_Str DSPLY + OA* A£.CDOP(DOWLE;ENDDO) + D* DOWLE + C EVAL A04_N50_CNT = 0 + C A04_N50_CNT DOWLE A04_N50_LIM + C EVAL A04_N50_CNT = A04_N50_CNT + 1 + C ENDDO + C EVAL £DBG_Str='CNT('+%CHAR(A04_N50_CNT)+')' + C £DBG_Str DSPLY + OA* A£.CDOP(DOWLT;ENDDO) + D* DOWLT + C EVAL A04_N50_CNT = 0 + C A04_N50_CNT DOWLT A04_N50_LIM + C EVAL A04_N50_CNT = A04_N50_CNT + 1 + C ENDDO + C EVAL £DBG_Str='CNT('+%CHAR(A04_N50_CNT)+')' + C £DBG_Str DSPLY \ No newline at end of file From 0d8e2407b4cde57e523f1689c0a3c3d8ef541306 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 9 Feb 2024 13:39:02 +0000 Subject: [PATCH 066/423] Implement %CHECK BIF --- .../smeup/rpgparser/interpreter/Evaluator.kt | 1 + .../interpreter/ExpressionEvaluation.kt | 22 ++++ .../parsing/ast/builtin_functions.kt | 11 ++ .../rpgparser/parsing/ast/serialization.kt | 1 + .../rpgparser/parsing/parsetreetoast/bif.kt | 10 ++ .../evaluation/SmeupInterpreterTest.kt | 23 ++++ .../src/test/resources/smeup/T04_A15.rpgle | 110 ++++++++++++++++++ 7 files changed, 178 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle 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 5da23544d..ebfe57b89 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 @@ -51,6 +51,7 @@ interface Evaluator { fun eval(expression: NotExpr): BooleanValue fun eval(expression: ScanExpr): Value fun eval(expression: SubstExpr): Value + fun eval(expression: CheckExpr): Value fun eval(expression: SubarrExpr): Value fun eval(expression: LenExpr): Value fun eval(expression: OffRefExpr): BooleanValue 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 fce6cd237..f807849e4 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 @@ -325,6 +325,28 @@ class ExpressionEvaluation( val result = source.indexOf(value, startIndex) return IntValue(if (result == -1) 0 else result.toLong() + 1) } + override fun eval(expression: CheckExpr): Value { + var startpos = 0 + if (expression.start != null) { + startpos = expression.start.evalWith(this).asInt().value.toInt() + if (startpos > 0) { + startpos -= 1 + } + } + val comparator = expression.value.evalWith(this).asString().value + val base = expression.source.evalWith(this).asString().value.toCharArray() + + var result = 0 + for (i in startpos until base.size) { + val currChar = base[i] + if (!comparator.contains(currChar)) { + result = i + 1 + break + } + } + + return IntValue(result.toLong()) + } override fun eval(expression: SubstExpr): Value { val length = if (expression.length != null) expression.length.evalWith(this).asInt().value.toInt() else 0 diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt index dfcd8ba39..cac6ad7e8 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt @@ -50,6 +50,17 @@ data class ScanExpr( override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } +// %CHECK +@Serializable +data class CheckExpr( + var value: Expression, + val source: Expression, + val start: Expression? = null, + override val position: Position? = null +) : Expression(position) { + override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) +} + // %XLATE @Serializable data class TranslateExpr( 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 ce0574210..d6028443e 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 @@ -106,6 +106,7 @@ private val modules = SerializersModule { subclass(AssignmentExpr::class) subclass(BlanksRefExpr::class) subclass(CharExpr::class) + subclass(CheckExpr::class) subclass(DataRefExpr::class) subclass(DecExpr::class) subclass(DiffExpr::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/bif.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/bif.kt index 8aab790e8..59a0dfce1 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/bif.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/bif.kt @@ -31,6 +31,7 @@ internal fun RpgParser.BifContext.toAst(conf: ToAstConfiguration = ToAstConfigur this.bif_lookup() != null -> this.bif_lookup().toAst(conf) this.bif_xlate() != null -> this.bif_xlate().toAst(conf) this.bif_scan() != null -> this.bif_scan().toAst(conf) + this.bif_check() != null -> this.bif_check().toAst(conf) this.bif_trim() != null -> this.bif_trim().toAst(conf) this.bif_trimr() != null -> this.bif_trimr().toAst(conf) this.bif_triml() != null -> this.bif_triml().toAst(conf) @@ -213,6 +214,15 @@ internal fun RpgParser.Bif_scanContext.toAst(conf: ToAstConfiguration = ToAstCon ) } +internal fun RpgParser.Bif_checkContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CheckExpr { + return CheckExpr( + value = this.comparator.toAst(conf), + source = this.base.toAst(conf), + start = this.start?.toAst(conf), + toPosition(conf.considerPosition) + ) +} + internal fun RpgParser.Bif_xlateContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): TranslateExpr { return TranslateExpr( this.from.toAst(conf), diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f060f8edc..89ed03370 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -319,4 +319,27 @@ open class SmeupInterpreterTest : AbstractTest() { "CALL(MULANGTC30, 7 , 0)") assertEquals(expected, "smeup/T10_A60_P04-P07".outputOf()) } + + @Test + fun executeT04_A15() { + val expected = listOf( + "P01_01(8)", + "P01_02(13)", + "P01_03(16)", + "P01_04(2)", + "P01_05(1)", + "P01_06(1)", + "P01_07(0)", + "P01_08(2)", + "P01_09(2)", + "P01_10(1)", + "P01_11(2)", + "P01_12(0)", + "P02_01(10)", + "P02_02(6)", + "P03_01(0)", + "P03_02(1)" + ) + assertEquals(expected, "smeup/T04_A15".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle new file mode 100644 index 000000000..6e96f9e66 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle @@ -0,0 +1,110 @@ + D name S 30A + D name2 S 4A + D pos S 5U 0 + D £DBG_Str S 30 + D £DBG_Pas S 3 + D alphabet C 'ABCDEFGHIJKLMNOPQRSTUVWXYZ + + D abcdefghijklmnopqrstuvwxyz + + D 0123456789+/' + * + C EXSR SEZ_T04_A15 + * + C SETON LR + *--------------------------------------------------------------- + RD* Errori programma MULANGT04 sezione A15 + *--------------------------------------------------------------* + C SEZ_T04_A15 BEGSR + OA* A&.BIFN(%CHECK) + D* %CHECK semplice + C EVAL £DBG_Pas='P01' + * + C EVAL name = ' Amit Jaiswal' + C EVAL pos = %check(' ' : name) + C EVAL £DBG_Str='P01_01('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = ' Amit Jaiswal' + C EVAL pos = %check(' Atim' : name) + C EVAL £DBG_Str='P01_02('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = ' Amit Jaiswal' + C EVAL pos = %check(' Amit Jai' : name) + C EVAL £DBG_Str='P01_03('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check('A' : name) + C EVAL £DBG_Str='P01_04('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check('a' : name) + C EVAL £DBG_Str='P01_05('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check('ab' : name) + C EVAL £DBG_Str='P01_06('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name2 = 'abab' + C EVAL pos = %check('ab' : name2) + C EVAL £DBG_Str='P01_07('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name2 = 'abab' + C EVAL pos = %check('ac' : name2) + C EVAL £DBG_Str='P01_08('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name2 = 'abab' + C EVAL pos = %check('acd' : name2) + C EVAL £DBG_Str='P01_09('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name2 = 'abab' + C EVAL pos = %check('cd' : name2) + C EVAL £DBG_Str='P01_10('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name2 = 'abab' + C EVAL pos = %check('ca' : name2) + C EVAL £DBG_Str='P01_11('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name2 = 'abab' + C EVAL pos = %check('cab' : name2) + C EVAL £DBG_Str='P01_12('+%char(pos)+')' + C £DBG_Str DSPLY + * + OA* A&.BIFN(%CHECK) + D* %CHECK con posizione + C EVAL £DBG_Pas='P02' + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check('Jais' : name:6) + C EVAL £DBG_Str='P02_01('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check('A' : name:6) + C EVAL £DBG_Str='P02_02('+%char(pos)+')' + C £DBG_Str DSPLY + * + * + OA* A&.BIFN(%CHECK) + D* %CHECK ricerca in alfabeto + C EVAL £DBG_Pas='P03' + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check(alphabet: name) + C EVAL £DBG_Str='P03_01('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = '££ t abc1234' + C EVAL pos = %check(alphabet: name) + C EVAL £DBG_Str='P03_02('+%char(pos)+')' + C £DBG_Str DSPLY + * + C ENDSR \ No newline at end of file From 986fc24ba40a0081613e6edc9829627b2e0e6631 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:13:09 +0000 Subject: [PATCH 067/423] add IF test with %CHECK --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 3 ++- .../src/test/resources/smeup/T04_A15.rpgle | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 89ed03370..8c2a9ceef 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -338,7 +338,8 @@ open class SmeupInterpreterTest : AbstractTest() { "P02_01(10)", "P02_02(6)", "P03_01(0)", - "P03_02(1)" + "P03_02(1)", + "P03_03(ok)" ) assertEquals(expected, "smeup/T04_A15".outputOf()) } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle index 6e96f9e66..5f13082c0 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle @@ -105,6 +105,13 @@ C EVAL name = '££ t abc1234' C EVAL pos = %check(alphabet: name) C EVAL £DBG_Str='P03_02('+%char(pos)+')' + C £DBG_Str DSPLY + * + C IF %CHECK(alphabet: 'Antonio Cosentino')= 0 + C EVAL £DBG_Str='P03_03(ok)' + C ELSE + C EVAL £DBG_Str='P03_03(ko)' + C ENDIF C £DBG_Str DSPLY * C ENDSR \ No newline at end of file From 8aba848f894788b794a980b8ebf96b912f0aa731 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 9 Feb 2024 16:59:39 +0100 Subject: [PATCH 068/423] Added test `DOWEQ` --- .../rpgparser/evaluation/InterpreterTest.kt | 6 + .../src/test/resources/DOWEQ.rpgle | 103 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/DOWEQ.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 1425e8d06..8f8101eaf 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2222,4 +2222,10 @@ Test 6 val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1") assertEquals(expected, "INDIC02".outputOf()) } + + @Test + fun executeDOWEQ() { + val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") + assertEquals(expected, "DOWEQ".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWEQ.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWEQ.rpgle new file mode 100644 index 000000000..b093ada34 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/DOWEQ.rpgle @@ -0,0 +1,103 @@ + D RES S 10 VARYING + + + + * + * COMPARISON WITH NUMERIC + * + + D LEFT S 1 0 + D RIGHT S 1 0 + + * When LEFT and RIGHT are equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWEQ 1 + C EVAL LEFT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWEQ 2 + C EVAL LEFT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT are equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=1 + C 1 DOWEQ RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=1 + C 2 DOWEQ RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT=1 + C EVAL RIGHT=1 + C LEFT DOWEQ RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT=1 + C EVAL RIGHT=2 + C LEFT DOWEQ RIGHT + C EVAL RIGHT=3 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + + + * + * COMPARISON WITH STRING + * + + D LEFT_STR S 110 VARYING + D RIGHT_STR S 110 VARYING + + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='1' + C EVAL RIGHT_STR='1' + C LEFT_STR DOWEQ RIGHT_STR + C EVAL RIGHT_STR='2' + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='1' + C EVAL RIGHT_STR='2' + C LEFT_STR DOWEQ RIGHT_STR + C EVAL RIGHT_STR='3' + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY \ No newline at end of file From 247942a29a4a58604073aa9400d986b445695c74 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 9 Feb 2024 17:00:40 +0100 Subject: [PATCH 069/423] Implemented ExecutionLog for `DOWxx` --- .../com/smeup/rpgparser/interpreter/logs.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt index 2f6378455..eda795365 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt @@ -262,6 +262,45 @@ class DoStatemenExecutionLogEnd(programName: String, val statement: DoStmt, val } } +class DOWxxStatementExecutionLogStart(programName: String, val statement: DOWxxStmt) : LogEntry(programName) { + override fun toString(): String { + return "executing DOWxx LOOP" + } + + override fun renderStatement(channel: String, filename: String, sep: String): String { + val data = "DOW${statement.comparison.symbol} LOOP START${sep}${statement.comparison.toString()}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}" + + return renderHeader(channel, filename, statement.startLine(), sep) + data + } + + override fun renderLoop(channel: String, filename: String, sep: String): String { + val data = "DOW${statement.comparison.symbol} LOOP START${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}" + + return renderHeader(channel, filename, statement.startLine(), sep) + data + } +} + +class DOWxxStatementExecutionLogEnd(programName: String, val statement: DOWxxStmt, val elapsed: Long) : LogEntry(programName) { + override fun toString(): String { + return "ending DOWxx LOOP" + } + + override fun renderStatement(channel: String, filename: String, sep: String): String { + return renderHeader(channel, filename, statement.endLine(), sep) + "DOWxx LOOP END" + } + + override fun renderPerformance(channel: String, filename: String, sep: String): String { + val data = "DOW${statement.comparison.symbol} LOOP END${sep}${statement.comparison.toString()}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}${sep}${elapsed}${sep}ms" + + return renderHeader(channel, filename, statement.endLine(), sep) + data + } + override fun renderLoop(channel: String, filename: String, sep: String): String { + val data = "DOW${statement.comparison.symbol} LOOP END" + + return renderHeader(channel, filename, statement.endLine(), sep) + data + } +} + class DouStatemenExecutionLogStart(programName: String, val statement: DouStmt) : LogEntry(programName) { override fun toString(): String { return "executing DOU LOOP" From 1a5060415b78c073d7dbf6b01be9a27e4dc58b8f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 9 Feb 2024 17:03:41 +0100 Subject: [PATCH 070/423] Implemented `DOWxxStmt` class with the logic of `DOWEQ` --- .../smeup/rpgparser/parsing/ast/statements.kt | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index d1532c8b0..695132b7e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -23,10 +23,9 @@ import com.smeup.dbnative.file.Result import com.smeup.rpgparser.MuteParser import com.smeup.rpgparser.execution.MainExecutionContext import com.smeup.rpgparser.interpreter.* -import com.smeup.rpgparser.parsing.parsetreetoast.acceptBody +import com.smeup.rpgparser.parsing.parsetreetoast.* import com.smeup.rpgparser.parsing.parsetreetoast.error import com.smeup.rpgparser.parsing.parsetreetoast.isInt -import com.smeup.rpgparser.parsing.parsetreetoast.toAst import com.smeup.rpgparser.utils.ComparisonOperator import com.smeup.rpgparser.utils.divideAtIndex import com.smeup.rpgparser.utils.resizeTo @@ -1219,6 +1218,41 @@ data class DisplayStmt(val factor1: Expression?, val response: Expression?, over } } +data class DOWxxStmt( + val comparison: ComparisonOperator, + val factor1: Expression, + val factor2: Expression, + override val body: List, + override val position: Position? = null +): Statement(position), CompositeStatement { + fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Expression, factor2: Expression): Boolean { + return when(comparison) { + ComparisonOperator.EQ -> this.eval(factor1) == this.eval(factor2) + else -> todo() + } + } + + override fun execute(interpreter: InterpreterCore) { + val startTime = System.currentTimeMillis() + try { + interpreter.log { DOWxxStatementExecutionLogStart(interpreter.getInterpretationContext().currentProgramName, this) } + while (interpreter.compare(comparison, factor1, factor2)) { + interpreter.execute(body) + } + } catch (e: LeaveException) { + // nothing to do here + interpreter.log { + val elapsed = System.currentTimeMillis() - startTime + DOWxxStatementExecutionLogEnd( + interpreter.getInterpretationContext().currentProgramName, + this, + elapsed, + ) + } + } + } +} + @Serializable data class DoStmt( val endLimit: Expression, From 82804a5c620f55bce879021ab7738032451390e3 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 9 Feb 2024 17:05:54 +0100 Subject: [PATCH 071/423] Implemented, for `BlockContext.toAst, a case when the object is an `csDOWxx`. Then the `CsDOWxxContext.toAst` with logic `DOWEQ` --- .../parsing/parsetreetoast/statements.kt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 166579e15..c5f21433c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -52,12 +52,32 @@ internal fun BlockContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) ) } this.begindow() != null -> this.begindow().toAst(blockContext = this, conf = conf) + this.csDOWxx() != null -> this.csDOWxx().toAst(blockContext = this, conf = conf) this.forstatement() != null -> this.forstatement().toAst(conf) this.begindou() != null -> this.begindou().toAst(blockContext = this, conf = conf) else -> todo(message = "Missing composite statement implementation for this block: ${this.text}", conf = conf) } } +internal fun RpgParser.CsDOWxxContext.toAst(blockContext: BlockContext, conf: ToAstConfiguration = ToAstConfiguration()): DOWxxStmt { + val comparison = when { + this.csDOWEQ() != null -> ComparisonOperator.EQ + else -> todo(conf = conf) + } + val factor2 = when { + this.csDOWEQ() != null -> this.csDOWEQ().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) + else -> todo(conf = conf) + } + + return DOWxxStmt( + comparison = comparison, + factor1 = this.factor1.content.toAst(conf = conf), + factor2 = factor2, + position = toPosition(conf.considerPosition), + body = blockContext.statement().map { it.toAst(conf) }, + ) +} + internal fun RpgParser.ForstatementContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): ForStmt { val csFOR = this.beginfor().csFOR() val assignment = csFOR.expression(0).toAst(conf) From 135d2a67787ac4e05803d55a06b68b52ff246802 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 9 Feb 2024 17:16:52 +0100 Subject: [PATCH 072/423] On the `DOWEQ` line, added the logic for `DOWNE`, `DOWGT`, `DOWGT`, `DOWGE`, `DOWLT` and `DOWLE`. --- .../com/smeup/rpgparser/parsing/ast/statements.kt | 6 +++++- .../rpgparser/parsing/parsetreetoast/statements.kt | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 695132b7e..62c28b11c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1228,7 +1228,11 @@ data class DOWxxStmt( fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Expression, factor2: Expression): Boolean { return when(comparison) { ComparisonOperator.EQ -> this.eval(factor1) == this.eval(factor2) - else -> todo() + ComparisonOperator.NE -> this.eval(factor1) != this.eval(factor2) + ComparisonOperator.GT -> this.eval(factor1) > this.eval(factor2) + ComparisonOperator.GE -> this.eval(factor1) >= this.eval(factor2) + ComparisonOperator.LT -> this.eval(factor1) < this.eval(factor2) + ComparisonOperator.LE -> this.eval(factor1) <= this.eval(factor2) } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index c5f21433c..c87a3a348 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -62,10 +62,20 @@ internal fun BlockContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) internal fun RpgParser.CsDOWxxContext.toAst(blockContext: BlockContext, conf: ToAstConfiguration = ToAstConfiguration()): DOWxxStmt { val comparison = when { this.csDOWEQ() != null -> ComparisonOperator.EQ + this.csDOWNE() != null -> ComparisonOperator.NE + this.csDOWGT() != null -> ComparisonOperator.GT + this.csDOWGE() != null -> ComparisonOperator.GE + this.csDOWLT() != null -> ComparisonOperator.LT + this.csDOWLE() != null -> ComparisonOperator.LE else -> todo(conf = conf) } val factor2 = when { this.csDOWEQ() != null -> this.csDOWEQ().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) + this.csDOWNE() != null -> this.csDOWNE().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) + this.csDOWGT() != null -> this.csDOWGT().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) + this.csDOWGE() != null -> this.csDOWGE().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) + this.csDOWLT() != null -> this.csDOWLT().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) + this.csDOWLE() != null -> this.csDOWLE().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) else -> todo(conf = conf) } From dd2376927f634e54529993545d4ee9f5e3992da8 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 08:58:03 +0100 Subject: [PATCH 073/423] Implemented case of test for `DOWNE` --- .../rpgparser/evaluation/InterpreterTest.kt | 6 + .../src/test/resources/DOWNE.rpgle | 103 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/DOWNE.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 8f8101eaf..4cfeef97e 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2228,4 +2228,10 @@ Test 6 val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") assertEquals(expected, "DOWEQ".outputOf()) } + + @Test + fun executeDOWNE() { + val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1") + assertEquals(expected, "DOWNE".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWNE.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWNE.rpgle new file mode 100644 index 000000000..d5c875000 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/DOWNE.rpgle @@ -0,0 +1,103 @@ + D RES S 10 VARYING + + + + * + * COMPARISON WITH NUMERIC + * + + D LEFT S 1 0 + D RIGHT S 1 0 + + * When LEFT and RIGHT are equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWNE 1 + C EVAL LEFT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWNE 2 + C EVAL LEFT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT are equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=1 + C 1 DOWNE RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=1 + C 2 DOWNE RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT=1 + C EVAL RIGHT=1 + C LEFT DOWNE RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT=1 + C EVAL RIGHT=2 + C LEFT DOWNE RIGHT + C EVAL RIGHT=1 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + + + * + * COMPARISON WITH STRING + * + + D LEFT_STR S 110 VARYING + D RIGHT_STR S 110 VARYING + + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='1' + C EVAL RIGHT_STR='1' + C LEFT_STR DOWNE RIGHT_STR + C EVAL RIGHT_STR='2' + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='1' + C EVAL RIGHT_STR='2' + C LEFT_STR DOWNE RIGHT_STR + C EVAL RIGHT_STR='1' + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY \ No newline at end of file From f7ec61d6351c2ae94f8a2264c62ea5b3d4f55bac Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 09:48:26 +0100 Subject: [PATCH 074/423] Implemented case of test for `DOWGT` --- .../rpgparser/evaluation/InterpreterTest.kt | 6 + .../src/test/resources/DOWGT.rpgle | 103 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/DOWGT.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 4cfeef97e..ae1d58d31 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2234,4 +2234,10 @@ Test 6 val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1") assertEquals(expected, "DOWNE".outputOf()) } + + @Test + fun executeDOWGT() { + val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") + assertEquals(expected, "DOWGT".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWGT.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWGT.rpgle new file mode 100644 index 000000000..63b2384ee --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/DOWGT.rpgle @@ -0,0 +1,103 @@ + D RES S 10 VARYING + + + + * + * COMPARISON WITH NUMERIC + * + + D LEFT S 1 0 + D RIGHT S 1 0 + + * When LEFT and RIGHT are equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=2 + C LEFT DOWGT 1 + C EVAL LEFT=1 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWGT 2 + C EVAL LEFT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT are equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=0 + C 1 DOWGT RIGHT + C EVAL RIGHT=1 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=2 + C 2 DOWGT RIGHT + C EVAL RIGHT=1 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT=2 + C EVAL RIGHT=1 + C LEFT DOWGT RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT=2 + C EVAL RIGHT=2 + C LEFT DOWGT RIGHT + C EVAL RIGHT=3 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + + + * + * COMPARISON WITH STRING + * + + D LEFT_STR S 110 VARYING + D RIGHT_STR S 110 VARYING + + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='2' + C EVAL RIGHT_STR='1' + C LEFT_STR DOWGT RIGHT_STR + C EVAL RIGHT_STR='2' + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='2' + C EVAL RIGHT_STR='2' + C LEFT_STR DOWGT RIGHT_STR + C EVAL RIGHT_STR='3' + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY \ No newline at end of file From 4ef660f3f75b90a9303409052bc44a3b0642a43f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 09:49:31 +0100 Subject: [PATCH 075/423] Added case when `value1` and `value2` are UnlimitedStringValue for `compare` in `comparison` --- .../main/kotlin/com/smeup/rpgparser/interpreter/comparison.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/comparison.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/comparison.kt index 64ced612d..59bbddd60 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/comparison.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/comparison.kt @@ -33,6 +33,7 @@ fun isSmallerThan(value1: Value, value2: Value, charset: Charset): Boolean { fun compare(value1: Value, value2: Value, charset: Charset): Comparison = when { value1 is StringValue && value2 is StringValue -> stringComparison(value1, value2, charset) + value1 is UnlimitedStringValue && value2 is UnlimitedStringValue -> stringComparison(StringValue(value1.toString()), StringValue(value2.toString()), charset) else -> value1.compareTo(value2) } From cb727911ad454e5c7d20f9d401d3dd40187e2509 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 09:51:30 +0100 Subject: [PATCH 076/423] Improved logic of `DOWxxStmt` by considering when values are both String or UnlimitedString --- .../smeup/rpgparser/parsing/ast/statements.kt | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 62c28b11c..05675a5c3 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1225,14 +1225,41 @@ data class DOWxxStmt( override val body: List, override val position: Position? = null ): Statement(position), CompositeStatement { - fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Expression, factor2: Expression): Boolean { + fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Expression, factor2: Expression, interpreter: InterpreterCore): Boolean { + val evaluationFactor1 = this.eval(factor1) + val evaluationFactor2 = this.eval(factor2) + return when(comparison) { - ComparisonOperator.EQ -> this.eval(factor1) == this.eval(factor2) - ComparisonOperator.NE -> this.eval(factor1) != this.eval(factor2) - ComparisonOperator.GT -> this.eval(factor1) > this.eval(factor2) - ComparisonOperator.GE -> this.eval(factor1) >= this.eval(factor2) - ComparisonOperator.LT -> this.eval(factor1) < this.eval(factor2) - ComparisonOperator.LE -> this.eval(factor1) <= this.eval(factor2) + ComparisonOperator.EQ -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == EQUAL + } + return evaluationFactor1 == evaluationFactor2 + } + ComparisonOperator.NE -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) != EQUAL + } + return evaluationFactor1 != evaluationFactor2 + } + ComparisonOperator.GT -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == GREATER + } + return evaluationFactor1 > evaluationFactor2 + } + ComparisonOperator.GE -> evaluationFactor1 >= evaluationFactor2 + ComparisonOperator.LT -> evaluationFactor1 < evaluationFactor2 + ComparisonOperator.LE -> evaluationFactor1 <= evaluationFactor2 } } @@ -1240,7 +1267,7 @@ data class DOWxxStmt( val startTime = System.currentTimeMillis() try { interpreter.log { DOWxxStatementExecutionLogStart(interpreter.getInterpretationContext().currentProgramName, this) } - while (interpreter.compare(comparison, factor1, factor2)) { + while (interpreter.compare(comparison, factor1, factor2, interpreter)) { interpreter.execute(body) } } catch (e: LeaveException) { From fc4e16fb30637df06834936dba9b076795d39be8 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 10:08:10 +0100 Subject: [PATCH 077/423] Resolved issues of `ktlintCheck` --- .../src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt | 4 ++-- .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 6 +++--- .../smeup/rpgparser/parsing/parsetreetoast/statements.kt | 2 +- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 3 +-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt index eda795365..111bbb2b6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt @@ -268,7 +268,7 @@ class DOWxxStatementExecutionLogStart(programName: String, val statement: DOWxxS } override fun renderStatement(channel: String, filename: String, sep: String): String { - val data = "DOW${statement.comparison.symbol} LOOP START${sep}${statement.comparison.toString()}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}" + val data = "DOW${statement.comparison.symbol} LOOP START${sep}${statement.comparison}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}" return renderHeader(channel, filename, statement.startLine(), sep) + data } @@ -290,7 +290,7 @@ class DOWxxStatementExecutionLogEnd(programName: String, val statement: DOWxxStm } override fun renderPerformance(channel: String, filename: String, sep: String): String { - val data = "DOW${statement.comparison.symbol} LOOP END${sep}${statement.comparison.toString()}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}${sep}${elapsed}${sep}ms" + val data = "DOW${statement.comparison.symbol} LOOP END${sep}${statement.comparison}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}${sep}${elapsed}${sep}ms" return renderHeader(channel, filename, statement.endLine(), sep) + data } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 05675a5c3..2789ab57d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1224,12 +1224,12 @@ data class DOWxxStmt( val factor2: Expression, override val body: List, override val position: Position? = null -): Statement(position), CompositeStatement { +) : Statement(position), CompositeStatement { fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Expression, factor2: Expression, interpreter: InterpreterCore): Boolean { val evaluationFactor1 = this.eval(factor1) val evaluationFactor2 = this.eval(factor2) - return when(comparison) { + return when (comparison) { ComparisonOperator.EQ -> { if ( (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && @@ -1277,7 +1277,7 @@ data class DOWxxStmt( DOWxxStatementExecutionLogEnd( interpreter.getInterpretationContext().currentProgramName, this, - elapsed, + elapsed ) } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index c87a3a348..7025edd58 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -84,7 +84,7 @@ internal fun RpgParser.CsDOWxxContext.toAst(blockContext: BlockContext, conf: To factor1 = this.factor1.content.toAst(conf = conf), factor2 = factor2, position = toPosition(conf.considerPosition), - body = blockContext.statement().map { it.toAst(conf) }, + body = blockContext.statement().map { it.toAst(conf) } ) } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index e5daccbe2..863b4a393 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -328,8 +328,7 @@ open class SmeupInterpreterTest : AbstractTest() { "CNT(100001)", "CNT(100000)", "CNT(100001)", - "CNT(100000)", - + "CNT(100000)" ) assertEquals(expected, "smeup/T12_A04_P07_12".outputOf()) } From b42a2866cea276d227fa68e2ef015c0cbf958a98 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 10:09:04 +0100 Subject: [PATCH 078/423] Resolved issue of `ktlintCheck` --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 2789ab57d..fd2f053db 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1255,7 +1255,7 @@ data class DOWxxStmt( ) { return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == GREATER } - return evaluationFactor1 > evaluationFactor2 + return evaluationFactor1 > evaluationFactor2 } ComparisonOperator.GE -> evaluationFactor1 >= evaluationFactor2 ComparisonOperator.LT -> evaluationFactor1 < evaluationFactor2 From 8a95b55b002f1c73445900d6d116ebec921c222d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 10:47:15 +0100 Subject: [PATCH 079/423] Added serialization for `DOWxxStmt` class --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/serialization.kt | 1 + .../main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 1 + 2 files changed, 2 insertions(+) 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 ce0574210..d7ec7a900 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 @@ -57,6 +57,7 @@ private val modules = SerializersModule { subclass(DoStmt::class) subclass(DouStmt::class) subclass(DowStmt::class) + subclass(DOWxxStmt::class) subclass(EvalStmt::class) subclass(ExecuteSubroutine::class) subclass(ForStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index fd2f053db..606a2e017 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1218,6 +1218,7 @@ data class DisplayStmt(val factor1: Expression?, val response: Expression?, over } } +@Serializable data class DOWxxStmt( val comparison: ComparisonOperator, val factor1: Expression, From 849cc58ddab3f9ff27d4ddaf8b729666e3ea4acf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 10:52:37 +0100 Subject: [PATCH 080/423] Implemented case of test for `DOWGE` --- .../rpgparser/evaluation/InterpreterTest.kt | 5 + .../src/test/resources/DOWGE.rpgle | 103 ++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/DOWGE.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index ae1d58d31..800cffa45 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2240,4 +2240,9 @@ Test 6 val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") assertEquals(expected, "DOWGT".outputOf()) } + @Test + fun executeDOWGE() { + val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") + assertEquals(expected, "DOWGE".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWGE.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWGE.rpgle new file mode 100644 index 000000000..86b153b67 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/DOWGE.rpgle @@ -0,0 +1,103 @@ + D RES S 10 VARYING + + + + * + * COMPARISON WITH NUMERIC + * + + D LEFT S 1 0 + D RIGHT S 1 0 + + * When LEFT and RIGHT are equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWGE 1 + C EVAL LEFT=0 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWGE 2 + C EVAL LEFT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT are equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=1 + C 1 DOWGE RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=3 + C 2 DOWGE RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT=1 + C EVAL RIGHT=1 + C LEFT DOWGE RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT=2 + C EVAL RIGHT=3 + C LEFT DOWGE RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + + + * + * COMPARISON WITH STRING + * + + D LEFT_STR S 110 VARYING + D RIGHT_STR S 110 VARYING + + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='1' + C EVAL RIGHT_STR='1' + C LEFT_STR DOWGE RIGHT_STR + C EVAL RIGHT_STR='2' + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='1' + C EVAL RIGHT_STR='2' + C LEFT_STR DOWGE RIGHT_STR + C EVAL RIGHT_STR='1' + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY \ No newline at end of file From 746753e72e5b490918895bcfd6318e1610d09e8f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 10:53:42 +0100 Subject: [PATCH 081/423] Improved logic for `GE` into `DOWxxStmt` class --- .../com/smeup/rpgparser/parsing/ast/statements.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 606a2e017..327651d97 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1258,7 +1258,15 @@ data class DOWxxStmt( } return evaluationFactor1 > evaluationFactor2 } - ComparisonOperator.GE -> evaluationFactor1 >= evaluationFactor2 + ComparisonOperator.GE -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset).run { this == GREATER || this == EQUAL } + } + return evaluationFactor1 >= evaluationFactor2 + } ComparisonOperator.LT -> evaluationFactor1 < evaluationFactor2 ComparisonOperator.LE -> evaluationFactor1 <= evaluationFactor2 } From e9ebd06addac892dd60461a9c07531697e56eda5 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 11:00:12 +0100 Subject: [PATCH 082/423] Implemented case of test for `DOWLT` --- .../rpgparser/evaluation/InterpreterTest.kt | 6 + .../src/test/resources/DOWLT.rpgle | 103 ++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/DOWLT.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 800cffa45..fdf3f418b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2245,4 +2245,10 @@ Test 6 val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") assertEquals(expected, "DOWGE".outputOf()) } + + @Test + fun executeDOWLT() { + val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1") + assertEquals(expected, "DOWLT".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWLT.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWLT.rpgle new file mode 100644 index 000000000..e6f20483d --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/DOWLT.rpgle @@ -0,0 +1,103 @@ + D RES S 10 VARYING + + + + * + * COMPARISON WITH NUMERIC + * + + D LEFT S 1 0 + D RIGHT S 1 0 + + * When LEFT and RIGHT are equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=2 + C LEFT DOWLT 1 + C EVAL LEFT=1 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWLT 2 + C EVAL LEFT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT are equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=0 + C 1 DOWLT RIGHT + C EVAL RIGHT=1 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=3 + C 2 DOWLT RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT=2 + C EVAL RIGHT=1 + C LEFT DOWLT RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT=2 + C EVAL RIGHT=3 + C LEFT DOWLT RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + + + * + * COMPARISON WITH STRING + * + + D LEFT_STR S 110 VARYING + D RIGHT_STR S 110 VARYING + + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='2' + C EVAL RIGHT_STR='1' + C LEFT_STR DOWLT RIGHT_STR + C EVAL RIGHT_STR='2' + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='2' + C EVAL RIGHT_STR='3' + C LEFT_STR DOWLT RIGHT_STR + C EVAL RIGHT_STR='2' + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY \ No newline at end of file From 9f426b56d3e0bdd5cccbfaec2332dc5e6e58c3af Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 11:00:31 +0100 Subject: [PATCH 083/423] Improved logic for `LT` into `DOWxxStmt` class --- .../com/smeup/rpgparser/parsing/ast/statements.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 327651d97..a98563e98 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1267,7 +1267,15 @@ data class DOWxxStmt( } return evaluationFactor1 >= evaluationFactor2 } - ComparisonOperator.LT -> evaluationFactor1 < evaluationFactor2 + ComparisonOperator.LT -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == SMALLER + } + return evaluationFactor1 < evaluationFactor2 + } ComparisonOperator.LE -> evaluationFactor1 <= evaluationFactor2 } } From 4d6b2efe1b2837dce518e2e35bbfdf6810536914 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 11:06:07 +0100 Subject: [PATCH 084/423] Implemented case of test for `DOWLE` --- .../rpgparser/evaluation/InterpreterTest.kt | 7 ++ .../src/test/resources/DOWLE.rpgle | 103 ++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/DOWLE.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index fdf3f418b..8d66806c7 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2240,6 +2240,7 @@ Test 6 val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") assertEquals(expected, "DOWGT".outputOf()) } + @Test fun executeDOWGE() { val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") @@ -2251,4 +2252,10 @@ Test 6 val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1") assertEquals(expected, "DOWLT".outputOf()) } + + @Test + fun executeDOWLE() { + val expected = listOf("1", "0", "1", "0", "1", "0", "1", "0") + assertEquals(expected, "DOWLE".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWLE.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWLE.rpgle new file mode 100644 index 000000000..78416f038 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/DOWLE.rpgle @@ -0,0 +1,103 @@ + D RES S 10 VARYING + + + + * + * COMPARISON WITH NUMERIC + * + + D LEFT S 1 0 + D RIGHT S 1 0 + + * When LEFT and RIGHT are equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWLE 1 + C EVAL LEFT=2 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with LEFT as variable + C EVAL RES=0 + C EVAL LEFT=1 + C LEFT DOWLE 0 + C EVAL LEFT=1 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT are equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=1 + C 1 DOWLE RIGHT + C EVAL RIGHT=0 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal with RIGHT as variable + C EVAL RES=0 + C EVAL RIGHT=1 + C 2 DOWLE RIGHT + C EVAL RIGHT=3 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT=1 + C EVAL RIGHT=1 + C LEFT DOWLE RIGHT + C EVAL RIGHT=0 + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT=2 + C EVAL RIGHT=1 + C LEFT DOWLE RIGHT + C EVAL RIGHT=2 + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY + + + + * + * COMPARISON WITH STRING + * + + D LEFT_STR S 110 VARYING + D RIGHT_STR S 110 VARYING + + + * When LEFT and RIGHT are equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='1' + C EVAL RIGHT_STR='1' + C LEFT_STR DOWLE RIGHT_STR + C EVAL RIGHT_STR='0' + C EVAL RES=1 + C ENDDO + * Excepted 1 + C RES DSPLY + * When LEFT and RIGHT aren't equal and both as variable + C EVAL RES=0 + C EVAL LEFT_STR='1' + C EVAL RIGHT_STR='0' + C LEFT_STR DOWLE RIGHT_STR + C EVAL RIGHT_STR='1' + C EVAL RES=1 + C ENDDO + * Excepted 0 + C RES DSPLY \ No newline at end of file From 0818c687286a83864fa21a614077911fd9e72ccc Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 11:06:33 +0100 Subject: [PATCH 085/423] Improved logic for `LE` into `DOWxxStmt` class --- .../com/smeup/rpgparser/parsing/ast/statements.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index a98563e98..5e67e9a15 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1276,7 +1276,15 @@ data class DOWxxStmt( } return evaluationFactor1 < evaluationFactor2 } - ComparisonOperator.LE -> evaluationFactor1 <= evaluationFactor2 + ComparisonOperator.LE -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset).run { this == SMALLER || this == EQUAL } + } + return evaluationFactor1 <= evaluationFactor2 + } } } From ad9682b39c5ed50d0b049540793e859b43206066 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 11:57:18 +0100 Subject: [PATCH 086/423] Fixed comments of tests --- .../src/test/resources/DOWGE.rpgle | 17 +++++++++-------- .../src/test/resources/DOWGT.rpgle | 15 ++++++++------- .../src/test/resources/DOWLE.rpgle | 9 +++++---- .../src/test/resources/DOWLT.rpgle | 17 +++++++++-------- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWGE.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWGE.rpgle index 86b153b67..5b2fb8787 100644 --- a/rpgJavaInterpreter-core/src/test/resources/DOWGE.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/DOWGE.rpgle @@ -9,7 +9,7 @@ D LEFT S 1 0 D RIGHT S 1 0 - * When LEFT and RIGHT are equal with LEFT as variable + * When LEFT and RIGHT are equal, with LEFT as variable C EVAL RES=0 C EVAL LEFT=1 C LEFT DOWGE 1 @@ -19,7 +19,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal with LEFT as variable + * When RIGHT is greater than LEFT, with LEFT as variable C EVAL RES=0 C EVAL LEFT=1 C LEFT DOWGE 2 @@ -29,7 +29,7 @@ * Excepted 0 C RES DSPLY - * When LEFT and RIGHT are equal with RIGHT as variable + * When LEFT and RIGHT are equal, with RIGHT as variable C EVAL RES=0 C EVAL RIGHT=1 C 1 DOWGE RIGHT @@ -39,7 +39,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal with RIGHT as variable + * When RIGHT is greater than LEFT, with RIGHT as variable C EVAL RES=0 C EVAL RIGHT=3 C 2 DOWGE RIGHT @@ -49,7 +49,7 @@ * Excepted 0 C RES DSPLY - * When LEFT and RIGHT are equal and both as variable + * When LEFT and RIGHT are equal, both as variable C EVAL RES=0 C EVAL LEFT=1 C EVAL RIGHT=1 @@ -60,7 +60,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal and both as variable + * When RIGHT is greater than LEFT, both as variable C EVAL RES=0 C EVAL LEFT=2 C EVAL RIGHT=3 @@ -81,7 +81,7 @@ D RIGHT_STR S 110 VARYING - * When LEFT and RIGHT are equal and both as variable + * When LEFT and RIGHT are equal, both as variable C EVAL RES=0 C EVAL LEFT_STR='1' C EVAL RIGHT_STR='1' @@ -91,7 +91,8 @@ C ENDDO * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal and both as variable + + * When RIGHT is greater than LEFT, both as variable C EVAL RES=0 C EVAL LEFT_STR='1' C EVAL RIGHT_STR='2' diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWGT.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWGT.rpgle index 63b2384ee..fa4606bf3 100644 --- a/rpgJavaInterpreter-core/src/test/resources/DOWGT.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/DOWGT.rpgle @@ -9,7 +9,7 @@ D LEFT S 1 0 D RIGHT S 1 0 - * When LEFT and RIGHT are equal with LEFT as variable + * When LEFT is greater than RIGHT, with LEFT as variable C EVAL RES=0 C EVAL LEFT=2 C LEFT DOWGT 1 @@ -19,7 +19,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal with LEFT as variable + * When LEFT isn't greater than RIGHT, with LEFT as variable C EVAL RES=0 C EVAL LEFT=1 C LEFT DOWGT 2 @@ -29,7 +29,7 @@ * Excepted 0 C RES DSPLY - * When LEFT and RIGHT are equal with RIGHT as variable + * When LEFT is greater than RIGHT, with RIGHT as variable C EVAL RES=0 C EVAL RIGHT=0 C 1 DOWGT RIGHT @@ -39,7 +39,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal with RIGHT as variable + * When LEFT isn't greater than RIGHT, with RIGHT as variable C EVAL RES=0 C EVAL RIGHT=2 C 2 DOWGT RIGHT @@ -49,7 +49,7 @@ * Excepted 0 C RES DSPLY - * When LEFT and RIGHT are equal and both as variable + * When LEFT is greater than RIGHT, both as variable C EVAL RES=0 C EVAL LEFT=2 C EVAL RIGHT=1 @@ -60,7 +60,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal and both as variable + * When LEFT and RIGHT are equal and both as variable C EVAL RES=0 C EVAL LEFT=2 C EVAL RIGHT=2 @@ -81,7 +81,7 @@ D RIGHT_STR S 110 VARYING - * When LEFT and RIGHT are equal and both as variable + * When LEFT is greater than RIGHT, both as variable C EVAL RES=0 C EVAL LEFT_STR='2' C EVAL RIGHT_STR='1' @@ -91,6 +91,7 @@ C ENDDO * Excepted 1 C RES DSPLY + * When LEFT and RIGHT aren't equal and both as variable C EVAL RES=0 C EVAL LEFT_STR='2' diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWLE.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWLE.rpgle index 78416f038..c7e0d16a1 100644 --- a/rpgJavaInterpreter-core/src/test/resources/DOWLE.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/DOWLE.rpgle @@ -19,7 +19,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal with LEFT as variable + * When LEFT isn't lower than RIGHT, with LEFT as variable C EVAL RES=0 C EVAL LEFT=1 C LEFT DOWLE 0 @@ -39,7 +39,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal with RIGHT as variable + * When LEFT isn't lower RIGHT, with RIGHT as variable C EVAL RES=0 C EVAL RIGHT=1 C 2 DOWLE RIGHT @@ -60,7 +60,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal and both as variable + * When LEFT isn't lower than RIGHT, both as variable C EVAL RES=0 C EVAL LEFT=2 C EVAL RIGHT=1 @@ -91,7 +91,8 @@ C ENDDO * Excepted 1 C RES DSPLY - * When LEFT and RIGHT aren't equal and both as variable + + * When LEFT isn't lower than RIGHT, both as variable C EVAL RES=0 C EVAL LEFT_STR='1' C EVAL RIGHT_STR='0' diff --git a/rpgJavaInterpreter-core/src/test/resources/DOWLT.rpgle b/rpgJavaInterpreter-core/src/test/resources/DOWLT.rpgle index e6f20483d..3c0adc507 100644 --- a/rpgJavaInterpreter-core/src/test/resources/DOWLT.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/DOWLT.rpgle @@ -9,7 +9,7 @@ D LEFT S 1 0 D RIGHT S 1 0 - * When LEFT and RIGHT are equal with LEFT as variable + * When LEFT isn't lower than RIGHT, with LEFT as variable C EVAL RES=0 C EVAL LEFT=2 C LEFT DOWLT 1 @@ -19,7 +19,7 @@ * Excepted 0 C RES DSPLY - * When LEFT and RIGHT aren't equal with LEFT as variable + * When LEFT is lower than RIGHT, with LEFT as variable C EVAL RES=0 C EVAL LEFT=1 C LEFT DOWLT 2 @@ -29,7 +29,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT are equal with RIGHT as variable + * When LEFT isn't lower than RIGHT, with RIGHT as variable C EVAL RES=0 C EVAL RIGHT=0 C 1 DOWLT RIGHT @@ -39,7 +39,7 @@ * Excepted 0 C RES DSPLY - * When LEFT and RIGHT aren't equal with RIGHT as variable + * When LEFT is lower than RIGHT, with RIGHT as variable C EVAL RES=0 C EVAL RIGHT=3 C 2 DOWLT RIGHT @@ -49,7 +49,7 @@ * Excepted 1 C RES DSPLY - * When LEFT and RIGHT are equal and both as variable + * When LEFT isn't lower than RIGHT, both as variable C EVAL RES=0 C EVAL LEFT=2 C EVAL RIGHT=1 @@ -60,7 +60,7 @@ * Excepted 0 C RES DSPLY - * When LEFT and RIGHT aren't equal and both as variable + * When LEFT is lower than RIGHT, both as variable C EVAL RES=0 C EVAL LEFT=2 C EVAL RIGHT=3 @@ -81,7 +81,7 @@ D RIGHT_STR S 110 VARYING - * When LEFT and RIGHT are equal and both as variable + * When LEFT isn't lower than RIGHT, both as variable C EVAL RES=0 C EVAL LEFT_STR='2' C EVAL RIGHT_STR='1' @@ -91,7 +91,8 @@ C ENDDO * Excepted 0 C RES DSPLY - * When LEFT and RIGHT aren't equal and both as variable + + * When LEFT is lower than RIGHT, both as variable C EVAL RES=0 C EVAL LEFT_STR='2' C EVAL RIGHT_STR='3' From 9942dea5414f286d2953b8732d66d757f14714b0 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 15:00:21 +0100 Subject: [PATCH 087/423] Implemented case of test --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T02_A60_P03.rpgle | 12 ++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f060f8edc..854b5e96a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -319,4 +319,10 @@ open class SmeupInterpreterTest : AbstractTest() { "CALL(MULANGTC30, 7 , 0)") assertEquals(expected, "smeup/T10_A60_P04-P07".outputOf()) } + + @Test + fun executeT02_A60_P03() { + val expected = listOf("Res(-A)=-10 Res( -A)= -10") + assertEquals(expected, "smeup/T02_A60_P03".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P03.rpgle new file mode 100644 index 000000000..da2a388ff --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P03.rpgle @@ -0,0 +1,12 @@ + D A60_N30A S 3 0 + D A60_N30B S 3 0 + D £DBG_Str S 100 VARYING + + D* Definizione numeri negativi (A60_N30A) + C EVAL A60_N30A=10 + C EVAL A60_N30B=-A60_N30A + C EVAL £DBG_Str='Res(-A)='+%CHAR(A60_N30B) + C EVAL A60_N30B= -A60_N30A + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' Res( -A)= '+%CHAR(A60_N30B) + C £DBG_Str DSPLY \ No newline at end of file From 62acb1d5cea29cb60d760645bf5cf69bf9ce958e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 17:07:47 +0100 Subject: [PATCH 088/423] Implemented `NegationExpr` to make a value opposite from original. --- .../com/smeup/rpgparser/interpreter/Evaluator.kt | 1 + .../rpgparser/interpreter/ExpressionEvaluation.kt | 6 ++++++ .../com/smeup/rpgparser/parsing/ast/expressions.kt | 10 ++++++++++ .../smeup/rpgparser/parsing/ast/serialization.kt | 1 + .../rpgparser/parsing/parsetreetoast/expressions.kt | 13 +++++++++++++ 5 files changed, 31 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 5da23544d..12188782a 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 @@ -60,6 +60,7 @@ interface Evaluator { fun eval(expression: EditcExpr): Value fun eval(expression: DiffExpr): Value fun eval(expression: DivExpr): Value + fun eval(expression: NegationExpr): Value fun eval(expression: ExpExpr): Value fun eval(expression: TrimrExpr): Value fun eval(expression: TrimlExpr): 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 fce6cd237..1962a27d4 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 @@ -418,6 +418,12 @@ class ExpressionEvaluation( } override fun eval(expression: OffRefExpr) = BooleanValue.FALSE + + override fun eval(expression: NegationExpr): DecimalValue { + val value = BigDecimal(0).minus(expression.value1.evalWith(this).asDecimal().value) + return DecimalValue(value) + } + override fun eval(expression: IndicatorExpr): BooleanValue { // if index is passed through expression, it means that it is a dynamic indicator val runtimeIndex = expression.indexExpression?.evalWith(this)?.asInt()?.value?.toInt() ?: expression.index 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 bcbf1683b..f29c3e948 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 @@ -211,6 +211,16 @@ data class DivExpr(var left: Expression, var right: Expression, override val pos override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } +@Serializable +data class NegationExpr( + var value1: Expression, + override val position: Position? = null +) : + Expression(position) { + + override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) +} + @Serializable data class ExpExpr(var left: Expression, var right: Expression, override val position: Position? = null) : Expression(position) { 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 ce0574210..6f1fcbc4d 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 @@ -111,6 +111,7 @@ private val modules = SerializersModule { subclass(DiffExpr::class) subclass(DifferentThanExpr::class) subclass(DivExpr::class) + subclass(NegationExpr::class) subclass(EditcExpr::class) subclass(EditwExpr::class) subclass(EofExpr::class) 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 676c6937e..297e0e0cf 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 @@ -1,6 +1,7 @@ package com.smeup.rpgparser.parsing.parsetreetoast import com.smeup.rpgparser.RpgParser +import com.smeup.rpgparser.RpgParser.ExpressionContext import com.smeup.rpgparser.parsing.ast.* import com.strumenta.kolasu.mapping.toPosition import com.strumenta.kolasu.model.Position @@ -45,6 +46,7 @@ fun RpgParser.ExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfigurat this.DIV() != null -> DivExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) this.EXP() != null -> ExpExpr(this.expression(0).toAst(conf), this.expression(1).toAst(conf)) this.indicator() != null -> this.indicator().toAst(conf) + this.unaryExpression() != null -> this.unaryExpression().toAst(conf) // FIXME it is rather ugly that we have to do this: we should get a different parse tree here this.children.size == 3 && this.children[0].text == "(" && this.children[2].text == ")" && this.children[1] is RpgParser.ExpressionContext -> (this.children[1] as RpgParser.ExpressionContext).toAst(conf) @@ -52,6 +54,17 @@ fun RpgParser.ExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfigurat } } +internal fun RpgParser.UnaryExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Expression { + if (this.children.size > 0) { + return when { + this.children[1] is ExpressionContext -> NegationExpr((this.children[1] as ExpressionContext).toAst(conf)) + else -> todo(conf = conf) + } + } + + return todo(conf = conf) +} + internal fun RpgParser.IndicatorContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): IndicatorExpr { // manage *IN( if (this.children[0].text.uppercase() == "*IN" && this.children[1].text == "(") { From 1223980796fe7ba3003d47e336f88c4180aaecdf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 12 Feb 2024 17:08:14 +0100 Subject: [PATCH 089/423] Created additional cases of test --- .../rpgparser/evaluation/InterpreterTest.kt | 6 ++++ .../src/test/resources/NEGATION.rpgle | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 1425e8d06..bcaaa150f 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2222,4 +2222,10 @@ Test 6 val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1") assertEquals(expected, "INDIC02".outputOf()) } + + @Test + fun executeNEGATION() { + val expected = listOf("-10", "10", "-10", "10") + assertEquals(expected, "NEGATION".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle b/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle new file mode 100644 index 000000000..8e9e2c685 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle @@ -0,0 +1,32 @@ + * + * WORKING WITH INDICATOR 15 AND EXPRESSIONS + * + + D NUM S 3 0 + D NUM_NEG S 3 0 + D RES S 100 VARYING + + C EVAL NUM=10 + C EVAL NUM_NEG=-NUM + C EVAL RES=%CHAR(NUM_NEG) + C* Excepted -10 + C RES DSPLY + + C EVAL NUM=0 + C EVAL NUM=-NUM_NEG + C EVAL RES=%CHAR(NUM) + C* Excepted 10 + C RES DSPLY + + + C EVAL NUM=10 + C EVAL NUM_NEG= -NUM + C EVAL RES=%CHAR(NUM_NEG) + C* Excepted -10 + C RES DSPLY + + C EVAL NUM=0 + C EVAL NUM= -NUM_NEG + C EVAL RES=%CHAR(NUM) + C* Excepted 10 + C RES DSPLY \ No newline at end of file From 357cd51430b9be4ac2c7ba044cd14ca7dad20c79 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 13 Feb 2024 09:09:35 +0100 Subject: [PATCH 090/423] Fixed `toAst` of `UnaryExpressionContext` by checking if first children is `-` too --- .../com/smeup/rpgparser/parsing/parsetreetoast/expressions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 297e0e0cf..87ab1b0d1 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 @@ -57,7 +57,7 @@ fun RpgParser.ExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfigurat internal fun RpgParser.UnaryExpressionContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Expression { if (this.children.size > 0) { return when { - this.children[1] is ExpressionContext -> NegationExpr((this.children[1] as ExpressionContext).toAst(conf)) + this.children[0].text.equals("-") && this.children[1] is ExpressionContext -> NegationExpr((this.children[1] as ExpressionContext).toAst(conf)) else -> todo(conf = conf) } } From 201e19285af50df32eb7ec2d71cef0e166294f07 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:05:35 +0000 Subject: [PATCH 091/423] Fix retrieving value from DS fields, fix DS fields not belonging to OVERLAY --- .../rpgparser/interpreter/SymbolTable.kt | 26 +++++++++++++-- .../parsetreetoast/data_definitions.kt | 23 +++++++++++++ .../evaluation/SmeupInterpreterTest.kt | 6 ++++ .../test/resources/smeup/T12_A03_P06.rpgle | 33 +++++++++++++++++++ 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A03_P06.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt index e97a3c434..e2bf1fc84 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt @@ -100,8 +100,30 @@ class SymbolTable : ISymbolTable { require(data.type.canBeAssigned(value)) { "Value $value cannot be assigned to data: $data" } - names[data.name.uppercase()] = data - return values.put(data, value.forType(data.type)) + + if (data is FieldDefinition) { + val containerValue = get(data.container) + if (data.container.isArray()) { + throw IllegalStateException("We do not yet handle an array container") + } else if (data.declaredArrayInLine != null) { + ProjectedArrayValue.forData(containerValue as DataStructValue, data).container.set(data, value.forType(data.type)) + return ProjectedArrayValue.forData(containerValue as DataStructValue, data) + } else { + // Should be always a DataStructValue + if (containerValue is DataStructValue) { + containerValue.set(data, value.forType(data.type)) + return coerce(containerValue[data], data.type) + } else if (containerValue is OccurableDataStructValue) { + containerValue.value().set(data, value.forType(data.type)) + return coerce(containerValue.value()[data], data.type) + } else { + throw IllegalStateException("The container value is expected to be a DataStructValue, instead it is $containerValue") + } + } + } else { + names[data.name.uppercase()] = data + return values.put(data, value.forType(data.type)) + } } override fun getValues(): Map { 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 c6e445a22..a08c3495f 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 @@ -721,6 +721,7 @@ internal fun RpgParser.Dcl_dsContext.calculateFieldInfos(knownDataDefinitions: C } fieldsList.considerFieldSequence() fieldsList.considerOverlays(this.name) + fieldsList.considerNotInOverlayFields() fieldsList.fields.filter { it.startOffset == null }.let { require(it.isEmpty()) { "Start offset not calculated for fields ${it.joinToString(separator = ", ") { it.name }}" } } @@ -933,6 +934,28 @@ class FieldsList(val fields: List) { } } + fun considerNotInOverlayFields() { + val declareDimElement = fields.filter { it.arraySizeDeclared != null }.firstOrNull() + if (declareDimElement != null) { + val totalArraySize = declareDimElement.arraySizeDeclared!! * declareDimElement.endOffset!! + var startOffsetIndex = totalArraySize + fields.forEachIndexed { index, field -> + + if (field.startOffset == null) { + if (field.overlayInfo == null) { + field.startOffset = startOffsetIndex + } + } + if (field.endOffset == null) { + if (field.overlayInfo == null) { + field.endOffset = (field.startOffset!! + field.elementSize!!) + startOffsetIndex = field.endOffset!! + } + } + } + } + } + fun isNotEmpty() = fields.isNotEmpty() } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f060f8edc..9bb341af2 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -319,4 +319,10 @@ open class SmeupInterpreterTest : AbstractTest() { "CALL(MULANGTC30, 7 , 0)") assertEquals(expected, "smeup/T10_A60_P04-P07".outputOf()) } + + @Test + fun executeT12_A03_P06() { + val expected = listOf("LOOP:1,2,3,4") + assertEquals(expected, "smeup/T12_A03_P06".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A03_P06.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A03_P06.rpgle new file mode 100644 index 000000000..d1499da07 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A03_P06.rpgle @@ -0,0 +1,33 @@ + D £DBG_Pas S 3 + D £DBG_Str S 100 + D DS + D SPAG 50 DIM(2) + D SPAG_CD 15 OVERLAY(SPAG:01) + D SPAG_DS 35 OVERLAY(SPAG:*NEXT) + D $PA 5 0 + D NPA 5 0 + * + C EXSR SEZ_T12_A03 + C SETON LR + * + *--------------------------------------------------------------- + RD* Errori programma MULANGT12 sezione A03 + *--------------------------------------------------------------* + C SEZ_T12_A03 BEGSR + OA* A£.CDOP(FOR;DS) + D* ciclo FOR con Lettura con indice e limite da DS + C EVAL £DBG_Pas='P06' + C EVAL £DBG_Str='LOOP: ' + C EVAL $PA=4 + C CLEAR SPAG + * + C FOR NPA=1 To $PA + C IF NPA>1 + C EVAL £DBG_Str=%TRIM(£DBG_Str)+',' + C ENDIF + C EVAL £DBG_Str=%TRIM(£DBG_Str)+%char(NPA) + C ENDFOR + * + C £DBG_Str DSPLY + * + C ENDSR \ No newline at end of file From 92bfc5c7e40a9a4390bf2a3e5ad83d3c9d60d5c2 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:30:20 +0000 Subject: [PATCH 092/423] add BIFCHECK --- .../smeup/rpgparser/evaluation/InterpreterTest.kt | 5 +++++ .../src/test/resources/BIFCHECK.rpgle | 15 +++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/BIFCHECK.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 1425e8d06..ef4519653 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2222,4 +2222,9 @@ Test 6 val expected = listOf("0", "1", "0", "1", "0", "1", "0", "1", "0", "1", "0", "1") assertEquals(expected, "INDIC02".outputOf()) } + + @Test + fun executeBIFCHECK() { + assertEquals(listOf("ok"), outputOf("BIFCHECK")) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/BIFCHECK.rpgle b/rpgJavaInterpreter-core/src/test/resources/BIFCHECK.rpgle new file mode 100644 index 000000000..93faeadbb --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/BIFCHECK.rpgle @@ -0,0 +1,15 @@ + D name S 30A + D name2 S 4A + D pos S 5U 0 + D £DBG_Str S 30 + D £DBG_Pas S 3 + D alphabet C 'ABCDEFGHIJKLMNOPQRSTUVWXYZ + + D abcdefghijklmnopqrstuvwxyz + + D 0123456789+/' + * + C IF %CHECK(alphabet: 'Antonio Cosentino 123')= 0 + C EVAL £DBG_Str='ok' + C ELSE + C EVAL £DBG_Str='ko' + C ENDIF + C £DBG_Str DSPLY From 9a6e99bcb578348104e8fae52d31bbb202d52ba3 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:42:13 +0000 Subject: [PATCH 093/423] split T04_15 into 3 tests --- .../evaluation/SmeupInterpreterTest.kt | 22 ++++++-- .../{T04_A15.rpgle => T04_A15_P01.rpgle} | 51 +------------------ .../test/resources/smeup/T04_A15_P02.rpgle | 18 +++++++ .../test/resources/smeup/T04_A15_P03.rpgle | 28 ++++++++++ 4 files changed, 65 insertions(+), 54 deletions(-) rename rpgJavaInterpreter-core/src/test/resources/smeup/{T04_A15.rpgle => T04_A15_P01.rpgle} (60%) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P02.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 8c2a9ceef..fe10c6e46 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -321,7 +321,7 @@ open class SmeupInterpreterTest : AbstractTest() { } @Test - fun executeT04_A15() { + fun executeT04_A15_P01() { val expected = listOf( "P01_01(8)", "P01_02(13)", @@ -334,13 +334,27 @@ open class SmeupInterpreterTest : AbstractTest() { "P01_09(2)", "P01_10(1)", "P01_11(2)", - "P01_12(0)", + "P01_12(0)" + ) + assertEquals(expected, "smeup/T04_A15_P01".outputOf()) + } + + @Test + fun executeT04_A15_P02() { + val expected = listOf( "P02_01(10)", - "P02_02(6)", + "P02_02(6)" + ) + assertEquals(expected, "smeup/T04_A15_P02".outputOf()) + } + + @Test + fun executeT04_A15_P03() { + val expected = listOf( "P03_01(0)", "P03_02(1)", "P03_03(ok)" ) - assertEquals(expected, "smeup/T04_A15".outputOf()) + assertEquals(expected, "smeup/T04_A15_P03".outputOf()) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P01.rpgle similarity index 60% rename from rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle rename to rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P01.rpgle index 5f13082c0..ce86bdbd9 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P01.rpgle @@ -3,19 +3,6 @@ D pos S 5U 0 D £DBG_Str S 30 D £DBG_Pas S 3 - D alphabet C 'ABCDEFGHIJKLMNOPQRSTUVWXYZ + - D abcdefghijklmnopqrstuvwxyz + - D 0123456789+/' - * - C EXSR SEZ_T04_A15 - * - C SETON LR - *--------------------------------------------------------------- - RD* Errori programma MULANGT04 sezione A15 - *--------------------------------------------------------------* - C SEZ_T04_A15 BEGSR - OA* A&.BIFN(%CHECK) - D* %CHECK semplice C EVAL £DBG_Pas='P01' * C EVAL name = ' Amit Jaiswal' @@ -78,40 +65,4 @@ C EVAL £DBG_Str='P01_12('+%char(pos)+')' C £DBG_Str DSPLY * - OA* A&.BIFN(%CHECK) - D* %CHECK con posizione - C EVAL £DBG_Pas='P02' - * - C EVAL name = 'Amit Jaiswal' - C EVAL pos = %check('Jais' : name:6) - C EVAL £DBG_Str='P02_01('+%char(pos)+')' - C £DBG_Str DSPLY - * - C EVAL name = 'Amit Jaiswal' - C EVAL pos = %check('A' : name:6) - C EVAL £DBG_Str='P02_02('+%char(pos)+')' - C £DBG_Str DSPLY - * - * - OA* A&.BIFN(%CHECK) - D* %CHECK ricerca in alfabeto - C EVAL £DBG_Pas='P03' - * - C EVAL name = 'Amit Jaiswal' - C EVAL pos = %check(alphabet: name) - C EVAL £DBG_Str='P03_01('+%char(pos)+')' - C £DBG_Str DSPLY - * - C EVAL name = '££ t abc1234' - C EVAL pos = %check(alphabet: name) - C EVAL £DBG_Str='P03_02('+%char(pos)+')' - C £DBG_Str DSPLY - * - C IF %CHECK(alphabet: 'Antonio Cosentino')= 0 - C EVAL £DBG_Str='P03_03(ok)' - C ELSE - C EVAL £DBG_Str='P03_03(ko)' - C ENDIF - C £DBG_Str DSPLY - * - C ENDSR \ No newline at end of file + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P02.rpgle new file mode 100644 index 000000000..d54c7dbf4 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P02.rpgle @@ -0,0 +1,18 @@ + D name S 30A + D pos S 5U 0 + D £DBG_Str S 30 + D £DBG_Pas S 3 + * + C EVAL £DBG_Pas='P02' + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check('Jais' : name:6) + C EVAL £DBG_Str='P02_01('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check('A' : name:6) + C EVAL £DBG_Str='P02_02('+%char(pos)+')' + C £DBG_Str DSPLY + * + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P03.rpgle new file mode 100644 index 000000000..e763b132d --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A15_P03.rpgle @@ -0,0 +1,28 @@ + D name S 30A + D pos S 5U 0 + D £DBG_Str S 30 + D £DBG_Pas S 3 + D alphabet C 'ABCDEFGHIJKLMNOPQRSTUVWXYZ + + D abcdefghijklmnopqrstuvwxyz + + D 0123456789+/' + * + C EVAL £DBG_Pas='P03' + * + C EVAL name = 'Amit Jaiswal' + C EVAL pos = %check(alphabet: name) + C EVAL £DBG_Str='P03_01('+%char(pos)+')' + C £DBG_Str DSPLY + * + C EVAL name = '££ t abc1234' + C EVAL pos = %check(alphabet: name) + C EVAL £DBG_Str='P03_02('+%char(pos)+')' + C £DBG_Str DSPLY + * + C IF %CHECK(alphabet: 'Antonio Cosentino')= 0 + C EVAL £DBG_Str='P03_03(ok)' + C ELSE + C EVAL £DBG_Str='P03_03(ko)' + C ENDIF + C £DBG_Str DSPLY + * + C SETON LR \ No newline at end of file From c76637d6c6d7c179c7b4823cdb5aeb5133bb7b4c Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 13 Feb 2024 12:09:45 +0100 Subject: [PATCH 094/423] Moved th logic of comparing from `InterpreterCore.compare` to `Value` class. --- .../com/smeup/rpgparser/interpreter/values.kt | 16 ++++- .../smeup/rpgparser/parsing/ast/statements.kt | 67 +++---------------- 2 files changed, 23 insertions(+), 60 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 e645ad3e9..6d19810ff 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 @@ -54,7 +54,21 @@ interface Value : Comparable { } return ConcreteArrayValue(elements, elementType) } - override operator fun compareTo(other: Value): Int = TODO("Cannot compare $this to $other") + + override fun compareTo(other: Value): Int { + if ( + (this is UnlimitedStringValue || this is StringValue) && + (other is UnlimitedStringValue || other is StringValue) + ) { + return compare(this, other, DEFAULT_CHARSET) + } else { + return when { + this.asDecimal() == other.asDecimal() -> EQUAL + this.asDecimal() > other.asDecimal() -> GREATER + else -> SMALLER + } + } + } } abstract class NumberValue : Value { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 5e67e9a15..5d33e03bc 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1226,65 +1226,14 @@ data class DOWxxStmt( override val body: List, override val position: Position? = null ) : Statement(position), CompositeStatement { - fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Expression, factor2: Expression, interpreter: InterpreterCore): Boolean { - val evaluationFactor1 = this.eval(factor1) - val evaluationFactor2 = this.eval(factor2) - + fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Value, factor2: Value, interpreter: InterpreterCore): Boolean { return when (comparison) { - ComparisonOperator.EQ -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == EQUAL - } - return evaluationFactor1 == evaluationFactor2 - } - ComparisonOperator.NE -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) != EQUAL - } - return evaluationFactor1 != evaluationFactor2 - } - ComparisonOperator.GT -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == GREATER - } - return evaluationFactor1 > evaluationFactor2 - } - ComparisonOperator.GE -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset).run { this == GREATER || this == EQUAL } - } - return evaluationFactor1 >= evaluationFactor2 - } - ComparisonOperator.LT -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == SMALLER - } - return evaluationFactor1 < evaluationFactor2 - } - ComparisonOperator.LE -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset).run { this == SMALLER || this == EQUAL } - } - return evaluationFactor1 <= evaluationFactor2 - } + ComparisonOperator.EQ -> factor1.compareTo(factor2) == EQUAL + ComparisonOperator.NE -> factor1.compareTo(factor2) != EQUAL + ComparisonOperator.GT -> factor1.compareTo(factor2) == GREATER + ComparisonOperator.GE -> factor1.compareTo(factor2).run { this == EQUAL || this == GREATER } + ComparisonOperator.LT -> factor1.compareTo(factor2) == SMALLER + ComparisonOperator.LE -> factor1.compareTo(factor2).run { this == EQUAL || this == SMALLER } } } @@ -1292,7 +1241,7 @@ data class DOWxxStmt( val startTime = System.currentTimeMillis() try { interpreter.log { DOWxxStatementExecutionLogStart(interpreter.getInterpretationContext().currentProgramName, this) } - while (interpreter.compare(comparison, factor1, factor2, interpreter)) { + while (interpreter.compare(comparison, interpreter.eval(factor1), interpreter.eval(factor2), interpreter)) { interpreter.execute(body) } } catch (e: LeaveException) { From a26963fe812cba62501c090d788047739a710dea Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 13 Feb 2024 13:17:37 +0100 Subject: [PATCH 095/423] Improved computation about negation of value --- .../com/smeup/rpgparser/interpreter/ExpressionEvaluation.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 1962a27d4..ccd336d85 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 @@ -420,8 +420,8 @@ class ExpressionEvaluation( override fun eval(expression: OffRefExpr) = BooleanValue.FALSE override fun eval(expression: NegationExpr): DecimalValue { - val value = BigDecimal(0).minus(expression.value1.evalWith(this).asDecimal().value) - return DecimalValue(value) + val value = expression.value1.evalWith(this).asDecimal().value + return DecimalValue(-value) } override fun eval(expression: IndicatorExpr): BooleanValue { From db99b0ae514526ea2adb573f55eb3992fa168a4d Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:09:23 +0000 Subject: [PATCH 096/423] add T02_A70_P01 user case --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../test/resources/QILEGEN/\302\243MUGTP.rpgle" | 15 +++++++++++++++ .../src/test/resources/smeup/T02_A70_P01.rpgle | 11 +++++++++++ 3 files changed, 32 insertions(+) create mode 100644 "rpgJavaInterpreter-core/src/test/resources/QILEGEN/\302\243MUGTP.rpgle" create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index fe10c6e46..5bea43db6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -357,4 +357,10 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T04_A15_P03".outputOf()) } + + @Test + fun executeT02_A70_P01() { + val expected = listOf("2") + assertEquals(expected, "smeup/T02_A70_P01".outputOf()) + } } \ No newline at end of file diff --git "a/rpgJavaInterpreter-core/src/test/resources/QILEGEN/\302\243MUGTP.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/\302\243MUGTP.rpgle" new file mode 100644 index 000000000..173fbcb7d --- /dev/null +++ "b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/\302\243MUGTP.rpgle" @@ -0,0 +1,15 @@ + P£MUGTP B + D £MUGTP PI 5 0 + D XCA 15 CONST + * + D OSZ S LIKE(XCF) STATIC + * + C EVAL OSZ=XCA + * + C IF XCA='A' + C RETURN 1 + C ELSE + C RETURN 2 + C ENDIF + * + P E \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle new file mode 100644 index 000000000..62f885355 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle @@ -0,0 +1,11 @@ + D £DBG_Str S 15 + D £DBG_Pas S 10 + * + D NIDX S 5 0 + D XCF S 15 + * + C EVAL £DBG_Str=' ' + C EVAL NIDX=£MUGTP('B') + C EVAL £DBG_Str=%CHAR(NIDX) + C £DBG_Str DSPLY + /COPY QILEGEN,£MUGTP From eceb278db3cbefde81d5b9ecc682087b6ec4a697 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:32:19 +0000 Subject: [PATCH 097/423] Rename and move procedure --- .../src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" | 0 .../src/test/resources/smeup/T02_A70_P01.rpgle | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename "rpgJavaInterpreter-core/src/test/resources/QILEGEN/\302\243MUGTP.rpgle" => "rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" (100%) diff --git "a/rpgJavaInterpreter-core/src/test/resources/QILEGEN/\302\243MUGTP.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" similarity index 100% rename from "rpgJavaInterpreter-core/src/test/resources/QILEGEN/\302\243MUGTP.rpgle" rename to "rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle index 62f885355..f118ef1a6 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle @@ -8,4 +8,4 @@ C EVAL NIDX=£MUGTP('B') C EVAL £DBG_Str=%CHAR(NIDX) C £DBG_Str DSPLY - /COPY QILEGEN,£MUGTP + /COPY QPROGEN,£MULANG_P From ef9c53db5f7ae7b8ce923c241460a063f722e989 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 13 Feb 2024 16:58:49 +0000 Subject: [PATCH 098/423] change procedure --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 2 +- .../src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" | 4 ++++ .../src/test/resources/smeup/T02_A70_P01.rpgle | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 5bea43db6..fee635f7c 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -360,7 +360,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A70_P01() { - val expected = listOf("2") + val expected = listOf("1", "3") assertEquals(expected, "smeup/T02_A70_P01".outputOf()) } } \ No newline at end of file diff --git "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" index 173fbcb7d..f7c93080c 100644 --- "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" +++ "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" @@ -4,7 +4,11 @@ * D OSZ S LIKE(XCF) STATIC * + C IF OSZ=' ' C EVAL OSZ=XCA + C ELSE + C RETURN 3 + C ENDIF * C IF XCA='A' C RETURN 1 diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle index f118ef1a6..ceb1c6b87 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle @@ -5,7 +5,12 @@ D XCF S 15 * C EVAL £DBG_Str=' ' + C EVAL NIDX=£MUGTP('A') + C EVAL £DBG_Str=%CHAR(NIDX) + C £DBG_Str DSPLY + * C EVAL NIDX=£MUGTP('B') C EVAL £DBG_Str=%CHAR(NIDX) C £DBG_Str DSPLY + * /COPY QPROGEN,£MULANG_P From fb6fa2618670e0556f3f626565792f0b5dd39dd6 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 14 Feb 2024 08:29:44 +0100 Subject: [PATCH 099/423] Restored previous logic of `Value` and `DOWxxStmt` classes --- .../com/smeup/rpgparser/interpreter/values.kt | 16 +---- .../smeup/rpgparser/parsing/ast/statements.kt | 67 ++++++++++++++++--- 2 files changed, 60 insertions(+), 23 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 6d19810ff..e645ad3e9 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 @@ -54,21 +54,7 @@ interface Value : Comparable { } return ConcreteArrayValue(elements, elementType) } - - override fun compareTo(other: Value): Int { - if ( - (this is UnlimitedStringValue || this is StringValue) && - (other is UnlimitedStringValue || other is StringValue) - ) { - return compare(this, other, DEFAULT_CHARSET) - } else { - return when { - this.asDecimal() == other.asDecimal() -> EQUAL - this.asDecimal() > other.asDecimal() -> GREATER - else -> SMALLER - } - } - } + override operator fun compareTo(other: Value): Int = TODO("Cannot compare $this to $other") } abstract class NumberValue : Value { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 5d33e03bc..5e67e9a15 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1226,14 +1226,65 @@ data class DOWxxStmt( override val body: List, override val position: Position? = null ) : Statement(position), CompositeStatement { - fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Value, factor2: Value, interpreter: InterpreterCore): Boolean { + fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Expression, factor2: Expression, interpreter: InterpreterCore): Boolean { + val evaluationFactor1 = this.eval(factor1) + val evaluationFactor2 = this.eval(factor2) + return when (comparison) { - ComparisonOperator.EQ -> factor1.compareTo(factor2) == EQUAL - ComparisonOperator.NE -> factor1.compareTo(factor2) != EQUAL - ComparisonOperator.GT -> factor1.compareTo(factor2) == GREATER - ComparisonOperator.GE -> factor1.compareTo(factor2).run { this == EQUAL || this == GREATER } - ComparisonOperator.LT -> factor1.compareTo(factor2) == SMALLER - ComparisonOperator.LE -> factor1.compareTo(factor2).run { this == EQUAL || this == SMALLER } + ComparisonOperator.EQ -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == EQUAL + } + return evaluationFactor1 == evaluationFactor2 + } + ComparisonOperator.NE -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) != EQUAL + } + return evaluationFactor1 != evaluationFactor2 + } + ComparisonOperator.GT -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == GREATER + } + return evaluationFactor1 > evaluationFactor2 + } + ComparisonOperator.GE -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset).run { this == GREATER || this == EQUAL } + } + return evaluationFactor1 >= evaluationFactor2 + } + ComparisonOperator.LT -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == SMALLER + } + return evaluationFactor1 < evaluationFactor2 + } + ComparisonOperator.LE -> { + if ( + (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && + (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) + ) { + return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset).run { this == SMALLER || this == EQUAL } + } + return evaluationFactor1 <= evaluationFactor2 + } } } @@ -1241,7 +1292,7 @@ data class DOWxxStmt( val startTime = System.currentTimeMillis() try { interpreter.log { DOWxxStatementExecutionLogStart(interpreter.getInterpretationContext().currentProgramName, this) } - while (interpreter.compare(comparison, interpreter.eval(factor1), interpreter.eval(factor2), interpreter)) { + while (interpreter.compare(comparison, factor1, factor2, interpreter)) { interpreter.execute(body) } } catch (e: LeaveException) { From d61b8c4eb6d9482b162f19a564e546a77fa50a0e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 14 Feb 2024 09:01:09 +0100 Subject: [PATCH 100/423] Improved `DOWxxStmt` by removing `compare` extension function of InterpreterCore` and by using `comparisonOperator.verify` in `execute` to compare the two factors. --- .../com/smeup/rpgparser/interpreter/logs.kt | 8 +-- .../smeup/rpgparser/parsing/ast/statements.kt | 66 +------------------ .../parsing/parsetreetoast/statements.kt | 2 +- 3 files changed, 7 insertions(+), 69 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt index 111bbb2b6..452bceb9d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt @@ -268,13 +268,13 @@ class DOWxxStatementExecutionLogStart(programName: String, val statement: DOWxxS } override fun renderStatement(channel: String, filename: String, sep: String): String { - val data = "DOW${statement.comparison.symbol} LOOP START${sep}${statement.comparison}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}" + val data = "DOW${statement.comparisonOperator.symbol} LOOP START${sep}${statement.comparisonOperator}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}" return renderHeader(channel, filename, statement.startLine(), sep) + data } override fun renderLoop(channel: String, filename: String, sep: String): String { - val data = "DOW${statement.comparison.symbol} LOOP START${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}" + val data = "DOW${statement.comparisonOperator.symbol} LOOP START${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}" return renderHeader(channel, filename, statement.startLine(), sep) + data } @@ -290,12 +290,12 @@ class DOWxxStatementExecutionLogEnd(programName: String, val statement: DOWxxStm } override fun renderPerformance(channel: String, filename: String, sep: String): String { - val data = "DOW${statement.comparison.symbol} LOOP END${sep}${statement.comparison}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}${sep}${elapsed}${sep}ms" + val data = "DOW${statement.comparisonOperator.symbol} LOOP END${sep}${statement.comparisonOperator}${sep}LEFT: ${statement.factor1.render()}/RIGHT ${statement.factor2.render()}${sep}${elapsed}${sep}ms" return renderHeader(channel, filename, statement.endLine(), sep) + data } override fun renderLoop(channel: String, filename: String, sep: String): String { - val data = "DOW${statement.comparison.symbol} LOOP END" + val data = "DOW${statement.comparisonOperator.symbol} LOOP END" return renderHeader(channel, filename, statement.endLine(), sep) + data } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 5e67e9a15..0e4a99e7c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1220,79 +1220,17 @@ data class DisplayStmt(val factor1: Expression?, val response: Expression?, over @Serializable data class DOWxxStmt( - val comparison: ComparisonOperator, + val comparisonOperator: ComparisonOperator, val factor1: Expression, val factor2: Expression, override val body: List, override val position: Position? = null ) : Statement(position), CompositeStatement { - fun InterpreterCore.compare(comparison: ComparisonOperator, factor1: Expression, factor2: Expression, interpreter: InterpreterCore): Boolean { - val evaluationFactor1 = this.eval(factor1) - val evaluationFactor2 = this.eval(factor2) - - return when (comparison) { - ComparisonOperator.EQ -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == EQUAL - } - return evaluationFactor1 == evaluationFactor2 - } - ComparisonOperator.NE -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) != EQUAL - } - return evaluationFactor1 != evaluationFactor2 - } - ComparisonOperator.GT -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == GREATER - } - return evaluationFactor1 > evaluationFactor2 - } - ComparisonOperator.GE -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset).run { this == GREATER || this == EQUAL } - } - return evaluationFactor1 >= evaluationFactor2 - } - ComparisonOperator.LT -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset) == SMALLER - } - return evaluationFactor1 < evaluationFactor2 - } - ComparisonOperator.LE -> { - if ( - (evaluationFactor1 is UnlimitedStringValue || evaluationFactor1 is StringValue) && - (evaluationFactor2 is UnlimitedStringValue || evaluationFactor2 is StringValue) - ) { - return compare(evaluationFactor1, evaluationFactor2, interpreter.getLocalizationContext().charset).run { this == SMALLER || this == EQUAL } - } - return evaluationFactor1 <= evaluationFactor2 - } - } - } - override fun execute(interpreter: InterpreterCore) { val startTime = System.currentTimeMillis() try { interpreter.log { DOWxxStatementExecutionLogStart(interpreter.getInterpretationContext().currentProgramName, this) } - while (interpreter.compare(comparison, factor1, factor2, interpreter)) { + while (comparisonOperator.verify(factor1, factor2, interpreter, interpreter.getLocalizationContext().charset).isVerified) { interpreter.execute(body) } } catch (e: LeaveException) { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 7025edd58..5d6a64cd6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -80,7 +80,7 @@ internal fun RpgParser.CsDOWxxContext.toAst(blockContext: BlockContext, conf: To } return DOWxxStmt( - comparison = comparison, + comparisonOperator = comparison, factor1 = this.factor1.content.toAst(conf = conf), factor2 = factor2, position = toPosition(conf.considerPosition), From f62e2e34f7f2280651cdb467171b9b6b873a606f Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 14 Feb 2024 10:36:11 +0000 Subject: [PATCH 101/423] pass main program variables to sub-procedures sub-procedures must have access to callers' variables --- .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 5ea2e886a..d7c3f373e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -240,7 +240,7 @@ fun RContext.toAst(conf: ToAstConfiguration = ToAstConfiguration(), source: Stri // if we have no procedures, the property procedure must be null because we decided it must be optional var procedures = this.procedure().mapNotNull { - it.runParserRuleContext(conf) { context -> kotlin.runCatching { context.toAst(conf) }.getOrNull() } + it.runParserRuleContext(conf) { context -> kotlin.runCatching { context.toAst(conf, dataDefinitions) }.getOrNull() } }.let { if (it.isEmpty()) null else it @@ -406,7 +406,7 @@ internal fun SubroutineContext.toAst(conf: ToAstConfiguration = ToAstConfigurati ) } -internal fun ProcedureContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CompilationUnit { +internal fun ProcedureContext.toAst(conf: ToAstConfiguration = ToAstConfiguration(), parentDataDefinitions: List): CompilationUnit { val procedureName = this.beginProcedure().psBegin().ps_name().text MainExecutionContext.getParsingProgramStack().peek().parsingFunctionNameStack.push(procedureName) @@ -414,7 +414,7 @@ internal fun ProcedureContext.toAst(conf: ToAstConfiguration = ToAstConfiguratio // TODO FileDefinitions // DataDefinitions - val dataDefinitions = getDataDefinitions(conf) + val dataDefinitions = getDataDefinitions(conf, parentDataDefinitions) // Procedure Parameters DataDefinitions val proceduresParamsDataDefinitions = getProceduresParamsDataDefinitions(dataDefinitions) @@ -521,12 +521,13 @@ private fun StatementContext.toDataDefinitionProvider( } } -private fun ProcedureContext.getDataDefinitions(conf: ToAstConfiguration = ToAstConfiguration()): List { +private fun ProcedureContext.getDataDefinitions(conf: ToAstConfiguration = ToAstConfiguration(), parentDataDefinitions: List): List { // We need to calculate first all the data definitions which do not contain the LIKE DS directives // then we calculate the ones with the LIKE DS clause, as they could have references to DS declared // after them val dataDefinitionProviders: MutableList = LinkedList() val knownDataDefinitions = mutableMapOf() + dataDefinitionProviders.addAll(parentDataDefinitions.map{ it.updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) }) // First pass ignore exception and all the know definitions dataDefinitionProviders.addAll(this.subprocedurestatement() From bfbfea29d44fc64f959e2f538d890aaebcb478de Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 14 Feb 2024 11:16:39 +0000 Subject: [PATCH 102/423] create static scope, pass static keyword to dataDefinition during parse, managed static repository --- .../smeup/rpgparser/interpreter/ISymbolTable.kt | 1 + .../com/smeup/rpgparser/interpreter/SymbolTable.kt | 7 +++++-- .../rpgparser/interpreter/data_definitions.kt | 14 +++++++++++--- .../parsing/parsetreetoast/data_definitions.kt | 8 +++++++- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt index e856a1b5e..c41962e48 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt @@ -21,6 +21,7 @@ import java.math.BigDecimal interface ISymbolTable { var parentSymbolTable: ISymbolTable? + var staticSymbolTable: ISymbolTable? /** * Get the program symbol table, which is the one without parentSymbolTable diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt index e97a3c434..63d60069b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt @@ -24,12 +24,14 @@ class SymbolTable : ISymbolTable { override operator fun contains(data: AbstractDataDefinition): Boolean = data in values override var parentSymbolTable: ISymbolTable? = null + override var staticSymbolTable: ISymbolTable? = null override operator fun get(data: AbstractDataDefinition): Value { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).getLocal(data) Scope.Local -> getLocal(data) - Scope.Static -> TODO() + // tony + Scope.Static -> (staticSymbolTable as SymbolTable).getLocal(data) } } @@ -86,7 +88,8 @@ class SymbolTable : ISymbolTable { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) Scope.Local -> setLocal(data, value) - Scope.Static -> TODO() + // tony + Scope.Static -> (staticSymbolTable as SymbolTable).setLocal(data, value) } } 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 34aaa4bba..5cb0d55cd 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 @@ -47,6 +47,9 @@ abstract class AbstractDataDefinition( * true means this is a constant, default false * */ @Transient open val const: Boolean = false, + + @Transient open val static: Boolean = false, + /** * This scope. Default: got by current parsing entity * */ @@ -60,7 +63,10 @@ abstract class AbstractDataDefinition( it.parsingFunctionNameStack.peek() } else null } - if (parsingFunction != null) { + if (static) + { + Scope.Static + } else if (parsingFunction != null) { Scope.Local } else Scope.Program } @@ -190,13 +196,15 @@ data class DataDefinition( override var const: Boolean = false, var paramPassedBy: ParamPassedBy = ParamPassedBy.Reference, var paramOptions: List = mutableListOf(), - @Transient var defaultValue: Value? = null + @Transient var defaultValue: Value? = null, + override val static: Boolean = false ) : AbstractDataDefinition( name = name, type = type, position = position, - const = const) { + const = const, + static = static) { override fun isArray() = type is ArrayType fun isCompileTimeArray() = type is ArrayType && type.compileTimeArray() 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 c6e445a22..4af171918 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 @@ -307,6 +307,7 @@ internal fun RpgParser.DspecContext.toAst( var elementsPerLineExpression: Expression? = null var compileTimeArray = false var varying = false + var static = false var ascend: Boolean? = null this.keyword().forEach { @@ -334,6 +335,9 @@ internal fun RpgParser.DspecContext.toAst( it.keyword_varying()?.let { varying = true } + it.keyword_static()?.let { + static = true + } } val elementSize = when { @@ -412,7 +416,9 @@ internal fun RpgParser.DspecContext.toAst( this.ds_name().text, type, initializationValue = initializationValue, - position = this.toPosition(true)) + position = this.toPosition(true), + static = static, + ) } internal fun RpgParser.DspecConstantContext.toAst( From 0f32d709ad75e0dec8f1bb2b2d5d78ccc185e5bf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 14 Feb 2024 14:53:28 +0100 Subject: [PATCH 103/423] Fixed description of `NEGATION.rpgle` --- rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle b/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle index 8e9e2c685..01cb8a763 100644 --- a/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle @@ -1,5 +1,5 @@ * - * WORKING WITH INDICATOR 15 AND EXPRESSIONS + * NEGATION OF NUMBER * D NUM S 3 0 From 96e1669c40393a036a1db85f3eb3e31ce85a8e40 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 14 Feb 2024 15:51:35 +0100 Subject: [PATCH 104/423] Added more cases of test for numbers. --- .../rpgparser/evaluation/InterpreterTest.kt | 6 +- .../src/test/resources/NEGATION_NUMBER.rpgle | 83 +++++++++++++++++++ 2 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/NEGATION_NUMBER.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index bcaaa150f..27d93d52b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2224,8 +2224,8 @@ Test 6 } @Test - fun executeNEGATION() { - val expected = listOf("-10", "10", "-10", "10") - assertEquals(expected, "NEGATION".outputOf()) + fun executeNEGATION_NUMBER() { + val expected = listOf("-10", "10", "-10", "-10", "10", "-10", "-1.50", "1.50", "-1.50", "-1.50", "1.50", "-1.50") + assertEquals(expected, "NEGATION_NUMBER".outputOf()) } } diff --git a/rpgJavaInterpreter-core/src/test/resources/NEGATION_NUMBER.rpgle b/rpgJavaInterpreter-core/src/test/resources/NEGATION_NUMBER.rpgle new file mode 100644 index 000000000..7fe6ed57c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/NEGATION_NUMBER.rpgle @@ -0,0 +1,83 @@ + * + * NEGATION OF NUMBERS + * + + D NUM S 3 0 + D NUMD S 5 2 + D NUM_NEG S 3 0 + D NUMD_NEG S 3 2 + D RES S 100 VARYING + + C EVAL NUM=10 + C EVAL NUM_NEG=-NUM + C EVAL RES=%CHAR(NUM_NEG) + C* Excepted -10 + C RES DSPLY + + C EVAL NUM=0 + C EVAL NUM=-NUM_NEG + C EVAL RES=%CHAR(NUM) + C* Excepted 10 + C RES DSPLY + + C EVAL NUM=-10 + C EVAL RES=%CHAR(NUM) + C* Excepted -10 + C RES DSPLY + + + + C EVAL NUM=10 + C EVAL NUM_NEG= -NUM + C EVAL RES=%CHAR(NUM_NEG) + C* Excepted -10 + C RES DSPLY + + C EVAL NUM=0 + C EVAL NUM= -NUM_NEG + C EVAL RES=%CHAR(NUM) + C* Excepted 10 + C RES DSPLY + + C EVAL NUM= -10 + C EVAL RES=%CHAR(NUM) + C* Excepted -10 + C RES DSPLY + + + + C EVAL NUMD=1.50 + C EVAL NUMD_NEG=-NUMD + C EVAL RES=%CHAR(NUMD_NEG) + C* Excepted -1.50 + C RES DSPLY + + C EVAL NUMD=0 + C EVAL NUMD=-NUMD_NEG + C EVAL RES=%CHAR(NUMD) + C* Excepted 1.50 + C RES DSPLY + + C EVAL NUMD= -1.50 + C EVAL RES=%CHAR(NUMD) + C* Excepted -1.50 + C RES DSPLY + + + + C EVAL NUMD=1.50 + C EVAL NUMD_NEG= -NUMD + C EVAL RES=%CHAR(NUMD_NEG) + C* Excepted -1.50 + C RES DSPLY + + C EVAL NUMD=0 + C EVAL NUMD= -NUMD_NEG + C EVAL RES=%CHAR(NUMD) + C* Excepted 1.50 + + C RES DSPLY + C EVAL NUMD= -1.50 + C EVAL RES=%CHAR(NUMD) + C* Excepted -1.50 + C RES DSPLY \ No newline at end of file From 366187e3a735c3f25c0ebab400dff42dbaac5eb1 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 14 Feb 2024 15:52:02 +0100 Subject: [PATCH 105/423] Removed old case of test --- .../src/test/resources/NEGATION.rpgle | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle b/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle deleted file mode 100644 index 01cb8a763..000000000 --- a/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle +++ /dev/null @@ -1,32 +0,0 @@ - * - * NEGATION OF NUMBER - * - - D NUM S 3 0 - D NUM_NEG S 3 0 - D RES S 100 VARYING - - C EVAL NUM=10 - C EVAL NUM_NEG=-NUM - C EVAL RES=%CHAR(NUM_NEG) - C* Excepted -10 - C RES DSPLY - - C EVAL NUM=0 - C EVAL NUM=-NUM_NEG - C EVAL RES=%CHAR(NUM) - C* Excepted 10 - C RES DSPLY - - - C EVAL NUM=10 - C EVAL NUM_NEG= -NUM - C EVAL RES=%CHAR(NUM_NEG) - C* Excepted -10 - C RES DSPLY - - C EVAL NUM=0 - C EVAL NUM= -NUM_NEG - C EVAL RES=%CHAR(NUM) - C* Excepted 10 - C RES DSPLY \ No newline at end of file From d766479d334c2b2772f5748053da496a4147c6f2 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Thu, 15 Feb 2024 16:42:33 +0000 Subject: [PATCH 106/423] Fix LIKE by using a different compileInterpreter, implement initialized property into ISymbolTable to perform the STATIC initialization just one time --- .../rpgparser/experimental/SymbolTable.kt | 6 ++- .../rpgparser/interpreter/ISymbolTable.kt | 10 +++- .../rpgparser/interpreter/SymbolTable.kt | 6 +-- .../interpreter/compile_time_interpreter.kt | 2 +- .../smeup/rpgparser/interpreter/function.kt | 2 + .../interpreter/internal_interpreter.kt | 17 +++++- .../parsetreetoast/data_definitions.kt | 54 +++++++++++++++---- .../rpgparser/parsing/parsetreetoast/misc.kt | 9 ++-- .../evaluation/SmeupInterpreterTest.kt | 1 + .../interpreter/MemorySliceStorageTest.kt | 3 +- .../QPROGEN/\302\243MULANG2_P.rpgle" | 22 ++++++++ .../QPROGEN/\302\243MULANG3_P.rpgle" | 19 +++++++ .../resources/QPROGEN/\302\243MULANG_P.rpgle" | 7 ++- 13 files changed, 128 insertions(+), 30 deletions(-) create mode 100644 "rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG2_P.rpgle" create mode 100644 "rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG3_P.rpgle" diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt index b279b0307..ab5f34d0f 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt @@ -32,12 +32,14 @@ class SymbolTable : ISymbolTable { override operator fun contains(data: AbstractDataDefinition): Boolean = data.key in values.keys override var parentSymbolTable: ISymbolTable? = null + override var staticTable: ISymbolTable? = null + override var initialized: Boolean = false override operator fun get(data: AbstractDataDefinition): Value { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).getLocal(data) Scope.Local -> getLocal(data) - Scope.Static -> TODO() + Scope.Static -> (staticSymbolTable as SymbolTable).getLocal(data) } } @@ -95,7 +97,7 @@ class SymbolTable : ISymbolTable { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) Scope.Local -> setLocal(data, value) - Scope.Static -> TODO() + Scope.Static -> (staticSymbolTable as SymbolTable).setLocal(data, value) } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt index c41962e48..f0b10bfd7 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt @@ -21,8 +21,8 @@ import java.math.BigDecimal interface ISymbolTable { var parentSymbolTable: ISymbolTable? - var staticSymbolTable: ISymbolTable? - + var staticTable: ISymbolTable? + var initialized: Boolean /** * Get the program symbol table, which is the one without parentSymbolTable * */ @@ -41,6 +41,12 @@ interface ISymbolTable { } } + val staticSymbolTable: ISymbolTable? + + get() { + return staticTable + } + /** * @return true if SymbolTable contains a variable named dataName * */ diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt index 63d60069b..3853b18d9 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt @@ -24,13 +24,12 @@ class SymbolTable : ISymbolTable { override operator fun contains(data: AbstractDataDefinition): Boolean = data in values override var parentSymbolTable: ISymbolTable? = null - override var staticSymbolTable: ISymbolTable? = null - + override var staticTable: ISymbolTable? = null + override var initialized: Boolean = false override operator fun get(data: AbstractDataDefinition): Value { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).getLocal(data) Scope.Local -> getLocal(data) - // tony Scope.Static -> (staticSymbolTable as SymbolTable).getLocal(data) } } @@ -88,7 +87,6 @@ class SymbolTable : ISymbolTable { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) Scope.Local -> setLocal(data, value) - // tony Scope.Static -> (staticSymbolTable as SymbolTable).setLocal(data, value) } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 99ae1f880..bc631d2fb 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -110,7 +110,7 @@ open class BaseCompileTimeInterpreter( it.dspec() != null -> { val name = it.dspec().ds_name().text if (name == declName) { - return it.dspec().toAst(conf = conf, knownDataDefinitions = listOf()).let { dataDefinition -> + return it.dspec().toAst(conf = conf, knownDataDefinitions = listOf(), null).let { dataDefinition -> if (dataDefinition.type is ArrayType) { dataDefinition.numberOfElements() } else throw it.dspec().ds_name().error("D spec is not an array", conf = conf) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt index 746b7c505..85e8d9791 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt @@ -17,6 +17,7 @@ package com.smeup.rpgparser.interpreter import com.smeup.rpgparser.execution.MainExecutionContext +import com.smeup.rpgparser.jvminterop.JavaSystemInterface import com.smeup.rpgparser.parsing.ast.CompilationUnit import com.smeup.rpgparser.parsing.parsetreetoast.error import com.smeup.rpgparser.parsing.parsetreetoast.resolveAndValidate @@ -77,6 +78,7 @@ open class RpgFunction(private val compilationUnit: CompilationUnit) : Function systemInterface = systemInterface, procedureName = compilationUnit.procedureName).apply { getGlobalSymbolTable().parentSymbolTable = symbolTable + getGlobalSymbolTable().staticTable = InternalInterpreter.StaticSymbolTable.getValue(systemInterface as SystemInterface) } // values passed to function in format argumentName to argumentValue diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 919c77fb6..a28052833 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -21,6 +21,7 @@ import com.smeup.dbnative.file.Record import com.smeup.rpgparser.execution.ErrorEvent import com.smeup.rpgparser.execution.ErrorEventSource import com.smeup.rpgparser.execution.MainExecutionContext +import com.smeup.rpgparser.jvminterop.JavaSystemInterface import com.smeup.rpgparser.parsing.ast.* import com.smeup.rpgparser.parsing.ast.AssignmentOperator.* import com.smeup.rpgparser.parsing.facade.SourceReference @@ -89,6 +90,20 @@ open class InternalInterpreter( return localizationContext } + class StaticSymbolTable() { + companion object { + private var instance: ISymbolTable? = null + fun getValue(systemInterface: SystemInterface): ISymbolTable { + if (instance == null) { + instance = systemInterface.getFeaturesFactory().createSymbolTable() + } else { + instance!!.initialized = true + } + return instance as ISymbolTable + } + } + } + private val globalSymbolTable = systemInterface.getFeaturesFactory().createSymbolTable() override fun getGlobalSymbolTable(): ISymbolTable { return globalSymbolTable @@ -274,7 +289,7 @@ open class InternalInterpreter( set(it, value) } - if (value != null) { + if (value != null && ((!it.static) || (it.static && !this.globalSymbolTable.staticSymbolTable?.initialized!!))) { set(it, coerce(value, it.type)) if (it is DataDefinition) { try { 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 4af171918..929996655 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 @@ -119,8 +119,6 @@ internal fun RpgParser.Keyword_extnameContext.toAst(conf: ToAstConfiguration = T ) } -// tony - internal fun RpgParser.Dcl_dsContext.toAstWithParameters(conf: ToAstConfiguration = ToAstConfiguration()): FileDefinition { val prefixContexts = this.keyword().mapNotNull { it.keyword_prefix() } val prefix: Prefix? = if (prefixContexts.isNotEmpty()) { @@ -278,12 +276,14 @@ internal fun RpgParser.Parm_fixedContext.toAst( internal fun RpgParser.DspecContext.toAst( conf: ToAstConfiguration = ToAstConfiguration(), - knownDataDefinitions: List + knownDataDefinitions: List, + parentDataDefinitions: List? ): DataDefinition { if (dspecConstant() != null) return dspecConstant().toAst(conf = conf) val compileTimeInterpreter = InjectableCompileTimeInterpreter(knownDataDefinitions, conf.compileTimeInterpreter) - + val compileTimeInterpreterParent = if (parentDataDefinitions != null) InjectableCompileTimeInterpreter(parentDataDefinitions, conf.compileTimeInterpreter) else null + val confParent = if(compileTimeInterpreterParent != null) conf.copy(compileTimeInterpreter = compileTimeInterpreterParent as CompileTimeInterpreter) else null // A Character (Fixed or Variable-length format) // B Numeric (Binary format) // C UCS-2 (Fixed or Variable-length format) @@ -319,6 +319,9 @@ internal fun RpgParser.DspecContext.toAst( } it.keyword_like()?.let { like = it.simpleExpression().toAst(conf) as AssignableExpression + if(!(like as DataRefExpr).variable.resolved && confParent != null){ + like = it.simpleExpression().toAst(confParent) as AssignableExpression + } } it.keyword_inz()?.let { initializationValue = it.simpleExpression()?.toAst(conf) @@ -342,7 +345,11 @@ internal fun RpgParser.DspecContext.toAst( val elementSize = when { like != null -> { - compileTimeInterpreter.evaluateElementSizeOf(this.rContext(), like!!, conf) + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null){ + compileTimeInterpreterParent.evaluateElementSizeOf(this.rContext(), like!!, conf) + } else { + compileTimeInterpreter.evaluateElementSizeOf(this.rContext(), like!!, conf) + } } else -> this.TO_POSITION().text.trim().let { if (it.isBlank()) null else it.toInt() } } @@ -355,7 +362,11 @@ internal fun RpgParser.DspecContext.toAst( NumberType(elementSize!! - decimalPositions, decimalPositions) } else { if (like != null) { - compileTimeInterpreter.evaluateTypeOf(this.rContext(), like!!, conf) + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null){ + compileTimeInterpreterParent.evaluateTypeOf(this.rContext(), like!!, conf) + } else { + compileTimeInterpreter.evaluateTypeOf(this.rContext(), like!!, conf) + } } else { StringType.createInstance(elementSize!!, varying) } @@ -394,7 +405,11 @@ internal fun RpgParser.DspecContext.toAst( var compileTimeRecordsPerLine: Int? = null if (compileTimeArray) { if (elementsPerLineExpression != null) { - compileTimeRecordsPerLine = compileTimeInterpreter.evaluate(this.rContext(), elementsPerLineExpression!!).asInt().value.toInt() + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null){ + compileTimeRecordsPerLine = compileTimeInterpreterParent.evaluate(this.rContext(), elementsPerLineExpression!!).asInt().value.toInt() + } else { + compileTimeRecordsPerLine = compileTimeInterpreter.evaluate(this.rContext(), elementsPerLineExpression!!).asInt().value.toInt() + } } else { compileTimeRecordsPerLine = 1 } @@ -402,12 +417,23 @@ internal fun RpgParser.DspecContext.toAst( } if (!baseType.isArray()) { - ArrayType(baseType, compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt(), compileTimeRecordsPerLine).also { - it.ascend = ascend + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null){ + ArrayType(baseType, compileTimeInterpreterParent.evaluate(this.rContext(), dim!!).asInt().value.toInt(), compileTimeRecordsPerLine).also { + it.ascend = ascend + } + } else { + ArrayType(baseType, compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt(), compileTimeRecordsPerLine).also { + it.ascend = ascend + } } } else { - val el = compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt() - (baseType as ArrayType).copy(nElements = el) + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { + val el = compileTimeInterpreterParent.evaluate(this.rContext(), dim!!).asInt().value.toInt() + (baseType as ArrayType).copy(nElements = el) + } else { + val el = compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt() + (baseType as ArrayType).copy(nElements = el) + } } } else { baseType @@ -421,6 +447,12 @@ internal fun RpgParser.DspecContext.toAst( ) } +private fun checkIfLikePresent(like: AssignableExpression?, parentDataDefinitions: List): Boolean { + val name = if(like != null) (like as DataRefExpr).variable.name else "" + val present = if(name.isNotEmpty()) parentDataDefinitions.any { it.name == name} else false + return present +} + internal fun RpgParser.DspecConstantContext.toAst( conf: ToAstConfiguration = ToAstConfiguration() ): DataDefinition { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index d7c3f373e..8d7f96bce 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -116,7 +116,7 @@ private fun RContext.getDataDefinitions( when { it.dspec() != null -> { it.dspec() - .toAst(conf, knownDataDefinitions.values.toList()) + .toAst(conf, knownDataDefinitions.values.toList(), null) .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) } it.dcl_c() != null -> { @@ -190,7 +190,6 @@ private fun FileDefinition.toDataDefinitions(): List { fun RContext.toAst(conf: ToAstConfiguration = ToAstConfiguration(), source: String? = null, copyBlocks: CopyBlocks? = null): CompilationUnit { val fileDefinitions = this.statement() - // tony .mapNotNull { statement -> when { statement.fspec_fixed() != null -> statement.fspec_fixed().runParserRuleContext(conf) { context -> @@ -527,7 +526,9 @@ private fun ProcedureContext.getDataDefinitions(conf: ToAstConfiguration = ToAst // after them val dataDefinitionProviders: MutableList = LinkedList() val knownDataDefinitions = mutableMapOf() - dataDefinitionProviders.addAll(parentDataDefinitions.map{ it.updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) }) + // dataDefinitionProviders.addAll(parentDataDefinitions.map{ it.updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) }) + // parentDataDefinitions.forEach { knownDataDefinitions.addIfNotPresent(it)} + // First pass ignore exception and all the know definitions dataDefinitionProviders.addAll(this.subprocedurestatement() @@ -544,7 +545,7 @@ private fun ProcedureContext.getDataDefinitions(conf: ToAstConfiguration = ToAst when { it.statement().dspec() != null -> { it.statement().dspec() - .toAst(conf, knownDataDefinitions.values.toList()) + .toAst(conf, knownDataDefinitions.values.toList(), parentDataDefinitions) .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) } it.statement().dcl_c() != null -> { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index fee635f7c..8b8a2feff 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -360,6 +360,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A70_P01() { + // assertASTCanBeProduced("smeup/T02_A70_P01", printTree = true) val expected = listOf("1", "3") assertEquals(expected, "smeup/T02_A70_P01".outputOf()) } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt index 377e4bcb8..16e171d64 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt @@ -33,7 +33,8 @@ val DEMO: Boolean = System.getenv("DEMO")?.toBoolean() ?: false private class SillySymbolTable : ISymbolTable { private val values = mutableMapOf() - + override var staticTable: ISymbolTable? = null + override var initialized: Boolean = false /** * @return true if SymbolTable contains a variable named dataName * */ diff --git "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG2_P.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG2_P.rpgle" new file mode 100644 index 000000000..6f94ed787 --- /dev/null +++ "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG2_P.rpgle" @@ -0,0 +1,22 @@ + P£MUGTP B + D £MUGTP PI 5 0 + D XCA 15 CONST + * + D OSZ S LIKE(XCF) STATIC + * + C IF OSZ=' ' + C EVAL OSZ=XCA + C ELSE + * QUESTO RETURN NON FUNZIONA !!! + C RETURN 3 + C ENDIF + * + C IF XCA='A' + C RETURN 1 + C ELSE + C RETURN 2 + C ENDIF + * + * MA FUNZIONA SOLO L'ULTIMO + C RETURN 5 + P E diff --git "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG3_P.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG3_P.rpgle" new file mode 100644 index 000000000..48f97028b --- /dev/null +++ "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG3_P.rpgle" @@ -0,0 +1,19 @@ + P£MUGTP B + D £MUGTP PI 5 0 + D XCA 15 CONST + * + D OSZ S LIKE(XCF) + * + C EVAL OSZ='B' + C IF OSZ=' ' + C EVAL OSZ=XCA + C IF XCA='A' + C RETURN 1 + C ELSE + C RETURN 2 + C ENDIF + C ELSE + C RETURN 3 + C ENDIF + * + P E \ No newline at end of file diff --git "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" index f7c93080c..3a901f82b 100644 --- "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" +++ "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" @@ -6,14 +6,13 @@ * C IF OSZ=' ' C EVAL OSZ=XCA - C ELSE - C RETURN 3 - C ENDIF - * C IF XCA='A' C RETURN 1 C ELSE C RETURN 2 + C ENDIF + C ELSE + C RETURN 3 C ENDIF * P E \ No newline at end of file From a3856971a0304e425c9b78a8bd3f98c08199f4c2 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 16 Feb 2024 08:17:31 +0000 Subject: [PATCH 107/423] rollback of STATIC keyword changes --- .../rpgparser/experimental/SymbolTable.kt | 6 ++--- .../rpgparser/interpreter/ISymbolTable.kt | 9 +------ .../rpgparser/interpreter/SymbolTable.kt | 9 +++---- .../rpgparser/interpreter/data_definitions.kt | 13 +++------ .../smeup/rpgparser/interpreter/function.kt | 2 -- .../interpreter/internal_interpreter.kt | 27 +++++-------------- .../parsetreetoast/data_definitions.kt | 23 +++++++--------- .../rpgparser/parsing/parsetreetoast/misc.kt | 1 - .../evaluation/SmeupInterpreterTest.kt | 2 +- .../interpreter/MemorySliceStorageTest.kt | 5 ++-- .../QPROGEN/\302\243MULANG2_P.rpgle" | 22 --------------- .../QPROGEN/\302\243MULANG3_P.rpgle" | 19 ------------- .../resources/QPROGEN/\302\243MULANG_P.rpgle" | 2 +- 13 files changed, 29 insertions(+), 111 deletions(-) delete mode 100644 "rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG2_P.rpgle" delete mode 100644 "rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG3_P.rpgle" diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt index ab5f34d0f..b279b0307 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt @@ -32,14 +32,12 @@ class SymbolTable : ISymbolTable { override operator fun contains(data: AbstractDataDefinition): Boolean = data.key in values.keys override var parentSymbolTable: ISymbolTable? = null - override var staticTable: ISymbolTable? = null - override var initialized: Boolean = false override operator fun get(data: AbstractDataDefinition): Value { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).getLocal(data) Scope.Local -> getLocal(data) - Scope.Static -> (staticSymbolTable as SymbolTable).getLocal(data) + Scope.Static -> TODO() } } @@ -97,7 +95,7 @@ class SymbolTable : ISymbolTable { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) Scope.Local -> setLocal(data, value) - Scope.Static -> (staticSymbolTable as SymbolTable).setLocal(data, value) + Scope.Static -> TODO() } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt index f0b10bfd7..e856a1b5e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt @@ -21,8 +21,7 @@ import java.math.BigDecimal interface ISymbolTable { var parentSymbolTable: ISymbolTable? - var staticTable: ISymbolTable? - var initialized: Boolean + /** * Get the program symbol table, which is the one without parentSymbolTable * */ @@ -41,12 +40,6 @@ interface ISymbolTable { } } - val staticSymbolTable: ISymbolTable? - - get() { - return staticTable - } - /** * @return true if SymbolTable contains a variable named dataName * */ diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt index 3853b18d9..9de0d059c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt @@ -24,13 +24,12 @@ class SymbolTable : ISymbolTable { override operator fun contains(data: AbstractDataDefinition): Boolean = data in values override var parentSymbolTable: ISymbolTable? = null - override var staticTable: ISymbolTable? = null - override var initialized: Boolean = false + override operator fun get(data: AbstractDataDefinition): Value { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).getLocal(data) Scope.Local -> getLocal(data) - Scope.Static -> (staticSymbolTable as SymbolTable).getLocal(data) + Scope.Static -> TODO() } } @@ -87,7 +86,7 @@ class SymbolTable : ISymbolTable { return when (data.scope) { Scope.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) Scope.Local -> setLocal(data, value) - Scope.Static -> (staticSymbolTable as SymbolTable).setLocal(data, value) + Scope.Static -> TODO() } } @@ -121,4 +120,4 @@ class SymbolTable : ISymbolTable { * @return if is empty * */ override fun isEmpty() = values.isEmpty() -} +} \ No newline at end of file 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 5cb0d55cd..6547b9737 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 @@ -48,8 +48,6 @@ abstract class AbstractDataDefinition( * */ @Transient open val const: Boolean = false, - @Transient open val static: Boolean = false, - /** * This scope. Default: got by current parsing entity * */ @@ -63,10 +61,7 @@ abstract class AbstractDataDefinition( it.parsingFunctionNameStack.peek() } else null } - if (static) - { - Scope.Static - } else if (parsingFunction != null) { + if (parsingFunction != null) { Scope.Local } else Scope.Program } @@ -196,15 +191,13 @@ data class DataDefinition( override var const: Boolean = false, var paramPassedBy: ParamPassedBy = ParamPassedBy.Reference, var paramOptions: List = mutableListOf(), - @Transient var defaultValue: Value? = null, - override val static: Boolean = false + @Transient var defaultValue: Value? = null ) : AbstractDataDefinition( name = name, type = type, position = position, - const = const, - static = static) { + const = const) { override fun isArray() = type is ArrayType fun isCompileTimeArray() = type is ArrayType && type.compileTimeArray() diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt index 85e8d9791..746b7c505 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt @@ -17,7 +17,6 @@ package com.smeup.rpgparser.interpreter import com.smeup.rpgparser.execution.MainExecutionContext -import com.smeup.rpgparser.jvminterop.JavaSystemInterface import com.smeup.rpgparser.parsing.ast.CompilationUnit import com.smeup.rpgparser.parsing.parsetreetoast.error import com.smeup.rpgparser.parsing.parsetreetoast.resolveAndValidate @@ -78,7 +77,6 @@ open class RpgFunction(private val compilationUnit: CompilationUnit) : Function systemInterface = systemInterface, procedureName = compilationUnit.procedureName).apply { getGlobalSymbolTable().parentSymbolTable = symbolTable - getGlobalSymbolTable().staticTable = InternalInterpreter.StaticSymbolTable.getValue(systemInterface as SystemInterface) } // values passed to function in format argumentName to argumentValue diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index a28052833..61d3a0090 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -21,7 +21,6 @@ import com.smeup.dbnative.file.Record import com.smeup.rpgparser.execution.ErrorEvent import com.smeup.rpgparser.execution.ErrorEventSource import com.smeup.rpgparser.execution.MainExecutionContext -import com.smeup.rpgparser.jvminterop.JavaSystemInterface import com.smeup.rpgparser.parsing.ast.* import com.smeup.rpgparser.parsing.ast.AssignmentOperator.* import com.smeup.rpgparser.parsing.facade.SourceReference @@ -90,20 +89,6 @@ open class InternalInterpreter( return localizationContext } - class StaticSymbolTable() { - companion object { - private var instance: ISymbolTable? = null - fun getValue(systemInterface: SystemInterface): ISymbolTable { - if (instance == null) { - instance = systemInterface.getFeaturesFactory().createSymbolTable() - } else { - instance!!.initialized = true - } - return instance as ISymbolTable - } - } - } - private val globalSymbolTable = systemInterface.getFeaturesFactory().createSymbolTable() override fun getGlobalSymbolTable(): ISymbolTable { return globalSymbolTable @@ -176,7 +161,7 @@ open class InternalInterpreter( // Added coerce val valueToAssign = coerce(value.asArray().getElement(i), data.type.asArray().element) dataStructValue.setSubstring(startOffset, startOffset + size, - data.type.asArray().element.toDataStructureValue(valueToAssign)) + data.type.asArray().element.toDataStructureValue(valueToAssign)) startOffset += data.stepSize } } else { @@ -240,7 +225,7 @@ open class InternalInterpreter( value = when { it.name in initialValues -> { val initialValue = initialValues[it.name] - ?: throw RuntimeException("Initial values for ${it.name} not found") + ?: throw RuntimeException("Initial values for ${it.name} not found") if (InterpreterConfiguration.enableRuntimeChecksOnAssignement) { require(initialValue.assignableTo(it.type)) { "Initial value for ${it.name} is not compatible. Passed $initialValue, type: ${it.type}" @@ -284,12 +269,12 @@ open class InternalInterpreter( val ctdata = compilationUnit.compileTimeArray(it.name) if (ctdata.name == it.name) { value = toArrayValue( - compilationUnit.compileTimeArray(it.name), - (it.type as ArrayType)) + compilationUnit.compileTimeArray(it.name), + (it.type as ArrayType)) set(it, value) } - if (value != null && ((!it.static) || (it.static && !this.globalSymbolTable.staticSymbolTable?.initialized!!))) { + if (value != null) { set(it, coerce(value, it.type)) if (it is DataDefinition) { try { @@ -1070,4 +1055,4 @@ internal fun Position.relative(): StatementReference { val programName = if (MainExecutionContext.getProgramStack().empty()) null else MainExecutionContext.getProgramStack().peek().name val copyBlocks = programName?.let { MainExecutionContext.getProgramStack().peek().cu.copyBlocks } return this.relative(programName, copyBlocks) -} +} \ No newline at end of file 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 929996655..45a90d17c 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 @@ -283,7 +283,7 @@ internal fun RpgParser.DspecContext.toAst( if (dspecConstant() != null) return dspecConstant().toAst(conf = conf) val compileTimeInterpreter = InjectableCompileTimeInterpreter(knownDataDefinitions, conf.compileTimeInterpreter) val compileTimeInterpreterParent = if (parentDataDefinitions != null) InjectableCompileTimeInterpreter(parentDataDefinitions, conf.compileTimeInterpreter) else null - val confParent = if(compileTimeInterpreterParent != null) conf.copy(compileTimeInterpreter = compileTimeInterpreterParent as CompileTimeInterpreter) else null + val confParent = if (compileTimeInterpreterParent != null) conf.copy(compileTimeInterpreter = compileTimeInterpreterParent as CompileTimeInterpreter) else null // A Character (Fixed or Variable-length format) // B Numeric (Binary format) // C UCS-2 (Fixed or Variable-length format) @@ -307,7 +307,6 @@ internal fun RpgParser.DspecContext.toAst( var elementsPerLineExpression: Expression? = null var compileTimeArray = false var varying = false - var static = false var ascend: Boolean? = null this.keyword().forEach { @@ -319,7 +318,7 @@ internal fun RpgParser.DspecContext.toAst( } it.keyword_like()?.let { like = it.simpleExpression().toAst(conf) as AssignableExpression - if(!(like as DataRefExpr).variable.resolved && confParent != null){ + if (!(like as DataRefExpr).variable.resolved && confParent != null) { like = it.simpleExpression().toAst(confParent) as AssignableExpression } } @@ -338,14 +337,11 @@ internal fun RpgParser.DspecContext.toAst( it.keyword_varying()?.let { varying = true } - it.keyword_static()?.let { - static = true - } } val elementSize = when { like != null -> { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null){ + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { compileTimeInterpreterParent.evaluateElementSizeOf(this.rContext(), like!!, conf) } else { compileTimeInterpreter.evaluateElementSizeOf(this.rContext(), like!!, conf) @@ -362,7 +358,7 @@ internal fun RpgParser.DspecContext.toAst( NumberType(elementSize!! - decimalPositions, decimalPositions) } else { if (like != null) { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null){ + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { compileTimeInterpreterParent.evaluateTypeOf(this.rContext(), like!!, conf) } else { compileTimeInterpreter.evaluateTypeOf(this.rContext(), like!!, conf) @@ -405,7 +401,7 @@ internal fun RpgParser.DspecContext.toAst( var compileTimeRecordsPerLine: Int? = null if (compileTimeArray) { if (elementsPerLineExpression != null) { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null){ + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { compileTimeRecordsPerLine = compileTimeInterpreterParent.evaluate(this.rContext(), elementsPerLineExpression!!).asInt().value.toInt() } else { compileTimeRecordsPerLine = compileTimeInterpreter.evaluate(this.rContext(), elementsPerLineExpression!!).asInt().value.toInt() @@ -417,7 +413,7 @@ internal fun RpgParser.DspecContext.toAst( } if (!baseType.isArray()) { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null){ + if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { ArrayType(baseType, compileTimeInterpreterParent.evaluate(this.rContext(), dim!!).asInt().value.toInt(), compileTimeRecordsPerLine).also { it.ascend = ascend } @@ -442,14 +438,13 @@ internal fun RpgParser.DspecContext.toAst( this.ds_name().text, type, initializationValue = initializationValue, - position = this.toPosition(true), - static = static, + position = this.toPosition(true) ) } private fun checkIfLikePresent(like: AssignableExpression?, parentDataDefinitions: List): Boolean { - val name = if(like != null) (like as DataRefExpr).variable.name else "" - val present = if(name.isNotEmpty()) parentDataDefinitions.any { it.name == name} else false + val name = if (like != null) (like as DataRefExpr).variable.name else "" + val present = if (name.isNotEmpty()) parentDataDefinitions.any { it.name == name } else false return present } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 8d7f96bce..e3d5f3f4e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -529,7 +529,6 @@ private fun ProcedureContext.getDataDefinitions(conf: ToAstConfiguration = ToAst // dataDefinitionProviders.addAll(parentDataDefinitions.map{ it.updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) }) // parentDataDefinitions.forEach { knownDataDefinitions.addIfNotPresent(it)} - // First pass ignore exception and all the know definitions dataDefinitionProviders.addAll(this.subprocedurestatement() .mapNotNull { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 8b8a2feff..05780d5d6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -361,7 +361,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A70_P01() { // assertASTCanBeProduced("smeup/T02_A70_P01", printTree = true) - val expected = listOf("1", "3") + val expected = listOf("1", "2") assertEquals(expected, "smeup/T02_A70_P01".outputOf()) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt index 16e171d64..752d5136d 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt @@ -33,8 +33,7 @@ val DEMO: Boolean = System.getenv("DEMO")?.toBoolean() ?: false private class SillySymbolTable : ISymbolTable { private val values = mutableMapOf() - override var staticTable: ISymbolTable? = null - override var initialized: Boolean = false + /** * @return true if SymbolTable contains a variable named dataName * */ @@ -239,4 +238,4 @@ open class MemorySliceStorageTest : AbstractTest() { simpleStorageTempDir.deleteRecursively() } } -} +} \ No newline at end of file diff --git "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG2_P.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG2_P.rpgle" deleted file mode 100644 index 6f94ed787..000000000 --- "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG2_P.rpgle" +++ /dev/null @@ -1,22 +0,0 @@ - P£MUGTP B - D £MUGTP PI 5 0 - D XCA 15 CONST - * - D OSZ S LIKE(XCF) STATIC - * - C IF OSZ=' ' - C EVAL OSZ=XCA - C ELSE - * QUESTO RETURN NON FUNZIONA !!! - C RETURN 3 - C ENDIF - * - C IF XCA='A' - C RETURN 1 - C ELSE - C RETURN 2 - C ENDIF - * - * MA FUNZIONA SOLO L'ULTIMO - C RETURN 5 - P E diff --git "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG3_P.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG3_P.rpgle" deleted file mode 100644 index 48f97028b..000000000 --- "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG3_P.rpgle" +++ /dev/null @@ -1,19 +0,0 @@ - P£MUGTP B - D £MUGTP PI 5 0 - D XCA 15 CONST - * - D OSZ S LIKE(XCF) - * - C EVAL OSZ='B' - C IF OSZ=' ' - C EVAL OSZ=XCA - C IF XCA='A' - C RETURN 1 - C ELSE - C RETURN 2 - C ENDIF - C ELSE - C RETURN 3 - C ENDIF - * - P E \ No newline at end of file diff --git "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" index 3a901f82b..993189693 100644 --- "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" +++ "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" @@ -2,7 +2,7 @@ D £MUGTP PI 5 0 D XCA 15 CONST * - D OSZ S LIKE(XCF) STATIC + D OSZ S LIKE(XCF) * C IF OSZ=' ' C EVAL OSZ=XCA From 5ed741abbcfd7597a4a17f8cab8fda8ed41b1274 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 16 Feb 2024 09:28:22 +0100 Subject: [PATCH 108/423] Changed the name of test `NEGATION_NUMBER` in `NEGATION` --- .../kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt | 4 ++-- .../test/resources/{NEGATION_NUMBER.rpgle => NEGATION.rpgle} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename rpgJavaInterpreter-core/src/test/resources/{NEGATION_NUMBER.rpgle => NEGATION.rpgle} (100%) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 27d93d52b..824bfbd7c 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2224,8 +2224,8 @@ Test 6 } @Test - fun executeNEGATION_NUMBER() { + fun executeNEGATION() { val expected = listOf("-10", "10", "-10", "-10", "10", "-10", "-1.50", "1.50", "-1.50", "-1.50", "1.50", "-1.50") - assertEquals(expected, "NEGATION_NUMBER".outputOf()) + assertEquals(expected, "NEGATION".outputOf()) } } diff --git a/rpgJavaInterpreter-core/src/test/resources/NEGATION_NUMBER.rpgle b/rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle similarity index 100% rename from rpgJavaInterpreter-core/src/test/resources/NEGATION_NUMBER.rpgle rename to rpgJavaInterpreter-core/src/test/resources/NEGATION.rpgle From 5d6ff03bcb0140c3f082c40c14a8de9387a4e5dd Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 16 Feb 2024 09:42:29 +0100 Subject: [PATCH 109/423] Added a test when is evaluated a negation of string variable. --- .../smeup/rpgparser/evaluation/InterpreterTest.kt | 6 ++++++ .../src/test/resources/NEGATIONERR.rpgle | 12 ++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/NEGATIONERR.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 824bfbd7c..26e54c0c5 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2228,4 +2228,10 @@ Test 6 val expected = listOf("-10", "10", "-10", "-10", "10", "-10", "-1.50", "1.50", "-1.50", "-1.50", "1.50", "-1.50") assertEquals(expected, "NEGATION".outputOf()) } + + @Test(expected = RuntimeException::class) + fun executeNEGATIONERR() { + val expected = listOf("") + assertEquals(expected, "NEGATIONERR".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/NEGATIONERR.rpgle b/rpgJavaInterpreter-core/src/test/resources/NEGATIONERR.rpgle new file mode 100644 index 000000000..782ed5665 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/NEGATIONERR.rpgle @@ -0,0 +1,12 @@ + * + * NEGATION OF STRING + * + + D STR S 100 VARYING INZ('10') + D STR_NEG S 100 VARYING + D RES S 100 VARYING + + C EVAL STR_NEG=-STR + C EVAL RES=%CHAR(STR_NEG) + C* Excepted Exception + C RES DSPLY \ No newline at end of file From 36fb19d8b2ddda3659802a44a1f47723b8db2a4d Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 16 Feb 2024 12:28:17 +0100 Subject: [PATCH 110/423] Refactor LIKE handling for procedure --- .../interpreter/compile_time_interpreter.kt | 2 +- .../parsetreetoast/data_definitions.kt | 58 +++++-------------- .../src/test/resources/PROCEDURE1.rpgle | 5 ++ 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index bc631d2fb..f9bd89bc6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -218,7 +218,7 @@ open class BaseCompileTimeInterpreter( rContext.statement() .forEach { when { - it.cspec_fixed() != null -> { + it.cspec_fixed() != null && it.cspec_fixed().cspec_fixed_standard().toAst(conf) is StatementThatCanDefineData -> { val dataDefinition = (it.cspec_fixed().cspec_fixed_standard().toAst(conf) as StatementThatCanDefineData).dataDefinition() dataDefinition.forEach { if (it.name.asValue().value == declName) { 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 45a90d17c..9b64d9647 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 @@ -281,9 +281,15 @@ internal fun RpgParser.DspecContext.toAst( ): DataDefinition { if (dspecConstant() != null) return dspecConstant().toAst(conf = conf) - val compileTimeInterpreter = InjectableCompileTimeInterpreter(knownDataDefinitions, conf.compileTimeInterpreter) - val compileTimeInterpreterParent = if (parentDataDefinitions != null) InjectableCompileTimeInterpreter(parentDataDefinitions, conf.compileTimeInterpreter) else null - val confParent = if (compileTimeInterpreterParent != null) conf.copy(compileTimeInterpreter = compileTimeInterpreterParent as CompileTimeInterpreter) else null + val compileTimeInterpreter = InjectableCompileTimeInterpreter( + knownDataDefinitions = knownDataDefinitions, + delegatedCompileTimeInterpreter = parentDataDefinitions?.let { + InjectableCompileTimeInterpreter( + it, + conf.compileTimeInterpreter + ) + } ?: conf.compileTimeInterpreter + ) // A Character (Fixed or Variable-length format) // B Numeric (Binary format) // C UCS-2 (Fixed or Variable-length format) @@ -318,9 +324,6 @@ internal fun RpgParser.DspecContext.toAst( } it.keyword_like()?.let { like = it.simpleExpression().toAst(conf) as AssignableExpression - if (!(like as DataRefExpr).variable.resolved && confParent != null) { - like = it.simpleExpression().toAst(confParent) as AssignableExpression - } } it.keyword_inz()?.let { initializationValue = it.simpleExpression()?.toAst(conf) @@ -341,11 +344,7 @@ internal fun RpgParser.DspecContext.toAst( val elementSize = when { like != null -> { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { - compileTimeInterpreterParent.evaluateElementSizeOf(this.rContext(), like!!, conf) - } else { - compileTimeInterpreter.evaluateElementSizeOf(this.rContext(), like!!, conf) - } + compileTimeInterpreter.evaluateElementSizeOf(this.rContext(), like!!, conf) } else -> this.TO_POSITION().text.trim().let { if (it.isBlank()) null else it.toInt() } } @@ -358,11 +357,7 @@ internal fun RpgParser.DspecContext.toAst( NumberType(elementSize!! - decimalPositions, decimalPositions) } else { if (like != null) { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { - compileTimeInterpreterParent.evaluateTypeOf(this.rContext(), like!!, conf) - } else { - compileTimeInterpreter.evaluateTypeOf(this.rContext(), like!!, conf) - } + compileTimeInterpreter.evaluateTypeOf(this.rContext(), like!!, conf) } else { StringType.createInstance(elementSize!!, varying) } @@ -401,11 +396,7 @@ internal fun RpgParser.DspecContext.toAst( var compileTimeRecordsPerLine: Int? = null if (compileTimeArray) { if (elementsPerLineExpression != null) { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { - compileTimeRecordsPerLine = compileTimeInterpreterParent.evaluate(this.rContext(), elementsPerLineExpression!!).asInt().value.toInt() - } else { - compileTimeRecordsPerLine = compileTimeInterpreter.evaluate(this.rContext(), elementsPerLineExpression!!).asInt().value.toInt() - } + compileTimeRecordsPerLine = compileTimeInterpreter.evaluate(this.rContext(), elementsPerLineExpression!!).asInt().value.toInt() } else { compileTimeRecordsPerLine = 1 } @@ -413,23 +404,12 @@ internal fun RpgParser.DspecContext.toAst( } if (!baseType.isArray()) { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { - ArrayType(baseType, compileTimeInterpreterParent.evaluate(this.rContext(), dim!!).asInt().value.toInt(), compileTimeRecordsPerLine).also { - it.ascend = ascend - } - } else { - ArrayType(baseType, compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt(), compileTimeRecordsPerLine).also { - it.ascend = ascend - } + ArrayType(baseType, compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt(), compileTimeRecordsPerLine).also { + it.ascend = ascend } } else { - if (!checkIfLikePresent(like, knownDataDefinitions) && compileTimeInterpreterParent != null) { - val el = compileTimeInterpreterParent.evaluate(this.rContext(), dim!!).asInt().value.toInt() - (baseType as ArrayType).copy(nElements = el) - } else { - val el = compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt() - (baseType as ArrayType).copy(nElements = el) - } + val el = compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt() + (baseType as ArrayType).copy(nElements = el) } } else { baseType @@ -442,12 +422,6 @@ internal fun RpgParser.DspecContext.toAst( ) } -private fun checkIfLikePresent(like: AssignableExpression?, parentDataDefinitions: List): Boolean { - val name = if (like != null) (like as DataRefExpr).variable.name else "" - val present = if (name.isNotEmpty()) parentDataDefinitions.any { it.name == name } else false - return present -} - internal fun RpgParser.DspecConstantContext.toAst( conf: ToAstConfiguration = ToAstConfiguration() ): DataDefinition { diff --git a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle index 64cc3b779..b80916c28 100644 --- a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle @@ -15,5 +15,10 @@ Dp 2 0 Dq 2 0 Dr 2 0 + + D MSG S 10 + + D MSG1 S LIKE(MSG) + C EVAL r=p+q PCALL1 E From 3c3ce93a8b12a486fe9e3c0148595de5e46cf1c1 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 16 Feb 2024 12:41:32 +0100 Subject: [PATCH 111/423] Fix revert --- .../smeup/rpgparser/interpreter/data_definitions.kt | 1 - .../rpgparser/interpreter/internal_interpreter.kt | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) 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 6547b9737..34aaa4bba 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 @@ -47,7 +47,6 @@ abstract class AbstractDataDefinition( * true means this is a constant, default false * */ @Transient open val const: Boolean = false, - /** * This scope. Default: got by current parsing entity * */ diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 61d3a0090..919c77fb6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -161,7 +161,7 @@ open class InternalInterpreter( // Added coerce val valueToAssign = coerce(value.asArray().getElement(i), data.type.asArray().element) dataStructValue.setSubstring(startOffset, startOffset + size, - data.type.asArray().element.toDataStructureValue(valueToAssign)) + data.type.asArray().element.toDataStructureValue(valueToAssign)) startOffset += data.stepSize } } else { @@ -225,7 +225,7 @@ open class InternalInterpreter( value = when { it.name in initialValues -> { val initialValue = initialValues[it.name] - ?: throw RuntimeException("Initial values for ${it.name} not found") + ?: throw RuntimeException("Initial values for ${it.name} not found") if (InterpreterConfiguration.enableRuntimeChecksOnAssignement) { require(initialValue.assignableTo(it.type)) { "Initial value for ${it.name} is not compatible. Passed $initialValue, type: ${it.type}" @@ -269,8 +269,8 @@ open class InternalInterpreter( val ctdata = compilationUnit.compileTimeArray(it.name) if (ctdata.name == it.name) { value = toArrayValue( - compilationUnit.compileTimeArray(it.name), - (it.type as ArrayType)) + compilationUnit.compileTimeArray(it.name), + (it.type as ArrayType)) set(it, value) } @@ -1055,4 +1055,4 @@ internal fun Position.relative(): StatementReference { val programName = if (MainExecutionContext.getProgramStack().empty()) null else MainExecutionContext.getProgramStack().peek().name val copyBlocks = programName?.let { MainExecutionContext.getProgramStack().peek().cu.copyBlocks } return this.relative(programName, copyBlocks) -} \ No newline at end of file +} From e8368e1539703e3f1fc6cb5c04228d94652ca564 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 16 Feb 2024 12:41:56 +0100 Subject: [PATCH 112/423] Add default value --- .../smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt | 2 +- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 3604340b3..dcd8c6b56 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 @@ -277,7 +277,7 @@ internal fun RpgParser.Parm_fixedContext.toAst( internal fun RpgParser.DspecContext.toAst( conf: ToAstConfiguration = ToAstConfiguration(), knownDataDefinitions: List, - parentDataDefinitions: List? + parentDataDefinitions: List? = null ): DataDefinition { if (dspecConstant() != null) return dspecConstant().toAst(conf = conf) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index e3d5f3f4e..2e27d5129 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -116,7 +116,7 @@ private fun RContext.getDataDefinitions( when { it.dspec() != null -> { it.dspec() - .toAst(conf, knownDataDefinitions.values.toList(), null) + .toAst(conf, knownDataDefinitions.values.toList()) .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) } it.dcl_c() != null -> { From f839abd5e8e6182e8a275cb365be51baf0c4291d Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 16 Feb 2024 12:44:40 +0100 Subject: [PATCH 113/423] Revert symboltable --- .../kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt | 2 +- rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt index 42ff76875..e2bf1fc84 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt @@ -142,4 +142,4 @@ class SymbolTable : ISymbolTable { * @return if is empty * */ override fun isEmpty() = values.isEmpty() -} \ No newline at end of file +} diff --git a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle index b80916c28..64cc3b779 100644 --- a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE1.rpgle @@ -15,10 +15,5 @@ Dp 2 0 Dq 2 0 Dr 2 0 - - D MSG S 10 - - D MSG1 S LIKE(MSG) - C EVAL r=p+q PCALL1 E From bc324d2f59f53eb4718e8fe22ab91966e52c53ee Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 16 Feb 2024 12:49:21 +0100 Subject: [PATCH 114/423] Revert MemorySliceStorageTest --- .../com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt index 752d5136d..377e4bcb8 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/MemorySliceStorageTest.kt @@ -238,4 +238,4 @@ open class MemorySliceStorageTest : AbstractTest() { simpleStorageTempDir.deleteRecursively() } } -} \ No newline at end of file +} From bb5173d8f94e148951c70c6496d305bb2ec33359 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 16 Feb 2024 12:57:56 +0100 Subject: [PATCH 115/423] Comments --- .../smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt | 1 + .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) 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 dcd8c6b56..39e2927a3 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 @@ -283,6 +283,7 @@ internal fun RpgParser.DspecContext.toAst( if (dspecConstant() != null) return dspecConstant().toAst(conf = conf) val compileTimeInterpreter = InjectableCompileTimeInterpreter( knownDataDefinitions = knownDataDefinitions, + // If we have a parent data definition we can use it to resolve the variable through the delegate delegatedCompileTimeInterpreter = parentDataDefinitions?.let { InjectableCompileTimeInterpreter( it, diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 2e27d5129..1e46e4896 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -526,8 +526,6 @@ private fun ProcedureContext.getDataDefinitions(conf: ToAstConfiguration = ToAst // after them val dataDefinitionProviders: MutableList = LinkedList() val knownDataDefinitions = mutableMapOf() - // dataDefinitionProviders.addAll(parentDataDefinitions.map{ it.updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) }) - // parentDataDefinitions.forEach { knownDataDefinitions.addIfNotPresent(it)} // First pass ignore exception and all the know definitions dataDefinitionProviders.addAll(this.subprocedurestatement() From 168976bc9e219e0e9d1154281a49120bc8e4c34c Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 16 Feb 2024 18:50:08 +0100 Subject: [PATCH 116/423] Add test case --- .../com/smeup/rpgparser/evaluation/InterpreterTest.kt | 5 +++++ rpgJavaInterpreter-core/src/test/resources/RETURN02.rpgle | 6 ++++++ 2 files changed, 11 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/RETURN02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 87eeed06c..286ff79a4 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -1270,6 +1270,11 @@ Test 6 assertEquals(listOf("Starting"), outputOf("RETURN01")) } + @Test + fun executeReturn02() { + assertEquals(listOf("Starting"), outputOf("RETURN02")) + } + @Test fun executeGoto01() { assertEquals(listOf("1", "2", "3", "4"), outputOf("GOTO01")) diff --git a/rpgJavaInterpreter-core/src/test/resources/RETURN02.rpgle b/rpgJavaInterpreter-core/src/test/resources/RETURN02.rpgle new file mode 100644 index 000000000..fd0a90fe2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/RETURN02.rpgle @@ -0,0 +1,6 @@ + C 'Starting' dsply + C 'A' IFEQ 'A' + C return + C ENDIF + C 'Done' dsply + C SETON LR From 26f629a240a60d9551317d553a0362c420243c1e Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 16 Feb 2024 18:50:36 +0100 Subject: [PATCH 117/423] Fix return inside a composite statement --- .../interpreter/internal_interpreter.kt | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 919c77fb6..c5b4240f8 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -360,13 +360,17 @@ open class InternalInterpreter( } } }.onFailure { - if (!MainExecutionContext.getProgramStack().isEmpty()) { - MainExecutionContext.getProgramStack().peek().cu.source?.apply { - System.err.println(it.message) - System.err.println(this.dumpSource()) + if (it is ReturnException) { + status.returnValue = it.returnValue + } else { + if (!MainExecutionContext.getProgramStack().isEmpty()) { + MainExecutionContext.getProgramStack().peek().cu.source?.apply { + System.err.println(it.message) + System.err.println(this.dumpSource()) + } } + throw it } - throw it } } @@ -382,18 +386,14 @@ open class InternalInterpreter( } override fun execute(statements: List) { - try { - var i = 0 - while (i < statements.size) { - try { - executeWithMute(statements[i++]) - } catch (e: GotoException) { - i = e.indexOfTaggedStatement(statements) - if (i < 0 || i >= statements.size) throw e - } + var i = 0 + while (i < statements.size) { + try { + executeWithMute(statements[i++]) + } catch (e: GotoException) { + i = e.indexOfTaggedStatement(statements) + if (i < 0 || i >= statements.size) throw e } - } catch (e: ReturnException) { - status.returnValue = e.returnValue } } From 590562135e0c8e931100d1f1461d0d00b22053a4 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Mon, 19 Feb 2024 10:07:25 +0000 Subject: [PATCH 118/423] add test case T02_A50_P05 --- .../evaluation/SmeupInterpreterTest.kt | 6 + .../src/test/resources/smeup/T02_A50_P5.rpgle | 10 + .../resources/smeup/metadata/CQNCOG0F.json | 257 ++++++++++++++++++ .../resources/smeup/metadata/CQNCOG1L.json | 257 ++++++++++++++++++ 4 files changed, 530 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P5.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/metadata/CQNCOG0F.json create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/metadata/CQNCOG1L.json diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index d2780010c..b751d25fa 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -382,4 +382,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Res(-A)=-10 Res( -A)= -10") assertEquals(expected, "smeup/T02_A60_P03".outputOf()) } + + @Test + fun executeT02_A50_P5() { + val expected = listOf("£C5") + assertEquals(expected, "smeup/T02_A50_P5".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P5.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P5.rpgle new file mode 100644 index 000000000..c04c5c55f --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P5.rpgle @@ -0,0 +1,10 @@ + D £DBG_Str S 10 + DCQNCOG E DS EXTNAME(CQNCOG0F) INZ + * + DK§CF DS + D K_N§TINC LIKE(N§TINC) + * + C EVAL K_N§TINC='£C5' + C £DBG_Str DSPLY + * + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/CQNCOG0F.json b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/CQNCOG0F.json new file mode 100644 index 000000000..cfd85e6da --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/CQNCOG0F.json @@ -0,0 +1,257 @@ +{"name": "CQNCOG0F", + "tableName": "CQNCOG0F", + "recordFormat": "CQNCOGR", + "fields": [ + { "fieldName": "N§DATI", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§ORAI", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":6, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DATM", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§ORAM", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":6, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§UTEN", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§WKST", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§PROG", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§FLR1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FLR2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FLR3", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§TINC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§NNOC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§DESC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":30, "varying":false}} + , { "fieldName": "N§LIVE", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§STAT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§OGG1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§OGG2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§OGG3", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TISC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§CIMP", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§DCOD", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§DCLS", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§DGRA", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":1, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DCOC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§DPRO", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§TIEM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§PAEM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COEM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TIER", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§PAER", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COER", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TIEA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§PAEA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COEA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§EDVT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COMM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§CESA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":5, "varying":false}} + , { "fieldName": "N§SEGM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§RINT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§TIIM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§PAIM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COIM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§ESMO", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§TOR1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§POR1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COR1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TOR2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§POR2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COR2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TMAT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§MATP", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TPCI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§CFAL", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":6, "varying":false}} + , { "fieldName": "N§CFAC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":6, "varying":false}} + , { "fieldName": "N§RIFI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§PNOC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TDOC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":4, "varying":false}} + , { "fieldName": "N§ARAL", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§ACOR", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§NPRG", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§CCGF", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":20, "varying":false}} + , { "fieldName": "N§TDOR", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§NDOR", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§NRIR", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":4, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DIVI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":4, "varying":false}} + , { "fieldName": "N§CAMB", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":6, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§QT01", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT02", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT03", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT04", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT05", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT06", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT07", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT08", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT09", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT10", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§VA01", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA02", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA03", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA04", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA05", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA06", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA07", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA08", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA09", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA10", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§DT01", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT02", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT03", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT04", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT05", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT06", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT07", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT08", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT09", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT10", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§COD1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§COD2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§COD3", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§COD4", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§COD5", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§NUM1", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§NUM2", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§NUM3", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§NUM4", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§NUM5", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§FL01", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL02", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL03", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL04", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL05", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL06", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL07", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL08", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL09", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL10", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL11", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL12", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL13", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL14", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL15", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL16", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL17", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL18", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL19", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL20", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + ], "accessFields": []} diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/CQNCOG1L.json b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/CQNCOG1L.json new file mode 100644 index 000000000..66cddfad9 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/CQNCOG1L.json @@ -0,0 +1,257 @@ +{"name": "CQNCOG1L", + "tableName": "CQNCOG0F", + "recordFormat": "CQNCOGR", + "fields": [ + { "fieldName": "N§DATI", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§ORAI", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":6, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DATM", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§ORAM", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":6, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§UTEN", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§WKST", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§PROG", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§FLR1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FLR2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FLR3", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§TINC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§NNOC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§DESC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":30, "varying":false}} + , { "fieldName": "N§LIVE", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§STAT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§OGG1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§OGG2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§OGG3", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TISC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§CIMP", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§DCOD", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§DCLS", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§DGRA", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":1, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DCOC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§DPRO", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§TIEM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§PAEM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COEM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TIER", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§PAER", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COER", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TIEA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§PAEA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COEA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§EDVT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COMM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§CESA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":5, "varying":false}} + , { "fieldName": "N§SEGM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§RINT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§TIIM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§PAIM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COIM", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§ESMO", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§TOR1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§POR1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COR1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TOR2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "N§POR2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§COR2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TMAT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§MATP", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TPCI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§CFAL", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":6, "varying":false}} + , { "fieldName": "N§CFAC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":6, "varying":false}} + , { "fieldName": "N§RIFI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§PNOC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§TDOC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":4, "varying":false}} + , { "fieldName": "N§ARAL", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§ACOR", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§NPRG", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§CCGF", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":20, "varying":false}} + , { "fieldName": "N§TDOR", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":3, "varying":false}} + , { "fieldName": "N§NDOR", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "N§NRIR", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":4, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DIVI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":4, "varying":false}} + , { "fieldName": "N§CAMB", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":6, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§QT01", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT02", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT03", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT04", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT05", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT06", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT07", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT08", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT09", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§QT10", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§VA01", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA02", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA03", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA04", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA05", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA06", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA07", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA08", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA09", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§VA10", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":15, "decimalDigits":6, "rpgType":"P"}} + , { "fieldName": "N§DT01", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT02", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT03", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT04", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT05", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT06", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT07", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT08", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT09", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§DT10", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "N§COD1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§COD2", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§COD3", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§COD4", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§COD5", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "N§NUM1", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§NUM2", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§NUM3", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§NUM4", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§NUM5", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":10, "decimalDigits":5, "rpgType":"P"}} + , { "fieldName": "N§FL01", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL02", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL03", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL04", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL05", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL06", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL07", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL08", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL09", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL10", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL11", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL12", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL13", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL14", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL15", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL16", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL17", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL18", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL19", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "N§FL20", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + ], "accessFields": [ "N§TINC", "N§NNOC"]} From a68476a6236847b16f87600cb90c73580de8a2b5 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Mon, 19 Feb 2024 17:31:03 +0000 Subject: [PATCH 119/423] fix undefined DS fields with LIKE --- .../parsetreetoast/data_definitions.kt | 41 ++++++++++++++++++- .../evaluation/SmeupInterpreterTest.kt | 4 +- .../{T02_A50_P5.rpgle => T02_A50_P05.rpgle} | 2 +- 3 files changed, 43 insertions(+), 4 deletions(-) rename rpgJavaInterpreter-core/src/test/resources/smeup/{T02_A50_P5.rpgle => T02_A50_P05.rpgle} (91%) 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 a08c3495f..14c91b8c4 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 @@ -705,7 +705,11 @@ internal fun RpgParser.Dcl_dsContext.calculateFieldInfos(knownDataDefinitions: C val caughtErrors = mutableListOf() val fieldsList = FieldsList(this.parm_fixed().mapNotNull { kotlin.runCatching { - it.toFieldInfo(knownDataDefinitions = knownDataDefinitions) + if (it.keyword().map { keyword -> keyword.keyword_like() }.firstOrNull() != null) { + it.toFieldInfoWithExtName(knownDataDefinitions = knownDataDefinitions) + } else { + it.toFieldInfo(knownDataDefinitions = knownDataDefinitions) + } }.onFailure { caughtErrors.add(it) }.getOrNull() @@ -779,6 +783,41 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = T position = this.toPosition(conf.considerPosition)) } +private fun RpgParser.Parm_fixedContext.toFieldInfoWithExtName(conf: ToAstConfiguration = ToAstConfiguration(), knownDataDefinitions: Collection): FieldInfo { + val keywordLike = this.keyword().first { it.keyword_like() != null }.keyword_like() + val like = keywordLike.simpleExpression().toAst(conf) as DataRefExpr + val descend = this.keyword().find { it.keyword_descend() != null } != null + + var initializationValue: Expression? = null + val hasInitValue = this.keyword().find { it.keyword_inz() != null } + if (hasInitValue != null) { + if (hasInitValue.keyword_inz().simpleExpression() != null) { + initializationValue = hasInitValue.keyword_inz().simpleExpression()?.toAst(conf) as Expression + } else { + initializationValue = if (null != this.toTypeInfo().decimalPositions) { + RealLiteral(BigDecimal.ZERO, position = toPosition()) + } else { + StringLiteral("", position = toPosition()) + } + } + } else { + this.toDSFieldInitKeyword(conf = conf)?.apply { + initializationValue = this.toAst() + } + } + + val arraySizeDeclared = this.arraySizeDeclared(conf) + return FieldInfo(this.name, + explicitStartOffset = this.explicitStartOffset(), + explicitEndOffset = if (explicitStartOffset() != null) this.explicitEndOffset() else null, + explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(like.variable.name, ignoreCase = true) }?.type, + arraySizeDeclared = this.arraySizeDeclared(conf), + arraySizeDeclaredOnThisField = this.arraySizeDeclared(conf), + initializationValue = initializationValue, + descend = descend, + position = this.toPosition(conf.considerPosition)) +} + fun RpgParser.Dcl_dsContext.declaredSize(): Int? { return if (TO_POSITION().text.trim().isNotEmpty()) { TO_POSITION().text.asInt() diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index b751d25fa..84103a716 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -384,8 +384,8 @@ open class SmeupInterpreterTest : AbstractTest() { } @Test - fun executeT02_A50_P5() { + fun executeT02_A50_P05() { val expected = listOf("£C5") - assertEquals(expected, "smeup/T02_A50_P5".outputOf(configuration = smeupConfig)) + assertEquals(expected, "smeup/T02_A50_P05".outputOf(configuration = smeupConfig)) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P5.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P05.rpgle similarity index 91% rename from rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P5.rpgle rename to rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P05.rpgle index c04c5c55f..5a751024d 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P5.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P05.rpgle @@ -5,6 +5,6 @@ D K_N§TINC LIKE(N§TINC) * C EVAL K_N§TINC='£C5' - C £DBG_Str DSPLY + C K_N§TINC DSPLY * C SETON LR \ No newline at end of file From dca03819fd4ea9fa9b588a66345ef7f1023f3c50 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 20 Feb 2024 14:46:05 +0000 Subject: [PATCH 120/423] add T02_A50_P07 and T02_A50_P08 user cases --- .../evaluation/SmeupInterpreterTest.kt | 6 +++++ .../test/resources/smeup/T02_A50_P07.rpgle | 25 +++++++++++++++++++ .../test/resources/smeup/T02_A50_P08.rpgle | 20 +++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index d2780010c..a9a1d1fad 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -382,4 +382,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Res(-A)=-10 Res( -A)= -10") assertEquals(expected, "smeup/T02_A60_P03".outputOf()) } + + @Test + fun executeT02_A50_P07() { + val expected = listOf("1,2,3,4", "4,3,2,1") + assertEquals(expected, "smeup/T02_A50_P07".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle new file mode 100644 index 000000000..62d78ab3f --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle @@ -0,0 +1,25 @@ + D £DBG_Str S 10 + D $G79FU S LIKE(£G79FU) + D $G79ME S LIKE(£G79ME) + * + C MOVEL(P) '1' £G79FU + C MOVEL(P) '2' £G79ME + C MOVEL(P) '3' $G79FU + C MOVEL(P) '4' $G79ME + * + C MOVEL(P) 'T02_A50_P08' AAA010 10 + C IF '1' = '1' + C CALL AAA010 37 + C PARM £G79FU 10 + C PARM £G79ME 10 + C PARM $G79FU + C PARM $G79ME + C ENDIF + * + C EVAL £DBG_Str=%trim(£G79FU)+','+ + C %trim(£G79ME)+','+ + C %trim($G79FU)+','+ + C %trim($G79ME) + C £DBG_Str DSPLY + * + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle new file mode 100644 index 000000000..5054f9df2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle @@ -0,0 +1,20 @@ + D £DBG_Str S 10 + C *ENTRY PLIST + C PARM £G79FU 10 + C PARM £G79ME 10 + C PARM $G79FU 10 + C PARM $G79ME 10 + * + C EVAL £DBG_Str=%trim(£G79FU)+','+ + C %trim(£G79ME)+','+ + C %trim($G79FU)+','+ + C %trim($G79ME) + * + C £DBG_Str DSPLY + * + C MOVEL(P) '4' £G79FU + C MOVEL(P) '3' £G79ME + C MOVEL(P) '2' $G79FU + C MOVEL(P) '1' $G79ME + * + C SETON LR \ No newline at end of file From 48724fe2ce8b1f70d21f53307c9b73c9368c69e6 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Tue, 20 Feb 2024 17:05:01 +0100 Subject: [PATCH 121/423] Add static keyword --- .../src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" index 993189693..3a901f82b 100644 --- "a/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" +++ "b/rpgJavaInterpreter-core/src/test/resources/QPROGEN/\302\243MULANG_P.rpgle" @@ -2,7 +2,7 @@ D £MUGTP PI 5 0 D XCA 15 CONST * - D OSZ S LIKE(XCF) + D OSZ S LIKE(XCF) STATIC * C IF OSZ=' ' C EVAL OSZ=XCA From bd9b0f9e689d9ed24ec454537d4025b8ada94bff Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:16:40 +0000 Subject: [PATCH 122/423] add recursive search of variable size and variable type in case of LIKE expression --- .../interpreter/compile_time_interpreter.kt | 65 +++++++++++-------- .../evaluation/SmeupInterpreterTest.kt | 2 +- .../test/resources/smeup/T02_A50_P07.rpgle | 2 +- .../test/resources/smeup/T02_A50_P07B.rpgle | 20 ++++++ .../test/resources/smeup/T02_A50_P08.rpgle | 20 ------ 5 files changed, 61 insertions(+), 48 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07B.rpgle delete mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 99ae1f880..5aaf9c912 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -139,35 +139,41 @@ open class BaseCompileTimeInterpreter( val field = it.fields.find { it.name.equals(declName, ignoreCase = true) } if (field != null) return (field.elementSize() /*/ field.declaredArrayInLine!!*/) } - rContext.statement() - .forEach { - when { - it.dspec() != null -> { - val name = it.dspec().ds_name().text - if (name == declName) { - // TODO verify... - return it.dspec().TO_POSITION().text.asInt() - } - } - it.cspec_fixed() != null -> { - val statement = it.cspec_fixed().cspec_fixed_standard().toAst(conf) - if (statement is StatementThatCanDefineData) { - val dataDefinition = (statement as StatementThatCanDefineData).dataDefinition() - dataDefinition.forEach { - if (it.name.asValue().value == declName) { - return it.type.size - } - } - } - } - it.dcl_ds() != null -> { - val name = it.dcl_ds().name - if (name == declName) { - return it.dcl_ds().elementSizeOf(knownDataDefinitions) + return findSize(rContext.statement(), declName, conf) + } + + private fun findSize(statements: List, declName: String, conf: ToAstConfiguration): Int { + statements.forEach { + when { + it.dspec() != null -> { + val name = it.dspec().ds_name().text + if (name == declName) { + // TODO verify... + return it.dspec().TO_POSITION().text.asInt() + } + } + it.cspec_fixed() != null -> { + val statement = it.cspec_fixed().cspec_fixed_standard().toAst(conf) + if (statement is StatementThatCanDefineData) { + val dataDefinition = (statement as StatementThatCanDefineData).dataDefinition() + dataDefinition.forEach { + if (it.name.asValue().value == declName) { + return it.type.size } } } } + it.dcl_ds() != null -> { + val name = it.dcl_ds().name + if (name == declName) { + return it.dcl_ds().elementSizeOf(knownDataDefinitions) + } + } + it.block() != null -> { + return findSize(it.block().ifstatement().statement(), declName, conf) + } + } + } throw NotFoundAtCompileTimeException(declName) } @@ -215,7 +221,11 @@ open class BaseCompileTimeInterpreter( return field.type } } - rContext.statement() + return findType(rContext.statement(), declName, conf) + } + + private fun findType(statements: List, declName: String, conf: ToAstConfiguration): Type { + statements .forEach { when { it.cspec_fixed() != null -> { @@ -226,6 +236,9 @@ open class BaseCompileTimeInterpreter( } } } + it.block() != null -> { + return findType(it.block().ifstatement().statement(), declName, conf) + } } } throw NotFoundAtCompileTimeException(declName) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index a9a1d1fad..ededbbaa2 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -385,7 +385,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A50_P07() { - val expected = listOf("1,2,3,4", "4,3,2,1") + val expected = listOf("1,2,3,4") assertEquals(expected, "smeup/T02_A50_P07".outputOf()) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle index 62d78ab3f..4552fa90f 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle @@ -7,7 +7,7 @@ C MOVEL(P) '3' $G79FU C MOVEL(P) '4' $G79ME * - C MOVEL(P) 'T02_A50_P08' AAA010 10 + C MOVEL(P) 'T02_A50_P07B'AAA010 10 C IF '1' = '1' C CALL AAA010 37 C PARM £G79FU 10 diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07B.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07B.rpgle new file mode 100644 index 000000000..715c7bc4d --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07B.rpgle @@ -0,0 +1,20 @@ + D £DBG_Str S 10 + C *ENTRY PLIST + C PARM £G79FU 10 + C PARM £G79ME 10 + C PARM $G79FU 10 + C PARM $G79ME 10 + * + C* EVAL £DBG_Str=%trim(£G79FU)+','+ + C* %trim(£G79ME)+','+ + C* %trim($G79FU)+','+ + C* %trim($G79ME) + * + C* £DBG_Str DSPLY + * + C* MOVEL(P) '4' £G79FU + C* MOVEL(P) '3' £G79ME + C* MOVEL(P) '2' $G79FU + C* MOVEL(P) '1' $G79ME + * + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle deleted file mode 100644 index 5054f9df2..000000000 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle +++ /dev/null @@ -1,20 +0,0 @@ - D £DBG_Str S 10 - C *ENTRY PLIST - C PARM £G79FU 10 - C PARM £G79ME 10 - C PARM $G79FU 10 - C PARM $G79ME 10 - * - C EVAL £DBG_Str=%trim(£G79FU)+','+ - C %trim(£G79ME)+','+ - C %trim($G79FU)+','+ - C %trim($G79ME) - * - C £DBG_Str DSPLY - * - C MOVEL(P) '4' £G79FU - C MOVEL(P) '3' £G79ME - C MOVEL(P) '2' $G79FU - C MOVEL(P) '1' $G79ME - * - C SETON LR \ No newline at end of file From e2c94cfa0db6849d25c39c927d1d27a1bc4bc5c7 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 12:21:12 +0100 Subject: [PATCH 123/423] Add to AbstractDataDefinition the new property static --- .../com/smeup/rpgparser/interpreter/data_definitions.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 34aaa4bba..654c88d6f 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 @@ -63,7 +63,8 @@ abstract class AbstractDataDefinition( if (parsingFunction != null) { Scope.Local } else Scope.Program - } + }, + @Transient open val static: Boolean = false ) : Node(position), Named { fun numberOfElements() = type.numberOfElements() open fun elementSize() = type.elementSize() @@ -190,13 +191,15 @@ data class DataDefinition( override var const: Boolean = false, var paramPassedBy: ParamPassedBy = ParamPassedBy.Reference, var paramOptions: List = mutableListOf(), - @Transient var defaultValue: Value? = null + @Transient var defaultValue: Value? = null, + override val static: Boolean = false ) : AbstractDataDefinition( name = name, type = type, position = position, - const = const) { + const = const, + static = static) { override fun isArray() = type is ArrayType fun isCompileTimeArray() = type is ArrayType && type.compileTimeArray() From 60bba895664a7ee671dc545a22d1c4f67f3e3ed6 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 12:23:36 +0100 Subject: [PATCH 124/423] Add test to check if the DataDefinition.static is properly set --- .../rpgparser/parsing/ast/ToAstSmokeTest.kt | 13 +++++++++ .../src/test/resources/PROCEDURE_T.rpgle | 28 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ToAstSmokeTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ToAstSmokeTest.kt index 51a4fce89..d78a7db6b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ToAstSmokeTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ToAstSmokeTest.kt @@ -348,4 +348,17 @@ open class ToAstSmokeTest : AbstractTest() { resolveAndValidate() } } + + @Test + fun buildAstForPROCEDURE_T() { + assertASTCanBeProduced(exampleName = "PROCEDURE_T", printTree = false).apply { + resolveAndValidate() + this.procedures!!.forEach { procedureAst -> + procedureAst.resolveAndValidate() + procedureAst.getDataDefinition("VSTAT").apply { + assertEquals(expected = true, actual = this.static, message = "VSTAT must be static") + } + } + } + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle new file mode 100644 index 000000000..93423cecc --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle @@ -0,0 +1,28 @@ + V* ============================================================== + D* 21/02/24 PROC WITH STATIC KEYWORD + V* ============================================================== + + DPRCSTAT PR + DP 2 0 + DR 2 0 + * + C Z-ADD 11 A 2 0 + C Z-ADD 22 B 2 0 + C Z-ADD *zeros C 2 0 + C CALLP PRCSTAT(A:B:C) + C C DSPLY + C CALLP PRCSTAT(A:B:C) + C C DSPLY + C SETON LR + * + PPRCSTAT B + DPRCSTAT PI + DP 2 0 + DQ 2 0 + DR 2 0 + * + DVSTAT S 2 0 STATIC + * + C EVAL VSTAT=VSTAT+1 + C EVAL R=P+Q+VSTAT + PPPRCST E \ No newline at end of file From a75f6c64272b3d16c47d2697bdc3463f6424a57a Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 12:24:31 +0100 Subject: [PATCH 125/423] Change DspecContext.toAst in order to pass new static property to DataDefinition constructor --- .../parsing/parsetreetoast/data_definitions.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) 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 39e2927a3..9ff59376c 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 @@ -315,6 +315,7 @@ internal fun RpgParser.DspecContext.toAst( var compileTimeArray = false var varying = false var ascend: Boolean? = null + var static = false this.keyword().forEach { it.keyword_ascend()?.let { @@ -341,6 +342,9 @@ internal fun RpgParser.DspecContext.toAst( it.keyword_varying()?.let { varying = true } + it.keyword_static()?.let { + static = true + } } val elementSize = when { @@ -416,11 +420,12 @@ internal fun RpgParser.DspecContext.toAst( baseType } return DataDefinition( - this.ds_name().text, - type, - initializationValue = initializationValue, - position = this.toPosition(true) - ) + name = this.ds_name().text, + type = type, + initializationValue = initializationValue, + position = this.toPosition(true), + static = static + ) } internal fun RpgParser.DspecConstantContext.toAst( From b5d807a40209f2553f7ec9cfb161fe17e84eb19a Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 13:07:31 +0100 Subject: [PATCH 126/423] Fix wrong definition in the procedure interface specification --- rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle index 93423cecc..b05b70575 100644 --- a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle @@ -1,9 +1,10 @@ V* ============================================================== D* 21/02/24 PROC WITH STATIC KEYWORD V* ============================================================== - + DPRCSTAT PR DP 2 0 + DQ 2 0 DR 2 0 * C Z-ADD 11 A 2 0 @@ -23,6 +24,6 @@ * DVSTAT S 2 0 STATIC * - C EVAL VSTAT=VSTAT+1 + C EVAL VSTAT=VSTAT+1 C EVAL R=P+Q+VSTAT PPPRCST E \ No newline at end of file From 004aaef90947960983724f5ca16de3b071df9187 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 13:08:40 +0100 Subject: [PATCH 127/423] Add PROCEDURE_T test case --- .../com/smeup/rpgparser/evaluation/InterpreterTest.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 286ff79a4..81ccd39b5 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -1880,6 +1880,15 @@ Test 6 ) } + @Test + fun executePROCEDURE_T() { + // TODO expected is to verify in AS4000 + assertEquals( + expected = listOf("33, 34"), + actual = "PROCEDURE_T".outputOf() + ) + } + @Test fun executeAPIPGM1() { assertEquals( From acde8692158390727960c04c2be372d4ddbef4fd Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 21 Feb 2024 13:26:36 +0100 Subject: [PATCH 128/423] Implemented a case of test for a mock EXFMT --- .../com/smeup/rpgparser/video/VideoInterpeterTest.kt | 6 ++++++ .../src/test/resources/video/EXFMT_MOCK.rpgle | 11 +++++++++++ 2 files changed, 17 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/video/EXFMT_MOCK.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt index cb2c5cd0d..f84c06633 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt @@ -32,4 +32,10 @@ class VideoInterpeterTest : AbstractTest() { val expected = listOf("W\$PERI:12", "£RASDI:HELLO_WORLD") assertEquals(expected = expected, actual = "video/FILEDEF".outputOf(configuration = configuration)) } + + @Test + fun executeEXFMT_MOCK() { + val expected = listOf("") + assertEquals(expected = expected, actual = "video/EXFMT_MOCK".outputOf(configuration = configuration)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/video/EXFMT_MOCK.rpgle b/rpgJavaInterpreter-core/src/test/resources/video/EXFMT_MOCK.rpgle new file mode 100644 index 000000000..ad7217eba --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/video/EXFMT_MOCK.rpgle @@ -0,0 +1,11 @@ + FB£DIR40V CF E WORKSTN USROPN + F INFDS(DSSF01) + + D MSG S 50 VARYING + + D WFUND1 DS + D WSDATA 8 0 + + C EXFMT W$PERI + C EVAL MSG='' + C MSG DSPLY From d0a7d085a79dff406321e1cdcad021176514df3d Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 14:45:11 +0100 Subject: [PATCH 129/423] Replace Scope enum with Scope class because in case of static the scope depends on procedureName --- .../rpgparser/experimental/SymbolTable.kt | 17 +++++----- .../rpgparser/interpreter/SymbolTable.kt | 16 +++++----- .../rpgparser/interpreter/data_definitions.kt | 32 +++++++++++++++++-- .../rpgparser/parsing/ast/ToAstSmokeTest.kt | 3 +- 4 files changed, 49 insertions(+), 19 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt index b279b0307..cc9a09af0 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/experimental/SymbolTable.kt @@ -24,6 +24,7 @@ import com.smeup.rpgparser.interpreter.* * Data are stored IntArrayMap, which is a more efficient map than standard ones * @see IntArrayMap * */ +@Deprecated("This class is experimental and will be removed in future versions. Use com.smeup.rpgparser.interpreter.SymbolTable instead.") class SymbolTable : ISymbolTable { private val values = IntArrayMap>(0, 32000) private val names = mutableMapOf() @@ -34,10 +35,10 @@ class SymbolTable : ISymbolTable { override var parentSymbolTable: ISymbolTable? = null override operator fun get(data: AbstractDataDefinition): Value { - return when (data.scope) { - Scope.Program -> (programSymbolTable as SymbolTable).getLocal(data) - Scope.Local -> getLocal(data) - Scope.Static -> TODO() + return when (data.scope.visibility) { + Visibility.Program -> (programSymbolTable as SymbolTable).getLocal(data) + Visibility.Local -> getLocal(data) + Visibility.Static -> TODO() } } @@ -92,10 +93,10 @@ class SymbolTable : ISymbolTable { } override operator fun set(data: AbstractDataDefinition, value: Value): Value? { - return when (data.scope) { - Scope.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) - Scope.Local -> setLocal(data, value) - Scope.Static -> TODO() + return when (data.scope.visibility) { + Visibility.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) + Visibility.Local -> setLocal(data, value) + Visibility.Static -> TODO() } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt index e2bf1fc84..095ee242e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt @@ -26,10 +26,10 @@ class SymbolTable : ISymbolTable { override var parentSymbolTable: ISymbolTable? = null override operator fun get(data: AbstractDataDefinition): Value { - return when (data.scope) { - Scope.Program -> (programSymbolTable as SymbolTable).getLocal(data) - Scope.Local -> getLocal(data) - Scope.Static -> TODO() + return when (data.scope.visibility) { + Visibility.Program -> (programSymbolTable as SymbolTable).getLocal(data) + Visibility.Local -> getLocal(data) + Visibility.Static -> TODO() } } @@ -83,10 +83,10 @@ class SymbolTable : ISymbolTable { } override operator fun set(data: AbstractDataDefinition, value: Value): Value? { - return when (data.scope) { - Scope.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) - Scope.Local -> setLocal(data, value) - Scope.Static -> TODO() + return when (data.scope.visibility) { + Visibility.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) + Visibility.Local -> setLocal(data, value) + Visibility.Static -> TODO() } } 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 654c88d6f..4991ef36a 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 @@ -61,7 +61,7 @@ abstract class AbstractDataDefinition( } else null } if (parsingFunction != null) { - Scope.Local + if (static) Scope.static(parsingFunction) else Scope.Local } else Scope.Program }, @Transient open val static: Boolean = false @@ -784,6 +784,34 @@ fun decodeFromDS(value: String, digits: Int, scale: Int): BigDecimal { } } -enum class Scope { +enum class Visibility { Program, Static, Local +} + +@Serializable +class Scope { + + val visibility: Visibility + val reference: String? + + private constructor(visibility: Visibility, reference: String? = null) { + this.visibility = visibility + this.reference = reference + } + + companion object { + /** + * Create a new program scope + * */ + val Program = Scope(visibility = Visibility.Program) + /** + * Create a new local scope + * */ + val Local = Scope(visibility = Visibility.Local) + /** + * Create a new static scope + * @param procedureName The procedure name + */ + fun static(procedureName: String) = Scope(visibility = Visibility.Static, reference = procedureName) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ToAstSmokeTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ToAstSmokeTest.kt index d78a7db6b..1848558a8 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ToAstSmokeTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/ToAstSmokeTest.kt @@ -19,6 +19,7 @@ package com.smeup.rpgparser.parsing.ast import com.smeup.rpgparser.AbstractTest import com.smeup.rpgparser.interpreter.DataStructureType import com.smeup.rpgparser.interpreter.Scope +import com.smeup.rpgparser.interpreter.Visibility import com.smeup.rpgparser.parsing.parsetreetoast.DSFieldInitKeywordType import com.smeup.rpgparser.parsing.parsetreetoast.resolveAndValidate import org.junit.Ignore @@ -267,7 +268,7 @@ open class ToAstSmokeTest : AbstractTest() { mainProgramCu.apply { // we must have none variable with scope: Scope.Local or Scope.Static val none = this.allDataDefinitions.filter { - it.scope == Scope.Local || it.scope == Scope.Static + it.scope == Scope.Local || it.scope.visibility == Visibility.Static }.none() assertTrue(none) } From a280ee0af1301238328585e3543a4a7c4a8787b1 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 21 Feb 2024 14:45:17 +0100 Subject: [PATCH 130/423] Implemented a blank `ExfmtStmt` for `EXFMT` operator --- .../com/smeup/rpgparser/parsing/ast/serialization.kt | 1 + .../com/smeup/rpgparser/parsing/ast/statements.kt | 9 +++++++++ .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 10 ++++++++++ 3 files changed, 20 insertions(+) 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 574e781d8..820681861 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 @@ -81,6 +81,7 @@ private val modules = SerializersModule { subclass(ReadPreviousEqualStmt::class) subclass(ReadStmt::class) subclass(ResetStmt::class) + subclass(ExfmtStmt::class) subclass(ReturnStmt::class) subclass(ScanStmt::class) subclass(SelectStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index ece9f62fe..4a73dd5fc 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1892,4 +1892,13 @@ data class ResetStmt( } interpreter.assign(dataDefinition, dataDefinition.defaultValue!!) } +} + +@Serializable +data class ExfmtStmt( + override val position: Position? = null +) : Statement(position) { + override fun execute(interpreter: InterpreterCore) { + // TODO + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 5ea2e886a..4375d34b7 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -913,6 +913,9 @@ internal fun Cspec_fixed_standardContext.toAst(conf: ToAstConfiguration = ToAstC this.csRESET() != null -> this.csRESET() .let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) } + this.csEXFMT() != null -> this.csEXFMT() + .let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) } + else -> todo(conf = conf) } } @@ -1917,6 +1920,13 @@ internal fun CsRESETContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( ) } +// TODO +internal fun CsEXFMTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { + val position = toPosition(conf.considerPosition) + return ExfmtStmt(position) +} + + /** * Run a block. In case of error throws an error encapsulating useful information * like node position From 2a391c46b4c701d332dc67e34faa79038bf291eb Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 14:45:36 +0100 Subject: [PATCH 131/423] remove comment --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 660be0752..c6533c6c4 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -366,8 +366,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A70_P01() { - // assertASTCanBeProduced("smeup/T02_A70_P01", printTree = true) - val expected = listOf("1", "2") + val expected = listOf("1", "2") assertEquals(expected, "smeup/T02_A70_P01".outputOf()) } From c8fddc875ebd41bba774cdd97de87252e28d570e Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 14:51:15 +0100 Subject: [PATCH 132/423] Add ISymbolTable.staticSymbolTable at scope main execution context --- .../com/smeup/rpgparser/interpreter/ISymbolTable.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt index e856a1b5e..c667f3585 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt @@ -16,6 +16,7 @@ package com.smeup.rpgparser.interpreter +import com.smeup.rpgparser.execution.MainExecutionContext import java.math.BigDecimal interface ISymbolTable { @@ -40,6 +41,16 @@ interface ISymbolTable { } } + /** + * Get the static symbol table. This symbol table is shared among all the procedures during the main execution. + * */ + val staticSymbolTable: ISymbolTable + get() { + return MainExecutionContext.getAttributes().computeIfAbsent("staticSymbolTable") { + SymbolTable() + } as SymbolTable + } + /** * @return true if SymbolTable contains a variable named dataName * */ From 4858a83b46fe0becb9aefecf78c58aeeca51f970 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 21 Feb 2024 15:34:00 +0100 Subject: [PATCH 133/423] Implemented a case of test for a mock READC --- .../rpgparser/video/VideoInterpeterTest.kt | 6 + .../src/test/resources/video/READC_MOCK.rpgle | 12 + .../video/metadata/B\302\243DIR40VSUB.json" | 525 ++++++++++++++++++ 3 files changed, 543 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/video/READC_MOCK.rpgle create mode 100644 "rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40VSUB.json" diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt index f84c06633..ad47a9cfd 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt @@ -38,4 +38,10 @@ class VideoInterpeterTest : AbstractTest() { val expected = listOf("") assertEquals(expected = expected, actual = "video/EXFMT_MOCK".outputOf(configuration = configuration)) } + + @Test + fun executeREADC_MOCK() { + val expected = listOf("") + assertEquals(expected = expected, actual = "video/READC_MOCK".outputOf(configuration = configuration)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/video/READC_MOCK.rpgle b/rpgJavaInterpreter-core/src/test/resources/video/READC_MOCK.rpgle new file mode 100644 index 000000000..d93343734 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/video/READC_MOCK.rpgle @@ -0,0 +1,12 @@ + FB£DIR40V CF E WORKSTN SFILE(B£DIR40VSUB:RRN) + F INFDS(DSSF01) + + D MSG S 50 VARYING + + D WFUND1 DS + D WSDATA 8 0 + + C EXFMT W$PERI + C READC B£DIR40VSUB + C EVAL MSG='' + C MSG DSPLY diff --git "a/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40VSUB.json" "b/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40VSUB.json" new file mode 100644 index 000000000..2b8bb634f --- /dev/null +++ "b/rpgJavaInterpreter-core/src/test/resources/video/metadata/B\302\243DIR40VSUB.json" @@ -0,0 +1,525 @@ +{ + "name": "B£DIR40V", + "tableName": "CALBAS0F", + "recordFormat": "", + "fields": [ + { + "fieldName": "£RASDI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 15, + "varying": false + } + }, + { + "fieldName": "£PDSNP", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "£PDSJN", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "£PDSNU", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$TPOG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 12, + "varying": false + } + }, + { + "fieldName": "W$TPRI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 12, + "varying": false + } + }, + { + "fieldName": "W$TRGG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 3, + "varying": false + } + }, + { + "fieldName": "W£TRGG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$RISG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 15, + "varying": false + } + }, + { + "fieldName": "W£RISG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$DAIN", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$DAFI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$MESV", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 76, + "varying": false + } + }, + { + "fieldName": "£RASDI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 15, + "varying": false + } + }, + { + "fieldName": "£PDSNP", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "£PDSJN", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "£PDSNU", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$TRGG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 3, + "varying": false + } + }, + { + "fieldName": "W£TRGG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$RISG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 15, + "varying": false + } + }, + { + "fieldName": "W£RISG", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$PERI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 8, + "varying": false + } + }, + { + "fieldName": "W$GSET", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 10, + "varying": false + } + }, + { + "fieldName": "W$SEAN", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 2, + "decimalDigits": 0, + "rpgType": "S" + } + }, + { + "fieldName": "W$NURI", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 2, + "decimalDigits": 0, + "rpgType": "S" + } + }, + { + "fieldName": "W$PLAV", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 3, + "decimalDigits": 0, + "rpgType": "S" + } + }, + { + "fieldName": "W$ORRI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W£ORRI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 40, + "varying": false + } + }, + { + "fieldName": "W$ECRI", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$PEUT", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 5, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$ORUT", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W£ORUT", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 40, + "varying": false + } + }, + { + "fieldName": "W$ECUT", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$COCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 2, + "varying": false + } + }, + { + "fieldName": "W£COCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 30, + "varying": false + } + }, + { + "fieldName": "W$ORCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W£ORCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 40, + "varying": false + } + }, + { + "fieldName": "W$ECCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$OI01", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF01", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$HTOT", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 6, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI02", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF02", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$HNET", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 6, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI03", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF03", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$HNTO", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 6, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI04", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF04", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI05", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF05", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W§CFCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 25, + "varying": false + } + }, + { + "fieldName": "W$CFCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 9, + "decimalDigits": 3, + "rpgType": "S" + } + }, + { + "fieldName": "W$OI06", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$OF06", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 4, + "decimalDigits": 2, + "rpgType": "S" + } + }, + { + "fieldName": "W$TOCO", + "type": { + "type": "com.smeup.rpgparser.interpreter.NumberType", + "entireDigits": 9, + "decimalDigits": 3, + "rpgType": "S" + } + }, + { + "fieldName": "W$TU01", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU02", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU03", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU04", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU05", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + }, + { + "fieldName": "W$TU06", + "type": { + "type": "com.smeup.rpgparser.interpreter.StringType", + "length": 1, + "varying": false + } + } + ], + "accessFields": [] +} \ No newline at end of file From ef42a720a333955e3b6d614f346232043b589b84 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 21 Feb 2024 15:34:59 +0100 Subject: [PATCH 134/423] Implemented a blank `ReadcStmt` for `READC` operator --- .../com/smeup/rpgparser/parsing/ast/serialization.kt | 1 + .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 9 +++++++++ .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 9 +++++++++ 3 files changed, 19 insertions(+) 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 820681861..c40e7c480 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 @@ -82,6 +82,7 @@ private val modules = SerializersModule { subclass(ReadStmt::class) subclass(ResetStmt::class) subclass(ExfmtStmt::class) + subclass(ReadcStmt::class) subclass(ReturnStmt::class) subclass(ScanStmt::class) subclass(SelectStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 4a73dd5fc..50bad7e6e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1901,4 +1901,13 @@ data class ExfmtStmt( override fun execute(interpreter: InterpreterCore) { // TODO } +} + +@Serializable +data class ReadcStmt( + override val position: Position? = null +) : Statement(position) { + override fun execute(interpreter: InterpreterCore) { + // TODO + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 4375d34b7..618f11808 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -916,6 +916,9 @@ internal fun Cspec_fixed_standardContext.toAst(conf: ToAstConfiguration = ToAstC this.csEXFMT() != null -> this.csEXFMT() .let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) } + this.csREADC() != null -> this.csREADC() + .let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) } + else -> todo(conf = conf) } } @@ -1926,6 +1929,12 @@ internal fun CsEXFMTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( return ExfmtStmt(position) } +// TODO +internal fun CsREADCContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { + val position = toPosition(conf.considerPosition) + return ExfmtStmt(position) +} + /** * Run a block. In case of error throws an error encapsulating useful information From 9408d81c3f7d33b1bd54a6b7f3eaf1f0017d13f8 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 21 Feb 2024 15:36:11 +0100 Subject: [PATCH 135/423] Fix after `ktlinCheck` --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 618f11808..aac0ab123 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1935,7 +1935,6 @@ internal fun CsREADCContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( return ExfmtStmt(position) } - /** * Run a block. In case of error throws an error encapsulating useful information * like node position From d1d5e716840fe5abda8c04100e3b5166f301d4bf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 21 Feb 2024 16:08:38 +0100 Subject: [PATCH 136/423] Fixed `CsREADCContext` --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index aac0ab123..d5dcc7398 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1933,6 +1933,8 @@ internal fun CsEXFMTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( internal fun CsREADCContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { val position = toPosition(conf.considerPosition) return ExfmtStmt(position) + return ReadcStmt(position) + return UnlockStmt(position) } /** From e7630d1a142b00ed4eb57e650424f38288a3419f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 21 Feb 2024 16:12:53 +0100 Subject: [PATCH 137/423] Implemented a case of test for a mock UNLOCK --- .../com/smeup/rpgparser/video/VideoInterpeterTest.kt | 6 ++++++ .../src/test/resources/video/UNLOCK_MOCK.rpgle | 11 +++++++++++ 2 files changed, 17 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/video/UNLOCK_MOCK.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt index ad47a9cfd..cf98fe8c2 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/video/VideoInterpeterTest.kt @@ -44,4 +44,10 @@ class VideoInterpeterTest : AbstractTest() { val expected = listOf("") assertEquals(expected = expected, actual = "video/READC_MOCK".outputOf(configuration = configuration)) } + + @Test + fun executeUNLOCK_MOCK() { + val expected = listOf("") + assertEquals(expected = expected, actual = "video/UNLOCK_MOCK".outputOf(configuration = configuration)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/video/UNLOCK_MOCK.rpgle b/rpgJavaInterpreter-core/src/test/resources/video/UNLOCK_MOCK.rpgle new file mode 100644 index 000000000..54d070435 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/video/UNLOCK_MOCK.rpgle @@ -0,0 +1,11 @@ + FB£DIR40V CF E WORKSTN SFILE(B£DIR40VSUB:RRN) + F INFDS(DSSF01) + + D MSG S 50 VARYING + + D WFUND1 DS + D WSDATA 8 0 + + C UNLOCK W$PERI + C EVAL MSG='' + C MSG DSPLY From 5c57686defb7e7ae746169d999125165a16f8170 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 21 Feb 2024 16:14:39 +0100 Subject: [PATCH 138/423] Implemented a blank `UnlockStmt` for `UNLOCK` operator --- .../com/smeup/rpgparser/parsing/ast/serialization.kt | 1 + .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 9 +++++++++ .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 9 ++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) 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 c40e7c480..100ea9c8a 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 @@ -84,6 +84,7 @@ private val modules = SerializersModule { subclass(ExfmtStmt::class) subclass(ReadcStmt::class) subclass(ReturnStmt::class) + subclass(UnlockStmt::class) subclass(ScanStmt::class) subclass(SelectStmt::class) subclass(SetStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 50bad7e6e..0d9c22f8a 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1910,4 +1910,13 @@ data class ReadcStmt( override fun execute(interpreter: InterpreterCore) { // TODO } +} + +@Serializable +data class UnlockStmt( + override val position: Position? = null +) : Statement(position) { + override fun execute(interpreter: InterpreterCore) { + // TODO + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index d5dcc7398..26be76b3c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -919,6 +919,9 @@ internal fun Cspec_fixed_standardContext.toAst(conf: ToAstConfiguration = ToAstC this.csREADC() != null -> this.csREADC() .let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) } + this.csUNLOCK() != null -> this.csUNLOCK() + .let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) } + else -> todo(conf = conf) } } @@ -1932,8 +1935,12 @@ internal fun CsEXFMTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( // TODO internal fun CsREADCContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { val position = toPosition(conf.considerPosition) - return ExfmtStmt(position) return ReadcStmt(position) +} + +// TODO +internal fun CsUNLOCKContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { + val position = toPosition(conf.considerPosition) return UnlockStmt(position) } From baac155fe1fa146075e8a196e48bdd599daf16c7 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:18:29 +0000 Subject: [PATCH 139/423] add recursive search of variable size and variable type in case of LIKE --- .../interpreter/compile_time_interpreter.kt | 72 +++++++++++++++---- .../evaluation/SmeupInterpreterTest.kt | 2 +- .../test/resources/smeup/T02_A50_P07.rpgle | 55 +++++++++----- .../test/resources/smeup/T02_A50_P07B.rpgle | 20 ------ 4 files changed, 99 insertions(+), 50 deletions(-) delete mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07B.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 5aaf9c912..55a4030be 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -139,10 +139,10 @@ open class BaseCompileTimeInterpreter( val field = it.fields.find { it.name.equals(declName, ignoreCase = true) } if (field != null) return (field.elementSize() /*/ field.declaredArrayInLine!!*/) } - return findSize(rContext.statement(), declName, conf) + return findSize(rContext.statement(), declName, conf, false)!! } - private fun findSize(statements: List, declName: String, conf: ToAstConfiguration): Int { + private fun findSize(statements: List, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Int? { statements.forEach { when { it.dspec() != null -> { @@ -170,11 +170,33 @@ open class BaseCompileTimeInterpreter( } } it.block() != null -> { - return findSize(it.block().ifstatement().statement(), declName, conf) + when { + it.block().ifstatement() != null -> { + val size = findSize(it.block().ifstatement().statement(), declName, conf) + if (size != null) return size + } + it.block().forstatement() != null -> { + val size = findSize(it.block().forstatement().statement(), declName, conf) + if (size != null) return size + } + it.block().selectstatement() != null -> { + it.block().selectstatement().whenstatement().forEach() { sl -> + val size = findSize(sl.statement(), declName, conf) + if (size != null) return size + } + } + it.block().csDOWxx() != null || it.block().csDOUxx() != null -> { + val size = findSize(it.block().statement(), declName, conf) + if (size != null) return size + } + } } } } - throw NotFoundAtCompileTimeException(declName) + if (innerBlock) + return null + else + throw NotFoundAtCompileTimeException(declName) } override fun evaluateElementSizeOf(rContext: RpgParser.RContext, expression: Expression, conf: ToAstConfiguration): Int { @@ -221,26 +243,52 @@ open class BaseCompileTimeInterpreter( return field.type } } - return findType(rContext.statement(), declName, conf) + return findType(rContext.statement(), declName, conf, false)!! } - private fun findType(statements: List, declName: String, conf: ToAstConfiguration): Type { + private fun findType(statements: List, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Type? { statements .forEach { when { it.cspec_fixed() != null -> { - val dataDefinition = (it.cspec_fixed().cspec_fixed_standard().toAst(conf) as StatementThatCanDefineData).dataDefinition() - dataDefinition.forEach { - if (it.name.asValue().value == declName) { - return it.type + val ast = it.cspec_fixed().cspec_fixed_standard().toAst(conf) + if (ast is StatementThatCanDefineData) { + val dataDefinition = (ast as StatementThatCanDefineData).dataDefinition() + dataDefinition.forEach { + if (it.name.asValue().value == declName) { + return it.type + } } } } it.block() != null -> { - return findType(it.block().ifstatement().statement(), declName, conf) + when { + it.block().ifstatement() != null -> { + val type = findType(it.block().ifstatement().statement(), declName, conf) + if (type != null) return type + } + it.block().forstatement() != null -> { + val type = findType(it.block().forstatement().statement(), declName, conf) + if (type != null) return type + } + it.block().selectstatement() != null -> { + it.block().selectstatement().whenstatement().forEach() { sl -> + val type = findType(sl.statement(), declName, conf) + if (type != null) return type + } + } + it.block().csDOWxx() != null || it.block().csDOUxx() != null -> { + val type = findType(it.block().statement(), declName, conf) + if (type != null) return type + } + } } } } - throw NotFoundAtCompileTimeException(declName) + if (innerBlock) { + return null + } else { + throw NotFoundAtCompileTimeException(declName) + } } } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index ededbbaa2..27c1f55ae 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -385,7 +385,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A50_P07() { - val expected = listOf("1,2,3,4") + val expected = listOf("1,2,3,4", "1,2,3,4") assertEquals(expected, "smeup/T02_A50_P07".outputOf()) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle index 4552fa90f..3ccd4072e 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle @@ -1,25 +1,46 @@ D £DBG_Str S 10 - D $G79FU S LIKE(£G79FU) - D $G79ME S LIKE(£G79ME) + D $VARIF S LIKE(£VARIF) + D $VARDOW S LIKE(£VARDOW) + D $VARSL S LIKE(£VARSL) + D $VARFOR S LIKE(£VARFOR) + D IND S 1 0 * - C MOVEL(P) '1' £G79FU - C MOVEL(P) '2' £G79ME - C MOVEL(P) '3' $G79FU - C MOVEL(P) '4' $G79ME - * - C MOVEL(P) 'T02_A50_P07B'AAA010 10 + C MOVEL(P) '1' $VARIF + C MOVEL(P) '2' $VARDOW + C MOVEL(P) '3' $VARSL + C MOVEL(P) '4' $VARFOR + * test IF C IF '1' = '1' - C CALL AAA010 37 - C PARM £G79FU 10 - C PARM £G79ME 10 - C PARM $G79FU - C PARM $G79ME + C MOVEL(P) '1' £VARIF 10 C ENDIF + * test DOW + C EVAL IND=1 + C IND DOWEQ 1 + C MOVEL(P) '2' £VARDOW 10 + C EVAL IND=2 + C ENDDO + * test SELECT + C SELECT + C WHEN IND = 2 + C MOVEL(P) '3' £VARSL 10 + C OTHER + C MOVEL(P) ' ' £VARSL 10 + C ENDSL + * test FOR + C FOR IND = 0 TO 1 + C MOVEL(P) '4' £VARFOR 10 + C ENDFOR + ****** + C EVAL £DBG_Str=%trim(£VARIF)+','+ + C %trim(£VARDOW)+','+ + C %trim(£VARSL)+','+ + C %trim(£VARFOR) + C £DBG_Str DSPLY * - C EVAL £DBG_Str=%trim(£G79FU)+','+ - C %trim(£G79ME)+','+ - C %trim($G79FU)+','+ - C %trim($G79ME) + C EVAL £DBG_Str=%trim($VARIF)+','+ + C %trim($VARDOW)+','+ + C %trim($VARSL)+','+ + C %trim($VARFOR) C £DBG_Str DSPLY * C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07B.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07B.rpgle deleted file mode 100644 index 715c7bc4d..000000000 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07B.rpgle +++ /dev/null @@ -1,20 +0,0 @@ - D £DBG_Str S 10 - C *ENTRY PLIST - C PARM £G79FU 10 - C PARM £G79ME 10 - C PARM $G79FU 10 - C PARM $G79ME 10 - * - C* EVAL £DBG_Str=%trim(£G79FU)+','+ - C* %trim(£G79ME)+','+ - C* %trim($G79FU)+','+ - C* %trim($G79ME) - * - C* £DBG_Str DSPLY - * - C* MOVEL(P) '4' £G79FU - C* MOVEL(P) '3' £G79ME - C* MOVEL(P) '2' $G79FU - C* MOVEL(P) '1' $G79ME - * - C SETON LR \ No newline at end of file From d976da3303efc55b597cd31a3e79786728917bd4 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:26:36 +0000 Subject: [PATCH 140/423] change T02_A50_P07.rpgle --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 2 +- .../src/test/resources/smeup/T02_A50_P07.rpgle | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 27c1f55ae..ededbbaa2 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -385,7 +385,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A50_P07() { - val expected = listOf("1,2,3,4", "1,2,3,4") + val expected = listOf("1,2,3,4") assertEquals(expected, "smeup/T02_A50_P07".outputOf()) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle index 3ccd4072e..306cd7c20 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P07.rpgle @@ -31,11 +31,6 @@ C MOVEL(P) '4' £VARFOR 10 C ENDFOR ****** - C EVAL £DBG_Str=%trim(£VARIF)+','+ - C %trim(£VARDOW)+','+ - C %trim(£VARSL)+','+ - C %trim(£VARFOR) - C £DBG_Str DSPLY * C EVAL £DBG_Str=%trim($VARIF)+','+ C %trim($VARDOW)+','+ From 6665c3c8c08244e57a0e4c3efeecaaf1d1fac13f Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 19:07:13 +0100 Subject: [PATCH 141/423] Replaced ISymbolTable.staticSymbolTable property with getStaticSymbolTable function in order to handle a static SymbolTable for each procedure. This is necessary because in SymbolTable each variable is defined by name, and we could have static variable with the same name but in different procedures --- .../rpgparser/interpreter/ISymbolTable.kt | 19 +++++++++++-------- .../evaluation/SmeupInterpreterTest.kt | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt index c667f3585..5b3727fa2 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/ISymbolTable.kt @@ -42,14 +42,17 @@ interface ISymbolTable { } /** - * Get the static symbol table. This symbol table is shared among all the procedures during the main execution. - * */ - val staticSymbolTable: ISymbolTable - get() { - return MainExecutionContext.getAttributes().computeIfAbsent("staticSymbolTable") { - SymbolTable() - } as SymbolTable - } + * Get the static symbol table for a procedure + * @param procedureName the name of the procedure + * @return the static symbol table for a procedure + */ + fun getStaticSymbolTable(procedureName: String): ISymbolTable { + return MainExecutionContext.getAttributes().computeIfAbsent( + "ISymbolTable.staticSymbolTable.${procedureName.uppercase()}" + ) { + SymbolTable() + } as SymbolTable + } /** * @return true if SymbolTable contains a variable named dataName diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index c6533c6c4..241959da5 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -366,7 +366,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A70_P01() { - val expected = listOf("1", "2") + val expected = listOf("1", "3") assertEquals(expected, "smeup/T02_A70_P01".outputOf()) } From 7dc4521fc5958fe06fa0e6905d06b469293b62d6 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 19:08:02 +0100 Subject: [PATCH 142/423] Implement in SymbolTable the access to static members --- .../kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt index 095ee242e..2e396b676 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/SymbolTable.kt @@ -29,7 +29,7 @@ class SymbolTable : ISymbolTable { return when (data.scope.visibility) { Visibility.Program -> (programSymbolTable as SymbolTable).getLocal(data) Visibility.Local -> getLocal(data) - Visibility.Static -> TODO() + Visibility.Static -> (getStaticSymbolTable(data.scope.reference!!) as SymbolTable).getLocal(data) } } @@ -86,7 +86,7 @@ class SymbolTable : ISymbolTable { return when (data.scope.visibility) { Visibility.Program -> (programSymbolTable as SymbolTable).setLocal(data, value) Visibility.Local -> setLocal(data, value) - Visibility.Static -> TODO() + Visibility.Static -> (getStaticSymbolTable(data.scope.reference!!) as SymbolTable).setLocal(data, value) } } From f7446f95c361dca17c49b08862edb560c4714f72 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 19:11:22 +0100 Subject: [PATCH 143/423] Fix test --- .../kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 81ccd39b5..7321d4be1 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -1882,9 +1882,9 @@ Test 6 @Test fun executePROCEDURE_T() { - // TODO expected is to verify in AS4000 + // TODO expected is to verify in AS400 assertEquals( - expected = listOf("33, 34"), + expected = listOf("33", "34"), actual = "PROCEDURE_T".outputOf() ) } From 12b10c6612e672db3d18d2cd5df9b1143d14f691 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 19:15:10 +0100 Subject: [PATCH 144/423] Add in InternalInterpreter.beforeInitialization and make open afterInitialization. It will be useful when I will change FunctionInterpreter --- .../rpgparser/interpreter/internal_interpreter.kt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index c5b4240f8..5504455e9 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -140,7 +140,7 @@ open class InternalInterpreter( override operator fun get(dataName: String) = globalSymbolTable[dataName] - operator fun set(data: AbstractDataDefinition, value: Value) { + open operator fun set(data: AbstractDataDefinition, value: Value) { require(data.canBeAssigned(value)) { "${data.name} of type ${data.type} defined at line ${data.position.line()} cannot be assigned the value $value" } @@ -219,6 +219,7 @@ open class InternalInterpreter( // symboltable goes empty when program exits in LR mode so, it is always needed reinitialize, in these // circumstances is correct reinitialization if (reinitialization || globalSymbolTable.isEmpty()) { + beforeInitialization() compilationUnit.allDataDefinitions.forEach { var value: Value? = null if (it is DataDefinition) { @@ -982,7 +983,15 @@ open class InternalInterpreter( * */ open fun getMemorySliceMgr(): MemorySliceMgr? = MainExecutionContext.getMemorySliceMgr() - private fun afterInitialization(initialValues: Map) { + /** + * This function is called before the initialization of the interpreter. + * */ + open fun beforeInitialization() {} + + /** + * This function is called after the initialization of the interpreter. + * */ + open fun afterInitialization(initialValues: Map) { getMemorySliceId()?.let { memorySliceId -> getMemorySliceMgr()?.let { MainExecutionContext.getAttributes()[memorySliceId.getAttributeKey()] = it.associate( From f211c31736c15b73b1230b7a323d9bd932494cb9 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 19:16:22 +0100 Subject: [PATCH 145/423] Refactor FunctionInterpreter and implement the logic in order to not reinitialize already static variable initialized --- .../smeup/rpgparser/interpreter/function.kt | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt index 746b7c505..26845925b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt @@ -202,6 +202,8 @@ private fun getProcedureUnit(functionName: String): CompilationUnit { private class FunctionInterpreter(systemInterface: SystemInterface, private val procedureName: String?) : InternalInterpreter(systemInterface = systemInterface) { + private var initializing = false + override fun getMemorySliceId(): MemorySliceId? { val memorySliceId = super.getMemorySliceId() return memorySliceId?.copy(programName = "${memorySliceId.programName}.$procedureName") @@ -213,4 +215,27 @@ private class FunctionInterpreter(systemInterface: SystemInterface, private val override fun fireOnEnterPgmCallBackFunction() { // here I do nothing because I am not a program } + + override fun beforeInitialization() { + initializing = true + super.beforeInitialization() + } + + override fun afterInitialization(initialValues: Map) { + super.afterInitialization(initialValues) + initializing = false + } + + override fun set(data: AbstractDataDefinition, value: Value) { + // if jariko is initializing and data is static, I must check if data is already present in static symbol table + // if not, I can set it else not because static data must be initialized only once + if (initializing && data.static) { + val staticSymbolTable = getGlobalSymbolTable().getStaticSymbolTable(data.scope.reference!!) + if (!staticSymbolTable.contains(data.name)) { + super.set(data, value) + } + } else { + super.set(data, value) + } + } } \ No newline at end of file From 04ccb9f5075695241638bb7932115c01b1b8e820 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 19:16:35 +0100 Subject: [PATCH 146/423] Fix test --- rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle index b05b70575..d7cfe2721 100644 --- a/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/PROCEDURE_T.rpgle @@ -24,6 +24,6 @@ * DVSTAT S 2 0 STATIC * - C EVAL VSTAT=VSTAT+1 C EVAL R=P+Q+VSTAT + C EVAL VSTAT=VSTAT+1 PPPRCST E \ No newline at end of file From 36c84cd150010f8d9e8c3a9d3b74101c7b464935 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 19:20:24 +0100 Subject: [PATCH 147/423] Resolve TODO --- .../kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 7321d4be1..4532307d6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -1882,7 +1882,6 @@ Test 6 @Test fun executePROCEDURE_T() { - // TODO expected is to verify in AS400 assertEquals( expected = listOf("33", "34"), actual = "PROCEDURE_T".outputOf() From 1003d837faabe84e1f04a8c57046bf1bd3137375 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 21 Feb 2024 19:26:14 +0100 Subject: [PATCH 148/423] Add test to check the persistence of static variable among different program calls --- .../rpgparser/evaluation/InterpreterTest.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 4532307d6..acb3f82ad 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -1888,6 +1888,25 @@ Test 6 ) } + /** + * When I call a program that call procedure, the static variables not have to be reset + * */ + @Test + fun executePROCEDURE_T_More_Times() { + // Initialize the configuration with a memory storage in order to keep the static variables + val configuration = Configuration( + memorySliceStorage = IMemorySliceStorage.createMemoryStorage(mutableMapOf()) + ) + assertEquals( + expected = listOf("33", "34"), + actual = "PROCEDURE_T".outputOf(configuration = configuration) + ) + assertEquals( + expected = listOf("35", "36"), + actual = "PROCEDURE_T".outputOf(configuration = configuration) + ) + } + @Test fun executeAPIPGM1() { assertEquals( From 61f6d8427a8a6a1101d0fabe297fd4bbd5790957 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Thu, 22 Feb 2024 09:06:16 +0000 Subject: [PATCH 149/423] reorganise code --- .../parsetreetoast/data_definitions.kt | 49 +++---------------- 1 file changed, 8 insertions(+), 41 deletions(-) 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 14c91b8c4..22bfe1fab 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 @@ -705,11 +705,7 @@ internal fun RpgParser.Dcl_dsContext.calculateFieldInfos(knownDataDefinitions: C val caughtErrors = mutableListOf() val fieldsList = FieldsList(this.parm_fixed().mapNotNull { kotlin.runCatching { - if (it.keyword().map { keyword -> keyword.keyword_like() }.firstOrNull() != null) { - it.toFieldInfoWithExtName(knownDataDefinitions = knownDataDefinitions) - } else { - it.toFieldInfo(knownDataDefinitions = knownDataDefinitions) - } + it.toFieldInfo(knownDataDefinitions = knownDataDefinitions) }.onFailure { caughtErrors.add(it) }.getOrNull() @@ -738,6 +734,11 @@ internal fun RpgParser.Dcl_dsContext.calculateFieldInfos(knownDataDefinitions: C private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = ToAstConfiguration(), knownDataDefinitions: Collection): FieldInfo { var overlayInfo: FieldInfo.OverlayInfo? = null val overlay = this.keyword().find { it.keyword_overlay() != null } + + val isLike = this.keyword().map { keyword -> keyword.keyword_like() }.firstOrNull() != null + val keywordLike = if (isLike) this.keyword().first { it.keyword_like() != null }.keyword_like() else null + val like = if (isLike) keywordLike!!.simpleExpression().toAst(conf) as DataRefExpr else null + // Set the SORTA order val descend = this.keyword().find { it.keyword_descend() != null } != null @@ -772,10 +773,11 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = T // compileTimeInterpreter.evaluate(this.rContext(), dim!!).asInt().value.toInt(), val arraySizeDeclared = this.arraySizeDeclared(conf) + val varName = if (isLike) like!!.variable.name else this.name return FieldInfo(this.name, overlayInfo = overlayInfo, explicitStartOffset = this.explicitStartOffset(), explicitEndOffset = if (explicitStartOffset() != null) this.explicitEndOffset() else null, - explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(this.name, ignoreCase = true) }?.type, + explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(varName, ignoreCase = true) }?.type, arraySizeDeclared = this.arraySizeDeclared(conf), arraySizeDeclaredOnThisField = this.arraySizeDeclared(conf), initializationValue = initializationValue, @@ -783,41 +785,6 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = T position = this.toPosition(conf.considerPosition)) } -private fun RpgParser.Parm_fixedContext.toFieldInfoWithExtName(conf: ToAstConfiguration = ToAstConfiguration(), knownDataDefinitions: Collection): FieldInfo { - val keywordLike = this.keyword().first { it.keyword_like() != null }.keyword_like() - val like = keywordLike.simpleExpression().toAst(conf) as DataRefExpr - val descend = this.keyword().find { it.keyword_descend() != null } != null - - var initializationValue: Expression? = null - val hasInitValue = this.keyword().find { it.keyword_inz() != null } - if (hasInitValue != null) { - if (hasInitValue.keyword_inz().simpleExpression() != null) { - initializationValue = hasInitValue.keyword_inz().simpleExpression()?.toAst(conf) as Expression - } else { - initializationValue = if (null != this.toTypeInfo().decimalPositions) { - RealLiteral(BigDecimal.ZERO, position = toPosition()) - } else { - StringLiteral("", position = toPosition()) - } - } - } else { - this.toDSFieldInitKeyword(conf = conf)?.apply { - initializationValue = this.toAst() - } - } - - val arraySizeDeclared = this.arraySizeDeclared(conf) - return FieldInfo(this.name, - explicitStartOffset = this.explicitStartOffset(), - explicitEndOffset = if (explicitStartOffset() != null) this.explicitEndOffset() else null, - explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(like.variable.name, ignoreCase = true) }?.type, - arraySizeDeclared = this.arraySizeDeclared(conf), - arraySizeDeclaredOnThisField = this.arraySizeDeclared(conf), - initializationValue = initializationValue, - descend = descend, - position = this.toPosition(conf.considerPosition)) -} - fun RpgParser.Dcl_dsContext.declaredSize(): Int? { return if (TO_POSITION().text.trim().isNotEmpty()) { TO_POSITION().text.asInt() From 178e48e81be0d982620076d2520ade364ad7fad4 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 22 Feb 2024 10:10:50 +0100 Subject: [PATCH 150/423] Refactor InternalInterpreter in order to reuse some features related the persistence handling of the symbol table in the life cycling of the interpretation --- .../interpreter/internal_interpreter.kt | 57 +++++++++++++------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 5504455e9..3adc4c0e8 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -974,9 +974,6 @@ open class InternalInterpreter( } } - // Memory slice context attribute name must to be also string representation of MemorySliceId - private fun MemorySliceId.getAttributeKey() = "${MEMORY_SLICE_ATTRIBUTE}_$this" - /** * @return an instance of MemorySliceMgr, return null to disable serialization/deserialization * of symboltable @@ -992,20 +989,7 @@ open class InternalInterpreter( * This function is called after the initialization of the interpreter. * */ open fun afterInitialization(initialValues: Map) { - getMemorySliceId()?.let { memorySliceId -> - getMemorySliceMgr()?.let { - MainExecutionContext.getAttributes()[memorySliceId.getAttributeKey()] = it.associate( - memorySliceId = memorySliceId, - symbolTable = globalSymbolTable, - initSymbolTableEntry = { dataDefinition, storedValue -> - // initial values have not to be overwritten - if (!initialValues.containsKey(dataDefinition.name)) { - globalSymbolTable[dataDefinition] = storedValue - } - } - ) - } - } + globalSymbolTable.restoreFromMemorySlice(getMemorySliceId(), getMemorySliceMgr(), initialValues) } private fun isExitingInRTMode(): Boolean { @@ -1025,7 +1009,7 @@ open class InternalInterpreter( // I had to introduce this function, which will be called from external, because symbol table cleaning before exits // could make failing RpgProgram.execute. // The failure depends on whether that the initialvalues are searched in symboltable - fun doSomethingAfterExecution() { + open fun doSomethingAfterExecution() { val exitingRT = isExitingInRTMode() MainExecutionContext.getAttributes()[getMemorySliceId()?.getAttributeKey()]?.let { (it as MemorySlice).persist = exitingRT @@ -1065,3 +1049,40 @@ internal fun Position.relative(): StatementReference { val copyBlocks = programName?.let { MainExecutionContext.getProgramStack().peek().cu.copyBlocks } return this.relative(programName, copyBlocks) } + +/** + * Memory slice context attribute name must to be also string representation of MemorySliceId + * */ +internal fun MemorySliceId.getAttributeKey() = "${MEMORY_SLICE_ATTRIBUTE}_$this" + +/** + * Restores the symbol table from a memory slice. + * + * This function is used to restore the state of the symbol table from a previously saved memory slice. + * This is useful in scenarios where the state of the symbol table needs to be preserved across different + * executions of the same program, for example in case of stateful programs. + * + * @param memorySliceId The ID of the memory slice to restore from. This ID is used to look up the memory slice in the memory slice manager. + * @param memorySliceMgr The memory slice manager that is used to manage memory slices. It provides functions to create, retrieve and delete memory slices. + * @param initialValues A map of initial values to be set in the symbol table. These values will not be overwritten by the values from the memory slice. + */ +internal fun ISymbolTable.restoreFromMemorySlice( + memorySliceId: MemorySliceId?, + memorySliceMgr: MemorySliceMgr?, + initialValues: Map = emptyMap() +) { + memorySliceId?.let { myMemorySliceId -> + memorySliceMgr?.let { + MainExecutionContext.getAttributes()[myMemorySliceId.getAttributeKey()] = it.associate( + memorySliceId = memorySliceId, + symbolTable = this, + initSymbolTableEntry = { dataDefinition, storedValue -> + // initial values have not to be overwritten + if (!initialValues.containsKey(dataDefinition.name)) { + this[dataDefinition] = storedValue + } + } + ) + } + } +} \ No newline at end of file From 21f5a0be664e1dad395080279dd71bbd334d846d Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 22 Feb 2024 12:44:17 +0100 Subject: [PATCH 151/423] Fix STATIC variable handling in case of program is called more than once in different main execution contexts. --- .../smeup/rpgparser/interpreter/function.kt | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt index 26845925b..20386db8c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/function.kt @@ -75,7 +75,7 @@ open class RpgFunction(private val compilationUnit: CompilationUnit) : Function val interpreter = FunctionInterpreter( systemInterface = systemInterface, - procedureName = compilationUnit.procedureName).apply { + procedureName = compilationUnit.procedureName!!).apply { getGlobalSymbolTable().parentSymbolTable = symbolTable } @@ -200,22 +200,26 @@ private fun getProcedureUnit(functionName: String): CompilationUnit { } } -private class FunctionInterpreter(systemInterface: SystemInterface, private val procedureName: String?) : InternalInterpreter(systemInterface = systemInterface) { +private class FunctionInterpreter(systemInterface: SystemInterface, private val procedureName: String) : InternalInterpreter(systemInterface = systemInterface) { private var initializing = false + private val staticSymbolTable = getGlobalSymbolTable().getStaticSymbolTable(procedureName) + + private val staticMemorySliceId = MemorySliceId( + activationGroup = "*STATIC", + programName = "FunctionInterpreter.$procedureName.static") + override fun getMemorySliceId(): MemorySliceId? { val memorySliceId = super.getMemorySliceId() return memorySliceId?.copy(programName = "${memorySliceId.programName}.$procedureName") } + /** + * This way I can avoid to persist the memory slice of the function + * */ override fun getMemorySliceMgr(): MemorySliceMgr? = null - @Deprecated("No longer used") - override fun fireOnEnterPgmCallBackFunction() { - // here I do nothing because I am not a program - } - override fun beforeInitialization() { initializing = true super.beforeInitialization() @@ -223,6 +227,15 @@ private class FunctionInterpreter(systemInterface: SystemInterface, private val override fun afterInitialization(initialValues: Map) { super.afterInitialization(initialValues) + // I restore static symbol table from memory slice only if it is the first execution. + // This is because the current state of memory slice will be persisted at the end of execution of + // the main program + if (isFirstExecution()) { + staticSymbolTable.restoreFromMemorySlice( + memorySliceMgr = MainExecutionContext.getMemorySliceMgr(), + memorySliceId = staticMemorySliceId + ) + } initializing = false } @@ -230,7 +243,6 @@ private class FunctionInterpreter(systemInterface: SystemInterface, private val // if jariko is initializing and data is static, I must check if data is already present in static symbol table // if not, I can set it else not because static data must be initialized only once if (initializing && data.static) { - val staticSymbolTable = getGlobalSymbolTable().getStaticSymbolTable(data.scope.reference!!) if (!staticSymbolTable.contains(data.name)) { super.set(data, value) } @@ -238,4 +250,15 @@ private class FunctionInterpreter(systemInterface: SystemInterface, private val super.set(data, value) } } + + override fun doSomethingAfterExecution() { + super.doSomethingAfterExecution() + MainExecutionContext.getAttributes()[staticMemorySliceId.getAttributeKey()]?.let { + (it as MemorySlice).persist = true + } + } + + private fun isFirstExecution(): Boolean { + return MainExecutionContext.getAttributes()[staticMemorySliceId.getAttributeKey()] == null + } } \ No newline at end of file From c678e2fbd9b7c9ec2ee85157f6e11909203b4102 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 23 Feb 2024 09:28:56 +0100 Subject: [PATCH 152/423] Implemented case of test --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T10_A35_P07.rpgle | 11 +++++++++++ 2 files changed, 17 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P07.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index d2780010c..c8fa9fbeb 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -382,4 +382,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Res(-A)=-10 Res( -A)= -10") assertEquals(expected, "smeup/T02_A60_P03".outputOf()) } + + @Test + fun executeT10_A35_P07() { + val expected = listOf("Src1=1 Src2=0") + assertEquals(expected, "smeup/T10_A35_P07".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P07.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P07.rpgle new file mode 100644 index 000000000..05aba5eea --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P07.rpgle @@ -0,0 +1,11 @@ + D A35_A20A S 20 INZ('!ABC!ABCDEF') + D £DBG_Str S 100 + + D* SCAN senza variabile + C SETOFF 20 + C '!' SCAN A35_A20A 20 + C EVAL £DBG_Str='Src1='+%CHAR(*IN20) + C '?' SCAN A35_A20A 20 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +' Src2='+%CHAR(*IN20) + C £DBG_Str DSPLY \ No newline at end of file From 0a1cc52339c9553a0fc73f7ee9e677d752ad094d Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:10:11 +0000 Subject: [PATCH 153/423] add T10_A60_P09 --- .../evaluation/SmeupInterpreterTest.kt | 6 +++++ .../test/resources/smeup/T10_A60_P09.rpgle | 25 +++++++++++++++++++ .../test/resources/smeup/T10_A60_P09B.rpgle | 25 +++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09B.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 84103a716..78e6e21ab 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -388,4 +388,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("£C5") assertEquals(expected, "smeup/T02_A50_P05".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT10_A60_P09() { + val expected = listOf("1,2,3,4", "4,3,2,1") + assertEquals(expected, "smeup/T10_A60_P09".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09.rpgle new file mode 100644 index 000000000..859b3c558 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09.rpgle @@ -0,0 +1,25 @@ + D £DBG_Str S 10 + D A60_P9_3 S LIKE(A60_P9_1) + D A60_P9_4 S LIKE(A60_P9_2) + * + C MOVEL(P) '1' A60_P9_1 10 + C MOVEL(P) '2' A60_P9_2 10 + C MOVEL(P) '3' A60_P9_3 + C MOVEL(P) '4' A60_P9_4 + * + C* IF 1=1 + C CALL 'T10_A60_P09B' 37 + C PARM A60_P9_1 10 + C PARM A60_P9_2 10 + C PARM A60_P9_3 + C PARM A60_P9_4 + C* ENDIF + * + C EVAL £DBG_Str=%trim(A60_P9_1)+','+ + C %trim(A60_P9_2)+','+ + C %trim(A60_P9_3)+','+ + C %trim(A60_P9_4) + * + C £DBG_Str DSPLY + * + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09B.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09B.rpgle new file mode 100644 index 000000000..f50e9195b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09B.rpgle @@ -0,0 +1,25 @@ + D £DBG_Str S 10 + D* A60_P9_1 S 10 + D* A60_P9_2 S 10 + D* A60_P9_3 S 10 + D* A60_P9_4 S 10 + * + C *ENTRY PLIST + C PARM A60_P9_1 + C PARM A60_P9_2 + C PARM A60_P9_3 + C PARM A60_P9_4 + * + C EVAL £DBG_Str=%trim(A60_P9_1)+','+ + C %trim(A60_P9_2)+','+ + C %trim(A60_P9_3)+','+ + C %trim(A60_P9_4) + * + C £DBG_Str DSPLY + * + C MOVEL(P) '4' A60_P9_1 + C MOVEL(P) '3' A60_P9_2 + C MOVEL(P) '2' A60_P9_3 + C MOVEL(P) '1' A60_P9_4 + * + C SETON LR \ No newline at end of file From 1f5e8404df7c991fb620bb5606a52735de6d1fac Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 23 Feb 2024 13:01:16 +0100 Subject: [PATCH 154/423] refactor block descendants processing --- .../interpreter/compile_time_interpreter.kt | 47 ++++--------------- 1 file changed, 8 insertions(+), 39 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 55a4030be..eb174c0d1 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -19,6 +19,7 @@ package com.smeup.rpgparser.interpreter import com.smeup.rpgparser.RpgParser import com.smeup.rpgparser.execution.MainExecutionContext import com.smeup.rpgparser.parsing.ast.* +import com.smeup.rpgparser.parsing.facade.findAllDescendants import com.smeup.rpgparser.parsing.parsetreetoast.* import com.smeup.rpgparser.utils.asInt @@ -170,25 +171,9 @@ open class BaseCompileTimeInterpreter( } } it.block() != null -> { - when { - it.block().ifstatement() != null -> { - val size = findSize(it.block().ifstatement().statement(), declName, conf) - if (size != null) return size - } - it.block().forstatement() != null -> { - val size = findSize(it.block().forstatement().statement(), declName, conf) - if (size != null) return size - } - it.block().selectstatement() != null -> { - it.block().selectstatement().whenstatement().forEach() { sl -> - val size = findSize(sl.statement(), declName, conf) - if (size != null) return size - } - } - it.block().csDOWxx() != null || it.block().csDOUxx() != null -> { - val size = findSize(it.block().statement(), declName, conf) - if (size != null) return size - } + it.block().findAllDescendants(type = RpgParser.StatementContext::class, includingMe = false).let { descendants -> + val size = findSize(descendants, declName, conf) + if (size != null) return size } } } @@ -248,7 +233,7 @@ open class BaseCompileTimeInterpreter( private fun findType(statements: List, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Type? { statements - .forEach { + .forEach { it -> when { it.cspec_fixed() != null -> { val ast = it.cspec_fixed().cspec_fixed_standard().toAst(conf) @@ -262,25 +247,9 @@ open class BaseCompileTimeInterpreter( } } it.block() != null -> { - when { - it.block().ifstatement() != null -> { - val type = findType(it.block().ifstatement().statement(), declName, conf) - if (type != null) return type - } - it.block().forstatement() != null -> { - val type = findType(it.block().forstatement().statement(), declName, conf) - if (type != null) return type - } - it.block().selectstatement() != null -> { - it.block().selectstatement().whenstatement().forEach() { sl -> - val type = findType(sl.statement(), declName, conf) - if (type != null) return type - } - } - it.block().csDOWxx() != null || it.block().csDOUxx() != null -> { - val type = findType(it.block().statement(), declName, conf) - if (type != null) return type - } + it.block().findAllDescendants(type = RpgParser.StatementContext::class, includingMe = false).let { descendants -> + val type = findType(descendants, declName, conf) + if (type != null) return type } } } From ccb5d7e7f7101b2fa1179ee440ed2c696c26f30d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 23 Feb 2024 14:02:09 +0100 Subject: [PATCH 155/423] Fixed the bug --- .../smeup/rpgparser/parsing/ast/statements.kt | 18 +++++++++++------- .../rpgparser/parsing/parsetreetoast/misc.kt | 6 +++++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index ece9f62fe..b82cc9e96 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1630,7 +1630,7 @@ data class ScanStmt( val leftLength: Int?, val right: Expression, val startPosition: Int, - val target: AssignableExpression, + val target: AssignableExpression?, val rightIndicators: WithRightIndicators, @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null @@ -1647,14 +1647,18 @@ data class ScanStmt( } while (index >= 0) if (occurrences.isEmpty()) { interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.FALSE, BooleanValue.FALSE) - interpreter.assign(target, IntValue(0)) + if (target != null) { + interpreter.assign(target, IntValue(0)) + } } else { interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.FALSE, BooleanValue.TRUE) - if (target.type().isArray()) { - val fullOccurrences = occurrences.resizeTo(target.type().numberOfElements(), IntValue.ZERO).toMutableList() - interpreter.assign(target, ConcreteArrayValue(fullOccurrences, target.type().asArray().element)) - } else { - interpreter.assign(target, occurrences[0]) + if (target != null) { + if (target.type().isArray()) { + val fullOccurrences = occurrences.resizeTo(target.type().numberOfElements(), IntValue.ZERO).toMutableList() + interpreter.assign(target, ConcreteArrayValue(fullOccurrences, target.type().asArray().element)) + } else { + interpreter.assign(target, occurrences[0]) + } } } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 5ea2e886a..6491ebc4b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1304,12 +1304,16 @@ internal fun CsSCANContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() val rightIndicators = cspec_fixed_standard_parts().rightIndicators() val result = this.cspec_fixed_standard_parts().result.text val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) + val target = when { + result.isNotBlank() -> this.cspec_fixed_standard_parts()!!.result!!.toAst(conf) + else -> null + } return ScanStmt( left = compareExpression, leftLength = compareLength, right = baseExpression, startPosition = startPosition ?: 1, - target = this.cspec_fixed_standard_parts()!!.result!!.toAst(conf), + target = target, rightIndicators = rightIndicators, dataDefinition = dataDefinition, position = position From 9d46d79aa5242545c8f8f2fa0dbf0c60313d6a1b Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 23 Feb 2024 14:06:40 +0100 Subject: [PATCH 156/423] Refactor findType and findSize in order to reuse as much as possible the common logic. --- .../interpreter/compile_time_interpreter.kt | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index eb174c0d1..0a37dd384 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -17,6 +17,7 @@ package com.smeup.rpgparser.interpreter import com.smeup.rpgparser.RpgParser +import com.smeup.rpgparser.RpgParser.Cspec_fixedContext import com.smeup.rpgparser.execution.MainExecutionContext import com.smeup.rpgparser.parsing.ast.* import com.smeup.rpgparser.parsing.facade.findAllDescendants @@ -154,15 +155,8 @@ open class BaseCompileTimeInterpreter( } } it.cspec_fixed() != null -> { - val statement = it.cspec_fixed().cspec_fixed_standard().toAst(conf) - if (statement is StatementThatCanDefineData) { - val dataDefinition = (statement as StatementThatCanDefineData).dataDefinition() - dataDefinition.forEach { - if (it.name.asValue().value == declName) { - return it.type.size - } - } - } + val size = it.cspec_fixed().findType(declName, conf)?.size + if (size != null) return size } it.dcl_ds() != null -> { val name = it.dcl_ds().name @@ -171,10 +165,8 @@ open class BaseCompileTimeInterpreter( } } it.block() != null -> { - it.block().findAllDescendants(type = RpgParser.StatementContext::class, includingMe = false).let { descendants -> - val size = findSize(descendants, declName, conf) - if (size != null) return size - } + val size = it.block().findType(declName, conf)?.size + if (size != null) return size } } } @@ -236,21 +228,12 @@ open class BaseCompileTimeInterpreter( .forEach { it -> when { it.cspec_fixed() != null -> { - val ast = it.cspec_fixed().cspec_fixed_standard().toAst(conf) - if (ast is StatementThatCanDefineData) { - val dataDefinition = (ast as StatementThatCanDefineData).dataDefinition() - dataDefinition.forEach { - if (it.name.asValue().value == declName) { - return it.type - } - } - } + val type = it.cspec_fixed().findType(declName, conf) + if (type != null) return type } it.block() != null -> { - it.block().findAllDescendants(type = RpgParser.StatementContext::class, includingMe = false).let { descendants -> - val type = findType(descendants, declName, conf) - if (type != null) return type - } + val type = it.block().findType(declName, conf) + if (type != null) return type } } } @@ -260,4 +243,23 @@ open class BaseCompileTimeInterpreter( throw NotFoundAtCompileTimeException(declName) } } + + private fun RpgParser.BlockContext.findType(declName: String, conf: ToAstConfiguration): Type? { + return this.findAllDescendants(type = RpgParser.StatementContext::class, includingMe = false).let { descendants -> + findType(descendants, declName, conf) + } + } + + private fun Cspec_fixedContext.findType(declName: String, conf: ToAstConfiguration): Type? { + val ast = this.toAst(conf) + if (ast is StatementThatCanDefineData) { + val dataDefinition = ast.dataDefinition() + dataDefinition.forEach { + if (it.name.asValue().value == declName) { + return it.type + } + } + } + return null + } } From 4d5b7a769e918ff38bc284bfab97ec2f7f178426 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:01:56 +0000 Subject: [PATCH 157/423] add T10_A60_P09 --- .../test/resources/smeup/T10_A60_P09.rpgle | 28 +++++++++---------- .../test/resources/smeup/T10_A60_P09B.rpgle | 8 +++--- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09.rpgle index 859b3c558..ab67222cc 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09.rpgle @@ -1,24 +1,24 @@ D £DBG_Str S 10 - D A60_P9_3 S LIKE(A60_P9_1) - D A60_P9_4 S LIKE(A60_P9_2) + D A6X_P9_3 S LIKE(A6X_P9_1) + D A6X_P9_4 S LIKE(A6X_P9_2) * - C MOVEL(P) '1' A60_P9_1 10 - C MOVEL(P) '2' A60_P9_2 10 - C MOVEL(P) '3' A60_P9_3 - C MOVEL(P) '4' A60_P9_4 + C MOVEL(P) '1' A6X_P9_1 + C MOVEL(P) '2' A6X_P9_2 + C MOVEL(P) '3' A6X_P9_3 + C MOVEL(P) '4' A6X_P9_4 * C* IF 1=1 C CALL 'T10_A60_P09B' 37 - C PARM A60_P9_1 10 - C PARM A60_P9_2 10 - C PARM A60_P9_3 - C PARM A60_P9_4 + C PARM A6X_P9_1 10 + C PARM A6X_P9_2 10 + C PARM A6X_P9_3 + C PARM A6X_P9_4 C* ENDIF * - C EVAL £DBG_Str=%trim(A60_P9_1)+','+ - C %trim(A60_P9_2)+','+ - C %trim(A60_P9_3)+','+ - C %trim(A60_P9_4) + C EVAL £DBG_Str=%trim(A6X_P9_1)+','+ + C %trim(A6X_P9_2)+','+ + C %trim(A6X_P9_3)+','+ + C %trim(A6X_P9_4) * C £DBG_Str DSPLY * diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09B.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09B.rpgle index f50e9195b..40843d311 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09B.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P09B.rpgle @@ -5,10 +5,10 @@ D* A60_P9_4 S 10 * C *ENTRY PLIST - C PARM A60_P9_1 - C PARM A60_P9_2 - C PARM A60_P9_3 - C PARM A60_P9_4 + C PARM A60_P9_1 10 + C PARM A60_P9_2 10 + C PARM A60_P9_3 10 + C PARM A60_P9_4 10 * C EVAL £DBG_Str=%trim(A60_P9_1)+','+ C %trim(A60_P9_2)+','+ From b82b92bbe64eeb348b3b59102e3065dff7e8bfa2 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 26 Feb 2024 15:46:17 +0100 Subject: [PATCH 158/423] Fixed `T02_A60_P02` test --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 1 - .../src/test/resources/smeup/T02_A60_P02.rpgle | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index b793bcc5c..8fd54db53 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -287,7 +287,6 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A60_P02() { -// assertASTCanBeProduced("smeup/T02_A60_P02") val expected = listOf("Res(A*B+C)=246; Res(A * B + C)=246") assertEquals(expected, "smeup/T02_A60_P02".outputOf()) } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P02.rpgle index d5104a9a0..9d54cb85c 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P02.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A60_P02.rpgle @@ -1,6 +1,7 @@ D SCALA S 3 0 D A60_N30B S 3 0 D £DBG_Str S 100 VARYING + C EVAL SCALA=10 C EVAL A60_N30B=24*SCALA+6 C EVAL £DBG_Str='Res(A*B+C)='+%CHAR(A60_N30B) From 9cd03b31b7b7d8a4a375b0e66168edca16db0e32 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 26 Feb 2024 15:47:29 +0100 Subject: [PATCH 159/423] Added additional test for multiplication between number and variable, to test the behaviour of `*` char. --- .../rpgparser/evaluation/InterpreterTest.kt | 13 +++++++++++ .../src/test/resources/EVALVARSNUMS.rpgle | 23 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/EVALVARSNUMS.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index e63b17690..a68256e95 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2210,4 +2210,17 @@ Test 6 "001000000000000000000000000000000000000000010000000000000000000000000000000000000000000100000000000") assertEquals(expected, "MOVEAIN".outputOf()) } + + @Test + fun executeEVALVARSNUMS() { + val expected = listOf( + "246", + "246", + "246", + "246", + "246", + "246" + ) + assertEquals(expected, "EVALVARSNUMS".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/EVALVARSNUMS.rpgle b/rpgJavaInterpreter-core/src/test/resources/EVALVARSNUMS.rpgle new file mode 100644 index 000000000..1f50d37c4 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/EVALVARSNUMS.rpgle @@ -0,0 +1,23 @@ + D VAL S 3 0 + D RES S 3 0 + + C EVAL VAL=10 + + C EVAL RES = 24 * VAL + 6 + C RES DSPLY + + C EVAL RES=24 * VAL + 6 + C RES DSPLY + + + C EVAL RES=24* VAL + 6 + C RES DSPLY + + C EVAL RES = 24* VAL + 6 + C RES DSPLY + + C EVAL RES=24*VAL+6 + C RES DSPLY + + C EVAL RES=24*VAL+6 + C RES DSPLY \ No newline at end of file From a85753d46ede562beab5140a3d3f426e038c552e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 26 Feb 2024 15:58:47 +0100 Subject: [PATCH 160/423] Fixed `RpgLexer` to pass the tests and perform multiplication between number and variable. --- .../src/main/antlr/RpgLexer.g4 | 15 +- .../src/main/antlr/RpgLexer.tokens | 1047 +++++++++-------- 2 files changed, 535 insertions(+), 527 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 index cacccaf10..ac408782a 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 @@ -55,8 +55,15 @@ fragment DECIMAL_SEPARATOR : [.,]; NUMBER : ([0-9]+(DECIMAL_SEPARATOR[0-9]*)?) | DECIMAL_SEPARATOR[0-9]+ ; SEMI : ';'; COLON : ':'; -ID : ('*' {getCharPositionInLine()>7}? '*'? [a-zA-Z])? - [§£#@%$a-zA-Z]{getCharPositionInLine()>7}? [§£#@$a-zA-Z0-9_]* ; +ID : ({ + _input.LA(-1) == 32 || + _input.LA(-1) == '(' || + _input.LA(-1) == '*' || + _input.LA(-1) == '+' || + _input.LA(-1) == '/' || + _input.LA(-1) == '=' + }? '*' {getCharPositionInLine()>7}? '*' ? [a-zA-Z])? + [§£#@%$a-zA-Z]{getCharPositionInLine()>7}? [§£#@$a-zA-Z0-9_]*; NEWLINE : (('\r'? '\n')|'\r') -> skip; WS : [ \t] {getCharPositionInLine()>6}? [ \t]* -> skip ; // skip spaces, tabs @@ -511,8 +518,8 @@ PLUS : '+' ; MINUS : '-' ; EXP : '**' ; ARRAY_REPEAT: {_input.LA(2) == ')' && _input.LA(-1) == '('}? '*' ; -MULT_NOSPACE: {_input.LA(2) != 32}? '*'; -MULT: {_input.LA(2) == 32}? '*' ; +MULT_NOSPACE: {_input.LA(2) != 32 || _input.LA(-1) != 32}? '*'; +MULT: {_input.LA(2) == 32 && _input.LA(-1) == 32}? '*' ; DIV : '/' ; // Assignment Operators diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens index 70ee2662e..7752ce687 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens @@ -252,529 +252,530 @@ SPLAT_FILE=251 SPLAT_GETIN=252 SPLAT_HIVAL=253 SPLAT_INIT=254 -SPLAT_INDICATOR=255 -SPLAT_INZSR=256 -SPLAT_IN=257 -SPLAT_INPUT=258 -SPLAT_OUTPUT=259 -SPLAT_JOBRUN=260 -SPLAT_JOB=261 -SPLAT_LDA=262 -SPLAT_LIKE=263 -SPLAT_LONGJUL=264 -SPLAT_LOVAL=265 -SPLAT_KEY=266 -SPLAT_MONTH=267 -SPLAT_NEXT=268 -SPLAT_NOIND=269 -SPLAT_NOKEY=270 -SPLAT_NULL=271 -SPLAT_OFL=272 -SPLAT_ON=273 -SPLAT_ONLY=274 -SPLAT_OFF=275 -SPLAT_PDA=276 -SPLAT_PLACE=277 -SPLAT_PSSR=278 -SPLAT_ROUTINE=279 -SPLAT_START=280 -SPLAT_SYS=281 -SPLAT_TERM=282 -SPLAT_TOTC=283 -SPLAT_TOTL=284 -SPLAT_USER=285 -SPLAT_VAR=286 -SPLAT_YEAR=287 -SPLAT_ZEROS=288 -SPLAT_HMS=289 -SPLAT_INLR=290 -SPLAT_INOF=291 -SPLAT_DATA=292 -SPLAT_ASTFILL=293 -SPLAT_CURSYM=294 -SPLAT_MAX=295 -SPLAT_LOCK=296 -SPLAT_PROGRAM=297 -SPLAT_EXTDESC=298 -SPLAT_D=299 -SPLAT_H=300 -SPLAT_HOURS=301 -SPLAT_DAYS=302 -SPLAT_M=303 -SPLAT_MINUTES=304 -SPLAT_MONTHS=305 -SPLAT_MN=306 -SPLAT_MS=307 -SPLAT_MSECONDS=308 -SPLAT_S=309 -SPLAT_SECONDS=310 -SPLAT_Y=311 -SPLAT_YEARS=312 -UDATE=313 -DATE=314 -UMONTH=315 -MONTH=316 -UYEAR=317 -YEAR=318 -UDAY=319 -DAY=320 -PAGE=321 -CHAR=322 -VARCHAR=323 -UCS2=324 -DATE_=325 -VARUCS2=326 -GRAPH=327 -VARGRAPH=328 -IND=329 -PACKED=330 -ZONED=331 -BINDEC=332 -INT=333 -UNS=334 -FLOAT=335 -TIME=336 -TIMESTAMP=337 -POINTER=338 -OBJECT=339 -KEYWORD_ALIAS=340 -KEYWORD_ALIGN=341 -KEYWORD_ALT=342 -KEYWORD_ALTSEQ=343 -KEYWORD_ASCEND=344 -KEYWORD_BASED=345 -KEYWORD_CCSID=346 -KEYWORD_CLASS=347 -KEYWORD_CONST=348 -KEYWORD_CTDATA=349 -KEYWORD_DATFMT=350 -KEYWORD_DESCEND=351 -KEYWORD_DIM=352 -KEYWORD_DTAARA=353 -KEYWORD_EXPORT=354 -KEYWORD_EXT=355 -KEYWORD_EXTFLD=356 -KEYWORD_EXTFMT=357 -KEYWORD_EXTNAME=358 -KEYWORD_EXTPGM=359 -KEYWORD_EXTPROC=360 -KEYWORD_FROMFILE=361 -KEYWORD_IMPORT=362 -KEYWORD_INZ=363 -KEYWORD_LEN=364 -KEYWORD_LIKE=365 -KEYWORD_LIKEDS=366 -KEYWORD_LIKEFILE=367 -KEYWORD_LIKEREC=368 -KEYWORD_NOOPT=369 -KEYWORD_OCCURS=370 -KEYWORD_OPDESC=371 -KEYWORD_OPTIONS=372 -KEYWORD_OVERLAY=373 -KEYWORD_PACKEVEN=374 -KEYWORD_PERRCD=375 -KEYWORD_PREFIX=376 -KEYWORD_POS=377 -KEYWORD_PROCPTR=378 -KEYWORD_QUALIFIED=379 -KEYWORD_RTNPARM=380 -KEYWORD_STATIC=381 -KEYWORD_TEMPLATE=382 -KEYWORD_TIMFMT=383 -KEYWORD_TOFILE=384 -KEYWORD_VALUE=385 -KEYWORD_VARYING=386 -KEYWORD_BLOCK=387 -KEYWORD_COMMIT=388 -KEYWORD_DEVID=389 -KEYWORD_EXTDESC=390 -KEYWORD_EXTFILE=391 -KEYWORD_EXTIND=392 -KEYWORD_EXTMBR=393 -KEYWORD_FORMLEN=394 -KEYWORD_FORMOFL=395 -KEYWORD_IGNORE=396 -KEYWORD_INCLUDE=397 -KEYWORD_INDDS=398 -KEYWORD_INFDS=399 -KEYWORD_INFSR=400 -KEYWORD_KEYLOC=401 -KEYWORD_MAXDEV=402 -KEYWORD_OFLIND=403 -KEYWORD_PASS=404 -KEYWORD_PGMNAME=405 -KEYWORD_PLIST=406 -KEYWORD_PRTCTL=407 -KEYWORD_RAFDATA=408 -KEYWORD_RECNO=409 -KEYWORD_RENAME=410 -KEYWORD_SAVEDS=411 -KEYWORD_SAVEIND=412 -KEYWORD_SFILE=413 -KEYWORD_SLN=414 -KEYWORD_SQLTYPE=415 -KEYWORD_USROPN=416 -KEYWORD_DISK=417 -KEYWORD_WORKSTN=418 -KEYWORD_PRINTER=419 -KEYWORD_SPECIAL=420 -KEYWORD_KEYED=421 -KEYWORD_USAGE=422 -KEYWORD_PSDS=423 -AMPERSAND=424 -AND=425 -OR=426 -NOT=427 -PLUS=428 -MINUS=429 -EXP=430 -ARRAY_REPEAT=431 -MULT_NOSPACE=432 -MULT=433 -DIV=434 -CPLUS=435 -CMINUS=436 -CMULT=437 -CDIV=438 -CEXP=439 -GT=440 -LT=441 -GE=442 -LE=443 -NE=444 -FREE_DOT=445 -EQUAL=446 -FREE_BY=447 -FREE_TO=448 -FREE_DOWNTO=449 -HexLiteralStart=450 -DateLiteralStart=451 -TimeLiteralStart=452 -TimeStampLiteralStart=453 -GraphicLiteralStart=454 -UCS2LiteralStart=455 -StringLiteralStart=456 -FREE_COMMENTS=457 -FREE_WS=458 -C_FREE_CONTINUATION=459 -D_FREE_CONTINUATION=460 -F_FREE_CONTINUATION=461 -FREE_LEAD_WS5=462 -FREE_LEAD_WS5_Comments=463 -FREE_FREE_SPEC=464 -C_FREE_NEWLINE=465 -FREE_NEWLINE=466 -FREE_SEMI=467 -NumberContinuation_CONTINUATION=468 -NumberPart=469 -NumberContinuation_ANY=470 -OP_ADD=471 -OP_ADDDUR=472 -OP_ALLOC=473 -OP_ANDxx=474 -OP_ANDEQ=475 -OP_ANDNE=476 -OP_ANDLE=477 -OP_ANDLT=478 -OP_ANDGE=479 -OP_ANDGT=480 -OP_BITOFF=481 -OP_BITON=482 -OP_CAB=483 -OP_CABEQ=484 -OP_CABNE=485 -OP_CABLE=486 -OP_CABLT=487 -OP_CABGE=488 -OP_CABGT=489 -OP_CALL=490 -OP_CALLB=491 -OP_CASEQ=492 -OP_CASNE=493 -OP_CASLE=494 -OP_CASLT=495 -OP_CASGE=496 -OP_CASGT=497 -OP_CAS=498 -OP_CAT=499 -OP_CHECK=500 -OP_CHECKR=501 -OP_COMP=502 -OP_DEFINE=503 -OP_DIV=504 -OP_DO=505 -OP_DOUEQ=506 -OP_DOUNE=507 -OP_DOULE=508 -OP_DOULT=509 -OP_DOUGE=510 -OP_DOUGT=511 -OP_DOWEQ=512 -OP_DOWNE=513 -OP_DOWLE=514 -OP_DOWLT=515 -OP_DOWGE=516 -OP_DOWGT=517 -OP_END=518 -OP_ENDCS=519 -OP_EXTRCT=520 -OP_GOTO=521 -OP_IFEQ=522 -OP_IFNE=523 -OP_IFLE=524 -OP_IFLT=525 -OP_IFGE=526 -OP_IFGT=527 -OP_KFLD=528 -OP_KLIST=529 -OP_LOOKUP=530 -OP_MHHZO=531 -OP_MHLZO=532 -OP_MLHZO=533 -OP_MLLZO=534 -OP_MOVE=535 -OP_MOVEA=536 -OP_MOVEL=537 -OP_MULT=538 -OP_MVR=539 -OP_OCCUR=540 -OP_OREQ=541 -OP_ORNE=542 -OP_ORLE=543 -OP_ORLT=544 -OP_ORGE=545 -OP_ORGT=546 -OP_PARM=547 -OP_PLIST=548 -OP_REALLOC=549 -OP_SCAN=550 -OP_SETOFF=551 -OP_SETON=552 -OP_SHTDN=553 -OP_SQRT=554 -OP_SUB=555 -OP_SUBDUR=556 -OP_SUBST=557 -OP_TAG=558 -OP_TESTB=559 -OP_TESTN=560 -OP_TESTZ=561 -OP_TIME=562 -OP_WHENEQ=563 -OP_WHENNE=564 -OP_WHENLE=565 -OP_WHENLT=566 -OP_WHENGE=567 -OP_WHENGT=568 -OP_XFOOT=569 -OP_XLATE=570 -OP_Z_ADD=571 -OP_Z_SUB=572 -FE_BLANKS=573 -FE_COMMENTS=574 -FE_NEWLINE=575 -StringContent=576 -StringEscapedQuote=577 -StringLiteralEnd=578 -FIXED_FREE_STRING_CONTINUATION=579 -FIXED_FREE_STRING_CONTINUATION_MINUS=580 -FREE_STRING_CONTINUATION=581 -FREE_STRING_CONTINUATION_MINUS=582 -PlusOrMinus=583 -EatCommentLinesPlus_Any=584 -EatCommentLines_WhiteSpace=585 -EatCommentLines_StarComment=586 -FIXED_FREE_STRING_CONTINUATION_Part2=587 -EatCommentLines_NothingLeft=588 -InFactor_EndFactor=589 -BLANK_COMMENTS_TEXT=590 -COMMENTS_TEXT=591 -COMMENTS_EOL=592 -COMMENTS_TEXT_SKIP=593 -COMMENTS_TEXT_HIDDEN=594 -COMMENTS_EOL_HIDDEN=595 -SQL_WS=596 -WORDS=597 -PS_NAME=598 -PS_CONTINUATION_NAME=599 -PS_CONTINUATION=600 -PS_RESERVED1=601 -PS_BEGIN=602 -PS_END=603 -PS_RESERVED2=604 -PS_KEYWORDS=605 -PS_WS80=606 -PS_COMMENTS80=607 -PS_Any=608 -BLANK_SPEC=609 -CONTINUATION_NAME=610 -CONTINUATION=611 -NAME=612 -EXTERNAL_DESCRIPTION=613 -DATA_STRUCTURE_TYPE=614 -DEF_TYPE_C=615 -DEF_TYPE_PI=616 -DEF_TYPE_PR=617 -DEF_TYPE_DS=618 -DEF_TYPE_S=619 -DEF_TYPE_BLANK=620 -DEF_TYPE=621 -FROM_POSITION=622 -TO_POSITION=623 -DATA_TYPE=624 -DECIMAL_POSITIONS=625 -RESERVED=626 -D_WS=627 -D_COMMENTS80=628 -EOL=629 -CE_WS=630 -CE_COMMENTS80=631 -CE_LEAD_WS5=632 -CE_LEAD_WS5_Comments=633 -CE_D_SPEC_FIXED=634 -CE_P_SPEC_FIXED=635 -CE_NEWLINE=636 -FS_RecordName=637 -FS_Type=638 -FS_Designation=639 -FS_EndOfFile=640 -FS_Addution=641 -FS_Sequence=642 -FS_Format=643 -FS_RecordLength=644 -FS_Limits=645 -FS_LengthOfKey=646 -FS_RecordAddressType=647 -FS_Organization=648 -FS_Device=649 -FS_Reserved=650 -FS_WhiteSpace=651 -OS_RecordName=652 -OS_AndOr=653 -OS_FieldReserved=654 -OS_Type=655 -OS_AddDelete=656 -OS_FetchOverflow=657 -OS_ExceptName=658 -OS_Space3=659 -OS_RemainingSpace=660 -OS_Comments=661 -OS_WS=662 -OS_FieldName=663 -OS_EditNames=664 -OS_BlankAfter=665 -OS_Reserved1=666 -OS_EndPosition=667 -OS_DataFormat=668 -OS_Any=669 -CS_BlankFactor=670 -CS_FactorWs=671 -CS_FactorWs2=672 -CS_FactorContent=673 -CS_OperationAndExtender_Blank=674 -CS_OperationAndExtender_WS=675 -CS_OperationAndExtender=676 -CS_FieldLength=677 -CS_DecimalPositions=678 -CS_WhiteSpace=679 -CS_Comments=680 -CS_FixedComments=681 -CS_FixedOperationAndExtender_WS=682 -CS_FixedOperationExtenderReturn=683 -CS_FixedOperationAndExtender2_WS=684 -CS_FixedOperationExtender2Return=685 -FreeOpExtender_Any=686 -FreeOpExtender2_WS=687 -BlankFlag=688 -NoFlag=689 -BlankIndicator=690 -GeneralIndicator=691 -FunctionKeyIndicator=692 -ControlLevelIndicator=693 -ControlLevel0Indicator=694 -LastRecordIndicator=695 -MatchingRecordIndicator=696 -HaltIndicator=697 -ReturnIndicator=698 -ExternalIndicator=699 -OverflowIndicator=700 -SubroutineIndicator=701 -AndIndicator=702 -OrIndicator=703 -DoubleSplatIndicator=704 -FirstPageIndicator=705 -OtherTextIndicator=706 -NewLineIndicator=707 -CSQL_EMPTY_TEXT=708 -CSQL_TEXT=709 -CSQL_LEADBLANK=710 -CSQL_LEADWS=711 -CSQL_END=712 -CSQL_CONT=713 -CSQL_CSplat=714 -CSQL_EOL=715 -CSQL_Any=716 -CSQLC_LEADWS=717 -CSQLC_CSplat=718 -CSQLC_WS=719 -CSQLC_Comments=720 -CSQLC_Any=721 -C2_FACTOR2_CONT=722 -C2_FACTOR2=723 -C2_OTHER=724 -IS_FileName=725 -IS_FieldReserved=726 -IS_ExtFieldReserved=727 -IS_LogicalRelationship=728 -IS_ExtRecordReserved=729 -IS_Sequence=730 -IS_Number=731 -IS_Option=732 -IS_RecordIdCode=733 -IS_WS=734 -IS_COMMENTS=735 -IF_Name=736 -IF_Reserved=737 -IF_FieldName=738 -IF_Reserved2=739 -IF_WS=740 -IR_WS=741 -IFD_DATA_ATTR=742 -IFD_DATETIME_SEP=743 -IFD_DATA_FORMAT=744 -IFD_FIELD_LOCATION=745 -IFD_DECIMAL_POSITIONS=746 -IFD_FIELD_NAME=747 -IFD_CONTROL_LEVEL=748 -IFD_MATCHING_FIELDS=749 -IFD_BLANKS=750 -IFD_COMMENTS=751 -HS_DECEDIT=752 -HS_NEW=753 -HS_CALLER=754 -HS_ACTGRP=755 -HS_WhiteSpace=756 -HS_CONTINUATION=757 +SPLAT_ALL_INDICATORS=255 +SPLAT_INDICATOR=256 +SPLAT_INZSR=257 +SPLAT_IN=258 +SPLAT_INPUT=259 +SPLAT_OUTPUT=260 +SPLAT_JOBRUN=261 +SPLAT_JOB=262 +SPLAT_LDA=263 +SPLAT_LIKE=264 +SPLAT_LONGJUL=265 +SPLAT_LOVAL=266 +SPLAT_KEY=267 +SPLAT_MONTH=268 +SPLAT_NEXT=269 +SPLAT_NOIND=270 +SPLAT_NOKEY=271 +SPLAT_NULL=272 +SPLAT_OFL=273 +SPLAT_ON=274 +SPLAT_ONLY=275 +SPLAT_OFF=276 +SPLAT_PDA=277 +SPLAT_PLACE=278 +SPLAT_PSSR=279 +SPLAT_ROUTINE=280 +SPLAT_START=281 +SPLAT_SYS=282 +SPLAT_TERM=283 +SPLAT_TOTC=284 +SPLAT_TOTL=285 +SPLAT_USER=286 +SPLAT_VAR=287 +SPLAT_YEAR=288 +SPLAT_ZEROS=289 +SPLAT_HMS=290 +SPLAT_INLR=291 +SPLAT_INOF=292 +SPLAT_DATA=293 +SPLAT_ASTFILL=294 +SPLAT_CURSYM=295 +SPLAT_MAX=296 +SPLAT_LOCK=297 +SPLAT_PROGRAM=298 +SPLAT_EXTDESC=299 +SPLAT_D=300 +SPLAT_H=301 +SPLAT_HOURS=302 +SPLAT_DAYS=303 +SPLAT_M=304 +SPLAT_MINUTES=305 +SPLAT_MONTHS=306 +SPLAT_MN=307 +SPLAT_MS=308 +SPLAT_MSECONDS=309 +SPLAT_S=310 +SPLAT_SECONDS=311 +SPLAT_Y=312 +SPLAT_YEARS=313 +UDATE=314 +DATE=315 +UMONTH=316 +MONTH=317 +UYEAR=318 +YEAR=319 +UDAY=320 +DAY=321 +PAGE=322 +CHAR=323 +VARCHAR=324 +UCS2=325 +DATE_=326 +VARUCS2=327 +GRAPH=328 +VARGRAPH=329 +IND=330 +PACKED=331 +ZONED=332 +BINDEC=333 +INT=334 +UNS=335 +FLOAT=336 +TIME=337 +TIMESTAMP=338 +POINTER=339 +OBJECT=340 +KEYWORD_ALIAS=341 +KEYWORD_ALIGN=342 +KEYWORD_ALT=343 +KEYWORD_ALTSEQ=344 +KEYWORD_ASCEND=345 +KEYWORD_BASED=346 +KEYWORD_CCSID=347 +KEYWORD_CLASS=348 +KEYWORD_CONST=349 +KEYWORD_CTDATA=350 +KEYWORD_DATFMT=351 +KEYWORD_DESCEND=352 +KEYWORD_DIM=353 +KEYWORD_DTAARA=354 +KEYWORD_EXPORT=355 +KEYWORD_EXT=356 +KEYWORD_EXTFLD=357 +KEYWORD_EXTFMT=358 +KEYWORD_EXTNAME=359 +KEYWORD_EXTPGM=360 +KEYWORD_EXTPROC=361 +KEYWORD_FROMFILE=362 +KEYWORD_IMPORT=363 +KEYWORD_INZ=364 +KEYWORD_LEN=365 +KEYWORD_LIKE=366 +KEYWORD_LIKEDS=367 +KEYWORD_LIKEFILE=368 +KEYWORD_LIKEREC=369 +KEYWORD_NOOPT=370 +KEYWORD_OCCURS=371 +KEYWORD_OPDESC=372 +KEYWORD_OPTIONS=373 +KEYWORD_OVERLAY=374 +KEYWORD_PACKEVEN=375 +KEYWORD_PERRCD=376 +KEYWORD_PREFIX=377 +KEYWORD_POS=378 +KEYWORD_PROCPTR=379 +KEYWORD_QUALIFIED=380 +KEYWORD_RTNPARM=381 +KEYWORD_STATIC=382 +KEYWORD_TEMPLATE=383 +KEYWORD_TIMFMT=384 +KEYWORD_TOFILE=385 +KEYWORD_VALUE=386 +KEYWORD_VARYING=387 +KEYWORD_BLOCK=388 +KEYWORD_COMMIT=389 +KEYWORD_DEVID=390 +KEYWORD_EXTDESC=391 +KEYWORD_EXTFILE=392 +KEYWORD_EXTIND=393 +KEYWORD_EXTMBR=394 +KEYWORD_FORMLEN=395 +KEYWORD_FORMOFL=396 +KEYWORD_IGNORE=397 +KEYWORD_INCLUDE=398 +KEYWORD_INDDS=399 +KEYWORD_INFDS=400 +KEYWORD_INFSR=401 +KEYWORD_KEYLOC=402 +KEYWORD_MAXDEV=403 +KEYWORD_OFLIND=404 +KEYWORD_PASS=405 +KEYWORD_PGMNAME=406 +KEYWORD_PLIST=407 +KEYWORD_PRTCTL=408 +KEYWORD_RAFDATA=409 +KEYWORD_RECNO=410 +KEYWORD_RENAME=411 +KEYWORD_SAVEDS=412 +KEYWORD_SAVEIND=413 +KEYWORD_SFILE=414 +KEYWORD_SLN=415 +KEYWORD_SQLTYPE=416 +KEYWORD_USROPN=417 +KEYWORD_DISK=418 +KEYWORD_WORKSTN=419 +KEYWORD_PRINTER=420 +KEYWORD_SPECIAL=421 +KEYWORD_KEYED=422 +KEYWORD_USAGE=423 +KEYWORD_PSDS=424 +AMPERSAND=425 +AND=426 +OR=427 +NOT=428 +PLUS=429 +MINUS=430 +EXP=431 +ARRAY_REPEAT=432 +MULT_NOSPACE=433 +MULT=434 +DIV=435 +CPLUS=436 +CMINUS=437 +CMULT=438 +CDIV=439 +CEXP=440 +GT=441 +LT=442 +GE=443 +LE=444 +NE=445 +FREE_DOT=446 +EQUAL=447 +FREE_BY=448 +FREE_TO=449 +FREE_DOWNTO=450 +HexLiteralStart=451 +DateLiteralStart=452 +TimeLiteralStart=453 +TimeStampLiteralStart=454 +GraphicLiteralStart=455 +UCS2LiteralStart=456 +StringLiteralStart=457 +FREE_COMMENTS=458 +FREE_WS=459 +C_FREE_CONTINUATION=460 +D_FREE_CONTINUATION=461 +F_FREE_CONTINUATION=462 +FREE_LEAD_WS5=463 +FREE_LEAD_WS5_Comments=464 +FREE_FREE_SPEC=465 +C_FREE_NEWLINE=466 +FREE_NEWLINE=467 +FREE_SEMI=468 +NumberContinuation_CONTINUATION=469 +NumberPart=470 +NumberContinuation_ANY=471 +OP_ADD=472 +OP_ADDDUR=473 +OP_ALLOC=474 +OP_ANDxx=475 +OP_ANDEQ=476 +OP_ANDNE=477 +OP_ANDLE=478 +OP_ANDLT=479 +OP_ANDGE=480 +OP_ANDGT=481 +OP_BITOFF=482 +OP_BITON=483 +OP_CAB=484 +OP_CABEQ=485 +OP_CABNE=486 +OP_CABLE=487 +OP_CABLT=488 +OP_CABGE=489 +OP_CABGT=490 +OP_CALL=491 +OP_CALLB=492 +OP_CASEQ=493 +OP_CASNE=494 +OP_CASLE=495 +OP_CASLT=496 +OP_CASGE=497 +OP_CASGT=498 +OP_CAS=499 +OP_CAT=500 +OP_CHECK=501 +OP_CHECKR=502 +OP_COMP=503 +OP_DEFINE=504 +OP_DIV=505 +OP_DO=506 +OP_DOUEQ=507 +OP_DOUNE=508 +OP_DOULE=509 +OP_DOULT=510 +OP_DOUGE=511 +OP_DOUGT=512 +OP_DOWEQ=513 +OP_DOWNE=514 +OP_DOWLE=515 +OP_DOWLT=516 +OP_DOWGE=517 +OP_DOWGT=518 +OP_END=519 +OP_ENDCS=520 +OP_EXTRCT=521 +OP_GOTO=522 +OP_IFEQ=523 +OP_IFNE=524 +OP_IFLE=525 +OP_IFLT=526 +OP_IFGE=527 +OP_IFGT=528 +OP_KFLD=529 +OP_KLIST=530 +OP_LOOKUP=531 +OP_MHHZO=532 +OP_MHLZO=533 +OP_MLHZO=534 +OP_MLLZO=535 +OP_MOVE=536 +OP_MOVEA=537 +OP_MOVEL=538 +OP_MULT=539 +OP_MVR=540 +OP_OCCUR=541 +OP_OREQ=542 +OP_ORNE=543 +OP_ORLE=544 +OP_ORLT=545 +OP_ORGE=546 +OP_ORGT=547 +OP_PARM=548 +OP_PLIST=549 +OP_REALLOC=550 +OP_SCAN=551 +OP_SETOFF=552 +OP_SETON=553 +OP_SHTDN=554 +OP_SQRT=555 +OP_SUB=556 +OP_SUBDUR=557 +OP_SUBST=558 +OP_TAG=559 +OP_TESTB=560 +OP_TESTN=561 +OP_TESTZ=562 +OP_TIME=563 +OP_WHENEQ=564 +OP_WHENNE=565 +OP_WHENLE=566 +OP_WHENLT=567 +OP_WHENGE=568 +OP_WHENGT=569 +OP_XFOOT=570 +OP_XLATE=571 +OP_Z_ADD=572 +OP_Z_SUB=573 +FE_BLANKS=574 +FE_COMMENTS=575 +FE_NEWLINE=576 +StringContent=577 +StringEscapedQuote=578 +StringLiteralEnd=579 +FIXED_FREE_STRING_CONTINUATION=580 +FIXED_FREE_STRING_CONTINUATION_MINUS=581 +FREE_STRING_CONTINUATION=582 +FREE_STRING_CONTINUATION_MINUS=583 +PlusOrMinus=584 +EatCommentLinesPlus_Any=585 +EatCommentLines_WhiteSpace=586 +EatCommentLines_StarComment=587 +FIXED_FREE_STRING_CONTINUATION_Part2=588 +EatCommentLines_NothingLeft=589 +InFactor_EndFactor=590 +BLANK_COMMENTS_TEXT=591 +COMMENTS_TEXT=592 +COMMENTS_EOL=593 +COMMENTS_TEXT_SKIP=594 +COMMENTS_TEXT_HIDDEN=595 +COMMENTS_EOL_HIDDEN=596 +SQL_WS=597 +WORDS=598 +PS_NAME=599 +PS_CONTINUATION_NAME=600 +PS_CONTINUATION=601 +PS_RESERVED1=602 +PS_BEGIN=603 +PS_END=604 +PS_RESERVED2=605 +PS_KEYWORDS=606 +PS_WS80=607 +PS_COMMENTS80=608 +PS_Any=609 +BLANK_SPEC=610 +CONTINUATION_NAME=611 +CONTINUATION=612 +NAME=613 +EXTERNAL_DESCRIPTION=614 +DATA_STRUCTURE_TYPE=615 +DEF_TYPE_C=616 +DEF_TYPE_PI=617 +DEF_TYPE_PR=618 +DEF_TYPE_DS=619 +DEF_TYPE_S=620 +DEF_TYPE_BLANK=621 +DEF_TYPE=622 +FROM_POSITION=623 +TO_POSITION=624 +DATA_TYPE=625 +DECIMAL_POSITIONS=626 +RESERVED=627 +D_WS=628 +D_COMMENTS80=629 +EOL=630 +CE_WS=631 +CE_COMMENTS80=632 +CE_LEAD_WS5=633 +CE_LEAD_WS5_Comments=634 +CE_D_SPEC_FIXED=635 +CE_P_SPEC_FIXED=636 +CE_NEWLINE=637 +FS_RecordName=638 +FS_Type=639 +FS_Designation=640 +FS_EndOfFile=641 +FS_Addution=642 +FS_Sequence=643 +FS_Format=644 +FS_RecordLength=645 +FS_Limits=646 +FS_LengthOfKey=647 +FS_RecordAddressType=648 +FS_Organization=649 +FS_Device=650 +FS_Reserved=651 +FS_WhiteSpace=652 +OS_RecordName=653 +OS_AndOr=654 +OS_FieldReserved=655 +OS_Type=656 +OS_AddDelete=657 +OS_FetchOverflow=658 +OS_ExceptName=659 +OS_Space3=660 +OS_RemainingSpace=661 +OS_Comments=662 +OS_WS=663 +OS_FieldName=664 +OS_EditNames=665 +OS_BlankAfter=666 +OS_Reserved1=667 +OS_EndPosition=668 +OS_DataFormat=669 +OS_Any=670 +CS_BlankFactor=671 +CS_FactorWs=672 +CS_FactorWs2=673 +CS_FactorContent=674 +CS_OperationAndExtender_Blank=675 +CS_OperationAndExtender_WS=676 +CS_OperationAndExtender=677 +CS_FieldLength=678 +CS_DecimalPositions=679 +CS_WhiteSpace=680 +CS_Comments=681 +CS_FixedComments=682 +CS_FixedOperationAndExtender_WS=683 +CS_FixedOperationExtenderReturn=684 +CS_FixedOperationAndExtender2_WS=685 +CS_FixedOperationExtender2Return=686 +FreeOpExtender_Any=687 +FreeOpExtender2_WS=688 +BlankFlag=689 +NoFlag=690 +BlankIndicator=691 +GeneralIndicator=692 +FunctionKeyIndicator=693 +ControlLevelIndicator=694 +ControlLevel0Indicator=695 +LastRecordIndicator=696 +MatchingRecordIndicator=697 +HaltIndicator=698 +ReturnIndicator=699 +ExternalIndicator=700 +OverflowIndicator=701 +SubroutineIndicator=702 +AndIndicator=703 +OrIndicator=704 +DoubleSplatIndicator=705 +FirstPageIndicator=706 +OtherTextIndicator=707 +NewLineIndicator=708 +CSQL_EMPTY_TEXT=709 +CSQL_TEXT=710 +CSQL_LEADBLANK=711 +CSQL_LEADWS=712 +CSQL_END=713 +CSQL_CONT=714 +CSQL_CSplat=715 +CSQL_EOL=716 +CSQL_Any=717 +CSQLC_LEADWS=718 +CSQLC_CSplat=719 +CSQLC_WS=720 +CSQLC_Comments=721 +CSQLC_Any=722 +C2_FACTOR2_CONT=723 +C2_FACTOR2=724 +C2_OTHER=725 +IS_FileName=726 +IS_FieldReserved=727 +IS_ExtFieldReserved=728 +IS_LogicalRelationship=729 +IS_ExtRecordReserved=730 +IS_Sequence=731 +IS_Number=732 +IS_Option=733 +IS_RecordIdCode=734 +IS_WS=735 +IS_COMMENTS=736 +IF_Name=737 +IF_Reserved=738 +IF_FieldName=739 +IF_Reserved2=740 +IF_WS=741 +IR_WS=742 +IFD_DATA_ATTR=743 +IFD_DATETIME_SEP=744 +IFD_DATA_FORMAT=745 +IFD_FIELD_LOCATION=746 +IFD_DECIMAL_POSITIONS=747 +IFD_FIELD_NAME=748 +IFD_CONTROL_LEVEL=749 +IFD_MATCHING_FIELDS=750 +IFD_BLANKS=751 +IFD_COMMENTS=752 +HS_DECEDIT=753 +HS_NEW=754 +HS_CALLER=755 +HS_ACTGRP=756 +HS_WhiteSpace=757 +HS_CONTINUATION=758 '('=20 ')'=21 ';'=23 -'&'=424 -'+'=428 -'-'=429 -'/'=434 -'+='=435 -'-='=436 -'*='=437 -'/='=438 -'**='=439 -'>'=440 -'<'=441 -'>='=442 -'<='=443 -'<>'=444 -'.'=445 -'='=446 -' '=609 -' '=660 -' '=670 -' '=674 +'&'=425 +'+'=429 +'-'=430 +'/'=435 +'+='=436 +'-='=437 +'*='=438 +'/='=439 +'**='=440 +'>'=441 +'<'=442 +'>='=443 +'<='=444 +'<>'=445 +'.'=446 +'='=447 +' '=610 +' '=661 +' '=671 +' '=675 From a544acf9b8aa8963c2f82821d17ff75b1709a8fb Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 09:00:19 +0100 Subject: [PATCH 161/423] Implemented cases of test for passes from 35 to 38 --- .../evaluation/SmeupInterpreterTest.kt | 11 +++ .../test/resources/smeup/T10_A20_P35-38.rpgle | 80 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P35-38.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index d4997eb1a..5a60391ea 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -394,4 +394,15 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("£C5") assertEquals(expected, "smeup/T02_A50_P05".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT10_A20_P35_38() { + val expected = listOf( + "Res(21, 0, 0, 0, 0, 0)", + "Res(0, -19, 0, 0, 0, 0)", + "Res(0, 0, 20, 0, 0, 0)", + "Res(0, 0, 0, 2, 0, 0)" + ) + assertEquals(expected, "smeup/T10_A20_P35-38".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P35-38.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P35-38.rpgle new file mode 100644 index 000000000..c35fb1b2e --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P35-38.rpgle @@ -0,0 +1,80 @@ + D A20_AR2 S 2 0 DIM(6) + D A20_N60 S 6 0 + D A20_I S 2 0 + D £DBG_Str S 100 VARYING + + D* ADD con interi ed elementi di array + C EVAL A20_N60=20 + C EVAL A20_I=1 + C EVAL A20_AR2(1)=1 + C EVAL A20_AR2(2)=0 + C EVAL A20_AR2(3)=0 + C EVAL A20_AR2(4)=0 + C EVAL A20_AR2(5)=0 + C EVAL A20_AR2(6)=0 + C ADD A20_N60 A20_AR2(A20_I) + C EVAL £DBG_Str='Res(' + C +%CHAR(A20_AR2(1))+', ' + C +%CHAR(A20_AR2(2))+', ' + C +%CHAR(A20_AR2(3))+', ' + C +%CHAR(A20_AR2(4))+', ' + C +%CHAR(A20_AR2(5))+', ' + C +%CHAR(A20_AR2(6))+')' + C £DBG_Str DSPLY + + D* SUB con interi ed elementi di array + C EVAL A20_N60=20 + C EVAL A20_I=2 + C EVAL A20_AR2(1)=0 + C EVAL A20_AR2(2)=1 + C EVAL A20_AR2(3)=0 + C EVAL A20_AR2(4)=0 + C EVAL A20_AR2(5)=0 + C EVAL A20_AR2(6)=0 + C SUB A20_N60 A20_AR2(A20_I) + C EVAL £DBG_Str='Res(' + C +%CHAR(A20_AR2(1))+', ' + C +%CHAR(A20_AR2(2))+', ' + C +%CHAR(A20_AR2(3))+', ' + C +%CHAR(A20_AR2(4))+', ' + C +%CHAR(A20_AR2(5))+', ' + C +%CHAR(A20_AR2(6))+')' + C £DBG_Str DSPLY + + D* MULT con interi ed elementi di array + C EVAL A20_N60=20 + C EVAL A20_I=3 + C EVAL A20_AR2(1)=0 + C EVAL A20_AR2(2)=0 + C EVAL A20_AR2(3)=1 + C EVAL A20_AR2(4)=0 + C EVAL A20_AR2(5)=0 + C EVAL A20_AR2(6)=0 + C MULT A20_N60 A20_AR2(A20_I) + C EVAL £DBG_Str='Res(' + C +%CHAR(A20_AR2(1))+', ' + C +%CHAR(A20_AR2(2))+', ' + C +%CHAR(A20_AR2(3))+', ' + C +%CHAR(A20_AR2(4))+', ' + C +%CHAR(A20_AR2(5))+', ' + C +%CHAR(A20_AR2(6))+')' + C £DBG_Str DSPLY + + D* DIV con interi ed elementi di array + C EVAL A20_N60=20 + C EVAL A20_I=4 + C EVAL A20_AR2(1)=0 + C EVAL A20_AR2(2)=0 + C EVAL A20_AR2(3)=0 + C EVAL A20_AR2(4)=40 + C EVAL A20_AR2(5)=0 + C EVAL A20_AR2(6)=0 + C DIV A20_N60 A20_AR2(A20_I) + C EVAL £DBG_Str='Res(' + C +%CHAR(A20_AR2(1))+', ' + C +%CHAR(A20_AR2(2))+', ' + C +%CHAR(A20_AR2(3))+', ' + C +%CHAR(A20_AR2(4))+', ' + C +%CHAR(A20_AR2(5))+', ' + C +%CHAR(A20_AR2(6))+')' + C £DBG_Str DSPLY From 54c458d6f6732deefc9858d9e42bac5c2a06fc1d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 09:02:51 +0100 Subject: [PATCH 162/423] Implemented case of test for pass 40 --- .../evaluation/SmeupInterpreterTest.kt | 6 +++++ .../test/resources/smeup/T10_A20_P40.rpgle | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P40.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 5a60391ea..231886676 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -405,4 +405,10 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T10_A20_P35-38".outputOf()) } + + @Test + fun executeT10_A20_P40() { + val expected = listOf("Res(0, 0, 0, 0, 0, -20)") + assertEquals(expected, "smeup/T10_A20_P40".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P40.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P40.rpgle new file mode 100644 index 000000000..c606fa07a --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P40.rpgle @@ -0,0 +1,23 @@ + D A20_AR2 S 2 0 DIM(6) + D A20_N60 S 6 0 + D A20_I S 2 0 + D £DBG_Str S 100 VARYING + + D* Z-SUB con interi ed elementi di array + C EVAL A20_N60=20 + C EVAL A20_I=6 + C EVAL A20_AR2(1)=0 + C EVAL A20_AR2(2)=0 + C EVAL A20_AR2(3)=0 + C EVAL A20_AR2(4)=0 + C EVAL A20_AR2(5)=0 + C EVAL A20_AR2(6)=20 + C Z-SUB A20_N60 A20_AR2(A20_I) + C EVAL £DBG_Str='Res(' + C +%CHAR(A20_AR2(1))+', ' + C +%CHAR(A20_AR2(2))+', ' + C +%CHAR(A20_AR2(3))+', ' + C +%CHAR(A20_AR2(4))+', ' + C +%CHAR(A20_AR2(5))+', ' + C +%CHAR(A20_AR2(6))+')' + C £DBG_Str DSPLY From 1da61e513a4bdbcecba615a2c8676041ed960e5d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 09:11:34 +0100 Subject: [PATCH 163/423] Fixed behaviour of ADD --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 5ea2e886a..d6203bb9c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1543,7 +1543,7 @@ internal fun CsADDContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) val left = leftExpr(conf) val right = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("ADD operation requires factor 2: ${this.text} - ${position.atLine()}") val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) - return AddStmt(left, DataRefExpr(ReferenceByName(result), position), dataDefinition, right, position) + return AddStmt(left, this.cspec_fixed_standard_parts().result.toAst(conf), dataDefinition, right, position) } internal fun CsZ_SUBContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): ZSubStmt { From f8826d46b8ea73dee67c5c0e2e385359d54c447e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 09:14:37 +0100 Subject: [PATCH 164/423] Fixed behaviour of SUB --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index d6203bb9c..272fdceb6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1560,7 +1560,7 @@ internal fun CsSUBContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) val left = leftExpr(conf) val right = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("SUB operation requires factor 2: ${this.text} - ${position.atLine()}") val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) - return SubStmt(left, DataRefExpr(ReferenceByName(result), position), dataDefinition, right, position) + return SubStmt(left, this.cspec_fixed_standard_parts().result.toAst(conf), dataDefinition, right, position) } internal fun ResultIndicatorContext?.asIntOrNull(): Int? = this?.text?.asIntOrNull() From ccace6796caa114500b26e17adf90b1348cd8360 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 09:38:43 +0100 Subject: [PATCH 165/423] Fixed behaviour of MULT --- .../rpgparser/interpreter/internal_interpreter.kt | 15 +++++++-------- .../com/smeup/rpgparser/parsing/ast/statements.kt | 7 +++++++ .../rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 919c77fb6..7326f9bcd 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -694,15 +694,14 @@ open class InternalInterpreter( override fun mult(statement: MultStmt): Value { // TODO When will pass my PR for more robustness replace Value.render with NumericValue.bigDecimal - require(statement.target is DataRefExpr) - val rightValue: BigDecimal = if (statement.factor1 != null) { - BigDecimal(eval(statement.factor1).render()) - } else { - BigDecimal(get(statement.target.variable.referred!!).render()) - } - val leftValue = BigDecimal(eval(statement.factor2).render()) + val rightValue = BigDecimal(eval(statement.left).render()) + val leftValue = BigDecimal(eval(statement.right).render()) val result = rightValue.multiply(leftValue) - val type = statement.target.variable.referred!!.type + val type = when { + statement.target is ArrayAccessExpr -> statement.target.type() + statement.target is DataRefExpr -> statement.target.variable.referred!!.type + else -> null + } require(type is NumberType) return if (statement.halfAdjust) { DecimalValue(result.setScale(type.decimalDigits, RoundingMode.HALF_UP)) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index ece9f62fe..17fe4cf93 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1083,6 +1083,13 @@ data class MultStmt( @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null ) : Statement(position), StatementThatCanDefineData { + @Derived + val left: Expression + get() = factor1 ?: target + + @Derived + val right: Expression + get() = factor2 override fun execute(interpreter: InterpreterCore) { interpreter.assign(target, interpreter.mult(this)) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 272fdceb6..923e2eabe 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1424,7 +1424,7 @@ internal fun CsMULTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() val extenders = this.operationExtender?.extender?.text?.uppercase(Locale.getDefault())?.toCharArray() ?: CharArray(0) val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) return MultStmt( - target = DataRefExpr(ReferenceByName(result), position), + target = this.cspec_fixed_standard_parts().result.toAst(conf), halfAdjust = 'H' in extenders, factor1 = factor1, factor2 = factor2, From a679f3a22214843ad138b429ccc8c0ccb9901b9a Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 09:42:26 +0100 Subject: [PATCH 166/423] Fixed behaviour of DIV --- .../rpgparser/interpreter/internal_interpreter.kt | 15 +++++++-------- .../com/smeup/rpgparser/parsing/ast/statements.kt | 7 +++++++ .../rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 7326f9bcd..77df6f963 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -712,15 +712,14 @@ open class InternalInterpreter( override fun div(statement: DivStmt): Value { // TODO When will pass my PR for more robustness replace Value.render with NumericValue.bigDecimal - require(statement.target is DataRefExpr) - val dividend: BigDecimal = if (statement.factor1 != null) { - BigDecimal(eval(statement.factor1).render()) - } else { - BigDecimal(get(statement.target.variable.referred!!).render()) - } - val divisor = BigDecimal(eval(statement.factor2).render()) + val dividend = BigDecimal(eval(statement.dividend).render()) + val divisor = BigDecimal(eval(statement.divisor).render()) val quotient = dividend.divide(divisor, MathContext.DECIMAL128) - val type = statement.target.variable.referred!!.type + val type = when { + statement.target is ArrayAccessExpr -> statement.target.type() + statement.target is DataRefExpr -> statement.target.variable.referred!!.type + else -> null + } require(type is NumberType) // calculation of rest // NB. rest based on type of quotient diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 17fe4cf93..57bb0233e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1108,6 +1108,13 @@ data class DivStmt( @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null ) : Statement(position), StatementThatCanDefineData { + @Derived + val dividend: Expression + get() = factor1 ?: target + + @Derived + val divisor: Expression + get() = factor2 override fun execute(interpreter: InterpreterCore) { interpreter.assign(target, interpreter.div(this)) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 923e2eabe..d49ee6261 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1445,7 +1445,7 @@ internal fun CsDIVContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) DataRefExpr(ReferenceByName(it), position) } return DivStmt( - target = DataRefExpr(ReferenceByName(result), position), + target = this.cspec_fixed_standard_parts().result.toAst(conf), halfAdjust = 'H' in extenders, factor1 = factor1, factor2 = factor2, From 18415e29218145243b4b84863545b6ebc19ef701 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 09:44:48 +0100 Subject: [PATCH 167/423] Fixed behaviour of Z-SUB --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index d49ee6261..b07b617dd 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1551,7 +1551,7 @@ internal fun CsZ_SUBContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("Z-SUB operation requires factor 2: ${this.text} - ${position.atLine()}") val name = this.cspec_fixed_standard_parts().result.text val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(name, position, conf) - return ZSubStmt(DataRefExpr(ReferenceByName(name), position), dataDefinition, expression, position) + return ZSubStmt(this.cspec_fixed_standard_parts().result.toAst(conf), dataDefinition, expression, position) } internal fun CsSUBContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): SubStmt { From b1da8ba59d5d68e56efcf474710fff9a237a479d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 09:47:31 +0100 Subject: [PATCH 168/423] Replaced `UnsupportedOperationException` with `todo`. --- .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index b07b617dd..758fa8cf6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1419,7 +1419,7 @@ internal fun CsMULTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() val position = toPosition(conf.considerPosition) val result = this.cspec_fixed_standard_parts().result.text val factor1 = leftExpr(conf) - val factor2 = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("SUB operation requires factor 2: ${this.text} - ${position.atLine()}") + val factor2 = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: this.todo(message = "SUB operation requires factor 2: ${this.text} - ${position.atLine()}", conf) this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) val extenders = this.operationExtender?.extender?.text?.uppercase(Locale.getDefault())?.toCharArray() ?: CharArray(0) val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) @@ -1437,7 +1437,7 @@ internal fun CsDIVContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) val position = toPosition(conf.considerPosition) val result = this.cspec_fixed_standard_parts().result.text val factor1 = leftExpr(conf) - val factor2 = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("SUB operation requires factor 2: ${this.text} - ${position.atLine()}") + val factor2 = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: this.todo(message = "SUB operation requires factor 2: ${this.text} - ${position.atLine()}", conf) this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) val extenders = this.operationExtender?.extender?.text?.uppercase(Locale.getDefault())?.toCharArray() ?: CharArray(0) val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) @@ -1541,14 +1541,14 @@ internal fun CsADDContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) val position = toPosition(conf.considerPosition) val result = this.cspec_fixed_standard_parts().result.text val left = leftExpr(conf) - val right = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("ADD operation requires factor 2: ${this.text} - ${position.atLine()}") + val right = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: this.todo(message = "ADD operation requires factor 2: ${this.text} - ${position.atLine()}", conf) val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) return AddStmt(left, this.cspec_fixed_standard_parts().result.toAst(conf), dataDefinition, right, position) } internal fun CsZ_SUBContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): ZSubStmt { val position = toPosition(conf.considerPosition) - val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("Z-SUB operation requires factor 2: ${this.text} - ${position.atLine()}") + val expression = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: this.todo(message = "Z-SUB operation requires factor 2: ${this.text} - ${position.atLine()}", conf) val name = this.cspec_fixed_standard_parts().result.text val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(name, position, conf) return ZSubStmt(this.cspec_fixed_standard_parts().result.toAst(conf), dataDefinition, expression, position) @@ -1558,7 +1558,7 @@ internal fun CsSUBContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) val position = toPosition(conf.considerPosition) val result = this.cspec_fixed_standard_parts().result.text val left = leftExpr(conf) - val right = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: throw UnsupportedOperationException("SUB operation requires factor 2: ${this.text} - ${position.atLine()}") + val right = this.cspec_fixed_standard_parts().factor2Expression(conf) ?: this.todo(message = "SUB operation requires factor 2: ${this.text} - ${position.atLine()}", conf) val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) return SubStmt(left, this.cspec_fixed_standard_parts().result.toAst(conf), dataDefinition, right, position) } From fd802f9338a46ab1e101dab1f33b45827050f9b6 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 10:32:58 +0100 Subject: [PATCH 169/423] Implemented case of test for pass 41 --- .../evaluation/SmeupInterpreterTest.kt | 6 +++ .../test/resources/smeup/T10_A20_P41.rpgle | 37 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P41.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 231886676..b60017adf 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -411,4 +411,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Res(0, 0, 0, 0, 0, -20)") assertEquals(expected, "smeup/T10_A20_P40".outputOf()) } + + @Test + fun executeT10_A20_P41() { + val expected = listOf("Res(20, 22, 12, 26, 28, 30) Div(2, 2, 2, 2, 2, 2)") + assertEquals(expected, "smeup/T10_A20_P41".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P41.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P41.rpgle new file mode 100644 index 000000000..e08da4170 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P41.rpgle @@ -0,0 +1,37 @@ + D A20_AR2 S 2 0 DIM(6) + D A20_AR3 S 2 0 DIM(6) + D A20_N60 S 6 0 + D A20_I S 2 0 + D £DBG_Str S 100 VARYING + + D* DIV con elementi di array + C EVAL A20_N60=20 + C EVAL A20_I=3 + C EVAL A20_AR2(1)=20 + C EVAL A20_AR2(2)=22 + C EVAL A20_AR2(3)=24 + C EVAL A20_AR2(4)=26 + C EVAL A20_AR2(5)=28 + C EVAL A20_AR2(6)=30 + C EVAL A20_AR3(1)=2 + C EVAL A20_AR3(2)=2 + C EVAL A20_AR3(3)=2 + C EVAL A20_AR3(4)=2 + C EVAL A20_AR3(5)=2 + C EVAL A20_AR3(6)=2 + C A20_AR2(A20_I)DIV A20_AR3(A20_I)A20_AR2(A20_I) + C EVAL £DBG_Str='Res(' + C +%CHAR(A20_AR2(1))+', ' + C +%CHAR(A20_AR2(2))+', ' + C +%CHAR(A20_AR2(3))+', ' + C +%CHAR(A20_AR2(4))+', ' + C +%CHAR(A20_AR2(5))+', ' + C +%CHAR(A20_AR2(6))+')' + C +' Div(' + C +%CHAR(A20_AR3(1))+', ' + C +%CHAR(A20_AR3(2))+', ' + C +%CHAR(A20_AR3(3))+', ' + C +%CHAR(A20_AR3(4))+', ' + C +%CHAR(A20_AR3(5))+', ' + C +%CHAR(A20_AR3(6))+')' + C £DBG_Str DSPLY From c9757740f35b57f6f0377d2784bdabc29293044d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 27 Feb 2024 10:52:05 +0100 Subject: [PATCH 170/423] Added another cases of test dor `EVALVARSNUMS` --- .../com/smeup/rpgparser/evaluation/InterpreterTest.kt | 2 ++ .../src/test/resources/EVALVARSNUMS.rpgle | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 1aa2adc8e..ff84ba119 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2284,6 +2284,8 @@ Test 6 "246", "246", "246", + "246", + "246", "246" ) assertEquals(expected, "EVALVARSNUMS".outputOf()) diff --git a/rpgJavaInterpreter-core/src/test/resources/EVALVARSNUMS.rpgle b/rpgJavaInterpreter-core/src/test/resources/EVALVARSNUMS.rpgle index 1f50d37c4..704facaaa 100644 --- a/rpgJavaInterpreter-core/src/test/resources/EVALVARSNUMS.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/EVALVARSNUMS.rpgle @@ -1,7 +1,9 @@ D VAL S 3 0 + D VAL$ S 3 0 D RES S 3 0 C EVAL VAL=10 + C EVAL VAL$=10 C EVAL RES = 24 * VAL + 6 C RES DSPLY @@ -19,5 +21,11 @@ C EVAL RES=24*VAL+6 C RES DSPLY - C EVAL RES=24*VAL+6 + C EVAL RES=24*VAL +6 + C RES DSPLY + + C EVAL RES=24 * VAL$ + 6 + C RES DSPLY + + C EVAL RES=24*VAL$+6 C RES DSPLY \ No newline at end of file From 795b575c4f44088e44e5bc2c2b30d97f56611bb1 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:49:53 +0000 Subject: [PATCH 171/423] add user case "DEFINE3" --- .../rpgparser/evaluation/InterpreterTest.kt | 7 +++ .../src/test/resources/DEFINE03.rpgle | 51 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/DEFINE03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 87eeed06c..d73891b62 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2275,4 +2275,11 @@ Test 6 val expected = listOf("") assertEquals(expected, "NEGATIONERR".outputOf()) } + + @Test + fun executeDEFINE03() { + val expected = listOf("1,2,3,4") + assertCanBeParsed(exampleName = "DEFINE03", printTree = true) + assertEquals(expected, "DEFINE03".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/DEFINE03.rpgle b/rpgJavaInterpreter-core/src/test/resources/DEFINE03.rpgle new file mode 100644 index 000000000..c648b10d4 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/DEFINE03.rpgle @@ -0,0 +1,51 @@ + D £DBG_Str S 10 + D $VARIF S LIKE(£VARIF) + D $VARDOW S LIKE(£VARDOW) + D $VARSL S LIKE(£VARSL) + D $VARFOR S LIKE(£VARFOR) + D IND S 1 0 + * + C EXSR SEZ_A50 + C* EXSR SEZ_A49 + C SETON LR + * + C* SEZ_A49 BEGSR + C* MOVEL(P) '1' $VARMY 10 + C* ENDSR + * + C SEZ_A50 BEGSR + * + C MOVEL(P) '1' $VARIF + C MOVEL(P) '2' $VARDOW + C MOVEL(P) '3' $VARSL + C MOVEL(P) '4' $VARFOR + * test IF + C IF '1' = '1' + C MOVEL(P) '1' £VARIF 10 + C ENDIF + * test DOW + C EVAL IND=1 + C IND DOWEQ 1 + C MOVEL(P) '2' £VARDOW 10 + C EVAL IND=2 + C ENDDO + * test SELECT + C SELECT + C WHEN IND = 2 + C MOVEL(P) '3' £VARSL 10 + C OTHER + C MOVEL(P) ' ' £VARSL 10 + C ENDSL + * test FOR + C FOR IND = 0 TO 1 + C MOVEL(P) '4' £VARFOR 10 + C ENDFOR + ****** + * + C EVAL £DBG_Str=%trim($VARIF)+','+ + C %trim($VARDOW)+','+ + C %trim($VARSL)+','+ + C %trim($VARFOR) + C £DBG_Str DSPLY + C ENDSR + * From c1240eda6e489a39c5aec1521a48c92834364e26 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Tue, 27 Feb 2024 16:53:16 +0100 Subject: [PATCH 172/423] Created example --- .../evaluation/SmeupInterpreterTest.kt | 6 +++++ .../src/test/resources/DIR_DEFINE.rpgle | 23 +++++++++++++++++++ .../test/resources/smeup/T70_A10_P01.rpgle | 22 ++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/DIR_DEFINE.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index d4997eb1a..230328836 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -394,4 +394,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("£C5") assertEquals(expected, "smeup/T02_A50_P05".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT79_A10_P01() { + val expected = listOf("OUT") + assertEquals(expected, "smeup/T70_A10_P01".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/DIR_DEFINE.rpgle b/rpgJavaInterpreter-core/src/test/resources/DIR_DEFINE.rpgle new file mode 100644 index 000000000..a19d6976f --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/DIR_DEFINE.rpgle @@ -0,0 +1,23 @@ + * + * Definisci variabili e registra definizione come eseguita + * + /IF NOT DEFINED(DMSE_INCLUDED) + /DEFINE DMSE_INCLUDED + D £D1 S 17 DIM(100) Cod.Msg + Msgf + D £D2 S 45 DIM(100) Variabili ass. + D £D3 S 80 DIM(100) Txt schiera + D £D4 S 1 DIM(45) Segmenta in 45 + /ENDIF + * + * Definizioni da saltare perchè già presenti + * + /IF NOT DEFINED(DMSE_INCLUDED) + D £D1 S 17 DIM(100) Cod.Msg + Msgf + D £D2 S 45 DIM(100) Variabili ass. + D £D3 S 80 DIM(100) Txt schiera + D £D4 S 1 DIM(45) Segmenta in 45 + /ENDIF + * + * Pulisci define + * + /UNDEFINE(DMSE_INCLUDED) \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle new file mode 100644 index 000000000..1376e31c3 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle @@ -0,0 +1,22 @@ + D £DBG_Str S 100 + * + C EVAL £DBG_Str='OUT' + * + * Definisci variabili e registra definizione come eseguita + * + /IF NOT DEFINED(DMSE_INCLUDED) + /DEFINE DMSE_INCLUDED + C £DBG_Str DSPLY + /ENDIF + * + * Definizioni da saltare perchè già presenti + * + /IF NOT DEFINED(DMSE_INCLUDED) + C £DBG_Str DSPLY + /ENDIF + * + * Pulisci define + * + /UNDEFINE DMSE_INCLUDED + * + C SETON LR \ No newline at end of file From c8570a7de5ddc857f8c84d36402bcc8835fb6132 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 27 Feb 2024 17:12:21 +0000 Subject: [PATCH 173/423] Fix variable declaration inside sub-procedures --- .../interpreter/compile_time_interpreter.kt | 44 ++++++++++++++++++- .../rpgparser/evaluation/InterpreterTest.kt | 1 - .../src/test/resources/DEFINE03.rpgle | 31 ++++++++----- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 0a37dd384..8cc1235f7 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -141,7 +141,27 @@ open class BaseCompileTimeInterpreter( val field = it.fields.find { it.name.equals(declName, ignoreCase = true) } if (field != null) return (field.elementSize() /*/ field.declaredArrayInLine!!*/) } - return findSize(rContext.statement(), declName, conf, false)!! + + return try { + // look for the variable in the main + findSize(rContext.statement(), declName, conf, false)!! + } catch (e: NotFoundAtCompileTimeException) { + // if it doesn't find the variable in the main, look for it in the sub-procedures + rContext.subroutine().findSize(rContext, declName, conf)!! + } + } + + private fun List.findSize(rContext: RpgParser.RContext, declName: String, conf: ToAstConfiguration): Int? { + if (rContext.subroutine() != null && rContext.subroutine().isNotEmpty()) { + rContext.subroutine().forEach { pr -> + try { + return findSize(pr.statement(), declName, conf, false)!! + } catch (e: NotFoundAtCompileTimeException) { + // do nothing + } + } + } + throw NotFoundAtCompileTimeException(declName) } private fun findSize(statements: List, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Int? { @@ -220,7 +240,27 @@ open class BaseCompileTimeInterpreter( return field.type } } - return findType(rContext.statement(), declName, conf, false)!! + + return try { + // look for the variable in the main + findType(rContext.statement(), declName, conf, false)!! + } catch (e: NotFoundAtCompileTimeException) { + // if it doesn't find the variable in the main, look for it in the sub-procedures + rContext.subroutine().findType(rContext, declName, conf)!! + } + } + + private fun List.findType(rContext: RpgParser.RContext, declName: String, conf: ToAstConfiguration): Type? { + if (rContext.subroutine() != null && rContext.subroutine().isNotEmpty()) { + rContext.subroutine().forEach { pr -> + try { + return findType(pr.statement(), declName, conf, false)!! + } catch (e: NotFoundAtCompileTimeException) { + // do nothing + } + } + } + throw NotFoundAtCompileTimeException(declName) } private fun findType(statements: List, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Type? { diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index d73891b62..0fa7e01d1 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2279,7 +2279,6 @@ Test 6 @Test fun executeDEFINE03() { val expected = listOf("1,2,3,4") - assertCanBeParsed(exampleName = "DEFINE03", printTree = true) assertEquals(expected, "DEFINE03".outputOf()) } } diff --git a/rpgJavaInterpreter-core/src/test/resources/DEFINE03.rpgle b/rpgJavaInterpreter-core/src/test/resources/DEFINE03.rpgle index c648b10d4..f17851ebe 100644 --- a/rpgJavaInterpreter-core/src/test/resources/DEFINE03.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/DEFINE03.rpgle @@ -5,20 +5,20 @@ D $VARFOR S LIKE(£VARFOR) D IND S 1 0 * - C EXSR SEZ_A50 - C* EXSR SEZ_A49 + C EXSR SUB_001 + C EXSR SUB_002 C SETON LR - * - C* SEZ_A49 BEGSR - C* MOVEL(P) '1' $VARMY 10 - C* ENDSR - * - C SEZ_A50 BEGSR - * + **************************** + C SUB_000 BEGSR + C MOVEL(P) ' ' $VARIF + C MOVEL(P) ' ' $VARDOW + C MOVEL(P) ' ' $VARSL + C MOVEL(P) ' ' $VARFOR + C ENDSR + **************************** + C SUB_001 BEGSR C MOVEL(P) '1' $VARIF C MOVEL(P) '2' $VARDOW - C MOVEL(P) '3' $VARSL - C MOVEL(P) '4' $VARFOR * test IF C IF '1' = '1' C MOVEL(P) '1' £VARIF 10 @@ -29,12 +29,19 @@ C MOVEL(P) '2' £VARDOW 10 C EVAL IND=2 C ENDDO + * + C ENDSR + **************************** + C SUB_002 BEGSR + * + C MOVEL(P) '3' $VARSL + C MOVEL(P) '4' $VARFOR * test SELECT C SELECT C WHEN IND = 2 C MOVEL(P) '3' £VARSL 10 C OTHER - C MOVEL(P) ' ' £VARSL 10 + C MOVEL(P) ' ' £VARSL C ENDSL * test FOR C FOR IND = 0 TO 1 From 4f8e1cd9a53e7de8153602c6e3ee0f327f98839e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 28 Feb 2024 08:59:10 +0100 Subject: [PATCH 174/423] Implemented and tested `T60_A10_P01_02` --- .../evaluation/SmeupInterpreterTest.kt | 6 ++++ .../test/resources/smeup/T60_A10_P01-02.rpgle | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01-02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index d2780010c..f3a7f825b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -382,4 +382,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Res(-A)=-10 Res( -A)= -10") assertEquals(expected, "smeup/T02_A60_P03".outputOf()) } + + @Test + fun executeT60_A10_P01_02() { + val expected = listOf() + assertEquals(expected, "smeup/T60_A10_P01-02".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01-02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01-02.rpgle new file mode 100644 index 000000000..5ee8cef1c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01-02.rpgle @@ -0,0 +1,28 @@ + D £DBG_Str S 52 + D $OP S 1N INZ(*ON) + + D* Passo mock di EXFMT + C EVAL £DBG_Str='' + C IF $OP=*OFF + C OPEN MLNGT60V + C ENDIF + C IF $OP=*OFF + C EXFMT FMT01 + C EVAL £DBG_Str='Eseguito EXFMT di FMT01' + C ENDIF + C IF $OP=*OFF + C CLOSE MLNGT60V + C ENDIF + + D* Passo mock di READC + C EVAL £DBG_Str='' + C IF $OP=*OFF + C OPEN MLNGT60V + C ENDIF + C IF $OP=*OFF + C READC SFL01 + C EVAL £DBG_Str='Eseguito READC di subfile SFLR' + C ENDIF + C IF $OP=*OFF + C CLOSE MLNGT60V + C ENDIF \ No newline at end of file From 031569e23b04146cbeb661e141792b0b2d39683b Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 28 Feb 2024 12:58:16 +0000 Subject: [PATCH 175/423] Get parameter type from inStatementsDataDefinitions in case it is not found in DataDefinition --- .../kotlin/com/smeup/rpgparser/interpreter/program.kt | 11 ++++++++--- .../com/smeup/rpgparser/parsing/ast/cu_components.kt | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt index 36ba8e840..11fb503fb 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt @@ -57,9 +57,14 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " df.name == it.param.name }!!.type + } + if (type == null) + throw IllegalArgumentException("Cannot resolve PARAM: ${it.param.name} in *ENTRY PLIST of the program: $name") ProgramParam(it.param.name, type) } ?: emptyList() diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt index b2b025fce..ae4508f0b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt @@ -73,7 +73,7 @@ data class CompilationUnit( get() = main.stmts.plist() ?: subroutines.mapNotNull { it.stmts.plist() }.firstOrNull() - private val inStatementsDataDefinitions = mutableListOf() + internal val inStatementsDataDefinitions = mutableListOf() fun addInStatementDataDefinitions(dataDefinitions: List) { inStatementsDataDefinitions.addAll(dataDefinitions) From ea2912702c8bfb956f29aa059c19af9f374b5a02 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Wed, 28 Feb 2024 13:18:26 +0000 Subject: [PATCH 176/423] change search method inside statements --- .../interpreter/compile_time_interpreter.kt | 42 +------------------ 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 8cc1235f7..2579d6c3d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -142,26 +142,7 @@ open class BaseCompileTimeInterpreter( if (field != null) return (field.elementSize() /*/ field.declaredArrayInLine!!*/) } - return try { - // look for the variable in the main - findSize(rContext.statement(), declName, conf, false)!! - } catch (e: NotFoundAtCompileTimeException) { - // if it doesn't find the variable in the main, look for it in the sub-procedures - rContext.subroutine().findSize(rContext, declName, conf)!! - } - } - - private fun List.findSize(rContext: RpgParser.RContext, declName: String, conf: ToAstConfiguration): Int? { - if (rContext.subroutine() != null && rContext.subroutine().isNotEmpty()) { - rContext.subroutine().forEach { pr -> - try { - return findSize(pr.statement(), declName, conf, false)!! - } catch (e: NotFoundAtCompileTimeException) { - // do nothing - } - } - } - throw NotFoundAtCompileTimeException(declName) + return findSize(rContext.statement() + rContext.subroutine().flatMap { it.statement() }, declName, conf, false)!! } private fun findSize(statements: List, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Int? { @@ -241,26 +222,7 @@ open class BaseCompileTimeInterpreter( } } - return try { - // look for the variable in the main - findType(rContext.statement(), declName, conf, false)!! - } catch (e: NotFoundAtCompileTimeException) { - // if it doesn't find the variable in the main, look for it in the sub-procedures - rContext.subroutine().findType(rContext, declName, conf)!! - } - } - - private fun List.findType(rContext: RpgParser.RContext, declName: String, conf: ToAstConfiguration): Type? { - if (rContext.subroutine() != null && rContext.subroutine().isNotEmpty()) { - rContext.subroutine().forEach { pr -> - try { - return findType(pr.statement(), declName, conf, false)!! - } catch (e: NotFoundAtCompileTimeException) { - // do nothing - } - } - } - throw NotFoundAtCompileTimeException(declName) + return findType(rContext.statement() + rContext.subroutine().flatMap { it.statement() }, declName, conf, false)!! } private fun findType(statements: List, declName: String, conf: ToAstConfiguration, innerBlock: Boolean = true): Type? { From 08c1e2bda180b21e575d59222d12268faf36be33 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 28 Feb 2024 15:01:22 +0100 Subject: [PATCH 177/423] Implemented `T52_A07_P01` --- .../evaluation/SmeupInterpreterTest.kt | 6 +++ .../test/resources/smeup/T52_A07_P01.rpgle | 26 ++++++++++ .../resources/smeup/metadata/MULANGTL.json | 49 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P01.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MULANGTL.json diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f3a7f825b..c626080c4 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -383,6 +383,12 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T02_A60_P03".outputOf()) } + @Test + fun executeT52_A07_P01() { + val expected = listOf("") + assertEquals(expected, "smeup/T52_A07_P01".outputOf(configuration = smeupConfig)) + } + @Test fun executeT60_A10_P01_02() { val expected = listOf() diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P01.rpgle new file mode 100644 index 000000000..45699b758 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P01.rpgle @@ -0,0 +1,26 @@ + FMULANGTL UF A E K DISK + + D KEY_A10C_SYST S 10 INZ('IBN') + D KEY_A10C_TIPO S 10 INZ('3') + D KEY_A10C_PROG S 10 INZ('MULANGXX') + + D A10C_PSEZ S 10 + D A10C_PPAS S 10 + D SEZ_52_INDICE S 4 0 + D £DBG_Str S 100 VARYING + + D* Scrittura nuove righe. + C FOR SEZ_52_INDICE=0 TO 10 + C EVAL A10C_PSEZ='A'+ + C %SUBST(%EDITC(SEZ_52_INDICE:'X'):1:2) + C EVAL A10C_PPAS='P'+ + C %SUBST(%EDITC(SEZ_52_INDICE:'X'):3:2) + C EVAL MLSYST=%TRIM(KEY_A10C_SYST) + C EVAL MLTIPO=%TRIM(KEY_A10C_TIPO) + C EVAL MLPROG=%TRIM(KEY_A10C_PROG) + C EVAL MLPSEZ=%TRIM(A10C_PSEZ) + C EVAL MLPPAS=%TRIM(A10C_PPAS) + C WRITE MULANGR + C ENDFOR + + C EVAL £DBG_Str=%TRIM(£DBG_Str)+':ENDWRT:' \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MULANGTL.json b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MULANGTL.json new file mode 100644 index 000000000..8092e1b7c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MULANGTL.json @@ -0,0 +1,49 @@ +{"name": "MULANGTL", + "tableName": "MULANGTF", + "recordFormat": "MULANGR", + "fields": [ + { "fieldName": "MLSYST", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":20, "varying":false}} + , { "fieldName": "MLLIBR", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLFILE", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLTIPO", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLPROG", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLPSEZ", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLPPAS", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLPDES", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":256, "varying":false}} + , { "fieldName": "MLSQIN", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLSQFI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLAAAT", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1024, "varying":false}} + , { "fieldName": "MLAAVA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1024, "varying":false}} + , { "fieldName": "MLNNAT", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":21, "decimalDigits":9, "rpgType":"P"}} + , { "fieldName": "MLNNVA", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":21, "decimalDigits":9, "rpgType":"P"}} + , { "fieldName": "MLINDI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":99, "varying":false}} + , { "fieldName": "MLTEES", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "MLUSES", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLDTES", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":8, "decimalDigits":0, "rpgType":"S"}} + , { "fieldName": "MLORES", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":6, "decimalDigits":0, "rpgType":"S"}} + , { "fieldName": "MLASLA", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "MLASNR", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":6, "decimalDigits":0, "rpgType":"P"}} + , { "fieldName": "MLLIBE", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":30000, "varying":true}} + ], "accessFields": [ "MLSYST", "MLTIPO", "MLPROG", "MLPSEZ", "MLPPAS"]} From 96623a596a8c3ed757819ee7dfd03c4aa03c12a3 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 28 Feb 2024 15:06:11 +0100 Subject: [PATCH 178/423] Used scoped function where is needed. --- .../com/smeup/rpgparser/parsing/ast/statements.kt | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index b82cc9e96..7b2cf7661 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1647,17 +1647,15 @@ data class ScanStmt( } while (index >= 0) if (occurrences.isEmpty()) { interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.FALSE, BooleanValue.FALSE) - if (target != null) { - interpreter.assign(target, IntValue(0)) - } + target?.let { interpreter.assign(it, IntValue(0)) } } else { interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.FALSE, BooleanValue.TRUE) - if (target != null) { - if (target.type().isArray()) { - val fullOccurrences = occurrences.resizeTo(target.type().numberOfElements(), IntValue.ZERO).toMutableList() - interpreter.assign(target, ConcreteArrayValue(fullOccurrences, target.type().asArray().element)) + target?.let { + if (it.type().isArray()) { + val fullOccurrences = occurrences.resizeTo(it.type().numberOfElements(), IntValue.ZERO).toMutableList() + interpreter.assign(it, ConcreteArrayValue(fullOccurrences, it.type().asArray().element)) } else { - interpreter.assign(target, occurrences[0]) + interpreter.assign(it, occurrences[0]) } } } From 206fa2cb5c730934c2d39665e43182280aedb9db Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 28 Feb 2024 15:37:15 +0100 Subject: [PATCH 179/423] Replaced `T52_A07_P01` test with the right one. --- .../evaluation/SmeupInterpreterTest.kt | 2 +- .../test/resources/smeup/T52_A07_P01.rpgle | 28 ++----------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index c626080c4..012d534bc 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -385,7 +385,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT52_A07_P01() { - val expected = listOf("") + val expected = listOf() assertEquals(expected, "smeup/T52_A07_P01".outputOf(configuration = smeupConfig)) } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P01.rpgle index 45699b758..b82d49dd2 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P01.rpgle @@ -1,26 +1,2 @@ - FMULANGTL UF A E K DISK - - D KEY_A10C_SYST S 10 INZ('IBN') - D KEY_A10C_TIPO S 10 INZ('3') - D KEY_A10C_PROG S 10 INZ('MULANGXX') - - D A10C_PSEZ S 10 - D A10C_PPAS S 10 - D SEZ_52_INDICE S 4 0 - D £DBG_Str S 100 VARYING - - D* Scrittura nuove righe. - C FOR SEZ_52_INDICE=0 TO 10 - C EVAL A10C_PSEZ='A'+ - C %SUBST(%EDITC(SEZ_52_INDICE:'X'):1:2) - C EVAL A10C_PPAS='P'+ - C %SUBST(%EDITC(SEZ_52_INDICE:'X'):3:2) - C EVAL MLSYST=%TRIM(KEY_A10C_SYST) - C EVAL MLTIPO=%TRIM(KEY_A10C_TIPO) - C EVAL MLPROG=%TRIM(KEY_A10C_PROG) - C EVAL MLPSEZ=%TRIM(A10C_PSEZ) - C EVAL MLPPAS=%TRIM(A10C_PPAS) - C WRITE MULANGR - C ENDFOR - - C EVAL £DBG_Str=%TRIM(£DBG_Str)+':ENDWRT:' \ No newline at end of file + D* Test mock comando UNLOCK + C UNLOCK MULANGTL From d9964365268a095a55a076a568f1441407a91d58 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 28 Feb 2024 16:01:02 +0100 Subject: [PATCH 180/423] Implemented case of test --- .../evaluation/SmeupInterpreterTest.kt | 9 +++++++ .../test/resources/smeup/T03_A30_P01-02.rpgle | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T03_A30_P01-02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index eb0b5f23a..98acf7dfb 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -406,4 +406,13 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Res(A*B+C)=246; Res(A * B + C)=246") assertEquals(expected, "smeup/T02_A60_P02".outputOf()) } + + @Test + fun executeT03_A30_P01_02() { + val expected = listOf( + "*IN15-1 OK *IN15-2 OK *IN15-3 OK *IN16-1 OK *IN16-2 OK *IN16-3 OK *IN25-1 OK *IN25-2 OK *IN25-3 OK *IN26-1 OK *IN26-2 OK *IN26-3 OK IndON OK IndON OK IndOF OK IndOF OK", + "*IN15-1 OK *IN15-2 OK *IN15-3 OK *IN16-1 OK *IN16-2 OK *IN16-3 OK *IN25-1 OK *IN25-2 OK *IN25-3 OK *IN26-1 OK *IN26-2 OK *IN26-3 OK IndON OK IndON OK IndOF OK IndOF OK" + ) + assertEquals(expected, "smeup/T03_A30_P01-02".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A30_P01-02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A30_P01-02.rpgle new file mode 100644 index 000000000..dc8eaad00 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A30_P01-02.rpgle @@ -0,0 +1,27 @@ + D £DBG_Str S 50 VARYING + + D* MOVEL ON/OFF indicatore con valore da variabile + C EVAL £DBG_Str=' ' + C SETON 33 + C SETOFF 34 + * + C Z-ADD 33 $2 5 0 + C MOVEL *OFF *IN($2) + C Z-ADD 34 $2 + C MOVEL *ON *IN($2) + C EVAL £DBG_Str='*IN33='+%CHAR(*IN(33))+','+ + C '*IN34='+%CHAR(*IN(34)) + C £DBG_Str DSPLY + + D* MOVE ON/OFF indicatore con valore da variabile + C EVAL £DBG_Str=' ' + C SETON 33 + C SETOFF 34 + * + C Z-ADD 33 $2 5 0 + C MOVE *OFF *IN($2) + C Z-ADD 34 $2 + C MOVE *ON *IN($2) + C EVAL £DBG_Str='*IN33='+%CHAR(*IN(33))+','+ + C '*IN34='+%CHAR(*IN(34)) + C £DBG_Str DSPLY From b8df67ce4a69b2c78765785e3f7cdd0fd1a45ac6 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 28 Feb 2024 16:18:49 +0100 Subject: [PATCH 181/423] Fixed result of test --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 5 +++-- .../src/test/resources/smeup/T03_A30_P01-02.rpgle | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 98acf7dfb..24b4ca86b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -2,6 +2,7 @@ package com.smeup.rpgparser.evaluation import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.AbstractTest +import com.smeup.rpgparser.assertCanBeParsed import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig @@ -410,8 +411,8 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT03_A30_P01_02() { val expected = listOf( - "*IN15-1 OK *IN15-2 OK *IN15-3 OK *IN16-1 OK *IN16-2 OK *IN16-3 OK *IN25-1 OK *IN25-2 OK *IN25-3 OK *IN26-1 OK *IN26-2 OK *IN26-3 OK IndON OK IndON OK IndOF OK IndOF OK", - "*IN15-1 OK *IN15-2 OK *IN15-3 OK *IN16-1 OK *IN16-2 OK *IN16-3 OK *IN25-1 OK *IN25-2 OK *IN25-3 OK *IN26-1 OK *IN26-2 OK *IN26-3 OK IndON OK IndON OK IndOF OK IndOF OK" + "*IN33=0,*IN34=1", + "*IN33=0,*IN34=1" ) assertEquals(expected, "smeup/T03_A30_P01-02".outputOf()) } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A30_P01-02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A30_P01-02.rpgle index dc8eaad00..0c32645e3 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A30_P01-02.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A30_P01-02.rpgle @@ -4,7 +4,7 @@ C EVAL £DBG_Str=' ' C SETON 33 C SETOFF 34 - * + C Z-ADD 33 $2 5 0 C MOVEL *OFF *IN($2) C Z-ADD 34 $2 @@ -17,7 +17,7 @@ C EVAL £DBG_Str=' ' C SETON 33 C SETOFF 34 - * + C Z-ADD 33 $2 5 0 C MOVE *OFF *IN($2) C Z-ADD 34 $2 From 4e63283b3f8dcacc7bc286d53863e7faba2f8c2c Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Thu, 29 Feb 2024 08:35:21 +0000 Subject: [PATCH 182/423] rollback previous changes, replaced getDataDefinition with getAnyDataDefinition I changed getDataDefinition with getAnyDataDefinition following the suggestion of Marco Lanari. Note: Apparently, doing so, there is no need to catch any exception, because if the variable has not been declared, an exception would be raised during the AST creation. --- .../kotlin/com/smeup/rpgparser/interpreter/program.kt | 9 +-------- .../com/smeup/rpgparser/parsing/ast/cu_components.kt | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt index 11fb503fb..e9fdc3f11 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt @@ -57,14 +57,7 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " df.name == it.param.name }!!.type - } - if (type == null) - throw IllegalArgumentException("Cannot resolve PARAM: ${it.param.name} in *ENTRY PLIST of the program: $name") + val type = cu.getAnyDataDefinition(it.param.name).type ProgramParam(it.param.name, type) } ?: emptyList() diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt index ae4508f0b..b2b025fce 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt @@ -73,7 +73,7 @@ data class CompilationUnit( get() = main.stmts.plist() ?: subroutines.mapNotNull { it.stmts.plist() }.firstOrNull() - internal val inStatementsDataDefinitions = mutableListOf() + private val inStatementsDataDefinitions = mutableListOf() fun addInStatementDataDefinitions(dataDefinitions: List) { inStatementsDataDefinitions.addAll(dataDefinitions) From 130b63eda443212bd6ed3f5ab4ffd66d23b34c6d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 29 Feb 2024 11:09:58 +0100 Subject: [PATCH 183/423] Fixed the behaviour of `MOVE` and `MOVEL`. --- .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 7 +++++-- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 1e46e4896..b5e00b894 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -939,8 +939,11 @@ private fun annidatedReferenceExpression( return GlobalIndicatorExpr(position) } if (text.uppercase(Locale.getDefault()).startsWith("*IN(") && text.endsWith(")")) { - val index = text.uppercase(Locale.getDefault()).removePrefix("*IN(").removeSuffix(")").toInt() - return IndicatorExpr(index, position) + val index = text.uppercase(Locale.getDefault()).removePrefix("*IN(").removeSuffix(")") + return when { + index.isInt() -> IndicatorExpr(index.toInt(), position) + else -> IndicatorExpr(DataRefExpr(ReferenceByName(index), position), position) + } } if (text.uppercase(Locale.getDefault()).startsWith("*IN")) { val index = text.uppercase(Locale.getDefault()).removePrefix("*IN").toInt() diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 24b4ca86b..2d7e9040b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -2,7 +2,6 @@ package com.smeup.rpgparser.evaluation import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.AbstractTest -import com.smeup.rpgparser.assertCanBeParsed import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig From e1831a0090d2fc5dfcdf6d6e39eed8d2b03c55c4 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:09:03 +0000 Subject: [PATCH 184/423] add T12_A08_P01, change CAS structure in rpgparser.g4 --- .../src/main/antlr/RpgParser.g4 | 29 ++++++--- .../smeup/rpgparser/parsing/ast/statements.kt | 63 +++++++++++++++++++ .../parsing/parsetreetoast/statements.kt | 40 ++++++++++++ .../evaluation/SmeupInterpreterTest.kt | 7 +++ .../test/resources/smeup/T12_A08_P01.rpgle | 59 +++++++++++++++++ 5 files changed, 191 insertions(+), 7 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index d5a1d2705..d49ab3711 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -317,19 +317,34 @@ elseClause: ; casestatement: - ((CS_FIXED + csCASxx* + csCASother? + casestatementend +; + +csCASxx: + CS_FIXED cspec_continuedIndicators* - cs_controlLevel - indicatorsOff=onOffIndicatorsFlag indicators=cs_indicators factor1=factor) - (csCASEQ + cs_controlLevel + indicatorsOff=onOffIndicatorsFlag indicators=cs_indicators factor1=factor + (csCASEQ | csCASNE | csCASLE | csCASLT | csCASGE - | csCASGT - | csCAS))+ - casestatementend + | csCASGT) ; + +csCASother: + (CS_FIXED + cspec_continuedIndicators* + cs_controlLevel + indicatorsOff=onOffIndicatorsFlag indicators=cs_indicators factor1=factor + csCAS + ) + | (op_other FREE_SEMI free_linecomments? ) +; + casestatementend: CS_FIXED cspec_continuedIndicators* diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index ece9f62fe..0867b89ae 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -192,6 +192,69 @@ data class SelectStmt( } } +// ?tony? +/* @Serializable +data class CaseStmt( + var cases: List, + var other: SelectOtherClause? = null, + @Derived val dataDefinition: InStatementDataDefinition? = null, + override val position: Position? = null +) : Statement(position), CompositeStatement, StatementThatCanDefineData { + + override fun accept(mutes: MutableMap, start: Int, end: Int): MutableList { + + val muteAttached: MutableList = mutableListOf() + + cases.forEach { + muteAttached.addAll( + acceptBody(it.body, mutes, it.position!!.start.line, it.position.end.line) + ) + } + + if (other != null) { + muteAttached.addAll( + acceptBody(other!!.body, mutes, other!!.position!!.start.line, other!!.position!!.end.line) + ) + } + + return muteAttached + } + + override fun dataDefinition(): List = dataDefinition?.let { listOf(it) } ?: emptyList() + + override fun execute(interpreter: InterpreterCore) { + for (case in this.cases) { + val result = interpreter.eval(case.condition) + + interpreter.log { SelectCaseExecutionLogEntry(interpreter.getInterpretationContext().currentProgramName, case, result) } + if (result.asBoolean().value) { + interpreter.execute(case.body) + return + } + } + if (this.other != null) { + interpreter.log { + SelectOtherExecutionLogEntry( + interpreter.getInterpretationContext().currentProgramName, + this.other!! + ) + } + interpreter.execute(this.other!!.body) + } + } + + @Derived + override val body: List + get() { + val result = mutableListOf() + cases.forEach { case -> + result.addAll(case.body.explode()) + } + if (other?.body != null) result.addAll(other!!.body.explode()) + return result + } +}*/ + @Serializable data class SelectOtherClause(override val body: List, override val position: Position? = null) : Node(position), CompositeStatement diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 5d6a64cd6..1b04ea632 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -44,6 +44,8 @@ internal fun BlockContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) conf = conf ) } + // ?tony? + // this.casestatement() != null -> this.casestatement().toAst(conf) this.begindo() != null -> this.begindo() .let { it.csDO().cspec_fixed_standard_parts().validate( @@ -214,6 +216,44 @@ internal fun RpgParser.WhenstatementContext.toAst(conf: ToAstConfiguration = ToA } } +// ?tony? +/* internal fun RpgParser.CasestatementContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseStmt { + + var statementsToConsider = this.csCASEQ().map { it.toAst(conf) } + val indexOfOther = statementsToConsider.indexOfFirst { it is OtherStmt } + if (indexOfOther != -1) { + statementsToConsider = statementsToConsider.subList(0, indexOfOther) + } + val position = toPosition(conf.considerPosition) + return if (this.`when`() != null) { + CaseStmt( + this.`when`().csWHEN().fixedexpression.expression().toAst(conf), + statementsToConsider, + position + ) + } else { + + val (comparison, factor2) = this.csCASEQ().getCondition() + val csANDxx = this.csWHENxx().csANDxx() + val ands = csANDxx.map { it.toAst(conf) } + val csORxx = this.csWHENxx().csORxx() + val ors = csORxx.map { it.toAst(conf) } + val condition = LogicalCondition(comparison.asExpression(this.csWHENxx().factor1, factor2, conf)) + condition.and(ands) + condition.or(ors) + CaseStmt( + condition, + statementsToConsider, + position + ) + } +} + +internal fun RpgParser.CsCASEQContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): LogicalCondition { + val (comparison, factor2) = this.getCondition() + return LogicalCondition(comparison.asExpression(this.factor1, factor2, conf)) +} */ + @Serializable data class LogicalCondition(val expression: Expression) : Expression() { val ands = mutableListOf() diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index eb0b5f23a..4afc74488 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -406,4 +406,11 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Res(A*B+C)=246; Res(A * B + C)=246") assertEquals(expected, "smeup/T02_A60_P02".outputOf()) } + + @Test + fun executeT12_A08_P01() { + val expected = listOf("1", "2") + assertASTCanBeProduced("smeup/T12_A08_P01", printTree = true) + assertEquals(expected, "smeup/T12_A08_P01".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle new file mode 100644 index 000000000..961bfd7b7 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle @@ -0,0 +1,59 @@ + D £DBG_Str S 1 + * + C MOVEL '1' CHOISE 1 + C EXSR SEZ_T12_A08 + C £DBG_Str DSPLY + * + C MOVEL '2' CHOISE 1 + C EXSR SEZ_T12_A08 + C £DBG_Str DSPLY + * + C *IN34 CABEQ *OFF G4MAIN + C 'IN34=ON' DSPLY + C G4MAIN TAG + * + C SETON LR + * + C SEZ_T12_A08 BEGSR + C CHOISE CASEQ '1' CHOISER1 + C CHOISE CASEQ '2' CHOISER2 + C ENDCS + C ENDSR + *--------------------------------------------------------------- + RD* Errori programma MULANGT12 sezione A08 - ROUTINE 1 + *--------------------------------------------------------------* + C CHOISER1 BEGSR + c EVAL £DBG_Str='1' + C ENDSR + *--------------------------------------------------------------- + RD* Errori programma MULANGT12 sezione A08 - ROUTINE 2 + *--------------------------------------------------------------* + C CHOISER2 BEGSR + c EVAL £DBG_Str='2' + C ENDSR + *--------------------------------------------------------------- + RD* Errori programma MULANGT12 sezione A08 - ROUTINE 3 + *--------------------------------------------------------------* + C CHOISER3 BEGSR + * + C *IN35 CABEQ *OFF G5MAIN + C 'IN35=ON' DSPLY + C G5MAIN TAG + * + C ENDSR + *--------------------------------------------------------------- + RD* Errori programma MULANGT12 sezione A08 - ROUTINE 3 + *--------------------------------------------------------------* + C CHOISER4 BEGSR + * + C SELECT + C £CRNA WHENEQ 'ZZ' + C CALL 'CALLDEFV2' + C PARM £CRNB 2 + * + C OTHER + C CALL 'CALLDEFV2' + C PARM £CRNA 2 + C ENDSL + * + C ENDSR From e114e8fd2c1ae124800474378d9bd7fe21fc4c22 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:25:58 +0000 Subject: [PATCH 185/423] implement getAnyDataDefinition with custom error --- .../main/kotlin/com/smeup/rpgparser/interpreter/program.kt | 4 +++- .../kotlin/com/smeup/rpgparser/parsing/ast/cu_components.kt | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt index e9fdc3f11..c24786cc4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/program.kt @@ -57,7 +57,9 @@ class RpgProgram(val cu: CompilationUnit, val name: String = " String = { "Data definition $name was not found" }) = allDataDefinitions.first { it.name.equals(name, ignoreCase = true) } + ?: throw IllegalArgumentException(errorMessage.invoke()) + fun compileTimeArray(name: String): CompileTimeArray { fun firstCompileTimeArray() = if (compileTimeArrays.isNotEmpty()) { compileTimeArrays[0] From 71659cc98f35e52cc1899d8cd66f7b50ea916871 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 29 Feb 2024 15:08:00 +0100 Subject: [PATCH 186/423] First implementation of compiler directives al preprocessor --- .../parsing/facade/RpgParserFacade.kt | 2 +- .../parsing/facade/compilerDirectives.kt | 105 ++++++++++++++++++ .../smeup/rpgparser/parsing/facade/copy.kt | 36 +----- .../rpgparser/parsing/facade/preprocess.kt | 36 ++++++ 4 files changed, 144 insertions(+), 35 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt create mode 100644 rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/RpgParserFacade.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/RpgParserFacade.kt index 0f917e1f7..0b05f210a 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/RpgParserFacade.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/RpgParserFacade.kt @@ -48,7 +48,7 @@ import java.io.* import java.nio.charset.StandardCharsets import java.util.* import kotlin.reflect.KClass -import kotlin.reflect.full.cast +import kotlin.reflect.cast import kotlin.system.measureTimeMillis typealias MutesMap = MutableMap diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt new file mode 100644 index 000000000..b9a1bde61 --- /dev/null +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt @@ -0,0 +1,105 @@ +package com.smeup.rpgparser.parsing.facade + +import java.util.regex.Pattern + +// If true, the last read line from the source will be used in the resulting source. +var useRow: Boolean = true +var definitions = mutableListOf() +var lastIfCode: String = "" + +val IF_DEFINED_PATTERN = Regex(""".{6}/IF\sDEFINED\(([\w£$§,]+)\)$""", RegexOption.IGNORE_CASE) +val IF_NOT_DEFINED_PATTERN = Regex(""".{6}/IF\sNOT\sDEFINED\(([\w£$§,]+)\)$""", RegexOption.IGNORE_CASE) +val DEFINE_PATTERN = Regex(""".{6}/DEFINE\s+([^\s]+)""", RegexOption.IGNORE_CASE) +val UNDEFINE_PATTERN = Regex(""".{6}/UNDEFINE\s+([^\s]+)""", RegexOption.IGNORE_CASE) +val ELSE_PATTERN = Regex(""".{6}/ELSE""", RegexOption.IGNORE_CASE) +val ENDIF_PATTERN = Regex(""".{6}/ENDIF""", RegexOption.IGNORE_CASE) + +fun String.resolveCompilerDirectives(): String { + var result = "" + // Split input text into rows + val rows = this.split("\n") + + // Check each row against regex patterns + for (row in rows) { + when { + IF_DEFINED_PATTERN.matches(row) -> manageIfDefined(row) + IF_NOT_DEFINED_PATTERN.matches(row) -> manageIfNotDefined(row) + DEFINE_PATTERN.matches(row) -> manageDefine(row) + UNDEFINE_PATTERN.matches(row) -> manageUndefine(row) + ELSE_PATTERN.matches(row) -> manageElse() + ENDIF_PATTERN.matches(row) -> manageEndIf() + else -> { + if (useRow) { + result += row.plus("\n") + } + } + } + } + return result +} + +fun manageEndIf() { + if (isDefined(lastIfCode)) { + lastIfCode = "" + } +} + +fun manageElse() { + useRow = !useRow +} + +fun manageUndefine(row: String) { + val matchResult = UNDEFINE_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + definitions.remove(code.uppercase()) + } +} + +fun manageDefine(row: String) { + val matchResult = DEFINE_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + definitions.add(code.uppercase()) + } +} + +fun manageIfNotDefined(row: String) { + val matchResult = IF_NOT_DEFINED_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + lastIfCode = code.uppercase() + useRow = !isDefined(code) + } +} + +private fun manageIfDefined(row: String) { + val matchResult = IF_DEFINED_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + lastIfCode = code.uppercase() + useRow = isDefined(code) + } +} + +private fun isDefined(code: String): Boolean { + return definitions.any { it.equals(code.uppercase()) } +} + +fun getContentInsideParentheses(input: String): String? { + val regexPattern = Regex(""".{6}/DEFINE\s+([^\s]+)""", RegexOption.IGNORE_CASE) + val matchResult = regexPattern.matchEntire(input) + return matchResult?.groups?.get(1)?.value +} + +fun main() { + // Example usage: + val testString = " /DEFINE DMSE_INCLUDED" + val contentInsideParentheses = getContentInsideParentheses(testString) + + if (contentInsideParentheses != null) { + println("Content inside parentheses: $contentInsideParentheses") + } else { + println("The string does not match the specified format.") + } +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt index 5532c9be2..fee4782e6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt @@ -18,8 +18,6 @@ package com.smeup.rpgparser.parsing.facade import com.andreapivetta.kolor.yellow import com.smeup.rpgparser.execution.MainExecutionContext -import com.smeup.rpgparser.interpreter.PreprocessingLogEnd -import com.smeup.rpgparser.interpreter.PreprocessingLogStart import com.smeup.rpgparser.parsing.parsetreetoast.fireErrorEvent import com.smeup.rpgparser.rpginterop.CopyFileExtension import kotlinx.serialization.Serializable @@ -28,7 +26,6 @@ import java.io.BufferedReader import java.io.InputStream import java.util.* import java.util.regex.Pattern -import kotlin.system.measureTimeMillis typealias RelativeLine = Pair @@ -43,7 +40,7 @@ class Copy(val source: String) { } } -private fun String.includesCopy( +fun String.includesCopy( findCopy: (copyId: CopyId) -> String? = { MainExecutionContext.getSystemInterface()!!.findCopy(it)!!.source }, @@ -108,35 +105,6 @@ fun String.copyId(): CopyId { else -> CopyId(null, null, this) } } - -internal fun InputStream.preprocess( - findCopy: (copyId: CopyId) -> String?, - onStartInclusion: (copyId: CopyId, start: Int) -> Unit = { _: CopyId, _: Int -> }, - onEndInclusion: (end: Int) -> Unit = { _: Int -> }, - beforeInclusion: (copyId: CopyId) -> Boolean = { true } -): String { - val programName = getExecutionProgramNameWithNoExtension() - MainExecutionContext.log(PreprocessingLogStart(programName = programName)) - val preprocessed: String - measureTimeMillis { - preprocessed = bufferedReader().use(BufferedReader::readText).includesCopy( - findCopy = findCopy, - onStartInclusion = onStartInclusion, - onEndInclusion = onEndInclusion, - beforeInclusion = beforeInclusion - ) - }.apply { - MainExecutionContext.log( - PreprocessingLogEnd( - programName = programName, - elapsed = this, - programSouce = preprocessed - ) - ) - } - return preprocessed -} - @Serializable data class CopyId(val library: String? = null, val file: String? = null, val member: String) { @@ -285,7 +253,7 @@ class CopyBlocks : Iterable { absoluteLine - block.start } else { val childrenBefore = children.filter { child -> child.end <= absoluteLine } - absoluteLine - block.start - childrenBefore.sumBy { childBefore -> childBefore.end - childBefore.start } + 1 + absoluteLine - block.start - childrenBefore.sumOf { childBefore -> childBefore.end - childBefore.start } + 1 } } // else if line inside program diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt new file mode 100644 index 000000000..a896961ee --- /dev/null +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt @@ -0,0 +1,36 @@ +package com.smeup.rpgparser.parsing.facade + +import com.smeup.rpgparser.execution.MainExecutionContext +import com.smeup.rpgparser.interpreter.PreprocessingLogEnd +import com.smeup.rpgparser.interpreter.PreprocessingLogStart +import java.io.BufferedReader +import java.io.InputStream +import kotlin.system.measureTimeMillis + +internal fun InputStream.preprocess( + findCopy: (copyId: CopyId) -> String?, + onStartInclusion: (copyId: CopyId, start: Int) -> Unit = { _: CopyId, _: Int -> }, + onEndInclusion: (end: Int) -> Unit = { _: Int -> }, + beforeInclusion: (copyId: CopyId) -> Boolean = { true } +): String { + val programName = getExecutionProgramNameWithNoExtension() + MainExecutionContext.log(PreprocessingLogStart(programName = programName)) + val preprocessed: String + measureTimeMillis { + preprocessed = bufferedReader().use(BufferedReader::readText).includesCopy( + findCopy = findCopy, + onStartInclusion = onStartInclusion, + onEndInclusion = onEndInclusion, + beforeInclusion = beforeInclusion + ).resolveCompilerDirectives() + }.apply { + MainExecutionContext.log( + PreprocessingLogEnd( + programName = programName, + elapsed = this, + programSouce = preprocessed + ) + ) + } + return preprocessed +} \ No newline at end of file From 6fd2575f18b8562e619668b203000031b7eeacc6 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 29 Feb 2024 15:19:25 +0100 Subject: [PATCH 187/423] Improved logic of `mult` --- .../com/smeup/rpgparser/interpreter/internal_interpreter.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 77df6f963..d1d0c7a52 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -697,11 +697,7 @@ open class InternalInterpreter( val rightValue = BigDecimal(eval(statement.left).render()) val leftValue = BigDecimal(eval(statement.right).render()) val result = rightValue.multiply(leftValue) - val type = when { - statement.target is ArrayAccessExpr -> statement.target.type() - statement.target is DataRefExpr -> statement.target.variable.referred!!.type - else -> null - } + val type = statement.target.type() require(type is NumberType) return if (statement.halfAdjust) { DecimalValue(result.setScale(type.decimalDigits, RoundingMode.HALF_UP)) From 9011c3a6464a58a32c3c90ce616af2a2fd9fd744 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 29 Feb 2024 15:20:00 +0100 Subject: [PATCH 188/423] Improved logic of `div` --- .../com/smeup/rpgparser/interpreter/internal_interpreter.kt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index d1d0c7a52..ea02c943c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -711,11 +711,7 @@ open class InternalInterpreter( val dividend = BigDecimal(eval(statement.dividend).render()) val divisor = BigDecimal(eval(statement.divisor).render()) val quotient = dividend.divide(divisor, MathContext.DECIMAL128) - val type = when { - statement.target is ArrayAccessExpr -> statement.target.type() - statement.target is DataRefExpr -> statement.target.variable.referred!!.type - else -> null - } + val type = statement.target.type() require(type is NumberType) // calculation of rest // NB. rest based on type of quotient From ed46c3a0abf8ac62f08842c4cd9d0885426eb7b2 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 29 Feb 2024 15:47:10 +0100 Subject: [PATCH 189/423] Added `Transient` annotation --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 57bb0233e..6c52847cb 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1083,10 +1083,12 @@ data class MultStmt( @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null ) : Statement(position), StatementThatCanDefineData { + @Transient @Derived val left: Expression get() = factor1 ?: target + @Transient @Derived val right: Expression get() = factor2 @@ -1108,10 +1110,12 @@ data class DivStmt( @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null ) : Statement(position), StatementThatCanDefineData { + @Transient @Derived val dividend: Expression get() = factor1 ?: target + @Transient @Derived val divisor: Expression get() = factor2 From 296f8d38e083d6ec8d6007e5455f8474fabbf2fc Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 29 Feb 2024 16:53:39 +0100 Subject: [PATCH 190/423] Add test --- .../smeup/rpgparser/parsing/ast/FileDefinitionTest.kt | 10 ++++++++++ .../src/test/resources/db/EXTNAME03.rpgle | 7 +++++++ 2 files changed, 17 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/FileDefinitionTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/FileDefinitionTest.kt index 5a495578c..e3b89e7e5 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/FileDefinitionTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/ast/FileDefinitionTest.kt @@ -61,6 +61,16 @@ class FileDefinitionTest : AbstractTest() { }) } + @Test + fun resolveEXTNAME03() { + assertASTCanBeProduced( + exampleName = "db/EXTNAME03", + considerPosition = true, + afterAstCreation = { compilationUnit -> + assertEquals(listOf(), compilationUnit.resolveAndValidate()) + }) + } + @Test fun resolveLIKEDSPEC01() { assertASTCanBeProduced( diff --git a/rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle b/rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle new file mode 100644 index 000000000..bad190597 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle @@ -0,0 +1,7 @@ + * + *BRARTIR is the name of record format of the file BRARTI0L + *Fix error: Incongruous definitions of BRARTIR: RecordFormatType vs DataStructureType... + * + DBRARTIR E DS EXTNAME(BRARTI0L) INZ + C CLEAR BRART + C A§ARTI DSPLY From 40bd0779ab410b193f4d55ae0145812ad37b2bda Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 29 Feb 2024 17:15:28 +0100 Subject: [PATCH 191/423] First implementation of compiler directives al preprocessor - Patch for kotlin formatting --- .../com/smeup/rpgparser/parsing/facade/compilerDirectives.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt index b9a1bde61..4d839fa14 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt @@ -1,7 +1,5 @@ package com.smeup.rpgparser.parsing.facade -import java.util.regex.Pattern - // If true, the last read line from the source will be used in the resulting source. var useRow: Boolean = true var definitions = mutableListOf() From 2fc4cbda2d154f6e7a7c674a466b377f14ee8272 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:04:00 +0000 Subject: [PATCH 192/423] implemented CASxx structure --- .../com/smeup/rpgparser/interpreter/logs.kt | 22 ++++++ .../smeup/rpgparser/parsing/ast/statements.kt | 22 ++++-- .../parsing/parsetreetoast/statements.kt | 77 +++++++++++-------- 3 files changed, 82 insertions(+), 39 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt index 452bceb9d..8c54dde59 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt @@ -382,6 +382,18 @@ class SelectCaseExecutionLogEntry(programName: String, val case: SelectCase, val } } +// ?tony? +class CaseCaseExecutionLogEntry(programName: String, val case: CaseClause, val result: Value) : LogEntry(programName) { + override fun toString(): String { + return "executing CASxx" + } + override fun renderStatement(channel: String, filename: String, sep: String): String { + val data = "CASxx${sep}${case.condition.render()}$sep(${result.asBoolean().value})" + + return renderHeader(channel, filename, case.startLine(), sep) + data + } +} + class SelectOtherExecutionLogEntry(programName: String, val other: SelectOtherClause, val duration: Long = -1) : LogEntry(programName) { override fun toString(): String { return "executing SELECT OTHER" @@ -391,6 +403,16 @@ class SelectOtherExecutionLogEntry(programName: String, val other: SelectOtherCl } } +// ?tony? +class CaseOtherExecutionLogEntry(programName: String, val other: CaseOtherClause, val duration: Long = -1) : LogEntry(programName) { + override fun toString(): String { + return "executing CAS" + } + override fun renderStatement(channel: String, filename: String, sep: String): String { + return renderHeader(channel, filename, other.startLine(), sep) + "CAS" + } +} + class IfExecutionLogEntry(programName: String, val statement: IfStmt, val result: Value) : LogEntry(programName) { override fun toString(): String { return "executing IF" diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 0867b89ae..309791ea3 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -193,10 +193,10 @@ data class SelectStmt( } // ?tony? -/* @Serializable +@Serializable data class CaseStmt( - var cases: List, - var other: SelectOtherClause? = null, + var cases: List, + var other: CaseOtherClause? = null, @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null ) : Statement(position), CompositeStatement, StatementThatCanDefineData { @@ -226,15 +226,17 @@ data class CaseStmt( for (case in this.cases) { val result = interpreter.eval(case.condition) - interpreter.log { SelectCaseExecutionLogEntry(interpreter.getInterpretationContext().currentProgramName, case, result) } + interpreter.log { CaseCaseExecutionLogEntry(interpreter.getInterpretationContext().currentProgramName, case, result) } if (result.asBoolean().value) { interpreter.execute(case.body) + // TODO ?tony? + //ExecuteSubroutine(subroutine = ReferenceByName(case.function, subroutine), position = subroutine.position).execute(this) return } } if (this.other != null) { interpreter.log { - SelectOtherExecutionLogEntry( + CaseOtherExecutionLogEntry( interpreter.getInterpretationContext().currentProgramName, this.other!! ) @@ -253,14 +255,22 @@ data class CaseStmt( if (other?.body != null) result.addAll(other!!.body.explode()) return result } -}*/ +} @Serializable data class SelectOtherClause(override val body: List, override val position: Position? = null) : Node(position), CompositeStatement +// ?tony? +@Serializable +data class CaseOtherClause(override val body: List, override val position: Position? = null) : Node(position), CompositeStatement + @Serializable data class SelectCase(val condition: Expression, override val body: List, override val position: Position? = null) : Node(position), CompositeStatement +// ?tony? +@Serializable +data class CaseClause(val condition: Expression, override val body: List, override val position: Position? = null, val function: String) : Node(position), CompositeStatement + @Serializable data class EvalFlags( val halfAdjust: Boolean = false, diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 1b04ea632..02c8b3c0f 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -45,7 +45,7 @@ internal fun BlockContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) ) } // ?tony? - // this.casestatement() != null -> this.casestatement().toAst(conf) + this.casestatement() != null -> this.casestatement().toAst(conf) this.begindo() != null -> this.begindo() .let { it.csDO().cspec_fixed_standard_parts().validate( @@ -217,43 +217,31 @@ internal fun RpgParser.WhenstatementContext.toAst(conf: ToAstConfiguration = ToA } // ?tony? -/* internal fun RpgParser.CasestatementContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseStmt { +internal fun RpgParser.CasestatementContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseStmt { + val casClauses = this.csCASxx().map { it.toAst(conf) } + val other: CaseOtherClause? = null + return CaseStmt( + cases = casClauses, + other = other, + position = toPosition(conf.considerPosition) + ) +} - var statementsToConsider = this.csCASEQ().map { it.toAst(conf) } - val indexOfOther = statementsToConsider.indexOfFirst { it is OtherStmt } - if (indexOfOther != -1) { - statementsToConsider = statementsToConsider.subList(0, indexOfOther) - } +// ?tony? +internal fun RpgParser.CsCASxxContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseClause { + val (comparison, factor2) = this.getCondition() + val function = this.getFunction() + val condition = LogicalCondition(comparison.asExpression(this.factor1, factor2, conf)) val position = toPosition(conf.considerPosition) - return if (this.`when`() != null) { - CaseStmt( - this.`when`().csWHEN().fixedexpression.expression().toAst(conf), - statementsToConsider, - position - ) - } else { + return CaseClause( + condition, + emptyList(), + position, + function + ) - val (comparison, factor2) = this.csCASEQ().getCondition() - val csANDxx = this.csWHENxx().csANDxx() - val ands = csANDxx.map { it.toAst(conf) } - val csORxx = this.csWHENxx().csORxx() - val ors = csORxx.map { it.toAst(conf) } - val condition = LogicalCondition(comparison.asExpression(this.csWHENxx().factor1, factor2, conf)) - condition.and(ands) - condition.or(ors) - CaseStmt( - condition, - statementsToConsider, - position - ) - } } -internal fun RpgParser.CsCASEQContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): LogicalCondition { - val (comparison, factor2) = this.getCondition() - return LogicalCondition(comparison.asExpression(this.factor1, factor2, conf)) -} */ - @Serializable data class LogicalCondition(val expression: Expression) : Expression() { val ands = mutableListOf() @@ -327,6 +315,29 @@ internal fun RpgParser.CsWHENxxContext.getCondition() = else -> throw RuntimeException("No valid WhenXX condition") } +// ?tony? +internal fun RpgParser.CsCASxxContext.getCondition() = + when { + this.csCASEQ() != null -> ComparisonOperator.EQ to this.csCASEQ().cspec_fixed_standard_parts().factor2 + this.csCASNE() != null -> ComparisonOperator.NE to this.csCASNE().cspec_fixed_standard_parts().factor2 + this.csCASGE() != null -> ComparisonOperator.GE to this.csCASGE().cspec_fixed_standard_parts().factor2 + this.csCASGT() != null -> ComparisonOperator.GT to this.csCASGT().cspec_fixed_standard_parts().factor2 + this.csCASLE() != null -> ComparisonOperator.LE to this.csCASLE().cspec_fixed_standard_parts().factor2 + this.csCASLT() != null -> ComparisonOperator.LT to this.csCASLT().cspec_fixed_standard_parts().factor2 + else -> throw RuntimeException("No valid WhenXX condition") + } + +internal fun RpgParser.CsCASxxContext.getFunction() = + when { + this.csCASEQ() != null -> this.csCASEQ().cspec_fixed_standard_parts().resultType().text + this.csCASNE() != null -> this.csCASNE().cspec_fixed_standard_parts().resultType().text + this.csCASGE() != null -> this.csCASGE().cspec_fixed_standard_parts().resultType().text + this.csCASGT() != null -> this.csCASGT().cspec_fixed_standard_parts().resultType().text + this.csCASLE() != null -> this.csCASLE().cspec_fixed_standard_parts().resultType().text + this.csCASLT() != null -> this.csCASLT().cspec_fixed_standard_parts().resultType().text + else -> throw RuntimeException("No valid WhenXX condition") + } + internal fun RpgParser.CsIFxxContext.getCondition() = when { this.csIFEQ() != null -> ComparisonOperator.EQ to this.csIFEQ().cspec_fixed_standard_parts().factor2 From 5b59439c55575a60755ea7f07b060113274be083 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 1 Mar 2024 09:31:39 +0000 Subject: [PATCH 193/423] Fix executeSubRoutine, Fix CAS case, add more tests --- .../com/smeup/rpgparser/interpreter/logs.kt | 2 - .../smeup/rpgparser/parsing/ast/statements.kt | 20 +++++--- .../parsing/parsetreetoast/statements.kt | 19 +++++--- .../evaluation/SmeupInterpreterTest.kt | 2 +- .../test/resources/smeup/T12_A08_P01.rpgle | 46 ++++++------------- 5 files changed, 40 insertions(+), 49 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt index 8c54dde59..49b52c97c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt @@ -382,7 +382,6 @@ class SelectCaseExecutionLogEntry(programName: String, val case: SelectCase, val } } -// ?tony? class CaseCaseExecutionLogEntry(programName: String, val case: CaseClause, val result: Value) : LogEntry(programName) { override fun toString(): String { return "executing CASxx" @@ -403,7 +402,6 @@ class SelectOtherExecutionLogEntry(programName: String, val other: SelectOtherCl } } -// ?tony? class CaseOtherExecutionLogEntry(programName: String, val other: CaseOtherClause, val duration: Long = -1) : LogEntry(programName) { override fun toString(): String { return "executing CAS" diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 309791ea3..036146caa 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -192,7 +192,6 @@ data class SelectStmt( } } -// ?tony? @Serializable data class CaseStmt( var cases: List, @@ -228,9 +227,7 @@ data class CaseStmt( interpreter.log { CaseCaseExecutionLogEntry(interpreter.getInterpretationContext().currentProgramName, case, result) } if (result.asBoolean().value) { - interpreter.execute(case.body) - // TODO ?tony? - //ExecuteSubroutine(subroutine = ReferenceByName(case.function, subroutine), position = subroutine.position).execute(this) + executeSubProcedure(interpreter, case.function) return } } @@ -241,10 +238,21 @@ data class CaseStmt( this.other!! ) } + executeSubProcedure(interpreter, other!!.function) interpreter.execute(this.other!!.body) } } + private fun executeSubProcedure(interpreter: InterpreterCore, subProcedureName: String) { + val containingCU = this.ancestor(CompilationUnit::class.java) + ?: throw IllegalStateException("Not contained in a CU") + containingCU.subroutines.firstOrNull { subroutine -> + subroutine.name.equals(other = subProcedureName, ignoreCase = true) + }?.let { subroutine -> + ExecuteSubroutine(subroutine = ReferenceByName(subProcedureName, subroutine), position = subroutine.position).execute(interpreter) + } + } + @Derived override val body: List get() { @@ -260,14 +268,12 @@ data class CaseStmt( @Serializable data class SelectOtherClause(override val body: List, override val position: Position? = null) : Node(position), CompositeStatement -// ?tony? @Serializable -data class CaseOtherClause(override val body: List, override val position: Position? = null) : Node(position), CompositeStatement +data class CaseOtherClause(override val body: List, override val position: Position? = null, val function: String) : Node(position), CompositeStatement @Serializable data class SelectCase(val condition: Expression, override val body: List, override val position: Position? = null) : Node(position), CompositeStatement -// ?tony? @Serializable data class CaseClause(val condition: Expression, override val body: List, override val position: Position? = null, val function: String) : Node(position), CompositeStatement diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 02c8b3c0f..5d562c0e1 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -44,7 +44,6 @@ internal fun BlockContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) conf = conf ) } - // ?tony? this.casestatement() != null -> this.casestatement().toAst(conf) this.begindo() != null -> this.begindo() .let { @@ -216,18 +215,16 @@ internal fun RpgParser.WhenstatementContext.toAst(conf: ToAstConfiguration = ToA } } -// ?tony? internal fun RpgParser.CasestatementContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseStmt { val casClauses = this.csCASxx().map { it.toAst(conf) } - val other: CaseOtherClause? = null + val otherClause = this.csCASother().toAst() return CaseStmt( cases = casClauses, - other = other, + other = otherClause, position = toPosition(conf.considerPosition) ) } -// ?tony? internal fun RpgParser.CsCASxxContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseClause { val (comparison, factor2) = this.getCondition() val function = this.getFunction() @@ -242,6 +239,17 @@ internal fun RpgParser.CsCASxxContext.toAst(conf: ToAstConfiguration = ToAstConf } +internal fun RpgParser.CsCASotherContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseOtherClause { + val function = this.csCAS().cspec_fixed_standard_parts().resultType().text + val position = toPosition(conf.considerPosition) + return CaseOtherClause( + emptyList(), + position, + function + ) + +} + @Serializable data class LogicalCondition(val expression: Expression) : Expression() { val ands = mutableListOf() @@ -315,7 +323,6 @@ internal fun RpgParser.CsWHENxxContext.getCondition() = else -> throw RuntimeException("No valid WhenXX condition") } -// ?tony? internal fun RpgParser.CsCASxxContext.getCondition() = when { this.csCASEQ() != null -> ComparisonOperator.EQ to this.csCASEQ().cspec_fixed_standard_parts().factor2 diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 4afc74488..adbb6b55b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -409,7 +409,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT12_A08_P01() { - val expected = listOf("1", "2") + val expected = listOf("1", "2", "3") assertASTCanBeProduced("smeup/T12_A08_P01", printTree = true) assertEquals(expected, "smeup/T12_A08_P01".outputOf()) } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle index 961bfd7b7..7cf738253 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle @@ -2,58 +2,38 @@ * C MOVEL '1' CHOISE 1 C EXSR SEZ_T12_A08 - C £DBG_Str DSPLY * - C MOVEL '2' CHOISE 1 + C MOVEL '2' CHOISE C EXSR SEZ_T12_A08 - C £DBG_Str DSPLY * - C *IN34 CABEQ *OFF G4MAIN - C 'IN34=ON' DSPLY - C G4MAIN TAG + C MOVEL ' ' CHOISE + C EXSR SEZ_T12_A08 * C SETON LR - * + *--------------------------------------------------------------- C SEZ_T12_A08 BEGSR + *--------------------------------------------------------------- + * C CHOISE CASEQ '1' CHOISER1 C CHOISE CASEQ '2' CHOISER2 + C CAS CHOISER3 C ENDCS + * + C £DBG_Str DSPLY + * C ENDSR *--------------------------------------------------------------- - RD* Errori programma MULANGT12 sezione A08 - ROUTINE 1 - *--------------------------------------------------------------* C CHOISER1 BEGSR + *--------------------------------------------------------------* c EVAL £DBG_Str='1' C ENDSR *--------------------------------------------------------------- - RD* Errori programma MULANGT12 sezione A08 - ROUTINE 2 - *--------------------------------------------------------------* C CHOISER2 BEGSR + *--------------------------------------------------------------* c EVAL £DBG_Str='2' C ENDSR *--------------------------------------------------------------- - RD* Errori programma MULANGT12 sezione A08 - ROUTINE 3 - *--------------------------------------------------------------* C CHOISER3 BEGSR - * - C *IN35 CABEQ *OFF G5MAIN - C 'IN35=ON' DSPLY - C G5MAIN TAG - * - C ENDSR - *--------------------------------------------------------------- - RD* Errori programma MULANGT12 sezione A08 - ROUTINE 3 *--------------------------------------------------------------* - C CHOISER4 BEGSR - * - C SELECT - C £CRNA WHENEQ 'ZZ' - C CALL 'CALLDEFV2' - C PARM £CRNB 2 - * - C OTHER - C CALL 'CALLDEFV2' - C PARM £CRNA 2 - C ENDSL - * + C EVAL £DBG_Str='3' C ENDSR From d897d6527d6508281bdd49fc2da4571e0ba91ee0 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 1 Mar 2024 10:03:02 +0000 Subject: [PATCH 194/423] remove CompositeStatement --- .../smeup/rpgparser/parsing/ast/statements.kt | 37 ++----------------- .../parsing/parsetreetoast/statements.kt | 4 -- 2 files changed, 3 insertions(+), 38 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 036146caa..abdb3db53 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -198,26 +198,7 @@ data class CaseStmt( var other: CaseOtherClause? = null, @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null -) : Statement(position), CompositeStatement, StatementThatCanDefineData { - - override fun accept(mutes: MutableMap, start: Int, end: Int): MutableList { - - val muteAttached: MutableList = mutableListOf() - - cases.forEach { - muteAttached.addAll( - acceptBody(it.body, mutes, it.position!!.start.line, it.position.end.line) - ) - } - - if (other != null) { - muteAttached.addAll( - acceptBody(other!!.body, mutes, other!!.position!!.start.line, other!!.position!!.end.line) - ) - } - - return muteAttached - } +) : Statement(position), StatementThatCanDefineData { override fun dataDefinition(): List = dataDefinition?.let { listOf(it) } ?: emptyList() @@ -239,7 +220,6 @@ data class CaseStmt( ) } executeSubProcedure(interpreter, other!!.function) - interpreter.execute(this.other!!.body) } } @@ -252,30 +232,19 @@ data class CaseStmt( ExecuteSubroutine(subroutine = ReferenceByName(subProcedureName, subroutine), position = subroutine.position).execute(interpreter) } } - - @Derived - override val body: List - get() { - val result = mutableListOf() - cases.forEach { case -> - result.addAll(case.body.explode()) - } - if (other?.body != null) result.addAll(other!!.body.explode()) - return result - } } @Serializable data class SelectOtherClause(override val body: List, override val position: Position? = null) : Node(position), CompositeStatement @Serializable -data class CaseOtherClause(override val body: List, override val position: Position? = null, val function: String) : Node(position), CompositeStatement +data class CaseOtherClause(override val position: Position? = null, val function: String) : Node(position) @Serializable data class SelectCase(val condition: Expression, override val body: List, override val position: Position? = null) : Node(position), CompositeStatement @Serializable -data class CaseClause(val condition: Expression, override val body: List, override val position: Position? = null, val function: String) : Node(position), CompositeStatement +data class CaseClause(val condition: Expression, override val position: Position? = null, val function: String) : Node(position) @Serializable data class EvalFlags( diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 5d562c0e1..50584831b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -232,22 +232,18 @@ internal fun RpgParser.CsCASxxContext.toAst(conf: ToAstConfiguration = ToAstConf val position = toPosition(conf.considerPosition) return CaseClause( condition, - emptyList(), position, function ) - } internal fun RpgParser.CsCASotherContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseOtherClause { val function = this.csCAS().cspec_fixed_standard_parts().resultType().text val position = toPosition(conf.considerPosition) return CaseOtherClause( - emptyList(), position, function ) - } @Serializable From 98fd459536c6350707e77506ef9eecaf0a6c9923 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 1 Mar 2024 10:58:34 +0000 Subject: [PATCH 195/423] Update SmeupInterpreterTest.kt --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f45023995..7ba7dd04d 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -416,7 +416,6 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT12_A08_P01() { val expected = listOf("1", "2", "3") - assertASTCanBeProduced("smeup/T12_A08_P01", printTree = true) assertEquals(expected, "smeup/T12_A08_P01".outputOf()) } From fad6d71f531a07e3078f3a8773a21650a0d450c2 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 1 Mar 2024 11:05:57 +0000 Subject: [PATCH 196/423] rename log methods --- .../src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt | 4 ++-- .../main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt index 49b52c97c..e5302877c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt @@ -382,7 +382,7 @@ class SelectCaseExecutionLogEntry(programName: String, val case: SelectCase, val } } -class CaseCaseExecutionLogEntry(programName: String, val case: CaseClause, val result: Value) : LogEntry(programName) { +class CasXXExecutionLogEntry(programName: String, val case: CaseClause, val result: Value) : LogEntry(programName) { override fun toString(): String { return "executing CASxx" } @@ -402,7 +402,7 @@ class SelectOtherExecutionLogEntry(programName: String, val other: SelectOtherCl } } -class CaseOtherExecutionLogEntry(programName: String, val other: CaseOtherClause, val duration: Long = -1) : LogEntry(programName) { +class CasOtherExecutionLogEntry(programName: String, val other: CaseOtherClause, val duration: Long = -1) : LogEntry(programName) { override fun toString(): String { return "executing CAS" } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index d4e563d9a..4cc68b8e0 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -206,7 +206,7 @@ data class CaseStmt( for (case in this.cases) { val result = interpreter.eval(case.condition) - interpreter.log { CaseCaseExecutionLogEntry(interpreter.getInterpretationContext().currentProgramName, case, result) } + interpreter.log { CasXXExecutionLogEntry(interpreter.getInterpretationContext().currentProgramName, case, result) } if (result.asBoolean().value) { executeSubProcedure(interpreter, case.function) return @@ -214,7 +214,7 @@ data class CaseStmt( } if (this.other != null) { interpreter.log { - CaseOtherExecutionLogEntry( + CasOtherExecutionLogEntry( interpreter.getInterpretationContext().currentProgramName, this.other!! ) From 24cc53d6ec612017dbb51bc0448f5fcf0ce67834 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 1 Mar 2024 12:18:54 +0100 Subject: [PATCH 197/423] Fix test --- rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle b/rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle index bad190597..b5c477444 100644 --- a/rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/db/EXTNAME03.rpgle @@ -3,5 +3,5 @@ *Fix error: Incongruous definitions of BRARTIR: RecordFormatType vs DataStructureType... * DBRARTIR E DS EXTNAME(BRARTI0L) INZ - C CLEAR BRART + C CLEAR BRARTIR C A§ARTI DSPLY From 032928aba4360615331356a05909911b61e6e3fc Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 1 Mar 2024 12:20:08 +0100 Subject: [PATCH 198/423] Fix issue by filtering unnecessary record format from data definitions list --- .../rpgparser/parsing/parsetreetoast/misc.kt | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 8ea95c655..aa255bba0 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1983,7 +1983,7 @@ internal fun getProgramNameToCopyBlocks(): ProgramNameToCopyBlocks { internal fun List.removeDuplicatedDataDefinition(): List { val dataDefinitionMap = mutableMapOf() - return this.filter { + return removeUnnecessaryRecordFormat().filter { val dataDefinition = dataDefinitionMap[it.name] if (dataDefinition == null) { dataDefinitionMap[it.name] = it @@ -1996,3 +1996,17 @@ internal fun List.removeDuplicatedDataDefinition } } } + +/** + * This function is used to remove unnecessary record formats from a list of data definitions. + * Data definitions of type RecordFormatType are necessary where in the AST we don't have a DS + * named like the record format, and we have operations such as CLEAR RECORD_FORMAT_NAME. + * In that case the record format in the data definitions list is necessary just to retrieve the fields that must be clean. + * + * @return A list of data definitions excluding the ones of type `RecordFormat`. + */ +private fun List.removeUnnecessaryRecordFormat(): List { + return this.filterNot { dataDef -> + dataDef.type is RecordFormatType && this.any { it.type is DataStructureType && it.name.uppercase() == dataDef.name.uppercase() } + } +} From 75b1d5b3b44e1c4547c09be68e8ec93822098a45 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Fri, 1 Mar 2024 13:55:28 +0100 Subject: [PATCH 199/423] Remove errors in tests execution --- .../parsing/facade/compilerDirectives.kt | 110 +++++++++--------- .../rpgparser/parsing/facade/preprocess.kt | 10 +- .../com/smeup/rpgparser/parsing/CopyTest.kt | 6 +- 3 files changed, 64 insertions(+), 62 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt index 4d839fa14..3a611bb2e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt @@ -1,9 +1,6 @@ package com.smeup.rpgparser.parsing.facade -// If true, the last read line from the source will be used in the resulting source. -var useRow: Boolean = true -var definitions = mutableListOf() -var lastIfCode: String = "" +val DIRECTIVES_KEYWORD = listOf(" /IF", " /DEFINE", " /UNDEFINE", " /ELSE", " /ENDIF") val IF_DEFINED_PATTERN = Regex(""".{6}/IF\sDEFINED\(([\w£$§,]+)\)$""", RegexOption.IGNORE_CASE) val IF_NOT_DEFINED_PATTERN = Regex(""".{6}/IF\sNOT\sDEFINED\(([\w£$§,]+)\)$""", RegexOption.IGNORE_CASE) @@ -13,21 +10,61 @@ val ELSE_PATTERN = Regex(""".{6}/ELSE""", RegexOption.IGNORE_CASE) val ENDIF_PATTERN = Regex(""".{6}/ENDIF""", RegexOption.IGNORE_CASE) fun String.resolveCompilerDirectives(): String { + + if (!containDirectives(this)) { + return this + } + + var lastIfCode = "" var result = "" + val definitions = mutableListOf() + var useRow = true // Split input text into rows - val rows = this.split("\n") + val rows = this.lines() // Check each row against regex patterns for (row in rows) { when { - IF_DEFINED_PATTERN.matches(row) -> manageIfDefined(row) - IF_NOT_DEFINED_PATTERN.matches(row) -> manageIfNotDefined(row) - DEFINE_PATTERN.matches(row) -> manageDefine(row) - UNDEFINE_PATTERN.matches(row) -> manageUndefine(row) - ELSE_PATTERN.matches(row) -> manageElse() - ENDIF_PATTERN.matches(row) -> manageEndIf() + IF_DEFINED_PATTERN.matches(row) -> { + val matchResult = IF_DEFINED_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + lastIfCode = code.uppercase() + useRow = isDefined(definitions, code) + } + } + IF_NOT_DEFINED_PATTERN.matches(row) -> { + val matchResult = IF_NOT_DEFINED_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + lastIfCode = code.uppercase() + useRow = !isDefined(definitions, code) + } + } + DEFINE_PATTERN.matches(row) -> { + val matchResult = DEFINE_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + definitions.add(code.uppercase()) + } + } + UNDEFINE_PATTERN.matches(row) -> { + val matchResult = UNDEFINE_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + definitions.remove(code.uppercase()) + } + } + ELSE_PATTERN.matches(row) -> { + useRow = !useRow + } + ENDIF_PATTERN.matches(row) -> { + if (isDefined(definitions, lastIfCode)) { + lastIfCode = "" + } + } else -> { - if (useRow) { + if (useRow && row.length > 0) { result += row.plus("\n") } } @@ -36,53 +73,12 @@ fun String.resolveCompilerDirectives(): String { return result } -fun manageEndIf() { - if (isDefined(lastIfCode)) { - lastIfCode = "" - } -} - -fun manageElse() { - useRow = !useRow -} - -fun manageUndefine(row: String) { - val matchResult = UNDEFINE_PATTERN.matchEntire(row) - val code = matchResult?.groups?.get(1)?.value - if (code != null) { - definitions.remove(code.uppercase()) - } -} - -fun manageDefine(row: String) { - val matchResult = DEFINE_PATTERN.matchEntire(row) - val code = matchResult?.groups?.get(1)?.value - if (code != null) { - definitions.add(code.uppercase()) - } +private fun containDirectives(inputString: String): Boolean { + return DIRECTIVES_KEYWORD.any { keyword -> inputString.contains(keyword, ignoreCase = true) } } -fun manageIfNotDefined(row: String) { - val matchResult = IF_NOT_DEFINED_PATTERN.matchEntire(row) - val code = matchResult?.groups?.get(1)?.value - if (code != null) { - lastIfCode = code.uppercase() - useRow = !isDefined(code) - } -} - -private fun manageIfDefined(row: String) { - val matchResult = IF_DEFINED_PATTERN.matchEntire(row) - val code = matchResult?.groups?.get(1)?.value - if (code != null) { - lastIfCode = code.uppercase() - useRow = isDefined(code) - } -} - -private fun isDefined(code: String): Boolean { - return definitions.any { it.equals(code.uppercase()) } -} +private fun isDefined(definitions: MutableList, lastIfCode: String) = + definitions.any { it.equals(lastIfCode.uppercase()) } fun getContentInsideParentheses(input: String): String? { val regexPattern = Regex(""".{6}/DEFINE\s+([^\s]+)""", RegexOption.IGNORE_CASE) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt index a896961ee..43fd67a20 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt @@ -11,18 +11,22 @@ internal fun InputStream.preprocess( findCopy: (copyId: CopyId) -> String?, onStartInclusion: (copyId: CopyId, start: Int) -> Unit = { _: CopyId, _: Int -> }, onEndInclusion: (end: Int) -> Unit = { _: Int -> }, - beforeInclusion: (copyId: CopyId) -> Boolean = { true } + beforeInclusion: (copyId: CopyId) -> Boolean = { true }, + resolveDirectives: Boolean = true ): String { val programName = getExecutionProgramNameWithNoExtension() MainExecutionContext.log(PreprocessingLogStart(programName = programName)) - val preprocessed: String + var preprocessed: String measureTimeMillis { preprocessed = bufferedReader().use(BufferedReader::readText).includesCopy( findCopy = findCopy, onStartInclusion = onStartInclusion, onEndInclusion = onEndInclusion, beforeInclusion = beforeInclusion - ).resolveCompilerDirectives() + ) + if (resolveDirectives) { + preprocessed = preprocessed.resolveCompilerDirectives() + } }.apply { MainExecutionContext.log( PreprocessingLogEnd( diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt index 5e3a182a6..6cafce55b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt @@ -164,7 +164,8 @@ class CopyTest { findCopy = { copyId -> File("$srcRoot/${copyId.key(CopyFileExtension.rpgle)}").readText(charset = Charsets.UTF_8) .apply { copyDefinitions[copyId] = this } - } + }, + resolveDirectives = false ) absoluteLinesMatchingRelativeLine(pgm = pgm, copyDefinitions) } @@ -174,7 +175,8 @@ class CopyTest { val preprocessed = pgm.byteInputStream().preprocess( findCopy = { copyId -> copyDefinitions[copyId] }, onStartInclusion = { copyId, start -> copyBlocks.onStartCopyBlock(copyId, start) }, - onEndInclusion = { end -> copyBlocks.onEndCopyBlock(end) } + onEndInclusion = { end -> copyBlocks.onEndCopyBlock(end) }, + resolveDirectives = false ) preprocessed.lines().forEachIndexed { index, expectedLineOfCode -> println("index: $index, expectedLineOfCode:$expectedLineOfCode") From a27579a4393e7cd9a87fb01c4d7f09c7aa2a604f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 1 Mar 2024 15:06:34 +0100 Subject: [PATCH 200/423] Implemented test case --- .../evaluation/SmeupInterpreterTest.kt | 8 +++++++ .../test/resources/smeup/T02_A40_P07.rpgle | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P07.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 14cb70633..dd36ae2e4 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -462,4 +462,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T03_A30_P01-02".outputOf()) } + + @Test + fun executeT02_A40_P07() { + val expected = listOf( + "AAAAABBBBBCCCCCDDDDDEEEEEFFFFFGGGGGHHHHHIIIIIAAAAADDDDDGGGGGBBBBBCCCCCEEEEEFFFFFHHHHHIIIIIZZZZZ12345" + ) + assertEquals(expected, "smeup/T02_A40_P07".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P07.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P07.rpgle new file mode 100644 index 000000000..f00ecd8fb --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P07.rpgle @@ -0,0 +1,22 @@ + D DS + D DS7_AR1 15 DIM(3) + D DS7_FL1 5 OVERLAY(DS7_AR1:01) + D DS7_FL2 10 OVERLAY(DS7_AR1:*NEXT) + D DS7_AL1 5 + D DS7_NR1 5 0 + D £DBG_Str S 100 VARYING + + D* DS con overlay e campi definiti singolarmente + C EVAL DS7_FL1(1) = 'AAAAA' + C EVAL DS7_FL2(1) = 'BBBBBCCCCC' + C EVAL DS7_FL1(2) = 'DDDDD' + C EVAL DS7_FL2(2) = 'EEEEEFFFFF' + C EVAL DS7_FL1(3) = 'GGGGG' + C EVAL DS7_FL2(3) = 'HHHHHIIIII' + C EVAL DS7_AL1 = 'ZZZZZ' + C EVAL DS7_NR1 = 12345 + C EVAL £DBG_Str=DS7_AR1(1)+DS7_AR1(2)+DS7_AR1(3) + C +DS7_FL1(1)+DS7_FL1(2)+DS7_FL1(3) + C +DS7_FL2(1)+DS7_FL2(2)+DS7_FL2(3) + C +DS7_AL1+%CHAR(DS7_NR1) + C £DBG_Str DSPLY From fdfeea7706788c846c44b838d8de8c841780b6ba Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 1 Mar 2024 15:16:35 +0100 Subject: [PATCH 201/423] Implemented test case --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 8 ++++++++ .../src/test/resources/smeup/T02_A30_P03.rpgle | 13 +++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 14cb70633..e7c6bff37 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -462,4 +462,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T03_A30_P01-02".outputOf()) } + + @Test + fun executeT02_A30_P03() { + val expected = listOf( + "AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFF" + ) + assertEquals(expected, "smeup/T02_A30_P03".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P03.rpgle new file mode 100644 index 000000000..6c4daf5d5 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P03.rpgle @@ -0,0 +1,13 @@ + D A30_AR1 S 20 DIM(10) + D A30_AR3 S 20 DIM(%ELEM(A30_AR1)) + D £DBG_Str S 150 VARYING + + C EVAL A30_AR3(01) = 'AAAAAAAAAAAAAAAAAAAA' + C EVAL A30_AR3(02) = 'BBBBBBBBBBBBBBBBBBBB' + C EVAL A30_AR3(03) = 'CCCCCCCCCCCCCCCCCCCC' + C EVAL A30_AR3(04) = 'DDDDDDDDDDDDDDDDDDDD' + C EVAL A30_AR3(05) = 'EEEEEEEEEEEEEEEEEEEE' + C EVAL A30_AR3(06) = 'FFFFFFFFFFFFFFFFFFFF' + c EVAL £DBG_Str=A30_AR3(01)+A30_AR3(02)+A30_AR3(03) + C +A30_AR3(04)+A30_AR3(05)+A30_AR3(06) + C £DBG_Str DSPLY From 672dbb989d0df9a0c746b623e2e8cb0dc8880ed8 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Fri, 1 Mar 2024 14:23:00 +0000 Subject: [PATCH 202/423] Update 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 100ea9c8a..1019293bd 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 @@ -87,6 +87,7 @@ private val modules = SerializersModule { subclass(UnlockStmt::class) subclass(ScanStmt::class) subclass(SelectStmt::class) + subclass(CaseStmt::class) subclass(SetStmt::class) subclass(SetllStmt::class) subclass(SetgtStmt::class) From 65841bbaea54685bbccc70262d42f270d5a82842 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 1 Mar 2024 15:41:23 +0100 Subject: [PATCH 203/423] Implemented test case --- .../evaluation/SmeupInterpreterTest.kt | 8 ++++++++ .../test/resources/smeup/T02_A40_P08.rpgle | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P08.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 14cb70633..1b8371233 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -462,4 +462,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T03_A30_P01-02".outputOf()) } + + @Test + fun executeT02_A40_P08() { + val expected = listOf( + "CNCLI AAAAAA 333" + ) + assertEquals(expected, "smeup/T02_A40_P08".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P08.rpgle new file mode 100644 index 000000000..42c059034 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P08.rpgle @@ -0,0 +1,20 @@ + D A40_DS1 DS 30 + D DS1_FL1 2 + D DS1_FL2 10 + D DS1_FL3 15 + D DS1_FL4 3 0 + + D A40_DS8 DS + D DS8_FL1 LIKE(DS1_FL1) + D DS8_FL2 LIKE(DS1_FL2) + D DS8_FL3 LIKE(DS1_FL3) + D DS8_FL4 LIKE(DS1_FL4) + D £DBG_Str S 50 VARYING + + D* DS con overlay e campi definiti singolarmente + C EVAL DS8_FL1 = 'CN' + C EVAL DS8_FL2 = 'CLI' + C EVAL DS8_FL3 = 'AAAAAA' + C EVAL DS8_FL4 = 333 + C EVAL £DBG_Str=%TRIMR(A40_DS8) + C £DBG_Str DSPLY From 09678c43eb091a8280f9209afda97b84a14823f2 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Fri, 1 Mar 2024 15:53:55 +0100 Subject: [PATCH 204/423] Add more syntax controls on compiler directive insertions in sources. --- .../parsing/facade/compilerDirectives.kt | 79 +++++++++++++------ .../evaluation/SmeupInterpreterTest.kt | 7 +- .../test/resources/smeup/T60_A10_P01-02.rpgle | 3 +- .../test/resources/smeup/T70_A10_P01.rpgle | 41 +++++++--- 4 files changed, 92 insertions(+), 38 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt index 3a611bb2e..9e3c1f2f8 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt @@ -1,7 +1,23 @@ package com.smeup.rpgparser.parsing.facade -val DIRECTIVES_KEYWORD = listOf(" /IF", " /DEFINE", " /UNDEFINE", " /ELSE", " /ENDIF") +import com.smeup.rpgparser.parsing.parsetreetoast.fireErrorEvent +enum class SYN_RELEVANT_DIRECTIVES { + NONE, + IF_DEFINED, + IF_NOT_DEFINED, + ELSE, + ENDIF +} + +// List used to skip the resolution procedure when the source does not contain compiler directives. +val DIRECTIVES_KEYWORD = listOf(" /IF", + " /DEFINE", + " /UNDEFINE", + " /ELSE", + " /ENDIF") + +// Search patterns for identifying compiler directive rows. val IF_DEFINED_PATTERN = Regex(""".{6}/IF\sDEFINED\(([\w£$§,]+)\)$""", RegexOption.IGNORE_CASE) val IF_NOT_DEFINED_PATTERN = Regex(""".{6}/IF\sNOT\sDEFINED\(([\w£$§,]+)\)$""", RegexOption.IGNORE_CASE) val DEFINE_PATTERN = Regex(""".{6}/DEFINE\s+([^\s]+)""", RegexOption.IGNORE_CASE) @@ -15,7 +31,7 @@ fun String.resolveCompilerDirectives(): String { return this } - var lastIfCode = "" + var lastCode: SYN_RELEVANT_DIRECTIVES = SYN_RELEVANT_DIRECTIVES.NONE var result = "" val definitions = mutableListOf() var useRow = true @@ -23,25 +39,41 @@ fun String.resolveCompilerDirectives(): String { val rows = this.lines() // Check each row against regex patterns - for (row in rows) { + for ((index, row) in rows.withIndex()) { when { IF_DEFINED_PATTERN.matches(row) -> { + // Control if IF_DEFINED is acceptable + val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) + if (!acceptedLastCodes.any { it == lastCode }) { + val exc = CompilerDirectivesException("Unexpected IF_DEFINED directive at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } + + lastCode = SYN_RELEVANT_DIRECTIVES.IF_DEFINED val matchResult = IF_DEFINED_PATTERN.matchEntire(row) val code = matchResult?.groups?.get(1)?.value if (code != null) { - lastIfCode = code.uppercase() + useRow = isDefined(definitions, code) } } IF_NOT_DEFINED_PATTERN.matches(row) -> { + // Control if IF_NOT_DEFINED is acceptable + val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) + if (!acceptedLastCodes.any { it == lastCode }) { + val exc = CompilerDirectivesException("Unexpected IF_NOT_DEFINED directive at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } + + lastCode = SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED val matchResult = IF_NOT_DEFINED_PATTERN.matchEntire(row) val code = matchResult?.groups?.get(1)?.value if (code != null) { - lastIfCode = code.uppercase() useRow = !isDefined(definitions, code) } } DEFINE_PATTERN.matches(row) -> { + // Define is allways acceptable val matchResult = DEFINE_PATTERN.matchEntire(row) val code = matchResult?.groups?.get(1)?.value if (code != null) { @@ -49,6 +81,7 @@ fun String.resolveCompilerDirectives(): String { } } UNDEFINE_PATTERN.matches(row) -> { + // Undefine is allways acceptable val matchResult = UNDEFINE_PATTERN.matchEntire(row) val code = matchResult?.groups?.get(1)?.value if (code != null) { @@ -56,12 +89,26 @@ fun String.resolveCompilerDirectives(): String { } } ELSE_PATTERN.matches(row) -> { + // Control if ELSE is acceptable + val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.IF_DEFINED, SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED) + if (!acceptedLastCodes.any { it == lastCode }) { + val exc = CompilerDirectivesException("Unexpected ELSE directive at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } + + lastCode = SYN_RELEVANT_DIRECTIVES.ELSE useRow = !useRow } ENDIF_PATTERN.matches(row) -> { - if (isDefined(definitions, lastIfCode)) { - lastIfCode = "" + // Control if ENDIF is acceptable + val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.IF_DEFINED, SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED, SYN_RELEVANT_DIRECTIVES.ELSE) + if (!acceptedLastCodes.any { it == lastCode }) { + val exc = CompilerDirectivesException("Unexpected ENDIF directive at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) } + + lastCode = SYN_RELEVANT_DIRECTIVES.ENDIF + useRow = true } else -> { if (useRow && row.length > 0) { @@ -80,20 +127,4 @@ private fun containDirectives(inputString: String): Boolean { private fun isDefined(definitions: MutableList, lastIfCode: String) = definitions.any { it.equals(lastIfCode.uppercase()) } -fun getContentInsideParentheses(input: String): String? { - val regexPattern = Regex(""".{6}/DEFINE\s+([^\s]+)""", RegexOption.IGNORE_CASE) - val matchResult = regexPattern.matchEntire(input) - return matchResult?.groups?.get(1)?.value -} - -fun main() { - // Example usage: - val testString = " /DEFINE DMSE_INCLUDED" - val contentInsideParentheses = getContentInsideParentheses(testString) - - if (contentInsideParentheses != null) { - println("Content inside parentheses: $contentInsideParentheses") - } else { - println("The string does not match the specified format.") - } -} \ No newline at end of file +class CompilerDirectivesException(message: String) : Exception(message) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 079899c2a..0a4433adb 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -402,9 +402,10 @@ open class SmeupInterpreterTest : AbstractTest() { } @Test - fun executeT79_A10_P01() { - val expected = listOf("OUT") - assertEquals(expected, "smeup/T70_A10_P01".outputOf()) + fun executeT70_A10_P01() { + val outputOf = "smeup/T70_A10_P01".outputOf() + println(outputOf) + assertTrue(outputOf.all { it.equals("PRINT") }) } @Test diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01-02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01-02.rpgle index 5ee8cef1c..e2ac58686 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01-02.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01-02.rpgle @@ -25,4 +25,5 @@ C ENDIF C IF $OP=*OFF C CLOSE MLNGT60V - C ENDIF \ No newline at end of file + C ENDIF + C SETON LR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle index 1376e31c3..2541d6a54 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle @@ -1,22 +1,43 @@ D £DBG_Str S 100 * - C EVAL £DBG_Str='OUT' + * Test DEFINE and IF NOT DEFINED * - * Definisci variabili e registra definizione come eseguita - * - /IF NOT DEFINED(DMSE_INCLUDED) - /DEFINE DMSE_INCLUDED + /IF NOT DEFINED(DEFINE_1) + /DEFINE DEFINE_1 + C EVAL £DBG_Str='PRINT' C £DBG_Str DSPLY /ENDIF * - * Definizioni da saltare perchè già presenti + * Test IF NOT DEFINED WITH ELSE * - /IF NOT DEFINED(DMSE_INCLUDED) + /IF NOT DEFINED(DEFINE_1) + C EVAL £DBG_Str='NO_PRINT' + C £DBG_Str DSPLY + /ELSE + C EVAL £DBG_Str='PRINT' C £DBG_Str DSPLY /ENDIF * - * Pulisci define + * Test IF DEFINED + * + /IF DEFINED(DEFINE_2) + C EVAL £DBG_Str='NO_PRINT' + C £DBG_Str DSPLY + /ELSE + /UNDEFINE DEFINE_1 + C EVAL £DBG_Str='PRINT' + C £DBG_Str DSPLY + /ENDIF * - /UNDEFINE DMSE_INCLUDED + /IF NOT DEFINED(DEFINE_1) + C EVAL £DBG_Str='PRINT' + C £DBG_Str DSPLY + /ELSE + C EVAL £DBG_Str='NOT_PRINT' + C £DBG_Str DSPLY + /ENDIF + C EVAL £DBG_Str='PRINT' + C £DBG_Str DSPLY * - C SETON LR \ No newline at end of file + C SETON LR + From d204f8809c9e551477558b514448d26b70ebf9b1 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 1 Mar 2024 17:46:28 +0100 Subject: [PATCH 205/423] Change test for reproducibility --- .../src/test/resources/smeup/T02_A70_P01.rpgle | 1 + 1 file changed, 1 insertion(+) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle index ceb1c6b87..930db93a1 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A70_P01.rpgle @@ -1,3 +1,4 @@ + D A10_N4 C -999999999999999.9999999 D £DBG_Str S 15 D £DBG_Pas S 10 * From 0decbfdc2af97351d51cbab074e33b02891cd927 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Fri, 1 Mar 2024 17:48:11 +0100 Subject: [PATCH 206/423] Fix nullpointer when it.dspec().ds_name() was null, for example in case of D spec defined as constants. Removed also a not commented TODO --- .../smeup/rpgparser/interpreter/compile_time_interpreter.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 2579d6c3d..95cb2fe00 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -149,9 +149,8 @@ open class BaseCompileTimeInterpreter( statements.forEach { when { it.dspec() != null -> { - val name = it.dspec().ds_name().text - if (name == declName) { - // TODO verify... + val name = it.dspec().ds_name()?.text ?: it.dspec().dspecConstant().ds_name()?.text + if (declName.equals(name, ignoreCase = true)) { return it.dspec().TO_POSITION().text.asInt() } } From 4db6c3a589cd9e3e13914c6a29373fe5fecf147c Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 1 Mar 2024 18:01:33 +0100 Subject: [PATCH 207/423] Fix test --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 1b8371233..93fb277b3 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -2,6 +2,7 @@ package com.smeup.rpgparser.evaluation import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.AbstractTest +import com.smeup.rpgparser.assertCanBeParsed import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig @@ -466,7 +467,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A40_P08() { val expected = listOf( - "CNCLI AAAAAA 333" + "CNCLIAAAAAA333" ) assertEquals(expected, "smeup/T02_A40_P08".outputOf()) } From ad840d1e10880f520ef4e04bfad2077286cb7104 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 1 Mar 2024 18:02:25 +0100 Subject: [PATCH 208/423] Fixed behaviour of data definition when is used `LIKE` --- .../rpgparser/parsing/parsetreetoast/data_definitions.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 08c1735ed..98e765c23 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 @@ -790,7 +790,13 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = T return FieldInfo(this.name, overlayInfo = overlayInfo, explicitStartOffset = this.explicitStartOffset(), explicitEndOffset = if (explicitStartOffset() != null) this.explicitEndOffset() else null, - explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(varName, ignoreCase = true) }?.type, + explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: let { + val dataDefinition = knownDataDefinitions.firstOrNull { + it.name.equals(varName, ignoreCase = true) || it.fields.firstOrNull { fe -> fe.name.equals(varName, ignoreCase = true) } != null + } + + if (dataDefinition?.name.equals(varName, ignoreCase = true)) dataDefinition else dataDefinition?.fields?.firstOrNull { f -> f.name.equals(varName, ignoreCase = true)} + }?.type, arraySizeDeclared = this.arraySizeDeclared(conf), arraySizeDeclaredOnThisField = this.arraySizeDeclared(conf), initializationValue = initializationValue, From d36cff13ca3a63569f15027948bdd73d70a70fa6 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 1 Mar 2024 18:02:47 +0100 Subject: [PATCH 209/423] Fixed behaviour of `%TRIM` for DS --- .../rpgparser/interpreter/ExpressionEvaluation.kt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) 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 58d9f94d5..6e8175ce4 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 @@ -23,6 +23,7 @@ import com.smeup.rpgparser.utils.asLong import com.smeup.rpgparser.utils.divideAtIndex import com.smeup.rpgparser.utils.moveEndingString import com.strumenta.kolasu.model.Position +import com.strumenta.kolasu.model.ReferenceByName import com.strumenta.kolasu.model.specificProcess import java.math.BigDecimal import java.math.MathContext @@ -572,7 +573,17 @@ class ExpressionEvaluation( override fun eval(expression: TrimrExpr): Value { return if (expression.charactersToTrim == null) { - StringValue(evalAsString(expression.value).trimEnd()) + when (expression.value) { + is DataRefExpr -> { + if ((expression.value as DataRefExpr).variable.referred is DataDefinition) { + val referred: DataDefinition = (expression.value as DataRefExpr).variable.referred as DataDefinition + return StringValue(referred.fields.fold("") { acc, i -> acc.plus(evalAsString(DataRefExpr(ReferenceByName(referred.name, i))).trimEnd()) }) + } + + StringValue(evalAsString(expression.value).trimEnd()) + } + else -> StringValue(evalAsString(expression.value).trimEnd()) + } } else { val suffix = evalAsString(expression.charactersToTrim) var result = evalAsString(expression.value) From f0fad4ee19bb4f3d333aa2812e7ae171b50a557b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 1 Mar 2024 18:05:41 +0100 Subject: [PATCH 210/423] Removed unused import --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 93fb277b3..4decb84bb 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -2,7 +2,6 @@ package com.smeup.rpgparser.evaluation import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.AbstractTest -import com.smeup.rpgparser.assertCanBeParsed import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig From add3449b2a8ee7e29d6fa556e7b26324dd936086 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 1 Mar 2024 18:06:23 +0100 Subject: [PATCH 211/423] Added space where is needed, after `ktlinCheck` --- .../smeup/rpgparser/parsing/parsetreetoast/data_definitions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 98e765c23..62e60a895 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 @@ -795,7 +795,7 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = T it.name.equals(varName, ignoreCase = true) || it.fields.firstOrNull { fe -> fe.name.equals(varName, ignoreCase = true) } != null } - if (dataDefinition?.name.equals(varName, ignoreCase = true)) dataDefinition else dataDefinition?.fields?.firstOrNull { f -> f.name.equals(varName, ignoreCase = true)} + if (dataDefinition?.name.equals(varName, ignoreCase = true)) dataDefinition else dataDefinition?.fields?.firstOrNull { f -> f.name.equals(varName, ignoreCase = true) } }?.type, arraySizeDeclared = this.arraySizeDeclared(conf), arraySizeDeclaredOnThisField = this.arraySizeDeclared(conf), From dc2e81a28ba78cb957dc9ad4492ec32370143c0b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 08:58:45 +0100 Subject: [PATCH 212/423] Fixed after run test --- .../com/smeup/rpgparser/interpreter/ExpressionEvaluation.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 6e8175ce4..60980ea20 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 @@ -575,9 +575,9 @@ class ExpressionEvaluation( return if (expression.charactersToTrim == null) { when (expression.value) { is DataRefExpr -> { - if ((expression.value as DataRefExpr).variable.referred is DataDefinition) { - val referred: DataDefinition = (expression.value as DataRefExpr).variable.referred as DataDefinition - return StringValue(referred.fields.fold("") { acc, i -> acc.plus(evalAsString(DataRefExpr(ReferenceByName(referred.name, i))).trimEnd()) }) + val referred = (expression.value as DataRefExpr).variable.referred + if (referred?.type is DataStructureType) { + return StringValue((referred as DataDefinition).fields.fold("") { acc, i -> acc.plus(evalAsString(DataRefExpr(ReferenceByName(referred.name, i))).trimEnd()) }) } StringValue(evalAsString(expression.value).trimEnd()) From 83db442fc732692d7c349fb724ee18e21d3abe91 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 10:10:26 +0100 Subject: [PATCH 213/423] Rebase evaluation of `%TRIM%` after execution on IBMi, with right result. --- .../rpgparser/interpreter/ExpressionEvaluation.kt | 13 +------------ .../rpgparser/evaluation/SmeupInterpreterTest.kt | 2 +- 2 files changed, 2 insertions(+), 13 deletions(-) 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 60980ea20..58d9f94d5 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 @@ -23,7 +23,6 @@ import com.smeup.rpgparser.utils.asLong import com.smeup.rpgparser.utils.divideAtIndex import com.smeup.rpgparser.utils.moveEndingString import com.strumenta.kolasu.model.Position -import com.strumenta.kolasu.model.ReferenceByName import com.strumenta.kolasu.model.specificProcess import java.math.BigDecimal import java.math.MathContext @@ -573,17 +572,7 @@ class ExpressionEvaluation( override fun eval(expression: TrimrExpr): Value { return if (expression.charactersToTrim == null) { - when (expression.value) { - is DataRefExpr -> { - val referred = (expression.value as DataRefExpr).variable.referred - if (referred?.type is DataStructureType) { - return StringValue((referred as DataDefinition).fields.fold("") { acc, i -> acc.plus(evalAsString(DataRefExpr(ReferenceByName(referred.name, i))).trimEnd()) }) - } - - StringValue(evalAsString(expression.value).trimEnd()) - } - else -> StringValue(evalAsString(expression.value).trimEnd()) - } + StringValue(evalAsString(expression.value).trimEnd()) } else { val suffix = evalAsString(expression.charactersToTrim) var result = evalAsString(expression.value) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 4decb84bb..eb578429d 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -466,7 +466,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A40_P08() { val expected = listOf( - "CNCLIAAAAAA333" + "CNCLI AAAAAA 333" ) assertEquals(expected, "smeup/T02_A40_P08".outputOf()) } From c4d012487a5f6dbcb6841fa1a8002431999c8c95 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 10:10:53 +0100 Subject: [PATCH 214/423] Implemented pass 09. --- .../evaluation/SmeupInterpreterTest.kt | 8 ++++++++ .../test/resources/smeup/T02_A40_P09.rpgle | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index eb578429d..3ab9edef8 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -470,4 +470,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T02_A40_P08".outputOf()) } + + @Test + fun executeT02_A40_P09() { + val expected = listOf( + "CNCLI AAAAAA 333" + ) + assertEquals(expected, "smeup/T02_A40_P09".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle new file mode 100644 index 000000000..eabe8db48 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle @@ -0,0 +1,20 @@ + D A40_DS1 DS 30 + D DS1_FL1 2 + D DS1_FL2 10 + D DS1_FL3 15 + D DS1_FL4 3 0 + + D A40_DS9 DS + D DS9_FL1 LIKE(DS1_FL1) + D DS9_FL2 10 + D DS9_FL3 LIKE(DS1_FL3) + D DS9_FL4 3 0 + D £DBG_Str S 50 VARYING + + D* DS con overlay e campi definiti singolarmente + C EVAL DS9_FL1 = 'CN' + C EVAL DS9_FL2 = 'CLI' + C EVAL DS8_FL3 = 'AAAAAA' + C EVAL DS9_FL4 = 333 + C EVAL £DBG_Str=%TRIMR(A40_DS9) + C £DBG_Str DSPLY From 678a59c691cbc3550778b5ec60515c4665ed5866 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 10:15:52 +0100 Subject: [PATCH 215/423] Fixed test of P09 --- .../src/test/resources/smeup/T02_A40_P09.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle index eabe8db48..0adf063bc 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle @@ -14,7 +14,7 @@ D* DS con overlay e campi definiti singolarmente C EVAL DS9_FL1 = 'CN' C EVAL DS9_FL2 = 'CLI' - C EVAL DS8_FL3 = 'AAAAAA' + C EVAL DS9_FL3 = 'AAAAAA' C EVAL DS9_FL4 = 333 C EVAL £DBG_Str=%TRIMR(A40_DS9) C £DBG_Str DSPLY From 485b1fa253acd3a7ce7c7408393cfcb17d834f5f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 11:05:49 +0100 Subject: [PATCH 216/423] Fixed comments `T02_A40_P08` and `T02_A40_P09` --- .../src/test/resources/smeup/T02_A40_P08.rpgle | 2 +- .../src/test/resources/smeup/T02_A40_P09.rpgle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P08.rpgle index 42c059034..87f56392c 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P08.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P08.rpgle @@ -11,7 +11,7 @@ D DS8_FL4 LIKE(DS1_FL4) D £DBG_Str S 50 VARYING - D* DS con overlay e campi definiti singolarmente + D* DS definita con tutti campi in LIKE C EVAL DS8_FL1 = 'CN' C EVAL DS8_FL2 = 'CLI' C EVAL DS8_FL3 = 'AAAAAA' diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle index 0adf063bc..e82d11b2a 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P09.rpgle @@ -11,7 +11,7 @@ D DS9_FL4 3 0 D £DBG_Str S 50 VARYING - D* DS con overlay e campi definiti singolarmente + D* DS definita con campi in LIKE e campi normali C EVAL DS9_FL1 = 'CN' C EVAL DS9_FL2 = 'CLI' C EVAL DS9_FL3 = 'AAAAAA' From 7e0915b2ddc6d4f982edba0b9df5af47393f3ec6 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Mon, 4 Mar 2024 10:47:21 +0000 Subject: [PATCH 217/423] Fix the null exception when the CASxx block does not have the CAS condition --- .../parsing/parsetreetoast/statements.kt | 2 +- .../evaluation/SmeupInterpreterTest.kt | 6 ++++ .../test/resources/smeup/T12_A08_P02.rpgle | 33 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P02.rpgle diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 50584831b..fc048932a 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -217,7 +217,7 @@ internal fun RpgParser.WhenstatementContext.toAst(conf: ToAstConfiguration = ToA internal fun RpgParser.CasestatementContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): CaseStmt { val casClauses = this.csCASxx().map { it.toAst(conf) } - val otherClause = this.csCASother().toAst() + val otherClause = if (this.csCASother() != null) this.csCASother().toAst() else null return CaseStmt( cases = casClauses, other = otherClause, diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 02f0c8ba1..1f1f20b36 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -419,6 +419,12 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T12_A08_P01".outputOf()) } + @Test + fun executeT12_A08_P02() { + val expected = listOf("1", "2", "2") + assertEquals(expected, "smeup/T12_A08_P02".outputOf()) + } + @Test fun executeT10_A35_P07() { val expected = listOf("Src1=1 Src2=0") diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P02.rpgle new file mode 100644 index 000000000..fbb0b6e10 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P02.rpgle @@ -0,0 +1,33 @@ + D £DBG_Str S 1 + * + C MOVEL '1' CHOISE 1 + C EXSR SEZ_T12_A08 + * + C MOVEL '2' CHOISE + C EXSR SEZ_T12_A08 + * + C MOVEL ' ' CHOISE + C EXSR SEZ_T12_A08 + * + C SETON LR + *--------------------------------------------------------------- + C SEZ_T12_A08 BEGSR + *--------------------------------------------------------------- + * + C CHOISE CASEQ '1' CHOISER1 + C CHOISE CASEQ '2' CHOISER2 + C ENDCS + * + C £DBG_Str DSPLY + * + C ENDSR + *--------------------------------------------------------------- + C CHOISER1 BEGSR + *--------------------------------------------------------------* + c EVAL £DBG_Str='1' + C ENDSR + *--------------------------------------------------------------- + C CHOISER2 BEGSR + *--------------------------------------------------------------* + c EVAL £DBG_Str='2' + C ENDSR From 422e63a0196c248647ba15dbde39cb2b96e64f50 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Mon, 4 Mar 2024 11:42:08 +0000 Subject: [PATCH 218/423] change tests to create just 2 steps --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 4 ++-- .../src/test/resources/smeup/T12_A08_P01.rpgle | 12 ++++++------ .../src/test/resources/smeup/T12_A08_P02.rpgle | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 1f1f20b36..d373d4a70 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -415,13 +415,13 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT12_A08_P01() { - val expected = listOf("1", "2", "3") + val expected = listOf("123") assertEquals(expected, "smeup/T12_A08_P01".outputOf()) } @Test fun executeT12_A08_P02() { - val expected = listOf("1", "2", "2") + val expected = listOf("12") assertEquals(expected, "smeup/T12_A08_P02".outputOf()) } diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle index 7cf738253..065fcc58a 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P01.rpgle @@ -1,4 +1,4 @@ - D £DBG_Str S 1 + D £DBG_Str S 3 * C MOVEL '1' CHOISE 1 C EXSR SEZ_T12_A08 @@ -9,6 +9,8 @@ C MOVEL ' ' CHOISE C EXSR SEZ_T12_A08 * + C £DBG_Str DSPLY + * C SETON LR *--------------------------------------------------------------- C SEZ_T12_A08 BEGSR @@ -19,21 +21,19 @@ C CAS CHOISER3 C ENDCS * - C £DBG_Str DSPLY - * C ENDSR *--------------------------------------------------------------- C CHOISER1 BEGSR *--------------------------------------------------------------* - c EVAL £DBG_Str='1' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'1' C ENDSR *--------------------------------------------------------------- C CHOISER2 BEGSR *--------------------------------------------------------------* - c EVAL £DBG_Str='2' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'2' C ENDSR *--------------------------------------------------------------- C CHOISER3 BEGSR *--------------------------------------------------------------* - C EVAL £DBG_Str='3' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'3' C ENDSR diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P02.rpgle index fbb0b6e10..ec1aafb2b 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P02.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A08_P02.rpgle @@ -1,4 +1,4 @@ - D £DBG_Str S 1 + D £DBG_Str S 3 * C MOVEL '1' CHOISE 1 C EXSR SEZ_T12_A08 @@ -9,6 +9,8 @@ C MOVEL ' ' CHOISE C EXSR SEZ_T12_A08 * + C £DBG_Str DSPLY + * C SETON LR *--------------------------------------------------------------- C SEZ_T12_A08 BEGSR @@ -18,16 +20,14 @@ C CHOISE CASEQ '2' CHOISER2 C ENDCS * - C £DBG_Str DSPLY - * C ENDSR *--------------------------------------------------------------- C CHOISER1 BEGSR *--------------------------------------------------------------* - c EVAL £DBG_Str='1' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'1' C ENDSR *--------------------------------------------------------------- C CHOISER2 BEGSR *--------------------------------------------------------------* - c EVAL £DBG_Str='2' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'2' C ENDSR From 0f51a479b3a2becb970005e24fadb4228c4db762 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 13:38:09 +0100 Subject: [PATCH 219/423] Implemented `T02_A50_P08` test --- .../evaluation/SmeupInterpreterTest.kt | 8 ++++++++ .../src/test/resources/smeup/T02_A50_P08.rpgle | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 3ab9edef8..7103b2da2 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -478,4 +478,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T02_A40_P09".outputOf()) } + + @Test + fun executeT02_A50_P08() { + val expected = listOf( + "A50_A81(Funzione ) A50_N81(Funzione )A50_V81(Funzione)" + ) + assertEquals(expected, "smeup/T02_A50_P08".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle new file mode 100644 index 000000000..912b64f3d --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle @@ -0,0 +1,18 @@ + D £DBG_I_Fun S 10 Funzione chiamata + D £DBG_I_Num S 7 0 Numero esecuzioni + D £DBG_O_Str S 2560 VARYING Risultato + + D A50_A81 S LIKE(£DBG_I_Fun) + D A50_N81 S LIKE(£DBG_I_Num) + D A50_V81 S LIKE(£DBG_O_Str) + + D £DBG_Str S 150 VARYING + + D* DS con overlay e campi definiti singolarmente + C EVAL A50_A81='Funzione' + C EVAL A50_N81=1234567 + C EVAL A50_V81='Funzione' + C EVAL £DBG_Str= 'A50_A81('+A50_A81+')' + C +' A50_N81('+%CHAR(A50_A81)+')' + C + 'A50_V81('+A50_V81+')' + C £DBG_Str DSPLY From 7475a9d70b48c5be78f6a56f9971d19a398ced96 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 13:40:38 +0100 Subject: [PATCH 220/423] Implemented `T02_A50_P09` test --- .../evaluation/SmeupInterpreterTest.kt | 8 +++++++ .../test/resources/smeup/T02_A50_P09.rpgle | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 7103b2da2..199c219e3 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -486,4 +486,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T02_A50_P08".outputOf()) } + + @Test + fun executeT02_A50_P09() { + val expected = listOf( + "A50_A91(Funzione ) A50_N91(Funzione )A50_V91(Funzione)" + ) + assertEquals(expected, "smeup/T02_A50_P09".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle new file mode 100644 index 000000000..20070a0ec --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle @@ -0,0 +1,22 @@ + D £DBG_I_Fun S 10 Funzione chiamata + D £DBG_I_Num S 7 0 Numero esecuzioni + D £DBG_O_Str S 2560 VARYING Risultato + + D A50_A81 S LIKE(£DBG_I_Fun) + D A50_N81 S LIKE(£DBG_I_Num) + D A50_V81 S LIKE(£DBG_O_Str) + + D A50_A91 S LIKE(A50_A81) + D A50_N91 S LIKE(A50_N81) + D A50_V91 S LIKE(A50_V81) + + D £DBG_Str S 150 VARYING + + D* DS con overlay e campi definiti singolarmente + C EVAL A50_A91='Funzione' + C EVAL A50_N91=1234567 + C EVAL A50_V91='Funzione' + C EVAL £DBG_Str= 'A50_A91('+A50_A91+')' + C +' A50_N91('+%CHAR(A50_A91)+')' + C + 'A50_V91('+A50_V91+')' + C £DBG_Str DSPLY From d0de1dfb77738f62705bbc92238aef49bc7f13bf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 15:32:34 +0100 Subject: [PATCH 221/423] Implemented case of test --- .../evaluation/SmeupInterpreterTest.kt | 7 ++ .../test/resources/smeup/T60_A10_P01.rpgle | 108 ++++++++++++++++++ .../resources/smeup/metadata/MLNGT60V.json | 19 +++ 3 files changed, 134 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60V.json diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index edc651468..d139e3b5b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -2,6 +2,7 @@ package com.smeup.rpgparser.evaluation import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.AbstractTest +import com.smeup.rpgparser.assertCanBeParsed import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig @@ -478,4 +479,10 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T02_A30_P03".outputOf()) } + + @Test + fun executeT60_A10_P01() { + val expected = listOf("KA(0)KB(0)KC(0)KD(0)KE(0)KF(0)KG(0)KH(0)KI(0)KJ(0)KK(0)KL(0)KM(0)KN(0)KP(0)KQ(0)KR(0)KS(0)KT(0)KU(0)KV(0)KW(0)KX(0)KY(0)") + assertEquals(expected, "smeup/T60_A10_P01".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01.rpgle new file mode 100644 index 000000000..6c4a3982c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A10_P01.rpgle @@ -0,0 +1,108 @@ + D £DBG_Str S 250 + D $OP S 1N INZ(*ON) + + D* Test sugli indicatori delle chiavi KA-KY (F01-F24) + C EVAL £DBG_Str='' + C IF $OP=*OFF + C OPEN MLNGT60V + C ENDIF + C KA EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KA(1) ' + C NKA EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KA(0) ' + C KB EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KB(1) ' + C NKB EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KB(0) ' + C KC EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KC(1) ' + C NKC EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KC(0) ' + C KD EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KD(1) ' + C NKD EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KD(0) ' + C KE EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KE(1) ' + C NKE EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KE(0) ' + C KF EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KF(1) ' + C NKF EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KF(0) ' + C KG EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KG(1) ' + C NKG EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KG(0) ' + C KH EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KH(1) ' + C NKH EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KH(0) ' + C KI EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KI(1) ' + C NKI EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KI(0) ' + C KJ EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KJ(1) ' + C NKJ EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KJ(0) ' + C KK EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KK(1) ' + C NKK EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KK(0) ' + C KL EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KL(1) ' + C NKL EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KL(0) ' + C KM EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KM(1) ' + C NKM EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KM(0) ' + C KN EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KN(1) ' + C NKN EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KN(0) ' + C KP EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KP(1) ' + C NKP EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KP(0) ' + C KQ EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KQ(1) ' + C NKQ EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KQ(0) ' + C KR EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KR(1) ' + C NKR EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KR(0) ' + C KS EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KS(1) ' + C NKS EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KS(0) ' + C KT EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KT(1) ' + C NKT EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KT(0) ' + C KU EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KU(1) ' + C NKU EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KU(0) ' + C KV EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KV(1) ' + C NKV EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KV(0) ' + C KW EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KW(1) ' + C NKW EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KW(0) ' + C KX EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KX(1) ' + C NKX EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KX(0) ' + C KY EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KY(1)' + C NKY EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C 'KY(0)' + C IF $OP=*OFF + C CLOSE MLNGT60V + C ENDIF + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60V.json b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60V.json new file mode 100644 index 000000000..27ba6b1a4 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60V.json @@ -0,0 +1,19 @@ +{"name": "MLNGT60V", + "tableName": "MULANGTF", + "recordFormat": "", + "fields": [ + { "fieldName": "*IN62", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "*IN96", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "*IN97", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "£RASDI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "£PDSNP", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "£PDSJN", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "£PDSNU", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + ], "accessFields": []} From 5b3e7d965ec934004d587e9d070c9aa59f3a8261 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 16:03:50 +0100 Subject: [PATCH 222/423] Fixed the bug by adding missed enums --- .../smeup/rpgparser/parsing/ast/indicators.kt | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt index 450939bb2..a5435905e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt @@ -41,7 +41,31 @@ typealias IndicatorKey = Int * Managed indicator types * */ enum class IndicatorType(val range: IntRange) { - Predefined(1..99), + KA(1..1), + KB(2..2), + KC(3..3), + KD(4..4), + KE(5..5), + KF(6..6), + KG(7..7), + KH(8..8), + KI(9..9), + KJ(10..10), + KK(11..11), + KL(12..12), + KM(13..13), + KN(14..14), + KP(15..15), + KQ(16..16), + KR(17..17), + KS(18..18), + KT(19..19), + KU(20..20), + KV(21..21), + KW(22..22), + KX(23..23), + KY(24..24), + Predefined(25..99), LR(100..100), RT(101..101), OC(102..102), From bde54b47b702c02420378b4e595fa711063bca52 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 4 Mar 2024 16:04:25 +0100 Subject: [PATCH 223/423] Fix after ktlinCheck --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index d139e3b5b..37cdda703 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -2,7 +2,6 @@ package com.smeup.rpgparser.evaluation import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.AbstractTest -import com.smeup.rpgparser.assertCanBeParsed import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig From 175510bd7f52de3a986fa0b534d22294c7eb344c Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 5 Mar 2024 10:07:32 +0100 Subject: [PATCH 224/423] Fixed the problem when is used predefined indicator --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt index a5435905e..c9e758711 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt @@ -41,6 +41,7 @@ typealias IndicatorKey = Int * Managed indicator types * */ enum class IndicatorType(val range: IntRange) { + Predefined(1..99), KA(1..1), KB(2..2), KC(3..3), @@ -65,7 +66,6 @@ enum class IndicatorType(val range: IntRange) { KW(22..22), KX(23..23), KY(24..24), - Predefined(25..99), LR(100..100), RT(101..101), OC(102..102), From 85ddccf42d5355f7aa21605e032693b8da6e4ebf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 5 Mar 2024 10:10:18 +0100 Subject: [PATCH 225/423] Removed space in .rpgle files --- .../src/test/resources/smeup/T02_A50_P08.rpgle | 2 +- .../src/test/resources/smeup/T02_A50_P09.rpgle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle index 912b64f3d..0c7fc3bb8 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle @@ -6,7 +6,7 @@ D A50_N81 S LIKE(£DBG_I_Num) D A50_V81 S LIKE(£DBG_O_Str) - D £DBG_Str S 150 VARYING + D £DBG_Str S 150 VARYING D* DS con overlay e campi definiti singolarmente C EVAL A50_A81='Funzione' diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle index 20070a0ec..b8a10731f 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle @@ -10,7 +10,7 @@ D A50_N91 S LIKE(A50_N81) D A50_V91 S LIKE(A50_V81) - D £DBG_Str S 150 VARYING + D £DBG_Str S 150 VARYING D* DS con overlay e campi definiti singolarmente C EVAL A50_A91='Funzione' From 568b6f0802de7d62e5542c83b545a011ce161a00 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 5 Mar 2024 10:17:27 +0100 Subject: [PATCH 226/423] Improved calculation of `explicitElementType` --- .../rpgparser/parsing/parsetreetoast/data_definitions.kt | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) 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 62e60a895..d89dbfdb0 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 @@ -790,13 +790,8 @@ private fun RpgParser.Parm_fixedContext.toFieldInfo(conf: ToAstConfiguration = T return FieldInfo(this.name, overlayInfo = overlayInfo, explicitStartOffset = this.explicitStartOffset(), explicitEndOffset = if (explicitStartOffset() != null) this.explicitEndOffset() else null, - explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: let { - val dataDefinition = knownDataDefinitions.firstOrNull { - it.name.equals(varName, ignoreCase = true) || it.fields.firstOrNull { fe -> fe.name.equals(varName, ignoreCase = true) } != null - } - - if (dataDefinition?.name.equals(varName, ignoreCase = true)) dataDefinition else dataDefinition?.fields?.firstOrNull { f -> f.name.equals(varName, ignoreCase = true) } - }?.type, + explicitElementType = this.calculateExplicitElementType(arraySizeDeclared, conf) ?: knownDataDefinitions.firstOrNull { it.name.equals(varName, ignoreCase = true) }?.type + ?: knownDataDefinitions.flatMap { it.fields }.firstOrNull { fe -> fe.name.equals(varName, ignoreCase = true) }?.type, arraySizeDeclared = this.arraySizeDeclared(conf), arraySizeDeclaredOnThisField = this.arraySizeDeclared(conf), initializationValue = initializationValue, From 15c8300741c75a1b8feaaf4e3724ba00fa1b544c Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 5 Mar 2024 13:09:41 +0100 Subject: [PATCH 227/423] Implemented `INDIC03` test case --- .../rpgparser/evaluation/InterpreterTest.kt | 9 +++++++++ .../src/test/resources/INDIC03.rpgle | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/INDIC03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index b8f2c6e4d..73c302d56 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2255,6 +2255,15 @@ Test 6 assertEquals(expected, "INDIC02".outputOf()) } + @Test + fun executeINDIC03() { + val expected = listOf( + "*INKA(0) *IN01(1)", + "*INKA(1) *IN01(0)" + ) + assertEquals(expected, "INDIC03".outputOf()) + } + @Test fun executeBIFCHECK() { assertEquals(listOf("ok"), outputOf("BIFCHECK")) diff --git a/rpgJavaInterpreter-core/src/test/resources/INDIC03.rpgle b/rpgJavaInterpreter-core/src/test/resources/INDIC03.rpgle new file mode 100644 index 000000000..e0098755b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/INDIC03.rpgle @@ -0,0 +1,18 @@ + D £DBG_Str S 50 VARYING + + C MOVEL *ON *IN01 + C MOVEL *OFF *INKA + * + C EVAL £DBG_Str= '*INKA('+%CHAR(*INKA)+')' + C +' *IN01('+%CHAR(*IN01)+')' + C £DBG_Str DSPLY + * result: '*INKA(0) *IN01(1)' + * + C MOVEL *OFF *IN01 + C MOVEL *ON *INKA + * + C EVAL £DBG_Str= '*INKA('+%CHAR(*INKA)+')' + C +' *IN01('+%CHAR(*IN01)+')' + C £DBG_Str DSPLY + * result: '*INKA(1) *IN01(0)' + C SETON LR From fceda42b0643565a1c2818783e4416df5d14a968 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 5 Mar 2024 15:06:51 +0100 Subject: [PATCH 228/423] Fixed enums --- .../smeup/rpgparser/parsing/ast/indicators.kt | 48 +++++++++---------- .../rpgparser/parsing/parsetreetoast/misc.kt | 4 +- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt index c9e758711..d992296f4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt @@ -42,35 +42,35 @@ typealias IndicatorKey = Int * */ enum class IndicatorType(val range: IntRange) { Predefined(1..99), - KA(1..1), - KB(2..2), - KC(3..3), - KD(4..4), - KE(5..5), - KF(6..6), - KG(7..7), - KH(8..8), - KI(9..9), - KJ(10..10), - KK(11..11), - KL(12..12), - KM(13..13), - KN(14..14), - KP(15..15), - KQ(16..16), - KR(17..17), - KS(18..18), - KT(19..19), - KU(20..20), - KV(21..21), - KW(22..22), - KX(23..23), - KY(24..24), LR(100..100), RT(101..101), OC(102..102), OF(103..103), OV(104..104), + KA(105..105), + KB(106..106), + KC(107..107), + KD(108..108), + KE(109..109), + KF(110..110), + KG(111..111), + KH(112..112), + KI(113..113), + KJ(114..114), + KK(115..115), + KL(116..116), + KM(117..117), + KN(118..118), + KP(119..119), + KQ(120..120), + KR(121..121), + KS(122..122), + KT(123..123), + KU(124..124), + KV(125..125), + KW(126..126), + KX(127..127), + KY(128..128), ; companion object { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 1657ca755..1c5215fa0 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -955,8 +955,8 @@ private fun annidatedReferenceExpression( } } if (text.uppercase(Locale.getDefault()).startsWith("*IN")) { - val index = text.uppercase(Locale.getDefault()).removePrefix("*IN").toInt() - return IndicatorExpr(index, position) + val index = text.uppercase(Locale.getDefault()).removePrefix("*IN") + return IndicatorExpr(index.toIndicatorKey(), position) } var expr: Expression From 1987343e2d157f9edd64d9be5a8fb211d67f6afa Mon Sep 17 00:00:00 2001 From: Domenico Mancini Date: Wed, 6 Mar 2024 14:09:25 +0100 Subject: [PATCH 229/423] Added implemented test cases --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 16 ++++++++++++++++ .../src/test/resources/smeup/T12_A04_P13.rpgle | 9 +++++++++ .../src/test/resources/smeup/T12_A04_P14.rpgle | 9 +++++++++ 3 files changed, 34 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P13.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P14.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 50a07a060..0bf18b613 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -528,4 +528,20 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("KA(0)KB(0)KC(0)KD(0)KE(0)KF(0)KG(0)KH(0)KI(0)KJ(0)KK(0)KL(0)KM(0)KN(0)KP(0)KQ(0)KR(0)KS(0)KT(0)KU(0)KV(0)KW(0)KX(0)KY(0)") assertEquals(expected, "smeup/T60_A10_P01".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT12_A04_P13() { + val expected = listOf( + "CNT()" + ) + assertEquals(expected, "smeup/T12_A04_P13".outputOf()) + } + + @Test + fun executeT12_A04_P14() { + val expected = listOf( + "CNT()" + ) + assertEquals(expected, "smeup/T12_A04_P14".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P13.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P13.rpgle new file mode 100644 index 000000000..fd589cd4b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P13.rpgle @@ -0,0 +1,9 @@ + D A04_A01_CNT S 1 INZ('') + D £DBG_Str S 150 VARYING + + C EVAL A04_A01_CNT = 'A' + C A04_A01_CNT DOWNE *BLANKS + C EVAL A04_A01_CNT = *BLANKS + C ENDDO + C EVAL £DBG_Str='CNT('+%TRIM(A04_A01_CNT)+')' + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P14.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P14.rpgle new file mode 100644 index 000000000..2433cbfb3 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P14.rpgle @@ -0,0 +1,9 @@ + D A04_A01_CNT S 1 INZ('') + D £DBG_Str S 150 VARYING + + C EVAL A04_A01_CNT = 'A' + C A04_A01_CNT DOWNE *BLANK + C EVAL A04_A01_CNT = *BLANK + C ENDDO + C EVAL £DBG_Str='CNT('+%TRIM(A04_A01_CNT)+')' + C £DBG_Str DSPLY \ No newline at end of file From 079912ea93c5d72decf38f7910f58fade1d7962c Mon Sep 17 00:00:00 2001 From: Domenico Mancini Date: Wed, 6 Mar 2024 15:00:50 +0100 Subject: [PATCH 230/423] Fixed DOWxx statements not producing proper AST for factor2 --- .../parsing/parsetreetoast/statements.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index fc048932a..3dd55e631 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -71,19 +71,21 @@ internal fun RpgParser.CsDOWxxContext.toAst(blockContext: BlockContext, conf: To else -> todo(conf = conf) } val factor2 = when { - this.csDOWEQ() != null -> this.csDOWEQ().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) - this.csDOWNE() != null -> this.csDOWNE().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) - this.csDOWGT() != null -> this.csDOWGT().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) - this.csDOWGE() != null -> this.csDOWGE().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) - this.csDOWLT() != null -> this.csDOWLT().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) - this.csDOWLE() != null -> this.csDOWLE().cspec_fixed_standard_parts().factor2.content.toAst(conf = conf) + this.csDOWEQ() != null -> this.csDOWEQ().cspec_fixed_standard_parts().factor2 + this.csDOWNE() != null -> this.csDOWNE().cspec_fixed_standard_parts().factor2 + this.csDOWGT() != null -> this.csDOWGT().cspec_fixed_standard_parts().factor2 + this.csDOWGE() != null -> this.csDOWGE().cspec_fixed_standard_parts().factor2 + this.csDOWLT() != null -> this.csDOWLT().cspec_fixed_standard_parts().factor2 + this.csDOWLE() != null -> this.csDOWLE().cspec_fixed_standard_parts().factor2 else -> todo(conf = conf) } + val factor2Ast = factor2.toAstIfSymbolicConstant() ?: factor2.content.toAst(conf) + return DOWxxStmt( comparisonOperator = comparison, factor1 = this.factor1.content.toAst(conf = conf), - factor2 = factor2, + factor2 = factor2Ast, position = toPosition(conf.considerPosition), body = blockContext.statement().map { it.toAst(conf) } ) From 1db7f51fea22cd8cf993555ce1a415fe22234ed7 Mon Sep 17 00:00:00 2001 From: Domenico Mancini Date: Wed, 6 Mar 2024 15:01:28 +0100 Subject: [PATCH 231/423] Implemented StringValue comparison with BlanksValue --- .../main/kotlin/com/smeup/rpgparser/interpreter/values.kt | 6 ++++++ 1 file changed, 6 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 e645ad3e9..b61ccf908 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 @@ -198,9 +198,15 @@ data class StringValue(var value: String, val varying: Boolean = false) : Abstra return s1.compareTo(s2) } + fun compare(other: BlanksValue, charset: Charset?, descend: Boolean = false): Int { + require(charset != null) + return if (this.isBlank()) EQUAL else SMALLER + } + override operator fun compareTo(other: Value): Int = when (other) { is StringValue -> compare(other, DEFAULT_CHARSET) + is BlanksValue -> compare(other, DEFAULT_CHARSET) else -> super.compareTo(other) } From 98790666980996532c685d3915e4d06347775a69 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Wed, 6 Mar 2024 16:02:59 +0100 Subject: [PATCH 232/423] Implement the /EOF directive and create new MUTE tests for all use cases. --- .../parsing/facade/compilerDirectives.kt | 60 ++++++++++++++++--- .../smeup/rpgparser/parsing/facade/copy.kt | 2 +- .../evaluation/SmeupInterpreterTest.kt | 4 +- .../test/resources/QILEGEN/T70_A10_P0.rpgle | 5 ++ ...T70_A10_P01.rpgle => T70_A10_P01-05.rpgle} | 10 +++- 5 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/QILEGEN/T70_A10_P0.rpgle rename rpgJavaInterpreter-core/src/test/resources/smeup/{T70_A10_P01.rpgle => T70_A10_P01-05.rpgle} (84%) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt index 9e3c1f2f8..472110351 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt @@ -2,6 +2,9 @@ package com.smeup.rpgparser.parsing.facade import com.smeup.rpgparser.parsing.parsetreetoast.fireErrorEvent +/** + * Directives that can be used only under certain conditions (for example, an ELSE must always follow an IF)." + */ enum class SYN_RELEVANT_DIRECTIVES { NONE, IF_DEFINED, @@ -11,11 +14,16 @@ enum class SYN_RELEVANT_DIRECTIVES { } // List used to skip the resolution procedure when the source does not contain compiler directives. -val DIRECTIVES_KEYWORD = listOf(" /IF", +val DIRECTIVES_KEYWORDS = listOf( + " /IF DEFINED", + " /IF NOT DEFINED", " /DEFINE", " /UNDEFINE", " /ELSE", - " /ENDIF") + " /ENDIF" + ) + +val EOF_DIRECTIVE_KEYWORD = " /EOF" // Search patterns for identifying compiler directive rows. val IF_DEFINED_PATTERN = Regex(""".{6}/IF\sDEFINED\(([\w£$§,]+)\)$""", RegexOption.IGNORE_CASE) @@ -24,6 +32,33 @@ val DEFINE_PATTERN = Regex(""".{6}/DEFINE\s+([^\s]+)""", RegexOption.IGNORE_CASE val UNDEFINE_PATTERN = Regex(""".{6}/UNDEFINE\s+([^\s]+)""", RegexOption.IGNORE_CASE) val ELSE_PATTERN = Regex(""".{6}/ELSE""", RegexOption.IGNORE_CASE) val ENDIF_PATTERN = Regex(""".{6}/ENDIF""", RegexOption.IGNORE_CASE) +val EOF_PATTERN = Regex(""".{6}/EOF""", RegexOption.IGNORE_CASE) + +/** + * Resolve the EOF directive: after this directive, all rows are ignored until the end of the file. + * The resolution of this directive is separated from other directives because EOF resolution has + * to be managed during /COPY directive resolution and cannot be done after all /COPY directives + * are resolved. + */ +fun String.resolveEOFDirective(): String { + if (!this.contains(EOF_DIRECTIVE_KEYWORD, true)) { + return this + } + // Split input text into rows + val rows = this.lines() + var result = "" + for (row in rows) { + if (EOF_PATTERN.matches(row)) { + // Break loop if EOF found + break + } else { + if (row.length > 0) { + result += row.plus("\n") + } + } + } + return result +} fun String.resolveCompilerDirectives(): String { @@ -35,6 +70,7 @@ fun String.resolveCompilerDirectives(): String { var result = "" val definitions = mutableListOf() var useRow = true + var eofInvoked = false // Split input text into rows val rows = this.lines() @@ -53,7 +89,6 @@ fun String.resolveCompilerDirectives(): String { val matchResult = IF_DEFINED_PATTERN.matchEntire(row) val code = matchResult?.groups?.get(1)?.value if (code != null) { - useRow = isDefined(definitions, code) } } @@ -73,7 +108,7 @@ fun String.resolveCompilerDirectives(): String { } } DEFINE_PATTERN.matches(row) -> { - // Define is allways acceptable + // Define directive is always acceptable val matchResult = DEFINE_PATTERN.matchEntire(row) val code = matchResult?.groups?.get(1)?.value if (code != null) { @@ -81,7 +116,7 @@ fun String.resolveCompilerDirectives(): String { } } UNDEFINE_PATTERN.matches(row) -> { - // Undefine is allways acceptable + // Undefine directive is always acceptable val matchResult = UNDEFINE_PATTERN.matchEntire(row) val code = matchResult?.groups?.get(1)?.value if (code != null) { @@ -110,21 +145,30 @@ fun String.resolveCompilerDirectives(): String { lastCode = SYN_RELEVANT_DIRECTIVES.ENDIF useRow = true } + EOF_PATTERN.matches(row) -> { + eofInvoked = true + useRow = false + } else -> { if (useRow && row.length > 0) { result += row.plus("\n") } } } + // Exit loop if EOF invoked + if (eofInvoked) break } return result } private fun containDirectives(inputString: String): Boolean { - return DIRECTIVES_KEYWORD.any { keyword -> inputString.contains(keyword, ignoreCase = true) } + return inputString.contains(EOF_DIRECTIVE_KEYWORD, true) || DIRECTIVES_KEYWORDS.any { keyword -> inputString.contains(keyword, ignoreCase = true) } } -private fun isDefined(definitions: MutableList, lastIfCode: String) = - definitions.any { it.equals(lastIfCode.uppercase()) } +private fun isDefined(definitions: MutableList, code: String) = + /** + * Manage also "*VxRxMx" formats (return always true) + */ + code.startsWith("*V") || definitions.any { it.equals(code.uppercase()) } class CompilerDirectivesException(message: String) : Exception(message) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt index fee4782e6..1dd9a523e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/copy.kt @@ -67,7 +67,7 @@ fun String.includesCopy( onEndInclusion = onEndInclusion, beforeInclusion = beforeInclusion, currentLine = copyStartLine - )?.surroundWithPreprocessingAnnotations(copyId)?.apply { + )?.resolveEOFDirective()?.surroundWithPreprocessingAnnotations(copyId)?.apply { } ?: let { println("Copy ${matcher.group()} not found".yellow()) matcher.group() diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 0a4433adb..d53152a1a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -402,8 +402,8 @@ open class SmeupInterpreterTest : AbstractTest() { } @Test - fun executeT70_A10_P01() { - val outputOf = "smeup/T70_A10_P01".outputOf() + fun executeT70_A10_P01_05() { + val outputOf = "smeup/T70_A10_P01-05".outputOf() println(outputOf) assertTrue(outputOf.all { it.equals("PRINT") }) } diff --git a/rpgJavaInterpreter-core/src/test/resources/QILEGEN/T70_A10_P0.rpgle b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/T70_A10_P0.rpgle new file mode 100644 index 000000000..c52920c2e --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/T70_A10_P0.rpgle @@ -0,0 +1,5 @@ + C EVAL £DBG_Str='PRINT' + C £DBG_Str DSPLY + /EOF + C EVAL £DBG_Str='NOPRINT' + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01-05.rpgle similarity index 84% rename from rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle rename to rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01-05.rpgle index 2541d6a54..4fa2aa385 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T70_A10_P01-05.rpgle @@ -1,5 +1,14 @@ D £DBG_Str S 100 * + * TestImporting same COPY two times + * + /COPY QILEGEN,£PDS + /COPY QILEGEN,£PDS + * + * Test importing a /COPY with /EOF directive inside + * + /COPY QILEGEN,T70_A10_P0 + * * Test DEFINE and IF NOT DEFINED * /IF NOT DEFINED(DEFINE_1) @@ -40,4 +49,3 @@ C £DBG_Str DSPLY * C SETON LR - From 993e6a43b5618fd3832be0e6cbbf92858027f7dc Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 7 Mar 2024 09:57:13 +0100 Subject: [PATCH 233/423] Added rpgle tests --- .../src/test/resources/smeup/T10_A45_P01.rpgle | 9 +++++++++ .../src/test/resources/smeup/T10_A45_P02.rpgle | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P01.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P01.rpgle new file mode 100644 index 000000000..5d33a8784 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P01.rpgle @@ -0,0 +1,9 @@ + D A45_A10 C '0123456789' + D A45_A04 S 4 INZ(' ') + D A45_N10 S 1 0 + D £DBG_Str S 150 VARYING + + C EVAL A45_A04='2019' + C A45_A10 CHECK A45_A04 A45_N10 + C EVAL £DBG_Str='NUM('+%CHAR(A45_N10)+')' + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P02.rpgle new file mode 100644 index 000000000..8b67bb9f9 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P02.rpgle @@ -0,0 +1,9 @@ + D A45_A10 C '0123456789' + D A45_A04 S 4 INZ(' ') + D A45_N10 S 1 0 + D £DBG_Str S 150 VARYING + + C EVAL A45_A04='201A' + C A45_A10 CHECK A45_A04 A45_N10 + C EVAL £DBG_Str='NUM('+%CHAR(A45_N10)+')' + C £DBG_Str DSPLY \ No newline at end of file From 54c3dd4e67ec83d92a800b769a50831bec1d96ea Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 7 Mar 2024 10:03:39 +0100 Subject: [PATCH 234/423] Implemented test cases --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 50a07a060..fe22711bb 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -528,4 +528,16 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("KA(0)KB(0)KC(0)KD(0)KE(0)KF(0)KG(0)KH(0)KI(0)KJ(0)KK(0)KL(0)KM(0)KN(0)KP(0)KQ(0)KR(0)KS(0)KT(0)KU(0)KV(0)KW(0)KX(0)KY(0)") assertEquals(expected, "smeup/T60_A10_P01".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT10_A45_P01() { + val expected = listOf("NUM(0)") + assertEquals(expected, "smeup/T10_A45_P01".outputOf(configuration = smeupConfig)) + } + + @Test + fun executeT10_A45_P02() { + val expected = listOf("NUM(4)") + assertEquals(expected, "smeup/T10_A45_P02".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file From e5f0c49fc06e066bc55796a6c032666c59e8b2c7 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 7 Mar 2024 12:35:25 +0100 Subject: [PATCH 235/423] Added rpgle test case for CHECK with inline declarations --- .../src/test/resources/smeup/T10_A45_P03.rpgle | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P03.rpgle new file mode 100644 index 000000000..636ec77e1 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P03.rpgle @@ -0,0 +1,8 @@ + D £DBG_Str S 150 VARYING + D A45_A04 S 4 INZ(' ') + D A45_A10 C '0123456789' + + C EVAL A45_A04='201A' + C A45_A10 CHECK A45_A04 A45_N20 1 0 + C EVAL £DBG_Str='NUM('+%CHAR(A45_N20)+')' + C £DBG_Str DSPLY \ No newline at end of file From f594837d4ab5eb1241a5e469ff9ac0b8eb40e289 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 7 Mar 2024 12:35:43 +0100 Subject: [PATCH 236/423] Implemented test cases --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 50a07a060..e0a8e805d 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -528,4 +528,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("KA(0)KB(0)KC(0)KD(0)KE(0)KF(0)KG(0)KH(0)KI(0)KJ(0)KK(0)KL(0)KM(0)KN(0)KP(0)KQ(0)KR(0)KS(0)KT(0)KU(0)KV(0)KW(0)KX(0)KY(0)") assertEquals(expected, "smeup/T60_A10_P01".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT10_A45_P03() { + val expected = listOf("NUM(4)") + assertEquals(expected, "smeup/T10_A45_P03".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file From 464f5bc4418eddb21eb9a9ac82fbe7328354c4a5 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 7 Mar 2024 12:36:16 +0100 Subject: [PATCH 237/423] Make CheckStmt implement StatementThatCanDefineData --- .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 5 ++++- .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 4cc68b8e0..a16531f84 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -610,8 +610,9 @@ data class CheckStmt( val baseString: Expression, val start: Int = 1, val wrongCharPosition: AssignableExpression?, + @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null -) : Statement(position) { +) : Statement(position), StatementThatCanDefineData { override fun execute(interpreter: InterpreterCore) { var baseString = interpreter.eval(this.baseString).asString().value if (this.baseString is DataRefExpr) { @@ -633,6 +634,8 @@ data class CheckStmt( } } } + + override fun dataDefinition(): List = dataDefinition?.let { listOf(it) } ?: emptyList() } @Serializable diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 1c5215fa0..c3c06c2c3 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1335,11 +1335,16 @@ internal fun CsCHECKContext.toAst(conf: ToAstConfiguration): Statement { val position = toPosition(conf.considerPosition) val factor1 = this.factor1Context()?.content?.toAst(conf) ?: throw UnsupportedOperationException("CHECK operation requires factor 1: ${this.text} - ${position.atLine()}") val (expression, startPosition) = this.cspec_fixed_standard_parts().factor2.toIndexedExpression(conf) + + val result = this.cspec_fixed_standard_parts().result + val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result.text, position, conf) + return CheckStmt( factor1, expression, startPosition ?: 1, this.cspec_fixed_standard_parts()?.result?.toAst(conf), + dataDefinition, position ) } From 25996a3fd3ea060dadae3595e13be1a03744ab91 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 5 Mar 2024 16:00:19 +0100 Subject: [PATCH 238/423] Implemented MULANG_D_D rpgle file and fixed `T02_A50_Px` tests. --- .../test/resources/QILEGEN/MULANG_D_D.rpgle | 37 +++++++++++++++++++ .../test/resources/smeup/T02_A50_P08.rpgle | 7 +--- .../test/resources/smeup/T02_A50_P09.rpgle | 7 +--- 3 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/QILEGEN/MULANG_D_D.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/QILEGEN/MULANG_D_D.rpgle b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/MULANG_D_D.rpgle new file mode 100644 index 000000000..fd197bf88 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/MULANG_D_D.rpgle @@ -0,0 +1,37 @@ + *==================================================================== + * smeup V6R1.020DV + * Nome sorgente : MULANG_D_D + * Sorgente di origine : SMEUP_DEM/QILEGEN(MULANG_D_D) + * Esportato il : 20240305 144511 + *==================================================================== + V*===================================================================== + V* MODIFICHE Ril. T Au Descrizione + V* gg/mm/aa nn.mm i xx Breve descrizione + V*===================================================================== + V* 04/10/23 V6.R1 LS Creato + V* 30/11/26 005315 BERNI aggiunto campo a DS per gestione MDV + V* 30/11/23 V6R1 ARRSTE Merge 005315 in SMEUP_DEM + V* 04/12/23 DEM BUSFIO Modificate £DBG_Str e £DBG_O_Str in varying + V*===================================================================== + * Per registrazione dei dati di un passo + D £DBG_DS DS + D £DBG_Fun 10 Funzione + D £DBG_Pgm 10 Programma + D £DBG_Sez 10 Sezione + D £DBG_Pas 10 Passo + D £DBG_Str 2560 VARYING Stringa + D £DBG_Ind 99 Indicatori + D £DBG_Mdv 18 Gestione MDV + * Per chiamata dei passi singoli dove previsto + D £DBG_I_Fun S 10 Funzione chiamata + D £DBG_I_Num S 7 0 Numero esecuzioni + D £DBG_I_Par S 256 Parametri + D £DBG_O_Str S 2560 VARYING Risultato + D £DBG_O_Msg S 10 Messaggio + * + D £DBG_TIMINI S Z + D £DBG_TIMEND S Z + D £DBG_SAVSEZ S 10 + D £DBG_SAVSCHPGM S 7 0 DIM(10) + D £DBG_SAVINI S 1 + * diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle index 0c7fc3bb8..42c13a88a 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle @@ -1,13 +1,8 @@ - D £DBG_I_Fun S 10 Funzione chiamata - D £DBG_I_Num S 7 0 Numero esecuzioni - D £DBG_O_Str S 2560 VARYING Risultato - + /COPY QILEGEN,MULANG_D_D D A50_A81 S LIKE(£DBG_I_Fun) D A50_N81 S LIKE(£DBG_I_Num) D A50_V81 S LIKE(£DBG_O_Str) - D £DBG_Str S 150 VARYING - D* DS con overlay e campi definiti singolarmente C EVAL A50_A81='Funzione' C EVAL A50_N81=1234567 diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle index b8a10731f..351b1bba2 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle @@ -1,7 +1,4 @@ - D £DBG_I_Fun S 10 Funzione chiamata - D £DBG_I_Num S 7 0 Numero esecuzioni - D £DBG_O_Str S 2560 VARYING Risultato - + /COPY QILEGEN,MULANG_D_D D A50_A81 S LIKE(£DBG_I_Fun) D A50_N81 S LIKE(£DBG_I_Num) D A50_V81 S LIKE(£DBG_O_Str) @@ -10,8 +7,6 @@ D A50_N91 S LIKE(A50_N81) D A50_V91 S LIKE(A50_V81) - D £DBG_Str S 150 VARYING - D* DS con overlay e campi definiti singolarmente C EVAL A50_A91='Funzione' C EVAL A50_N91=1234567 From 6e426f99456795a10d1023c511cf417036b4555b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 7 Mar 2024 16:22:46 +0100 Subject: [PATCH 239/423] Fixed tests --- .../src/test/resources/smeup/T02_A50_P08.rpgle | 2 +- .../src/test/resources/smeup/T02_A50_P09.rpgle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle index 42c13a88a..827ce6964 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P08.rpgle @@ -1,7 +1,7 @@ - /COPY QILEGEN,MULANG_D_D D A50_A81 S LIKE(£DBG_I_Fun) D A50_N81 S LIKE(£DBG_I_Num) D A50_V81 S LIKE(£DBG_O_Str) + /COPY QILEGEN,MULANG_D_D D* DS con overlay e campi definiti singolarmente C EVAL A50_A81='Funzione' diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle index 351b1bba2..c17a22105 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P09.rpgle @@ -1,4 +1,3 @@ - /COPY QILEGEN,MULANG_D_D D A50_A81 S LIKE(£DBG_I_Fun) D A50_N81 S LIKE(£DBG_I_Num) D A50_V81 S LIKE(£DBG_O_Str) @@ -6,6 +5,7 @@ D A50_A91 S LIKE(A50_A81) D A50_N91 S LIKE(A50_N81) D A50_V91 S LIKE(A50_V81) + /COPY QILEGEN,MULANG_D_D D* DS con overlay e campi definiti singolarmente C EVAL A50_A91='Funzione' From 2c013425bc617eb3dcb20e1c6603875968c54368 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 7 Mar 2024 16:23:44 +0100 Subject: [PATCH 240/423] Applied the fix --- .../rpgparser/parsing/parsetreetoast/misc.kt | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 1c5215fa0..88c6386a1 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -99,6 +99,7 @@ private fun RContext.getDataDefinitions( // then we calculate the ones with the LIKE DS clause, as they could have references to DS declared // after them val dataDefinitionProviders: MutableList = LinkedList() + val statementsNotResolved: MutableList = LinkedList() val knownDataDefinitions = KnownDataDefinition.getInstance() fileDefinitions.values.flatten().toList().removeDuplicatedDataDefinition().forEach { @@ -134,6 +135,36 @@ private fun RContext.getDataDefinitions( } else -> null } + } + .onFailure { e -> statementsNotResolved.add(it) } + .getOrNull() + } + ) + // Third pass, everything, I mean everything but with statements not resolved + dataDefinitionProviders.addAll(statementsNotResolved + .mapNotNull { + kotlin.runCatching { + when { + it.dspec() != null -> { + it.dspec() + .toAst(conf, knownDataDefinitions.values.toList()) + .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) + } + it.dcl_c() != null -> { + it.dcl_c() + .toAst(conf) + .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) + } + it.dcl_ds() != null && it.dcl_ds().useLikeDs(conf) -> { + DataDefinitionCalculator(it.dcl_ds().toAstWithLikeDs(conf, dataDefinitionProviders)) + } + it.dcl_ds() != null && it.dcl_ds().useExtName() && fileDefinitions.keys.any { fileDefinition -> + fileDefinition.name.equals(it.dcl_ds().getKeywordExtName().getExtName(), ignoreCase = true) + } -> { + DataDefinitionCalculator(it.dcl_ds().toAstWithExtName(conf, fileDefinitions)) + } + else -> null + } }.getOrNull() } ) From afcdeef5b1770e97b9856ae16f30d4c24265f85f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 7 Mar 2024 16:33:42 +0100 Subject: [PATCH 241/423] Adjusted comment --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 88c6386a1..b561b37ab 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -140,7 +140,7 @@ private fun RContext.getDataDefinitions( .getOrNull() } ) - // Third pass, everything, I mean everything but with statements not resolved + // Third pass with statements not resolved dataDefinitionProviders.addAll(statementsNotResolved .mapNotNull { kotlin.runCatching { From 7e1044aec98da3b8a97928a816c50f7a0d5c803c Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 7 Mar 2024 17:02:44 +0100 Subject: [PATCH 242/423] Implemented removing of duplicates of ErrorEvents --- .../com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt index 7b0894df6..39ec765f8 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt @@ -506,10 +506,12 @@ class JarikoCallbackTest : AbstractTest() { }.onSuccess { Assert.fail("Program must exit with error") }.onFailure { + val distinctErrorEvents = errorEvents.distinctBy { it.error.message } + println(it.stackTraceToString()) - Assert.assertEquals(sourceReferenceType, errorEvents[0].sourceReference!!.sourceReferenceType) - Assert.assertEquals(sourceId, errorEvents[0].sourceReference!!.sourceId) - Assert.assertEquals(lines.sorted(), errorEvents.map { errorEvent -> errorEvent.sourceReference!!.relativeLine }.sorted()) + Assert.assertEquals(sourceReferenceType, distinctErrorEvents[0].sourceReference!!.sourceReferenceType) + Assert.assertEquals(sourceId, distinctErrorEvents[0].sourceReference!!.sourceId) + Assert.assertEquals(lines.sorted(), distinctErrorEvents.map { errorEvent -> errorEvent.sourceReference!!.relativeLine }.sorted()) } } From 294e0ceccbb97c76fd2588b88ffb065ea683e5db Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 8 Mar 2024 09:49:14 +0100 Subject: [PATCH 243/423] Implemented removing of duplicates of ErrorEvents on `compile_time_interpreter`, instead `JarikoCallbackTest` --- .../rpgparser/interpreter/compile_time_interpreter.kt | 7 ++++++- .../com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt | 8 +++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 95cb2fe00..19443150e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -185,7 +185,12 @@ open class BaseCompileTimeInterpreter( if (delegatedCompileTimeInterpreter != null) { return delegatedCompileTimeInterpreter.evaluateElementSizeOf(rContext, expression, conf) } else { - throw expression.error(message = e.message, cause = e) + val errorsExisting = getAstCreationErrors().filter { it is AstResolutionError }.firstOrNull() { it.cause?.message == e.message } + if (errorsExisting == null) { + throw expression.error(message = e.message, cause = e) + } + + throw e } } } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt index 39ec765f8..7b0894df6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt @@ -506,12 +506,10 @@ class JarikoCallbackTest : AbstractTest() { }.onSuccess { Assert.fail("Program must exit with error") }.onFailure { - val distinctErrorEvents = errorEvents.distinctBy { it.error.message } - println(it.stackTraceToString()) - Assert.assertEquals(sourceReferenceType, distinctErrorEvents[0].sourceReference!!.sourceReferenceType) - Assert.assertEquals(sourceId, distinctErrorEvents[0].sourceReference!!.sourceId) - Assert.assertEquals(lines.sorted(), distinctErrorEvents.map { errorEvent -> errorEvent.sourceReference!!.relativeLine }.sorted()) + Assert.assertEquals(sourceReferenceType, errorEvents[0].sourceReference!!.sourceReferenceType) + Assert.assertEquals(sourceId, errorEvents[0].sourceReference!!.sourceId) + Assert.assertEquals(lines.sorted(), errorEvents.map { errorEvent -> errorEvent.sourceReference!!.relativeLine }.sorted()) } } From 3c11c2eda5d353d02ff87a82fedfec57403cc89a Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 8 Mar 2024 09:50:07 +0100 Subject: [PATCH 244/423] Refactored `misc` to avoid duplicate blocks --- .../rpgparser/parsing/parsetreetoast/misc.kt | 88 +++++++++---------- 1 file changed, 40 insertions(+), 48 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index b561b37ab..a210ddefa 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -113,64 +113,56 @@ private fun RContext.getDataDefinitions( // Second pass, everything, I mean everything dataDefinitionProviders.addAll(this.statement() .mapNotNull { - kotlin.runCatching { - when { - it.dspec() != null -> { - it.dspec() - .toAst(conf, knownDataDefinitions.values.toList()) - .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) - } - it.dcl_c() != null -> { - it.dcl_c() - .toAst(conf) - .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) - } - it.dcl_ds() != null && it.dcl_ds().useLikeDs(conf) -> { - DataDefinitionCalculator(it.dcl_ds().toAstWithLikeDs(conf, dataDefinitionProviders)) - } - it.dcl_ds() != null && it.dcl_ds().useExtName() && fileDefinitions.keys.any { fileDefinition -> - fileDefinition.name.equals(it.dcl_ds().getKeywordExtName().getExtName(), ignoreCase = true) - } -> { - DataDefinitionCalculator(it.dcl_ds().toAstWithExtName(conf, fileDefinitions)) - } - else -> null - } - } - .onFailure { e -> statementsNotResolved.add(it) } - .getOrNull() + it.scanForDefinitions(conf, knownDataDefinitions, dataDefinitionProviders, fileDefinitions) + .onFailure { e -> statementsNotResolved.add(it) } + .getOrNull() } ) // Third pass with statements not resolved dataDefinitionProviders.addAll(statementsNotResolved .mapNotNull { - kotlin.runCatching { - when { - it.dspec() != null -> { - it.dspec() - .toAst(conf, knownDataDefinitions.values.toList()) - .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) - } - it.dcl_c() != null -> { - it.dcl_c() - .toAst(conf) - .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) - } - it.dcl_ds() != null && it.dcl_ds().useLikeDs(conf) -> { - DataDefinitionCalculator(it.dcl_ds().toAstWithLikeDs(conf, dataDefinitionProviders)) - } - it.dcl_ds() != null && it.dcl_ds().useExtName() && fileDefinitions.keys.any { fileDefinition -> - fileDefinition.name.equals(it.dcl_ds().getKeywordExtName().getExtName(), ignoreCase = true) - } -> { - DataDefinitionCalculator(it.dcl_ds().toAstWithExtName(conf, fileDefinitions)) - } - else -> null - } - }.getOrNull() + it.scanForDefinitions(conf, knownDataDefinitions, dataDefinitionProviders, fileDefinitions) + .getOrNull() } ) return dataDefinitionProviders.mapNotNull { kotlin.runCatching { it.toDataDefinition() }.getOrNull() } } +private fun StatementContext.scanForDefinitions( + conf: ToAstConfiguration, + knownDataDefinitions: MutableMap, + dataDefinitionProviders: MutableList, + fileDefinitions: Map> +): Result { + return runCatching { + when { + this.dspec() != null -> { + this.dspec() + .toAst(conf, knownDataDefinitions.values.toList()) + .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) + } + + this.dcl_c() != null -> { + this.dcl_c() + .toAst(conf) + .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) + } + + this.dcl_ds() != null && this.dcl_ds().useLikeDs(conf) -> { + DataDefinitionCalculator(this.dcl_ds().toAstWithLikeDs(conf, dataDefinitionProviders)) + } + + this.dcl_ds() != null && this.dcl_ds().useExtName() && fileDefinitions.keys.any { fileDefinition -> + fileDefinition.name.equals(this.dcl_ds().getKeywordExtName().getExtName(), ignoreCase = true) + } -> { + DataDefinitionCalculator(this.dcl_ds().toAstWithExtName(conf, fileDefinitions)) + } + + else -> null + } + } +} + private fun DataDefinition.updateKnownDataDefinitionsAndGetHolder( knownDataDefinitions: MutableMap ): DataDefinitionHolder { From 6a5d326b4529acbf43ee77968bc95044666e018b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 8 Mar 2024 10:02:14 +0100 Subject: [PATCH 245/423] Created test with cyclic dependency between main source and its dependency called in `copy` --- .../com/smeup/rpgparser/evaluation/InterpreterTest.kt | 6 ++++++ .../src/test/resources/LIKEWITHCOPY.rpgle | 5 +++++ .../src/test/resources/QILEGEN/LIKEWITHCOPY_DEP.rpgle | 2 ++ 3 files changed, 13 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/QILEGEN/LIKEWITHCOPY_DEP.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 73c302d56..53bf5b30b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2337,4 +2337,10 @@ Test 6 ) assertEquals(expected, "EVALVARSNUMS".outputOf()) } + + @Test + fun executeLIKEWITHCOPY() { + val expected = listOf("OK") + assertEquals(expected, "LIKEWITHCOPY".outputOf()) + } } diff --git a/rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY.rpgle b/rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY.rpgle new file mode 100644 index 000000000..08baf0829 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY.rpgle @@ -0,0 +1,5 @@ + D FOO S LIKE(BAR) + D BAZ S 2560 VARYING + /COPY QILEGEN,LIKEWITHCOPY_DEP + + C 'OK' DSPLY diff --git a/rpgJavaInterpreter-core/src/test/resources/QILEGEN/LIKEWITHCOPY_DEP.rpgle b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/LIKEWITHCOPY_DEP.rpgle new file mode 100644 index 000000000..b4e9ac3ff --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/QILEGEN/LIKEWITHCOPY_DEP.rpgle @@ -0,0 +1,2 @@ + D BAR S 2560 VARYING + D QUX S LIKE(BAZ) From 98e38b3a0670e3c4b5af82172d03eff8631df0ca Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 8 Mar 2024 10:55:06 +0100 Subject: [PATCH 246/423] Created new `LIKEWITHCOPY` test --- .../com/smeup/rpgparser/evaluation/InterpreterTest.kt | 10 ++++++++-- .../{LIKEWITHCOPY.rpgle => LIKEWITHCOPY1.rpgle} | 0 .../src/test/resources/LIKEWITHCOPY2.rpgle | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) rename rpgJavaInterpreter-core/src/test/resources/{LIKEWITHCOPY.rpgle => LIKEWITHCOPY1.rpgle} (100%) create mode 100644 rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY2.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt index 53bf5b30b..3cbfe8983 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/InterpreterTest.kt @@ -2339,8 +2339,14 @@ Test 6 } @Test - fun executeLIKEWITHCOPY() { + fun executeLIKEWITHCOPY1() { val expected = listOf("OK") - assertEquals(expected, "LIKEWITHCOPY".outputOf()) + assertEquals(expected, "LIKEWITHCOPY1".outputOf()) + } + + @Test + fun executeLIKEWITHCOPY2() { + val expected = listOf("OK") + assertEquals(expected, "LIKEWITHCOPY2".outputOf()) } } diff --git a/rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY.rpgle b/rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY1.rpgle similarity index 100% rename from rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY.rpgle rename to rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY1.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY2.rpgle b/rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY2.rpgle new file mode 100644 index 000000000..ebdaddfc8 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/LIKEWITHCOPY2.rpgle @@ -0,0 +1,5 @@ + /COPY QILEGEN,LIKEWITHCOPY_DEP + D FOO S LIKE(BAR) + D BAZ S 2560 VARYING + + C 'OK' DSPLY From 87b58ba5a1a243d6de0cb4965cd50eeabd68b5f6 Mon Sep 17 00:00:00 2001 From: "Sme.UP" Date: Fri, 8 Mar 2024 12:05:15 +0100 Subject: [PATCH 247/423] Update project CODEOWNERS Added Antonio Cosentino as code owner --- docs/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index bf28a2688..1e2ebff18 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -1,2 +1,2 @@ # default code owners -* marco.lanari@smeup.com marco.benetti@smeup.com mattiabonardi99@gmail.com fiorenza.busi@smeup.com \ No newline at end of file +* marco.lanari@smeup.com marco.benetti@smeup.com mattiabonardi99@gmail.com fiorenza.busi@smeup.com antonio.cosentino@smeup.com From 93d91b524428f9d5fd7456693cf4bc203d2b49e5 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 8 Mar 2024 12:50:23 +0100 Subject: [PATCH 248/423] Implemented case of test --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T02_A30_P04.rpgle | 13 +++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 50a07a060..89568eef0 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -528,4 +528,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("KA(0)KB(0)KC(0)KD(0)KE(0)KF(0)KG(0)KH(0)KI(0)KJ(0)KK(0)KL(0)KM(0)KN(0)KP(0)KQ(0)KR(0)KS(0)KT(0)KU(0)KV(0)KW(0)KX(0)KY(0)") assertEquals(expected, "smeup/T60_A10_P01".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT02_A30_P04() { + val expected = listOf("AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFF") + assertEquals(expected, "smeup/T02_A30_P04".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle new file mode 100644 index 000000000..3385890d8 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle @@ -0,0 +1,13 @@ + D A30_C04 C CONST(6) + D A30_AR4 S 20 DIM(A30_C04) + D £DBG_Str S 150 VARYING + + C EVAL A30_AR4(01) = 'AAAAAAAAAAAAAAAAAAAA' + C EVAL A30_AR4(02) = 'BBBBBBBBBBBBBBBBBBBB' + C EVAL A30_AR4(03) = 'CCCCCCCCCCCCCCCCCCCC' + C EVAL A30_AR4(04) = 'DDDDDDDDDDDDDDDDDDDD' + C EVAL A30_AR4(05) = 'EEEEEEEEEEEEEEEEEEEE' + C EVAL A30_AR4(06) = 'FFFFFFFFFFFFFFFFFFFF' + c EVAL £DBG_Str=A30_AR4(01)+A30_AR4(02)+A30_AR4(03) + C +A30_AR4(04)+A30_AR4(05)+A30_AR4(06) + C £DBG_Str DSPLY From f5956bbce5669b9893ccc8d179e4647b19cc8c51 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 8 Mar 2024 14:16:09 +0100 Subject: [PATCH 249/423] Little fix of test --- .../src/test/resources/smeup/T02_A30_P04.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle index 3385890d8..b5a81cb8e 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle @@ -8,6 +8,6 @@ C EVAL A30_AR4(04) = 'DDDDDDDDDDDDDDDDDDDD' C EVAL A30_AR4(05) = 'EEEEEEEEEEEEEEEEEEEE' C EVAL A30_AR4(06) = 'FFFFFFFFFFFFFFFFFFFF' - c EVAL £DBG_Str=A30_AR4(01)+A30_AR4(02)+A30_AR4(03) + C EVAL £DBG_Str=A30_AR4(01)+A30_AR4(02)+A30_AR4(03) C +A30_AR4(04)+A30_AR4(05)+A30_AR4(06) C £DBG_Str DSPLY From c8704bedda96535ba6564c174b0c89af9462f0b7 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 8 Mar 2024 14:20:42 +0100 Subject: [PATCH 250/423] Fixed the problem in compile time --- .../rpgparser/interpreter/compile_time_interpreter.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 95cb2fe00..cbf2b1577 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -23,6 +23,7 @@ import com.smeup.rpgparser.parsing.ast.* import com.smeup.rpgparser.parsing.facade.findAllDescendants import com.smeup.rpgparser.parsing.parsetreetoast.* import com.smeup.rpgparser.utils.asInt +import com.strumenta.kolasu.model.tryToResolve /** * This is a very limited interpreter used at compile time, mainly @@ -74,6 +75,14 @@ open class BaseCompileTimeInterpreter( is NumberOfElementsExpr -> IntValue(evaluateNumberOfElementsOf(rContext, expression.value).toLong()) is IntLiteral -> IntValue(expression.value) is StringLiteral -> StringValue(expression.value) + is DataRefExpr -> { + expression.variable.tryToResolve(knownDataDefinitions) + if (expression.variable.referred != null) { + return this.evaluate(rContext, (expression.variable.referred as? DataDefinition)?.initializationValue as Expression) + } + + TODO(expression.toString()) + } else -> TODO(expression.toString()) } } From 805e3e575f7cffd6a8ddf1be0f3221d6e5e9920d Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 8 Mar 2024 15:24:06 +0100 Subject: [PATCH 251/423] Add test cases --- .../src/main/antlr/RpgLexer.g4 | 1 + .../src/main/antlr/RpgLexer.tokens | 171 +++++++++--------- .../src/main/antlr/RpgParser.g4 | 2 +- .../evaluation/SmeupInterpreterTest.kt | 8 + .../test/resources/smeup/T10_A20_P51.rpgle | 32 ++++ 5 files changed, 128 insertions(+), 86 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 index f4f6a0628..72e3f3147 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 @@ -1171,6 +1171,7 @@ CS_FactorContent: (~[\r\n' :] || (getCharPositionInLine()>=36 && getCharPositionInLine()<=49) }? )+; +CS_FactorContentArrayIndexing: (CS_ResultContent | CS_FactorContent) WS* OPEN_PAREN (CS_ResultContent | CS_FactorContent) CLOSE_PAREN {setText(getText().replace(" ", ""));}; CS_ResultContent: (~[\r\n' :] {(getCharPositionInLine()>=50 && getCharPositionInLine()<=63)}? )+ -> type(CS_FactorContent); diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens index 7752ce687..c24a2bfba 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens @@ -672,90 +672,91 @@ CS_BlankFactor=671 CS_FactorWs=672 CS_FactorWs2=673 CS_FactorContent=674 -CS_OperationAndExtender_Blank=675 -CS_OperationAndExtender_WS=676 -CS_OperationAndExtender=677 -CS_FieldLength=678 -CS_DecimalPositions=679 -CS_WhiteSpace=680 -CS_Comments=681 -CS_FixedComments=682 -CS_FixedOperationAndExtender_WS=683 -CS_FixedOperationExtenderReturn=684 -CS_FixedOperationAndExtender2_WS=685 -CS_FixedOperationExtender2Return=686 -FreeOpExtender_Any=687 -FreeOpExtender2_WS=688 -BlankFlag=689 -NoFlag=690 -BlankIndicator=691 -GeneralIndicator=692 -FunctionKeyIndicator=693 -ControlLevelIndicator=694 -ControlLevel0Indicator=695 -LastRecordIndicator=696 -MatchingRecordIndicator=697 -HaltIndicator=698 -ReturnIndicator=699 -ExternalIndicator=700 -OverflowIndicator=701 -SubroutineIndicator=702 -AndIndicator=703 -OrIndicator=704 -DoubleSplatIndicator=705 -FirstPageIndicator=706 -OtherTextIndicator=707 -NewLineIndicator=708 -CSQL_EMPTY_TEXT=709 -CSQL_TEXT=710 -CSQL_LEADBLANK=711 -CSQL_LEADWS=712 -CSQL_END=713 -CSQL_CONT=714 -CSQL_CSplat=715 -CSQL_EOL=716 -CSQL_Any=717 -CSQLC_LEADWS=718 -CSQLC_CSplat=719 -CSQLC_WS=720 -CSQLC_Comments=721 -CSQLC_Any=722 -C2_FACTOR2_CONT=723 -C2_FACTOR2=724 -C2_OTHER=725 -IS_FileName=726 -IS_FieldReserved=727 -IS_ExtFieldReserved=728 -IS_LogicalRelationship=729 -IS_ExtRecordReserved=730 -IS_Sequence=731 -IS_Number=732 -IS_Option=733 -IS_RecordIdCode=734 -IS_WS=735 -IS_COMMENTS=736 -IF_Name=737 -IF_Reserved=738 -IF_FieldName=739 -IF_Reserved2=740 -IF_WS=741 -IR_WS=742 -IFD_DATA_ATTR=743 -IFD_DATETIME_SEP=744 -IFD_DATA_FORMAT=745 -IFD_FIELD_LOCATION=746 -IFD_DECIMAL_POSITIONS=747 -IFD_FIELD_NAME=748 -IFD_CONTROL_LEVEL=749 -IFD_MATCHING_FIELDS=750 -IFD_BLANKS=751 -IFD_COMMENTS=752 -HS_DECEDIT=753 -HS_NEW=754 -HS_CALLER=755 -HS_ACTGRP=756 -HS_WhiteSpace=757 -HS_CONTINUATION=758 +CS_FactorContentArrayIndexing=675 +CS_OperationAndExtender_Blank=676 +CS_OperationAndExtender_WS=677 +CS_OperationAndExtender=678 +CS_FieldLength=679 +CS_DecimalPositions=680 +CS_WhiteSpace=681 +CS_Comments=682 +CS_FixedComments=683 +CS_FixedOperationAndExtender_WS=684 +CS_FixedOperationExtenderReturn=685 +CS_FixedOperationAndExtender2_WS=686 +CS_FixedOperationExtender2Return=687 +FreeOpExtender_Any=688 +FreeOpExtender2_WS=689 +BlankFlag=690 +NoFlag=691 +BlankIndicator=692 +GeneralIndicator=693 +FunctionKeyIndicator=694 +ControlLevelIndicator=695 +ControlLevel0Indicator=696 +LastRecordIndicator=697 +MatchingRecordIndicator=698 +HaltIndicator=699 +ReturnIndicator=700 +ExternalIndicator=701 +OverflowIndicator=702 +SubroutineIndicator=703 +AndIndicator=704 +OrIndicator=705 +DoubleSplatIndicator=706 +FirstPageIndicator=707 +OtherTextIndicator=708 +NewLineIndicator=709 +CSQL_EMPTY_TEXT=710 +CSQL_TEXT=711 +CSQL_LEADBLANK=712 +CSQL_LEADWS=713 +CSQL_END=714 +CSQL_CONT=715 +CSQL_CSplat=716 +CSQL_EOL=717 +CSQL_Any=718 +CSQLC_LEADWS=719 +CSQLC_CSplat=720 +CSQLC_WS=721 +CSQLC_Comments=722 +CSQLC_Any=723 +C2_FACTOR2_CONT=724 +C2_FACTOR2=725 +C2_OTHER=726 +IS_FileName=727 +IS_FieldReserved=728 +IS_ExtFieldReserved=729 +IS_LogicalRelationship=730 +IS_ExtRecordReserved=731 +IS_Sequence=732 +IS_Number=733 +IS_Option=734 +IS_RecordIdCode=735 +IS_WS=736 +IS_COMMENTS=737 +IF_Name=738 +IF_Reserved=739 +IF_FieldName=740 +IF_Reserved2=741 +IF_WS=742 +IR_WS=743 +IFD_DATA_ATTR=744 +IFD_DATETIME_SEP=745 +IFD_DATA_FORMAT=746 +IFD_FIELD_LOCATION=747 +IFD_DECIMAL_POSITIONS=748 +IFD_FIELD_NAME=749 +IFD_CONTROL_LEVEL=750 +IFD_MATCHING_FIELDS=751 +IFD_BLANKS=752 +IFD_COMMENTS=753 +HS_DECEDIT=754 +HS_NEW=755 +HS_CALLER=756 +HS_ACTGRP=757 +HS_WhiteSpace=758 +HS_CONTINUATION=759 '('=20 ')'=21 ';'=23 @@ -778,4 +779,4 @@ HS_CONTINUATION=758 ' '=610 ' '=661 ' '=671 -' '=675 +' '=676 diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index d49ab3711..c94e52bc6 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -1737,7 +1737,7 @@ factorContent: CS_FactorContent | literal; resultType: - CS_FactorContent (COLON (constant=symbolicConstants))? | CS_BlankFactor; + (CS_FactorContentArrayIndexing | CS_FactorContent) (COLON (constant=symbolicConstants))? | CS_BlankFactor; cs_fixed_comments:CS_FixedComments; //cs_fixed_x2: CS_OperationAndExtendedFactor2 C2_FACTOR2_CONT* C2_FACTOR2 C_EOL; cspec_fixed_x2: diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 5383421dd..9d571c2ca 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -2,6 +2,7 @@ package com.smeup.rpgparser.evaluation import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.AbstractTest +import com.smeup.rpgparser.assertCanBeParsed import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig @@ -546,4 +547,11 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("NUM(4)") assertEquals(expected, "smeup/T10_A45_P03".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT10_A20_P51() { + assertCanBeParsed("smeup/T10_A20_P51", printTree = true) + val expected = listOf("Res(21, -19, 20, 2, 20, -20)") + assertEquals(expected, "smeup/T10_A20_P51".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle new file mode 100644 index 000000000..9b71c984e --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle @@ -0,0 +1,32 @@ + D £DBG_Str S 150 VARYING + D A20_N60 S 6 0 + D A20_AR2 S 2 0 DIM(6) + D A20I S 2 0 + + C EVAL A20_N60=20 + C EVAL A20_AR2(1)=1 + C EVAL A20_AR2(2)=1 + C EVAL A20_AR2(3)=1 + C EVAL A20_AR2(4)=40 + C EVAL A20_AR2(5)=20 + C EVAL A20_AR2(6)=20 + C EVAL A20I=1 + C ADD A20_N60 A20_AR2 (A20I) + C EVAL A20I=2 + C SUB A20_N60 A20_AR2 (A20I) + C EVAL A20I=3 + C MULT A20_N60 A20_AR2 (A20I) + C EVAL A20I=4 + C DIV A20_N60 A20_AR2 (A20I) + C EVAL A20I=5 + C Z-ADD A20_N60 A20_AR2 (A20I) + C EVAL A20I=6 + C Z-SUB A20_N60 A20_AR2 (A20I) + C EVAL £DBG_Str='Res(' + C +%CHAR(A20_AR2(1))+', ' + C +%CHAR(A20_AR2(2))+', ' + C +%CHAR(A20_AR2(3))+', ' + C +%CHAR(A20_AR2(4))+', ' + C +%CHAR(A20_AR2(5))+', ' + C +%CHAR(A20_AR2(6))+')' + C £DBG_Str DSPLY \ No newline at end of file From c8020c1ced0f1f755011d7417841d9a943b40817 Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 8 Mar 2024 15:24:34 +0100 Subject: [PATCH 252/423] Revert "Add test cases" This reverts commit 805e3e575f7cffd6a8ddf1be0f3221d6e5e9920d. --- .../src/main/antlr/RpgLexer.g4 | 1 - .../src/main/antlr/RpgLexer.tokens | 171 +++++++++--------- .../src/main/antlr/RpgParser.g4 | 2 +- .../evaluation/SmeupInterpreterTest.kt | 8 - .../test/resources/smeup/T10_A20_P51.rpgle | 32 ---- 5 files changed, 86 insertions(+), 128 deletions(-) delete mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 index 72e3f3147..f4f6a0628 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 @@ -1171,7 +1171,6 @@ CS_FactorContent: (~[\r\n' :] || (getCharPositionInLine()>=36 && getCharPositionInLine()<=49) }? )+; -CS_FactorContentArrayIndexing: (CS_ResultContent | CS_FactorContent) WS* OPEN_PAREN (CS_ResultContent | CS_FactorContent) CLOSE_PAREN {setText(getText().replace(" ", ""));}; CS_ResultContent: (~[\r\n' :] {(getCharPositionInLine()>=50 && getCharPositionInLine()<=63)}? )+ -> type(CS_FactorContent); diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens index c24a2bfba..7752ce687 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens @@ -672,91 +672,90 @@ CS_BlankFactor=671 CS_FactorWs=672 CS_FactorWs2=673 CS_FactorContent=674 -CS_FactorContentArrayIndexing=675 -CS_OperationAndExtender_Blank=676 -CS_OperationAndExtender_WS=677 -CS_OperationAndExtender=678 -CS_FieldLength=679 -CS_DecimalPositions=680 -CS_WhiteSpace=681 -CS_Comments=682 -CS_FixedComments=683 -CS_FixedOperationAndExtender_WS=684 -CS_FixedOperationExtenderReturn=685 -CS_FixedOperationAndExtender2_WS=686 -CS_FixedOperationExtender2Return=687 -FreeOpExtender_Any=688 -FreeOpExtender2_WS=689 -BlankFlag=690 -NoFlag=691 -BlankIndicator=692 -GeneralIndicator=693 -FunctionKeyIndicator=694 -ControlLevelIndicator=695 -ControlLevel0Indicator=696 -LastRecordIndicator=697 -MatchingRecordIndicator=698 -HaltIndicator=699 -ReturnIndicator=700 -ExternalIndicator=701 -OverflowIndicator=702 -SubroutineIndicator=703 -AndIndicator=704 -OrIndicator=705 -DoubleSplatIndicator=706 -FirstPageIndicator=707 -OtherTextIndicator=708 -NewLineIndicator=709 -CSQL_EMPTY_TEXT=710 -CSQL_TEXT=711 -CSQL_LEADBLANK=712 -CSQL_LEADWS=713 -CSQL_END=714 -CSQL_CONT=715 -CSQL_CSplat=716 -CSQL_EOL=717 -CSQL_Any=718 -CSQLC_LEADWS=719 -CSQLC_CSplat=720 -CSQLC_WS=721 -CSQLC_Comments=722 -CSQLC_Any=723 -C2_FACTOR2_CONT=724 -C2_FACTOR2=725 -C2_OTHER=726 -IS_FileName=727 -IS_FieldReserved=728 -IS_ExtFieldReserved=729 -IS_LogicalRelationship=730 -IS_ExtRecordReserved=731 -IS_Sequence=732 -IS_Number=733 -IS_Option=734 -IS_RecordIdCode=735 -IS_WS=736 -IS_COMMENTS=737 -IF_Name=738 -IF_Reserved=739 -IF_FieldName=740 -IF_Reserved2=741 -IF_WS=742 -IR_WS=743 -IFD_DATA_ATTR=744 -IFD_DATETIME_SEP=745 -IFD_DATA_FORMAT=746 -IFD_FIELD_LOCATION=747 -IFD_DECIMAL_POSITIONS=748 -IFD_FIELD_NAME=749 -IFD_CONTROL_LEVEL=750 -IFD_MATCHING_FIELDS=751 -IFD_BLANKS=752 -IFD_COMMENTS=753 -HS_DECEDIT=754 -HS_NEW=755 -HS_CALLER=756 -HS_ACTGRP=757 -HS_WhiteSpace=758 -HS_CONTINUATION=759 +CS_OperationAndExtender_Blank=675 +CS_OperationAndExtender_WS=676 +CS_OperationAndExtender=677 +CS_FieldLength=678 +CS_DecimalPositions=679 +CS_WhiteSpace=680 +CS_Comments=681 +CS_FixedComments=682 +CS_FixedOperationAndExtender_WS=683 +CS_FixedOperationExtenderReturn=684 +CS_FixedOperationAndExtender2_WS=685 +CS_FixedOperationExtender2Return=686 +FreeOpExtender_Any=687 +FreeOpExtender2_WS=688 +BlankFlag=689 +NoFlag=690 +BlankIndicator=691 +GeneralIndicator=692 +FunctionKeyIndicator=693 +ControlLevelIndicator=694 +ControlLevel0Indicator=695 +LastRecordIndicator=696 +MatchingRecordIndicator=697 +HaltIndicator=698 +ReturnIndicator=699 +ExternalIndicator=700 +OverflowIndicator=701 +SubroutineIndicator=702 +AndIndicator=703 +OrIndicator=704 +DoubleSplatIndicator=705 +FirstPageIndicator=706 +OtherTextIndicator=707 +NewLineIndicator=708 +CSQL_EMPTY_TEXT=709 +CSQL_TEXT=710 +CSQL_LEADBLANK=711 +CSQL_LEADWS=712 +CSQL_END=713 +CSQL_CONT=714 +CSQL_CSplat=715 +CSQL_EOL=716 +CSQL_Any=717 +CSQLC_LEADWS=718 +CSQLC_CSplat=719 +CSQLC_WS=720 +CSQLC_Comments=721 +CSQLC_Any=722 +C2_FACTOR2_CONT=723 +C2_FACTOR2=724 +C2_OTHER=725 +IS_FileName=726 +IS_FieldReserved=727 +IS_ExtFieldReserved=728 +IS_LogicalRelationship=729 +IS_ExtRecordReserved=730 +IS_Sequence=731 +IS_Number=732 +IS_Option=733 +IS_RecordIdCode=734 +IS_WS=735 +IS_COMMENTS=736 +IF_Name=737 +IF_Reserved=738 +IF_FieldName=739 +IF_Reserved2=740 +IF_WS=741 +IR_WS=742 +IFD_DATA_ATTR=743 +IFD_DATETIME_SEP=744 +IFD_DATA_FORMAT=745 +IFD_FIELD_LOCATION=746 +IFD_DECIMAL_POSITIONS=747 +IFD_FIELD_NAME=748 +IFD_CONTROL_LEVEL=749 +IFD_MATCHING_FIELDS=750 +IFD_BLANKS=751 +IFD_COMMENTS=752 +HS_DECEDIT=753 +HS_NEW=754 +HS_CALLER=755 +HS_ACTGRP=756 +HS_WhiteSpace=757 +HS_CONTINUATION=758 '('=20 ')'=21 ';'=23 @@ -779,4 +778,4 @@ HS_CONTINUATION=759 ' '=610 ' '=661 ' '=671 -' '=676 +' '=675 diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index c94e52bc6..d49ab3711 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -1737,7 +1737,7 @@ factorContent: CS_FactorContent | literal; resultType: - (CS_FactorContentArrayIndexing | CS_FactorContent) (COLON (constant=symbolicConstants))? | CS_BlankFactor; + CS_FactorContent (COLON (constant=symbolicConstants))? | CS_BlankFactor; cs_fixed_comments:CS_FixedComments; //cs_fixed_x2: CS_OperationAndExtendedFactor2 C2_FACTOR2_CONT* C2_FACTOR2 C_EOL; cspec_fixed_x2: diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 9d571c2ca..5383421dd 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -2,7 +2,6 @@ package com.smeup.rpgparser.evaluation import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.AbstractTest -import com.smeup.rpgparser.assertCanBeParsed import com.smeup.rpgparser.execution.Configuration import com.smeup.rpgparser.execution.ReloadConfig import com.smeup.rpgparser.execution.SimpleReloadConfig @@ -547,11 +546,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("NUM(4)") assertEquals(expected, "smeup/T10_A45_P03".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT10_A20_P51() { - assertCanBeParsed("smeup/T10_A20_P51", printTree = true) - val expected = listOf("Res(21, -19, 20, 2, 20, -20)") - assertEquals(expected, "smeup/T10_A20_P51".outputOf(configuration = smeupConfig)) - } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle deleted file mode 100644 index 9b71c984e..000000000 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle +++ /dev/null @@ -1,32 +0,0 @@ - D £DBG_Str S 150 VARYING - D A20_N60 S 6 0 - D A20_AR2 S 2 0 DIM(6) - D A20I S 2 0 - - C EVAL A20_N60=20 - C EVAL A20_AR2(1)=1 - C EVAL A20_AR2(2)=1 - C EVAL A20_AR2(3)=1 - C EVAL A20_AR2(4)=40 - C EVAL A20_AR2(5)=20 - C EVAL A20_AR2(6)=20 - C EVAL A20I=1 - C ADD A20_N60 A20_AR2 (A20I) - C EVAL A20I=2 - C SUB A20_N60 A20_AR2 (A20I) - C EVAL A20I=3 - C MULT A20_N60 A20_AR2 (A20I) - C EVAL A20I=4 - C DIV A20_N60 A20_AR2 (A20I) - C EVAL A20I=5 - C Z-ADD A20_N60 A20_AR2 (A20I) - C EVAL A20I=6 - C Z-SUB A20_N60 A20_AR2 (A20I) - C EVAL £DBG_Str='Res(' - C +%CHAR(A20_AR2(1))+', ' - C +%CHAR(A20_AR2(2))+', ' - C +%CHAR(A20_AR2(3))+', ' - C +%CHAR(A20_AR2(4))+', ' - C +%CHAR(A20_AR2(5))+', ' - C +%CHAR(A20_AR2(6))+')' - C £DBG_Str DSPLY \ No newline at end of file From 215052f3d7fe7455b010384497ae1b1c459531d8 Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 8 Mar 2024 15:28:00 +0100 Subject: [PATCH 253/423] Add test cases --- .../evaluation/SmeupInterpreterTest.kt | 6 ++++ .../test/resources/smeup/T10_A20_P51.rpgle | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 5383421dd..fc92cab9a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -546,4 +546,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("NUM(4)") assertEquals(expected, "smeup/T10_A45_P03".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT10_A20_P51() { + val expected = listOf("Res(21, -19, 20, 2, 20, -20)") + assertEquals(expected, "smeup/T10_A20_P51".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle new file mode 100644 index 000000000..9b71c984e --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P51.rpgle @@ -0,0 +1,32 @@ + D £DBG_Str S 150 VARYING + D A20_N60 S 6 0 + D A20_AR2 S 2 0 DIM(6) + D A20I S 2 0 + + C EVAL A20_N60=20 + C EVAL A20_AR2(1)=1 + C EVAL A20_AR2(2)=1 + C EVAL A20_AR2(3)=1 + C EVAL A20_AR2(4)=40 + C EVAL A20_AR2(5)=20 + C EVAL A20_AR2(6)=20 + C EVAL A20I=1 + C ADD A20_N60 A20_AR2 (A20I) + C EVAL A20I=2 + C SUB A20_N60 A20_AR2 (A20I) + C EVAL A20I=3 + C MULT A20_N60 A20_AR2 (A20I) + C EVAL A20I=4 + C DIV A20_N60 A20_AR2 (A20I) + C EVAL A20I=5 + C Z-ADD A20_N60 A20_AR2 (A20I) + C EVAL A20I=6 + C Z-SUB A20_N60 A20_AR2 (A20I) + C EVAL £DBG_Str='Res(' + C +%CHAR(A20_AR2(1))+', ' + C +%CHAR(A20_AR2(2))+', ' + C +%CHAR(A20_AR2(3))+', ' + C +%CHAR(A20_AR2(4))+', ' + C +%CHAR(A20_AR2(5))+', ' + C +%CHAR(A20_AR2(6))+')' + C £DBG_Str DSPLY \ No newline at end of file From 3e9523fae14a2ebefa46c98420a570e438a165c1 Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 8 Mar 2024 15:28:24 +0100 Subject: [PATCH 254/423] Update grammar to support array indexing with spaces --- .../src/main/antlr/RpgLexer.g4 | 1 + .../src/main/antlr/RpgLexer.tokens | 171 +++++++++--------- .../src/main/antlr/RpgParser.g4 | 2 +- 3 files changed, 88 insertions(+), 86 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 index f4f6a0628..72e3f3147 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 @@ -1171,6 +1171,7 @@ CS_FactorContent: (~[\r\n' :] || (getCharPositionInLine()>=36 && getCharPositionInLine()<=49) }? )+; +CS_FactorContentArrayIndexing: (CS_ResultContent | CS_FactorContent) WS* OPEN_PAREN (CS_ResultContent | CS_FactorContent) CLOSE_PAREN {setText(getText().replace(" ", ""));}; CS_ResultContent: (~[\r\n' :] {(getCharPositionInLine()>=50 && getCharPositionInLine()<=63)}? )+ -> type(CS_FactorContent); diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens index 7752ce687..c24a2bfba 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens @@ -672,90 +672,91 @@ CS_BlankFactor=671 CS_FactorWs=672 CS_FactorWs2=673 CS_FactorContent=674 -CS_OperationAndExtender_Blank=675 -CS_OperationAndExtender_WS=676 -CS_OperationAndExtender=677 -CS_FieldLength=678 -CS_DecimalPositions=679 -CS_WhiteSpace=680 -CS_Comments=681 -CS_FixedComments=682 -CS_FixedOperationAndExtender_WS=683 -CS_FixedOperationExtenderReturn=684 -CS_FixedOperationAndExtender2_WS=685 -CS_FixedOperationExtender2Return=686 -FreeOpExtender_Any=687 -FreeOpExtender2_WS=688 -BlankFlag=689 -NoFlag=690 -BlankIndicator=691 -GeneralIndicator=692 -FunctionKeyIndicator=693 -ControlLevelIndicator=694 -ControlLevel0Indicator=695 -LastRecordIndicator=696 -MatchingRecordIndicator=697 -HaltIndicator=698 -ReturnIndicator=699 -ExternalIndicator=700 -OverflowIndicator=701 -SubroutineIndicator=702 -AndIndicator=703 -OrIndicator=704 -DoubleSplatIndicator=705 -FirstPageIndicator=706 -OtherTextIndicator=707 -NewLineIndicator=708 -CSQL_EMPTY_TEXT=709 -CSQL_TEXT=710 -CSQL_LEADBLANK=711 -CSQL_LEADWS=712 -CSQL_END=713 -CSQL_CONT=714 -CSQL_CSplat=715 -CSQL_EOL=716 -CSQL_Any=717 -CSQLC_LEADWS=718 -CSQLC_CSplat=719 -CSQLC_WS=720 -CSQLC_Comments=721 -CSQLC_Any=722 -C2_FACTOR2_CONT=723 -C2_FACTOR2=724 -C2_OTHER=725 -IS_FileName=726 -IS_FieldReserved=727 -IS_ExtFieldReserved=728 -IS_LogicalRelationship=729 -IS_ExtRecordReserved=730 -IS_Sequence=731 -IS_Number=732 -IS_Option=733 -IS_RecordIdCode=734 -IS_WS=735 -IS_COMMENTS=736 -IF_Name=737 -IF_Reserved=738 -IF_FieldName=739 -IF_Reserved2=740 -IF_WS=741 -IR_WS=742 -IFD_DATA_ATTR=743 -IFD_DATETIME_SEP=744 -IFD_DATA_FORMAT=745 -IFD_FIELD_LOCATION=746 -IFD_DECIMAL_POSITIONS=747 -IFD_FIELD_NAME=748 -IFD_CONTROL_LEVEL=749 -IFD_MATCHING_FIELDS=750 -IFD_BLANKS=751 -IFD_COMMENTS=752 -HS_DECEDIT=753 -HS_NEW=754 -HS_CALLER=755 -HS_ACTGRP=756 -HS_WhiteSpace=757 -HS_CONTINUATION=758 +CS_FactorContentArrayIndexing=675 +CS_OperationAndExtender_Blank=676 +CS_OperationAndExtender_WS=677 +CS_OperationAndExtender=678 +CS_FieldLength=679 +CS_DecimalPositions=680 +CS_WhiteSpace=681 +CS_Comments=682 +CS_FixedComments=683 +CS_FixedOperationAndExtender_WS=684 +CS_FixedOperationExtenderReturn=685 +CS_FixedOperationAndExtender2_WS=686 +CS_FixedOperationExtender2Return=687 +FreeOpExtender_Any=688 +FreeOpExtender2_WS=689 +BlankFlag=690 +NoFlag=691 +BlankIndicator=692 +GeneralIndicator=693 +FunctionKeyIndicator=694 +ControlLevelIndicator=695 +ControlLevel0Indicator=696 +LastRecordIndicator=697 +MatchingRecordIndicator=698 +HaltIndicator=699 +ReturnIndicator=700 +ExternalIndicator=701 +OverflowIndicator=702 +SubroutineIndicator=703 +AndIndicator=704 +OrIndicator=705 +DoubleSplatIndicator=706 +FirstPageIndicator=707 +OtherTextIndicator=708 +NewLineIndicator=709 +CSQL_EMPTY_TEXT=710 +CSQL_TEXT=711 +CSQL_LEADBLANK=712 +CSQL_LEADWS=713 +CSQL_END=714 +CSQL_CONT=715 +CSQL_CSplat=716 +CSQL_EOL=717 +CSQL_Any=718 +CSQLC_LEADWS=719 +CSQLC_CSplat=720 +CSQLC_WS=721 +CSQLC_Comments=722 +CSQLC_Any=723 +C2_FACTOR2_CONT=724 +C2_FACTOR2=725 +C2_OTHER=726 +IS_FileName=727 +IS_FieldReserved=728 +IS_ExtFieldReserved=729 +IS_LogicalRelationship=730 +IS_ExtRecordReserved=731 +IS_Sequence=732 +IS_Number=733 +IS_Option=734 +IS_RecordIdCode=735 +IS_WS=736 +IS_COMMENTS=737 +IF_Name=738 +IF_Reserved=739 +IF_FieldName=740 +IF_Reserved2=741 +IF_WS=742 +IR_WS=743 +IFD_DATA_ATTR=744 +IFD_DATETIME_SEP=745 +IFD_DATA_FORMAT=746 +IFD_FIELD_LOCATION=747 +IFD_DECIMAL_POSITIONS=748 +IFD_FIELD_NAME=749 +IFD_CONTROL_LEVEL=750 +IFD_MATCHING_FIELDS=751 +IFD_BLANKS=752 +IFD_COMMENTS=753 +HS_DECEDIT=754 +HS_NEW=755 +HS_CALLER=756 +HS_ACTGRP=757 +HS_WhiteSpace=758 +HS_CONTINUATION=759 '('=20 ')'=21 ';'=23 @@ -778,4 +779,4 @@ HS_CONTINUATION=758 ' '=610 ' '=661 ' '=671 -' '=675 +' '=676 diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index d49ab3711..c94e52bc6 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -1737,7 +1737,7 @@ factorContent: CS_FactorContent | literal; resultType: - CS_FactorContent (COLON (constant=symbolicConstants))? | CS_BlankFactor; + (CS_FactorContentArrayIndexing | CS_FactorContent) (COLON (constant=symbolicConstants))? | CS_BlankFactor; cs_fixed_comments:CS_FixedComments; //cs_fixed_x2: CS_OperationAndExtendedFactor2 C2_FACTOR2_CONT* C2_FACTOR2 C_EOL; cspec_fixed_x2: From e65dfb6879587aa90182867b587f4bf9075865eb Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 8 Mar 2024 15:38:43 +0100 Subject: [PATCH 255/423] Refactor StringValue - BlanksValue comparator --- .../main/kotlin/com/smeup/rpgparser/interpreter/values.kt | 7 +------ 1 file changed, 1 insertion(+), 6 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 b61ccf908..c404b7f31 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 @@ -198,15 +198,10 @@ data class StringValue(var value: String, val varying: Boolean = false) : Abstra return s1.compareTo(s2) } - fun compare(other: BlanksValue, charset: Charset?, descend: Boolean = false): Int { - require(charset != null) - return if (this.isBlank()) EQUAL else SMALLER - } - override operator fun compareTo(other: Value): Int = when (other) { is StringValue -> compare(other, DEFAULT_CHARSET) - is BlanksValue -> compare(other, DEFAULT_CHARSET) + is BlanksValue -> if (this.isBlank()) EQUAL else SMALLER else -> super.compareTo(other) } From f2afa243d4ad0121394c06d2e8026ec96225f52f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 11 Mar 2024 08:16:23 +0100 Subject: [PATCH 256/423] Implemented test --- .../evaluation/SmeupInterpreterTest.kt | 8 ++++++++ .../test/resources/smeup/T12_A04_P17.rpgle | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P17.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 8c53c9191..3ce6272f9 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -562,4 +562,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T12_A04_P14".outputOf()) } + + @Test + fun executeT12_A04_P17() { + val expected = listOf( + "A04_N50_CNT(50)A04_N1(2)A04_N2(50)A04_N4(51)" + ) + assertEquals(expected, "smeup/T12_A04_P17".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P17.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P17.rpgle new file mode 100644 index 000000000..40479d0be --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P17.rpgle @@ -0,0 +1,20 @@ + D A04_N50_LIM S 6 0 INZ(100000) + D A04_N50_CNT S LIKE(A04_N50_LIM) + D A04_N1 S 3 0 INZ(2) + D A04_N2 S 3 0 INZ(50) + D £DBG_Str S 50 VARYING + + + C EVAL A04_N50_CNT = 0 + C SELECT + C A04_N50_CNT WHENEQ 0 + C A04_N1 DO A04_N2 A04_N4 3 0 + C EVAL A04_N50_CNT = A04_N4 + C ENDDO + C ENDSL + C EVAL £DBG_Str= + C 'A04_N50_CNT('+%CHAR(A04_N50_CNT)+')' + C +'A04_N1('+%CHAR(A04_N1)+')' + C +'A04_N2('+%CHAR(A04_N2)+')' + C +'A04_N4('+%CHAR(A04_N4)+')' + C £DBG_Str DSPLY From 6bc01b201a4154c7b68fa1321036045b967a49c9 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 11 Mar 2024 10:07:20 +0100 Subject: [PATCH 257/423] Add rpgle test case T04_A80_P05 --- .../test/resources/smeup/T04_A80_P05.rpgle | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T04_A80_P05.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A80_P05.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A80_P05.rpgle new file mode 100644 index 000000000..c043b6e39 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A80_P05.rpgle @@ -0,0 +1,74 @@ + D £DBG_Str S 150 VARYING + D A80_A1 S 28 + D A80_A2 S 1 + D A80_F C '0123456789' + D A80_T C 'xxxxxxxxxx' + D A80_I1 S 2 0 + + C TIME A80_D1 6 0 + C EVAL A80_A1=%CHAR(A80_D1) + C EXSR SUB_A80_B + C EVAL £DBG_Str= + C 'A80_D1('+%TRIM(A80_A1)+')' + * + C TIME A80_D2 12 0 + C EVAL A80_A1=%CHAR(A80_D2) + C EXSR SUB_A80_B + C EVAL £DBG_Str=%TRIMR(£DBG_Str) + C +' A80_D2('+%TRIM(A80_A1)+')' + * + C TIME A80_D3 14 0 + C EVAL A80_A1=%CHAR(A80_D3) + C EXSR SUB_A80_B + C EVAL £DBG_Str=%TRIMR(£DBG_Str) + C +' A80_D3('+%TRIM(A80_A1)+')' + + C £DBG_Str DSPLY + + *--------------------------------------------------------------------- + RD* Subsezione di SEZ_A80 + *--------------------------------------------------------------------- + C SUB_A80_B BEGSR + * + C IF %REM(%LEN(A80_A1):2)<>0 + C EVAL A80_A1='0'+A80_A1 + C ENDIF + * + C A80_F:A80_T XLATE A80_A1 A80_A1 + C DO 2 + C EVAL A80_A2='h' + C EXSR SUB_A80_D + C ENDDO + C DO 2 + C EVAL A80_A2='m' + C EXSR SUB_A80_D + C ENDDO + C DO 2 + C EVAL A80_A2='s' + C EXSR SUB_A80_D + C ENDDO + C DO 2 + C EVAL A80_A2='D' + C EXSR SUB_A80_D + C ENDDO + C DO 2 + C EVAL A80_A2='M' + C EXSR SUB_A80_D + C ENDDO + C DO 4 + C EVAL A80_A2='Y' + C EXSR SUB_A80_D + C ENDDO + * + C ENDSR + *--------------------------------------------------------------------- + RD* + *--------------------------------------------------------------------- + C SUB_A80_D BEGSR + * + C EVAL A80_I1=%SCAN('x':A80_A1) + C IF A80_I1<>0 + C EVAL A80_A1=%REPLACE(A80_A2:A80_A1:A80_I1) + C ENDIF + * + C ENDSR \ No newline at end of file From 28a8a82d11ec3a30ae744db0bffaf78564abeb22 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 11 Mar 2024 10:07:55 +0100 Subject: [PATCH 258/423] Implement unit test executeT04_A80_P05 --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 8c53c9191..784be7f69 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -562,4 +562,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T12_A04_P14".outputOf()) } + + @Test + fun executeT04_A80_P05() { + val expected = listOf( + "A80_D1(hhmmss) A80_D2(hhmmssDDMMYY) A80_D3(hhmmssDDMMYYYY)" + ) + assertEquals(expected, "smeup/T04_A80_P05".outputOf()) + } } \ No newline at end of file From c202317fe654cffe5920c776d0d51417595e7a46 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 11 Mar 2024 10:33:07 +0100 Subject: [PATCH 259/423] Implement StatementThatCanDefineData for TimeStmt --- .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 5 ++++- .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index a16531f84..1740768fc 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1252,8 +1252,9 @@ data class SubStmt( @Serializable data class TimeStmt( val value: Expression, + @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null -) : Statement(position) { +) : Statement(position), StatementThatCanDefineData { override fun execute(interpreter: InterpreterCore) { when (value) { is DataRefExpr -> { @@ -1275,6 +1276,8 @@ data class TimeStmt( else -> throw UnsupportedOperationException("I do not know how to set TIME to ${this.value}") } } + + override fun dataDefinition(): List = dataDefinition?.let { listOf(it) } ?: emptyList() } @Serializable diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index c3c06c2c3..2a3c50a53 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1094,7 +1094,11 @@ internal fun CsPARMContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() internal fun CsTIMEContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): TimeStmt { val name = this.cspec_fixed_standard_parts().result.text val position = toPosition(conf.considerPosition) - return TimeStmt(annidatedReferenceExpression(name, toPosition(conf.considerPosition)), position) + + val result = this.cspec_fixed_standard_parts().result + val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result.text, position, conf) + + return TimeStmt(annidatedReferenceExpression(name, toPosition(conf.considerPosition)), dataDefinition, position) } fun Cspec_fixed_standard_partsContext.factor2Expression(conf: ToAstConfiguration): Expression? { From 68387c1a0b1cdc146b01f5be65015fc490411761 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 11 Mar 2024 13:33:36 +0100 Subject: [PATCH 260/423] Add T04_A90_P05 rpgle test case --- .../test/resources/smeup/T04_A90_P05.rpgle | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T04_A90_P05.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A90_P05.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A90_P05.rpgle new file mode 100644 index 000000000..9d06f1c23 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T04_A90_P05.rpgle @@ -0,0 +1,31 @@ + D £DBG_Str S 150 VARYING + D A90_A1 S 30 INZ + D A90_A2 S 30 INZ + D A90_Z1 S Z INZ + D A90_Z2 S Z INZ + D A90_N1 S 10I 0 + D A90_N2 S 10I 0 + D A90_N3 S 10I 0 + D A90_N4 S 10I 0 + + C EVAL A90_A1='2020-11-01-14.11.17.725000' + C EVAL A90_Z1=%TIMESTAMP(A90_A1) + C EVAL A90_A2='2023-12-11-20.14.01.538000' + C EVAL A90_Z2=%TIMESTAMP(A90_A2) + C A90_Z2 SUBDUR A90_Z1 A90_D1:*MS 20 0 + C A90_Z2 SUBDUR A90_Z1 A90_D2:*S 20 0 + C A90_Z2 SUBDUR A90_Z1 A90_D3:*MN 20 0 + C A90_Z2 SUBDUR A90_Z1 A90_D4:*H 20 0 + C A90_Z2 SUBDUR A90_Z1 A90_D5:*D 10 0 + C A90_Z2 SUBDUR A90_Z1 A90_D6:*M 10 0 + C A90_Z2 SUBDUR A90_Z1 A90_D7:*Y 5 0 + C EVAL £DBG_Str= + C 'Microsecondi('+%CHAR(A90_D1)+') ' + C +'Secondi('+%CHAR(A90_D2)+') ' + C +'Minuti('+%CHAR(A90_D3)+') ' + C +'Ore('+%CHAR(A90_D4)+') ' + C +'Giorni('+%CHAR(A90_D5)+') ' + C +'Mesi('+%CHAR(A90_D6)+') ' + C +'Anni('+%CHAR(A90_D7)+') ' + + C £DBG_Str DSPLY \ No newline at end of file From 3841ba1ee0605012a62cb101d534716242cd3e29 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 11 Mar 2024 13:34:02 +0100 Subject: [PATCH 261/423] Implement unit test executeT04_A90_P05 --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 8c53c9191..ff3772600 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -562,4 +562,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T12_A04_P14".outputOf()) } + + @Test + fun executeT04_A90_P05() { + val expected = listOf( + "Microsecondi(98085763813000) Secondi(98085763) Minuti(1634762) Ore(27246) Giorni(1135) Mesi(37) Anni(3)" + ) + assertEquals(expected, "smeup/T04_A90_P05".outputOf()) + } } \ No newline at end of file From 7deadfdb1ce37616c492bcff6c54df3eb3968e95 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 11 Mar 2024 14:09:10 +0100 Subject: [PATCH 262/423] Implement StatementThatCanDefineData for SubDurStmt --- .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 5 ++++- .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index a16531f84..e78dc7900 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -280,9 +280,10 @@ data class SubDurStmt( val target: AssignableExpression, val factor2: Expression, val durationCode: DurationCode, + @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null ) : - Statement(position) { + Statement(position), StatementThatCanDefineData { override fun execute(interpreter: InterpreterCore) { when (target) { is DataRefExpr -> { @@ -293,6 +294,8 @@ data class SubDurStmt( else -> throw UnsupportedOperationException("Data reference required: $this") } } + + override fun dataDefinition(): List = dataDefinition?.let { listOf(it) } ?: emptyList() } @Serializable diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index c3c06c2c3..dea1c0a8a 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1216,7 +1216,9 @@ internal fun CsSUBDURContext.toAst(conf: ToAstConfiguration = ToAstConfiguration // TODO handle duration code after the : val target = this.cspec_fixed_standard_parts().result.text.split(":") val durationCode = if (target.size > 1) target[1].toDuration() else DurationInMSecs - return SubDurStmt(left, DataRefExpr(ReferenceByName(target[0]), position), factor2, durationCode, position) + val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(target.first(), position, conf) + + return SubDurStmt(left, DataRefExpr(ReferenceByName(target[0]), position), factor2, durationCode, dataDefinition, position) } private fun String.toDuration(): DurationCode = From e50ddb6e32b01e2d56a832c759de288cac1ceaba Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 11 Mar 2024 16:53:27 +0100 Subject: [PATCH 263/423] Implemented test `T10_A20_P47` for task 230 --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 8 ++++++++ .../src/test/resources/smeup/T10_A20_P47.rpgle | 15 +++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P47.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 3ce6272f9..986bb3c99 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -570,4 +570,12 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T12_A04_P17".outputOf()) } + + @Test + fun executeT10_A20_P47() { + val expected = listOf( + "A20_D7(53.33) A20_D8(.002) A20_D9(2) A20_D0(3)" + ) + assertEquals(expected, "smeup/T10_A20_P47".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P47.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P47.rpgle new file mode 100644 index 000000000..aaa061e37 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P47.rpgle @@ -0,0 +1,15 @@ + D A20_D1 S 3 0 INZ(32) + D A20_D2 S 3 1 INZ(0.6) + D A20_D3 S 2 0 INZ(25) + D A20_D4 S 2 0 INZ(11) + D £DBG_Str S 50 VARYING + + C A20_D1 DIV A20_D2 A20_D7 11 2 + C MVR A20_D8 5 3 + C A20_D3 DIV A20_D4 A20_D9 2 0 + C MVR A20_D0 2 0 + C EVAL £DBG_Str='A20_D7('+%CHAR(A20_D7)+')' + C +' A20_D8('+%CHAR(A20_D8)+')' + C +' A20_D9('+%CHAR(A20_D9)+')' + C +' A20_D0('+%CHAR(A20_D0)+')' + C £DBG_Str DSPLY \ No newline at end of file From 1fbc6c2f89abc93220dfc7765156ff2865d20089 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 11 Mar 2024 16:56:08 +0100 Subject: [PATCH 264/423] Created `MvrStmt` --- .../com/smeup/rpgparser/parsing/ast/serialization.kt | 1 + .../com/smeup/rpgparser/parsing/ast/statements.kt | 10 ++++++++++ 2 files changed, 11 insertions(+) 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 1019293bd..f58318903 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 @@ -72,6 +72,7 @@ private val modules = SerializersModule { subclass(MoveLStmt::class) subclass(MoveStmt::class) subclass(MultStmt::class) + subclass(MvrStmt::class) subclass(OtherStmt::class) subclass(OccurStmt::class) subclass(OpenStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index a16531f84..433c91e2b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1178,6 +1178,16 @@ data class DivStmt( override fun dataDefinition() = dataDefinition?.let { listOf(it) } ?: emptyList() } +@Serializable +data class MvrStmt( + val target: AssignableExpression?, + @Derived val dataDefinition: InStatementDataDefinition? = null, + override val position: Position? = null +) : Statement(position), StatementThatCanDefineData { + override fun dataDefinition() = dataDefinition?.let { listOf(it) } ?: emptyList() + override fun execute(interpreter: InterpreterCore) { } +} + @Serializable data class AddStmt( val left: Expression?, From 37294be1e551c67def375d98af0e605d8631e040 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 11 Mar 2024 16:56:27 +0100 Subject: [PATCH 265/423] Replaced `mvrTarget` with `mvrStatement`, after implementation of `MvrStmt` --- .../smeup/rpgparser/parsing/ast/statements.kt | 2 +- .../rpgparser/parsing/parsetreetoast/misc.kt | 21 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 433c91e2b..909e8db63 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1157,7 +1157,7 @@ data class DivStmt( val halfAdjust: Boolean = false, val factor1: Expression?, val factor2: Expression, - val mvrTarget: AssignableExpression? = null, + val mvrStatement: MvrStmt? = null, @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null ) : Statement(position), StatementThatCanDefineData { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index c3c06c2c3..9ea491eff 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1461,20 +1461,33 @@ internal fun CsDIVContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) val extenders = this.operationExtender?.extender?.text?.uppercase(Locale.getDefault())?.toCharArray() ?: CharArray(0) val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) - val mvrTarget: AssignableExpression? = this.csMVR()?.cspec_fixed_standard_parts()?.result?.text?.let { - DataRefExpr(ReferenceByName(it), position) - } return DivStmt( target = this.cspec_fixed_standard_parts().result.toAst(conf), halfAdjust = 'H' in extenders, factor1 = factor1, factor2 = factor2, - mvrTarget = mvrTarget, + mvrStatement = this.csMVR()?.toAst(conf), dataDefinition = dataDefinition, position = position ) } +internal fun CsMVRContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MvrStmt { + val result = this.cspec_fixed_standard_parts().result.text + val target = result?.let { + DataRefExpr(ReferenceByName(it), toPosition(conf.considerPosition)) + } + val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition( + name = result, + position = toPosition(conf.considerPosition), + conf = conf + ) + return MvrStmt( + target = target, + dataDefinition = dataDefinition + ) +} + internal fun CsTAGContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): TagStmt { return TagStmt(this.factor1Context()?.content?.text!!, toPosition(conf.considerPosition)) } From d6c4ce922fba717bd879f92c1834b0ccaa2e5b5f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 11 Mar 2024 17:05:01 +0100 Subject: [PATCH 266/423] Fixed behaviour of `div` in `internal_interpreter`. Now in considered `mvrStatement` instead `mvrTarget` --- .../rpgparser/interpreter/internal_interpreter.kt | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 42c87fc55..52b8a79dd 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -716,13 +716,20 @@ open class InternalInterpreter( require(type is NumberType) // calculation of rest // NB. rest based on type of quotient - if (statement.mvrTarget != null) { - val restType = statement.mvrTarget.type() + if (statement.mvrStatement != null) { + val restType = when { + statement.mvrStatement.dataDefinition != null -> statement.mvrStatement.dataDefinition.type + statement.mvrStatement.target != null -> statement.mvrStatement.target.type() + else -> null + } require(restType is NumberType) val truncatedQuotient: BigDecimal = quotient.setScale(type.decimalDigits, RoundingMode.DOWN) // rest = divident - (truncatedQuotient * divisor) val rest: BigDecimal = dividend.subtract(truncatedQuotient.multiply(divisor)) - assign(statement.mvrTarget, DecimalValue(rest.setScale(restType.decimalDigits, RoundingMode.DOWN))) + when { + statement.mvrStatement.dataDefinition != null -> assign(statement.mvrStatement.dataDefinition, DecimalValue(rest.setScale(restType.decimalDigits, RoundingMode.DOWN))) + statement.mvrStatement.target != null -> assign(statement.mvrStatement.target, DecimalValue(rest.setScale(restType.decimalDigits, RoundingMode.DOWN))) + } } return if (statement.halfAdjust) { DecimalValue(quotient.setScale(type.decimalDigits, RoundingMode.HALF_UP)) From c07d3fd21dc22a77c65d2017196490f8e4ea6365 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 11 Mar 2024 17:06:14 +0100 Subject: [PATCH 267/423] Applied the correction to `resolution.kt` for inline variable --- .../parsing/parsetreetoast/resolution.kt | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt index 59a740860..ac49756fd 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt @@ -20,6 +20,7 @@ import com.smeup.rpgparser.execution.MainExecutionContext import com.smeup.rpgparser.execution.ParsingProgram import com.smeup.rpgparser.interpreter.AbstractDataDefinition import com.smeup.rpgparser.interpreter.DataDefinition +import com.smeup.rpgparser.interpreter.InStatementDataDefinition import com.smeup.rpgparser.interpreter.type import com.smeup.rpgparser.parsing.ast.* import com.smeup.rpgparser.parsing.facade.AstCreatingException @@ -31,8 +32,39 @@ import java.util.* private fun CompilationUnit.findInStatementDataDefinitions() { // TODO could they be also annidated? - this.allStatements(preserveCompositeStatement = true).filterIsInstance(StatementThatCanDefineData::class.java).forEach { - this.addInStatementDataDefinitions(it.dataDefinition()) + this.allStatements(preserveCompositeStatement = true).forEach { + this.addInStatementDataDefinitions(scanInDephStatementDataDefinition(it)) + } +} + +private fun scanInDephStatementDataDefinition(node: Node): List { + val list = mutableListOf() + return when { + node is CompositeStatement -> { + /* Is possible that the node is both CompositeStatement and StatementThatCanDefineData. */ + if (node is StatementThatCanDefineData) { + list.addAll(node.dataDefinition()) + } + + node.body.forEach { + if (it is StatementThatCanDefineData) { + list.addAll(it.dataDefinition()) + } else if (it.parent != null && it.parent is StatementThatCanDefineData) { + list.addAll((it.parent as StatementThatCanDefineData).dataDefinition()) + } else { + list.addAll(scanInDephStatementDataDefinition(it)) + } + } + return list + } + node is StatementThatCanDefineData -> { + if (node is DivStmt) { + node.mvrStatement?.let { list.addAll(it.dataDefinition()) } + } + list.addAll(node.dataDefinition()) + return list + } + else -> emptyList() } } From f30ac5735bd883cce5d820ba213b140b50a4a6c8 Mon Sep 17 00:00:00 2001 From: "Sme.UP" Date: Tue, 12 Mar 2024 09:38:19 +0100 Subject: [PATCH 268/423] Update CODEOWNERS Added Antonio Cosentino as codeowner --- docs/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/CODEOWNERS b/docs/CODEOWNERS index bf28a2688..1e2ebff18 100644 --- a/docs/CODEOWNERS +++ b/docs/CODEOWNERS @@ -1,2 +1,2 @@ # default code owners -* marco.lanari@smeup.com marco.benetti@smeup.com mattiabonardi99@gmail.com fiorenza.busi@smeup.com \ No newline at end of file +* marco.lanari@smeup.com marco.benetti@smeup.com mattiabonardi99@gmail.com fiorenza.busi@smeup.com antonio.cosentino@smeup.com From 4c5e43d6751de5dc8295f7fc6df2248e55663727 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 12 Mar 2024 08:53:50 +0000 Subject: [PATCH 269/423] split T03_A10_P09_10 into 2 separated tests --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 13 ++++++++++--- .../{T03_A10_P09-10.rpgle => T03_A10_P09.rpgle} | 11 +---------- .../src/test/resources/smeup/T03_A10_P10.rpgle | 11 +++++++++++ 3 files changed, 22 insertions(+), 13 deletions(-) rename rpgJavaInterpreter-core/src/test/resources/smeup/{T03_A10_P09-10.rpgle => T03_A10_P09.rpgle} (68%) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P10.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 8c53c9191..7892ba68e 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -292,12 +292,19 @@ open class SmeupInterpreterTest : AbstractTest() { } @Test - fun executeT03_A10_P09_10() { + fun executeT03_A10_P09() { + val expected = listOf( + "I(15)=0 I(15)=1 I(15)=0" + ) + assertEquals(expected, "smeup/T03_A10_P09".outputOf()) + } + + @Test + fun executeT03_A10_P10() { val expected = listOf( - "I(15)=0 I(15)=1 I(15)=0", "*IN(n)->000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ) - assertEquals(expected, "smeup/T03_A10_P09-10".outputOf()) + assertEquals(expected, "smeup/T03_A10_P10".outputOf()) } @Test diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09.rpgle similarity index 68% rename from rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle rename to rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09.rpgle index f7cdf8071..c818b160f 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09-10.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P09.rpgle @@ -14,13 +14,4 @@ C EVAL £DBG_Str=%TRIM(£DBG_Str) C +' I('+%CHAR($IND)+')=' C +%CHAR(*IN($IND)) - C £DBG_Str DSPLY - - D* Indicatori come array con indice n *IN(n) - C EVAL £DBG_Str='*IN(n)->' - C EVAL $IND=1 - C DO 99 - C EVAL £DBG_Str=%TRIM(£DBG_Str) - C +%CHAR(*IN($IND)) - C ENDDO - C £DBG_Str DSPLY + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P10.rpgle new file mode 100644 index 000000000..3fb2136a8 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P10.rpgle @@ -0,0 +1,11 @@ + D $IND S 2 0 + D £DBG_Str S 110 VARYING + + D* Indicatori come array con indice n *IN(n) + C EVAL £DBG_Str='*IN(n)->' + C EVAL $IND=1 + C DO 99 + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +%CHAR(*IN($IND)) + C ENDDO + C £DBG_Str DSPLY From 676d28e10c00c0652c9f2ab9d2e6d9198190156b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 12 Mar 2024 09:55:48 +0100 Subject: [PATCH 270/423] Implemented case of test --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T18_A10_P01.rpgle | 10 ++++++++++ 2 files changed, 16 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P01.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 8c53c9191..f66e04983 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -562,4 +562,10 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T12_A04_P14".outputOf()) } + + @Test + fun executeT18_A10_P01() { + val expected = listOf("Ritorno_Procedura") + assertEquals(expected, "smeup/T18_A10_P01".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P01.rpgle new file mode 100644 index 000000000..fac03a970 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P01.rpgle @@ -0,0 +1,10 @@ + D A10_PR01 PR 25A + D £DBG_Str S 50 VARYING + + C EVAL £DBG_Str=A10_PR01() + C £DBG_Str DSPLY + + P A10_PR01 B + D A10_PR01 PI 25A + C RETURN 'Ritorno_Procedura' + P A10_PR01 E \ No newline at end of file From adb7cda72b34289fb5f8fdc1ac9e0d67a41ec7bc Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 12 Mar 2024 10:04:24 +0100 Subject: [PATCH 271/423] Applied the fix --- .../smeup/rpgparser/parsing/parsetreetoast/resolution.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt index 59a740860..4da08ce44 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt @@ -64,7 +64,13 @@ private fun Node.resolveDataRefs(cu: CompilationUnit) { currentCu = currentCu.parent?.let { it as CompilationUnit } } if (!resolved) { - kotlin.runCatching { dre.error("Data reference not resolved: ${dre.variable.name}") } + /* Maybe is a procedure without parenthesis. */ + val procedureFound = cu.procedures?.firstOrNull() { it.procedureName == dre.variable.name } + if (procedureFound != null) { + procedureFound.resolve() + } else { + kotlin.runCatching { dre.error("Data reference not resolved: ${dre.variable.name}") } + } } } } From 7ba972da7f50448315af3c00b8b08dacac407d5a Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 12 Mar 2024 09:22:16 +0000 Subject: [PATCH 272/423] add T03_A10_P11, T03_A10_P12 --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 16 ++++++++++++++++ .../src/test/resources/smeup/T03_A10_P11.rpgle | 9 +++++++++ .../src/test/resources/smeup/T03_A10_P12.rpgle | 16 ++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P11.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P12.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 7892ba68e..27390cb41 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -307,6 +307,22 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T03_A10_P10".outputOf()) } + @Test + fun executeT03_A10_P11() { + val expected = listOf( + "*INLR->1" + ) + assertEquals(expected, "smeup/T03_A10_P11".outputOf()) + } + + @Test + fun executeT03_A10_P12() { + val expected = listOf( + "*IN35->1, *INLR->1" + ) + assertEquals(expected, "smeup/T03_A10_P12".outputOf()) + } + @Test fun executeT15_A20_P04_06() { val expected = listOf( diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P11.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P11.rpgle new file mode 100644 index 000000000..faf16445a --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P11.rpgle @@ -0,0 +1,9 @@ + D £DBG_Str S 10 VARYING + * Indicatori con letter case differente + C EVAL *inlr=*On + * + C EVAL £DBG_Str='*INLR->' + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +%CHAR(*INLR) + * + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P12.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P12.rpgle new file mode 100644 index 000000000..7182263bf --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T03_A10_P12.rpgle @@ -0,0 +1,16 @@ + D £DBG_Str S 20 VARYING + * Indicatori con letter case differente + C EVAL *in35=*On + * + C *In35 IFEQ *ON + C EVAL *inlr=*On + c ENDIF + C EVAL £DBG_Str='*IN35->' + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +%CHAR(*IN35) + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +', *INLR->' + C EVAL £DBG_Str=%TRIM(£DBG_Str) + C +%CHAR(*INLR) + * + C £DBG_Str DSPLY From bbc6b37e926b00a8a9275ee67bba3739bdd99550 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:25:08 +0000 Subject: [PATCH 273/423] fix letter case problem with *in --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt | 3 ++- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt index d992296f4..eca5be551 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/indicators.kt @@ -5,6 +5,7 @@ import com.smeup.rpgparser.interpreter.Value import com.smeup.rpgparser.parsing.parsetreetoast.isInt import com.strumenta.kolasu.model.Position import kotlinx.serialization.Serializable +import java.util.* // *IN01..*IN99 and *INLR *INRT @Serializable @@ -98,7 +99,7 @@ fun String.toIndicatorKey(): IndicatorKey { require(IndicatorType.Predefined.range.contains(it.toInt())) it.toInt() } - else -> IndicatorType.valueOf(this).range.first + else -> IndicatorType.valueOf(this.uppercase()).range.first } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index c3c06c2c3..ab4efb355 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -665,7 +665,7 @@ internal fun SymbolicConstantsContext.toAst(conf: ToAstConfiguration = ToAstConf this.SPLAT_ON() != null -> OnRefExpr(position) this.SPLAT_INDICATOR() != null -> { IndicatorExpr( - index = children[0].text.replace("*IN", "").toIndicatorKey(), + index = children[0].text.uppercase().replace("*IN", "").toIndicatorKey(), position = position ) } From 8657fccb9f52639be3dbe041c2c86ea2f781b15c Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 12 Mar 2024 11:26:30 +0100 Subject: [PATCH 274/423] Add test cases for MoveA --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T40_A20_P26.rpgle | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T40_A20_P26.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 505e989fb..4f5a47a17 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -568,4 +568,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Res(21, -19, 20, 2, 20, -20)") assertEquals(expected, "smeup/T10_A20_P51".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT40_A20_P26() { + val expected = listOf("T40_AR2(TEST01;NO_TEST;)") + assertEquals(expected, "smeup/T40_A20_P26".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A20_P26.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A20_P26.rpgle new file mode 100644 index 000000000..c0b3db56e --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A20_P26.rpgle @@ -0,0 +1,15 @@ + D £DBG_Str S 150 VARYING + D T40_AR2 S 10 DIM(5) + D A20N S 2 0 + + C EVAL T40_AR2(01)='TEST01' + C EVAL T40_AR2(02)='TEST02' + C EVAL T40_AR2(03)='TEST03' + C EVAL A20N=2 + C MOVEA(P) 'NO_TEST' T40_AR2 (A20N) + C EVAL £DBG_Str='T40_AR2('+ + C %TRIM(T40_AR2(01))+';'+ + C %TRIM(T40_AR2(02))+';'+ + C %TRIM(T40_AR2(03))+')' + + C £DBG_Str DSPLY \ No newline at end of file From a249ac53e3a3322bfa91c6ba8683d4153e58734e Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 12 Mar 2024 11:27:02 +0100 Subject: [PATCH 275/423] Improve whitespace stripping logic for array indexing --- rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 index 72e3f3147..cbb766c1d 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.g4 @@ -1171,7 +1171,7 @@ CS_FactorContent: (~[\r\n' :] || (getCharPositionInLine()>=36 && getCharPositionInLine()<=49) }? )+; -CS_FactorContentArrayIndexing: (CS_ResultContent | CS_FactorContent) WS* OPEN_PAREN (CS_ResultContent | CS_FactorContent) CLOSE_PAREN {setText(getText().replace(" ", ""));}; +CS_FactorContentArrayIndexing: (CS_ResultContent | CS_FactorContent) WS* OPEN_PAREN (CS_ResultContent | CS_FactorContent) CLOSE_PAREN {setText(getText().replaceAll("\\s", ""));}; CS_ResultContent: (~[\r\n' :] {(getCharPositionInLine()>=50 && getCharPositionInLine()<=63)}? )+ -> type(CS_FactorContent); From 7d0735bc469f23436f754218dc07300cbe13c001 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 12 Mar 2024 11:27:51 +0100 Subject: [PATCH 276/423] Fix issue with StringType value size when used with MoveA(P) --- .../main/kotlin/com/smeup/rpgparser/interpreter/move_a.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/move_a.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/move_a.kt index b96abb82e..147d44b8a 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/move_a.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/move_a.kt @@ -112,7 +112,11 @@ private fun moveaString( if (operationExtenter == null) { interpreterCore.get(target.variable.referred!!).takeLast((realSize - newValue.value.length)) } else { - StringValue(" ".repeat((realSize - value.type().size))) + val valueSize = when (val valueType = value.type()) { + is StringType -> valueType.length + else -> valueType.size + } + StringValue(" ".repeat((realSize - valueSize))) } newValue = newValue.concatenate(other).asString() } From ad23d1ab11bfa1ef5a6db968e2e9facb6a8e4adc Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 12 Mar 2024 11:29:49 +0100 Subject: [PATCH 277/423] Implemented case of test --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T18_A10_P02.rpgle | 14 ++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 8c53c9191..33d429353 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -562,4 +562,10 @@ open class SmeupInterpreterTest : AbstractTest() { ) assertEquals(expected, "smeup/T12_A04_P14".outputOf()) } + + @Test + fun executeT18_A10_P02() { + val expected = listOf("TestProcedura_Ritorno") + assertEquals(expected, "smeup/T18_A10_P02".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P02.rpgle new file mode 100644 index 000000000..871bbacc4 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P02.rpgle @@ -0,0 +1,14 @@ + D A10_PR02 PR 25A + D A10_PR02_V1 CONST LIKE(T10_A10_A20) + D T10_A10_A20 S 25 + D £DBG_Str S 50 VARYING + + C EVAL T10_A10_A20='TestProcedura' + C EVAL £DBG_Str=A10_PR02(T10_A10_A20) + C £DBG_Str DSPLY + + P A10_PR02 B + D A10_PR02 PI 25A + D A10_PR02_V1 CONST LIKE(T10_A10_A20) + C RETURN %TRIM(A10_PR02_V1)+'_Ritorno' + P A10_PR02 E \ No newline at end of file From 247a3fc5460bdabac19422cbd8a6ab23228b2280 Mon Sep 17 00:00:00 2001 From: cosentino-smeup <32836304+cosentino-smeup@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:33:50 +0000 Subject: [PATCH 278/423] replace the obsolete "toUpperCase" method with "uppercase" --- .../smeup/rpgparser/parsing/parsetreetoast/expressions.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 87ab1b0d1..e773b7a3d 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 @@ -204,7 +204,7 @@ internal fun RpgParser.Multipart_identifier_elementContext.toAst(conf: ToAstConf } internal fun String.indicatorIndex(): Int? { - val uCaseIndicatorString = this.toUpperCase() + val uCaseIndicatorString = this.uppercase() return when { uCaseIndicatorString.startsWith("*IN") -> this.substring("*IN".length).toIndicatorKey() @@ -214,9 +214,9 @@ internal fun String.indicatorIndex(): Int? { internal fun String.dataWrapUpChoice(): DataWrapUpChoice? { val indicator = when { - this.toUpperCase().startsWith("*IN(") && this.endsWith(")") -> - this.toUpperCase().removePrefix("*IN(").removeSuffix(")") - this.toUpperCase().startsWith("*IN") -> this.substring("*IN".length) + this.uppercase().startsWith("*IN(") && this.endsWith(")") -> + this.uppercase().removePrefix("*IN(").removeSuffix(")") + this.uppercase().startsWith("*IN") -> this.substring("*IN".length) else -> null } return when (indicator) { From 154a7ab6fe95a4262d266a486a8c941f04463be6 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 09:02:05 +0100 Subject: [PATCH 279/423] Fixed test --- .../src/test/resources/smeup/T18_A10_P01.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P01.rpgle index fac03a970..0441886ba 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P01.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T18_A10_P01.rpgle @@ -1,7 +1,7 @@ D A10_PR01 PR 25A D £DBG_Str S 50 VARYING - C EVAL £DBG_Str=A10_PR01() + C EVAL £DBG_Str=A10_PR01 C £DBG_Str DSPLY P A10_PR01 B From f0667a72e943d1dd4f70d288e85b485b5a979bf4 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 09:02:24 +0100 Subject: [PATCH 280/423] Restored `resolution.kt` --- .../smeup/rpgparser/parsing/parsetreetoast/resolution.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt index 4da08ce44..59a740860 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt @@ -64,13 +64,7 @@ private fun Node.resolveDataRefs(cu: CompilationUnit) { currentCu = currentCu.parent?.let { it as CompilationUnit } } if (!resolved) { - /* Maybe is a procedure without parenthesis. */ - val procedureFound = cu.procedures?.firstOrNull() { it.procedureName == dre.variable.name } - if (procedureFound != null) { - procedureFound.resolve() - } else { - kotlin.runCatching { dre.error("Data reference not resolved: ${dre.variable.name}") } - } + kotlin.runCatching { dre.error("Data reference not resolved: ${dre.variable.name}") } } } } From 53bc3f972a14240f4e93b3c3bc310ca9a06c15be Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 10:02:18 +0100 Subject: [PATCH 281/423] Fixed problem by `expressions` --- .../rpgparser/parsing/parsetreetoast/expressions.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) 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 87ab1b0d1..5fe281334 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 @@ -1,7 +1,10 @@ package com.smeup.rpgparser.parsing.parsetreetoast import com.smeup.rpgparser.RpgParser +import com.smeup.rpgparser.RpgParser.Dcl_prContext +import com.smeup.rpgparser.RpgParser.Ds_nameContext import com.smeup.rpgparser.RpgParser.ExpressionContext +import com.smeup.rpgparser.RpgParser.PrBeginContext import com.smeup.rpgparser.parsing.ast.* import com.strumenta.kolasu.mapping.toPosition import com.strumenta.kolasu.model.Position @@ -156,10 +159,20 @@ private fun RpgParser.IdentifierContext.variableExpression(conf: ToAstConfigurat return when { this.text.indicatorIndex() != null -> IndicatorExpr(this.text.indicatorIndex()!!, toPosition(conf.considerPosition)) this.multipart_identifier() != null -> this.multipart_identifier().toAst(conf) + isFunctionWithoutParams(this.text) -> FunctionCall(ReferenceByName(this.text), listOf()) else -> DataRefExpr(variable = ReferenceByName(this.text), position = toPosition(conf.considerPosition)) } } +fun RpgParser.IdentifierContext.isFunctionWithoutParams(referenceName: String): Boolean { + return runCatching { + rContext().children.filterIsInstance() + .flatMap { it.children.filterIsInstance() } + .flatMap { it.children.filterIsInstance() } + .firstOrNull { it.text == referenceName }?.text + }.getOrNull() != null +} + internal fun RpgParser.Multipart_identifierContext.toAst(conf: ToAstConfiguration = ToAstConfiguration(), fieldName: String? = null): Expression { require(this.elements.size == 2) { "More than two elements not yet supported" } From f53fcf5d0048978c52867a127c4baed79267b0af Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 10:05:15 +0100 Subject: [PATCH 282/423] Changed function to private --- .../com/smeup/rpgparser/parsing/parsetreetoast/expressions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 5fe281334..792386a96 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 @@ -164,7 +164,7 @@ private fun RpgParser.IdentifierContext.variableExpression(conf: ToAstConfigurat } } -fun RpgParser.IdentifierContext.isFunctionWithoutParams(referenceName: String): Boolean { +private fun RpgParser.IdentifierContext.isFunctionWithoutParams(referenceName: String): Boolean { return runCatching { rContext().children.filterIsInstance() .flatMap { it.children.filterIsInstance() } From e8e8cc6aa44c51d4126824fa7d8faed0666fbc92 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 10:11:24 +0100 Subject: [PATCH 283/423] Improved logic --- .../smeup/rpgparser/parsing/parsetreetoast/expressions.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 792386a96..94fafbefe 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 @@ -144,6 +144,11 @@ internal fun RpgParser.IdentifierContext.toAst(conf: ToAstConfiguration = ToAstC if (this.text.toUpperCase().startsWith("*ALL")) { return AllExpr(this.all().literal().toAst(conf), toPosition(conf.considerPosition)) } + + if (isFunctionWithoutParams(this.text)) { + return FunctionCall(ReferenceByName(this.text), listOf(), toPosition(conf.considerPosition)) + } + return when (this.text.toUpperCase()) { "*BLANK", "*BLANKS" -> BlanksRefExpr(toPosition(conf.considerPosition)) "*ZERO", "*ZEROS" -> ZeroExpr(toPosition(conf.considerPosition)) @@ -159,7 +164,6 @@ private fun RpgParser.IdentifierContext.variableExpression(conf: ToAstConfigurat return when { this.text.indicatorIndex() != null -> IndicatorExpr(this.text.indicatorIndex()!!, toPosition(conf.considerPosition)) this.multipart_identifier() != null -> this.multipart_identifier().toAst(conf) - isFunctionWithoutParams(this.text) -> FunctionCall(ReferenceByName(this.text), listOf()) else -> DataRefExpr(variable = ReferenceByName(this.text), position = toPosition(conf.considerPosition)) } } From 19662c696260eb2abbef6198f344c247ccf8592a Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 10:30:32 +0100 Subject: [PATCH 284/423] Recovered old logic of `misc` --- .../rpgparser/parsing/parsetreetoast/misc.kt | 69 +++++++------------ 1 file changed, 23 insertions(+), 46 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index a210ddefa..1c5215fa0 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -99,7 +99,6 @@ private fun RContext.getDataDefinitions( // then we calculate the ones with the LIKE DS clause, as they could have references to DS declared // after them val dataDefinitionProviders: MutableList = LinkedList() - val statementsNotResolved: MutableList = LinkedList() val knownDataDefinitions = KnownDataDefinition.getInstance() fileDefinitions.values.flatten().toList().removeDuplicatedDataDefinition().forEach { @@ -113,56 +112,34 @@ private fun RContext.getDataDefinitions( // Second pass, everything, I mean everything dataDefinitionProviders.addAll(this.statement() .mapNotNull { - it.scanForDefinitions(conf, knownDataDefinitions, dataDefinitionProviders, fileDefinitions) - .onFailure { e -> statementsNotResolved.add(it) } - .getOrNull() - } - ) - // Third pass with statements not resolved - dataDefinitionProviders.addAll(statementsNotResolved - .mapNotNull { - it.scanForDefinitions(conf, knownDataDefinitions, dataDefinitionProviders, fileDefinitions) - .getOrNull() + kotlin.runCatching { + when { + it.dspec() != null -> { + it.dspec() + .toAst(conf, knownDataDefinitions.values.toList()) + .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) + } + it.dcl_c() != null -> { + it.dcl_c() + .toAst(conf) + .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) + } + it.dcl_ds() != null && it.dcl_ds().useLikeDs(conf) -> { + DataDefinitionCalculator(it.dcl_ds().toAstWithLikeDs(conf, dataDefinitionProviders)) + } + it.dcl_ds() != null && it.dcl_ds().useExtName() && fileDefinitions.keys.any { fileDefinition -> + fileDefinition.name.equals(it.dcl_ds().getKeywordExtName().getExtName(), ignoreCase = true) + } -> { + DataDefinitionCalculator(it.dcl_ds().toAstWithExtName(conf, fileDefinitions)) + } + else -> null + } + }.getOrNull() } ) return dataDefinitionProviders.mapNotNull { kotlin.runCatching { it.toDataDefinition() }.getOrNull() } } -private fun StatementContext.scanForDefinitions( - conf: ToAstConfiguration, - knownDataDefinitions: MutableMap, - dataDefinitionProviders: MutableList, - fileDefinitions: Map> -): Result { - return runCatching { - when { - this.dspec() != null -> { - this.dspec() - .toAst(conf, knownDataDefinitions.values.toList()) - .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) - } - - this.dcl_c() != null -> { - this.dcl_c() - .toAst(conf) - .updateKnownDataDefinitionsAndGetHolder(knownDataDefinitions) - } - - this.dcl_ds() != null && this.dcl_ds().useLikeDs(conf) -> { - DataDefinitionCalculator(this.dcl_ds().toAstWithLikeDs(conf, dataDefinitionProviders)) - } - - this.dcl_ds() != null && this.dcl_ds().useExtName() && fileDefinitions.keys.any { fileDefinition -> - fileDefinition.name.equals(this.dcl_ds().getKeywordExtName().getExtName(), ignoreCase = true) - } -> { - DataDefinitionCalculator(this.dcl_ds().toAstWithExtName(conf, fileDefinitions)) - } - - else -> null - } - } -} - private fun DataDefinition.updateKnownDataDefinitionsAndGetHolder( knownDataDefinitions: MutableMap ): DataDefinitionHolder { From 5a0d2c363546e6a1e9a87bba97375e1db3d3a9bf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 10:31:40 +0100 Subject: [PATCH 285/423] Recovered old logic of `compiler_time_interpreter` with improvements by suggestions of Marco --- .../interpreter/compile_time_interpreter.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index 19443150e..7df228f36 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -185,12 +185,7 @@ open class BaseCompileTimeInterpreter( if (delegatedCompileTimeInterpreter != null) { return delegatedCompileTimeInterpreter.evaluateElementSizeOf(rContext, expression, conf) } else { - val errorsExisting = getAstCreationErrors().filter { it is AstResolutionError }.firstOrNull() { it.cause?.message == e.message } - if (errorsExisting == null) { - throw expression.error(message = e.message, cause = e) - } - - throw e + throw expression.error(message = e.message, cause = e) } } } @@ -233,6 +228,12 @@ open class BaseCompileTimeInterpreter( statements .forEach { it -> when { + it.dspec() != null -> { + val name = it.dspec().ds_name()?.text ?: it.dspec().dspecConstant().ds_name()?.text + if (declName.equals(name, ignoreCase = true)) { + return it.dspec().toAst(conf = conf, knownDataDefinitions = knownDataDefinitions).type + } + } it.cspec_fixed() != null -> { val type = it.cspec_fixed().findType(declName, conf) if (type != null) return type From e6929028a180beff0910e5a3bf325f73eb902d15 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 10:56:43 +0100 Subject: [PATCH 286/423] Removed useless configuration from test --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 89568eef0..475ef5abd 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -532,6 +532,6 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A30_P04() { val expected = listOf("AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFF") - assertEquals(expected, "smeup/T02_A30_P04".outputOf(configuration = smeupConfig)) + assertEquals(expected, "smeup/T02_A30_P04".outputOf()) } } \ No newline at end of file From 0efe09ecdf89fbee3c04ed22b282a01a965224f3 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 10:57:24 +0100 Subject: [PATCH 287/423] Removed useless space from rpgle file --- .../src/test/resources/smeup/T02_A30_P04.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle index b5a81cb8e..1c8d023bd 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A30_P04.rpgle @@ -1,6 +1,6 @@ D A30_C04 C CONST(6) D A30_AR4 S 20 DIM(A30_C04) - D £DBG_Str S 150 VARYING + D £DBG_Str S 150 VARYING C EVAL A30_AR4(01) = 'AAAAAAAAAAAAAAAAAAAA' C EVAL A30_AR4(02) = 'BBBBBBBBBBBBBBBBBBBB' From a2137fd6c7368f57583f76a9d78d200ecdab7f80 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 13 Mar 2024 11:05:13 +0100 Subject: [PATCH 288/423] Refactored code on `evaluate` like suggested --- .../rpgparser/interpreter/compile_time_interpreter.kt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt index cbf2b1577..b2c68f3f9 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/compile_time_interpreter.kt @@ -75,14 +75,10 @@ open class BaseCompileTimeInterpreter( is NumberOfElementsExpr -> IntValue(evaluateNumberOfElementsOf(rContext, expression.value).toLong()) is IntLiteral -> IntValue(expression.value) is StringLiteral -> StringValue(expression.value) - is DataRefExpr -> { - expression.variable.tryToResolve(knownDataDefinitions) - if (expression.variable.referred != null) { - return this.evaluate(rContext, (expression.variable.referred as? DataDefinition)?.initializationValue as Expression) - } - + is DataRefExpr -> if (expression.variable.tryToResolve(knownDataDefinitions)) + return this.evaluate(rContext, (expression.variable.referred as? DataDefinition)?.initializationValue as Expression) + else TODO(expression.toString()) - } else -> TODO(expression.toString()) } } From 5a5e3bb4e24dc7f7809a5c3a12ed5a02cba2bd88 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Wed, 13 Mar 2024 11:22:43 +0100 Subject: [PATCH 289/423] Removed condition on compiler directive resolution, as requested by code owner --- .../com/smeup/rpgparser/parsing/facade/preprocess.kt | 10 +++------- .../kotlin/com/smeup/rpgparser/parsing/CopyTest.kt | 6 ++---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt index 43fd67a20..b682354c7 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt @@ -7,12 +7,11 @@ import java.io.BufferedReader import java.io.InputStream import kotlin.system.measureTimeMillis -internal fun InputStream.preprocess( +fun InputStream.preprocess( findCopy: (copyId: CopyId) -> String?, onStartInclusion: (copyId: CopyId, start: Int) -> Unit = { _: CopyId, _: Int -> }, onEndInclusion: (end: Int) -> Unit = { _: Int -> }, - beforeInclusion: (copyId: CopyId) -> Boolean = { true }, - resolveDirectives: Boolean = true + beforeInclusion: (copyId: CopyId) -> Boolean = { true } ): String { val programName = getExecutionProgramNameWithNoExtension() MainExecutionContext.log(PreprocessingLogStart(programName = programName)) @@ -23,10 +22,7 @@ internal fun InputStream.preprocess( onStartInclusion = onStartInclusion, onEndInclusion = onEndInclusion, beforeInclusion = beforeInclusion - ) - if (resolveDirectives) { - preprocessed = preprocessed.resolveCompilerDirectives() - } + ).resolveCompilerDirectives() }.apply { MainExecutionContext.log( PreprocessingLogEnd( diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt index 6cafce55b..5e3a182a6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt @@ -164,8 +164,7 @@ class CopyTest { findCopy = { copyId -> File("$srcRoot/${copyId.key(CopyFileExtension.rpgle)}").readText(charset = Charsets.UTF_8) .apply { copyDefinitions[copyId] = this } - }, - resolveDirectives = false + } ) absoluteLinesMatchingRelativeLine(pgm = pgm, copyDefinitions) } @@ -175,8 +174,7 @@ class CopyTest { val preprocessed = pgm.byteInputStream().preprocess( findCopy = { copyId -> copyDefinitions[copyId] }, onStartInclusion = { copyId, start -> copyBlocks.onStartCopyBlock(copyId, start) }, - onEndInclusion = { end -> copyBlocks.onEndCopyBlock(end) }, - resolveDirectives = false + onEndInclusion = { end -> copyBlocks.onEndCopyBlock(end) } ) preprocessed.lines().forEachIndexed { index, expectedLineOfCode -> println("index: $index, expectedLineOfCode:$expectedLineOfCode") From d90af8aef55dbd85da4821d1786d313f7a760f7c Mon Sep 17 00:00:00 2001 From: Domenico Date: Wed, 13 Mar 2024 14:15:19 +0100 Subject: [PATCH 290/423] Add unit tests for new ScanStmt logic --- .../evaluation/SmeupInterpreterTest.kt | 12 +++++++++++ .../test/resources/smeup/T10_A35_P08.rpgle | 18 +++++++++++++++++ .../test/resources/smeup/T10_A35_P10.rpgle | 20 +++++++++++++++++++ 3 files changed, 50 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P08.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P10.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index b9a9a76c4..c9ef84148 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -598,6 +598,18 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T40_A20_P26".outputOf(configuration = smeupConfig)) } + @Test + fun executeT10_A35_P08() { + val expected = listOf("A35_AR1(2)(123&5) IN45(1)") + assertEquals(expected, "smeup/T10_A35_P08".outputOf(configuration = smeupConfig)) + } + + @Test + fun executeT10_A35_P10() { + val expected = listOf("A35_AR2(01)(5) A35_AR2(02)(6) A35_AR2(03)(0) IN20(1)") + assertEquals(expected, "smeup/T10_A35_P10".outputOf(configuration = smeupConfig)) + } + @Test fun executeT18_A10_P01() { val expected = listOf("Ritorno_Procedura") diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P08.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P08.rpgle new file mode 100644 index 000000000..e37b2aaa5 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P08.rpgle @@ -0,0 +1,18 @@ + D £DBG_Str S 150 VARYING + D A35_AR1 S 70 DIM(10) + D A35_A1 S 6 + D A35_A2 S 1 + D A35_AR2 S 2 0 DIM(5) + D $A S 1 0 + D I S 2 0 + + C EVAL A35_AR1(1)='ABCDEF' + C EVAL A35_AR1(2)='123&5' + C EVAL A35_AR1(3)='TEST&' + C EVAL I = 2 + C '&' SCAN A35_AR1(I):1 45 + C EVAL £DBG_Str= + C 'A35_AR1(2)('+%TRIMR(A35_AR1(2))+') ' + C +'IN45('+%CHAR(*IN45)+')' + + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P10.rpgle new file mode 100644 index 000000000..976940a27 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A35_P10.rpgle @@ -0,0 +1,20 @@ + D £DBG_Str S 150 VARYING + D A35_AR1 S 70 DIM(10) + D A35_A1 S 6 + D A35_A2 S 1 + D A35_AR2 S 2 0 DIM(5) + D $A S 1 0 + D I S 2 0 + + C SETOFF 20 + C EVAL A35_A1='YARRYY' + C EVAL A35_A2='Y' + C EVAL $A=3 + C A35_A2 SCAN A35_A1:$A A35_AR2 20 + C EVAL £DBG_Str= + C 'A35_AR2(01)('+%CHAR(A35_AR2(01))+') ' + C +'A35_AR2(02)('+%CHAR(A35_AR2(02))+') ' + C +'A35_AR2(03)('+%CHAR(A35_AR2(03))+') ' + C +'IN20('+%CHAR(*IN20)+')' + + C £DBG_Str DSPLY \ No newline at end of file From 384e4df2f47a99999f8cd01962bd955f1b47ae3a Mon Sep 17 00:00:00 2001 From: Domenico Date: Wed, 13 Mar 2024 14:15:41 +0100 Subject: [PATCH 291/423] Extend ScanStmt to support expressions after colons --- .../smeup/rpgparser/parsing/ast/statements.kt | 8 +++-- .../rpgparser/parsing/parsetreetoast/misc.kt | 36 +++++++++++++------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 531d89063..611475750 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1704,7 +1704,7 @@ data class ScanStmt( val left: Expression, val leftLength: Int?, val right: Expression, - val startPosition: Int, + val startPosition: Expression?, val target: AssignableExpression?, val rightIndicators: WithRightIndicators, @Derived val dataDefinition: InStatementDataDefinition? = null, @@ -1712,13 +1712,15 @@ data class ScanStmt( ) : Statement(position), WithRightIndicators by rightIndicators, StatementThatCanDefineData { override fun execute(interpreter: InterpreterCore) { + val start = startPosition?.let { interpreter.eval(it).asString().value.toInt() } ?: 1 + val stringToSearch = interpreter.eval(left).asString().value.substringOfLength(leftLength) - val searchInto = interpreter.eval(right).asString().value.substring(startPosition - 1) + val searchInto = interpreter.eval(right).asString().value.substring(start - 1) val occurrences = mutableListOf() var index = -1 do { index = searchInto.indexOf(stringToSearch, index + 1) - if (index >= 0) occurrences.add(IntValue((index + startPosition).toLong())) + if (index >= 0) occurrences.add(IntValue((index + start).toLong())) } while (index >= 0) if (occurrences.isEmpty()) { interpreter.setIndicators(this, BooleanValue.FALSE, BooleanValue.FALSE, BooleanValue.FALSE) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index cbc2f9014..fd6dc60c2 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1316,20 +1316,31 @@ internal fun CsDELETEContext.toAst(conf: ToAstConfiguration): Statement { internal fun CsSCANContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): ScanStmt { val position = toPosition(conf.considerPosition) + val (compareExpression, compareLength) = this.factor1Context().toIndexedExpression(conf) - val (baseExpression, startPosition) = this.cspec_fixed_standard_parts().factor2.toIndexedExpression(conf) + + val factor2 = this.cspec_fixed_standard_parts().factor2 + + val result = this.cspec_fixed_standard_parts().result + val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result.text, position, conf) + val rightIndicators = cspec_fixed_standard_parts().rightIndicators() - val result = this.cspec_fixed_standard_parts().result.text - val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) - val target = when { - result.isNotBlank() -> this.cspec_fixed_standard_parts()!!.result!!.toAst(conf) - else -> null - } + val target = if (result.text.isNotBlank()) result.toAst(conf) else null + + val baseExpression = factor2.factorContent(0).toAst(conf) + // and "B" is the start position to substring, if not specified it returns null + val positionExpression = + if (factor2.factorContent().size > 1) { + factor2.factorContent(1).toAst(conf) + } else { + null + } + return ScanStmt( left = compareExpression, leftLength = compareLength, right = baseExpression, - startPosition = startPosition ?: 1, + startPosition = positionExpression, target = target, rightIndicators = rightIndicators, dataDefinition = dataDefinition, @@ -1378,8 +1389,6 @@ private fun FactorContext.toIndexedExpression(conf: ToAstConfiguration): Pair { - fun String.isLiteral(): Boolean { return (startsWith('\'') && endsWith('\'')) } - val baseStringTokens = this.split(":") val startPosition = when (baseStringTokens.size) { @@ -1389,7 +1398,10 @@ private fun String.toIndexedExpression(position: Position?): Pair StringLiteral(reference.trim('\''), position) + reference.isStringLiteral() -> StringLiteral(reference.trim('\''), position) + reference.contains('(') && reference.endsWith(")") -> { + annidatedReferenceExpression(this, position) + } else -> DataRefExpr(ReferenceByName(reference), position) } to startPosition } @@ -2024,3 +2036,5 @@ private fun List.removeUnnecessaryRecordFormat() dataDef.type is RecordFormatType && this.any { it.type is DataStructureType && it.name.uppercase() == dataDef.name.uppercase() } } } + +private fun String.isStringLiteral(): Boolean = startsWith('\'') && endsWith('\'') \ No newline at end of file From 1e0308cf27604fb88945a6fc7e801bc7cef9a767 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Wed, 13 Mar 2024 11:22:43 +0100 Subject: [PATCH 292/423] Unused rows after compiler directive resolution are trasformed in comments --- .../parsing/facade/compilerDirectives.kt | 208 +++++++++++------- .../rpgparser/parsing/facade/preprocess.kt | 10 +- .../com/smeup/rpgparser/parsing/CopyTest.kt | 10 +- 3 files changed, 135 insertions(+), 93 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt index 9b7b34536..a0c203738 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt @@ -47,13 +47,16 @@ internal fun String.resolveEOFDirective(): String { // Split input text into rows val rows = this.lines() var result = "" + var useRow = true for (row in rows) { if (EOF_PATTERN.matches(row)) { - // Break loop if EOF found - break + useRow = false + result += row.transformToComment().plus("\n") } else { - if (row.length > 0) { + if (useRow) { result += row.plus("\n") + } else { + result += row.transformToComment().plus("\n") } } } @@ -71,108 +74,153 @@ internal fun String.resolveCompilerDirectives(): String { val definitions = mutableListOf() var useRow = true var eofInvoked = false + var directiveRow = false // Split input text into rows val rows = this.lines() // Check each row against regex patterns for ((index, row) in rows.withIndex()) { - when { - IF_DEFINED_PATTERN.matches(row) -> { - // Control if IF_DEFINED is acceptable - val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) - if (!acceptedLastCodes.any { it == lastCode }) { + // if eof invoked manage all remaining rows as comments + if (!eofInvoked) { + when { + IF_DEFINED_PATTERN.matches(row) -> { + directiveRow = true + // Control if IF_DEFINED is acceptable + val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) + if (!acceptedLastCodes.any { it == lastCode }) { val exc = CompilerDirectivesException("Unexpected IF_DEFINED directive at line " + (index + 1)) throw AstCreatingException(this, exc).fireErrorEvent(null) + } + + lastCode = SYN_RELEVANT_DIRECTIVES.IF_DEFINED + val matchResult = IF_DEFINED_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + useRow = isDefined(definitions, code) + } else { + val exc = + CompilerDirectivesException("IF_DEFINED directive without code value at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } } - lastCode = SYN_RELEVANT_DIRECTIVES.IF_DEFINED - val matchResult = IF_DEFINED_PATTERN.matchEntire(row) - val code = matchResult?.groups?.get(1)?.value - if (code != null) { - useRow = isDefined(definitions, code) - } else { - val exc = CompilerDirectivesException("IF_DEFINED directive without code value at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) - } - } - IF_NOT_DEFINED_PATTERN.matches(row) -> { - // Control if IF_NOT_DEFINED is acceptable - val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) - if (!acceptedLastCodes.any { it == lastCode }) { - val exc = CompilerDirectivesException("Unexpected IF_NOT_DEFINED directive at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + IF_NOT_DEFINED_PATTERN.matches(row) -> { + directiveRow = true + // Control if IF_NOT_DEFINED is acceptable + val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) + if (!acceptedLastCodes.any { it == lastCode }) { + val exc = + CompilerDirectivesException("Unexpected IF_NOT_DEFINED directive at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } + + lastCode = SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED + val matchResult = IF_NOT_DEFINED_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + useRow = !isDefined(definitions, code) + } else { + val exc = + CompilerDirectivesException("IF_NOT_DEFINED directive without code value at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } } - lastCode = SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED - val matchResult = IF_NOT_DEFINED_PATTERN.matchEntire(row) - val code = matchResult?.groups?.get(1)?.value - if (code != null) { - useRow = !isDefined(definitions, code) - } else { - val exc = CompilerDirectivesException("IF_NOT_DEFINED directive without code value at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + DEFINE_PATTERN.matches(row) -> { + directiveRow = true + // Define directive is always acceptable + val matchResult = DEFINE_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + definitions.add(code.uppercase()) + } else { + val exc = + CompilerDirectivesException("DEFINE directive without code value at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } } - } - DEFINE_PATTERN.matches(row) -> { - // Define directive is always acceptable - val matchResult = DEFINE_PATTERN.matchEntire(row) - val code = matchResult?.groups?.get(1)?.value - if (code != null) { - definitions.add(code.uppercase()) - } else { - val exc = CompilerDirectivesException("DEFINE directive without code value at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + + UNDEFINE_PATTERN.matches(row) -> { + directiveRow = true + // Undefine directive is always acceptable + val matchResult = UNDEFINE_PATTERN.matchEntire(row) + val code = matchResult?.groups?.get(1)?.value + if (code != null) { + definitions.remove(code.uppercase()) + } else { + val exc = + CompilerDirectivesException("UNDEFINE directive without code value at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } } - } - UNDEFINE_PATTERN.matches(row) -> { - // Undefine directive is always acceptable - val matchResult = UNDEFINE_PATTERN.matchEntire(row) - val code = matchResult?.groups?.get(1)?.value - if (code != null) { - definitions.remove(code.uppercase()) - } else { - val exc = CompilerDirectivesException("UNDEFINE directive without code value at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + + ELSE_PATTERN.matches(row) -> { + directiveRow = true + // Control if ELSE is acceptable + val acceptedLastCodes = + listOf(SYN_RELEVANT_DIRECTIVES.IF_DEFINED, SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED) + if (!acceptedLastCodes.any { it == lastCode }) { + val exc = CompilerDirectivesException("Unexpected ELSE directive at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } + + lastCode = SYN_RELEVANT_DIRECTIVES.ELSE + useRow = !useRow } - } - ELSE_PATTERN.matches(row) -> { - // Control if ELSE is acceptable - val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.IF_DEFINED, SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED) - if (!acceptedLastCodes.any { it == lastCode }) { - val exc = CompilerDirectivesException("Unexpected ELSE directive at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + + ENDIF_PATTERN.matches(row) -> { + directiveRow = true + // Control if ENDIF is acceptable + val acceptedLastCodes = listOf( + SYN_RELEVANT_DIRECTIVES.IF_DEFINED, + SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED, + SYN_RELEVANT_DIRECTIVES.ELSE + ) + if (!acceptedLastCodes.any { it == lastCode }) { + val exc = CompilerDirectivesException("Unexpected ENDIF directive at line " + (index + 1)) + throw AstCreatingException(this, exc).fireErrorEvent(null) + } + + lastCode = SYN_RELEVANT_DIRECTIVES.ENDIF + useRow = true } - lastCode = SYN_RELEVANT_DIRECTIVES.ELSE - useRow = !useRow - } - ENDIF_PATTERN.matches(row) -> { - // Control if ENDIF is acceptable - val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.IF_DEFINED, SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED, SYN_RELEVANT_DIRECTIVES.ELSE) - if (!acceptedLastCodes.any { it == lastCode }) { - val exc = CompilerDirectivesException("Unexpected ENDIF directive at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + EOF_PATTERN.matches(row) -> { + directiveRow = true + eofInvoked = true + useRow = false } - lastCode = SYN_RELEVANT_DIRECTIVES.ENDIF - useRow = true - } - EOF_PATTERN.matches(row) -> { - eofInvoked = true - useRow = false - } - else -> { - if (useRow && row.length > 0) { - result += row.plus("\n") + else -> { + directiveRow = false } } } - // Exit loop if EOF invoked - if (eofInvoked) break + + if (directiveRow || eofInvoked) { + // Comment directives row and all rows after an EOF directive + result += row.transformToComment().plus("\n") + } else if (useRow) { + result += row.plus("\n") + } else { + // Transform row in comment because declared as unused after directive resolution + result += row.transformToComment().plus("\n") + } } return result } +private fun String.transformToComment(): String { + val newString: String + if (this.length >= 7) { + newString = this.substring(0, 6) + '*' + this.substring(7) + } else { + val padding = " " + newString = this + padding.substring(0, 7 - this.length) + '*' + } + return newString +} + private fun containDirectives(inputString: String): Boolean { return inputString.contains(EOF_DIRECTIVE_KEYWORD, true) || DIRECTIVES_KEYWORDS.any { keyword -> inputString.contains(keyword, ignoreCase = true) } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt index 43fd67a20..b682354c7 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/preprocess.kt @@ -7,12 +7,11 @@ import java.io.BufferedReader import java.io.InputStream import kotlin.system.measureTimeMillis -internal fun InputStream.preprocess( +fun InputStream.preprocess( findCopy: (copyId: CopyId) -> String?, onStartInclusion: (copyId: CopyId, start: Int) -> Unit = { _: CopyId, _: Int -> }, onEndInclusion: (end: Int) -> Unit = { _: Int -> }, - beforeInclusion: (copyId: CopyId) -> Boolean = { true }, - resolveDirectives: Boolean = true + beforeInclusion: (copyId: CopyId) -> Boolean = { true } ): String { val programName = getExecutionProgramNameWithNoExtension() MainExecutionContext.log(PreprocessingLogStart(programName = programName)) @@ -23,10 +22,7 @@ internal fun InputStream.preprocess( onStartInclusion = onStartInclusion, onEndInclusion = onEndInclusion, beforeInclusion = beforeInclusion - ) - if (resolveDirectives) { - preprocessed = preprocessed.resolveCompilerDirectives() - } + ).resolveCompilerDirectives() }.apply { MainExecutionContext.log( PreprocessingLogEnd( diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt index 6cafce55b..99d44dc44 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/parsing/CopyTest.kt @@ -164,8 +164,7 @@ class CopyTest { findCopy = { copyId -> File("$srcRoot/${copyId.key(CopyFileExtension.rpgle)}").readText(charset = Charsets.UTF_8) .apply { copyDefinitions[copyId] = this } - }, - resolveDirectives = false + } ) absoluteLinesMatchingRelativeLine(pgm = pgm, copyDefinitions) } @@ -175,18 +174,17 @@ class CopyTest { val preprocessed = pgm.byteInputStream().preprocess( findCopy = { copyId -> copyDefinitions[copyId] }, onStartInclusion = { copyId, start -> copyBlocks.onStartCopyBlock(copyId, start) }, - onEndInclusion = { end -> copyBlocks.onEndCopyBlock(end) }, - resolveDirectives = false + onEndInclusion = { end -> copyBlocks.onEndCopyBlock(end) } ) preprocessed.lines().forEachIndexed { index, expectedLineOfCode -> println("index: $index, expectedLineOfCode:$expectedLineOfCode") - if (!expectedLineOfCode.startsWith("**********")) { + if (expectedLineOfCode.length > 0 && !expectedLineOfCode.startsWith("**********")) { val relativeLine = copyBlocks.relativeLine(index + 1) println("relativeLine: $relativeLine") val actualLineOfCode = relativeLine.second?.let { copyBlock -> copyDefinitions[copyBlock.copyId]!!.lines()[relativeLine.first - 1] } ?: pgm.lines()[relativeLine.first - 1] - if (!actualLineOfCode.contains("/COPY")) { + if (!actualLineOfCode.contains("/COPY") && !expectedLineOfCode.startsWith(" *")) { println("expectedLineOfCode: $expectedLineOfCode, actualLineOfCode: $actualLineOfCode") Assert.assertEquals(expectedLineOfCode, actualLineOfCode) } From c3e25ad53176e82cf7a814c9f7bbbfc7a73d27c6 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 14 Mar 2024 10:59:19 +0100 Subject: [PATCH 293/423] Add unit tests for T40_A30 --- .../evaluation/SmeupInterpreterTest.kt | 12 +++++++ .../test/resources/smeup/T40_A30_P01.rpgle | 32 ++++++++++++++++++ .../test/resources/smeup/T40_A30_P03.rpgle | 33 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T40_A30_P01.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T40_A30_P03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index b9a9a76c4..c52ea855b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -631,4 +631,16 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("TestProcedura_Ritorno") assertEquals(expected, "smeup/T18_A10_P02".outputOf()) } + + @Test + fun executeT40_A30_P01() { + val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") + assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) + } + + @Test + fun executeT40_A30_P03() { + val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") + assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A30_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A30_P01.rpgle new file mode 100644 index 000000000..81a9fe075 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A30_P01.rpgle @@ -0,0 +1,32 @@ + D £DBG_Str S 150 VARYING + d A30_DS_P01A e ds extname(mulangtf) inz + d prefix(S1:2) + D A30_DS_P01C E DS EXTNAME(mulangtf) INZ + D PREFIX(S3:2) + + C EVAL £DBG_Str='Lunghezza: ' + C +%CHAR(%LEN(A30_DS_P01A)) + C +' Contenuto: ' + C +S1SYST + C +'-'+S1LIBR + C +'-'+S1FILE + C +'-'+S1TIPO + C +'-'+S1PROG + C +'-'+S1PSEZ + C +'-'+S1PPAS + C +'-'+S1PDES + C +'-'+S1SQIN + C +'-'+S1SQFI + C +'-'+S1AAAT + C +'-'+S1AAVA + C +'-'+%CHAR(S1NNAT) + C +'-'+%CHAR(S1NNVA) + C +'-'+S1INDI + C +'-'+%CHAR(S1TEES) + C +'-'+S1USES + C +'-'+%CHAR(S1DTES) + C +'-'+%CHAR(S1ORES) + C +'-'+S1ASLA + C +'-'+%CHAR(S1ASNR) + + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A30_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A30_P03.rpgle new file mode 100644 index 000000000..f71e348cd --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A30_P03.rpgle @@ -0,0 +1,33 @@ + D £DBG_Str S 150 VARYING + d A30_DS_P01A e ds extname(mulangtf) inz + d prefix(S1:2) + D A30_DS_P01C E DS EXTNAME(mulangtf) INZ + D PREFIX(S3:2) + + C EVAL £DBG_Str='Lunghezza: ' + C +%CHAR(%LEN(A30_DS_P01C)) + C +' Contenuto: ' + C +S3SYST + C +'-'+S3LIBR + C +'-'+S3FILE + C +'-'+S3TIPO + C +'-'+S3PROG + C +'-'+S3PSEZ + C +'-'+S3PPAS + C +'-'+S3PDES + C +'-'+S3SQIN + C +'-'+S3SQFI + C +'-'+S3AAAT + C +'-'+S3AAVA + C +'-'+%CHAR(S3NNAT) + C +'-'+%CHAR(S3NNVA) + C +'-'+S3INDI + C +'-'+%CHAR(S3TEES) + C +'-'+S3USES + C +'-'+%CHAR(S3DTES) + C +'-'+%CHAR(S3ORES) + C +'-'+S3ASLA + C +'-'+%CHAR(S3ASNR) + C EXSR £DBG + + C £DBG_Str DSPLY \ No newline at end of file From 5f512c87132389adca921320e880a95653d0c37f Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 14 Mar 2024 10:59:58 +0100 Subject: [PATCH 294/423] Make ExtName case insensitive --- .../parsing/parsetreetoast/data_definitions.kt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) 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 d89dbfdb0..df122d084 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 @@ -1066,13 +1066,25 @@ internal fun RpgParser.Dcl_dsContext.toAstWithExtName( ): () -> DataDefinition { return { val keywordExtName = getKeywordExtName() - val extName = keywordExtName.getExtName() val keywordPrefix = getKeywordPrefix() + + val extName = keywordExtName.getExtName() val prefixName = keywordPrefix?.getPrefixName() - val dataDefinitions = fileDefinitions.filter { it.key.name == extName && ((keywordPrefix == null && it.key.prefix == null) || (keywordPrefix != null && it.key.prefix != null && it.key.prefix is Prefix && it.key.prefix!!.prefix == prefixName)) }.values.flatten() + + val dataDefinitions = + fileDefinitions.filter { + val nameMatches = it.key.name.uppercase() == extName.uppercase() + val prefixIsNull = keywordPrefix == null && it.key.prefix == null + val prefixIsValid = keywordPrefix != null && it.key.prefix != null && it.key.prefix is Prefix + val prefixMatches = prefixIsValid && it.key.prefix?.prefix == prefixName + + nameMatches && (prefixIsNull || prefixMatches) + }.values.flatten() + if (dataDefinitions.isEmpty()) { keywordExtName.error(message = "Datadefinition $extName not found", conf = conf) } + var offset = 0 val fields = dataDefinitions.map { FieldDefinition( From 9322369c69d42ef4c9352527cef870024634d70e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 14 Mar 2024 11:03:28 +0100 Subject: [PATCH 295/423] Replaced old code for `internal_interpreter` --- .../rpgparser/interpreter/internal_interpreter.kt | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 52b8a79dd..ed356bd9b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -717,19 +717,11 @@ open class InternalInterpreter( // calculation of rest // NB. rest based on type of quotient if (statement.mvrStatement != null) { - val restType = when { - statement.mvrStatement.dataDefinition != null -> statement.mvrStatement.dataDefinition.type - statement.mvrStatement.target != null -> statement.mvrStatement.target.type() - else -> null - } + val restType = statement.mvrStatement.target?.type() require(restType is NumberType) val truncatedQuotient: BigDecimal = quotient.setScale(type.decimalDigits, RoundingMode.DOWN) - // rest = divident - (truncatedQuotient * divisor) val rest: BigDecimal = dividend.subtract(truncatedQuotient.multiply(divisor)) - when { - statement.mvrStatement.dataDefinition != null -> assign(statement.mvrStatement.dataDefinition, DecimalValue(rest.setScale(restType.decimalDigits, RoundingMode.DOWN))) - statement.mvrStatement.target != null -> assign(statement.mvrStatement.target, DecimalValue(rest.setScale(restType.decimalDigits, RoundingMode.DOWN))) - } + assign(statement.mvrStatement.target, DecimalValue(rest.setScale(restType.decimalDigits, RoundingMode.DOWN))) } return if (statement.halfAdjust) { DecimalValue(quotient.setScale(type.decimalDigits, RoundingMode.HALF_UP)) From 67bbced44f25afe3fe4ddb0e02516fe4c3a0f53f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 14 Mar 2024 11:12:32 +0100 Subject: [PATCH 296/423] Improved `resolution` for `scanInDepthStatementDataDefinition` --- .../parsing/parsetreetoast/resolution.kt | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt index ac49756fd..70c441a61 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt @@ -31,13 +31,12 @@ import com.strumenta.kolasu.validation.ErrorType import java.util.* private fun CompilationUnit.findInStatementDataDefinitions() { - // TODO could they be also annidated? this.allStatements(preserveCompositeStatement = true).forEach { - this.addInStatementDataDefinitions(scanInDephStatementDataDefinition(it)) + this.addInStatementDataDefinitions(scanInDepthStatementDataDefinition(it)) } } -private fun scanInDephStatementDataDefinition(node: Node): List { +private fun scanInDepthStatementDataDefinition(node: Node): List { val list = mutableListOf() return when { node is CompositeStatement -> { @@ -46,15 +45,15 @@ private fun scanInDephStatementDataDefinition(node: Node): List { @@ -68,6 +67,17 @@ private fun scanInDephStatementDataDefinition(node: Node): List.addAllDistinct(list: List): List { + list.forEach { item -> + run { + if (this.isEmpty() || this.any { it.name != item.name }) { + this.add(item) + } + } + } + return this +} + fun CompilationUnit.allStatements(preserveCompositeStatement: Boolean = false): List { val result = mutableListOf() result.addAll(this.main.stmts.explode(preserveCompositeStatement = preserveCompositeStatement)) From 9d296e81986b91710f760646569a93869da161bf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 14 Mar 2024 11:32:50 +0100 Subject: [PATCH 297/423] Implemented case of test --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T02_A80_P03.rpgle | 10 ++++++++++ 2 files changed, 16 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index cbc19d86b..9edd3ab72 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -647,4 +647,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("TestProcedura_Ritorno") assertEquals(expected, "smeup/T18_A10_P02".outputOf()) } + + @Test + fun executeT02_A80_P03() { + val expected = listOf("123") + assertEquals(expected, "smeup/T02_A80_P03".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P03.rpgle new file mode 100644 index 000000000..f031d7a69 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P03.rpgle @@ -0,0 +1,10 @@ + D A80_A10 S 10 + D A80_N50 S 5 0 + D A80_NN3 S 3 0 + D £DBG_Str S 50 VARYING + + C CLEAR A80_N30 3 0 + C *LIKE DEFINE A80_NN3 A80_N30 + C EVAL A80_N30 = 123 + C EVAL £DBG_Str=%CHAR(A80_N30) + C £DBG_Str DSPLY \ No newline at end of file From 76fb4e966c48ba80961340ad034eb2f790d82e48 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 14 Mar 2024 13:26:47 +0100 Subject: [PATCH 298/423] Restored `resolutions` --- .../parsing/parsetreetoast/resolution.kt | 35 ++----------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt index 70c441a61..bd240e581 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt @@ -31,39 +31,8 @@ import com.strumenta.kolasu.validation.ErrorType import java.util.* private fun CompilationUnit.findInStatementDataDefinitions() { - this.allStatements(preserveCompositeStatement = true).forEach { - this.addInStatementDataDefinitions(scanInDepthStatementDataDefinition(it)) - } -} - -private fun scanInDepthStatementDataDefinition(node: Node): List { - val list = mutableListOf() - return when { - node is CompositeStatement -> { - /* Is possible that the node is both CompositeStatement and StatementThatCanDefineData. */ - if (node is StatementThatCanDefineData) { - list.addAll(node.dataDefinition()) - } - - if (node is SelectStmt) { - node.cases.forEach { - list.addAllDistinct(scanInDepthStatementDataDefinition(it)) - } - } - - node.body.forEach { - list.addAllDistinct(scanInDepthStatementDataDefinition(it)) - } - return list - } - node is StatementThatCanDefineData -> { - if (node is DivStmt) { - node.mvrStatement?.let { list.addAll(it.dataDefinition()) } - } - list.addAll(node.dataDefinition()) - return list - } - else -> emptyList() + this.allStatements(preserveCompositeStatement = true).filterIsInstance(StatementThatCanDefineData::class.java).forEach { + this.addInStatementDataDefinitions(it.dataDefinition()) } } From 25d49eed22c05c3e43f43ac43d6190e2ed47fa2b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 14 Mar 2024 13:27:13 +0100 Subject: [PATCH 299/423] Fixed behaviour of `SelectStmt` --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 1c271d464..1236e4f68 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -185,9 +185,9 @@ data class SelectStmt( get() { val result = mutableListOf() cases.forEach { case -> - result.addAll(case.body.explode()) + result.addAll(case.body.explode(preserveCompositeStatement = true)) } - if (other?.body != null) result.addAll(other!!.body.explode()) + if (other?.body != null) result.addAll(other!!.body.explode(preserveCompositeStatement = true)) return result } } From df9d634b553f5d721082e544e8aa294343a885a2 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 14 Mar 2024 13:27:25 +0100 Subject: [PATCH 300/423] Improved `DivStmt` --- .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 1236e4f68..16d630be7 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1163,7 +1163,7 @@ data class DivStmt( val mvrStatement: MvrStmt? = null, @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null -) : Statement(position), StatementThatCanDefineData { +) : Statement(position), CompositeStatement, StatementThatCanDefineData { @Transient @Derived val dividend: Expression @@ -1179,6 +1179,11 @@ data class DivStmt( } override fun dataDefinition() = dataDefinition?.let { listOf(it) } ?: emptyList() + + @Transient + @Derived + override val body: List + get() = mvrStatement?.let { listOf(it) } ?: emptyList() } @Serializable From 01571bc21efcc5e1ddfb742dcafcb5d2ba11c951 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 14 Mar 2024 14:22:50 +0100 Subject: [PATCH 301/423] Add unit test T10_A20_P52 --- .../evaluation/SmeupInterpreterTest.kt | 6 ++++ .../test/resources/smeup/T10_A20_P52.rpgle | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P52.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index cbc19d86b..4d3ec749b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -647,4 +647,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("TestProcedura_Ritorno") assertEquals(expected, "smeup/T18_A10_P02".outputOf()) } + + @Test + fun executeT10_A20_P52() { + val expected = listOf("A20_N73(2.272) A20_N70(0) A20_N112(11.11) A20_N110(0) A20_N309(4.889964788)") + assertEquals(expected, "smeup/T10_A20_P52".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P52.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P52.rpgle new file mode 100644 index 000000000..932244957 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A20_P52.rpgle @@ -0,0 +1,28 @@ + D £DBG_Str S 150 VARYING + + D A20_N70 S 20P 0 + D A20_N73 S 20P 3 + D A20_N110 S 11P 0 + D A20_N112 S 11P 2 + D A20_N309 S 30P 9 + + C EXSR SUB_A20_I + C EVAL £DBG_Str='A20_N73('+%CHAR(A20_N73)+')' + C +' A20_N70('+%CHAR(A20_N70)+')' + C +' A20_N112('+%CHAR(A20_N112)+')' + C +' A20_N110('+%CHAR(A20_N110)+')' + C +' A20_N309('+%CHAR(A20_N309)+')' + + C £DBG_Str DSPLY + + *--------------------------------------------------------------------- + C SUB_A20_I BEGSR + * + C SETOFF 22 + C SETON 23 + C N2225 DIV 11 A20_N73 + C N22 MVR A20_N70 + C 23100 DIV 9 A20_N112 + C 23 MVR A20_N110 + C A20_N112 DIV A20_N73 A20_N309 + C ENDSR From 45cc2e92a6f2b77de3b5f1a91f4253147d42111d Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 14 Mar 2024 14:23:14 +0100 Subject: [PATCH 302/423] Extend MVR parsing to allow for indicators --- rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index c94e52bc6..a6c37a809 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -1496,8 +1496,8 @@ csMULT: csMVR: CS_FIXED BlankIndicator - BlankFlag - BlankIndicator + (BlankFlag | NoFlag) + (BlankIndicator | GeneralIndicator) CS_BlankFactor operation=OP_MVR cspec_fixed_standard_parts; From 52db12ec9bfb6ccbc8a7f957aa7356bfec6375b7 Mon Sep 17 00:00:00 2001 From: Domenico Date: Thu, 14 Mar 2024 14:45:17 +0100 Subject: [PATCH 303/423] Cleanup --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index fd6dc60c2..82fecba6b 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1328,7 +1328,6 @@ internal fun CsSCANContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() val target = if (result.text.isNotBlank()) result.toAst(conf) else null val baseExpression = factor2.factorContent(0).toAst(conf) - // and "B" is the start position to substring, if not specified it returns null val positionExpression = if (factor2.factorContent().size > 1) { factor2.factorContent(1).toAst(conf) From 2900736c8d89248d404defc98130c81d50ad258e Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 14 Mar 2024 16:55:33 +0100 Subject: [PATCH 304/423] Small adjustments and comments made as requested by the code owner. --- .../parsing/facade/compilerDirectives.kt | 58 +++++++++---------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt index a0c203738..9d1acc855 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt @@ -35,7 +35,8 @@ val ENDIF_PATTERN = Regex(""".{6}/ENDIF""", RegexOption.IGNORE_CASE) val EOF_PATTERN = Regex(""".{6}/EOF""", RegexOption.IGNORE_CASE) /** - * Resolve the EOF directive: after this directive, all rows are ignored until the end of the file. + * Resolve the EOF directive: after this directive, all rows are ignored until the end of the file + * and marked in the result string as comments. * The resolution of this directive is separated from other directives because EOF resolution has * to be managed during /COPY directive resolution and cannot be done after all /COPY directives * are resolved. @@ -46,23 +47,29 @@ internal fun String.resolveEOFDirective(): String { } // Split input text into rows val rows = this.lines() - var result = "" + val result = StringBuffer() var useRow = true for (row in rows) { if (EOF_PATTERN.matches(row)) { useRow = false - result += row.transformToComment().plus("\n") + result.appendLine(row.transformToComment()) } else { if (useRow) { - result += row.plus("\n") + result.appendLine(row) } else { - result += row.transformToComment().plus("\n") + result.appendLine(row.transformToComment()) } } } - return result + return result.toString() } +/* +Receives an RPG source as string and resolves all embedded compile directives. +The response is a string where all lines that should not be executed after resolving +the compile directives are transformed into comment lines. The resolution of +compilation directives must be performed after the resolution of /COPY directives. +*/ internal fun String.resolveCompilerDirectives(): String { if (!containDirectives(this)) { @@ -70,7 +77,7 @@ internal fun String.resolveCompilerDirectives(): String { } var lastCode: SYN_RELEVANT_DIRECTIVES = SYN_RELEVANT_DIRECTIVES.NONE - var result = "" + val result = StringBuffer() val definitions = mutableListOf() var useRow = true var eofInvoked = false @@ -88,8 +95,7 @@ internal fun String.resolveCompilerDirectives(): String { // Control if IF_DEFINED is acceptable val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) if (!acceptedLastCodes.any { it == lastCode }) { - val exc = CompilerDirectivesException("Unexpected IF_DEFINED directive at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + throw CompilerDirectivesException("Unexpected IF_DEFINED directive at line " + (index + 1)).fireErrorEvent(null) } lastCode = SYN_RELEVANT_DIRECTIVES.IF_DEFINED @@ -98,9 +104,7 @@ internal fun String.resolveCompilerDirectives(): String { if (code != null) { useRow = isDefined(definitions, code) } else { - val exc = - CompilerDirectivesException("IF_DEFINED directive without code value at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + throw CompilerDirectivesException("IF_DEFINED directive without code value at line " + (index + 1)).fireErrorEvent(null) } } @@ -109,9 +113,7 @@ internal fun String.resolveCompilerDirectives(): String { // Control if IF_NOT_DEFINED is acceptable val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) if (!acceptedLastCodes.any { it == lastCode }) { - val exc = - CompilerDirectivesException("Unexpected IF_NOT_DEFINED directive at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + throw CompilerDirectivesException("Unexpected IF_NOT_DEFINED directive at line " + (index + 1)).fireErrorEvent(null) } lastCode = SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED @@ -120,9 +122,7 @@ internal fun String.resolveCompilerDirectives(): String { if (code != null) { useRow = !isDefined(definitions, code) } else { - val exc = - CompilerDirectivesException("IF_NOT_DEFINED directive without code value at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + throw CompilerDirectivesException("IF_NOT_DEFINED directive without code value at line " + (index + 1)).fireErrorEvent(null) } } @@ -134,9 +134,7 @@ internal fun String.resolveCompilerDirectives(): String { if (code != null) { definitions.add(code.uppercase()) } else { - val exc = - CompilerDirectivesException("DEFINE directive without code value at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + throw CompilerDirectivesException("DEFINE directive without code value at line " + (index + 1)).fireErrorEvent(null) } } @@ -148,9 +146,7 @@ internal fun String.resolveCompilerDirectives(): String { if (code != null) { definitions.remove(code.uppercase()) } else { - val exc = - CompilerDirectivesException("UNDEFINE directive without code value at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + throw CompilerDirectivesException("UNDEFINE directive without code value at line " + (index + 1)).fireErrorEvent(null) } } @@ -160,8 +156,7 @@ internal fun String.resolveCompilerDirectives(): String { val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.IF_DEFINED, SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED) if (!acceptedLastCodes.any { it == lastCode }) { - val exc = CompilerDirectivesException("Unexpected ELSE directive at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + throw CompilerDirectivesException("Unexpected ELSE directive at line " + (index + 1)).fireErrorEvent(null) } lastCode = SYN_RELEVANT_DIRECTIVES.ELSE @@ -177,8 +172,7 @@ internal fun String.resolveCompilerDirectives(): String { SYN_RELEVANT_DIRECTIVES.ELSE ) if (!acceptedLastCodes.any { it == lastCode }) { - val exc = CompilerDirectivesException("Unexpected ENDIF directive at line " + (index + 1)) - throw AstCreatingException(this, exc).fireErrorEvent(null) + throw CompilerDirectivesException("Unexpected ENDIF directive at line " + (index + 1)).fireErrorEvent(null) } lastCode = SYN_RELEVANT_DIRECTIVES.ENDIF @@ -199,15 +193,15 @@ internal fun String.resolveCompilerDirectives(): String { if (directiveRow || eofInvoked) { // Comment directives row and all rows after an EOF directive - result += row.transformToComment().plus("\n") + result.appendLine(row.transformToComment()) } else if (useRow) { - result += row.plus("\n") + result.appendLine(row) } else { // Transform row in comment because declared as unused after directive resolution - result += row.transformToComment().plus("\n") + result.appendLine(row.transformToComment()) } } - return result + return result.toString() } private fun String.transformToComment(): String { From cc56684937c1f2388dc3670e43a29508332d4054 Mon Sep 17 00:00:00 2001 From: Dario Foresti Date: Thu, 14 Mar 2024 16:57:42 +0100 Subject: [PATCH 305/423] Small adjustments and comments made as requested by the code owner. --- .../parsing/facade/compilerDirectives.kt | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt index 9d1acc855..a81768004 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/facade/compilerDirectives.kt @@ -1,7 +1,5 @@ package com.smeup.rpgparser.parsing.facade -import com.smeup.rpgparser.parsing.parsetreetoast.fireErrorEvent - /** * Directives that can be used only under certain conditions (for example, an ELSE must always follow an IF)." */ @@ -95,7 +93,7 @@ internal fun String.resolveCompilerDirectives(): String { // Control if IF_DEFINED is acceptable val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) if (!acceptedLastCodes.any { it == lastCode }) { - throw CompilerDirectivesException("Unexpected IF_DEFINED directive at line " + (index + 1)).fireErrorEvent(null) + throw CompilerDirectivesException("Unexpected IF_DEFINED directive at line " + (index + 1)) } lastCode = SYN_RELEVANT_DIRECTIVES.IF_DEFINED @@ -104,7 +102,7 @@ internal fun String.resolveCompilerDirectives(): String { if (code != null) { useRow = isDefined(definitions, code) } else { - throw CompilerDirectivesException("IF_DEFINED directive without code value at line " + (index + 1)).fireErrorEvent(null) + throw CompilerDirectivesException("IF_DEFINED directive without code value at line " + (index + 1)) } } @@ -113,7 +111,7 @@ internal fun String.resolveCompilerDirectives(): String { // Control if IF_NOT_DEFINED is acceptable val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.NONE, SYN_RELEVANT_DIRECTIVES.ENDIF) if (!acceptedLastCodes.any { it == lastCode }) { - throw CompilerDirectivesException("Unexpected IF_NOT_DEFINED directive at line " + (index + 1)).fireErrorEvent(null) + throw CompilerDirectivesException("Unexpected IF_NOT_DEFINED directive at line " + (index + 1)) } lastCode = SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED @@ -122,7 +120,7 @@ internal fun String.resolveCompilerDirectives(): String { if (code != null) { useRow = !isDefined(definitions, code) } else { - throw CompilerDirectivesException("IF_NOT_DEFINED directive without code value at line " + (index + 1)).fireErrorEvent(null) + throw CompilerDirectivesException("IF_NOT_DEFINED directive without code value at line " + (index + 1)) } } @@ -134,7 +132,7 @@ internal fun String.resolveCompilerDirectives(): String { if (code != null) { definitions.add(code.uppercase()) } else { - throw CompilerDirectivesException("DEFINE directive without code value at line " + (index + 1)).fireErrorEvent(null) + throw CompilerDirectivesException("DEFINE directive without code value at line " + (index + 1)) } } @@ -146,7 +144,7 @@ internal fun String.resolveCompilerDirectives(): String { if (code != null) { definitions.remove(code.uppercase()) } else { - throw CompilerDirectivesException("UNDEFINE directive without code value at line " + (index + 1)).fireErrorEvent(null) + throw CompilerDirectivesException("UNDEFINE directive without code value at line " + (index + 1)) } } @@ -156,7 +154,7 @@ internal fun String.resolveCompilerDirectives(): String { val acceptedLastCodes = listOf(SYN_RELEVANT_DIRECTIVES.IF_DEFINED, SYN_RELEVANT_DIRECTIVES.IF_NOT_DEFINED) if (!acceptedLastCodes.any { it == lastCode }) { - throw CompilerDirectivesException("Unexpected ELSE directive at line " + (index + 1)).fireErrorEvent(null) + throw CompilerDirectivesException("Unexpected ELSE directive at line " + (index + 1)) } lastCode = SYN_RELEVANT_DIRECTIVES.ELSE @@ -172,7 +170,7 @@ internal fun String.resolveCompilerDirectives(): String { SYN_RELEVANT_DIRECTIVES.ELSE ) if (!acceptedLastCodes.any { it == lastCode }) { - throw CompilerDirectivesException("Unexpected ENDIF directive at line " + (index + 1)).fireErrorEvent(null) + throw CompilerDirectivesException("Unexpected ENDIF directive at line " + (index + 1)) } lastCode = SYN_RELEVANT_DIRECTIVES.ENDIF From 16c5aa5ce5008819f7ea43ddf30014c8d08f448a Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 15 Mar 2024 08:49:06 +0100 Subject: [PATCH 306/423] Implemented test --- .../evaluation/SmeupInterpreterTest.kt | 6 +++ .../test/resources/smeup/T02_A40_P03.rpgle | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P03.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 9edd3ab72..bace88760 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -653,4 +653,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("123") assertEquals(expected, "smeup/T02_A80_P03".outputOf()) } + + @Test + fun executeT02_A40_P03() { + val expected = listOf("CNCLICNCLIAAAABBBBBAAAABBBBBCNFORCNFORCCCCDDDDDCCCCDDDDDCNCOLCNCOLEEEEFFFFFEEEEFFFFF") + assertEquals(expected, "smeup/T02_A40_P03".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P03.rpgle new file mode 100644 index 000000000..b1e322c3d --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P03.rpgle @@ -0,0 +1,40 @@ + D DS + D A40_DS10A 5 DIM(3) + D DS10A_FL1 2 OVERLAY(A40_DS10A:01) + D DS10A_FL2 3 OVERLAY(A40_DS10A:*NEXT) + D A40_DS10B 9 DIM(3) + D DS10B_FL1 4 OVERLAY(A40_DS10B:01) + D DS10B_FL2 5 OVERLAY(A40_DS10B:*NEXT) + D £DBG_Str S 150 VARYING + + C EVAL DS10A_FL1(1)='CN' + C EVAL DS10A_FL2(1)='CLI' + C EVAL DS10B_FL1(1)='AAAA' + C EVAL DS10B_FL2(1)='BBBBB' + C EVAL DS10A_FL1(2)='CN' + C EVAL DS10A_FL2(2)='FOR' + C EVAL DS10B_FL1(2)='CCCC' + C EVAL DS10B_FL2(2)='DDDDD' + C EVAL DS10A_FL1(3)='CN' + C EVAL DS10A_FL2(3)='COL' + C EVAL DS10B_FL1(3)='EEEE' + C EVAL DS10B_FL2(3)='FFFFF' + C EVAL £DBG_Str=%TRIM(A40_DS10A(1))+ + C %TRIM(DS10A_FL1(1))+ + C %TRIM(DS10A_FL2(1))+ + C %TRIM(A40_DS10B(1))+ + C %TRIM(DS10B_FL1(1))+ + C %TRIM(DS10B_FL2(1))+ + C %TRIM(A40_DS10A(2))+ + C %TRIM(DS10A_FL1(2))+ + C %TRIM(DS10A_FL2(2))+ + C %TRIM(A40_DS10B(2))+ + C %TRIM(DS10B_FL1(2))+ + C %TRIM(DS10B_FL2(2))+ + C %TRIM(A40_DS10A(3))+ + C %TRIM(DS10A_FL1(3))+ + C %TRIM(DS10A_FL2(3))+ + C %TRIM(A40_DS10B(3))+ + C %TRIM(DS10B_FL1(3))+ + C %TRIM(DS10B_FL2(3)) + C £DBG_Str DSPLY \ No newline at end of file From 6f2da7a2268a4f957c75dbc167f5111bdaa59c39 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 15 Mar 2024 08:49:26 +0100 Subject: [PATCH 307/423] Applied the fix --- .../parsing/parsetreetoast/data_definitions.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) 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 d89dbfdb0..744c9be7c 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 @@ -937,9 +937,13 @@ class FieldsList(val fields: List) { if (field.startOffset == null) { if (field.overlayInfo == null) { if (index > 0) { - val prevField = fields[index - 1] - if (prevField.endOffsetIncludingAllElement != null) { - field.startOffset = prevField.endOffsetIncludingAllElement + var step = index + while (step > 0) { + val prevField = fields[--step] + if (prevField.endOffsetIncludingAllElement != null) { + field.startOffset = prevField.endOffsetIncludingAllElement + break + } } } } From cd32465b6f0ff3661f36cc1a4ef98fd27ec66683 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 15 Mar 2024 09:12:29 +0100 Subject: [PATCH 308/423] Implemented test --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T02_A80_P02.rpgle | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 9edd3ab72..81e917f27 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -653,4 +653,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("123") assertEquals(expected, "smeup/T02_A80_P03".outputOf()) } + + @Test + fun executeT02_A80_P02() { + val expected = listOf("PROVA") + assertEquals(expected, "smeup/T02_A80_P02".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P02.rpgle new file mode 100644 index 000000000..b41c0f91d --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P02.rpgle @@ -0,0 +1,9 @@ + D A80_A10 S 10 + D A80_N50 S 5 0 + D A80_NN3 S 3 0 + D £DBG_Str S 50 VARYING + + C CLEAR £DBG_Mdv 18 + C EVAL £DBG_Mdv='PROVA' + C EVAL £DBG_Str=%TRIM(£DBG_Mdv) + C £DBG_Str DSPLY \ No newline at end of file From e79ad489ba2b476a0a5cd5fb68996e701648f6dc Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 15 Mar 2024 09:18:28 +0100 Subject: [PATCH 309/423] Implemented test --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T02_A80_P01.rpgle | 10 ++++++++++ 2 files changed, 16 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P01.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 9edd3ab72..943dd8282 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -653,4 +653,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("123") assertEquals(expected, "smeup/T02_A80_P03".outputOf()) } + + @Test + fun executeT02_A80_P01() { + val expected = listOf("ABCDEFGHIJ12345") + assertEquals(expected, "smeup/T02_A80_P01".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P01.rpgle new file mode 100644 index 000000000..6ae94378e --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P01.rpgle @@ -0,0 +1,10 @@ + D A80_A10 S 10 + D A80_N50 S 5 0 + D £DBG_Str S 50 VARYING + + C CLEAR A80_A10 10 + C CLEAR A80_N50 5 0 + C EVAL A80_A10 = 'ABCDEFGHIJ' + C EVAL A80_N50 = 12345 + C EVAL £DBG_Str=%TRIM(A80_A10)+%CHAR(A80_N50) + C £DBG_Str DSPLY \ No newline at end of file From 3edf4dd02bb5ba5a70516b78c582de410d3d3faf Mon Sep 17 00:00:00 2001 From: paolofacchinetti Date: Fri, 15 Mar 2024 11:49:06 +0100 Subject: [PATCH 310/423] chore(ci): bump checkout and setup-java, add gradle cache, set jvm distro to zulu --- .github/workflows/build.yml | 6 ++++-- .github/workflows/publish-smeup.yml | 6 ++++-- .github/workflows/publish.yml | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 021ad2a8b..b4b55951f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,11 +10,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - name: Set up JDK 11 - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: java-version: 11 + cache: gradle + distribution: zulu - name: Checking kotlin formatting run: ./gradlew ktlintCheck - name: Compiling and test diff --git a/.github/workflows/publish-smeup.yml b/.github/workflows/publish-smeup.yml index 2039f1e7d..46d36e8ec 100644 --- a/.github/workflows/publish-smeup.yml +++ b/.github/workflows/publish-smeup.yml @@ -7,10 +7,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: java-version: 11 + cache: gradle + distribution: zulu # save private key to file (private.gpg) - run: echo "${{ secrets.GPG_KEY_BASE64 }}" | base64 -d > ~/private.gpg # create gradle.properties file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d430118ac..18fe3a188 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,10 +8,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 with: java-version: 11 + cache: gradle + distribution: zulu # save private key to file (private.gpg) - run: echo "${{ secrets.GPG_KEY_BASE64 }}" | base64 -d > ~/private.gpg # create gradle.properties file From 815a7a3c32fc05e8cedb223fdcbc2f522a439319 Mon Sep 17 00:00:00 2001 From: paolofacchinetti Date: Fri, 15 Mar 2024 12:22:26 +0100 Subject: [PATCH 311/423] feat(ci): add dependabot for gha --- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..c83312405 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +--- +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" \ No newline at end of file From 3e4e2dd08915f2f4401257baa6d8118bf84c3440 Mon Sep 17 00:00:00 2001 From: paolofacchinetti Date: Fri, 15 Mar 2024 12:34:30 +0100 Subject: [PATCH 312/423] feat(ci): refactor unit-tests from circle-ci to gha --- .circleci/config.yml | 11 ----------- .github/workflows/publish-smeup.yml | 6 ++---- .github/workflows/publish.yml | 6 ++---- .github/workflows/{build.yml => unit-test.yml} | 17 ++++++++--------- 4 files changed, 12 insertions(+), 28 deletions(-) delete mode 100644 .circleci/config.yml rename .github/workflows/{build.yml => unit-test.yml} (62%) diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 83396de82..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,11 +0,0 @@ -version: 2.0 - -jobs: - build: - docker: - - image: circleci/openjdk:11-jdk - steps: - - checkout - - run: ./gradlew ktlintCheck - - run: ./gradlew check - diff --git a/.github/workflows/publish-smeup.yml b/.github/workflows/publish-smeup.yml index 46d36e8ec..4bc071a3d 100644 --- a/.github/workflows/publish-smeup.yml +++ b/.github/workflows/publish-smeup.yml @@ -11,8 +11,8 @@ jobs: - uses: actions/setup-java@v4 with: java-version: 11 - cache: gradle distribution: zulu + - uses: gradle/actions/setup-gradle@v3 # save private key to file (private.gpg) - run: echo "${{ secrets.GPG_KEY_BASE64 }}" | base64 -d > ~/private.gpg # create gradle.properties file @@ -25,6 +25,4 @@ jobs: echo "smeupUsername=${{ secrets.NEXUS_USER }}" >> ~/.gradle/gradle.properties echo "smeupPassword=${{ secrets.NEXUS_PASSWORD }}" >> ~/.gradle/gradle.properties # deploy - - uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 - with: - arguments: publishToSmeup + - run: ./gradlew publishToSmeup diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 18fe3a188..00a5037fe 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,8 +12,8 @@ jobs: - uses: actions/setup-java@v4 with: java-version: 11 - cache: gradle distribution: zulu + - uses: gradle/actions/setup-gradle@v3 # save private key to file (private.gpg) - run: echo "${{ secrets.GPG_KEY_BASE64 }}" | base64 -d > ~/private.gpg # create gradle.properties file @@ -26,6 +26,4 @@ jobs: echo "sonatypeUsername=${{ secrets.OSSRH_USERNAME }}" >> ~/.gradle/gradle.properties echo "sonatypePassword=${{ secrets.OSSRH_PASSWORD }}" >> ~/.gradle/gradle.properties # deploy - - uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1 - with: - arguments: publishToSonatype closeAndReleaseSonatypeStagingRepository + - run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository diff --git a/.github/workflows/build.yml b/.github/workflows/unit-test.yml similarity index 62% rename from .github/workflows/build.yml rename to .github/workflows/unit-test.yml index b4b55951f..a89eadcaa 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/unit-test.yml @@ -1,22 +1,21 @@ -name: CIBuild +name: Unit Test on: - push: - workflow_dispatch: + pull_request: + branches: + - master + - develop jobs: - build: - + unit-test: runs-on: ubuntu-latest - steps: - uses: actions/checkout@v4 - - name: Set up JDK 11 - uses: actions/setup-java@v4 + - uses: actions/setup-java@v4 with: java-version: 11 - cache: gradle distribution: zulu + - uses: gradle/actions/setup-gradle@v3 - name: Checking kotlin formatting run: ./gradlew ktlintCheck - name: Compiling and test From a58c254110724fbfe2850a2770c84dee7f7738a4 Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 15 Mar 2024 12:46:14 +0100 Subject: [PATCH 313/423] Add unit tests --- .../evaluation/SmeupInterpreterTest.kt | 18 ++++++++++++++++++ .../src/test/resources/smeup/T10_A45_P04.rpgle | 12 ++++++++++++ .../src/test/resources/smeup/T10_A45_P05.rpgle | 12 ++++++++++++ .../src/test/resources/smeup/T10_A45_P06.rpgle | 12 ++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P04.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P05.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P06.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index cf332b9c7..b75b247f6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -660,4 +660,22 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("123") assertEquals(expected, "smeup/T02_A80_P03".outputOf()) } + + @Test + fun executeT10_A45_P04() { + val expected = listOf("IND(0)") + assertEquals(expected, "smeup/T10_A45_P04".outputOf()) + } + + @Test + fun executeT10_A45_P05() { + val expected = listOf("IND(1)") + assertEquals(expected, "smeup/T10_A45_P05".outputOf()) + } + + @Test + fun executeT10_A45_P06() { + val expected = listOf("IND(0)") + assertEquals(expected, "smeup/T10_A45_P06".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P04.rpgle new file mode 100644 index 000000000..f2fcff064 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P04.rpgle @@ -0,0 +1,12 @@ + D £DBG_Str S 150 VARYING + + D A45_A10 C '0123456789' + D A45_A04 S 4 INZ(' ') + D A45_N10 S 1 0 + + C SETOFF 40 + C EVAL A45_A04='2019' + C A45_A10 CHECK A45_A04 40 + C EVAL £DBG_Str='IND('+%CHAR(*IN40)+')' + + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P05.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P05.rpgle new file mode 100644 index 000000000..b1a963b1f --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P05.rpgle @@ -0,0 +1,12 @@ + D £DBG_Str S 150 VARYING + + D A45_A10 C '0123456789' + D A45_A04 S 4 INZ(' ') + D A45_N10 S 1 0 + + C SETOFF 40 + C EVAL A45_A04='201A' + C A45_A10 CHECK A45_A04 40 + C EVAL £DBG_Str='IND('+%CHAR(*IN40)+')' + + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P06.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P06.rpgle new file mode 100644 index 000000000..ac102a928 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A45_P06.rpgle @@ -0,0 +1,12 @@ + D £DBG_Str S 150 VARYING + + D A45_A10 C '0123456789' + D A45_A04 S 4 INZ(' ') + D A45_N10 S 1 0 + + C SETOFF 40 + C EVAL A45_A04='201A' + C A45_A10 CHECK A45_A04 40 + C EVAL £DBG_Str='IND('+%CHAR(*IN40)+')' + + C £DBG_Str DSPLY \ No newline at end of file From 113fb4c6de9978c2c579d34e9cfa7e311dac1ad2 Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 15 Mar 2024 12:46:34 +0100 Subject: [PATCH 314/423] Add support for indicators in EQ position --- .../com/smeup/rpgparser/interpreter/values.kt | 4 ++++ .../rpgparser/parsing/parsetreetoast/misc.kt | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 4 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 c404b7f31..d9b6cee70 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 @@ -314,6 +314,10 @@ data class IntValue(val value: Long) : NumberValue() { return StringValue(render()) } + override fun asBoolean(): BooleanValue { + return BooleanValue(value > 0) + } + operator fun plus(other: IntValue) = IntValue(this.bigDecimal.plus(other.bigDecimal).longValueExact()) operator fun minus(other: IntValue) = IntValue(this.bigDecimal.minus(other.bigDecimal).longValueExact()) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index e9cc0ddf4..831faaaa3 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1031,10 +1031,10 @@ internal fun ResultTypeContext.toAst(conf: ToAstConfiguration = ToAstConfigurati // what kind of expression is this val position = toPosition(conf.considerPosition) - if (text.contains('.')) { - return handleParsingOfTargets(text, position) + return if (text.contains('.')) { + handleParsingOfTargets(text, position) } else { - return annidatedReferenceExpression(text, position) + annidatedReferenceExpression(text, position) } } @@ -1345,11 +1345,19 @@ internal fun CsCHECKContext.toAst(conf: ToAstConfiguration): Statement { val result = this.cspec_fixed_standard_parts().result val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result.text, position, conf) + val eqIndicator = this.cspec_fixed_standard_parts().resultIndicator(2)?.text + + val wrongCharExpression = when { + result != null && result.text.isNotBlank() -> result.toAst(conf) + !eqIndicator.isNullOrBlank() -> IndicatorExpr(eqIndicator.toIndicatorKey(), position) + else -> null + } + return CheckStmt( factor1, expression, startPosition ?: 1, - this.cspec_fixed_standard_parts()?.result?.toAst(conf), + wrongCharExpression, dataDefinition, position ) From 05b5509a897e183c98ebdfe20aa2df9603e997b7 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 18 Mar 2024 09:27:24 +0100 Subject: [PATCH 315/423] Implemented test --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T10_A60_P10.rpgle | 15 +++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P10.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 4052ff83e..b91e8c82a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,4 +666,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("PROVA") assertEquals(expected, "smeup/T02_A80_P02".outputOf()) } + + @Test + fun executeT10_A60_P10() { + val expected = listOf("CALL_1( , 1, MULANGTB10: chiamata 1 )") + assertEquals(expected, "smeup/T10_A60_P10".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P10.rpgle new file mode 100644 index 000000000..cefb447f2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P10.rpgle @@ -0,0 +1,15 @@ + D £DBG_Str S 50 VARYING + D A60_D1 S 10 + D A60_D2 S 2 0 + D A60_D3 DS + D A60_DA1 5 + D A60_DA2 45 + + C CALL 'MULANGTB10' + C PARM A60_D1 10 + C PARM 1 A60_D2 2 0 + C PARM A60_D3 50 + C EVAL £DBG_Str='CALL_1('+A60_D1+', ' + C +%CHAR(A60_D2) + C +', '+A60_D3+') ' + C £DBG_Str DSPLY \ No newline at end of file From ae83885b7849f72a8817a202e5628a8b2b975334 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 18 Mar 2024 11:08:29 +0100 Subject: [PATCH 316/423] Implemented test --- .../evaluation/SmeupInterpreterTest.kt | 6 +++ .../test/resources/smeup/T60_A40_P01.rpgle | 7 ++++ .../resources/smeup/metadata/MLNGT60AV.json | 21 ++++++++++ .../resources/smeup/metadata/MLNGT60BV.json | 39 +++++++++++++++++++ 4 files changed, 73 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T60_A40_P01.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60AV.json create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60BV.json diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 4052ff83e..ee33fe5d6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,4 +666,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("PROVA") assertEquals(expected, "smeup/T02_A80_P02".outputOf()) } + + @Test + fun executeT60_A40_P01() { + val expected = listOf("5") + assertEquals(expected, "smeup/T60_A40_P01".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A40_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A40_P01.rpgle new file mode 100644 index 000000000..ced488a6b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T60_A40_P01.rpgle @@ -0,0 +1,7 @@ + D £DBG_Str S 50 VARYING + FMLNGT60AV CF E WORKSTN USROPN + FMLNGT60BV CF E WORKSTN SFILE(SFL1:RRN01) + + C Z-ADD 5 RRN01 4 0 + C EVAL £DBG_Str=%CHAR(RRN01) + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60AV.json b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60AV.json new file mode 100644 index 000000000..72b09b587 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60AV.json @@ -0,0 +1,21 @@ +{"name": "MLNGT60AV", + "tableName": "MULANGTF", + "recordFormat": "", + "fields": [ + { "fieldName": "*IN60", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "*IN62", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "£RASDI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "£PDSNP", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "£PDSJN", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "£PDSNU", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "W$MESV", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":76, "varying":false}} + , { "fieldName": "W$RISC", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":8, "varying":false}} + ], "accessFields": []} diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60BV.json b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60BV.json new file mode 100644 index 000000000..b49c5c7d7 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/metadata/MLNGT60BV.json @@ -0,0 +1,39 @@ +{"name": "MLNGT60BV", + "tableName": "MULANGTF", + "recordFormat": "", + "fields": [ + { "fieldName": "*IN42", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "*IN54", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "*IN63", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "SHDEAR", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":35, "varying":false}} + , { "fieldName": "S$OPZI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":2, "varying":false}} + , { "fieldName": "X$FLD1", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":50, "varying":false}} + , { "fieldName": "*IN92", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "*IN93", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "*IN94", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "*IN96", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "RRN01", + "type":{"type":"com.smeup.rpgparser.interpreter.NumberType","entireDigits":4, "decimalDigits":0, "rpgType":"S"}} + , { "fieldName": "£RASDI", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":15, "varying":false}} + , { "fieldName": "£PDSNP", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "£PDSJN", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "£PDSNU", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":10, "varying":false}} + , { "fieldName": "*IN60", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":1, "varying":false}} + , { "fieldName": "W$MESV", + "type":{"type":"com.smeup.rpgparser.interpreter.StringType","length":76, "varying":false}} + ], "accessFields": []} From 68e2b1975325e5a89d5d3285a1303c7bac4f167e Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 18 Mar 2024 14:14:27 +0100 Subject: [PATCH 317/423] Add unit tests for MonitorStmt --- .../evaluation/SmeupInterpreterTest.kt | 24 +++++++ .../test/resources/smeup/T11_A10_P01.rpgle | 13 ++++ .../test/resources/smeup/T11_A10_P02.rpgle | 31 ++++++++++ .../test/resources/smeup/T11_A10_P03.rpgle | 36 +++++++++++ .../test/resources/smeup/T11_A10_P04.rpgle | 62 +++++++++++++++++++ 5 files changed, 166 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P01.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P02.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P03.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P04.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 4052ff83e..30071716a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,4 +666,28 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("PROVA") assertEquals(expected, "smeup/T02_A80_P02".outputOf()) } + + @Test + fun executeT11_A10_P01() { + val expected = listOf("BLOCCO; ERR_ZERO_DIV;") + assertEquals(expected, "smeup/T11_A10_P01".outputOf()) + } + + @Test + fun executeT11_A10_P02() { + val expected = listOf("BLOCCO1; BLOCCO2; BLOCCO3; ERR_ZERO_DIV; FINE_BLOCCO3;; ERR_ZERO_DIV; FINE_BLOCCO2;; ERR_ZERO_DIV; FINE_BLOCCO1;") + assertEquals(expected, "smeup/T11_A10_P02".outputOf()) + } + + @Test + fun executeT11_A10_P03() { + val expected = listOf("DENTRO_IF(BLOCCO; ERR_ZERO_DIV;) DENTRO_DO(BLOCCO; ERR_ZERO_DIV;BLOCCO; ERR_ZERO_DIV;) DENTRO_WHEN(BLOCCO; ERR_ZERO_DIV;) DENTRO_OTHER(BLOCCO; ERR_ZERO_DIV;)") + assertEquals(expected, "smeup/T11_A10_P03".outputOf()) + } + + @Test + fun executeT11_A10_P04() { + val expected = listOf("DENTRO_IF(BLOCCO; ERR_ZERO_DIV;) DENTRO_DO(BLOCCO; ERR_ZERO_DIV;) DENTRO_WHEN(BLOCCO; ERR_ZERO_DIV;) DENTRO_OTHER(BLOCCO; ERR_ZERO_DIV;)") + assertEquals(expected, "smeup/T11_A10_P04".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P01.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P01.rpgle new file mode 100644 index 000000000..16f593448 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P01.rpgle @@ -0,0 +1,13 @@ + D £DBG_Str S 150 VARYING + D T11_A10_A20A S 2 0 INZ(10) + D T11_A10_A20B S 2 0 INZ(0) + C MONITOR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'BLOCCO' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; FINE_BLOCCO;' + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P02.rpgle new file mode 100644 index 000000000..4386ee2e5 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P02.rpgle @@ -0,0 +1,31 @@ + D £DBG_Str S 150 VARYING + D T11_A10_A20A S 2 0 INZ(10) + D T11_A10_A20B S 2 0 INZ(0) + C MONITOR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'BLOCCO1;' + C MONITOR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' BLOCCO2;' + C MONITOR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' BLOCCO3' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' FINE_BLOCCO3;' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' FINE_BLOCCO2;' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' FINE_BLOCCO1;' + C £DBG_Str DSPLY diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P03.rpgle new file mode 100644 index 000000000..ddebc84b8 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P03.rpgle @@ -0,0 +1,36 @@ + D £DBG_Str S 180 VARYING + D T11_A10_A20A S 2 0 INZ(10) + D T11_A10_A20B S 2 0 INZ(0) + C EVAL £DBG_Str='DENTRO_IF(' + C IF 'A'='A' + C EXSR SUB_SEZ_A10 + C ENDIF + C EVAL £DBG_Str=%TRIM(£DBG_Str)+') DENTRO_DO(' + C DO 2 + C EXSR SUB_SEZ_A10 + C ENDDO + C EVAL £DBG_Str=%TRIM(£DBG_Str)+') DENTRO_WHEN(' + C SELECT + C WHEN 'A'='A' + C EXSR SUB_SEZ_A10 + C ENDSL + C EVAL £DBG_Str=%TRIM(£DBG_Str)+') DENTRO_OTHER(' + C SELECT + C WHEN 'A'='B' + C OTHER + C EXSR SUB_SEZ_A10 + C ENDSL + C EVAL £DBG_Str=%TRIM(£DBG_Str)+')' + C £DBG_Str DSPLY + + C SUB_SEZ_A10 BEGSR + C MONITOR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'BLOCCO' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; FINE_BLOCCO;' + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C ENDSR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P04.rpgle new file mode 100644 index 000000000..af3c386c2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T11_A10_P04.rpgle @@ -0,0 +1,62 @@ + D £DBG_Str S 150 VARYING + D T11_A10_A20A S 2 0 INZ(10) + D T11_A10_A20B S 2 0 INZ(0) + C MONITOR + C EVAL £DBG_Str='DENTRO_IF(' + C IF 'A'='A' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'BLOCCO' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; FINE_BLOCCO;' + C ENDIF + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C EVAL £DBG_Str=%TRIM(£DBG_Str)+')' + * + C MONITOR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' DENTRO_DO(' + C DO 2 + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'BLOCCO' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; FINE_BLOCCO;' + C ENDDO + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C EVAL £DBG_Str=%TRIM(£DBG_Str)+')' + * + C MONITOR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' DENTRO_WHEN(' + C SELECT + C WHEN 'A'='A' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'BLOCCO' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; FINE_BLOCCO;' + C ENDSL + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C EVAL £DBG_Str=%TRIM(£DBG_Str)+')' + * + C MONITOR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+' DENTRO_OTHER(' + C SELECT + C WHEN 'A'='B' + C OTHER + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'BLOCCO' + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; '+ + C %CHAR(T11_A10_A20A/T11_A10_A20B) + C EVAL £DBG_Str=%TRIM(£DBG_Str)+'; FINE_BLOCCO;' + C ENDSL + C ON-ERROR + C EVAL £DBG_Str=%TRIM(£DBG_Str)+ + C '; ERR_ZERO_DIV;' + C ENDMON + C EVAL £DBG_Str=%TRIM(£DBG_Str)+')' + C £DBG_Str DSPLY \ No newline at end of file From 30dc3ceed0541c01d38fbdc3df6744520093917f Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 18 Mar 2024 14:16:30 +0100 Subject: [PATCH 318/423] Implement MonitorStmt --- .../interpreter/ExpressionEvaluation.kt | 28 ++++----- .../com/smeup/rpgparser/interpreter/logs.kt | 21 +++++++ .../rpgparser/parsing/ast/serialization.kt | 1 + .../smeup/rpgparser/parsing/ast/statements.kt | 61 ++++++++++++++++++- .../rpgparser/parsing/parsetreetoast/misc.kt | 5 +- .../parsing/parsetreetoast/statements.kt | 24 ++++++++ 6 files changed, 120 insertions(+), 20 deletions(-) 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 58d9f94d5..a419a0e74 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 @@ -206,21 +206,19 @@ class ExpressionEvaluation( override fun eval(expression: CharExpr): Value { val value = expression.value.evalWith(this) - return if (expression.value is DivExpr) { - // are always return 10 decimal digits - // fill with 0 if necessary - if (value.asDecimal().value.scale() != 0) { - val numeDecimals = value.asDecimal().value.scale() - if (numeDecimals < 10) { - StringValue(value.stringRepresentation(expression.format) + "0".repeat(10 - numeDecimals)) - } else { - StringValue(value.stringRepresentation(expression.format).trim()) - } - } else { - StringValue(value.stringRepresentation(expression.format) + ".0000000000") - } - } else { - StringValue(value.stringRepresentation(expression.format)) + val representation = value.stringRepresentation(expression.format) + + if (expression.value !is DivExpr) { + return StringValue(representation) + } + + // Decimals are always returned with 10 decimal digits + // fill with 0 if necessary + val numDecimals = value.asDecimal().value.scale() + return when { + numDecimals == 0 -> StringValue("$representation.0000000000") + numDecimals < 10 -> StringValue(representation + "0".repeat(10 - numDecimals)) + else -> StringValue(representation.trim()) } } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt index e5302877c..73c63f9a4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/logs.kt @@ -411,6 +411,17 @@ class CasOtherExecutionLogEntry(programName: String, val other: CaseOtherClause, } } +class MonitorExecutionLogEntry(programName: String, val statement: MonitorStmt) : LogEntry(programName) { + override fun toString(): String { + return "executing MONITOR" + } + + override fun renderStatement(channel: String, filename: String, sep: String): String { + val data = "MONITOR" + return renderHeader(channel, filename, statement.startLine(), sep) + data + } +} + class IfExecutionLogEntry(programName: String, val statement: IfStmt, val result: Value) : LogEntry(programName) { override fun toString(): String { return "executing IF" @@ -442,6 +453,16 @@ class ElseExecutionLogEntry(programName: String, val statement: ElseClause, val } } +class OnErrorExecutionLogEntry(programName: String, val statement: OnErrorClause) : LogEntry(programName) { + override fun toString(): String { + return "executing ON-ERROR" + } + override fun renderStatement(channel: String, filename: String, sep: String): String { + val data = "ON-ERROR" + return renderHeader(channel, filename, statement.startLine(), sep) + data + } +} + class EvaluationLogEntry(programName: String, val statement: EvalStmt, val value: Value?) : LogEntry(programName) { override fun toString(): String { return "evaluating $statement as $value" 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 f58318903..ed2fb4c07 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 @@ -68,6 +68,7 @@ private val modules = SerializersModule { subclass(LeaveSrStmt::class) subclass(LeaveStmt::class) subclass(LookupStmt::class) + subclass(MonitorStmt::class) subclass(MoveAStmt::class) subclass(MoveLStmt::class) subclass(MoveStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 16d630be7..8e6ae5dca 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -814,6 +814,62 @@ private constructor(val name: String, val fields: List, override val pos } } +@Serializable +data class MonitorStmt( + @SerialName("body") + val monitorBody: List, + val onErrorClauses: List = emptyList(), + override val position: Position? = null +) : Statement(position), CompositeStatement { + + // Since that this property is a collection achieved from thenBody + elseIfClauses + elseClause, this annotation + // is necessary to avoid that the same node is processed more than ones, thing that it would cause that the same + // ErrorEvent is fired more times + @Derived + @Transient + override val body: List = mutableListOf().apply { + addAll(monitorBody) + onErrorClauses.forEach { addAll(it.body) } + } + + override fun accept(mutes: MutableMap, start: Int, end: Int): MutableList { + // check if the annotation is just before the ELSE + val muteAttached: MutableList = mutableListOf() + + // Process the body statements + muteAttached.addAll( + acceptBody(monitorBody, mutes, this.position!!.start.line, this.position.end.line) + ) + + // Process the ON ERROR + onErrorClauses.forEach { + muteAttached.addAll( + acceptBody(it.body, mutes, it.position!!.start.line, it.position.end.line) + ) + } + + return muteAttached + } + + override fun execute(interpreter: InterpreterCore) { + interpreter.log { + MonitorExecutionLogEntry( + interpreter.getInterpretationContext().currentProgramName, + this + ) + } + + try { + interpreter.execute(this.monitorBody) + } catch (_: Exception) { + onErrorClauses.forEach { + interpreter.log { OnErrorExecutionLogEntry(interpreter.getInterpretationContext().currentProgramName, it) } + interpreter.execute(it.body) + } + } + } +} + @Serializable data class IfStmt( val condition: Expression, @@ -889,6 +945,9 @@ data class IfStmt( } } +@Serializable +data class OnErrorClause(override val body: List, override val position: Position? = null) : Node(position), CompositeStatement + @Serializable data class ElseClause(override val body: List, override val position: Position? = null) : Node(position), CompositeStatement @@ -1061,7 +1120,7 @@ data class DefineStmt( } else { val inStatementDataDefinition = containingCU.main.stmts - .filterIsInstance(StatementThatCanDefineData::class.java) + .filterIsInstance() .filter { it != this } .asSequence() .map(StatementThatCanDefineData::dataDefinition) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index e9cc0ddf4..877657f1d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1121,10 +1121,7 @@ internal fun Cspec_fixed_standard_partsContext.toDataDefinition( position: Position?, conf: ToAstConfiguration ): InStatementDataDefinition? { - val len = this.len.asInt() - if (len == null) { - return null - } + val len = this.len.asInt() ?: return null val decimals = this.decimalPositions.asInt() val initialValue = this.factor2Expression(conf) return InStatementDataDefinition(name, dataType(len, decimals), position, initializationValue = initialValue) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt index 3dd55e631..e8bb11dc6 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/statements.kt @@ -56,6 +56,12 @@ internal fun BlockContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()) this.csDOWxx() != null -> this.csDOWxx().toAst(blockContext = this, conf = conf) this.forstatement() != null -> this.forstatement().toAst(conf) this.begindou() != null -> this.begindou().toAst(blockContext = this, conf = conf) + this.monitorstatement() != null -> this.monitorstatement().let { + it.beginmonitor().csMONITOR().cspec_fixed_standard_parts().validate( + stmt = it.toAst(conf = conf), + conf = conf + ) + } else -> todo(message = "Missing composite statement implementation for this block: ${this.text}", conf = conf) } } @@ -358,6 +364,18 @@ internal fun toAst(conf: ToAstConfiguration = ToAstConfiguration()): SelectOther TODO("OtherContext.toAst with $conf") } +internal fun RpgParser.MonitorstatementContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MonitorStmt { + val position = toPosition(conf.considerPosition) + val statements = this.statement().mapNotNull { + it.toAst(conf) + } + val onErrorClauses = this.onError().mapNotNull { + it.toAst(conf) + } + + return MonitorStmt(statements, onErrorClauses, position) +} + internal fun RpgParser.IfstatementContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): IfStmt { val position = toPosition(conf.considerPosition) return if (this.beginif().fixedexpression != null) { @@ -387,6 +405,12 @@ internal fun RpgParser.IfstatementContext.toAst(conf: ToAstConfiguration = ToAst } } +internal fun RpgParser.OnErrorContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): OnErrorClause { + val body = this.statement().mapNotNull { kotlin.runCatching { it.toAst(conf) }.getOrNull() } + val position = toPosition(conf.considerPosition) + return OnErrorClause(body, position) +} + internal fun RpgParser.ElseClauseContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): ElseClause { return ElseClause(this.statement().mapNotNull { kotlin.runCatching { it.toAst(conf) }.getOrNull() }, toPosition(conf.considerPosition)) } From 57bfec7c3a7ffaf711cbe0c6d2e88914107a06f3 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:25:33 +0100 Subject: [PATCH 319/423] Add abstract class MULANGTTest --- .../com/smeup/rpgparser/smeup/MULANGTTest.kt | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt new file mode 100644 index 000000000..966f0f6e2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt @@ -0,0 +1,33 @@ +package com.smeup.rpgparser.smeup + +import com.smeup.dbnative.DBNativeAccessConfig +import com.smeup.rpgparser.AbstractTest +import com.smeup.rpgparser.execution.Configuration +import com.smeup.rpgparser.execution.ReloadConfig +import com.smeup.rpgparser.execution.SimpleReloadConfig +import kotlin.test.BeforeTest + +/** + * This is the base class for all the tests related to the MULANGT program. + * For each MULANGTnn program we have MULANGTnnTestPurposesTest and MULANGTnnTestPurposesCompiledTest + * @see MULANGT60VideoTest where nn is 60 and TestPurposes is Video + * @see MULANGT60VideoCompiledTest see above + */ +abstract class MULANGTTest : AbstractTest() { + + /** + * The configuration used to execute some kind of tests, for example all test required files. + * The required files are placed in the resources/smeup/metadata folder. + */ + lateinit var smeupConfig: Configuration + + @BeforeTest + fun setUp() { + smeupConfig = Configuration() + val path = javaClass.getResource("/smeup/metadata")!!.path + val reloadConfig = SimpleReloadConfig(metadataPath = path, connectionConfigs = listOf()) + smeupConfig.reloadConfig = ReloadConfig( + nativeAccessConfig = DBNativeAccessConfig(emptyList()), + metadataProducer = { dbFile: String -> reloadConfig.getMetadata(dbFile = dbFile) }) + } +} \ No newline at end of file From abad6d4961f0cca1303b1f469323bd6473602ed7 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:26:53 +0100 Subject: [PATCH 320/423] Add MULANGT60VideoTest --- .../smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt | 9 +++++++++ .../com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt | 3 +++ 2 files changed, 12 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt new file mode 100644 index 000000000..e2f086525 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt @@ -0,0 +1,9 @@ +package com.smeup.rpgparser.smeup + +/** + * This class doest must be implemented because it exists just to test the compiled version of the programs defined in the superclass. + */ +class MULANGT60VideoCompiledTest : MULANGT60VideoTest() { + + override fun useCompiledVersion() = true +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt new file mode 100644 index 000000000..fd8197a43 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT60VideoTest : MULANGTTest() \ No newline at end of file From 77088cf6105a548200790e7ee7ab95f2fd57261f Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:36:40 +0100 Subject: [PATCH 321/423] Refactor SmeupInterpreterTest and moved T60 unit tests in MULANGT60VideoTest --- .../evaluation/SmeupInterpreterTest.kt | 12 ------------ .../rpgparser/smeup/MULANGT60VideoTest.kt | 18 +++++++++++++++++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index afeae5b9c..0d845883a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -467,12 +467,6 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T52_A07_P01".outputOf(configuration = smeupConfig)) } - @Test - fun executeT60_A10_P01_02() { - val expected = listOf() - assertEquals(expected, "smeup/T60_A10_P01-02".outputOf(configuration = smeupConfig)) - } - @Test fun executeT10_A20_P35_38() { val expected = listOf( @@ -553,12 +547,6 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T02_A50_P09".outputOf()) } - @Test - fun executeT60_A10_P01() { - val expected = listOf("KA(0)KB(0)KC(0)KD(0)KE(0)KF(0)KG(0)KH(0)KI(0)KJ(0)KK(0)KL(0)KM(0)KN(0)KP(0)KQ(0)KR(0)KS(0)KT(0)KU(0)KV(0)KW(0)KX(0)KY(0)") - assertEquals(expected, "smeup/T60_A10_P01".outputOf(configuration = smeupConfig)) - } - @Test fun executeT10_A45_P01() { val expected = listOf("NUM(0)") diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt index fd8197a43..e7c1f349e 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt @@ -1,3 +1,19 @@ package com.smeup.rpgparser.smeup -open class MULANGT60VideoTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT60VideoTest : MULANGTTest() { + + @Test + fun executeT60_A10_P01() { + val expected = listOf("KA(0)KB(0)KC(0)KD(0)KE(0)KF(0)KG(0)KH(0)KI(0)KJ(0)KK(0)KL(0)KM(0)KN(0)KP(0)KQ(0)KR(0)KS(0)KT(0)KU(0)KV(0)KW(0)KX(0)KY(0)") + assertEquals(expected, "smeup/T60_A10_P01".outputOf(configuration = smeupConfig)) + } + + @Test + fun executeT60_A10_P01_02() { + val expected = listOf() + assertEquals(expected, "smeup/T60_A10_P01-02".outputOf(configuration = smeupConfig)) + } +} \ No newline at end of file From d880bf118e591c3304976b148a4ba96996c72095 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:39:38 +0100 Subject: [PATCH 322/423] Fix typo --- .../com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt index e2f086525..eabdcbc02 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt @@ -1,7 +1,7 @@ package com.smeup.rpgparser.smeup /** - * This class doest must be implemented because it exists just to test the compiled version of the programs defined in the superclass. + * This class doesn't must be implemented because it exists just to test the compiled version of the programs defined in the superclass. */ class MULANGT60VideoCompiledTest : MULANGT60VideoTest() { From 5bf6e79b0e77062e0f100c749ddc1d05f3e73cbf Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:40:08 +0100 Subject: [PATCH 323/423] Add MULANGT01HelloWorldTest scaffold --- .../rpgparser/smeup/MULANGT01HelloWorldCompiledTest.kt | 9 +++++++++ .../com/smeup/rpgparser/smeup/MULANGT01HelloWorldTest.kt | 3 +++ 2 files changed, 12 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldCompiledTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldTest.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldCompiledTest.kt new file mode 100644 index 000000000..989a919e2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldCompiledTest.kt @@ -0,0 +1,9 @@ +package com.smeup.rpgparser.smeup + +/** + * This class doest must be implemented because it exists just to test the compiled version of the programs defined in the superclass. + */ +class MULANGT01HelloWorldCompiledTest : MULANGT01HelloWorldTest() { + + override fun useCompiledVersion() = true +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldTest.kt new file mode 100644 index 000000000..b0d085a4a --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT01HelloWorldTest : MULANGTTest() \ No newline at end of file From d593f388ef9a705db7ae8729d8d6eb71c8faca3e Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:43:32 +0100 Subject: [PATCH 324/423] Add MULANGT02ConstsAndDSpecsTest scaffold --- .../rpgparser/smeup/MULANGT02ConstsAndDSpecsCompiledTest.kt | 5 +++++ .../smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsCompiledTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsCompiledTest.kt new file mode 100644 index 000000000..2f8315533 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsCompiledTest.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT02ConstsAndDSpecsCompiledTest : MULANGT02ConstsAndDSpecsTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt new file mode 100644 index 000000000..9983b0548 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT02ConstsAndDSpecsTest : MULANGTTest() \ No newline at end of file From 1bd539a4a79cdc3733abfb4adc281b89c11f953e Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:46:17 +0100 Subject: [PATCH 325/423] Add MULANGT03IndicatorsTest scaffold --- .../smeup/rpgparser/smeup/MULANGT03IndicatorsCompiledTest.kt | 5 +++++ .../com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsCompiledTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsCompiledTest.kt new file mode 100644 index 000000000..cdb22e804 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsCompiledTest.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT03IndicatorsCompiledTest : MULANGT03IndicatorsTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt new file mode 100644 index 000000000..3c83c6229 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT03IndicatorsTest : MULANGTTest() \ No newline at end of file From 3a9eba096097411603e88fc39db340494ce6b15c Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:49:52 +0100 Subject: [PATCH 326/423] Refactor --- ...orldCompiledTest.kt => MULANGT01HelloWorldTestCompiled.kt} | 2 +- ...ompiledTest.kt => MULANGT02ConstsAndDSpecsTestCompiled.kt} | 2 +- ...torsCompiledTest.kt => MULANGT03IndicatorsTestCompiled.kt} | 2 +- ...GT60VideoCompiledTest.kt => MULANGT60VideoTestCompiled.kt} | 2 +- .../src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) rename rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/{MULANGT01HelloWorldCompiledTest.kt => MULANGT01HelloWorldTestCompiled.kt} (78%) rename rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/{MULANGT02ConstsAndDSpecsCompiledTest.kt => MULANGT02ConstsAndDSpecsTestCompiled.kt} (60%) rename rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/{MULANGT03IndicatorsCompiledTest.kt => MULANGT03IndicatorsTestCompiled.kt} (57%) rename rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/{MULANGT60VideoCompiledTest.kt => MULANGT60VideoTestCompiled.kt} (79%) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldTestCompiled.kt similarity index 78% rename from rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldCompiledTest.kt rename to rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldTestCompiled.kt index 989a919e2..922db9683 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldCompiledTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT01HelloWorldTestCompiled.kt @@ -3,7 +3,7 @@ package com.smeup.rpgparser.smeup /** * This class doest must be implemented because it exists just to test the compiled version of the programs defined in the superclass. */ -class MULANGT01HelloWorldCompiledTest : MULANGT01HelloWorldTest() { +class MULANGT01HelloWorldTestCompiled : MULANGT01HelloWorldTest() { override fun useCompiledVersion() = true } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTestCompiled.kt similarity index 60% rename from rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsCompiledTest.kt rename to rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTestCompiled.kt index 2f8315533..08b324950 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsCompiledTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTestCompiled.kt @@ -1,5 +1,5 @@ package com.smeup.rpgparser.smeup -open class MULANGT02ConstsAndDSpecsCompiledTest : MULANGT02ConstsAndDSpecsTest() { +open class MULANGT02ConstsAndDSpecsTestCompiled : MULANGT02ConstsAndDSpecsTest() { override fun useCompiledVersion() = true } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTestCompiled.kt similarity index 57% rename from rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsCompiledTest.kt rename to rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTestCompiled.kt index cdb22e804..13a4cdd98 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsCompiledTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTestCompiled.kt @@ -1,5 +1,5 @@ package com.smeup.rpgparser.smeup -class MULANGT03IndicatorsCompiledTest : MULANGT03IndicatorsTest() { +class MULANGT03IndicatorsTestCompiled : MULANGT03IndicatorsTest() { override fun useCompiledVersion() = true } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTestCompiled.kt similarity index 79% rename from rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt rename to rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTestCompiled.kt index eabdcbc02..fa72a3a38 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoCompiledTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTestCompiled.kt @@ -3,7 +3,7 @@ package com.smeup.rpgparser.smeup /** * This class doesn't must be implemented because it exists just to test the compiled version of the programs defined in the superclass. */ -class MULANGT60VideoCompiledTest : MULANGT60VideoTest() { +class MULANGT60VideoTestCompiled : MULANGT60VideoTest() { override fun useCompiledVersion() = true } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt index 966f0f6e2..14b50192b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGTTest.kt @@ -9,9 +9,9 @@ import kotlin.test.BeforeTest /** * This is the base class for all the tests related to the MULANGT program. - * For each MULANGTnn program we have MULANGTnnTestPurposesTest and MULANGTnnTestPurposesCompiledTest + * For each MULANGTnn program we have MULANGTnnPurposesTest and MULANGTnnPurposesTestCompiled. * @see MULANGT60VideoTest where nn is 60 and TestPurposes is Video - * @see MULANGT60VideoCompiledTest see above + * @see MULANGT60VideoTestCompiled see above */ abstract class MULANGTTest : AbstractTest() { From 4bf96c0ab04648503abc3dbffff2f2cae6451603 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:52:11 +0100 Subject: [PATCH 327/423] Add MULANGT04EssentialsCodopAndBifTest scaffold --- .../rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt | 3 +++ .../smeup/MULANGT04EssentialsCodopAndBifTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt new file mode 100644 index 000000000..550a33d21 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT04EssentialsCodopAndBifTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTestCompiled.kt new file mode 100644 index 000000000..dcdac027b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT04EssentialsCodopAndBifTestCompiled : MULANGT04EssentialsCodopAndBifTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From f41be96420d426860b66a2ff6e86c6904bb1c646 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:54:06 +0100 Subject: [PATCH 328/423] Add MULANGT10BaseCodopTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt | 3 +++ .../smeup/rpgparser/smeup/MULANGT10BaseCodopTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt new file mode 100644 index 000000000..9d46c6f12 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT10BaseCodopTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTestCompiled.kt new file mode 100644 index 000000000..f10ec4474 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT10BaseCodopTestCompiled : MULANGT10BaseCodopTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From 78154021e3ccd540992cc40a85ea99d8da538d73 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:56:10 +0100 Subject: [PATCH 329/423] Add MULANGT11Codop2Test scaffold --- .../kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt | 3 +++ .../com/smeup/rpgparser/smeup/MULANGT11Codop2TestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2TestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt new file mode 100644 index 000000000..f45bd304b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT11Codop2Test : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2TestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2TestCompiled.kt new file mode 100644 index 000000000..91b349562 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2TestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT11Codop2TestCompiled : MULANGT11Codop2Test() { + override fun useCompiledVersion() = true +} \ No newline at end of file From ec49df251acd1337d6250161e69d6f54a74f6e30 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 18 Mar 2024 14:56:39 +0100 Subject: [PATCH 330/423] Implemented test --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T02_A80_P04.rpgle | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P04.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 4052ff83e..cb19dd626 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,4 +666,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("PROVA") assertEquals(expected, "smeup/T02_A80_P02".outputOf()) } + + @Test + fun executeT02_A80_P04() { + val expected = listOf("ABCDEFGHIJ") + assertEquals(expected, "smeup/T02_A80_P04".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P04.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P04.rpgle new file mode 100644 index 000000000..37af1b31c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P04.rpgle @@ -0,0 +1,7 @@ + DCQNCOG E DS EXTNAME(CQNCOG0F) INZ + D £DBG_Str S 50 VARYING + + C CLEAR N§PROG 10 + C EVAL N§PROG = 'ABCDEFGHIJ' + C EVAL £DBG_Str=%TRIM(N§PROG) + C £DBG_Str DSPLY \ No newline at end of file From ed2afcd8c85f8764f089eb70efb344b468de66fe Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 14:59:52 +0100 Subject: [PATCH 331/423] Add MULANGT12LoopFlowGotoTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt | 3 +++ .../rpgparser/smeup/MULANGT12LoopFlowGotoTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt new file mode 100644 index 000000000..68c9e6bda --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT12LoopFlowGotoTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTestCompiled.kt new file mode 100644 index 000000000..ddd3812d7 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT12LoopFlowGotoTestCompiled : MULANGT12LoopFlowGotoTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From 6974ea31a7490f50304d7b8f8d036f1f90c6b6f4 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:00:57 +0100 Subject: [PATCH 332/423] Refactor --- .../com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 3 +++ .../rpgparser/smeup/MULANGT02ConstAndDSpecTestCompiled.kt | 5 +++++ .../smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt | 3 --- .../rpgparser/smeup/MULANGT02ConstsAndDSpecsTestCompiled.kt | 5 ----- .../com/smeup/rpgparser/smeup/MULANGT03IndicatorTest.kt | 3 +++ ...torsTestCompiled.kt => MULANGT03IndicatorTestCompiled.kt} | 2 +- .../com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt | 3 --- 7 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTestCompiled.kt delete mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt delete mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTestCompiled.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorTest.kt rename rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/{MULANGT03IndicatorsTestCompiled.kt => MULANGT03IndicatorTestCompiled.kt} (54%) delete mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt 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 new file mode 100644 index 000000000..bc693fd12 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT02ConstAndDSpecTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTestCompiled.kt new file mode 100644 index 000000000..628995561 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstAndDSpecTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT02ConstAndDSpecTestCompiled : MULANGT02ConstAndDSpecTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt deleted file mode 100644 index 9983b0548..000000000 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTest.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.smeup.rpgparser.smeup - -open class MULANGT02ConstsAndDSpecsTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTestCompiled.kt deleted file mode 100644 index 08b324950..000000000 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT02ConstsAndDSpecsTestCompiled.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.smeup.rpgparser.smeup - -open class MULANGT02ConstsAndDSpecsTestCompiled : MULANGT02ConstsAndDSpecsTest() { - override fun useCompiledVersion() = true -} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorTest.kt new file mode 100644 index 000000000..d0995d884 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT03IndicatorTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorTestCompiled.kt similarity index 54% rename from rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTestCompiled.kt rename to rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorTestCompiled.kt index 13a4cdd98..f1107aef7 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTestCompiled.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorTestCompiled.kt @@ -1,5 +1,5 @@ package com.smeup.rpgparser.smeup -class MULANGT03IndicatorsTestCompiled : MULANGT03IndicatorsTest() { +class MULANGT03IndicatorTestCompiled : MULANGT03IndicatorTest() { override fun useCompiledVersion() = true } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt deleted file mode 100644 index 3c83c6229..000000000 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT03IndicatorsTest.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.smeup.rpgparser.smeup - -open class MULANGT03IndicatorsTest : MULANGTTest() \ No newline at end of file From 4f419f69fd6ba5e48a8dbd2af6bc84babb072b2e Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:11:57 +0100 Subject: [PATCH 333/423] Add MULANGT15BaseBif1Test scaffold --- .../com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt | 3 +++ .../smeup/rpgparser/smeup/MULANGT15BaseBif1TestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1TestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt new file mode 100644 index 000000000..d42cf0dee --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT15BaseBif1Test : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1TestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1TestCompiled.kt new file mode 100644 index 000000000..e6a2b6a37 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1TestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT15BaseBif1TestCompiled : MULANGT15BaseBif1Test() { + override fun useCompiledVersion() = true +} \ No newline at end of file From 22469fab6529453a43f8362e6c844158bfe6468d Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:24:21 +0100 Subject: [PATCH 334/423] Add MULANGT16BaseBif2Test scaffold --- .../smeup/rpgparser/smeup/MULANGT15BaseBif2TestCompiled.kt | 5 +++++ .../com/smeup/rpgparser/smeup/MULANGT16BaseBif2Test.kt | 3 +++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif2TestCompiled.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT16BaseBif2Test.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif2TestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif2TestCompiled.kt new file mode 100644 index 000000000..8b997b250 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif2TestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT15BaseBif2TestCompiled : MULANGT16BaseBif2Test() { + override fun useCompiledVersion() = true +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT16BaseBif2Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT16BaseBif2Test.kt new file mode 100644 index 000000000..937cae7ca --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT16BaseBif2Test.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT16BaseBif2Test : MULANGTTest() \ No newline at end of file From 9af1b8a84e5804583ccc0fa9e54981b59b0f1fe5 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:25:34 +0100 Subject: [PATCH 335/423] Add MULANGT18ProcedureTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT18ProcedureTest.kt | 3 +++ .../smeup/rpgparser/smeup/MULANGT18ProcedureTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT18ProcedureTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT18ProcedureTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT18ProcedureTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT18ProcedureTest.kt new file mode 100644 index 000000000..d30e699ea --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT18ProcedureTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT18ProcedureTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT18ProcedureTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT18ProcedureTestCompiled.kt new file mode 100644 index 000000000..449c5cbe9 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT18ProcedureTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT18ProcedureTestCompiled : MULANGT18ProcedureTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From 2a6d6a134687824ee311863efda27c552c408216 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:29:11 +0100 Subject: [PATCH 336/423] Add MULANGT20PerformanceTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT20PerformanceTest.kt | 6 ++++++ .../rpgparser/smeup/MULANGT20PerformanceTestCompiled.kt | 5 +++++ 2 files changed, 11 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT20PerformanceTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT20PerformanceTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT20PerformanceTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT20PerformanceTest.kt new file mode 100644 index 000000000..d4ab1d576 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT20PerformanceTest.kt @@ -0,0 +1,6 @@ +package com.smeup.rpgparser.smeup + +/** + * Every method in this class must be annotated with @Test @Category(PerformanceTest::class) annotation + * */ +open class MULANGT20PerformanceTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT20PerformanceTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT20PerformanceTestCompiled.kt new file mode 100644 index 000000000..97b668486 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT20PerformanceTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT20PerformanceTestCompiled : MULANGT20PerformanceTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From d4a5d96bb9b68fb7c465da91032954baca4ef60d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 18 Mar 2024 15:29:38 +0100 Subject: [PATCH 337/423] Implemented test --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T02_A80_P05.rpgle | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P05.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index afeae5b9c..09190663e 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -678,4 +678,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT02_A80_P05() { + val expected = listOf("ABCDEFGHIJ") + assertEquals(expected, "smeup/T02_A80_P05".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P05.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P05.rpgle new file mode 100644 index 000000000..a1981351c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P05.rpgle @@ -0,0 +1,7 @@ + DXQNCOG E DS EXTNAME(CQNCOG0F) INZ + D £DBG_Str S 50 VARYING + + C CLEAR X§PROG 10 + C EVAL X§PROG = 'ABCDEFGHIJ' + C EVAL £DBG_Str=%TRIM(X§PROG) + C £DBG_Str DSPLY \ No newline at end of file From 80d00e19a5dc3ad8593125570f15c9e3387c9689 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:31:06 +0100 Subject: [PATCH 338/423] Add MULANGT30OutputPrintTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT30OutputPrintTest.kt | 3 +++ .../rpgparser/smeup/MULANGT30OutputPrintTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT30OutputPrintTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT30OutputPrintTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT30OutputPrintTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT30OutputPrintTest.kt new file mode 100644 index 000000000..1d187fa50 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT30OutputPrintTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT30OutputPrintTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT30OutputPrintTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT30OutputPrintTestCompiled.kt new file mode 100644 index 000000000..a1a79f298 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT30OutputPrintTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT30OutputPrintTestCompiled : MULANGT30OutputPrintTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From 4782423c6f06f643bb9ae841edc5c03f504f6901 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:32:40 +0100 Subject: [PATCH 339/423] Add MULANGT40ArrayAndDSTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt | 3 +++ .../smeup/rpgparser/smeup/MULANGT40ArrayAndDSTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt new file mode 100644 index 000000000..53c400fe2 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT40ArrayAndDSTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTestCompiled.kt new file mode 100644 index 000000000..19ebeae7c --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT40ArrayAndDSTestCompiled : MULANGT40ArrayAndDSTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From 20a4425030f3bfc3cdba8935617cb5789dd51c99 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:33:53 +0100 Subject: [PATCH 340/423] Add MULANGT50FileAccessTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt | 3 +++ .../smeup/rpgparser/smeup/MULANGT50FileAccessTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt new file mode 100644 index 000000000..165acf1af --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT50FileAccessTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTestCompiled.kt new file mode 100644 index 000000000..1aacd686a --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT50FileAccessTestCompiled : MULANGT50FileAccessTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From c0c7418671223ffbdd962319847791f44a0ce138 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:34:54 +0100 Subject: [PATCH 341/423] Add MULANGT52FileAccessTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt | 3 +++ .../smeup/rpgparser/smeup/MULANGT52FileAccessTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt new file mode 100644 index 000000000..8e39be29a --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT52FileAccessTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTestCompiled.kt new file mode 100644 index 000000000..cb80097b5 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT52FileAccessTestCompiled : MULANGT52FileAccessTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From 4a4dca09d935222537d6aa2282cb45792f9782ab Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:36:08 +0100 Subject: [PATCH 342/423] Refactor --- .../com/smeup/rpgparser/smeup/MULANGT50FileAccess1Test.kt | 3 +++ ...cessTestCompiled.kt => MULANGT50FileAccess1TestCompiled.kt} | 2 +- .../com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt | 3 --- .../com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt | 3 +++ ...cessTestCompiled.kt => MULANGT52FileAccess2TestCompiled.kt} | 2 +- .../com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt | 3 --- 6 files changed, 8 insertions(+), 8 deletions(-) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1Test.kt rename rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/{MULANGT50FileAccessTestCompiled.kt => MULANGT50FileAccess1TestCompiled.kt} (53%) delete mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt rename rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/{MULANGT52FileAccessTestCompiled.kt => MULANGT52FileAccess2TestCompiled.kt} (53%) delete mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt 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 new file mode 100644 index 000000000..3a17b7750 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1Test.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT50FileAccess1Test : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1TestCompiled.kt similarity index 53% rename from rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTestCompiled.kt rename to rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1TestCompiled.kt index 1aacd686a..3a7816e50 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTestCompiled.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccess1TestCompiled.kt @@ -1,5 +1,5 @@ package com.smeup.rpgparser.smeup -class MULANGT50FileAccessTestCompiled : MULANGT50FileAccessTest() { +class MULANGT50FileAccess1TestCompiled : MULANGT50FileAccess1Test() { override fun useCompiledVersion() = true } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt deleted file mode 100644 index 165acf1af..000000000 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT50FileAccessTest.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.smeup.rpgparser.smeup - -open class MULANGT50FileAccessTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt new file mode 100644 index 000000000..28e9f8136 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT52FileAccess2Test : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2TestCompiled.kt similarity index 53% rename from rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTestCompiled.kt rename to rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2TestCompiled.kt index cb80097b5..ab27cf50b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTestCompiled.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2TestCompiled.kt @@ -1,5 +1,5 @@ package com.smeup.rpgparser.smeup -class MULANGT52FileAccessTestCompiled : MULANGT52FileAccessTest() { +class MULANGT52FileAccess2TestCompiled : MULANGT52FileAccess2Test() { override fun useCompiledVersion() = true } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt deleted file mode 100644 index 8e39be29a..000000000 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccessTest.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.smeup.rpgparser.smeup - -open class MULANGT52FileAccessTest : MULANGTTest() \ No newline at end of file From 04f8f6cdab65fbae3546ed8f997946cd83bcd74e Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:37:23 +0100 Subject: [PATCH 343/423] Add MULANGT53FileAccess3Test scaffold --- .../com/smeup/rpgparser/smeup/MULANGT53FileAccess3Test.kt | 3 +++ .../rpgparser/smeup/MULANGT53FileAccess3TestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT53FileAccess3Test.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT53FileAccess3TestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT53FileAccess3Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT53FileAccess3Test.kt new file mode 100644 index 000000000..7b1c15ba5 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT53FileAccess3Test.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT53FileAccess3Test : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT53FileAccess3TestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT53FileAccess3TestCompiled.kt new file mode 100644 index 000000000..1e8c401e8 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT53FileAccess3TestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT53FileAccess3TestCompiled : MULANGT53FileAccess3Test() { + override fun useCompiledVersion() = true +} \ No newline at end of file From e15bbb2cec44eb8d242f8312cb57fbbfed301660 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:41:18 +0100 Subject: [PATCH 344/423] Add MULANGT54FileMUDBMS0FTest scaffold --- .../com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTest.kt | 3 +++ .../rpgparser/smeup/MULANGT54FileMUDBMS0FTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTest.kt new file mode 100644 index 000000000..8647e29a5 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT54FileMUDBMS0FTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTestCompiled.kt new file mode 100644 index 000000000..b54f2b60e --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT54FileMUDBMS0FTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT54FileMUDBMS0FTestCompiled : MULANGT54FileMUDBMS0FTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From a38a837a64a90ac0a2fb3e62cc99de5316e60fc0 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 18 Mar 2024 15:44:54 +0100 Subject: [PATCH 345/423] Add MULANGT70CompilationDirectiveTest scaffold --- .../rpgparser/smeup/MULANGT70CompilationDirectiveTest.kt | 3 +++ .../smeup/MULANGT70CompilationDirectiveTestCompiled.kt | 5 +++++ 2 files changed, 8 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT70CompilationDirectiveTest.kt create mode 100644 rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT70CompilationDirectiveTestCompiled.kt diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT70CompilationDirectiveTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT70CompilationDirectiveTest.kt new file mode 100644 index 000000000..bc661c5da --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT70CompilationDirectiveTest.kt @@ -0,0 +1,3 @@ +package com.smeup.rpgparser.smeup + +open class MULANGT70CompilationDirectiveTest : MULANGTTest() \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT70CompilationDirectiveTestCompiled.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT70CompilationDirectiveTestCompiled.kt new file mode 100644 index 000000000..5ecd4425b --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT70CompilationDirectiveTestCompiled.kt @@ -0,0 +1,5 @@ +package com.smeup.rpgparser.smeup + +class MULANGT70CompilationDirectiveTestCompiled : MULANGT70CompilationDirectiveTest() { + override fun useCompiledVersion() = true +} \ No newline at end of file From 86132a844555e2fa7c78eee979e70837c98f188e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 18 Mar 2024 16:18:40 +0100 Subject: [PATCH 346/423] Fixed test --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 2 +- .../src/test/resources/smeup/T02_A80_P05.rpgle | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 09190663e..e97be4ac9 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -681,7 +681,7 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A80_P05() { - val expected = listOf("ABCDEFGHIJ") + val expected = listOf("ABCDEFGHIJ123.00000") assertEquals(expected, "smeup/T02_A80_P05".outputOf(configuration = smeupConfig)) } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P05.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P05.rpgle index a1981351c..6af35c596 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P05.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P05.rpgle @@ -1,7 +1,10 @@ DXQNCOG E DS EXTNAME(CQNCOG0F) INZ + DCQNCOG E DS EXTNAME(CQNCOG0F) INZ D £DBG_Str S 50 VARYING C CLEAR X§PROG 10 + C CLEAR X§QT01 15 5 C EVAL X§PROG = 'ABCDEFGHIJ' - C EVAL £DBG_Str=%TRIM(X§PROG) + C EVAL X§QT01 = 123 + C EVAL £DBG_Str=%TRIM(X§PROG)+%CHAR(X§QT01) C £DBG_Str DSPLY \ No newline at end of file From 8d78ddb8cb7bb4e0f4f6286e50cdd5ba5cca11a5 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 18 Mar 2024 16:57:13 +0100 Subject: [PATCH 347/423] Merge from develop --- .../src/main/antlr/RpgLexer.tokens | 1047 ++++++++--------- .../evaluation/SmeupInterpreterTest.kt | 1 - 2 files changed, 523 insertions(+), 525 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens index 7752ce687..70ee2662e 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgLexer.tokens @@ -252,530 +252,529 @@ SPLAT_FILE=251 SPLAT_GETIN=252 SPLAT_HIVAL=253 SPLAT_INIT=254 -SPLAT_ALL_INDICATORS=255 -SPLAT_INDICATOR=256 -SPLAT_INZSR=257 -SPLAT_IN=258 -SPLAT_INPUT=259 -SPLAT_OUTPUT=260 -SPLAT_JOBRUN=261 -SPLAT_JOB=262 -SPLAT_LDA=263 -SPLAT_LIKE=264 -SPLAT_LONGJUL=265 -SPLAT_LOVAL=266 -SPLAT_KEY=267 -SPLAT_MONTH=268 -SPLAT_NEXT=269 -SPLAT_NOIND=270 -SPLAT_NOKEY=271 -SPLAT_NULL=272 -SPLAT_OFL=273 -SPLAT_ON=274 -SPLAT_ONLY=275 -SPLAT_OFF=276 -SPLAT_PDA=277 -SPLAT_PLACE=278 -SPLAT_PSSR=279 -SPLAT_ROUTINE=280 -SPLAT_START=281 -SPLAT_SYS=282 -SPLAT_TERM=283 -SPLAT_TOTC=284 -SPLAT_TOTL=285 -SPLAT_USER=286 -SPLAT_VAR=287 -SPLAT_YEAR=288 -SPLAT_ZEROS=289 -SPLAT_HMS=290 -SPLAT_INLR=291 -SPLAT_INOF=292 -SPLAT_DATA=293 -SPLAT_ASTFILL=294 -SPLAT_CURSYM=295 -SPLAT_MAX=296 -SPLAT_LOCK=297 -SPLAT_PROGRAM=298 -SPLAT_EXTDESC=299 -SPLAT_D=300 -SPLAT_H=301 -SPLAT_HOURS=302 -SPLAT_DAYS=303 -SPLAT_M=304 -SPLAT_MINUTES=305 -SPLAT_MONTHS=306 -SPLAT_MN=307 -SPLAT_MS=308 -SPLAT_MSECONDS=309 -SPLAT_S=310 -SPLAT_SECONDS=311 -SPLAT_Y=312 -SPLAT_YEARS=313 -UDATE=314 -DATE=315 -UMONTH=316 -MONTH=317 -UYEAR=318 -YEAR=319 -UDAY=320 -DAY=321 -PAGE=322 -CHAR=323 -VARCHAR=324 -UCS2=325 -DATE_=326 -VARUCS2=327 -GRAPH=328 -VARGRAPH=329 -IND=330 -PACKED=331 -ZONED=332 -BINDEC=333 -INT=334 -UNS=335 -FLOAT=336 -TIME=337 -TIMESTAMP=338 -POINTER=339 -OBJECT=340 -KEYWORD_ALIAS=341 -KEYWORD_ALIGN=342 -KEYWORD_ALT=343 -KEYWORD_ALTSEQ=344 -KEYWORD_ASCEND=345 -KEYWORD_BASED=346 -KEYWORD_CCSID=347 -KEYWORD_CLASS=348 -KEYWORD_CONST=349 -KEYWORD_CTDATA=350 -KEYWORD_DATFMT=351 -KEYWORD_DESCEND=352 -KEYWORD_DIM=353 -KEYWORD_DTAARA=354 -KEYWORD_EXPORT=355 -KEYWORD_EXT=356 -KEYWORD_EXTFLD=357 -KEYWORD_EXTFMT=358 -KEYWORD_EXTNAME=359 -KEYWORD_EXTPGM=360 -KEYWORD_EXTPROC=361 -KEYWORD_FROMFILE=362 -KEYWORD_IMPORT=363 -KEYWORD_INZ=364 -KEYWORD_LEN=365 -KEYWORD_LIKE=366 -KEYWORD_LIKEDS=367 -KEYWORD_LIKEFILE=368 -KEYWORD_LIKEREC=369 -KEYWORD_NOOPT=370 -KEYWORD_OCCURS=371 -KEYWORD_OPDESC=372 -KEYWORD_OPTIONS=373 -KEYWORD_OVERLAY=374 -KEYWORD_PACKEVEN=375 -KEYWORD_PERRCD=376 -KEYWORD_PREFIX=377 -KEYWORD_POS=378 -KEYWORD_PROCPTR=379 -KEYWORD_QUALIFIED=380 -KEYWORD_RTNPARM=381 -KEYWORD_STATIC=382 -KEYWORD_TEMPLATE=383 -KEYWORD_TIMFMT=384 -KEYWORD_TOFILE=385 -KEYWORD_VALUE=386 -KEYWORD_VARYING=387 -KEYWORD_BLOCK=388 -KEYWORD_COMMIT=389 -KEYWORD_DEVID=390 -KEYWORD_EXTDESC=391 -KEYWORD_EXTFILE=392 -KEYWORD_EXTIND=393 -KEYWORD_EXTMBR=394 -KEYWORD_FORMLEN=395 -KEYWORD_FORMOFL=396 -KEYWORD_IGNORE=397 -KEYWORD_INCLUDE=398 -KEYWORD_INDDS=399 -KEYWORD_INFDS=400 -KEYWORD_INFSR=401 -KEYWORD_KEYLOC=402 -KEYWORD_MAXDEV=403 -KEYWORD_OFLIND=404 -KEYWORD_PASS=405 -KEYWORD_PGMNAME=406 -KEYWORD_PLIST=407 -KEYWORD_PRTCTL=408 -KEYWORD_RAFDATA=409 -KEYWORD_RECNO=410 -KEYWORD_RENAME=411 -KEYWORD_SAVEDS=412 -KEYWORD_SAVEIND=413 -KEYWORD_SFILE=414 -KEYWORD_SLN=415 -KEYWORD_SQLTYPE=416 -KEYWORD_USROPN=417 -KEYWORD_DISK=418 -KEYWORD_WORKSTN=419 -KEYWORD_PRINTER=420 -KEYWORD_SPECIAL=421 -KEYWORD_KEYED=422 -KEYWORD_USAGE=423 -KEYWORD_PSDS=424 -AMPERSAND=425 -AND=426 -OR=427 -NOT=428 -PLUS=429 -MINUS=430 -EXP=431 -ARRAY_REPEAT=432 -MULT_NOSPACE=433 -MULT=434 -DIV=435 -CPLUS=436 -CMINUS=437 -CMULT=438 -CDIV=439 -CEXP=440 -GT=441 -LT=442 -GE=443 -LE=444 -NE=445 -FREE_DOT=446 -EQUAL=447 -FREE_BY=448 -FREE_TO=449 -FREE_DOWNTO=450 -HexLiteralStart=451 -DateLiteralStart=452 -TimeLiteralStart=453 -TimeStampLiteralStart=454 -GraphicLiteralStart=455 -UCS2LiteralStart=456 -StringLiteralStart=457 -FREE_COMMENTS=458 -FREE_WS=459 -C_FREE_CONTINUATION=460 -D_FREE_CONTINUATION=461 -F_FREE_CONTINUATION=462 -FREE_LEAD_WS5=463 -FREE_LEAD_WS5_Comments=464 -FREE_FREE_SPEC=465 -C_FREE_NEWLINE=466 -FREE_NEWLINE=467 -FREE_SEMI=468 -NumberContinuation_CONTINUATION=469 -NumberPart=470 -NumberContinuation_ANY=471 -OP_ADD=472 -OP_ADDDUR=473 -OP_ALLOC=474 -OP_ANDxx=475 -OP_ANDEQ=476 -OP_ANDNE=477 -OP_ANDLE=478 -OP_ANDLT=479 -OP_ANDGE=480 -OP_ANDGT=481 -OP_BITOFF=482 -OP_BITON=483 -OP_CAB=484 -OP_CABEQ=485 -OP_CABNE=486 -OP_CABLE=487 -OP_CABLT=488 -OP_CABGE=489 -OP_CABGT=490 -OP_CALL=491 -OP_CALLB=492 -OP_CASEQ=493 -OP_CASNE=494 -OP_CASLE=495 -OP_CASLT=496 -OP_CASGE=497 -OP_CASGT=498 -OP_CAS=499 -OP_CAT=500 -OP_CHECK=501 -OP_CHECKR=502 -OP_COMP=503 -OP_DEFINE=504 -OP_DIV=505 -OP_DO=506 -OP_DOUEQ=507 -OP_DOUNE=508 -OP_DOULE=509 -OP_DOULT=510 -OP_DOUGE=511 -OP_DOUGT=512 -OP_DOWEQ=513 -OP_DOWNE=514 -OP_DOWLE=515 -OP_DOWLT=516 -OP_DOWGE=517 -OP_DOWGT=518 -OP_END=519 -OP_ENDCS=520 -OP_EXTRCT=521 -OP_GOTO=522 -OP_IFEQ=523 -OP_IFNE=524 -OP_IFLE=525 -OP_IFLT=526 -OP_IFGE=527 -OP_IFGT=528 -OP_KFLD=529 -OP_KLIST=530 -OP_LOOKUP=531 -OP_MHHZO=532 -OP_MHLZO=533 -OP_MLHZO=534 -OP_MLLZO=535 -OP_MOVE=536 -OP_MOVEA=537 -OP_MOVEL=538 -OP_MULT=539 -OP_MVR=540 -OP_OCCUR=541 -OP_OREQ=542 -OP_ORNE=543 -OP_ORLE=544 -OP_ORLT=545 -OP_ORGE=546 -OP_ORGT=547 -OP_PARM=548 -OP_PLIST=549 -OP_REALLOC=550 -OP_SCAN=551 -OP_SETOFF=552 -OP_SETON=553 -OP_SHTDN=554 -OP_SQRT=555 -OP_SUB=556 -OP_SUBDUR=557 -OP_SUBST=558 -OP_TAG=559 -OP_TESTB=560 -OP_TESTN=561 -OP_TESTZ=562 -OP_TIME=563 -OP_WHENEQ=564 -OP_WHENNE=565 -OP_WHENLE=566 -OP_WHENLT=567 -OP_WHENGE=568 -OP_WHENGT=569 -OP_XFOOT=570 -OP_XLATE=571 -OP_Z_ADD=572 -OP_Z_SUB=573 -FE_BLANKS=574 -FE_COMMENTS=575 -FE_NEWLINE=576 -StringContent=577 -StringEscapedQuote=578 -StringLiteralEnd=579 -FIXED_FREE_STRING_CONTINUATION=580 -FIXED_FREE_STRING_CONTINUATION_MINUS=581 -FREE_STRING_CONTINUATION=582 -FREE_STRING_CONTINUATION_MINUS=583 -PlusOrMinus=584 -EatCommentLinesPlus_Any=585 -EatCommentLines_WhiteSpace=586 -EatCommentLines_StarComment=587 -FIXED_FREE_STRING_CONTINUATION_Part2=588 -EatCommentLines_NothingLeft=589 -InFactor_EndFactor=590 -BLANK_COMMENTS_TEXT=591 -COMMENTS_TEXT=592 -COMMENTS_EOL=593 -COMMENTS_TEXT_SKIP=594 -COMMENTS_TEXT_HIDDEN=595 -COMMENTS_EOL_HIDDEN=596 -SQL_WS=597 -WORDS=598 -PS_NAME=599 -PS_CONTINUATION_NAME=600 -PS_CONTINUATION=601 -PS_RESERVED1=602 -PS_BEGIN=603 -PS_END=604 -PS_RESERVED2=605 -PS_KEYWORDS=606 -PS_WS80=607 -PS_COMMENTS80=608 -PS_Any=609 -BLANK_SPEC=610 -CONTINUATION_NAME=611 -CONTINUATION=612 -NAME=613 -EXTERNAL_DESCRIPTION=614 -DATA_STRUCTURE_TYPE=615 -DEF_TYPE_C=616 -DEF_TYPE_PI=617 -DEF_TYPE_PR=618 -DEF_TYPE_DS=619 -DEF_TYPE_S=620 -DEF_TYPE_BLANK=621 -DEF_TYPE=622 -FROM_POSITION=623 -TO_POSITION=624 -DATA_TYPE=625 -DECIMAL_POSITIONS=626 -RESERVED=627 -D_WS=628 -D_COMMENTS80=629 -EOL=630 -CE_WS=631 -CE_COMMENTS80=632 -CE_LEAD_WS5=633 -CE_LEAD_WS5_Comments=634 -CE_D_SPEC_FIXED=635 -CE_P_SPEC_FIXED=636 -CE_NEWLINE=637 -FS_RecordName=638 -FS_Type=639 -FS_Designation=640 -FS_EndOfFile=641 -FS_Addution=642 -FS_Sequence=643 -FS_Format=644 -FS_RecordLength=645 -FS_Limits=646 -FS_LengthOfKey=647 -FS_RecordAddressType=648 -FS_Organization=649 -FS_Device=650 -FS_Reserved=651 -FS_WhiteSpace=652 -OS_RecordName=653 -OS_AndOr=654 -OS_FieldReserved=655 -OS_Type=656 -OS_AddDelete=657 -OS_FetchOverflow=658 -OS_ExceptName=659 -OS_Space3=660 -OS_RemainingSpace=661 -OS_Comments=662 -OS_WS=663 -OS_FieldName=664 -OS_EditNames=665 -OS_BlankAfter=666 -OS_Reserved1=667 -OS_EndPosition=668 -OS_DataFormat=669 -OS_Any=670 -CS_BlankFactor=671 -CS_FactorWs=672 -CS_FactorWs2=673 -CS_FactorContent=674 -CS_OperationAndExtender_Blank=675 -CS_OperationAndExtender_WS=676 -CS_OperationAndExtender=677 -CS_FieldLength=678 -CS_DecimalPositions=679 -CS_WhiteSpace=680 -CS_Comments=681 -CS_FixedComments=682 -CS_FixedOperationAndExtender_WS=683 -CS_FixedOperationExtenderReturn=684 -CS_FixedOperationAndExtender2_WS=685 -CS_FixedOperationExtender2Return=686 -FreeOpExtender_Any=687 -FreeOpExtender2_WS=688 -BlankFlag=689 -NoFlag=690 -BlankIndicator=691 -GeneralIndicator=692 -FunctionKeyIndicator=693 -ControlLevelIndicator=694 -ControlLevel0Indicator=695 -LastRecordIndicator=696 -MatchingRecordIndicator=697 -HaltIndicator=698 -ReturnIndicator=699 -ExternalIndicator=700 -OverflowIndicator=701 -SubroutineIndicator=702 -AndIndicator=703 -OrIndicator=704 -DoubleSplatIndicator=705 -FirstPageIndicator=706 -OtherTextIndicator=707 -NewLineIndicator=708 -CSQL_EMPTY_TEXT=709 -CSQL_TEXT=710 -CSQL_LEADBLANK=711 -CSQL_LEADWS=712 -CSQL_END=713 -CSQL_CONT=714 -CSQL_CSplat=715 -CSQL_EOL=716 -CSQL_Any=717 -CSQLC_LEADWS=718 -CSQLC_CSplat=719 -CSQLC_WS=720 -CSQLC_Comments=721 -CSQLC_Any=722 -C2_FACTOR2_CONT=723 -C2_FACTOR2=724 -C2_OTHER=725 -IS_FileName=726 -IS_FieldReserved=727 -IS_ExtFieldReserved=728 -IS_LogicalRelationship=729 -IS_ExtRecordReserved=730 -IS_Sequence=731 -IS_Number=732 -IS_Option=733 -IS_RecordIdCode=734 -IS_WS=735 -IS_COMMENTS=736 -IF_Name=737 -IF_Reserved=738 -IF_FieldName=739 -IF_Reserved2=740 -IF_WS=741 -IR_WS=742 -IFD_DATA_ATTR=743 -IFD_DATETIME_SEP=744 -IFD_DATA_FORMAT=745 -IFD_FIELD_LOCATION=746 -IFD_DECIMAL_POSITIONS=747 -IFD_FIELD_NAME=748 -IFD_CONTROL_LEVEL=749 -IFD_MATCHING_FIELDS=750 -IFD_BLANKS=751 -IFD_COMMENTS=752 -HS_DECEDIT=753 -HS_NEW=754 -HS_CALLER=755 -HS_ACTGRP=756 -HS_WhiteSpace=757 -HS_CONTINUATION=758 +SPLAT_INDICATOR=255 +SPLAT_INZSR=256 +SPLAT_IN=257 +SPLAT_INPUT=258 +SPLAT_OUTPUT=259 +SPLAT_JOBRUN=260 +SPLAT_JOB=261 +SPLAT_LDA=262 +SPLAT_LIKE=263 +SPLAT_LONGJUL=264 +SPLAT_LOVAL=265 +SPLAT_KEY=266 +SPLAT_MONTH=267 +SPLAT_NEXT=268 +SPLAT_NOIND=269 +SPLAT_NOKEY=270 +SPLAT_NULL=271 +SPLAT_OFL=272 +SPLAT_ON=273 +SPLAT_ONLY=274 +SPLAT_OFF=275 +SPLAT_PDA=276 +SPLAT_PLACE=277 +SPLAT_PSSR=278 +SPLAT_ROUTINE=279 +SPLAT_START=280 +SPLAT_SYS=281 +SPLAT_TERM=282 +SPLAT_TOTC=283 +SPLAT_TOTL=284 +SPLAT_USER=285 +SPLAT_VAR=286 +SPLAT_YEAR=287 +SPLAT_ZEROS=288 +SPLAT_HMS=289 +SPLAT_INLR=290 +SPLAT_INOF=291 +SPLAT_DATA=292 +SPLAT_ASTFILL=293 +SPLAT_CURSYM=294 +SPLAT_MAX=295 +SPLAT_LOCK=296 +SPLAT_PROGRAM=297 +SPLAT_EXTDESC=298 +SPLAT_D=299 +SPLAT_H=300 +SPLAT_HOURS=301 +SPLAT_DAYS=302 +SPLAT_M=303 +SPLAT_MINUTES=304 +SPLAT_MONTHS=305 +SPLAT_MN=306 +SPLAT_MS=307 +SPLAT_MSECONDS=308 +SPLAT_S=309 +SPLAT_SECONDS=310 +SPLAT_Y=311 +SPLAT_YEARS=312 +UDATE=313 +DATE=314 +UMONTH=315 +MONTH=316 +UYEAR=317 +YEAR=318 +UDAY=319 +DAY=320 +PAGE=321 +CHAR=322 +VARCHAR=323 +UCS2=324 +DATE_=325 +VARUCS2=326 +GRAPH=327 +VARGRAPH=328 +IND=329 +PACKED=330 +ZONED=331 +BINDEC=332 +INT=333 +UNS=334 +FLOAT=335 +TIME=336 +TIMESTAMP=337 +POINTER=338 +OBJECT=339 +KEYWORD_ALIAS=340 +KEYWORD_ALIGN=341 +KEYWORD_ALT=342 +KEYWORD_ALTSEQ=343 +KEYWORD_ASCEND=344 +KEYWORD_BASED=345 +KEYWORD_CCSID=346 +KEYWORD_CLASS=347 +KEYWORD_CONST=348 +KEYWORD_CTDATA=349 +KEYWORD_DATFMT=350 +KEYWORD_DESCEND=351 +KEYWORD_DIM=352 +KEYWORD_DTAARA=353 +KEYWORD_EXPORT=354 +KEYWORD_EXT=355 +KEYWORD_EXTFLD=356 +KEYWORD_EXTFMT=357 +KEYWORD_EXTNAME=358 +KEYWORD_EXTPGM=359 +KEYWORD_EXTPROC=360 +KEYWORD_FROMFILE=361 +KEYWORD_IMPORT=362 +KEYWORD_INZ=363 +KEYWORD_LEN=364 +KEYWORD_LIKE=365 +KEYWORD_LIKEDS=366 +KEYWORD_LIKEFILE=367 +KEYWORD_LIKEREC=368 +KEYWORD_NOOPT=369 +KEYWORD_OCCURS=370 +KEYWORD_OPDESC=371 +KEYWORD_OPTIONS=372 +KEYWORD_OVERLAY=373 +KEYWORD_PACKEVEN=374 +KEYWORD_PERRCD=375 +KEYWORD_PREFIX=376 +KEYWORD_POS=377 +KEYWORD_PROCPTR=378 +KEYWORD_QUALIFIED=379 +KEYWORD_RTNPARM=380 +KEYWORD_STATIC=381 +KEYWORD_TEMPLATE=382 +KEYWORD_TIMFMT=383 +KEYWORD_TOFILE=384 +KEYWORD_VALUE=385 +KEYWORD_VARYING=386 +KEYWORD_BLOCK=387 +KEYWORD_COMMIT=388 +KEYWORD_DEVID=389 +KEYWORD_EXTDESC=390 +KEYWORD_EXTFILE=391 +KEYWORD_EXTIND=392 +KEYWORD_EXTMBR=393 +KEYWORD_FORMLEN=394 +KEYWORD_FORMOFL=395 +KEYWORD_IGNORE=396 +KEYWORD_INCLUDE=397 +KEYWORD_INDDS=398 +KEYWORD_INFDS=399 +KEYWORD_INFSR=400 +KEYWORD_KEYLOC=401 +KEYWORD_MAXDEV=402 +KEYWORD_OFLIND=403 +KEYWORD_PASS=404 +KEYWORD_PGMNAME=405 +KEYWORD_PLIST=406 +KEYWORD_PRTCTL=407 +KEYWORD_RAFDATA=408 +KEYWORD_RECNO=409 +KEYWORD_RENAME=410 +KEYWORD_SAVEDS=411 +KEYWORD_SAVEIND=412 +KEYWORD_SFILE=413 +KEYWORD_SLN=414 +KEYWORD_SQLTYPE=415 +KEYWORD_USROPN=416 +KEYWORD_DISK=417 +KEYWORD_WORKSTN=418 +KEYWORD_PRINTER=419 +KEYWORD_SPECIAL=420 +KEYWORD_KEYED=421 +KEYWORD_USAGE=422 +KEYWORD_PSDS=423 +AMPERSAND=424 +AND=425 +OR=426 +NOT=427 +PLUS=428 +MINUS=429 +EXP=430 +ARRAY_REPEAT=431 +MULT_NOSPACE=432 +MULT=433 +DIV=434 +CPLUS=435 +CMINUS=436 +CMULT=437 +CDIV=438 +CEXP=439 +GT=440 +LT=441 +GE=442 +LE=443 +NE=444 +FREE_DOT=445 +EQUAL=446 +FREE_BY=447 +FREE_TO=448 +FREE_DOWNTO=449 +HexLiteralStart=450 +DateLiteralStart=451 +TimeLiteralStart=452 +TimeStampLiteralStart=453 +GraphicLiteralStart=454 +UCS2LiteralStart=455 +StringLiteralStart=456 +FREE_COMMENTS=457 +FREE_WS=458 +C_FREE_CONTINUATION=459 +D_FREE_CONTINUATION=460 +F_FREE_CONTINUATION=461 +FREE_LEAD_WS5=462 +FREE_LEAD_WS5_Comments=463 +FREE_FREE_SPEC=464 +C_FREE_NEWLINE=465 +FREE_NEWLINE=466 +FREE_SEMI=467 +NumberContinuation_CONTINUATION=468 +NumberPart=469 +NumberContinuation_ANY=470 +OP_ADD=471 +OP_ADDDUR=472 +OP_ALLOC=473 +OP_ANDxx=474 +OP_ANDEQ=475 +OP_ANDNE=476 +OP_ANDLE=477 +OP_ANDLT=478 +OP_ANDGE=479 +OP_ANDGT=480 +OP_BITOFF=481 +OP_BITON=482 +OP_CAB=483 +OP_CABEQ=484 +OP_CABNE=485 +OP_CABLE=486 +OP_CABLT=487 +OP_CABGE=488 +OP_CABGT=489 +OP_CALL=490 +OP_CALLB=491 +OP_CASEQ=492 +OP_CASNE=493 +OP_CASLE=494 +OP_CASLT=495 +OP_CASGE=496 +OP_CASGT=497 +OP_CAS=498 +OP_CAT=499 +OP_CHECK=500 +OP_CHECKR=501 +OP_COMP=502 +OP_DEFINE=503 +OP_DIV=504 +OP_DO=505 +OP_DOUEQ=506 +OP_DOUNE=507 +OP_DOULE=508 +OP_DOULT=509 +OP_DOUGE=510 +OP_DOUGT=511 +OP_DOWEQ=512 +OP_DOWNE=513 +OP_DOWLE=514 +OP_DOWLT=515 +OP_DOWGE=516 +OP_DOWGT=517 +OP_END=518 +OP_ENDCS=519 +OP_EXTRCT=520 +OP_GOTO=521 +OP_IFEQ=522 +OP_IFNE=523 +OP_IFLE=524 +OP_IFLT=525 +OP_IFGE=526 +OP_IFGT=527 +OP_KFLD=528 +OP_KLIST=529 +OP_LOOKUP=530 +OP_MHHZO=531 +OP_MHLZO=532 +OP_MLHZO=533 +OP_MLLZO=534 +OP_MOVE=535 +OP_MOVEA=536 +OP_MOVEL=537 +OP_MULT=538 +OP_MVR=539 +OP_OCCUR=540 +OP_OREQ=541 +OP_ORNE=542 +OP_ORLE=543 +OP_ORLT=544 +OP_ORGE=545 +OP_ORGT=546 +OP_PARM=547 +OP_PLIST=548 +OP_REALLOC=549 +OP_SCAN=550 +OP_SETOFF=551 +OP_SETON=552 +OP_SHTDN=553 +OP_SQRT=554 +OP_SUB=555 +OP_SUBDUR=556 +OP_SUBST=557 +OP_TAG=558 +OP_TESTB=559 +OP_TESTN=560 +OP_TESTZ=561 +OP_TIME=562 +OP_WHENEQ=563 +OP_WHENNE=564 +OP_WHENLE=565 +OP_WHENLT=566 +OP_WHENGE=567 +OP_WHENGT=568 +OP_XFOOT=569 +OP_XLATE=570 +OP_Z_ADD=571 +OP_Z_SUB=572 +FE_BLANKS=573 +FE_COMMENTS=574 +FE_NEWLINE=575 +StringContent=576 +StringEscapedQuote=577 +StringLiteralEnd=578 +FIXED_FREE_STRING_CONTINUATION=579 +FIXED_FREE_STRING_CONTINUATION_MINUS=580 +FREE_STRING_CONTINUATION=581 +FREE_STRING_CONTINUATION_MINUS=582 +PlusOrMinus=583 +EatCommentLinesPlus_Any=584 +EatCommentLines_WhiteSpace=585 +EatCommentLines_StarComment=586 +FIXED_FREE_STRING_CONTINUATION_Part2=587 +EatCommentLines_NothingLeft=588 +InFactor_EndFactor=589 +BLANK_COMMENTS_TEXT=590 +COMMENTS_TEXT=591 +COMMENTS_EOL=592 +COMMENTS_TEXT_SKIP=593 +COMMENTS_TEXT_HIDDEN=594 +COMMENTS_EOL_HIDDEN=595 +SQL_WS=596 +WORDS=597 +PS_NAME=598 +PS_CONTINUATION_NAME=599 +PS_CONTINUATION=600 +PS_RESERVED1=601 +PS_BEGIN=602 +PS_END=603 +PS_RESERVED2=604 +PS_KEYWORDS=605 +PS_WS80=606 +PS_COMMENTS80=607 +PS_Any=608 +BLANK_SPEC=609 +CONTINUATION_NAME=610 +CONTINUATION=611 +NAME=612 +EXTERNAL_DESCRIPTION=613 +DATA_STRUCTURE_TYPE=614 +DEF_TYPE_C=615 +DEF_TYPE_PI=616 +DEF_TYPE_PR=617 +DEF_TYPE_DS=618 +DEF_TYPE_S=619 +DEF_TYPE_BLANK=620 +DEF_TYPE=621 +FROM_POSITION=622 +TO_POSITION=623 +DATA_TYPE=624 +DECIMAL_POSITIONS=625 +RESERVED=626 +D_WS=627 +D_COMMENTS80=628 +EOL=629 +CE_WS=630 +CE_COMMENTS80=631 +CE_LEAD_WS5=632 +CE_LEAD_WS5_Comments=633 +CE_D_SPEC_FIXED=634 +CE_P_SPEC_FIXED=635 +CE_NEWLINE=636 +FS_RecordName=637 +FS_Type=638 +FS_Designation=639 +FS_EndOfFile=640 +FS_Addution=641 +FS_Sequence=642 +FS_Format=643 +FS_RecordLength=644 +FS_Limits=645 +FS_LengthOfKey=646 +FS_RecordAddressType=647 +FS_Organization=648 +FS_Device=649 +FS_Reserved=650 +FS_WhiteSpace=651 +OS_RecordName=652 +OS_AndOr=653 +OS_FieldReserved=654 +OS_Type=655 +OS_AddDelete=656 +OS_FetchOverflow=657 +OS_ExceptName=658 +OS_Space3=659 +OS_RemainingSpace=660 +OS_Comments=661 +OS_WS=662 +OS_FieldName=663 +OS_EditNames=664 +OS_BlankAfter=665 +OS_Reserved1=666 +OS_EndPosition=667 +OS_DataFormat=668 +OS_Any=669 +CS_BlankFactor=670 +CS_FactorWs=671 +CS_FactorWs2=672 +CS_FactorContent=673 +CS_OperationAndExtender_Blank=674 +CS_OperationAndExtender_WS=675 +CS_OperationAndExtender=676 +CS_FieldLength=677 +CS_DecimalPositions=678 +CS_WhiteSpace=679 +CS_Comments=680 +CS_FixedComments=681 +CS_FixedOperationAndExtender_WS=682 +CS_FixedOperationExtenderReturn=683 +CS_FixedOperationAndExtender2_WS=684 +CS_FixedOperationExtender2Return=685 +FreeOpExtender_Any=686 +FreeOpExtender2_WS=687 +BlankFlag=688 +NoFlag=689 +BlankIndicator=690 +GeneralIndicator=691 +FunctionKeyIndicator=692 +ControlLevelIndicator=693 +ControlLevel0Indicator=694 +LastRecordIndicator=695 +MatchingRecordIndicator=696 +HaltIndicator=697 +ReturnIndicator=698 +ExternalIndicator=699 +OverflowIndicator=700 +SubroutineIndicator=701 +AndIndicator=702 +OrIndicator=703 +DoubleSplatIndicator=704 +FirstPageIndicator=705 +OtherTextIndicator=706 +NewLineIndicator=707 +CSQL_EMPTY_TEXT=708 +CSQL_TEXT=709 +CSQL_LEADBLANK=710 +CSQL_LEADWS=711 +CSQL_END=712 +CSQL_CONT=713 +CSQL_CSplat=714 +CSQL_EOL=715 +CSQL_Any=716 +CSQLC_LEADWS=717 +CSQLC_CSplat=718 +CSQLC_WS=719 +CSQLC_Comments=720 +CSQLC_Any=721 +C2_FACTOR2_CONT=722 +C2_FACTOR2=723 +C2_OTHER=724 +IS_FileName=725 +IS_FieldReserved=726 +IS_ExtFieldReserved=727 +IS_LogicalRelationship=728 +IS_ExtRecordReserved=729 +IS_Sequence=730 +IS_Number=731 +IS_Option=732 +IS_RecordIdCode=733 +IS_WS=734 +IS_COMMENTS=735 +IF_Name=736 +IF_Reserved=737 +IF_FieldName=738 +IF_Reserved2=739 +IF_WS=740 +IR_WS=741 +IFD_DATA_ATTR=742 +IFD_DATETIME_SEP=743 +IFD_DATA_FORMAT=744 +IFD_FIELD_LOCATION=745 +IFD_DECIMAL_POSITIONS=746 +IFD_FIELD_NAME=747 +IFD_CONTROL_LEVEL=748 +IFD_MATCHING_FIELDS=749 +IFD_BLANKS=750 +IFD_COMMENTS=751 +HS_DECEDIT=752 +HS_NEW=753 +HS_CALLER=754 +HS_ACTGRP=755 +HS_WhiteSpace=756 +HS_CONTINUATION=757 '('=20 ')'=21 ';'=23 -'&'=425 -'+'=429 -'-'=430 -'/'=435 -'+='=436 -'-='=437 -'*='=438 -'/='=439 -'**='=440 -'>'=441 -'<'=442 -'>='=443 -'<='=444 -'<>'=445 -'.'=446 -'='=447 -' '=610 -' '=661 -' '=671 -' '=675 +'&'=424 +'+'=428 +'-'=429 +'/'=434 +'+='=435 +'-='=436 +'*='=437 +'/='=438 +'**='=439 +'>'=440 +'<'=441 +'>='=442 +'<='=443 +'<>'=444 +'.'=445 +'='=446 +' '=609 +' '=660 +' '=670 +' '=674 diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 34a7192dd..f5babc492 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -75,7 +75,6 @@ open class SmeupInterpreterTest : AbstractTest() { @Test fun executeT02_A40_P5() { val expected = listOf("333,zz") - //assertASTCanBeProduced("smeup/T02_A40_P5", printTree = true) assertEquals(expected, "smeup/T02_A40_P5".outputOf()) } From 9c59dc9871835c04aaebfbaca2c7e0a16ae0b439 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 07:43:18 +0100 Subject: [PATCH 348/423] Implemented test --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ++++++ .../src/test/resources/smeup/T02_A50_P02.rpgle | 9 +++++++++ 2 files changed, 15 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 0d845883a..9fb4885e9 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,4 +666,10 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT02_A50_P02() { + val expected = listOf("A50_A3( ) A50_A4( )") + assertEquals(expected, "smeup/T02_A50_P02".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P02.rpgle new file mode 100644 index 000000000..534112465 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P02.rpgle @@ -0,0 +1,9 @@ + D £DBG_Str S 50 VARYING + D A50_A1 S 7 + + + C *LIKE DEFINE A50_A1 A50_A3 + C *LIKE DEFINE A50_A3 A50_A4 + C EVAL £DBG_Str= 'A50_A3('+A50_A3+')' + C +' A50_A4('+A50_A4+')' + C £DBG_Str DSPLY \ No newline at end of file From bcda8fe3ffcf1370c84b4669d945c28dac498547 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 07:52:17 +0100 Subject: [PATCH 349/423] Moved test into opportune file --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ------ .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 9fb4885e9..0d845883a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,10 +666,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT02_A50_P02() { - val expected = listOf("A50_A3( ) A50_A4( )") - assertEquals(expected, "smeup/T02_A50_P02".outputOf()) - } } \ 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 bc693fd12..f1b290ea9 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 @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT02ConstAndDSpecTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT02ConstAndDSpecTest : MULANGTTest() { + /** + * Like define di una variabile precedentemente dichiara tramite un altro like define + * @see #160 + */ + @Test + fun executeT02_A50_P02() { + val expected = listOf("A50_A3( ) A50_A4( )") + assertEquals(expected, "smeup/T02_A50_P02".outputOf()) + } +} \ No newline at end of file From ab2a22cd013b375c6a2258819001c1b558cafcf9 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 08:03:08 +0100 Subject: [PATCH 350/423] Moved test into opportune file --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ------ .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 66b5116a4..0d845883a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,10 +666,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT02_A40_P03() { - val expected = listOf("CNCLICNCLIAAAABBBBBAAAABBBBBCNFORCNFORCCCCDDDDDCCCCDDDDDCNCOLCNCOLEEEEFFFFFEEEEFFFFF") - assertEquals(expected, "smeup/T02_A40_P03".outputOf()) - } } \ 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 bc693fd12..d6d83aa16 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 @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT02ConstAndDSpecTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT02ConstAndDSpecTest : MULANGTTest() { + /** + * Data reference - DS con 2 Array definiti con overlay + * @see #247 + */ + @Test + fun executeT02_A40_P03() { + val expected = listOf("CNCLICNCLIAAAABBBBBAAAABBBBBCNFORCNFORCCCCDDDDDCCCCDDDDDCNCOLCNCOLEEEEFFFFFEEEEFFFFF") + assertEquals(expected, "smeup/T02_A40_P03".outputOf()) + } +} \ No newline at end of file From efc3acb060b3a0aa6a3858d9dff885a5abd07206 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 08:05:04 +0100 Subject: [PATCH 351/423] Moved test into opportune file --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ------ .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index b48cdadb3..0d845883a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,10 +666,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT02_A80_P04() { - val expected = listOf("ABCDEFGHIJ") - assertEquals(expected, "smeup/T02_A80_P04".outputOf(configuration = smeupConfig)) - } } \ 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 bc693fd12..30a14401c 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 @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT02ConstAndDSpecTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT02ConstAndDSpecTest : MULANGTTest() { + /** + * Data reference - Definizione variabile sia inline che in file + * @see #253 + */ + @Test + fun executeT02_A80_P04() { + val expected = listOf("ABCDEFGHIJ") + assertEquals(expected, "smeup/T02_A80_P04".outputOf(configuration = smeupConfig)) + } +} \ No newline at end of file From 898f31d3299add259b91d16c077dd3482f0b7422 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 08:06:30 +0100 Subject: [PATCH 352/423] Moved test into opportune file --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ------ .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 956beeac1..0d845883a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,10 +666,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT02_A80_P05() { - val expected = listOf("ABCDEFGHIJ123.00000") - assertEquals(expected, "smeup/T02_A80_P05".outputOf(configuration = smeupConfig)) - } } \ 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 bc693fd12..95fd69974 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 @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT02ConstAndDSpecTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT02ConstAndDSpecTest : MULANGTTest() { + /** + * Data reference - Definizione in line e con prefix External DS + * @see #254 + */ + @Test + fun executeT02_A80_P05() { + val expected = listOf("ABCDEFGHIJ123.00000") + assertEquals(expected, "smeup/T02_A80_P05".outputOf(configuration = smeupConfig)) + } +} \ No newline at end of file From 661221a459107a2d39ce776867c642bc6868ca30 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 08:10:17 +0100 Subject: [PATCH 353/423] Moved test into opportune file --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ------ .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 15 ++++++++++++++- .../smeup/{T02_A40_P5.rpgle => T02_A40_P05.rpgle} | 0 3 files changed, 14 insertions(+), 7 deletions(-) rename rpgJavaInterpreter-core/src/test/resources/smeup/{T02_A40_P5.rpgle => T02_A40_P05.rpgle} (100%) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f5babc492..0d845883a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -72,12 +72,6 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T02_A40".outputOf()) } - @Test - fun executeT02_A40_P5() { - val expected = listOf("333,zz") - assertEquals(expected, "smeup/T02_A40_P5".outputOf()) - } - @Test fun executeT04_A20() { val expected = listOf("CALL_1(MULANGT04 , 1, MULANGTB10: MULANGT04 chiamata 1 ) CALL_2(MULANGT04 , 3, MULANGTB10: MULANGT04 chiamata 1 )") 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 bc693fd12..a6a05922c 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 @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT02ConstAndDSpecTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT02ConstAndDSpecTest : MULANGTTest() { + /** + * I cannot calculate the size of DS5_FL1 from the overlaying fields as there are none + * @see #24 + */ + @Test + fun executeT02_A40_P05() { + val expected = listOf("333,zz") + assertEquals(expected, "smeup/T02_A40_P05".outputOf()) + } +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P5.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P05.rpgle similarity index 100% rename from rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P5.rpgle rename to rpgJavaInterpreter-core/src/test/resources/smeup/T02_A40_P05.rpgle From 229b1953107b86730cc2fb5064b3e629614c1f43 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 08:27:40 +0100 Subject: [PATCH 354/423] Move test to MULANGT10BaseCodopTest --- .../rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ------ .../rpgparser/smeup/MULANGT10BaseCodopTest.kt | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 5b7da5187..afeae5b9c 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -678,10 +678,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT10_A20_P52() { - val expected = listOf("A20_N73(2.272) A20_N70(0) A20_N112(11.11) A20_N110(0) A20_N309(4.889964788)") - assertEquals(expected, "smeup/T10_A20_P52".outputOf(configuration = smeupConfig)) - } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt index 9d46c6f12..bd7521a70 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT10BaseCodopTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT10BaseCodopTest : MULANGTTest() { + /** + * DIV e MVR con indicatori + * @see #245 + */ + @Test + fun executeT10_A20_P52() { + val expected = listOf("A20_N73(2.272) A20_N70(0) A20_N112(11.11) A20_N110(0) A20_N309(4.889964788)") + assertEquals(expected, "smeup/T10_A20_P52".outputOf(configuration = smeupConfig)) + } +} \ No newline at end of file From 749c7d53e9d31a7f80c1c33f9315413cbc13b260 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 08:31:39 +0100 Subject: [PATCH 355/423] Move test to MULANGT11Codop2Test --- .../evaluation/SmeupInterpreterTest.kt | 24 ---------- .../rpgparser/smeup/MULANGT11Codop2Test.kt | 45 ++++++++++++++++++- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 389937dc2..0d845883a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -666,28 +666,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT11_A10_P01() { - val expected = listOf("BLOCCO; ERR_ZERO_DIV;") - assertEquals(expected, "smeup/T11_A10_P01".outputOf()) - } - - @Test - fun executeT11_A10_P02() { - val expected = listOf("BLOCCO1; BLOCCO2; BLOCCO3; ERR_ZERO_DIV; FINE_BLOCCO3;; ERR_ZERO_DIV; FINE_BLOCCO2;; ERR_ZERO_DIV; FINE_BLOCCO1;") - assertEquals(expected, "smeup/T11_A10_P02".outputOf()) - } - - @Test - fun executeT11_A10_P03() { - val expected = listOf("DENTRO_IF(BLOCCO; ERR_ZERO_DIV;) DENTRO_DO(BLOCCO; ERR_ZERO_DIV;BLOCCO; ERR_ZERO_DIV;) DENTRO_WHEN(BLOCCO; ERR_ZERO_DIV;) DENTRO_OTHER(BLOCCO; ERR_ZERO_DIV;)") - assertEquals(expected, "smeup/T11_A10_P03".outputOf()) - } - - @Test - fun executeT11_A10_P04() { - val expected = listOf("DENTRO_IF(BLOCCO; ERR_ZERO_DIV;) DENTRO_DO(BLOCCO; ERR_ZERO_DIV;) DENTRO_WHEN(BLOCCO; ERR_ZERO_DIV;) DENTRO_OTHER(BLOCCO; ERR_ZERO_DIV;)") - assertEquals(expected, "smeup/T11_A10_P04".outputOf()) - } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt index f45bd304b..61d651633 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt @@ -1,3 +1,46 @@ package com.smeup.rpgparser.smeup -open class MULANGT11Codop2Test : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT11Codop2Test : MULANGTTest() { + /** + * Monitoraggio e cattura errore + * @see #241 + */ + @Test + fun executeT11_A10_P01() { + val expected = listOf("BLOCCO; ERR_ZERO_DIV;") + assertEquals(expected, "smeup/T11_A10_P01".outputOf()) + } + + /** + * Specifiche MONITOR annidiate + * @see #241 + */ + @Test + fun executeT11_A10_P02() { + val expected = listOf("BLOCCO1; BLOCCO2; BLOCCO3; ERR_ZERO_DIV; FINE_BLOCCO3;; ERR_ZERO_DIV; FINE_BLOCCO2;; ERR_ZERO_DIV; FINE_BLOCCO1;") + assertEquals(expected, "smeup/T11_A10_P02".outputOf()) + } + + /** + * Specifiche MONITOR annidiate in IF, DO e SELECT + * @see #241 + */ + @Test + fun executeT11_A10_P03() { + val expected = listOf("DENTRO_IF(BLOCCO; ERR_ZERO_DIV;) DENTRO_DO(BLOCCO; ERR_ZERO_DIV;BLOCCO; ERR_ZERO_DIV;) DENTRO_WHEN(BLOCCO; ERR_ZERO_DIV;) DENTRO_OTHER(BLOCCO; ERR_ZERO_DIV;)") + assertEquals(expected, "smeup/T11_A10_P03".outputOf()) + } + + /** + * Specifiche IF, DO e SELECT in MONITOR + * @see #241 + */ + @Test + fun executeT11_A10_P04() { + val expected = listOf("DENTRO_IF(BLOCCO; ERR_ZERO_DIV;) DENTRO_DO(BLOCCO; ERR_ZERO_DIV;) DENTRO_WHEN(BLOCCO; ERR_ZERO_DIV;) DENTRO_OTHER(BLOCCO; ERR_ZERO_DIV;)") + assertEquals(expected, "smeup/T11_A10_P04".outputOf()) + } +} \ No newline at end of file From 6b0396cdb7e7d86cc2222e43a032e4900e9536b2 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 09:00:51 +0100 Subject: [PATCH 356/423] Move tests to MULANGT10BaseCodopTest --- .../evaluation/SmeupInterpreterTest.kt | 18 ---------- .../rpgparser/smeup/MULANGT10BaseCodopTest.kt | 35 ++++++++++++++++++- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 9be2b68da..d949ee3d7 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -672,22 +672,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT10_A45_P04() { - val expected = listOf("IND(0)") - assertEquals(expected, "smeup/T10_A45_P04".outputOf()) - } - - @Test - fun executeT10_A45_P05() { - val expected = listOf("IND(1)") - assertEquals(expected, "smeup/T10_A45_P05".outputOf()) - } - - @Test - fun executeT10_A45_P06() { - val expected = listOf("IND(0)") - assertEquals(expected, "smeup/T10_A45_P06".outputOf()) - } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt index 9d46c6f12..d2d2fe7cb 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt @@ -1,3 +1,36 @@ package com.smeup.rpgparser.smeup -open class MULANGT10BaseCodopTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT10BaseCodopTest : MULANGTTest() { + /** + * Check con indicatore con verifica a buon fine + * @see #246 + */ + @Test + fun executeT10_A45_P04() { + val expected = listOf("IND(0)") + assertEquals(expected, "smeup/T10_A45_P04".outputOf()) + } + + /** + * Check con indicatore con verifica non ok + * @see #246 + */ + @Test + fun executeT10_A45_P05() { + val expected = listOf("IND(1)") + assertEquals(expected, "smeup/T10_A45_P05".outputOf()) + } + + /** + * Check con indicatore di errore + * @see #246 + */ + @Test + fun executeT10_A45_P06() { + val expected = listOf("IND(0)") + assertEquals(expected, "smeup/T10_A45_P06".outputOf()) + } +} \ No newline at end of file From 10894cc94badc9ea6332cdaeb2ca6d3855395db6 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 11:40:17 +0100 Subject: [PATCH 357/423] Add unit test --- .../rpgparser/smeup/MULANGT40ArrayAndDSTest.kt | 15 ++++++++++++++- .../src/test/resources/smeup/T40_A10_P10.rpgle | 7 +++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P10.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt index 53c400fe2..d88696736 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT40ArrayAndDSTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT40ArrayAndDSTest : MULANGTTest() { + /** + * Reset con definizione inline + * @see #242 + */ + @Test + fun executeT40_A10_P10() { + val expected = listOf("Contenuto Pre-RESET: AAA - Contenuto Post-RESET:") + assertEquals(expected, "smeup/T40_A10_P10".outputOf(configuration = smeupConfig)) + } +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P10.rpgle new file mode 100644 index 000000000..fc9ee5879 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T40_A10_P10.rpgle @@ -0,0 +1,7 @@ + D £DBG_Str S 150 VARYING + C EVAL A10_D1='AAA' + C EVAL £DBG_Str='Contenuto Pre-RESET: '+A10_D1 + C RESET A10_D1 10 + C EVAL £DBG_Str=%TRIMR(£DBG_Str) + C +' - Contenuto Post-RESET: '+A10_D1 + C £DBG_Str DSPLY From 7b65b54b31f13499672add6443a02170bea11742 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 11:40:54 +0100 Subject: [PATCH 358/423] Add support for ResetStmt inline declarations --- .../smeup/rpgparser/parsing/ast/statements.kt | 27 +++++++++++-------- .../rpgparser/parsing/parsetreetoast/misc.kt | 5 ++++ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 16d630be7..512924a9f 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1968,22 +1968,27 @@ data class XlateStmt( @Serializable data class ResetStmt( val name: String, + @Derived val dataDefinition: InStatementDataDefinition? = null, override val position: Position? = null -) : Statement(position) { +) : Statement(position), StatementThatCanDefineData { override fun execute(interpreter: InterpreterCore) { - val dataDefinition = interpreter.dataDefinitionByName(name) - require(dataDefinition != null) { - this.error("Data definition $name not found") - } - require(dataDefinition is DataDefinition) { - this.error("Data definition $name is not an instance of DataDefinition") - } - require(dataDefinition.defaultValue != null) { - this.error("Data definition $name has no default value") + when (val dataDefinition = interpreter.dataDefinitionByName(name)) { + null -> this.error("Data definition $name not found") + is DataDefinition -> { + require(dataDefinition.defaultValue != null) { + this.error("Data definition $name has no default value") + } + interpreter.assign(dataDefinition, dataDefinition.defaultValue!!) + } + is InStatementDataDefinition -> { + interpreter.assign(dataDefinition, dataDefinition.type.blank()) + } + else -> this.error("Data definition $name is not a valid instance of DataDefinition") } - interpreter.assign(dataDefinition, dataDefinition.defaultValue!!) } + + override fun dataDefinition(): List = dataDefinition?.let { listOf(it) } ?: emptyList() } @Serializable diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index e9cc0ddf4..4c07b4b23 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1940,6 +1940,7 @@ internal fun CsCLOSEContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( internal fun CsRESETContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { val position = toPosition(conf.considerPosition) + require(this.cspec_fixed_standard_parts().factor().text.isEmptyTrim()) { "RESET operation does not support factor1" } @@ -1950,8 +1951,12 @@ internal fun CsRESETContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( require(!result.isEmptyTrim()) { "RESET operation requires result" } + + val dataDefinition = this.cspec_fixed_standard_parts().toDataDefinition(result, position, conf) + return ResetStmt( name = result, + dataDefinition = dataDefinition, position = position ) } From 933c6eee4674e91a5311eeb3199d6ddaceaf8893 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 13:04:50 +0100 Subject: [PATCH 359/423] Update test description --- .../kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt index d88696736..5a740c0e4 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT40ArrayAndDSTest.kt @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT40ArrayAndDSTest : MULANGTTest() { /** - * Reset con definizione inline + * Reset with inline declaration * @see #242 */ @Test From 267fc4739d31157ad3ede7c9fec7db04775fca82 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 13:06:51 +0100 Subject: [PATCH 360/423] Update test description --- .../com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt index 61d651633..8bda0a157 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT11Codop2Test.kt @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT11Codop2Test : MULANGTTest() { /** - * Monitoraggio e cattura errore + * MONITOR and error catching * @see #241 */ @Test @@ -15,7 +15,7 @@ open class MULANGT11Codop2Test : MULANGTTest() { } /** - * Specifiche MONITOR annidiate + * Nested MONITOR statements * @see #241 */ @Test @@ -25,7 +25,7 @@ open class MULANGT11Codop2Test : MULANGTTest() { } /** - * Specifiche MONITOR annidiate in IF, DO e SELECT + * MONITOR nested in IF, DO and SELECT * @see #241 */ @Test @@ -35,7 +35,7 @@ open class MULANGT11Codop2Test : MULANGTTest() { } /** - * Specifiche IF, DO e SELECT in MONITOR + * IF, DO and SELECT in MONITOR * @see #241 */ @Test From 39d13863f79b9183f4d74ca4e79d01071332aa10 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 13:08:54 +0100 Subject: [PATCH 361/423] Update test description --- .../com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt index d2d2fe7cb..cdfd829ee 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT10BaseCodopTest : MULANGTTest() { /** - * Check con indicatore con verifica a buon fine + * Positive Check with indicator * @see #246 */ @Test @@ -15,7 +15,7 @@ open class MULANGT10BaseCodopTest : MULANGTTest() { } /** - * Check con indicatore con verifica non ok + * Negative Check with indicator * @see #246 */ @Test @@ -25,7 +25,7 @@ open class MULANGT10BaseCodopTest : MULANGTTest() { } /** - * Check con indicatore di errore + * Check with error indicator * @see #246 */ @Test From 5edf31064064fcd8b6e55fc17fa91ae0fed1470d Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 13:09:36 +0100 Subject: [PATCH 362/423] Update test description --- .../kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt index bd7521a70..61423f3eb 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT10BaseCodopTest : MULANGTTest() { /** - * DIV e MVR con indicatori + * DIV and MVR with indicators * @see #245 */ @Test From 3ee154953a81fbe4c1d5003ecdc55b2d597666c5 Mon Sep 17 00:00:00 2001 From: Domenico Date: Tue, 19 Mar 2024 13:15:14 +0100 Subject: [PATCH 363/423] Move unit tests to MULANGT10BaseCodopTest --- .../evaluation/SmeupInterpreterTest.kt | 12 --------- .../rpgparser/smeup/MULANGT10BaseCodopTest.kt | 25 ++++++++++++++++++- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index f9fe3310b..afeae5b9c 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -621,18 +621,6 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T10_A20_P47".outputOf()) } - @Test - fun executeT10_A35_P08() { - val expected = listOf("A35_AR1(2)(123&5) IN45(1)") - assertEquals(expected, "smeup/T10_A35_P08".outputOf(configuration = smeupConfig)) - } - - @Test - fun executeT10_A35_P10() { - val expected = listOf("A35_AR2(01)(5) A35_AR2(02)(6) A35_AR2(03)(0) IN20(1)") - assertEquals(expected, "smeup/T10_A35_P10".outputOf(configuration = smeupConfig)) - } - @Test fun executeT18_A10_P01() { val expected = listOf("Ritorno_Procedura") diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt index 9d46c6f12..0b10a127e 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt @@ -1,3 +1,26 @@ package com.smeup.rpgparser.smeup -open class MULANGT10BaseCodopTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT10BaseCodopTest : MULANGTTest() { + /** + * SCAN with array in input + * @see #218 + */ + @Test + fun executeT10_A35_P08() { + val expected = listOf("A35_AR1(2)(123&5) IN45(1)") + assertEquals(expected, "smeup/T10_A35_P08".outputOf(configuration = smeupConfig)) + } + + /** + * SCAN with array in result + * @see #244 + */ + @Test + fun executeT10_A35_P10() { + val expected = listOf("A35_AR2(01)(5) A35_AR2(02)(6) A35_AR2(03)(0) IN20(1)") + assertEquals(expected, "smeup/T10_A35_P10".outputOf(configuration = smeupConfig)) + } +} \ No newline at end of file From d3cd7a2f8cdf9d8d0228d89a7811d6454c9bd5ce Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 14:03:49 +0100 Subject: [PATCH 364/423] Fixed comments --- .../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 f69d2c890..8c630cf1a 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 @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT02ConstAndDSpecTest : MULANGTTest() { /** - * Data reference - Definizione inline e in specifiche D + * Data reference - Inline definition * @see #250 */ @Test From a5e9b3b518b06a2f0b71ccd76451669d627d4278 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 14:04:38 +0100 Subject: [PATCH 365/423] Fixed comments --- .../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 d6d83aa16..d2533c3d9 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 @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT02ConstAndDSpecTest : MULANGTTest() { /** - * Data reference - DS con 2 Array definiti con overlay + * Data reference - DS with 2 array defined with overlay * @see #247 */ @Test From 1cf9eea0cc3dde10c2155a289d4411f204197d31 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 14:04:55 +0100 Subject: [PATCH 366/423] Fixed comments --- .../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 d2533c3d9..e4df6941f 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 @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT02ConstAndDSpecTest : MULANGTTest() { /** - * Data reference - DS with 2 array defined with overlay + * Data reference - DS with 2 arrays defined with overlay * @see #247 */ @Test From f64e9a2421c1fecb10428aac69086982a9a14c8e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 14:05:22 +0100 Subject: [PATCH 367/423] Fixed comments --- .../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 30a14401c..f45a678e2 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 @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT02ConstAndDSpecTest : MULANGTTest() { /** - * Data reference - Definizione variabile sia inline che in file + * Data reference - Definition both inline and file * @see #253 */ @Test From 1dda86d2bd46912b567e955405288a3da47cd2db Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 14:05:55 +0100 Subject: [PATCH 368/423] Fixed comments --- .../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 95fd69974..6c506a570 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 @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT02ConstAndDSpecTest : MULANGTTest() { /** - * Data reference - Definizione in line e con prefix External DS + * Data reference - Inline definition and with prefix External DS * @see #254 */ @Test From a5fb94dba5dfcea9af66bfedae23cf2b81241ad3 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 14:07:52 +0100 Subject: [PATCH 369/423] Fixed comments --- .../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 f1b290ea9..47245d519 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 @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT02ConstAndDSpecTest : MULANGTTest() { /** - * Like define di una variabile precedentemente dichiara tramite un altro like define + * Definition with Like to a variable defined also with like. * @see #160 */ @Test From 2df74e2e0b0398a14586e403d41416650b73af3e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 19 Mar 2024 14:09:54 +0100 Subject: [PATCH 370/423] Fixed comments --- .../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 a6a05922c..9884885ce 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 @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT02ConstAndDSpecTest : MULANGTTest() { /** - * I cannot calculate the size of DS5_FL1 from the overlaying fields as there are none + * Calculation the size of DS5_FL1 from the overlaying fields * @see #24 */ @Test From d31e4a50e2ce710d10d38f8fc0ac10318f65b43c Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 20 Mar 2024 12:03:37 +0100 Subject: [PATCH 371/423] Moved test from olt Test file to new --- .../smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ------ .../smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt | 10 ++++++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index cdd929b82..afeae5b9c 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -678,10 +678,4 @@ open class SmeupInterpreterTest : AbstractTest() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") assertEquals(expected, "smeup/T40_A30_P01".outputOf(configuration = smeupConfig)) } - - @Test - fun executeT10_A60_P10() { - val expected = listOf("CALL_1( , 1, MULANGTB10: chiamata 1 )") - assertEquals(expected, "smeup/T10_A60_P10".outputOf()) - } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt index 32b403025..d42c43f89 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT10BaseCodopTest.kt @@ -63,4 +63,14 @@ open class MULANGT10BaseCodopTest : MULANGTTest() { val expected = listOf("IND(0)") assertEquals(expected, "smeup/T10_A45_P06".outputOf()) } + + /** + * Definition with PARM and DS + * @see #251 + */ + @Test + fun executeT10_A60_P10() { + val expected = listOf("CALL_1( , 1, MULANGTB10: chiamata 1 )") + assertEquals(expected, "smeup/T10_A60_P10".outputOf()) + } } \ No newline at end of file From 51c49f1953c69a41333dccbe7c89aca52ec0be9e Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 20 Mar 2024 15:48:48 +0100 Subject: [PATCH 372/423] Fixed test --- .../src/test/resources/smeup/T10_A60_P10.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P10.rpgle index cefb447f2..1d05cbbc0 100644 --- a/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P10.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T10_A60_P10.rpgle @@ -1,4 +1,4 @@ - D £DBG_Str S 50 VARYING + D £DBG_Str S 150 VARYING D A60_D1 S 10 D A60_D2 S 2 0 D A60_D3 DS From f70624b6b38462ad5a48df5c79afe1009609ed8a Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 20 Mar 2024 15:50:40 +0100 Subject: [PATCH 373/423] Applied fix for test `T10_A60_P10` --- .../interpreter/ExpressionEvaluation.kt | 9 ++++++++ .../rpgparser/parsing/parsetreetoast/misc.kt | 22 ++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) 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 a419a0e74..233fa1f0e 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 @@ -135,6 +135,15 @@ class ExpressionEvaluation( left is ArrayValue && right is ArrayValue -> { sum(left, right, expression.position) } + left is StringValue && right is DataStructValue -> { + if (left.varying) { + val s = left.value.trimEnd() + right.value + StringValue(s) + } else { + val s = left.value + right.value + StringValue(s) + } + } else -> { throw UnsupportedOperationException("I do not know how to sum $left and $right at ${expression.position}") } diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index d959f321d..5bac1207e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1082,11 +1082,13 @@ internal fun CsPARMContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() } val position = toPosition(conf.considerPosition) return PlistParam( - ReferenceByName(paramName), this.cspec_fixed_standard_parts().toDataDefinition( + ReferenceByName(paramName), + this.cspec_fixed_standard_parts().toDataDefinition( paramName, position, conf - ), position, + ), + position, initializationValue ) } @@ -2037,7 +2039,7 @@ internal fun List.removeDuplicatedDataDefinition dataDefinitionMap[it.name] = it true } else { - it.require(dataDefinition.type == it.type) { + it.require(it.matchType(dataDefinition)) { "Incongruous definitions of ${it.name}: ${dataDefinition.type} vs ${it.type}" } false @@ -2045,6 +2047,20 @@ internal fun List.removeDuplicatedDataDefinition } } +internal fun AbstractDataDefinition.matchType(dataDefinition: AbstractDataDefinition): Boolean { + if (dataDefinition.type == this.type) { + return true + } else if (dataDefinition.type != this.type && dataDefinition.elementSize() == this.elementSize()) { + return when { + dataDefinition.type is StringType && this.type is DataStructureType -> true + dataDefinition.type is DataStructureType && this.type is StringType -> true + else -> false + } + } + + return false +} + /** * This function is used to remove unnecessary record formats from a list of data definitions. * Data definitions of type RecordFormatType are necessary where in the AST we don't have a DS From b47b31e653a126ed3c01c679d8553750ce617cc2 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 20 Mar 2024 16:02:37 +0100 Subject: [PATCH 374/423] Moved test into opportune file --- .../com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt | 6 ------ .../kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index 736a730e7..afeae5b9c 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -667,12 +667,6 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T02_A80_P02".outputOf()) } - @Test - fun executeT60_A40_P01() { - val expected = listOf("5") - assertEquals(expected, "smeup/T60_A40_P01".outputOf(configuration = smeupConfig)) - } - @Test fun executeT40_A30_P01() { val expected = listOf("Lunghezza: 32580 Contenuto: - - - - - - -") diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt index e7c1f349e..cd0477904 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt @@ -16,4 +16,10 @@ open class MULANGT60VideoTest : MULANGTTest() { val expected = listOf() assertEquals(expected, "smeup/T60_A10_P01-02".outputOf(configuration = smeupConfig)) } + + @Test + fun executeT60_A40_P01() { + val expected = listOf("5") + assertEquals(expected, "smeup/T60_A40_P01".outputOf(configuration = smeupConfig)) + } } \ No newline at end of file From cb1be7f9aaab23f090556caaa89315bbf33ec6b3 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 20 Mar 2024 16:03:41 +0100 Subject: [PATCH 375/423] Fixed comments --- .../kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt index cd0477904..805982fa4 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt @@ -17,6 +17,11 @@ open class MULANGT60VideoTest : MULANGTTest() { assertEquals(expected, "smeup/T60_A10_P01-02".outputOf(configuration = smeupConfig)) } + + /** + * Data reference - Inline definition and in video file + * @see #252 + */ @Test fun executeT60_A40_P01() { val expected = listOf("5") From 95933c7e256491d43e2040ddf523b8ba1ca665cc Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 21 Mar 2024 09:36:29 +0100 Subject: [PATCH 376/423] Implemented new test with boolean case --- .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 10 ++++++++++ .../src/test/resources/smeup/T02_A80_P06.rpgle | 7 +++++++ 2 files changed, 17 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P06.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 c2cec619c..e1bd9ac23 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 @@ -33,4 +33,14 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { val expected = listOf("ABCDEFGHIJ") assertEquals(expected, "smeup/T02_A80_P04".outputOf(configuration = smeupConfig)) } + + /** + * Inline variable with specification in D (boolean) + * @see #253, in addition to issue + */ + @Test + fun executeT02_A80_P06() { + val expected = listOf("1") + assertEquals(expected, "smeup/T02_A80_P06".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P06.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P06.rpgle new file mode 100644 index 000000000..10779bd32 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A80_P06.rpgle @@ -0,0 +1,7 @@ + D A80_B01 S 1N + D £DBG_Str S 50 VARYING + + C CLEAR A80_B01 1 + C EVAL A80_B01 = *ON + C EVAL £DBG_Str=%CHAR(A80_B01) + C £DBG_Str DSPLY \ No newline at end of file From 416832dded49cc7ff7c9c9df2a0f3ecac022da46 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 21 Mar 2024 09:39:36 +0100 Subject: [PATCH 377/423] Applied fix for new case of test --- .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 5bac1207e..f9598aa2e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -2054,6 +2054,8 @@ internal fun AbstractDataDefinition.matchType(dataDefinition: AbstractDataDefini return when { dataDefinition.type is StringType && this.type is DataStructureType -> true dataDefinition.type is DataStructureType && this.type is StringType -> true + dataDefinition.type is BooleanType && this.type is StringType -> true + dataDefinition.type is StringType && this.type is BooleanType -> true else -> false } } From aac51ca27bd3e0d51d77f27f865e4ecdd2ec3cc7 Mon Sep 17 00:00:00 2001 From: Domenico Date: Fri, 22 Mar 2024 07:08:50 +0100 Subject: [PATCH 378/423] Update assertion for unit test T04_A80_P05 --- .../evaluation/SmeupInterpreterTest.kt | 8 -------- .../MULANGT04EssentialsCodopAndBifTest.kt | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt index afeae5b9c..b05434a6f 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/evaluation/SmeupInterpreterTest.kt @@ -635,14 +635,6 @@ open class SmeupInterpreterTest : AbstractTest() { assertEquals(expected, "smeup/T04_A90_P05".outputOf()) } - @Test - fun executeT04_A80_P05() { - val expected = listOf( - "A80_D1(hhmmss) A80_D2(hhmmssDDMMYY) A80_D3(hhmmssDDMMYYYY)" - ) - assertEquals(expected, "smeup/T04_A80_P05".outputOf()) - } - @Test fun executeT02_A30_P04() { val expected = listOf("AAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFF") diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt index 550a33d21..41af101cd 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT04EssentialsCodopAndBifTest.kt @@ -1,3 +1,20 @@ package com.smeup.rpgparser.smeup -open class MULANGT04EssentialsCodopAndBifTest : MULANGTTest() \ No newline at end of file +import org.junit.Test +import java.time.LocalDateTime +import kotlin.test.assertEquals + +open class MULANGT04EssentialsCodopAndBifTest : MULANGTTest() { + /** + * TIME with inline number declarations + */ + @Test + fun executeT04_A80_P05() { + val isEarly = LocalDateTime.now().hour < 10 + val suffixLength = if (isEarly) 1 else 2 + val expected = listOf( + "A80_D1(hhmm${"s".repeat(suffixLength)}) A80_D2(hhmmssDDMM${"Y".repeat(suffixLength)}) A80_D3(hhmmssDDMMYY${"Y".repeat(suffixLength)})" + ) + assertEquals(expected, "smeup/T04_A80_P05".outputOf()) + } +} \ No newline at end of file From 988cd1535d3f88a88c5c1b7573841eaaac40dbf8 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 12:26:08 +0100 Subject: [PATCH 379/423] Improved solution --- .../rpgparser/parsing/parsetreetoast/misc.kt | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index f9598aa2e..2b5d56f33 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -2048,19 +2048,16 @@ internal fun List.removeDuplicatedDataDefinition } internal fun AbstractDataDefinition.matchType(dataDefinition: AbstractDataDefinition): Boolean { - if (dataDefinition.type == this.type) { - return true - } else if (dataDefinition.type != this.type && dataDefinition.elementSize() == this.elementSize()) { - return when { - dataDefinition.type is StringType && this.type is DataStructureType -> true - dataDefinition.type is DataStructureType && this.type is StringType -> true - dataDefinition.type is BooleanType && this.type is StringType -> true - dataDefinition.type is StringType && this.type is BooleanType -> true - else -> false + return when { + dataDefinition.type == this.type -> true + dataDefinition.elementSize() == this.elementSize() -> { + dataDefinition.type is StringType && this.type is DataStructureType || + dataDefinition.type is DataStructureType && this.type is StringType || + dataDefinition.type is BooleanType && this.type is StringType || + dataDefinition.type is StringType && this.type is BooleanType } + else -> false } - - return false } /** From 73603ce6fcdf973fd64e36569663eff4758b2a93 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 14:19:44 +0100 Subject: [PATCH 380/423] Implemented test --- .../rpgparser/smeup/MULANGT02ConstAndDSpecTest.kt | 10 ++++++++++ .../src/test/resources/smeup/T02_A50_P10.rpgle | 11 +++++++++++ 2 files changed, 21 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P10.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 d116b141f..8841cf889 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 @@ -44,6 +44,16 @@ open class MULANGT02ConstAndDSpecTest : MULANGTTest() { assertEquals(expected, "smeup/T02_A50_P02".outputOf()) } + /** + * LIKE define of field from file + * @see #255 + */ + @Test + fun executeT02_A50_P10() { + val expected = listOf("A50_A10(AAA) A50_B10(BBB)") + assertEquals(expected, "smeup/T02_A50_P10".outputOf(configuration = smeupConfig)) + } + /** * Data reference - Definition both inline and file * @see #253 diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P10.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P10.rpgle new file mode 100644 index 000000000..4fe6dc758 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T02_A50_P10.rpgle @@ -0,0 +1,11 @@ + D £DBG_Str S 50 VARYING + D A50_A1 S 7 + DCQNCOG E DS EXTNAME(CQNCOG0F) INZ + + C *LIKE DEFINE N§TINC A50_A10 + C *LIKE DEFINE A50_A10 A50_B10 + C EVAL A50_A10='AAA' + C EVAL A50_B10='BBB' + C EVAL £DBG_Str= 'A50_A10('+A50_A10+')' + C +' A50_B10('+A50_B10+')' + C £DBG_Str DSPLY From 419b2f8173e03f7da14ef7473846e42419c2a162 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 14:29:56 +0100 Subject: [PATCH 381/423] Implemented test --- .../rpgparser/smeup/MULANGT52FileAccess2Test.kt | 15 ++++++++++++++- .../src/test/resources/smeup/T52_A07_P02.rpgle | 2 ++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P02.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt index 28e9f8136..8cc2948de 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT52FileAccess2Test.kt @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT52FileAccess2Test : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT52FileAccess2Test : MULANGTTest() { + /** + * Mock FEOD operation code + * @see #262 + */ + @Test + fun executeT52_A07_P02() { + val expected = listOf("") + assertEquals(expected, "smeup/T52_A07_P02".outputOf()) + } +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P02.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P02.rpgle new file mode 100644 index 000000000..178e6eed7 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T52_A07_P02.rpgle @@ -0,0 +1,2 @@ + C FEOD MULANGTL + C '' DSPLY From d5b531987453a4533f2e7837b874a817db9c7c70 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 14:30:21 +0100 Subject: [PATCH 382/423] Implemented statement without logic --- .../com/smeup/rpgparser/parsing/ast/serialization.kt | 1 + .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 9 +++++++++ .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 9 +++++++++ 3 files changed, 19 insertions(+) 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 ed2fb4c07..ff6c7e1b8 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 @@ -60,6 +60,7 @@ private val modules = SerializersModule { subclass(DOWxxStmt::class) subclass(EvalStmt::class) subclass(ExecuteSubroutine::class) + subclass(FeodStmt::class) subclass(ForStmt::class) subclass(GotoStmt::class) subclass(IfStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index d75909109..88272dbf1 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -2077,4 +2077,13 @@ data class UnlockStmt( override fun execute(interpreter: InterpreterCore) { // TODO } +} + +@Serializable +data class FeodStmt( + override val position: Position? = null +) : Statement(position) { + override fun execute(interpreter: InterpreterCore) { + // TODO + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 2b5d56f33..e9400af91 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -921,6 +921,9 @@ internal fun Cspec_fixed_standardContext.toAst(conf: ToAstConfiguration = ToAstC this.csUNLOCK() != null -> this.csUNLOCK() .let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) } + this.csFEOD() != null -> this.csFEOD() + .let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) } + else -> todo(conf = conf) } } @@ -1997,6 +2000,12 @@ internal fun CsUNLOCKContext.toAst(conf: ToAstConfiguration = ToAstConfiguration return UnlockStmt(position) } +// TODO +internal fun CsFEODContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { + val position = toPosition(conf.considerPosition) + return FeodStmt(position) +} + /** * Run a block. In case of error throws an error encapsulating useful information * like node position From 768cdea79585376d90f6cbcf002c08c3cdb3f93d Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 14:36:09 +0100 Subject: [PATCH 383/423] Fix after `ktlinCheck` --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 88272dbf1..642e88b7d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -2081,7 +2081,7 @@ data class UnlockStmt( @Serializable data class FeodStmt( - override val position: Position? = null + override val position: Position? = null ) : Statement(position) { override fun execute(interpreter: InterpreterCore) { // TODO From 5a31c5b121f18537e91118e3990b57ff2d839d05 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 15:15:36 +0100 Subject: [PATCH 384/423] Fixed behaviour in `NumberType` --- .../com/smeup/rpgparser/interpreter/typesystem.kt | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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 26690a014..221b6970f 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 @@ -193,7 +193,7 @@ infix fun Long.log(base: Int): Double { } @Serializable -data class NumberType(val entireDigits: Int, val decimalDigits: Int, val rpgType: String? = "") : Type() { +data class `NumberType`(val entireDigits: Int, val decimalDigits: Int, val rpgType: String? = "") : Type() { constructor(entireDigits: Int, decimalDigits: Int, rpgType: RpgType) : this(entireDigits, decimalDigits, rpgType.rpgType) @@ -242,6 +242,19 @@ data class NumberType(val entireDigits: Int, val decimalDigits: Int, val rpgType return false } } + + override fun equals(other: Any?): Boolean { + return if (other is NumberType) { + val resultDigits = this.entireDigits == other.entireDigits && this.decimalDigits == other.decimalDigits + if (rpgType?.isNotBlank()!! && other.rpgType?.isNotEmpty()!!) { + return resultDigits && rpgType == other.rpgType + } + + return resultDigits; + } else { + false + } + } } @Serializable From 496f37d34233a536c3657136d987265c2c52e3cf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 15:58:03 +0100 Subject: [PATCH 385/423] Created `MockStatement` and changed derived class for `Exfmt`, `Readc`, `Unlock`, `Feod` classes --- .../rpgparser/parsing/ast/serialization.kt | 10 ++++--- .../smeup/rpgparser/parsing/ast/statements.kt | 29 +++++++++---------- 2 files changed, 19 insertions(+), 20 deletions(-) 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 ff6c7e1b8..d906955c1 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 @@ -39,6 +39,12 @@ private val modules = SerializersModule { subclass(FieldDefinition::class) subclass(DataDefinition::class) } + polymorphic(MockStatement::class) { + subclass(ExfmtStmt::class) + subclass(ReadcStmt::class) + subclass(UnlockStmt::class) + subclass(FeodStmt::class) + } polymorphic(Statement::class) { subclass(AddStmt::class) subclass(CabStmt::class) @@ -60,7 +66,6 @@ private val modules = SerializersModule { subclass(DOWxxStmt::class) subclass(EvalStmt::class) subclass(ExecuteSubroutine::class) - subclass(FeodStmt::class) subclass(ForStmt::class) subclass(GotoStmt::class) subclass(IfStmt::class) @@ -84,10 +89,7 @@ private val modules = SerializersModule { subclass(ReadPreviousEqualStmt::class) subclass(ReadStmt::class) subclass(ResetStmt::class) - subclass(ExfmtStmt::class) - subclass(ReadcStmt::class) subclass(ReturnStmt::class) - subclass(UnlockStmt::class) subclass(ScanStmt::class) subclass(SelectStmt::class) subclass(CaseStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 642e88b7d..8f783a4b4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -85,6 +85,11 @@ abstract class Statement( abstract fun execute(interpreter: InterpreterCore) } +@Serializable +abstract class MockStatement ( + @Transient override val position: Position? = null, +) : Statement(position) { } + interface CompositeStatement { val body: List } @@ -2055,35 +2060,27 @@ data class ResetStmt( @Serializable data class ExfmtStmt( override val position: Position? = null -) : Statement(position) { - override fun execute(interpreter: InterpreterCore) { - // TODO - } +) : MockStatement(position) { + override fun execute(interpreter: InterpreterCore) { } } @Serializable data class ReadcStmt( override val position: Position? = null -) : Statement(position) { - override fun execute(interpreter: InterpreterCore) { - // TODO - } +) : MockStatement(position) { + override fun execute(interpreter: InterpreterCore) { } } @Serializable data class UnlockStmt( override val position: Position? = null -) : Statement(position) { - override fun execute(interpreter: InterpreterCore) { - // TODO - } +) : MockStatement(position) { + override fun execute(interpreter: InterpreterCore) { } } @Serializable data class FeodStmt( override val position: Position? = null -) : Statement(position) { - override fun execute(interpreter: InterpreterCore) { - // TODO - } +) : MockStatement(position) { + override fun execute(interpreter: InterpreterCore) { } } \ No newline at end of file From b4de5c0e4882e559fc462ee1036eb1dbaa9b6b68 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 15:58:37 +0100 Subject: [PATCH 386/423] Created `MockStatement` and changed derived class for `Exfmt`, `Readc`, `Unlock`, `Feod` classes --- .../com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index e9400af91..42015ca1d 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1983,25 +1983,25 @@ internal fun CsRESETContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( } // TODO -internal fun CsEXFMTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { +internal fun CsEXFMTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MockStatement { val position = toPosition(conf.considerPosition) return ExfmtStmt(position) } // TODO -internal fun CsREADCContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { +internal fun CsREADCContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MockStatement { val position = toPosition(conf.considerPosition) return ReadcStmt(position) } // TODO -internal fun CsUNLOCKContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { +internal fun CsUNLOCKContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MockStatement { val position = toPosition(conf.considerPosition) return UnlockStmt(position) } // TODO -internal fun CsFEODContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { +internal fun CsFEODContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MockStatement { val position = toPosition(conf.considerPosition) return FeodStmt(position) } From 27678a466b17e382e276f61ed662f60d52bab0e0 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 15:59:07 +0100 Subject: [PATCH 387/423] Implemented callback for new `MockStatement` --- .../kotlin/com/smeup/rpgparser/execution/Configuration.kt | 4 +++- .../smeup/rpgparser/interpreter/internal_interpreter.kt | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/execution/Configuration.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/execution/Configuration.kt index daaecacb0..6dd0a3933 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/execution/Configuration.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/execution/Configuration.kt @@ -19,6 +19,7 @@ package com.smeup.rpgparser.execution import com.smeup.dbnative.DBNativeAccessConfig import com.smeup.rpgparser.interpreter.* import com.smeup.rpgparser.parsing.ast.CompilationUnit +import com.smeup.rpgparser.parsing.ast.MockStatement import com.smeup.rpgparser.parsing.facade.CopyBlocks import com.smeup.rpgparser.parsing.facade.CopyId import com.smeup.rpgparser.parsing.facade.SourceReference @@ -162,7 +163,8 @@ data class JarikoCallback( }, var onCallPgmError: (errorEvent: ErrorEvent) -> Unit = { }, var logInfo: ((channel: String, message: String) -> Unit)? = null, - var channelLoggingEnabled: ((channel: String) -> Boolean)? = null + var channelLoggingEnabled: ((channel: String) -> Boolean)? = null, + var onMockStatement: ((mockStatement: MockStatement) -> Unit) = { System.err.println("Executing mock: ${it.javaClass.simpleName}") } ) /** diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index ed356bd9b..3e094df9f 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -411,7 +411,12 @@ open class InternalInterpreter( MainExecutionContext.getConfiguration().jarikoCallback.onEnterStatement(it.first, it.second) } } - statement.execute(this) + + if (statement is MockStatement) { + MainExecutionContext.getConfiguration().jarikoCallback.onMockStatement + } else { + statement.execute(this) + } } } catch (e: ControlFlowException) { throw e From 35f3c4cad8da2b77c97d745de0ac989deff07dcb Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 16:29:22 +0100 Subject: [PATCH 388/423] Changed `MockStatement` from abstract class to interface --- .../smeup/rpgparser/parsing/ast/serialization.kt | 10 ++++------ .../com/smeup/rpgparser/parsing/ast/statements.kt | 13 +++++-------- .../smeup/rpgparser/parsing/parsetreetoast/misc.kt | 8 ++++---- 3 files changed, 13 insertions(+), 18 deletions(-) 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 d906955c1..602722ed9 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 @@ -39,12 +39,6 @@ private val modules = SerializersModule { subclass(FieldDefinition::class) subclass(DataDefinition::class) } - polymorphic(MockStatement::class) { - subclass(ExfmtStmt::class) - subclass(ReadcStmt::class) - subclass(UnlockStmt::class) - subclass(FeodStmt::class) - } polymorphic(Statement::class) { subclass(AddStmt::class) subclass(CabStmt::class) @@ -66,6 +60,8 @@ private val modules = SerializersModule { subclass(DOWxxStmt::class) subclass(EvalStmt::class) subclass(ExecuteSubroutine::class) + subclass(ExfmtStmt::class) + subclass(FeodStmt::class) subclass(ForStmt::class) subclass(GotoStmt::class) subclass(IfStmt::class) @@ -84,6 +80,7 @@ private val modules = SerializersModule { subclass(OccurStmt::class) subclass(OpenStmt::class) subclass(PlistStmt::class) + subclass(ReadcStmt::class) subclass(ReadEqualStmt::class) subclass(ReadPreviousStmt::class) subclass(ReadPreviousEqualStmt::class) @@ -102,6 +99,7 @@ private val modules = SerializersModule { subclass(SubstStmt::class) subclass(TagStmt::class) subclass(TimeStmt::class) + subclass(UnlockStmt::class) subclass(UpdateStmt::class) subclass(XFootStmt::class) subclass(XlateStmt::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 8f783a4b4..8d3fed8d2 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -85,10 +85,7 @@ abstract class Statement( abstract fun execute(interpreter: InterpreterCore) } -@Serializable -abstract class MockStatement ( - @Transient override val position: Position? = null, -) : Statement(position) { } +interface MockStatement interface CompositeStatement { val body: List @@ -2060,27 +2057,27 @@ data class ResetStmt( @Serializable data class ExfmtStmt( override val position: Position? = null -) : MockStatement(position) { +) : Statement(position), MockStatement { override fun execute(interpreter: InterpreterCore) { } } @Serializable data class ReadcStmt( override val position: Position? = null -) : MockStatement(position) { +) : Statement(position), MockStatement { override fun execute(interpreter: InterpreterCore) { } } @Serializable data class UnlockStmt( override val position: Position? = null -) : MockStatement(position) { +) : Statement(position), MockStatement { override fun execute(interpreter: InterpreterCore) { } } @Serializable data class FeodStmt( override val position: Position? = null -) : MockStatement(position) { +) : Statement(position), MockStatement { override fun execute(interpreter: InterpreterCore) { } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 42015ca1d..e9400af91 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1983,25 +1983,25 @@ internal fun CsRESETContext.toAst(conf: ToAstConfiguration = ToAstConfiguration( } // TODO -internal fun CsEXFMTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MockStatement { +internal fun CsEXFMTContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { val position = toPosition(conf.considerPosition) return ExfmtStmt(position) } // TODO -internal fun CsREADCContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MockStatement { +internal fun CsREADCContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { val position = toPosition(conf.considerPosition) return ReadcStmt(position) } // TODO -internal fun CsUNLOCKContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MockStatement { +internal fun CsUNLOCKContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { val position = toPosition(conf.considerPosition) return UnlockStmt(position) } // TODO -internal fun CsFEODContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): MockStatement { +internal fun CsFEODContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement { val position = toPosition(conf.considerPosition) return FeodStmt(position) } From 094838fe55c077a83da009815f4e17190c0dabac Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 16:36:48 +0100 Subject: [PATCH 389/423] Added javadoc --- .../kotlin/com/smeup/rpgparser/execution/Configuration.kt | 4 ++++ .../main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 3 +++ 2 files changed, 7 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/execution/Configuration.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/execution/Configuration.kt index 6dd0a3933..50a1f088f 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/execution/Configuration.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/execution/Configuration.kt @@ -164,6 +164,10 @@ data class JarikoCallback( var onCallPgmError: (errorEvent: ErrorEvent) -> Unit = { }, var logInfo: ((channel: String, message: String) -> Unit)? = null, var channelLoggingEnabled: ((channel: String) -> Boolean)? = null, + /** + * This is called for those statements mocked. + * @param mockStatement "Statement" where is get its name for the `println`. + */ var onMockStatement: ((mockStatement: MockStatement) -> Unit) = { System.err.println("Executing mock: ${it.javaClass.simpleName}") } ) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 8d3fed8d2..82d4041c3 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -85,6 +85,9 @@ abstract class Statement( abstract fun execute(interpreter: InterpreterCore) } +/** + * For statements with this interface there isn't execution but will be called the callback `onMockStatement`. + */ interface MockStatement interface CompositeStatement { From 63b41bf52b7b53d2aa99a3906036f3f28b01ca2b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Fri, 22 Mar 2024 16:54:39 +0100 Subject: [PATCH 390/423] Fix after ktlinCheck --- .../main/kotlin/com/smeup/rpgparser/interpreter/typesystem.kt | 2 +- .../test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt | 1 - 2 files changed, 1 insertion(+), 2 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 221b6970f..2242ce138 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 @@ -250,7 +250,7 @@ data class `NumberType`(val entireDigits: Int, val decimalDigits: Int, val rpgTy return resultDigits && rpgType == other.rpgType } - return resultDigits; + return resultDigits } else { false } diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt index 805982fa4..23fe67081 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT60VideoTest.kt @@ -17,7 +17,6 @@ open class MULANGT60VideoTest : MULANGTTest() { assertEquals(expected, "smeup/T60_A10_P01-02".outputOf(configuration = smeupConfig)) } - /** * Data reference - Inline definition and in video file * @see #252 From 5101ff2ad83273d9291b242c736fa99932610366 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 25 Mar 2024 08:57:05 +0100 Subject: [PATCH 391/423] Removed backtick --- .../main/kotlin/com/smeup/rpgparser/interpreter/typesystem.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2242ce138..fb2aab4f8 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 @@ -193,7 +193,7 @@ infix fun Long.log(base: Int): Double { } @Serializable -data class `NumberType`(val entireDigits: Int, val decimalDigits: Int, val rpgType: String? = "") : Type() { +data class NumberType(val entireDigits: Int, val decimalDigits: Int, val rpgType: String? = "") : Type() { constructor(entireDigits: Int, decimalDigits: Int, rpgType: RpgType) : this(entireDigits, decimalDigits, rpgType.rpgType) From cc5bcfe0fa1e341cf8ed5c459685536766adcd01 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 25 Mar 2024 11:49:04 +0100 Subject: [PATCH 392/423] Moved the `equals` method from top do bottom --- .../com/smeup/rpgparser/interpreter/typesystem.kt | 13 ------------- .../smeup/rpgparser/parsing/parsetreetoast/misc.kt | 14 +++++++++++++- 2 files changed, 13 insertions(+), 14 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 fb2aab4f8..26690a014 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 @@ -242,19 +242,6 @@ data class NumberType(val entireDigits: Int, val decimalDigits: Int, val rpgType return false } } - - override fun equals(other: Any?): Boolean { - return if (other is NumberType) { - val resultDigits = this.entireDigits == other.entireDigits && this.decimalDigits == other.decimalDigits - if (rpgType?.isNotBlank()!! && other.rpgType?.isNotEmpty()!!) { - return resultDigits && rpgType == other.rpgType - } - - return resultDigits - } else { - false - } - } } @Serializable diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 2b5d56f33..037a0aebd 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -2048,8 +2048,20 @@ internal fun List.removeDuplicatedDataDefinition } internal fun AbstractDataDefinition.matchType(dataDefinition: AbstractDataDefinition): Boolean { + fun Type.matchType(other: Any?): Boolean { + if (this is NumberType && other is NumberType) { + val resultDigits = this.entireDigits == other.entireDigits && this.decimalDigits == other.decimalDigits + if (rpgType?.isNotBlank()!! && other.rpgType?.isNotEmpty()!!) { + return resultDigits && rpgType == other.rpgType + } + return resultDigits + } else { + return this == other + } + } + return when { - dataDefinition.type == this.type -> true + dataDefinition.type.matchType(this.type) -> true dataDefinition.elementSize() == this.elementSize() -> { dataDefinition.type is StringType && this.type is DataStructureType || dataDefinition.type is DataStructureType && this.type is StringType || From 54a3453f50438108e728ad5f2b463a333ca2b62e Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 25 Mar 2024 12:12:49 +0100 Subject: [PATCH 393/423] Add rpgle tests cases --- .../test/resources/smeup/T15_A30_P03.rpgle | 18 ++++++++++++++++ .../test/resources/smeup/T15_A30_P05.rpgle | 21 +++++++++++++++++++ .../test/resources/smeup/T15_A30_P06.rpgle | 8 +++++++ .../test/resources/smeup/T15_A30_P07.rpgle | 13 ++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P03.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P05.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P06.rpgle create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P07.rpgle diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P03.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P03.rpgle new file mode 100644 index 000000000..25d5f2649 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P03.rpgle @@ -0,0 +1,18 @@ + D £DBG_Str S 150 VARYING + D A30_SEC S 15 5 + D A30_N70 S 30 0 + D A30_A08 S 8 INZ('12345.67') + + C EXSR SUB_A30_B + C EVAL £DBG_Str=%CHAR(A30_N70) + + C £DBG_Str DSPLY + + *--------------------------------------------------------------------- + RD* Subsezione di SEZ_A30 P03 e P05 + *--------------------------------------------------------------------- + C SUB_A30_B BEGSR + * + C EVAL A30_N70=%INTH(A30_A08) + * + C ENDSR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P05.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P05.rpgle new file mode 100644 index 000000000..fd5d87d5a --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P05.rpgle @@ -0,0 +1,21 @@ + D £DBG_Str S 150 VARYING + D A30_SEC S 15 5 + D NNN S 6 0 INZ(100000) + D A30_N70 S 30 0 + D A30_A08 S 8 INZ('12345.67') + + C DO NNN + C EXSR SUB_A30_B + C ENDDO + C EVAL £DBG_Str=%CHAR(A30_N70) + + C £DBG_Str DSPLY + + *--------------------------------------------------------------------- + RD* Subsezione di SEZ_A30 P03 e P05 + *--------------------------------------------------------------------- + C SUB_A30_B BEGSR + * + C EVAL A30_N70=%INTH(A30_A08) + * + C ENDSR \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P06.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P06.rpgle new file mode 100644 index 000000000..86161fc31 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P06.rpgle @@ -0,0 +1,8 @@ + D £DBG_Str S 150 VARYING + D A30_SEC S 15 5 + + C EVAL A30_SEC=219120.38 + C EVAL A30_SEC=%INTH(A30_SEC) + C EVAL £DBG_Str=%CHAR(A30_SEC) + + C £DBG_Str DSPLY \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P07.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P07.rpgle new file mode 100644 index 000000000..f8c5f1ec9 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A30_P07.rpgle @@ -0,0 +1,13 @@ + D £DBG_Str S 150 VARYING + D A30_SEC S 15 5 + + C EVAL A30_SEC=219120.38 + C EVAL A30_SEC=%INTH(A30_SEC/60)*60 + C EVAL £DBG_Str='Min('+%CHAR(A30_SEC)+') ' + * Arrotondamento ai centesimi + C EVAL A30_SEC=219120.38 + C EVAL A30_SEC=%INTH(A30_SEC/36)*36 + C EVAL £DBG_Str=%TRIMR(£DBG_Str) + C +' Cen('+%CHAR(A30_SEC)+') ' + + C £DBG_Str DSPLY \ No newline at end of file From 76cfd791e36d192975e046ef167edb19482ed904 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 25 Mar 2024 12:13:00 +0100 Subject: [PATCH 394/423] Implement unit tests --- .../rpgparser/smeup/MULANGT15BaseBif1Test.kt | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt index d42cf0dee..d96fbb66b 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt @@ -1,3 +1,46 @@ package com.smeup.rpgparser.smeup -open class MULANGT15BaseBif1Test : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT15BaseBif1Test : MULANGTTest() { + /** + * %INTH with half adjustment + * @see #260 + */ + @Test + fun executeT15_A30_P03() { + val expected = listOf("12346") + assertEquals(expected, "smeup/T15_A30_P03".outputOf()) + } + + /** + * %INTH with half adjustment (100.000 times) + * @see #260 + */ + @Test + fun executeT15_A30_P05() { + val expected = listOf("12346") + assertEquals(expected, "smeup/T15_A30_P05".outputOf()) + } + + /** + * %INTH with seconds half adjustment + * @see #258 + */ + @Test + fun executeT15_A30_P06() { + val expected = listOf("219120.00000") + assertEquals(expected, "smeup/T15_A30_P06".outputOf()) + } + + /** + * %INTH with pre-half adjustment + * @see #259 + */ + @Test + fun executeT15_A30_P07() { + val expected = listOf("Min(219120.00000) Cen(219132.00000)") + assertEquals(expected, "smeup/T15_A30_P07".outputOf()) + } +} \ No newline at end of file From 68b44a7b4b3e77d69da2c5a6ece3e065b9156594 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 25 Mar 2024 12:14:20 +0100 Subject: [PATCH 395/423] Define BIF and Expression --- .../smeup/rpgparser/parsing/ast/builtin_functions.kt | 11 +++++++++++ .../com/smeup/rpgparser/parsing/ast/serialization.kt | 1 + .../com/smeup/rpgparser/parsing/parsetreetoast/bif.kt | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt index cac6ad7e8..0afeefccb 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt @@ -201,6 +201,17 @@ data class IntExpr( override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } +// %INTH +@Serializable +data class InthExpr( + var value: Expression, + override val position: Position? = null +) : + Expression(position) { + override fun render(): String = this.value.render() + override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) +} + // %SQRT @Serializable data class SqrtExpr(var value: Expression, override val position: Position? = null) : 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 602722ed9..427e79dc1 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 @@ -133,6 +133,7 @@ private val modules = SerializersModule { subclass(GreaterThanExpr::class) subclass(HiValExpr::class) subclass(IntExpr::class) + subclass(InthExpr::class) subclass(IntLiteral::class) subclass(LenExpr::class) subclass(LessEqualThanExpr::class) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/bif.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/bif.kt index 59a0dfce1..557960c29 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/bif.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/bif.kt @@ -48,6 +48,7 @@ internal fun RpgParser.BifContext.toAst(conf: ToAstConfiguration = ToAstConfigur this.bif_equal() != null -> this.bif_equal().toAst(conf) this.bif_abs() != null -> this.bif_abs().toAst(conf) this.bif_int() != null -> this.bif_int().toAst(conf) + this.bif_inth() != null -> this.bif_inth().toAst(conf) this.bif_editw() != null -> this.bif_editw().toAst(conf) this.bif_rem() != null -> this.bif_rem().toAst(conf) this.bif_replace() != null -> this.bif_replace().toAst(conf) @@ -133,6 +134,12 @@ internal fun RpgParser.Bif_intContext.toAst(conf: ToAstConfiguration = ToAstConf toPosition(conf.considerPosition)) } +internal fun RpgParser.Bif_inthContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): InthExpr { + return InthExpr( + this.expression().toAst(conf), + toPosition(conf.considerPosition)) +} + internal fun RpgParser.Bif_sqrtContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): SqrtExpr { return SqrtExpr( this.expression().toAst(conf), From c1b32419e506fab7b08393fb016b95b0868a6fe3 Mon Sep 17 00:00:00 2001 From: Domenico Date: Mon, 25 Mar 2024 12:14:32 +0100 Subject: [PATCH 396/423] Implement evaluation logic --- .../com/smeup/rpgparser/interpreter/Evaluator.kt | 1 + .../rpgparser/interpreter/ExpressionEvaluation.kt | 12 ++++++++++++ 2 files changed, 13 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 7167b9e24..1eaf8f748 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 @@ -72,6 +72,7 @@ interface Evaluator { fun eval(expression: AbsExpr): Value fun eval(expression: EditwExpr): Value fun eval(expression: IntExpr): Value + fun eval(expression: InthExpr): Value fun eval(expression: RemExpr): Value fun eval(expression: QualifiedAccessExpr): Value fun eval(expression: ReplaceExpr): 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 233fa1f0e..b16a6fecc 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 @@ -30,6 +30,7 @@ import java.math.RoundingMode import java.time.ZoneId import java.time.temporal.ChronoUnit import kotlin.math.abs +import kotlin.math.roundToLong import kotlin.math.sqrt class ExpressionEvaluation( @@ -649,6 +650,17 @@ class ExpressionEvaluation( else -> throw UnsupportedOperationException("I do not know how to handle $value with %INT") } + override fun eval(expression: InthExpr): Value = + when (val value = expression.value.evalWith(this)) { + is StringValue -> + IntValue(value.value.toDouble().roundToLong()) + is DecimalValue -> + IntValue(value.value.toDouble().roundToLong()) + is UnlimitedStringValue -> + IntValue(value.value.toDouble().roundToLong()) + else -> throw UnsupportedOperationException("I do not know how to handle $value with %INTH") + } + override fun eval(expression: RemExpr): Value { val n = evalAsLong(expression.dividend) val m = evalAsLong(expression.divisor) From e2ab018380f696e6238ff7a7ba7ec948b8fc864b Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Mon, 25 Mar 2024 13:06:40 +0100 Subject: [PATCH 397/423] Implemented test --- .../rpgparser/smeup/MULANGT15BaseBif1Test.kt | 15 ++++++++++++++- .../src/test/resources/smeup/T15_A80_P09.rpgle | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T15_A80_P09.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt index d42cf0dee..d2bf6c101 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt @@ -1,3 +1,16 @@ package com.smeup.rpgparser.smeup -open class MULANGT15BaseBif1Test : MULANGTTest() \ No newline at end of file +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT15BaseBif1Test : MULANGTTest() { + /** + * %LEN near EVAL + * @see #261 + */ + @Test + fun executeT02_A50_P10() { + val expected = listOf("1(10 - North York) 2(5 - North) 3(15 - North )") + assertEquals(expected, "smeup/T15_A80_P09".outputOf()) + } +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A80_P09.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A80_P09.rpgle new file mode 100644 index 000000000..44fc5a4c5 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T15_A80_P09.rpgle @@ -0,0 +1,18 @@ + D A80_V S 40 VARYING INZ('North York') + D A80_N S 5 0 + D £DBG_Str S 100 VARYING + + * Recupero lunghezza attuale + C EVAL A80_N = %LEN(A80_V) + C EVAL £DBG_Str='1('+%CHAR(A80_N)+' - '+A80_V+')' + * Setto lunghezza a 5 + C EVAL %LEN(A80_V) = 5 + C EVAL A80_N= %LEN(A80_V) + C EVAL £DBG_Str=%TRIMR(£DBG_Str) + C +' 2('+%CHAR(A80_N)+' - '+A80_V+')' + * Setto lunghezza a 15 + C EVAL %LEN(A80_V) = 15 + C EVAL A80_N= %LEN(A80_V) + C EVAL £DBG_Str=%TRIMR(£DBG_Str) + C +' 3('+%CHAR(A80_N)+' - '+A80_V+')' + C £DBG_Str DSPLY From a81c0f6b2898ed44209b02b7dab7eb547cda85c2 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 26 Mar 2024 11:56:56 +0100 Subject: [PATCH 398/423] Implemented test --- .../smeup/MULANGT12LoopFlowGotoTest.kt | 17 ++++++++++++++- .../test/resources/smeup/T12_A04_P18.rpgle | 21 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P18.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt index 68c9e6bda..204dec7cd 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt @@ -1,3 +1,18 @@ package com.smeup.rpgparser.smeup -open class MULANGT12LoopFlowGotoTest : MULANGTTest() \ No newline at end of file +import com.smeup.rpgparser.assertCanBeParsed +import org.junit.Test +import kotlin.test.assertEquals + +open class MULANGT12LoopFlowGotoTest : MULANGTTest() { + /** + * DO- Operation not implemented + * @see #263 + */ + @Test + fun executeT12_A04_P18() { +// assertCanBeParsed("smeup/T12_A04_P18", printTree = true) + val expected = listOf("A04_N50_CNT(10) A04_STR(1) A04_END(10) A04_CNT(11)") + assertEquals(expected, "smeup/T12_A04_P18".outputOf()) + } +} \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P18.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P18.rpgle new file mode 100644 index 000000000..45f245138 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P18.rpgle @@ -0,0 +1,21 @@ + D A04_N50_LIM S 6 0 INZ(100000) + D A04_N50_CNT S LIKE(A04_N50_LIM) + D A04_STR S 2 0 + D A04_CNT S 2 0 + D A04_END S 2 0 + D £DBG_Str S 100 VARYING + + C EVAL A04_STR = 2 + C EVAL A04_END = 10 + C A04_STR IFGT 1 -commento + C EVAL A04_STR = 1 + C END + C A04_STR DO A04_END A04_CNT -commento + C EVAL A04_N50_CNT = A04_CNT + C END + C EVAL £DBG_Str= + C 'A04_N50_CNT('+%CHAR(A04_N50_CNT)+') ' + C +'A04_STR('+%CHAR(A04_STR)+') ' + C +'A04_END('+%CHAR(A04_END)+') ' + C +'A04_CNT('+%CHAR(A04_CNT)+') ' + C £DBG_Str DSPLY From 1fe4f109495b0ec86649fe01d0ce414aab9f8036 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 26 Mar 2024 15:02:00 +0100 Subject: [PATCH 399/423] Fixed test --- .../com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt index 204dec7cd..ad50ccd51 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt @@ -1,6 +1,5 @@ package com.smeup.rpgparser.smeup -import com.smeup.rpgparser.assertCanBeParsed import org.junit.Test import kotlin.test.assertEquals @@ -11,7 +10,6 @@ open class MULANGT12LoopFlowGotoTest : MULANGTTest() { */ @Test fun executeT12_A04_P18() { -// assertCanBeParsed("smeup/T12_A04_P18", printTree = true) val expected = listOf("A04_N50_CNT(10) A04_STR(1) A04_END(10) A04_CNT(11)") assertEquals(expected, "smeup/T12_A04_P18".outputOf()) } From 4e772d37d8d1bc3007c47ee9ade0d29c8d9ffba1 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 26 Mar 2024 15:17:12 +0100 Subject: [PATCH 400/423] Fixed test --- .../com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt index ad50ccd51..e4de88fec 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt @@ -5,7 +5,7 @@ import kotlin.test.assertEquals open class MULANGT12LoopFlowGotoTest : MULANGTTest() { /** - * DO- Operation not implemented + * If followed by Do * @see #263 */ @Test From 9311b9de96b040b6f5d48366a08f1ed9e550a74f Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 26 Mar 2024 15:19:44 +0100 Subject: [PATCH 401/423] Created `T12_A04_P19` test for task #264 --- .../smeup/MULANGT12LoopFlowGotoTest.kt | 10 ++++++++ .../test/resources/smeup/T12_A04_P19.rpgle | 25 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P19.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt index e4de88fec..ce373dda8 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT12LoopFlowGotoTest.kt @@ -13,4 +13,14 @@ open class MULANGT12LoopFlowGotoTest : MULANGTTest() { val expected = listOf("A04_N50_CNT(10) A04_STR(1) A04_END(10) A04_CNT(11)") assertEquals(expected, "smeup/T12_A04_P18".outputOf()) } + + /** + * If followed by Do + * @see #264 + */ + @Test + fun executeT12_A04_P19() { + val expected = listOf("DO_1(A04_N50_CNT(10) A04_STR(1) A04_END(10) A04_CNT(11)) DO_2(A04_N50_CNT(15) A04_CNT(16))") + assertEquals(expected, "smeup/T12_A04_P19".outputOf()) + } } \ No newline at end of file diff --git a/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P19.rpgle b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P19.rpgle new file mode 100644 index 000000000..dbe30f231 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/smeup/T12_A04_P19.rpgle @@ -0,0 +1,25 @@ + D A04_N50_LIM S 6 0 INZ(100000) + D A04_N50_CNT S LIKE(A04_N50_LIM) + D A04_STR S 2 0 + D A04_CNT S 2 0 + D A04_END S 2 0 + D £DBG_Str S 100 VARYING + + C EVAL A04_STR = 1 + C EVAL A04_END = 10 + C A04_STR DO A04_END A04_CNT -commento + C EVAL A04_N50_CNT = A04_CNT + C END + C EVAL £DBG_Str='DO_1(' + C +'A04_N50_CNT('+%CHAR(A04_N50_CNT)+') ' + C +'A04_STR('+%CHAR(A04_STR)+') ' + C +'A04_END('+%CHAR(A04_END)+') ' + C +'A04_CNT('+%CHAR(A04_CNT)+')) ' + * + C DO 15 A04_CNT + C EVAL A04_N50_CNT = A04_CNT + C END + C EVAL £DBG_Str=%TRIMR(£DBG_Str)+' DO_2(' + C +'A04_N50_CNT('+%CHAR(A04_N50_CNT)+') ' + C +'A04_CNT('+%CHAR(A04_CNT)+'))' + C £DBG_Str DSPLY From 366eb3af4540ae207adcdcf2f7754058daf574f8 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Tue, 26 Mar 2024 15:30:31 +0100 Subject: [PATCH 402/423] Applied fix --- rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index a6c37a809..9e5f09dbe 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -317,9 +317,14 @@ elseClause: ; casestatement: - csCASxx* - csCASother? - casestatementend + ( + csCASxx+ + csCASother? + casestatementend + ) | ( + csCASother + casestatementend + ) ; csCASxx: From 2e4356c1bde6e90b203ac183a4a779dda5195d57 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 08:34:01 +0100 Subject: [PATCH 403/423] Changed `LenExpr` from simple `Expression` to `AssignableExpression` --- .../com/smeup/rpgparser/parsing/ast/builtin_functions.kt | 8 +++++++- .../com/smeup/rpgparser/parsing/ast/serialization.kt | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt index cac6ad7e8..f9b621c5e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/builtin_functions.kt @@ -159,10 +159,16 @@ data class SubarrExpr( // %LEN @Serializable data class LenExpr(var value: Expression, override val position: Position? = null) : - Expression(position) { + AssignableExpression(position) { + override fun render(): String { return "%LEN(${this.value.render()})" } + + override fun size(): Int { + TODO("Not yet implemented") + } + override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } 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 602722ed9..7861f8eab 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 @@ -134,7 +134,6 @@ private val modules = SerializersModule { subclass(HiValExpr::class) subclass(IntExpr::class) subclass(IntLiteral::class) - subclass(LenExpr::class) subclass(LessEqualThanExpr::class) subclass(LessThanExpr::class) subclass(LogicalAndExpr::class) @@ -178,6 +177,7 @@ private val modules = SerializersModule { subclass(QualifiedAccessExpr::class) subclass(SubstExpr::class) subclass(SubarrExpr::class) + subclass(LenExpr::class) } polymorphic(Directive::class) { subclass(ActivationGroupDirective::class) From b49e4f00bd631126b052a853c17809e6b791f186 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 08:36:24 +0100 Subject: [PATCH 404/423] Changed access for certain attribute of several classes --- .../com/smeup/rpgparser/interpreter/data_definitions.kt | 4 ++-- .../src/main/kotlin/com/smeup/rpgparser/interpreter/values.kt | 2 +- .../kotlin/com/smeup/rpgparser/parsing/ast/expressions.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) 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 4991ef36a..6e35363cb 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 @@ -183,7 +183,7 @@ data class FileDefinition private constructor( @Serializable data class DataDefinition( override val name: String, - @SerialName(value = "dataDefType") override val type: Type, + @SerialName(value = "dataDefType") override var type: Type, var fields: List = emptyList(), val initializationValue: Expression? = null, val inz: Boolean = false, @@ -202,7 +202,7 @@ data class DataDefinition( static = static) { override fun isArray() = type is ArrayType - fun isCompileTimeArray() = type is ArrayType && type.compileTimeArray() + fun isCompileTimeArray() = type is ArrayType && (type as ArrayType).compileTimeArray() init { this.require(name.trim().isNotEmpty(), { "name cannot be empty" }) 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 d9b6cee70..f6d220f4a 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 @@ -75,7 +75,7 @@ interface AbstractStringValue : Value { } @Serializable -data class StringValue(var value: String, val varying: Boolean = false) : AbstractStringValue { +data class StringValue(var value: String, var varying: Boolean = false) : AbstractStringValue { override fun assignableTo(expectedType: Type): Boolean { return when (expectedType) { 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 f29c3e948..108b1e98d 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 @@ -58,7 +58,7 @@ data class RealLiteral( override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } @Serializable -data class StringLiteral(val value: String, override val position: Position? = null) : Expression(position) { +data class StringLiteral(var value: String, override val position: Position? = null) : Expression(position) { override fun render() = "\"$value\"" override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this) } From 085595d9430ca9bec53740b694da6f417847de59 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 08:36:46 +0100 Subject: [PATCH 405/423] Fixed parser --- rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 | 1 + .../kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 index a6c37a809..d9ea9a1a9 100644 --- a/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 +++ b/rpgJavaInterpreter-core/src/main/antlr/RpgParser.g4 @@ -2659,6 +2659,7 @@ target: | base=target OPEN_PAREN index=expression CLOSE_PAREN #indexedTarget | bif_subst #substTarget | bif_subarr #subarrTarget + | bif_len #lenTarget | container=idOrKeyword DOT fieldName=idOrKeyword #qualifiedTarget | indic=SPLAT_INDICATOR #indicatorTarget | base=SPLAT_IN OPEN_PAREN index=expression CLOSE_PAREN #indexedIndicatorTarget diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt index 319c317cb..2896b3285 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/misc.kt @@ -1673,6 +1673,7 @@ internal fun TargetContext.toAst(conf: ToAstConfiguration = ToAstConfiguration() ) is SubstTargetContext -> this.bif_subst().toAst(conf) is SubarrTargetContext -> this.bif_subarr().toAst(conf) + is LenTargetContext -> this.bif_len().toAst(conf) is QualifiedTargetContext -> QualifiedAccessExpr( DataRefExpr(ReferenceByName(this.container.text), this.container!!.toPosition(conf.considerPosition)), ReferenceByName(this.getFieldName()), From 6df744837e0294795076d3ef79c94bec13b42302 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 08:37:58 +0100 Subject: [PATCH 406/423] Implemented logic for setting size by `LenExpr` --- .../interpreter/internal_interpreter.kt | 10 ++++++++++ .../interpreter/interpretation_utils.kt | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 3e094df9f..63a78c3d5 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -824,6 +824,16 @@ open class InternalInterpreter( } return assign(target.array as AssignableExpression, array) } + is LenExpr -> { + require((target.value as? DataRefExpr)?.variable?.referred is DataDefinition) + val dataDefinition: DataDefinition = (target.value as DataRefExpr).variable.referred!! as DataDefinition + + when { + dataDefinition.type is StringType -> dataDefinition.resizeStringSize(value.asInt().value.toInt()) + else -> TODO("Implements redefinition of ${dataDefinition.type.javaClass.name}") + } + return value; + } is QualifiedAccessExpr -> { when (val container = eval(target.container)) { is DataStructValue -> { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt index 335b1741f..c851c3750 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt @@ -65,3 +65,20 @@ fun ActivationGroupType.assignedName(current: RpgProgram, caller: RpgProgram?): else -> error("$this ActivationGroupType is not yet handled") } } + +fun DataDefinition.resizeStringSize(newSize: Int): Unit { + require(this.initializationValue is StringLiteral) + require(this.defaultValue is StringValue) + + val initializationValue: StringLiteral = this.initializationValue + val defaultValue: StringValue = this.defaultValue as StringValue + this.type = StringType(newSize, true) + if (initializationValue.value.length >= newSize) { + initializationValue.value = initializationValue.value.substring(0, newSize) + defaultValue.value = defaultValue.value.substring(0, newSize) + } else { + initializationValue.value = initializationValue.value.padEnd(newSize) + defaultValue.value = defaultValue.value.padEnd(newSize) + } + defaultValue.varying = false +} From 3e5ba7dbec3d0dc93fe86938b8a2eeb1bb2ec45c Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 08:41:00 +0100 Subject: [PATCH 407/423] Some fix after `ktlinCheck` --- .../com/smeup/rpgparser/interpreter/internal_interpreter.kt | 2 +- .../com/smeup/rpgparser/interpreter/interpretation_utils.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index 63a78c3d5..a3fb14327 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -832,7 +832,7 @@ open class InternalInterpreter( dataDefinition.type is StringType -> dataDefinition.resizeStringSize(value.asInt().value.toInt()) else -> TODO("Implements redefinition of ${dataDefinition.type.javaClass.name}") } - return value; + return value } is QualifiedAccessExpr -> { when (val container = eval(target.container)) { diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt index c851c3750..6ffe23327 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt @@ -66,7 +66,7 @@ fun ActivationGroupType.assignedName(current: RpgProgram, caller: RpgProgram?): } } -fun DataDefinition.resizeStringSize(newSize: Int): Unit { +fun DataDefinition.resizeStringSize(newSize: Int) { require(this.initializationValue is StringLiteral) require(this.defaultValue is StringValue) From 7c2e9fffdc1f73cfa08e2c33d4ff2e6037641b62 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 08:43:24 +0100 Subject: [PATCH 408/423] Added `LenExpr to `polymorphic(Expression::class), like previously --- .../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 7861f8eab..a1fa943e3 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 @@ -134,6 +134,7 @@ private val modules = SerializersModule { subclass(HiValExpr::class) subclass(IntExpr::class) subclass(IntLiteral::class) + subclass(LenExpr::class) subclass(LessEqualThanExpr::class) subclass(LessThanExpr::class) subclass(LogicalAndExpr::class) From f1fbad65773a1dc4540e50f2d59e061bc38ede59 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 14:55:04 +0100 Subject: [PATCH 409/423] Changed TODO --- .../com/smeup/rpgparser/interpreter/internal_interpreter.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt index a3fb14327..104d14031 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/internal_interpreter.kt @@ -29,6 +29,7 @@ import com.smeup.rpgparser.parsing.facade.relative import com.smeup.rpgparser.parsing.parsetreetoast.MuteAnnotationExecutionLogEntry import com.smeup.rpgparser.parsing.parsetreetoast.RpgType import com.smeup.rpgparser.parsing.parsetreetoast.resolveAndValidate +import com.smeup.rpgparser.parsing.parsetreetoast.todo import com.smeup.rpgparser.utils.ComparisonOperator.* import com.smeup.rpgparser.utils.chunkAs import com.smeup.rpgparser.utils.resizeTo @@ -830,7 +831,7 @@ open class InternalInterpreter( when { dataDefinition.type is StringType -> dataDefinition.resizeStringSize(value.asInt().value.toInt()) - else -> TODO("Implements redefinition of ${dataDefinition.type.javaClass.name}") + else -> target.todo("Implements redefinition of ${dataDefinition.type.javaClass.name}") } return value } From 79617f89e7f30b95487b3404dea2f35dffe47166 Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 15:49:57 +0100 Subject: [PATCH 410/423] Fixed name of test --- .../kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt index d2bf6c101..df004d9b6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/smeup/MULANGT15BaseBif1Test.kt @@ -9,7 +9,7 @@ open class MULANGT15BaseBif1Test : MULANGTTest() { * @see #261 */ @Test - fun executeT02_A50_P10() { + fun executeT15_A80_P09() { val expected = listOf("1(10 - North York) 2(5 - North) 3(15 - North )") assertEquals(expected, "smeup/T15_A80_P09".outputOf()) } From 7bae89b3f6d0d08997c473625d73a4991d6b6c6a Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Wed, 27 Mar 2024 15:54:57 +0100 Subject: [PATCH 411/423] Changed modifier `resizeStringSize` and added documentation about the purpose of function. --- .../smeup/rpgparser/interpreter/interpretation_utils.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt index 6ffe23327..32421d7c4 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt @@ -66,7 +66,13 @@ fun ActivationGroupType.assignedName(current: RpgProgram, caller: RpgProgram?): } } -fun DataDefinition.resizeStringSize(newSize: Int) { +/** + * This function provides the resizing of a variable defined like String. + * For example: `%LEN() in `EVAL` like this + * C EVAL %LEN(VAR) = 5 + * changes the previous size declaration of `VAR` to a new size. + */ +internal fun DataDefinition.resizeStringSize(newSize: Int) { require(this.initializationValue is StringLiteral) require(this.defaultValue is StringValue) From 7361978009616855fb85807b58e79d649cc2fccf Mon Sep 17 00:00:00 2001 From: Davide Palladino Date: Thu, 28 Mar 2024 08:46:46 +0100 Subject: [PATCH 412/423] Updated documentation about `resizeStringSize` --- .../smeup/rpgparser/interpreter/interpretation_utils.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt index 32421d7c4..778f7e8b5 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/interpreter/interpretation_utils.kt @@ -67,8 +67,11 @@ fun ActivationGroupType.assignedName(current: RpgProgram, caller: RpgProgram?): } /** - * This function provides the resizing of a variable defined like String. - * For example: `%LEN() in `EVAL` like this + * This function provides the resizing of a variable defined like String, changing the varying to not varying. + * In addition, truncates the previous string if the target size is shorter, or add spaces if is longer. + * Throws an `IllegalArgumentException` if the `initializationValue` isn't `StringLiteral` or `defaultValue` isn't `StringValue`. + * + * For example: `%LEN() in `EVAL` like this: * C EVAL %LEN(VAR) = 5 * changes the previous size declaration of `VAR` to a new size. */ @@ -78,7 +81,7 @@ internal fun DataDefinition.resizeStringSize(newSize: Int) { val initializationValue: StringLiteral = this.initializationValue val defaultValue: StringValue = this.defaultValue as StringValue - this.type = StringType(newSize, true) + this.type = StringType(newSize, false) if (initializationValue.value.length >= newSize) { initializationValue.value = initializationValue.value.substring(0, newSize) defaultValue.value = defaultValue.value.substring(0, newSize) From c21083b5dbe8373dc16c3fd7c347c3d037f1dc3f Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Mon, 25 Mar 2024 17:45:17 +0100 Subject: [PATCH 413/423] Add executeERROR13ShouldNotThrowStackOverflowError test --- .../interpreter/JarikoCallbackTest.kt | 14 ++++++++- .../src/test/resources/ERROR13.rpgle | 30 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt index 7b0894df6..054f1c44a 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt @@ -25,6 +25,7 @@ import com.smeup.rpgparser.parsing.facade.SourceReference import com.smeup.rpgparser.parsing.facade.SourceReferenceType import org.junit.Assert import java.io.StringReader +import kotlin.test.DefaultAsserter.assertTrue import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotNull @@ -412,6 +413,16 @@ class JarikoCallbackTest : AbstractTest() { executePgmCallBackTest("ERROR12", SourceReferenceType.Program, "ERROR12", listOf(7)) } + @Test + fun executeERROR13ShouldNotThrowStackOverflowError() { + executeSourceLineTest(pgm = "ERROR13", throwableConsumer = { + assertTrue( + message = "java.lang.StackOverflowError should not be present", + actual = it.message!!.indexOf("java.lang.StackOverflowError") == -1 + ) + }) + } + /** * This test simulates what a precompiler might do throws the use of the beforeParsing callback * In ERROR01.rpgle I will comment C specification to avoid a division by zero errors @@ -517,7 +528,7 @@ class JarikoCallbackTest : AbstractTest() { * Verify that the sourceLine is properly set in case of error. * ErrorEvent must contain a reference of an absolute line of the source code * */ - private fun executeSourceLineTest(pgm: String) { + private fun executeSourceLineTest(pgm: String, throwableConsumer: (Throwable) -> Unit = {}) { lateinit var lines: List val errorEvents = mutableListOf() val configuration = Configuration().apply { @@ -535,6 +546,7 @@ class JarikoCallbackTest : AbstractTest() { }.onSuccess { Assert.fail("$pgm must exit with error") }.onFailure { + throwableConsumer(it) errorEvents.forEach { Assert.assertEquals(lines[it.absoluteLine!! - 1], it.fragment) } diff --git a/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle b/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle new file mode 100644 index 000000000..66df6f9e1 --- /dev/null +++ b/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle @@ -0,0 +1,30 @@ + V* ============================================================== + D* Stackoverflowexception evaluation + D* + V* ============================================================== + FC5RREG0L IP E DISK + FC5RATE1L UF E K DISK + *--------------------------------------------------------------* + L >D £U13MB S 10 INZ('C5UTX02 ') + L >D £U13FI S 10 INZ('C5SRC ') +1 C IF R5CAUS='206' + C MOVE R5RIGA XXRIGA 5 + C MOVEL(P) 'E5' KTPOR + C EVAL KCDOR=R5PROG+XXRIGA + C KEYRAT SETLL C5RATER + * +2 C DO *HIVAL + C KEYRAT READE C5RATER 51 + C 51 LEAVE + C MOVEL(P) 'I' S5FL19 + C UPDATE C5RATER +2e C ENDDO + * +1e C ENDIF + * + C KEYRAT KLIST + C KFLD KTPOR + C KFLD KCDOR + * + C *LIKE DEFINE S5TPOR KTPOR + C *LIKE DEFINE S5CDOR KCDOR \ No newline at end of file From c83851e06ca68c0e962cb9dca18afda403c31438 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 27 Mar 2024 11:05:54 +0100 Subject: [PATCH 414/423] Better error isolation --- .../interpreter/JarikoCallbackTest.kt | 1 + .../src/test/resources/ERROR13.rpgle | 33 +++++-------------- 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt index 054f1c44a..2316e42e6 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt @@ -416,6 +416,7 @@ class JarikoCallbackTest : AbstractTest() { @Test fun executeERROR13ShouldNotThrowStackOverflowError() { executeSourceLineTest(pgm = "ERROR13", throwableConsumer = { + it.printStackTrace() assertTrue( message = "java.lang.StackOverflowError should not be present", actual = it.message!!.indexOf("java.lang.StackOverflowError") == -1 diff --git a/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle b/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle index 66df6f9e1..1720adf8b 100644 --- a/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle @@ -1,30 +1,13 @@ V* ============================================================== D* Stackoverflowexception evaluation D* - V* ============================================================== - FC5RREG0L IP E DISK - FC5RATE1L UF E K DISK - *--------------------------------------------------------------* - L >D £U13MB S 10 INZ('C5UTX02 ') - L >D £U13FI S 10 INZ('C5SRC ') -1 C IF R5CAUS='206' - C MOVE R5RIGA XXRIGA 5 - C MOVEL(P) 'E5' KTPOR - C EVAL KCDOR=R5PROG+XXRIGA - C KEYRAT SETLL C5RATER - * -2 C DO *HIVAL - C KEYRAT READE C5RATER 51 - C 51 LEAVE - C MOVEL(P) 'I' S5FL19 - C UPDATE C5RATER -2e C ENDDO - * -1e C ENDIF - * - C KEYRAT KLIST - C KFLD KTPOR - C KFLD KCDOR + V* ============================================================== * + * The stackoverflowexception is thrown when I have more than 1 + * DEFINE statement related to not found D specs. + * In this case KTPOR and KCDOR are not found. C *LIKE DEFINE S5TPOR KTPOR - C *LIKE DEFINE S5CDOR KCDOR \ No newline at end of file + C *LIKE DEFINE S5CDOR KCDOR + + C 'HI' DSPLY + \ No newline at end of file From 3d049a7f33d515bd74dfd00586616cc91d3f418a Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 27 Mar 2024 11:47:21 +0100 Subject: [PATCH 415/423] Fix error comment --- rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle b/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle index 1720adf8b..146695b90 100644 --- a/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle +++ b/rpgJavaInterpreter-core/src/test/resources/ERROR13.rpgle @@ -5,7 +5,7 @@ * * The stackoverflowexception is thrown when I have more than 1 * DEFINE statement related to not found D specs. - * In this case KTPOR and KCDOR are not found. + * In this case S5TPOR and S5CDOR are not found as D specs. C *LIKE DEFINE S5TPOR KTPOR C *LIKE DEFINE S5CDOR KCDOR From 1c465b12ca7b4ab1a2a615b075c2e0bb8b0f339c Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 27 Mar 2024 12:05:56 +0100 Subject: [PATCH 416/423] Fix stackoverflow --- .../kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 82d4041c3..707c44922 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1126,11 +1126,15 @@ data class DefineStmt( val inStatementDataDefinition = containingCU.main.stmts .filterIsInstance() - .filter { it != this } + // Since that DefineStmt is a particular case of DefineDataStmt, we need to filter it out + // in order to avoid stack overflow + // The previous filter "it != this" went wrong if we had more than one DefineStmt + // with originalName not resolved + .filter { it !is DefineStmt } .asSequence() .map(StatementThatCanDefineData::dataDefinition) .flatten() - .find { it.name == originalName } ?: return emptyList() + .find { it.name.uppercase() == originalName.uppercase() } ?: throw this.error("Data reference $originalName not found") return listOf(InStatementDataDefinition(newVarName, inStatementDataDefinition.type, position)) } From 3e84ad34c6f8c0cfa2ef15ba736cf0ef2da1b18c Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 27 Mar 2024 12:45:31 +0100 Subject: [PATCH 417/423] Add test to evaluate the quality of raised error --- .../com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt index 2316e42e6..201fc9b9c 100644 --- a/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt +++ b/rpgJavaInterpreter-core/src/test/kotlin/com/smeup/rpgparser/interpreter/JarikoCallbackTest.kt @@ -424,6 +424,11 @@ class JarikoCallbackTest : AbstractTest() { }) } + @Test + fun executeERROR13CallBackTest() { + executePgmCallBackTest("ERROR13", SourceReferenceType.Program, "ERROR13", listOf(9, 10)) + } + /** * This test simulates what a precompiler might do throws the use of the beforeParsing callback * In ERROR01.rpgle I will comment C specification to avoid a division by zero errors From dd0fa6dd1824b7918aa11ee1d856c44a7187cb7a Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 27 Mar 2024 12:47:08 +0100 Subject: [PATCH 418/423] Improve CompilationUnit.findInStatementDataDefinitions in order to nake not blocking the StatementThatCanDefineData.dataDefinition invocation errors --- .../parsing/parsetreetoast/resolution.kt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt index bd240e581..af34e5513 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/parsetreetoast/resolution.kt @@ -31,9 +31,19 @@ import com.strumenta.kolasu.validation.ErrorType import java.util.* private fun CompilationUnit.findInStatementDataDefinitions() { - this.allStatements(preserveCompositeStatement = true).filterIsInstance(StatementThatCanDefineData::class.java).forEach { - this.addInStatementDataDefinitions(it.dataDefinition()) - } + this.allStatements(preserveCompositeStatement = true) + .filterIsInstance() + .forEach { statementThatCanDefineData -> + kotlin.runCatching { + this.addInStatementDataDefinitions(statementThatCanDefineData.dataDefinition()) + }.onFailure { error -> + if (statementThatCanDefineData is Node) { + kotlin.runCatching { + statementThatCanDefineData.error("Error while creating data definition from statement: $statementThatCanDefineData", error) + } + } else throw error + } + } } private fun MutableList.addAllDistinct(list: List): List { From 5c0be191da75f8ebd29212bdbecbc52b1d1034cb Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 27 Mar 2024 12:48:05 +0100 Subject: [PATCH 419/423] Refactor DefineStmt.dataDefinition() in order to remove duplicated error notifications --- .../main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 707c44922..277b9e792 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1134,8 +1134,7 @@ data class DefineStmt( .asSequence() .map(StatementThatCanDefineData::dataDefinition) .flatten() - .find { it.name.uppercase() == originalName.uppercase() } ?: throw this.error("Data reference $originalName not found") - + .find { it.name.uppercase() == originalName.uppercase() } ?: throw Error("Data reference $originalName not found") return listOf(InStatementDataDefinition(newVarName, inStatementDataDefinition.type, position)) } } From 9b62a4a9d14d1441c11d93903662515f89ffa7e9 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 27 Mar 2024 17:20:03 +0100 Subject: [PATCH 420/423] Fix regression of executeDEFINE02_defineOfVarCreatedByAnotherDefine --- .../smeup/rpgparser/parsing/ast/statements.kt | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 277b9e792..4432f4fda 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1105,9 +1105,18 @@ data class DefineStmt( val newVarName: String, override val position: Position? = null ) : Statement(position), StatementThatCanDefineData { + + @Transient + private var inStatementDataDefinitions: List? = null + override fun dataDefinition(): List { + if (inStatementDataDefinitions != null) { + return inStatementDataDefinitions!! + } val containingCU = this.ancestor(CompilationUnit::class.java) - ?: return emptyList() + ?: return emptyList().apply { + inStatementDataDefinitions = this + } val originalDataDefinition = containingCU.dataDefinitions.find { it.name == originalName } // If definition was not found as a 'standalone' 'D spec' declaration, @@ -1115,27 +1124,30 @@ data class DefineStmt( containingCU.dataDefinitions.forEach { it.fields.forEach { if (it.name == originalName) { - return listOf(InStatementDataDefinition(newVarName, it.type, position)) + return listOf(InStatementDataDefinition(newVarName, it.type, position)).apply { inStatementDataDefinitions = this } } } } if (originalDataDefinition != null) { - return listOf(InStatementDataDefinition(newVarName, originalDataDefinition.type, position)) + return listOf(InStatementDataDefinition(newVarName, originalDataDefinition.type, position)).apply { inStatementDataDefinitions = this } } else { val inStatementDataDefinition = containingCU.main.stmts .filterIsInstance() - // Since that DefineStmt is a particular case of DefineDataStmt, we need to filter it out - // in order to avoid stack overflow - // The previous filter "it != this" went wrong if we had more than one DefineStmt - // with originalName not resolved - .filter { it !is DefineStmt } .asSequence() - .map(StatementThatCanDefineData::dataDefinition) + .filter { this != it } + .map { + if (it is DefineStmt) { + if (!addDefineStmtCaller(it)) { + throw Error("Data reference $originalName not resolved") + } + } + it.dataDefinition() + } .flatten() - .find { it.name.uppercase() == originalName.uppercase() } ?: throw Error("Data reference $originalName not found") - return listOf(InStatementDataDefinition(newVarName, inStatementDataDefinition.type, position)) + .find { it.name.uppercase() == originalName.uppercase() } ?: throw Error("Data reference $originalName not resolved") + return listOf(InStatementDataDefinition(newVarName, inStatementDataDefinition.type, position)).apply { inStatementDataDefinitions = this } } } @@ -1144,6 +1156,13 @@ data class DefineStmt( } } +private fun addDefineStmtCaller(defineStmt: DefineStmt): Boolean { + val defineStmtCallers = MainExecutionContext.getAttributes().computeIfAbsent("DefineStmt.defineStmtCallers") { + mutableSetOf() + } as MutableSet + return defineStmtCallers.add(defineStmt) +} + interface WithRightIndicators { fun allPresent(): Boolean = hi != null && lo != null && eq != null From 4e0e8125fbba52f7d0bf40c250c71f04534541a3 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Wed, 27 Mar 2024 17:53:13 +0100 Subject: [PATCH 421/423] Refactor the logic needed to avoid infinite recursions --- .../smeup/rpgparser/parsing/ast/statements.kt | 45 +++++++++---------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index 4432f4fda..c73ede54c 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1105,18 +1105,9 @@ data class DefineStmt( val newVarName: String, override val position: Position? = null ) : Statement(position), StatementThatCanDefineData { - - @Transient - private var inStatementDataDefinitions: List? = null - override fun dataDefinition(): List { - if (inStatementDataDefinitions != null) { - return inStatementDataDefinitions!! - } val containingCU = this.ancestor(CompilationUnit::class.java) - ?: return emptyList().apply { - inStatementDataDefinitions = this - } + ?: return emptyList() val originalDataDefinition = containingCU.dataDefinitions.find { it.name == originalName } // If definition was not found as a 'standalone' 'D spec' declaration, @@ -1124,30 +1115,29 @@ data class DefineStmt( containingCU.dataDefinitions.forEach { it.fields.forEach { if (it.name == originalName) { - return listOf(InStatementDataDefinition(newVarName, it.type, position)).apply { inStatementDataDefinitions = this } + return listOf(InStatementDataDefinition(newVarName, it.type, position)) } } } if (originalDataDefinition != null) { - return listOf(InStatementDataDefinition(newVarName, originalDataDefinition.type, position)).apply { inStatementDataDefinitions = this } + return listOf(InStatementDataDefinition(newVarName, originalDataDefinition.type, position)) } else { + if (!this.resolvingFromStatementsCanDefineData()) { + // if this function returns false means a recursion happened + throw Error("Data reference $originalName not resolved") + } val inStatementDataDefinition = containingCU.main.stmts .filterIsInstance() + .filter { it != this } .asSequence() .filter { this != it } - .map { - if (it is DefineStmt) { - if (!addDefineStmtCaller(it)) { - throw Error("Data reference $originalName not resolved") - } - } - it.dataDefinition() - } + .map(StatementThatCanDefineData::dataDefinition) .flatten() .find { it.name.uppercase() == originalName.uppercase() } ?: throw Error("Data reference $originalName not resolved") - return listOf(InStatementDataDefinition(newVarName, inStatementDataDefinition.type, position)).apply { inStatementDataDefinitions = this } + this.resolved() + return listOf(InStatementDataDefinition(newVarName, inStatementDataDefinition.type, position)) } } @@ -1156,11 +1146,18 @@ data class DefineStmt( } } -private fun addDefineStmtCaller(defineStmt: DefineStmt): Boolean { - val defineStmtCallers = MainExecutionContext.getAttributes().computeIfAbsent("DefineStmt.defineStmtCallers") { +private fun DefineStmt.resolvingFromStatementsCanDefineData(): Boolean { + val stack = MainExecutionContext.getAttributes().computeIfAbsent("DefineStmt.resolvingFromStatementsCanDefineData") { + mutableSetOf() + } as MutableSet + return stack.add(this) +} + +private fun DefineStmt.resolved(): Boolean { + val stack = MainExecutionContext.getAttributes().computeIfAbsent("DefineStmt.resolvingFromStatementsCanDefineData") { mutableSetOf() } as MutableSet - return defineStmtCallers.add(defineStmt) + return stack.remove(this) } interface WithRightIndicators { From 2204620d65c11a507a43320bc88d69e51606d48f Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 28 Mar 2024 09:59:23 +0100 Subject: [PATCH 422/423] Minor refactor to improve the readability --- .../smeup/rpgparser/parsing/ast/statements.kt | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt index c73ede54c..3f9a95a1e 100644 --- a/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt +++ b/rpgJavaInterpreter-core/src/main/kotlin/com/smeup/rpgparser/parsing/ast/statements.kt @@ -1123,8 +1123,8 @@ data class DefineStmt( if (originalDataDefinition != null) { return listOf(InStatementDataDefinition(newVarName, originalDataDefinition.type, position)) } else { - if (!this.resolvingFromStatementsCanDefineData()) { - // if this function returns false means a recursion happened + if (!this.enterInStack()) { + // This check is necessary to avoid infinite recursion throw Error("Data reference $originalName not resolved") } val inStatementDataDefinition = @@ -1132,11 +1132,10 @@ data class DefineStmt( .filterIsInstance() .filter { it != this } .asSequence() - .filter { this != it } .map(StatementThatCanDefineData::dataDefinition) .flatten() - .find { it.name.uppercase() == originalName.uppercase() } ?: throw Error("Data reference $originalName not resolved") - this.resolved() + .find { it.name == originalName } ?: throw Error("Data reference $originalName not resolved") + this.exitFromStack() return listOf(InStatementDataDefinition(newVarName, inStatementDataDefinition.type, position)) } } @@ -1146,15 +1145,22 @@ data class DefineStmt( } } -private fun DefineStmt.resolvingFromStatementsCanDefineData(): Boolean { - val stack = MainExecutionContext.getAttributes().computeIfAbsent("DefineStmt.resolvingFromStatementsCanDefineData") { +/** + * Receiver wants to enter in call stack + * @return false if the receiver cannot enter + */ +private fun DefineStmt.enterInStack(): Boolean { + val stack = MainExecutionContext.getAttributes().computeIfAbsent("DefineStmt.callStack") { mutableSetOf() } as MutableSet return stack.add(this) } -private fun DefineStmt.resolved(): Boolean { - val stack = MainExecutionContext.getAttributes().computeIfAbsent("DefineStmt.resolvingFromStatementsCanDefineData") { +/** + * Receiver will exit from call stack + * */ +private fun DefineStmt.exitFromStack(): Boolean { + val stack = MainExecutionContext.getAttributes().computeIfAbsent("DefineStmt.callStack") { mutableSetOf() } as MutableSet return stack.remove(this) From b9a2c1cc07c83342a2e38930c88bf6dd970a72d0 Mon Sep 17 00:00:00 2001 From: lanarimarco Date: Thu, 28 Mar 2024 14:55:31 +0100 Subject: [PATCH 423/423] Bump v1.4.0 --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index da46df8d7..2e44a3f20 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,6 +19,6 @@ FlightRecorderOptions=stackdepth=64 kotlinVersion=1.8.20 serializationVersion=1.5.0 jvmVersion=11 -reloadVersion=develop-SNAPSHOT +reloadVersion=v1.3.2 jarikoGroupId=io.github.smeup.jariko -jarikoVersion=develop-SNAPSHOT +jarikoVersion=v1.4.0