@@ -15,6 +15,12 @@ object ExprEvaluate {
1515
1616 def evalBinary (binary : expr.BinaryExpr , lhs : ExprValue , rhs : ExprValue ): ExprValue = {
1717 import expr .BinaryExpr .Op
18+
19+ ErrorValue .aggregate(Seq (lhs, rhs)) match {
20+ case Some (errorValue) => return errorValue // errors propagation takes priority
21+ case None => () // continue with normal evaluation
22+ }
23+
1824 binary.op match {
1925 // Note promotion rules: range takes precedence, then float, then int
2026 case Op .ADD => (lhs, rhs) match {
@@ -223,6 +229,12 @@ object ExprEvaluate {
223229
224230 def evalBinarySet (binarySet : expr.BinarySetExpr , lhs : ExprValue , rhs : ExprValue ): ExprValue = {
225231 import expr .BinarySetExpr .Op
232+
233+ ErrorValue .aggregate(Seq (lhs, rhs)) match {
234+ case Some (errorValue) => return errorValue // errors propagation takes priority
235+ case None => () // continue with normal evaluation
236+ }
237+
226238 binarySet.op match {
227239 // Note promotion rules: range takes precedence, then float, then int
228240 // TODO: can we deduplicate these cases to delegate them to evalBinary?
@@ -272,6 +284,12 @@ object ExprEvaluate {
272284
273285 def evalUnary (unary : expr.UnaryExpr , `val` : ExprValue ): ExprValue = {
274286 import expr .UnaryExpr .Op
287+
288+ ErrorValue .aggregate(Seq (`val`)) match {
289+ case Some (errorValue) => return errorValue // errors propagation takes priority
290+ case None => () // continue with normal evaluation
291+ }
292+
275293 (unary.op, `val`) match {
276294 case (Op .NEGATE , `val`) => `val` match {
277295 case RangeValue (valMin, valMax) =>
@@ -307,6 +325,13 @@ object ExprEvaluate {
307325
308326 def evalUnarySet (unarySet : expr.UnarySetExpr , vals : ExprValue , emptyValue : ExprValue ): ExprValue = {
309327 import expr .UnarySetExpr .Op
328+
329+ // note this does not short circuit out emptyValue if vals is not empty
330+ ErrorValue .aggregate(Seq (vals, emptyValue)) match {
331+ case Some (errorValue) => return errorValue // errors propagation takes priority
332+ case None => () // continue with normal evaluation
333+ }
334+
310335 (unarySet.op, vals) match {
311336 case (_, ArrayValue .Empty (_)) => emptyValue
312337 // In this case we don't do numeric promotion
@@ -402,29 +427,42 @@ object ExprEvaluate {
402427
403428 def evalStruct (struct : expr.StructExpr , vals : Map [String , ExprValue ]): ExprValue = ???
404429
405- def evalRange (range : expr.RangeExpr , minimum : ExprValue , maximum : ExprValue ): ExprValue = (minimum, maximum) match {
406- case (FloatPromotable (lhs), FloatPromotable (rhs)) => if (lhs <= rhs) {
407- RangeValue (lhs, rhs)
408- } else {
409- ErrorValue (Some (s " range( $minimum, $maximum) is malformed, $minimum > $maximum" ))
410- }
411- case _ => throw new ExprEvaluateException (s " Unknown range operands types $minimum $maximum from $range" )
430+ def evalRange (range : expr.RangeExpr , minimum : ExprValue , maximum : ExprValue ): ExprValue = {
431+ ErrorValue .aggregate(Seq (minimum, maximum)) match {
432+ case Some (errorValue) => return errorValue // errors propagation takes priority
433+ case None => () // continue with normal evaluation
434+ }
435+
436+ (minimum, maximum) match {
437+ case (FloatPromotable (lhs), FloatPromotable (rhs)) => if (lhs <= rhs) {
438+ RangeValue (lhs, rhs)
439+ } else {
440+ ErrorValue (Some (s " range( $minimum, $maximum) is malformed, $minimum > $maximum" ))
441+ }
442+ case _ => throw new ExprEvaluateException (s " Unknown range operands types $minimum $maximum from $range" )
443+ }
412444 }
413445
414446 def evalIfThenElse (ite : expr.IfThenElseExpr , cond : ExprValue , tru : ExprValue , fal : ExprValue ): ExprValue =
415447 cond match {
448+ case ErrorValue (_) => cond
416449 case BooleanValue (true ) => tru
417450 case BooleanValue (false ) => fal
418451 case _ => throw new ExprEvaluateException (s " Unknown condition types if $cond then $tru else $fal from $ite" )
419452 }
420453
421- def evalExtract (extract : expr.ExtractExpr , container : ExprValue , index : ExprValue ): ExprValue =
454+ def evalExtract (extract : expr.ExtractExpr , container : ExprValue , index : ExprValue ): ExprValue = {
455+ ErrorValue .aggregate(Seq (container, index)) match {
456+ case Some (errorValue) => return errorValue // errors propagation takes priority
457+ case None => () // continue with normal evaluation
458+ }
422459 (container, index) match {
423460 case (ArrayValue (container), IntValue (index)) => container(index.toInt)
424461 case _ => throw new ExprEvaluateException (
425462 s " Unknown operand types for extract element $index from $container from $extract"
426463 )
427464 }
465+ }
428466}
429467
430468class ExprEvaluate (refs : ConstProp , root : DesignPath ) extends ValueExprMap [ExprValue ] {
0 commit comments