Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/ls24003807/S to DS with positive number #600

Merged
merged 39 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b6708bc
Implemented `SMOVELDS01` as `MUDRNRAPU00108` which executes `MOVEL` w…
davidepalladino-apuliasoft Aug 26, 2024
c4771e1
Implemented `SMOVELDS04` as `MUDRNRAPU00109` which executes `EVAL` wi…
davidepalladino-apuliasoft Aug 26, 2024
6e99715
Implemented `SMOVELDS02` as `ERROR37` which executes `MOVEL` with cra…
davidepalladino-apuliasoft Aug 26, 2024
ae4b181
Removed `SETON`
davidepalladino-apuliasoft Aug 26, 2024
8fb1afd
Implemented `SMOVELDS05` as `ERROR38` which executes `MOVEL` with cra…
davidepalladino-apuliasoft Aug 26, 2024
7b4abe0
Implemented `SMOVELDS03` as `ERROR39` which executes `MOVEL` with cra…
davidepalladino-apuliasoft Aug 26, 2024
71382d6
Implemented `SMOVELDS06` as `ERROR40` which executes `EVAL` with cras…
davidepalladino-apuliasoft Aug 26, 2024
a700ef8
Typo
davidepalladino-apuliasoft Aug 26, 2024
e809dfd
Typo
davidepalladino-apuliasoft Aug 26, 2024
d7a6a7a
Added test execution for `MUDRNRAPU00108`
davidepalladino-apuliasoft Aug 26, 2024
b95df23
Fixed result of test
davidepalladino-apuliasoft Aug 26, 2024
d410cbc
Applied fix for `MOVEL`
davidepalladino-apuliasoft Aug 26, 2024
9821aa3
Added test execution for `MUDRNRAPU00109`
davidepalladino-apuliasoft Aug 26, 2024
aebdabd
Typo
davidepalladino-apuliasoft Aug 26, 2024
7b67ff4
Added `UnsupportedOperationException` instead `TODO`
davidepalladino-apuliasoft Aug 26, 2024
e4b2d2e
Applied refactoring
davidepalladino-apuliasoft Aug 27, 2024
952b1ff
Improved `ERROR27`
davidepalladino-apuliasoft Aug 27, 2024
ab1b436
Added test execution for `ERROR37`
davidepalladino-apuliasoft Aug 27, 2024
5deb123
Moved the logic of coercion from `movel` to `coercing`, to avoid code…
davidepalladino-apuliasoft Aug 27, 2024
dbb9207
Added test execution for `ERROR38`
davidepalladino-apuliasoft Aug 27, 2024
6b3e36e
Improved coercion and added commments
davidepalladino-apuliasoft Aug 27, 2024
1f9f345
Added test execution for `ERROR39`
davidepalladino-apuliasoft Aug 27, 2024
28b2210
Added test execution for `ERROR40`
davidepalladino-apuliasoft Aug 28, 2024
e206ab4
Typo
davidepalladino-apuliasoft Aug 28, 2024
b161c43
Refactored the logic of coercing for DS from `coercing` to right comp…
davidepalladino-apuliasoft Aug 29, 2024
8911457
Fixed results for `ERROR37`, `ERROR38`, `ERROR39` and `ERROR40`,
davidepalladino-apuliasoft Aug 29, 2024
a7574c0
Merge branch 'develop' into bugfix/LS24003807/s-to-ds
davidepalladino-apuliasoft Aug 29, 2024
2444004
Little refactoring
davidepalladino-apuliasoft Aug 29, 2024
1423479
Typo
davidepalladino-apuliasoft Aug 29, 2024
23475b4
Typo
davidepalladino-apuliasoft Aug 29, 2024
da6070a
Added test `ERROR41`
davidepalladino-apuliasoft Aug 29, 2024
8b7b834
Renamed some tests for next merge from develop
davidepalladino-apuliasoft Aug 29, 2024
64479a7
Merge branch 'develop' into bugfix/LS24003807/s-to-ds
davidepalladino-apuliasoft Aug 29, 2024
3067ff5
Typo
davidepalladino-apuliasoft Aug 30, 2024
dc84cfb
Typo
davidepalladino-apuliasoft Aug 30, 2024
fc0ab1f
Added line comment to RPG `ERRORxx` programs
davidepalladino-apuliasoft Aug 30, 2024
5e8036c
Updates Purpose for `ERRORxx` files
davidepalladino-apuliasoft Aug 30, 2024
84fd3b6
Fixed results
davidepalladino-apuliasoft Aug 30, 2024
dab20f1
Fixed result for `executePgmCallBackTest`
davidepalladino-apuliasoft Aug 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.smeup.rpgparser.interpreter

import com.smeup.rpgparser.parsing.parsetreetoast.RpgType
import com.smeup.rpgparser.parsing.parsetreetoast.isNumber
import com.smeup.rpgparser.utils.repeatWithMaxSize
import java.math.BigDecimal
import java.math.RoundingMode
Expand Down Expand Up @@ -133,6 +134,9 @@ private fun coerceString(value: StringValue, type: Type): Value {
DecimalValue(BigDecimal.ZERO)
}
}
type.rpgType == RpgType.PACKED.rpgType && value.value.isNumber() -> {
throw UnsupportedOperationException("Cannot coerce `${value.value}` to $type.")
}
else -> {
if (!value.isBlank()) {
val intValue = decodeFromDS(value.value.trim(), type.entireDigits, type.decimalDigits)
Expand All @@ -144,12 +148,18 @@ private fun coerceString(value: StringValue, type: Type): Value {
}
} else {
if (!value.isBlank()) {
if (type.rpgType == RpgType.ZONED.rpgType) {
val decimalValue = decodeFromZoned(value.value.trim(), type.entireDigits, type.decimalDigits)
DecimalValue(decimalValue)
} else {
val decimalValue = decodeFromDS(value.value.trim(), type.entireDigits, type.decimalDigits)
DecimalValue(decimalValue)
when {
type.rpgType == RpgType.ZONED.rpgType -> {
val decimalValue = decodeFromZoned(value.value.trim(), type.entireDigits, type.decimalDigits)
DecimalValue(decimalValue)
}
type.rpgType == RpgType.PACKED.rpgType && value.value.isNumber() -> {
throw UnsupportedOperationException("Cannot coerce `${value.value}` to $type.")
}
else -> {
val decimalValue = decodeFromDS(value.value.trim(), type.entireDigits, type.decimalDigits)
DecimalValue(decimalValue)
}
}
} else {
DecimalValue(BigDecimal.ZERO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ private fun valueToString(value: Value, type: Type): String {

is BooleanType -> return s

is DataStructureType -> return s

else -> throw UnsupportedOperationException("MOVE/MOVEL not supported for the type: $type")
}
}
Expand Down Expand Up @@ -256,6 +258,10 @@ private fun stringToValue(value: String, type: Type): Value {

is BooleanType -> return StringValue(value)

is DataStructureType -> {
return DataStructValue(value)
}

else -> throw UnsupportedOperationException("MOVE/MOVEL not supported for the type: $type")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1094,7 +1094,29 @@ data class DataStructValue(var value: String, private val optionalExternalLen: I
} else if (data.declaredArrayInLine != null) {
ProjectedArrayValue.forData(this, data)
} else {
coerce(this.getSubstring(data.startOffset, data.endOffset), data.type)
val substring = this.getSubstring(data.startOffset, data.endOffset)
if (data.type is NumberType && !checkNumberSyntax(substring.value, data.type)) {
throw UnsupportedOperationException("Cannot coerce sub-string `${substring.value}` to ${data.type}.")
}
coerce(substring, data.type)
}
}

/**
* On AS400 for DS there are some syntax rule for number. In example,
* ZONED number with at least space at the end is not allowed.
* This function provides to check if the number follow these requirements.
* @param value to check.
* @param type necessary for checking based of `RpgType`
* @return true if the `value` follows the syntax.
*/
fun checkNumberSyntax(
value: String,
type: NumberType
): Boolean {
return when {
type.rpgType == RpgType.ZONED.rpgType -> value.trimEnd().length == value.length
else -> true
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,8 @@ internal fun String.isDecimal() = this.toDoubleOrNull() != null

internal fun String.toDecimal() = this.toDouble()

internal fun String.isNumber() = this.isInt() || this.isDecimal()

internal fun ParserRuleContext.rContext(): RContext {
return if (this.parent == null) {
this as RContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,9 @@ abstract class AbstractTest {
Pair(it.value, it.contains(lines))
}
Assert.assertTrue(
"Errors doesn't correspond:\n" + found.joinToString(separator = "\n") { it.first },
"Errors don't correspond.\n" +
"Actual: ${found.joinToString(separator = "\n\\") { it.first }}\n" +
"Expected: ${lines.map { it.value }.joinToString(separator = "\n\\") { it } }\n",
found.size == found.filter { it.second }.size && found.size == lines.size
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,66 @@ class JarikoCallbackTest : AbstractTest() {
executeSourceLineTest(pgm = "ERROR38")
}

@Test
fun executeERROR39CallBackTest() {
executePgmCallBackTest("ERROR39", SourceReferenceType.Program, "ERROR39", mapOf(
24 to "Cannot coerce `00520` to NumberType(entireDigits=7, decimalDigits=2, rpgType=P)."
))
}

@Test
fun executeERROR39SourceLineTest() {
executeSourceLineTest("ERROR39")
}

@Test
fun executeERROR40CallBackTest() {
executePgmCallBackTest("ERROR40", SourceReferenceType.Program, "ERROR40", mapOf(
24 to "Cannot coerce `00520` to NumberType(entireDigits=7, decimalDigits=2, rpgType=P)."
))
}

@Test
fun executeERROR40SourceLineTest() {
executeSourceLineTest("ERROERROR40R41")
}

@Test
fun executeERROR41CallBackTest() {
executePgmCallBackTest("ERROR41", SourceReferenceType.Program, "ERROR41", mapOf(
24 to "Cannot coerce sub-string `0052 ` to NumberType(entireDigits=3, decimalDigits=2, rpgType=S)."
))
}

@Test
fun executeERROR41SourceLineTest() {
executeSourceLineTest("ERROR41")
}

@Test
fun executeERROR42CallBackTest() {
executePgmCallBackTest("ERROR42", SourceReferenceType.Program, "ERROR42", mapOf(
24 to "Cannot coerce sub-string `0052 ` to NumberType(entireDigits=3, decimalDigits=2, rpgType=S)."
))
}

@Test
fun executeERROR42SourceLineTest() {
executeSourceLineTest("ERROR42")
}

@Test
fun executeERROR43CallBackTest() {
executePgmCallBackTest("ERROR43", SourceReferenceType.Program, "ERROR43", mapOf(
23 to "Cannot coerce sub-string `0005 ` to NumberType(entireDigits=5, decimalDigits=0, rpgType=S)."
))
}

@Test
fun executeERROR43SourceLineTest() {
executeSourceLineTest("ERROR43")
}

@Test
fun bypassSyntaxErrorTest() {
val configuration = Configuration().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ open class MULANGT04EssentialsCodopAndBifTest : MULANGTTest() {
}

/**
*Assigns content of DS to a String not VARYING in EVAL
* Assigns content of DS to a String not VARYING in EVAL
* @see #LS24003679
*/
@Test
Expand All @@ -45,7 +45,7 @@ open class MULANGT04EssentialsCodopAndBifTest : MULANGTTest() {
}

/**
*Assigns content of DS to a String VARYING in EVAL
* Assigns content of DS to a String VARYING in EVAL
* @see #LS24003679
*/
@Test
Expand All @@ -55,7 +55,7 @@ open class MULANGT04EssentialsCodopAndBifTest : MULANGTTest() {
}

/**
*Assigns content of DS to a String not VARYING in EVAL where, size of DS is greater than String
* Assigns content of DS to a String not VARYING in EVAL where, size of DS is greater than String
* @see #LS24003755
*/
@Test
Expand All @@ -65,7 +65,7 @@ open class MULANGT04EssentialsCodopAndBifTest : MULANGTTest() {
}

/**
*Assigns content of DS to a String not VARYING in EVAL where, size of DS is greater than String
* Assigns content of DS to a String not VARYING in EVAL where, size of DS is greater than String
* @see #LS24003755
*/
@Test
Expand All @@ -74,6 +74,28 @@ open class MULANGT04EssentialsCodopAndBifTest : MULANGTTest() {
assertEquals(expected, "smeup/MUDRNRAPU00107".outputOf())
}

/**
* Assigns content of String to a DS with type check and coercion between substring and destination field.
* In this test is used `MOVEL`
* @see #LS24003807
*/
@Test
fun executeMUDRNRAPU00108() {
val expected = listOf("Lorem ipsum dolor si", "t amet, consectetuer", "5", "5.20", "Lorem ipsum dolor si", "t amet, consectetuer", "5", "5.20")
assertEquals(expected, "smeup/MUDRNRAPU00108".outputOf())
}

/**
* Assigns content of String to a DS with type check and coercion between substring and destination field.
* In this test is used `EVAL`
* @see #LS24003807
*/
@Test
fun executeMUDRNRAPU00109() {
val expected = listOf("Lorem ipsum dolor si", "t amet, consectetuer", "5", "5.20", "Lorem ipsum dolor si", "t amet, consectetuer", "5", "5.20")
assertEquals(expected, "smeup/MUDRNRAPU00109".outputOf())
}

/**
* %DIFF with several DurationCodes
* @see #LS24003282
Expand Down
26 changes: 26 additions & 0 deletions rpgJavaInterpreter-core/src/test/resources/ERROR39.rpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
V* ==============================================================
D* 26/08/24
D* Purpose: Must fire the following errors during execution of
D* `MOVEL` from `S` to `DS`.
D* line 24 - Wrong value.
V* ==============================================================
D A40_A50 S 50
D A40_DS1 DS
D A40_DS1_F1 1 20
D A40_DS1_F2 21 40
D A40_DS1_F3 41 45 0
D A40_DS1_F4 46 50P 2

D A40_DS2_F4_S S 20

C EVAL A40_A50 = 'Lorem ipsum dolor si'
C + 't amet, consectetuer'
C + '0000500520'

C MOVEL A40_A50 A40_DS1
C A40_DS1_F1 DSPLY
C A40_DS1_F2 DSPLY
C A40_DS1_F3 DSPLY
C EVAL A40_DS2_F4_S=%CHAR(A40_DS1_F4)
V* Cannot assign Zoned number as Packed
C A40_DS2_F4_S DSPLY
26 changes: 26 additions & 0 deletions rpgJavaInterpreter-core/src/test/resources/ERROR40.rpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
V* ==============================================================
D* 26/08/24
D* Purpose: Must fire the following errors during execution of
D* `EVAL` from `S` to `DS`.
D* line 24 - Wrong value.
V* ==============================================================
D A40_A50 S 50
D A40_DS1 DS
D A40_DS1_F1 1 20
D A40_DS1_F2 21 40
D A40_DS1_F3 41 45 0
D A40_DS1_F4 46 50P 2

D A40_DS2_F4_S S 20

C EVAL A40_A50 = 'Lorem ipsum dolor si'
C + 't amet, consectetuer'
C + '0000500520'

C EVAL A40_DS1=A40_A50
C A40_DS1_F1 DSPLY
C A40_DS1_F2 DSPLY
C A40_DS1_F3 DSPLY
C EVAL A40_DS2_F4_S=%CHAR(A40_DS1_F4)
V* Cannot assign Zoned number as Packed
C A40_DS2_F4_S DSPLY
26 changes: 26 additions & 0 deletions rpgJavaInterpreter-core/src/test/resources/ERROR41.rpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
V* ==============================================================
D* 26/08/24
D* Purpose: Must fire the following errors during execution of
D* `MOVEL` from `S` to `DS`.
D* line 24 - Wrong value.
V* ==============================================================
D A40_A50 S 50
D A40_DS1 DS
D A40_DS1_F1 1 20
D A40_DS1_F2 21 40
D A40_DS1_F3 41 45 0
D A40_DS1_F4 46 50S 2

D A40_DS2_F4_S S 20

C EVAL A40_A50 = 'Lorem ipsum dolor si'
C + 't amet, consectetuer'
C + ' 0050052 '

C MOVEL A40_A50 A40_DS1
C A40_DS1_F1 DSPLY
C A40_DS1_F2 DSPLY
C A40_DS1_F3 DSPLY
C EVAL A40_DS2_F4_S=%CHAR(A40_DS1_F4)
V* Is not possible to assign a number with at least one blank char at the end.
C A40_DS2_F4_S DSPLY
26 changes: 26 additions & 0 deletions rpgJavaInterpreter-core/src/test/resources/ERROR42.rpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
V* ==============================================================
D* 26/08/24
D* Purpose: Must fire the following errors during execution of
D* `EVAL` from `S` to `DS`.
D* line 24 - Wrong value.
V* ==============================================================
D A40_A50 S 50
D A40_DS1 DS
D A40_DS1_F1 1 20
D A40_DS1_F2 21 40
D A40_DS1_F3 41 45 0
D A40_DS1_F4 46 50S 2

D A40_DS2_F4_S S 20

C EVAL A40_A50 = 'Lorem ipsum dolor si'
C + 't amet, consectetuer'
C + ' 0050052 '

C EVAL A40_DS1=A40_A50
C A40_DS1_F1 DSPLY
C A40_DS1_F2 DSPLY
C A40_DS1_F3 DSPLY
C EVAL A40_DS2_F4_S=%CHAR(A40_DS1_F4)
V* Is not possible to assign a number with at least one blank char at the end.
C A40_DS2_F4_S DSPLY
26 changes: 26 additions & 0 deletions rpgJavaInterpreter-core/src/test/resources/ERROR43.rpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
V* ==============================================================
D* 26/08/24
D* Purpose: Must fire the following errors during execution of
D* `EVAL` from `S` to `DS`.
D* line 24 - Wrong value.
V* ==============================================================
D A40_A50 S 50
D A40_DS1 DS
D A40_DS1_F1 1 20
D A40_DS1_F2 21 40
D A40_DS1_F3 41 45 0
D A40_DS1_F4 46 50S 2

D A40_DS2_F4_S S 20

C EVAL A40_A50 = 'Lorem ipsum dolor si'
C + 't amet, consectetuer'
C + '0005 00520'

C EVAL A40_DS1=A40_A50
C A40_DS1_F1 DSPLY
C A40_DS1_F2 DSPLY
C A40_DS1_F3 DSPLY
V* Is not possible to assign a number with at least one blank char at the end.
C EVAL A40_DS2_F4_S=%CHAR(A40_DS1_F4)
C A40_DS2_F4_S DSPLY
Loading