@@ -59,7 +59,9 @@ object ExprEvaluate {
5959 val lower = contribMax * targetMin
6060 val upper = contribMin * targetMax
6161 if (lower > upper) {
62- ErrorValue (s " shrink_mult( $lhs, $rhs) produces empty range, target $lhs tighter tol than contrib $rhs" )
62+ ErrorValue (
63+ Some (s " shrink_mult( $lhs, $rhs) produces empty range, target $lhs tighter tol than contrib $rhs" )
64+ )
6365 } else {
6466 RangeValue (lower, upper)
6567 }
@@ -293,8 +295,8 @@ object ExprEvaluate {
293295 case (Op .MIN , RangeValue (valMin, _)) => FloatValue (valMin)
294296 case (Op .MAX , RangeValue (_, valMax)) => FloatValue (valMax)
295297
296- case (Op .MAX , RangeEmpty ) => ErrorValue (" max(RangeEmpty) is undefined" )
297- case (Op .MIN , RangeEmpty ) => ErrorValue (" min(RangeEmpty) is undefined" )
298+ case (Op .MAX , RangeEmpty ) => ErrorValue (Some ( " max(RangeEmpty) is undefined" ) )
299+ case (Op .MIN , RangeEmpty ) => ErrorValue (Some ( " min(RangeEmpty) is undefined" ) )
298300
299301 case (Op .CENTER , RangeValue (valMin, valMax)) => FloatValue ((valMin + valMax) / 2 )
300302 case (Op .WIDTH , RangeValue (valMin, valMax)) => FloatValue (math.abs(valMax - valMin))
@@ -303,25 +305,23 @@ object ExprEvaluate {
303305 }
304306 }
305307
306- def evalUnarySet (unarySet : expr.UnarySetExpr , vals : ExprValue ): ExprValue = {
308+ def evalUnarySet (unarySet : expr.UnarySetExpr , vals : ExprValue , emptyValue : ExprValue ): ExprValue = {
307309 import expr .UnarySetExpr .Op
308310 (unarySet.op, vals) match {
311+ case (_, ArrayValue .Empty (_)) => emptyValue
309312 // In this case we don't do numeric promotion
310- case (Op .SUM , ArrayValue .Empty (_)) => FloatValue (0 ) // TODO type needs to be dynamic
311313 case (Op .SUM , ArrayValue .ExtractFloat (vals)) => FloatValue (vals.sum)
312314 case (Op .SUM , ArrayValue .ExtractInt (vals)) => IntValue (vals.sum)
313315 case (Op .SUM , ArrayValue .ExtractBoolean (vals)) => IntValue (vals.count(_ == true ))
314316 case (Op .SUM , ArrayValue .UnpackRange (extracted)) => extracted match {
315317 case ArrayValue .UnpackRange .FullRange (valMins, valMaxs) => RangeValue (valMins.sum, valMaxs.sum)
316318 case ArrayValue .UnpackRange .RangeWithEmpty (_, _) => RangeEmpty
317319 case ArrayValue .UnpackRange .EmptyRange () => RangeEmpty
318- case ArrayValue .UnpackRange .EmptyArray () =>
319- RangeValue ( 0 , 0 ) // unreachable in practice, superseded by float 0 case
320+ case ArrayValue .UnpackRange .EmptyArray () => // empty array case handled above
321+ throw new AssertionError ( " compiler internal error, shouldn't happen " )
320322 }
321323
322- case (Op .ALL_TRUE , ArrayValue .Empty (_)) => BooleanValue (true )
323324 case (Op .ALL_TRUE , ArrayValue .ExtractBoolean (vals)) => BooleanValue (vals.forall(_ == true ))
324- case (Op .ANY_TRUE , ArrayValue .Empty (_)) => BooleanValue (false )
325325 case (Op .ANY_TRUE , ArrayValue .ExtractBoolean (vals)) => BooleanValue (vals.contains(true ))
326326
327327 // TODO better support for empty arrays?
@@ -335,11 +335,10 @@ object ExprEvaluate {
335335 case (Op .MINIMUM , ArrayValue .ExtractFloat (vals)) => FloatValue (vals.min)
336336 case (Op .MINIMUM , ArrayValue .ExtractInt (vals)) => IntValue (vals.min)
337337
338- case (Op .SET_EXTRACT , ArrayValue .Empty (_)) => ErrorValue (" set_extract(empty) is undefined" )
339338 case (Op .SET_EXTRACT , ArrayValue (vals)) => if (vals.forall(_ == vals.head)) {
340339 vals.head
341340 } else {
342- ErrorValue (f " set_extract( $vals) with non-equal values " )
341+ ErrorValue (Some ( f " set_extract( $vals) with non-equal values " ) )
343342 }
344343
345344 // Any empty value means the expression result is empty
@@ -349,21 +348,20 @@ object ExprEvaluate {
349348 if (maxMin <= minMax) {
350349 RangeValue (maxMin, minMax)
351350 } else { // does not intersect, null set
352- ErrorValue (f " intersection( $extracted) produces empty set " )
351+ ErrorValue (Some ( f " intersection( $extracted) produces empty set " ) )
353352 }
354353 case ArrayValue .UnpackRange .RangeWithEmpty (_, _) => RangeEmpty
355354 case ArrayValue .UnpackRange .EmptyRange () => RangeEmpty
356- // The implicit initial value of intersect is the full range
357- case ArrayValue .UnpackRange .EmptyArray () => RangeValue (Float .NegativeInfinity , Float .PositiveInfinity )
358- case _ => ErrorValue (f " intersection( $vals) is undefined " )
355+ case _ => ErrorValue (Some (f " intersection( $vals) is undefined " ))
359356 }
360357
361358 // Any value is used (empty effectively discarded)
362359 case (Op .HULL , ArrayValue .UnpackRange (extracted)) => extracted match {
363360 case ArrayValue .UnpackRange .FullRange (valMins, valMaxs) => RangeValue (valMins.min, valMaxs.max)
364361 case ArrayValue .UnpackRange .RangeWithEmpty (valMins, valMaxs) => RangeValue (valMins.min, valMaxs.max)
365362 case ArrayValue .UnpackRange .EmptyRange () => RangeEmpty
366- case ArrayValue .UnpackRange .EmptyArray () => RangeEmpty // TODO: should this be an error?
363+ case ArrayValue .UnpackRange .EmptyArray () => // empty array case handled above
364+ throw new AssertionError (" compiler internal error, shouldn't happen" )
367365 }
368366 case (Op .HULL , ArrayValue .ExtractFloat (vals)) => RangeValue (vals.min, vals.max)
369367
@@ -408,7 +406,7 @@ object ExprEvaluate {
408406 case (FloatPromotable (lhs), FloatPromotable (rhs)) => if (lhs <= rhs) {
409407 RangeValue (lhs, rhs)
410408 } else {
411- ErrorValue (s " range( $minimum, $maximum) is malformed, $minimum > $maximum" )
409+ ErrorValue (Some ( s " range( $minimum, $maximum) is malformed, $minimum > $maximum" ) )
412410 }
413411 case _ => throw new ExprEvaluateException (s " Unknown range operands types $minimum $maximum from $range" )
414412 }
@@ -442,8 +440,8 @@ class ExprEvaluate(refs: ConstProp, root: DesignPath) extends ValueExprMap[ExprV
442440 override def mapUnary (unary : expr.UnaryExpr , `val` : ExprValue ): ExprValue =
443441 ExprEvaluate .evalUnary(unary, `val`)
444442
445- override def mapUnarySet (unarySet : expr.UnarySetExpr , vals : ExprValue ): ExprValue =
446- ExprEvaluate .evalUnarySet(unarySet, vals)
443+ override def mapUnarySet (unarySet : expr.UnarySetExpr , vals : ExprValue , emptyValue : ExprValue ): ExprValue =
444+ ExprEvaluate .evalUnarySet(unarySet, vals, emptyValue )
447445
448446 override def mapArray (array : expr.ArrayExpr , vals : Seq [ExprValue ]): ExprValue =
449447 ExprEvaluate .evalArray(array, vals)
0 commit comments