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

Feature/cod open close #389

Merged
merged 12 commits into from
Jan 8, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class DBFileMap {
* */
data class EnrichedDBFile(private val dbFile: DBFile, private val fileDefinition: FileDefinition, val jarikoMetadata: FileMetadata) : DBFile {

// All files are opened by default when defined in F specs.
var open = true

override var fileMetadata = dbFile.fileMetadata

override var name = dbFile.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,5 @@ interface Evaluator {
fun eval(expression: AssignmentExpr): Value
fun eval(expression: GlobalIndicatorExpr): Value
fun eval(expression: ParmsExpr): Value
fun eval(expression: OpenExpr): Value
}
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,16 @@ class ExpressionEvaluation(
return IntValue(interpreterStatus.params.toLong())
}

override fun eval(expression: OpenExpr): Value {
val name = expression.name
require(name != null) {
"Line ${expression.position?.line()} - %OPEN require a table name"
}
val enrichedDBFile = interpreterStatus.dbFileMap.get(name)
?: throw RuntimeException("Table $name cannot be found (${expression.position.line()})")
return BooleanValue(enrichedDBFile.open)
}

private fun cleanNumericString(s: String): String {
val result = s.moveEndingString("-")
return when {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ class InterpreterStatus(
val indicators: HashMap<IndicatorKey, BooleanValue>,
var returnValue: Value? = null,
var params: Int = 0,
var inzsrExecuted: Boolean = false
var inzsrExecuted: Boolean = false,
var dbFileMap: DBFileMap
) {
var lastFound = false
var lastDBFile: DBFile? = null
Expand Down Expand Up @@ -110,13 +111,13 @@ open class InternalInterpreter(

fun logsEnabled() = logHandlers.isNotEmpty()

private val status = InterpreterStatus(globalSymbolTable, indicators)
private val dbFileMap = DBFileMap()

private val status = InterpreterStatus(globalSymbolTable, indicators, dbFileMap = dbFileMap)
override fun getStatus(): InterpreterStatus {
return status
}

private val dbFileMap = DBFileMap()

private val expressionEvaluation = ExpressionEvaluation(systemInterface, localizationContext, status)

override fun log(logEntry: () -> LogEntry) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,16 @@ data class ReplaceExpr(
override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this)
}

// %OPEN
@Serializable
data class OpenExpr(
var name: String? = null,
override val position: Position? = null
) :
Expression(position) {
override fun evalWith(evaluator: Evaluator): Value = evaluator.eval(this)
}

@Serializable
sealed class DurationCode
@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ private val modules = SerializersModule {
subclass(ChainStmt::class)
subclass(CheckStmt::class)
subclass(ClearStmt::class)
subclass(CloseStmt::class)
subclass(CompStmt::class)
subclass(DefineStmt::class)
subclass(DeleteStmt::class)
Expand All @@ -72,6 +73,7 @@ private val modules = SerializersModule {
subclass(MultStmt::class)
subclass(OtherStmt::class)
subclass(OccurStmt::class)
subclass(OpenStmt::class)
subclass(PlistStmt::class)
subclass(ReadEqualStmt::class)
subclass(ReadPreviousStmt::class)
Expand Down Expand Up @@ -135,6 +137,7 @@ private val modules = SerializersModule {
subclass(NumberOfElementsExpr::class)
subclass(OnRefExpr::class)
subclass(OffRefExpr::class)
subclass(OpenExpr::class)
subclass(PlusExpr::class)
subclass(GlobalIndicatorExpr::class)
subclass(IndicatorExpr::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import com.smeup.rpgparser.interpreter.*
import com.smeup.rpgparser.parsing.parsetreetoast.acceptBody
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.ComparisonOperator
import com.smeup.rpgparser.utils.resizeTo
import com.smeup.rpgparser.utils.substringOfLength
import com.strumenta.kolasu.model.*
Expand Down Expand Up @@ -1732,6 +1732,42 @@ fun OccurableDataStructValue.pos(occurrence: Int, interpreter: InterpreterCore,
}
}

@Serializable
data class OpenStmt(
@Transient open val name: String = "", // Factor 2
@Transient override val position: Position? = null,
val operationExtender: String?,
val errorIndicator: IndicatorKey?
) : Statement(position) {
init {
require(operationExtender == null) {
"Operation extender not supported"
}
}
override fun execute(interpreter: InterpreterCore) {
val dbFile = interpreter.dbFile(name, this)
dbFile.open = true
}
}
@Serializable
data class CloseStmt(
@Transient open val name: String = "", // Factor 2
@Transient override val position: Position? = null,
val operationExtender: String?,
val errorIndicator: IndicatorKey?
) : Statement(position) {

init {
require(operationExtender == null) {
"Operation extender not supported"
}
}
override fun execute(interpreter: InterpreterCore) {
val dbFile = interpreter.dbFile(name, this)
dbFile.open = false
}
}

/**
* XLATE operation Code: all characters in the source string (factor 2) are translated according
* to the From and To strings (both in factor 1) and put into a receiver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ internal fun RpgParser.BifContext.toAst(conf: ToAstConfiguration = ToAstConfigur
this.bif_replace() != null -> this.bif_replace().toAst(conf)
this.bif_sqrt() != null -> this.bif_sqrt().toAst(conf)
this.bif_parms() != null -> this.bif_parms().toAst(conf)
this.bif_open() != null -> this.bif_open().toAst(conf)
else -> todo(conf = conf)
}
}
Expand Down Expand Up @@ -235,3 +236,9 @@ internal fun RpgParser.Bif_parmsContext.toAst(conf: ToAstConfiguration = ToAstCo
this.text,
toPosition(conf.considerPosition))
}

internal fun RpgParser.Bif_openContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): OpenExpr {
return OpenExpr(
this.identifier().text,
toPosition(conf.considerPosition))
}
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,12 @@ internal fun Cspec_fixed_standardContext.toAst(conf: ToAstConfiguration = ToAstC
this.csOCCUR() != null -> this.csOCCUR()
.let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) }

this.csOPEN() != null -> this.csOPEN()
.let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) }

this.csCLOSE() != null -> this.csCLOSE()
.let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) }

this.csXLATE() != null -> this.csXLATE()
.let { it.cspec_fixed_standard_parts().validate(stmt = it.toAst(conf), conf = conf) }

Expand Down Expand Up @@ -1827,6 +1833,28 @@ internal fun CsXLATEContext.toAst(conf: ToAstConfiguration = ToAstConfiguration(
)
}

internal fun CsOPENContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement {
val position = toPosition(conf.considerPosition)
val factor2 = this.cspec_fixed_standard_parts().factor2.text ?: throw UnsupportedOperationException("READ operation requires factor 2: ${this.text} - ${position.atLine()}")
return OpenStmt(
name = factor2,
position = position,
operationExtender = this.operationExtender?.text,
errorIndicator = this.cspec_fixed_standard_parts().lo.asIndex()
)
}

internal fun CsCLOSEContext.toAst(conf: ToAstConfiguration = ToAstConfiguration()): Statement {
val position = toPosition(conf.considerPosition)
val factor2 = this.cspec_fixed_standard_parts().factor2.text ?: throw UnsupportedOperationException("READ operation requires factor 2: ${this.text} - ${position.atLine()}")
return CloseStmt(
name = factor2,
position = position,
operationExtender = this.operationExtender?.text,
errorIndicator = this.cspec_fixed_standard_parts().lo.asIndex()
)
}

/**
* Run a block. In case of error throws an error encapsulating useful information
* like node position
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2019 Sme.UP S.p.A.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.smeup.rpgparser.db

import com.smeup.rpgparser.AbstractTest
import org.junit.Test
import kotlin.test.assertEquals

open class OpenCloseTest : AbstractTest() {

@Test
fun testT53_A01() {
val outputLines = outputOfDBPgm(
"db/T53_A01",
listOf(createEmployeeMetadata()),
emptyList(),
emptyMap()
)
assertEquals(listOf("OPENED", "CLOSED", "OPENED"), outputLines)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.smeup.rpgparser.db

class OpenCloseTestCompiled() : OpenCloseTest() {
override fun useCompiledVersion() = true
}
28 changes: 28 additions & 0 deletions rpgJavaInterpreter-core/src/test/resources/db/T53_A01.rpgle
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FEMPLOYEE IF E K DISK UsrOpn
**************************************************************************
D £DBG_Str S 2560 Stringa
D £DBG_Pas S 10 Passo
**************************************************************************
D* All files are open by default even if the UsrOpn parm is not defined
C EVAL £DBG_Pas='P01'
C EVAL £DBG_Str='TEST_%OPEN:'
C IF %OPEN(EMPLOYEE)
C EVAL £DBG_Str='OPENED'
C ELSE
C EVAL £DBG_Str='CLOSED'
C ENDIF
C £DBG_Str DSPLY
*
C CLOSE EMPLOYEE
C IF NOT %OPEN(EMPLOYEE)
C EVAL £DBG_Str='CLOSED'
C £DBG_Str DSPLY
C ENDIF
*
C OPEN EMPLOYEE
C IF %OPEN(EMPLOYEE)
C EVAL £DBG_Str='OPENED'
C £DBG_Str DSPLY
C ENDIF
*
C SETON LR