@@ -285,13 +285,16 @@ def _from_lit(cls, pb: edgir.ValueLit) -> int:
285285
286286
287287FloatLit = Union [float , int ]
288- FloatLike = Union ['FloatExpr' , float ]
289- class FloatExpr (NumLikeExpr [float , FloatLike ]):
288+ FloatLike = Union ['FloatExpr' , float , int ]
289+ class FloatExpr (NumLikeExpr [float , Union [ FloatLike , IntExpr ] ]):
290290 @classmethod
291- def _to_expr_type (cls , input : FloatLike ) -> FloatExpr :
291+ def _to_expr_type (cls , input : Union [ FloatLike , IntExpr ] ) -> FloatExpr :
292292 if isinstance (input , FloatExpr ):
293293 assert input ._is_bound ()
294294 return input
295+ elif isinstance (input , IntExpr ):
296+ assert input ._is_bound () and input .binding is not None
297+ return FloatExpr ()._bind (input .binding )
295298 elif isinstance (input , int ) or isinstance (input , float ):
296299 return FloatExpr ()._bind (FloatLiteralBinding (input ))
297300 else :
@@ -316,7 +319,7 @@ def max(self, other: FloatLike) -> FloatExpr:
316319
317320
318321RangeLike = Union ['RangeExpr' , Range , Tuple [FloatLike , FloatLike ]]
319- class RangeExpr (NumLikeExpr [Range , Union [RangeLike , FloatLike ]]):
322+ class RangeExpr (NumLikeExpr [Range , Union [RangeLike , FloatLike , IntExpr ]]):
320323 # Some range literals for defaults
321324 POSITIVE : Range = Range .from_lower (0.0 )
322325 NEGATIVE : Range = Range .from_upper (0.0 )
@@ -326,11 +329,11 @@ class RangeExpr(NumLikeExpr[Range, Union[RangeLike, FloatLike]]):
326329 EMPTY = Range (float ('NaN' ), float ('NaN' )) # special marker to define an empty range, which is subset-eq of any range
327330
328331 @classmethod
329- def _to_expr_type (cls , input : Union [RangeLike , FloatLike ]) -> RangeExpr :
332+ def _to_expr_type (cls , input : Union [RangeLike , FloatLike , IntLike ]) -> RangeExpr :
330333 if isinstance (input , RangeExpr ):
331334 assert input ._is_bound ()
332335 return input
333- elif isinstance (input , (int , float , FloatExpr )):
336+ elif isinstance (input , (int , float , FloatExpr , IntExpr )):
334337 expr = FloatExpr ._to_expr_type (input )
335338 return RangeExpr ()._bind (RangeBuilderBinding (expr , expr ))
336339 elif isinstance (input , tuple ) and isinstance (input [0 ], (int , float )) and isinstance (input [1 ], (int , float )):
@@ -390,7 +393,7 @@ def within(self, item: RangeLike) -> BoolExpr:
390393 def contains (self , item : Union [RangeLike , FloatLike ]) -> BoolExpr :
391394 if isinstance (item , (RangeExpr , tuple , Range )):
392395 return RangeExpr ._to_expr_type (item ).within (self )
393- elif isinstance (item , (int , float , FloatExpr )):
396+ elif isinstance (item , (int , float , FloatExpr , IntExpr )):
394397 return self ._create_bool_op (FloatExpr ._to_expr_type (item ), self , OrdOp .within )
395398
396399 def intersect (self , other : Union [RangeLike , FloatLike ]) -> RangeExpr :
@@ -411,38 +414,38 @@ def center(self) -> FloatExpr:
411414 @classmethod
412415 def _create_range_float_binary_op (cls ,
413416 lhs : RangeExpr ,
414- rhs : Union [RangeExpr , FloatExpr ],
417+ rhs : Union [RangeExpr , IntExpr , FloatExpr ],
415418 op : Union [NumericOp ]) -> RangeExpr :
416419 """Creates a new expression that is the result of a binary operation on inputs"""
417420 if not isinstance (lhs , RangeExpr ):
418421 raise TypeError (f"range mul and div lhs must be range type, "
419422 f"got lhs={ lhs } of type { type (lhs )} and rhs={ rhs } of type { type (rhs )} " )
420423
421- if not isinstance (rhs , (RangeExpr , FloatExpr )):
422- raise TypeError (f"range mul and div rhs must be range or float type, "
424+ if not isinstance (rhs , (RangeExpr , FloatExpr , IntExpr )):
425+ raise TypeError (f"range mul and div rhs must be range or float or int type, "
423426 f"got lhs={ lhs } of type { type (lhs )} and rhs={ rhs } of type { type (rhs )} " )
424427
425428 assert lhs ._is_bound () and rhs ._is_bound ()
426429 return lhs ._new_bind (BinaryOpBinding (lhs , rhs , op ))
427430
428431 # special option to allow range * float
429- def __mul__ (self , rhs : Union [RangeLike , FloatLike ]) -> RangeExpr :
432+ def __mul__ (self , rhs : Union [RangeLike , FloatLike , IntLike ]) -> RangeExpr :
430433 if isinstance (rhs , (int , float )): # TODO clean up w/ literal to expr pass, then type based on that
431- rhs_cast : Union [FloatExpr , RangeExpr ] = FloatExpr ._to_expr_type (rhs )
432- elif not isinstance (rhs , FloatExpr ):
433- rhs_cast = self ._to_expr_type (rhs ) # type: ignore
434- else :
434+ rhs_cast : Union [FloatExpr , IntExpr , RangeExpr ] = FloatExpr ._to_expr_type (rhs )
435+ elif isinstance (rhs , (FloatExpr , IntExpr )):
435436 rhs_cast = rhs
437+ else :
438+ rhs_cast = self ._to_expr_type (rhs ) # type: ignore
436439 return self ._create_range_float_binary_op (self , rhs_cast , NumericOp .mul )
437440
438441 # special option to allow range / float
439- def __truediv__ (self , rhs : Union [RangeLike , FloatLike ]) -> RangeExpr :
442+ def __truediv__ (self , rhs : Union [RangeLike , FloatLike , IntLike ]) -> RangeExpr :
440443 if isinstance (rhs , (int , float )): # TODO clean up w/ literal to expr pass, then type based on that
441- rhs_cast : Union [FloatExpr , RangeExpr ] = FloatExpr ._to_expr_type (rhs )
442- elif not isinstance (rhs , FloatExpr ):
443- rhs_cast = self ._to_expr_type (rhs ) # type: ignore
444- else :
444+ rhs_cast : Union [FloatExpr , IntExpr , RangeExpr ] = FloatExpr ._to_expr_type (rhs )
445+ elif isinstance (rhs , (FloatExpr , IntExpr )):
445446 rhs_cast = rhs
447+ else :
448+ rhs_cast = self ._to_expr_type (rhs ) # type: ignore
446449 return self * rhs_cast .__mul_inv__ ()
447450
448451 def abs (self ) -> RangeExpr :
0 commit comments