scala.scalanative.nir.Vals.scala Maven / Gradle / Ivy
package scala.scalanative
package nir
import java.lang.Float.floatToRawIntBits
import java.lang.Double.doubleToRawLongBits
sealed abstract class Val {
final def ty: Type = this match {
case Val.Null => Type.Null
case Val.Zero(ty) => ty
case Val.True | Val.False => Type.Bool
case Val.Char(_) => Type.Char
case Val.Byte(_) => Type.Byte
case Val.Short(_) => Type.Short
case Val.Int(_) => Type.Int
case Val.Long(_) => Type.Long
case Val.Float(_) => Type.Float
case Val.Double(_) => Type.Double
case Val.StructValue(vals) => Type.StructValue(vals.map(_.ty))
case Val.ArrayValue(ty, vals) => Type.ArrayValue(ty, vals.length)
case v: Val.Chars => Type.ArrayValue(Type.Byte, v.byteCount)
case Val.Local(_, ty) => ty
case Val.Global(_, ty) => ty
case Val.Unit => Type.Unit
case Val.Const(_) => Type.Ptr
case Val.String(_) =>
Type.Ref(Rt.String.name, exact = true, nullable = false)
case Val.Virtual(_) => Type.Virtual
case Val.ClassOf(n) => Rt.Class
}
final def show: String = nir.Show(this)
final def isVirtual: Boolean =
this.isInstanceOf[Val.Virtual]
final def isCanonical: Boolean = this match {
case Val.True | Val.False =>
true
case _: Val.Char =>
true
case _: Val.Byte | _: Val.Short | _: Val.Int | _: Val.Long =>
true
case _: Val.Float | _: Val.Double =>
true
case _: Val.Global | Val.Null =>
true
case _ =>
false
}
final def isZero: Boolean = this match {
case Val.Zero(_) => true
case Val.False => true
case Val.Char('\u0000') => true
case Val.Byte(0) => true
case Val.Short(0) => true
case Val.Int(0) => true
case Val.Long(0L) => true
case Val.Float(0f) => true
case Val.Double(0d) => true
case Val.Null => true
case _ => false
}
final def isOne: Boolean = this match {
case Val.True => true
case Val.Char(c) if c.toInt == 1 => true
case Val.Byte(1) => true
case Val.Short(1) => true
case Val.Int(1) => true
case Val.Long(1L) => true
case Val.Float(1f) => true
case Val.Double(1d) => true
case _ => false
}
final def isMinusOne: Boolean = this match {
case Val.Byte(-1) => true
case Val.Short(-1) => true
case Val.Int(-1) => true
case Val.Long(-1L) => true
case Val.Float(-1f) => true
case Val.Double(-1d) => true
case _ => false
}
final def isSignedMinValue: Boolean = this match {
case Val.Byte(v) => v == Byte.MinValue
case Val.Short(v) => v == Short.MinValue
case Val.Int(v) => v == Int.MinValue
case Val.Long(v) => v == Long.MinValue
case _ => false
}
final def isSignedMaxValue: Boolean = this match {
case Val.Byte(v) => v == Byte.MaxValue
case Val.Short(v) => v == Short.MaxValue
case Val.Int(v) => v == Int.MaxValue
case Val.Long(v) => v == Long.MaxValue
case _ => false
}
final def isUnsignedMinValue: Boolean =
isZero
final def isUnsignedMaxValue: Boolean =
isMinusOne || (this match {
case Val.Char(c) => c == Char.MaxValue
case _ => false
})
final def canonicalize: Val = this match {
case Val.Zero(Type.Bool) =>
Val.False
case Val.Zero(Type.Char) =>
Val.Char('\u0000')
case Val.Zero(Type.Byte) =>
Val.Byte(0.toByte)
case Val.Zero(Type.Short) =>
Val.Short(0.toShort)
case Val.Zero(Type.Int) =>
Val.Int(0)
case Val.Zero(Type.Long) =>
Val.Long(0L)
case Val.Zero(Type.Float) =>
Val.Float(0f)
case Val.Zero(Type.Double) =>
Val.Double(0d)
case Val.Zero(Type.Ptr) | Val.Zero(_: Type.RefKind) =>
Val.Null
case _ =>
this
}
}
object Val {
// low-level
case object True extends Val
case object False extends Val
object Bool extends (Boolean => Val) {
def apply(value: Boolean): Val =
if (value) True else False
def unapply(value: Val): Option[Boolean] = value match {
case True => Some(true)
case False => Some(false)
case _ => scala.None
}
}
case object Null extends Val
final case class Zero(of: nir.Type) extends Val
final case class Char(value: scala.Char) extends Val
final case class Byte(value: scala.Byte) extends Val
final case class Short(value: scala.Short) extends Val
final case class Int(value: scala.Int) extends Val
final case class Long(value: scala.Long) extends Val
final case class Float(value: scala.Float) extends Val {
override def equals(that: Any): Boolean = that match {
case Float(thatValue) =>
val theseBits = floatToRawIntBits(value)
val thoseBits = floatToRawIntBits(thatValue)
theseBits == thoseBits
case _ => false
}
}
final case class Double(value: scala.Double) extends Val {
override def equals(that: Any): Boolean = that match {
case Double(thatValue) =>
val theseBits = doubleToRawLongBits(value)
val thoseBits = doubleToRawLongBits(thatValue)
theseBits == thoseBits
case _ => false
}
}
final case class StructValue(values: Seq[Val]) extends Val
final case class ArrayValue(elemty: nir.Type, values: Seq[Val]) extends Val
final case class Chars(value: Seq[scala.Byte]) extends Val {
lazy val byteCount: scala.Int = value.length + 1
lazy val bytes: Array[scala.Byte] = value.toArray
}
final case class Local(name: nir.Local, valty: nir.Type) extends Val
final case class Global(name: nir.Global, valty: nir.Type) extends Val
// high-level
case object Unit extends Val
final case class Const(value: Val) extends Val
final case class String(value: java.lang.String) extends Val
final case class Virtual(key: scala.Long) extends Val
final case class ClassOf(name: nir.Global) extends Val
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy