use std::fmt::Debug;
use super::op::Const;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)]
pub enum Type {
Top = 0,
Bool,
I8,
I16,
I32,
I64,
F32,
F64,
Void,
}
impl Type {
pub fn is_floating_point(self) -> bool {
self == Type::F32 || self == Type::F64
}
pub fn is_integer(self) -> bool {
self as u8 >= Type::I8 as u8 && (self as u8) <= Type::I64 as u8
}
pub fn mem_size(self) -> usize {
use Type::*;
match self {
Top | Void => unreachable!(),
Bool => 1,
I8 => 1,
I16 => 2,
I32 => 4,
I64 => 8,
F32 => 4,
F64 => 8,
}
}
}
pub trait AnyTy: Clone + Copy + Debug + Sized {
const TYPE: Type;
}
pub trait Ty: AnyTy {}
pub trait NumTy: Ty {
fn constant(v: Self) -> Const;
fn zero() -> Self;
}
pub trait IntTy: NumTy {}
#[derive(Debug, Clone, Copy, Hash)]
pub struct Top;
impl AnyTy for Top {
const TYPE: Type = Type::Top;
}
impl AnyTy for () {
const TYPE: Type = Type::Void;
}
impl AnyTy for bool {
const TYPE: Type = Type::Bool;
}
impl Ty for () {}
impl Ty for bool {}
impl NumTy for bool {
#[inline]
fn constant(v: Self) -> Const {
Const::Bool(v)
}
#[inline]
fn zero() -> Self {
false
}
}
impl IntTy for bool {}
impl AnyTy for i8 {
const TYPE: Type = Type::I8;
}
impl Ty for i8 {}
impl NumTy for i8 {
#[inline]
fn constant(v: Self) -> Const {
Const::I8(v)
}
#[inline]
fn zero() -> Self {
0
}
}
impl IntTy for i8 {}
impl AnyTy for i16 {
const TYPE: Type = Type::I16;
}
impl Ty for i16 {}
impl NumTy for i16 {
#[inline]
fn constant(v: Self) -> Const {
Const::I16(v)
}
#[inline]
fn zero() -> Self {
0
}
}
impl IntTy for i16 {}
impl AnyTy for i32 {
const TYPE: Type = Type::I32;
}
impl Ty for i32 {}
impl NumTy for i32 {
#[inline]
fn constant(v: Self) -> Const {
Const::I32(v)
}
#[inline]
fn zero() -> Self {
0
}
}
impl IntTy for i32 {}
impl AnyTy for i64 {
const TYPE: Type = Type::I64;
}
impl Ty for i64 {}
impl NumTy for i64 {
#[inline]
fn constant(v: Self) -> Const {
Const::I64(v)
}
#[inline]
fn zero() -> Self {
0
}
}
impl IntTy for i64 {}
pub trait FloatTy: NumTy {}
impl AnyTy for f32 {
const TYPE: Type = Type::F32;
}
impl Ty for f32 {}
impl NumTy for f32 {
#[inline]
fn constant(v: Self) -> Const {
Const::F32(v)
}
#[inline]
fn zero() -> Self {
0.
}
}
impl FloatTy for f32 {}
impl AnyTy for f64 {
const TYPE: Type = Type::F64;
}
impl Ty for f64 {}
impl NumTy for f64 {
#[inline]
fn constant(v: Self) -> Const {
Const::F64(v)
}
#[inline]
fn zero() -> Self {
0.
}
}
impl FloatTy for f64 {}