3
3
package inox
4
4
package ast
5
5
6
+ import scala .collection .immutable
6
7
import scala .collection .immutable .BitSet
7
8
8
9
/** Expression definitions for Pure Scala.
@@ -229,6 +230,42 @@ trait Expressions { self: Trees =>
229
230
def getType (using Symbols ): Type = RealType ()
230
231
}
231
232
233
+ /** $encodingof a floating point literal */
234
+ sealed case class FPLiteral (exponent : Int , significand : Int , value : BitSet ) extends Literal [BitSet ] {
235
+ override def getType (using Symbols ) = FPType (exponent, significand)
236
+ def toBV : BVLiteral = BVLiteral (true , value, exponent + significand)
237
+ }
238
+
239
+ object FPLiteral {
240
+ def fromBV (exponent : Int , significand : Int , bv : BVLiteral ) = FPLiteral (exponent, significand, bv.value)
241
+ }
242
+
243
+ object Float32Literal {
244
+ def apply (value : Float ): FPLiteral = FPLiteral .fromBV(8 , 24 , Int32Literal (java.lang.Float .floatToIntBits(value)))
245
+
246
+ def unapply (e : Expr ): Option [Float ] = e match {
247
+ case f @ FPLiteral (8 , 24 , b) if b.maxOption.getOrElse(- 1 ) < 32 =>
248
+ f.toBV match {
249
+ case Int32Literal (i) => Some (java.lang.Float .intBitsToFloat(i))
250
+ case _ => None
251
+ }
252
+ case _ => None
253
+ }
254
+ }
255
+
256
+ object Float64Literal {
257
+ def apply (value : Double ): FPLiteral = FPLiteral .fromBV(11 , 53 , Int64Literal (java.lang.Double .doubleToLongBits(value)))
258
+
259
+ def unapply (e : Expr ): Option [Double ] = e match {
260
+ case f @ FPLiteral (11 , 53 , b) if b.maxOption.getOrElse(- 1 ) < 64 =>
261
+ f.toBV match {
262
+ case Int64Literal (i) => Some (java.lang.Double .longBitsToDouble(i))
263
+ case _ => None
264
+ }
265
+ case _ => None
266
+ }
267
+ }
268
+
232
269
/** $encodingof a boolean literal '''true''' or '''false''' */
233
270
sealed case class BooleanLiteral (value : Boolean ) extends Literal [Boolean ] {
234
271
def getType (using Symbols ): Type = BooleanType ()
@@ -397,25 +434,25 @@ trait Expressions { self: Trees =>
397
434
/** $encodingof `... + ...` */
398
435
sealed case class Plus (lhs : Expr , rhs : Expr ) extends Expr with CachingTyped {
399
436
override protected def computeType (using Symbols ): Type =
400
- getIntegerType(lhs, rhs) `orElse` getRealType(lhs, rhs) `orElse` getBVType(lhs, rhs)
437
+ getIntegerType(lhs, rhs) `orElse` getRealType(lhs, rhs) `orElse` getBVType(lhs, rhs) `orElse` getFPType(lhs, rhs)
401
438
}
402
439
403
440
/** $encodingof `... - ...` */
404
441
sealed case class Minus (lhs : Expr , rhs : Expr ) extends Expr with CachingTyped {
405
442
override protected def computeType (using Symbols ): Type =
406
- getIntegerType(lhs, rhs) `orElse` getRealType(lhs, rhs) `orElse` getBVType(lhs, rhs)
443
+ getIntegerType(lhs, rhs) `orElse` getRealType(lhs, rhs) `orElse` getBVType(lhs, rhs) `orElse` getFPType(lhs, rhs)
407
444
}
408
445
409
446
/** $encodingof `- ...` */
410
447
sealed case class UMinus (expr : Expr ) extends Expr with CachingTyped {
411
448
override protected def computeType (using Symbols ): Type =
412
- getIntegerType(expr) `orElse` getRealType(expr) `orElse` getBVType(expr)
449
+ getIntegerType(expr) `orElse` getRealType(expr) `orElse` getBVType(expr) `orElse` getFPType(expr)
413
450
}
414
451
415
452
/** $encodingof `... * ...` */
416
453
sealed case class Times (lhs : Expr , rhs : Expr ) extends Expr with CachingTyped {
417
454
override protected def computeType (using Symbols ): Type =
418
- getIntegerType(lhs, rhs) `orElse` getRealType(lhs, rhs) `orElse` getBVType(lhs, rhs)
455
+ getIntegerType(lhs, rhs) `orElse` getRealType(lhs, rhs) `orElse` getBVType(lhs, rhs) `orElse` getFPType(lhs, rhs)
419
456
}
420
457
421
458
/** $encodingof `... / ...`
@@ -431,7 +468,7 @@ trait Expressions { self: Trees =>
431
468
*/
432
469
sealed case class Division (lhs : Expr , rhs : Expr ) extends Expr with CachingTyped {
433
470
override protected def computeType (using Symbols ): Type =
434
- getIntegerType(lhs, rhs) `orElse` getRealType(lhs, rhs) `orElse` getBVType(lhs, rhs)
471
+ getIntegerType(lhs, rhs) `orElse` getRealType(lhs, rhs) `orElse` getBVType(lhs, rhs) `orElse` getFPType(lhs, rhs)
435
472
}
436
473
437
474
/** $encodingof `... % ...` (can return negative numbers)
@@ -440,7 +477,7 @@ trait Expressions { self: Trees =>
440
477
*/
441
478
sealed case class Remainder (lhs : Expr , rhs : Expr ) extends Expr with CachingTyped {
442
479
override protected def computeType (using Symbols ): Type =
443
- getIntegerType(lhs, rhs) `orElse` getBVType(lhs, rhs)
480
+ getIntegerType(lhs, rhs) `orElse` getBVType(lhs, rhs) `orElse` getFPType(lhs, rhs)
444
481
}
445
482
446
483
/** $encodingof `... mod ...` (cannot return negative numbers)
@@ -458,7 +495,8 @@ trait Expressions { self: Trees =>
458
495
getIntegerType(lhs, rhs).isTyped ||
459
496
getRealType(lhs, rhs).isTyped ||
460
497
getBVType(lhs, rhs).isTyped ||
461
- getCharType(lhs, rhs).isTyped
498
+ getCharType(lhs, rhs).isTyped ||
499
+ getFPType(lhs, rhs).isTyped
462
500
) BooleanType () else Untyped
463
501
}
464
502
@@ -468,7 +506,8 @@ trait Expressions { self: Trees =>
468
506
getIntegerType(lhs, rhs).isTyped ||
469
507
getRealType(lhs, rhs).isTyped ||
470
508
getBVType(lhs, rhs).isTyped ||
471
- getCharType(lhs, rhs).isTyped
509
+ getCharType(lhs, rhs).isTyped ||
510
+ getFPType(lhs, rhs).isTyped
472
511
) BooleanType () else Untyped
473
512
}
474
513
@@ -478,7 +517,8 @@ trait Expressions { self: Trees =>
478
517
getIntegerType(lhs, rhs).isTyped ||
479
518
getRealType(lhs, rhs).isTyped ||
480
519
getBVType(lhs, rhs).isTyped ||
481
- getCharType(lhs, rhs).isTyped
520
+ getCharType(lhs, rhs).isTyped ||
521
+ getFPType(lhs, rhs).isTyped
482
522
) BooleanType () else Untyped
483
523
}
484
524
@@ -488,7 +528,8 @@ trait Expressions { self: Trees =>
488
528
getIntegerType(lhs, rhs).isTyped ||
489
529
getRealType(lhs, rhs).isTyped ||
490
530
getBVType(lhs, rhs).isTyped ||
491
- getCharType(lhs, rhs).isTyped
531
+ getCharType(lhs, rhs).isTyped ||
532
+ getFPType(lhs, rhs).isTyped
492
533
) BooleanType () else Untyped
493
534
}
494
535
0 commit comments