Files
leaf/assembly/src/values/constants.rs
T

143 lines
3.2 KiB
Rust

use crate::{
functions::Function,
types::{Type, derivations::ArrayT},
values::ValueFlags,
};
use derive_more::{Debug, *};
use half::f16;
use std::hash::Hash;
#[derive(Debug, Display, Clone, Copy, From, TryInto, PartialEq, Eq, Hash)]
pub enum Int {
I8(i8),
I16(i16),
I32(i32),
I64(i64),
#[from]
I128(i128),
ISize(i128),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
#[from]
U128(u128),
USize(u128),
}
#[derive(Debug, Display, Clone, Copy, From, TryInto, PartialEq)]
pub enum Float {
F16(f16),
F32(f32),
F64(f64),
}
impl Eq for Float {}
impl Hash for Float {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
match self {
Float::F16(v) => v.to_ne_bytes().hash(state),
Float::F32(v) => v.to_ne_bytes().hash(state),
Float::F64(v) => v.to_ne_bytes().hash(state),
}
}
}
#[derive(Debug, Display, Deref, DerefMut, Clone, Copy, From, PartialEq, Eq, Hash)]
#[debug("{:?}", _0)]
#[display("{}", _0)]
pub struct Const<T>(T);
impl<'l, T: 'l> Into<AnyConst<'l>> for &'l Const<T>
where
for<'a> &'a T: Into<AnyConst<'a>>,
{
fn into(self) -> AnyConst<'l> {
(&self.0).into()
}
}
struct ListDisplay<'l>(&'l [AnyConst<'l>]);
impl std::fmt::Display for ListDisplay<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut list = f.debug_list();
for ele in self.0 {
list.entry(&format_args!("{ele}"));
}
list.finish()
}
}
#[derive(Debug, Display, Clone, Copy, From, TryInto, PartialEq, Eq, Hash)]
#[from(forward)]
pub enum AnyConst<'l> {
#[display("void")]
#[debug("void")]
Void,
#[debug("{:?}", _0)]
#[display("{}", _0)]
Bool(bool),
#[debug("{:?}", _0)]
#[display("{}", _0)]
Char(char),
#[debug("{:?}", _0)]
#[display("{}", _0)]
Int(Int),
#[debug("{:?}", _0)]
#[display("{}", _0)]
Float(Float),
#[debug("{:?}", _0)]
#[display("\"{}\"", _0)]
Str(&'l str),
#[debug("{:?}", _0)]
#[display("{}", _0)]
Function(&'l Function<'l>),
#[debug("{:?}", _0)]
#[display("{}", ListDisplay(_0))]
Array(&'l [AnyConst<'l>]),
Type(Type<'l>),
}
impl<'l> AnyConst<'l> {
pub fn ty(&self) -> Type<'l> {
match self {
Self::Void => Type::Void,
Self::Bool(_) => Type::Bool,
Self::Char(_) => Type::Char,
Self::Type(_) => Type::Type,
Self::Int(Int::I8(_)) => Type::I8,
Self::Int(Int::I16(_)) => Type::I16,
Self::Int(Int::I32(_)) => Type::I32,
Self::Int(Int::I64(_)) => Type::I64,
Self::Int(Int::I128(_)) => Type::I128,
Self::Int(Int::ISize(_)) => Type::ISIZE,
Self::Int(Int::U8(_)) => Type::U8,
Self::Int(Int::U16(_)) => Type::U16,
Self::Int(Int::U32(_)) => Type::U32,
Self::Int(Int::U64(_)) => Type::U64,
Self::Int(Int::U128(_)) => Type::U128,
Self::Int(Int::USize(_)) => Type::USIZE,
Self::Float(Float::F16(_)) => Type::F16,
Self::Float(Float::F32(_)) => Type::F32,
Self::Float(Float::F64(_)) => Type::F64,
Self::Array([]) => Type::Array(&ArrayT {
base: Type::Void,
length: Some(0),
}),
Self::Array(a @ [v, ..]) => Type::Array(v.ty().make_array(Some(a.len() as u32))),
_ => todo!("{self:?}"),
}
}
pub fn flags(&self) -> super::ValueFlags {
match self {
AnyConst::Function(function) => ValueFlags::Function,
AnyConst::Type(_) => ValueFlags::Type,
_ => ValueFlags::Const,
}
}
}