tuxji commented on code in PR #1199:
URL: https://github.com/apache/daffodil/pull/1199#discussion_r1544570225


##########
daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dpath/DFDLFunctions.scala:
##########
@@ -39,6 +42,94 @@ case class DFDLCheckConstraints(recipe: CompiledDPath) 
extends RecipeOpWithSubRe
   }
 }
 
+case class DFDLCheckRangeInclusive(
+  dataRecipe: CompiledDPath,
+  minRecipe: CompiledDPath,
+  maxRecipe: CompiledDPath,
+) extends RecipeOpWithSubRecipes(dataRecipe, minRecipe, maxRecipe) {
+  override def run(dstate: DState): Unit = {
+    val saved = dstate.currentNode
+    dataRecipe.run(dstate)
+    val dataVal = dstate.currentValue
+    dstate.setCurrentNode(saved)
+    minRecipe.run(dstate)
+    val minVal = dstate.currentValue
+    dstate.setCurrentNode(saved)
+    maxRecipe.run(dstate)
+    val maxVal = dstate.currentValue
+
+    val res = executeCheck(
+      dataVal: DataValue.DataValuePrimitiveNullable,
+      minVal: DataValue.DataValuePrimitiveNullable,
+      maxVal: DataValue.DataValuePrimitiveNullable,
+    )
+    dstate.setCurrentValue(res)
+  }
+
+  def executeCheck(
+    dataVal: DataValue.DataValuePrimitiveNullable,
+    minVal: DataValue.DataValuePrimitiveNullable,
+    maxVal: DataValue.DataValuePrimitiveNullable,
+  ): Boolean = {
+    (dataVal.value, minVal.value, maxVal.value) match {
+      case (data: Integer, min: Integer, max: Integer) => data >= min && data 
<= max
+      case (data: java.lang.Double, min: java.lang.Double, max: 
java.lang.Double) =>
+        data >= min && data <= max
+      case (data: java.lang.Float, min: java.lang.Float, max: java.lang.Float) 
=>
+        data >= min && data <= max
+      case (data: java.math.BigDecimal, min: java.math.BigDecimal, max: 
java.math.BigDecimal) =>
+        data.compareTo(min) >= 0 && data.compareTo(max) <= 0
+      case (data: BigInteger, min: BigInteger, max: BigInteger) =>
+        data.compareTo(min) >= 0 && data.compareTo(max) <= 0
+      case (_, _, _) => false
+    }
+  }
+}
+
+case class DFDLCheckRangeExclusive(
+  dataRecipe: CompiledDPath,
+  minRecipe: CompiledDPath,
+  maxRecipe: CompiledDPath,
+) extends RecipeOpWithSubRecipes(dataRecipe, minRecipe, maxRecipe) {
+  override def run(dstate: DState): Unit = {
+    val saved = dstate.currentNode
+    dataRecipe.run(dstate)
+    val dataVal = dstate.currentValue
+    dstate.setCurrentNode(saved)
+    minRecipe.run(dstate)
+    val minVal = dstate.currentValue
+    dstate.setCurrentNode(saved)
+    maxRecipe.run(dstate)
+    val maxVal = dstate.currentValue

Review Comment:
   > Note that we don't have to restore currentNode after calling 
maxReipce.run() because we aren't personally calling anymore runs, so whatever 
currentNode ended up as doesn't matter to us. If some other expression was 
called that led to this run() being called, then they were responsible for 
saving and restoring currentNode if they needed it.
   
   Actually, why do `run` implementations even mutate expression state (current 
node, current value) inside `dstate` at all?  A more functional way would be to 
pass `dstate` or a smaller expression state contained by `dstate` to 
`run(exprState)` as a parameter and receive a new expression state (with the 
new current node and new current value) as a result value from the 
`run(exprState)` call.  Then these `dstate.setCurrentNode(saved)` calls would 
go away because dstate's expression state (current node, current value) never 
gets mutated even after it's passed to the `run` implementation.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to