use super::*;
#[derive(Debug, Clone, SExpr)]
pub struct TypedLit {
#[pp(open)]
pub lit: RadixIntLit,
#[pp(close)]
pub ty: Type,
}
impl TypedLit {
pub fn new(lit: RadixIntLit, ty: Type) -> Self {
Self { lit, ty }
}
pub fn is_true(&self) -> bool {
self.lit.is_true()
}
}
macro_rules! impl_from_uint_for_typedlit {
($(($t:ty, $width:expr)),*) => {
$(
impl From<$t> for TypedLit {
fn from(value: $t) -> Self {
TypedLit::new(value.into(), Type::UInt($width))
}
}
)*
};
}
impl_from_uint_for_typedlit!(
(u8, 8),
(u16, 16),
(u32, 32),
(u64, 64),
(u128, 128),
(usize, usize::BITS)
);
macro_rules! impl_from_int_for_typedlit {
($(($t:ty, $width:expr)),*) => {
$(
impl From<$t> for TypedLit {
fn from(value: $t) -> Self {
TypedLit::new(value.into(), Type::SInt($width))
}
}
)*
};
}
impl_from_int_for_typedlit!(
(i8, 8),
(i16, 16),
(i32, 32),
(i64, 64),
(i128, 128),
(isize, isize::BITS)
);
impl TypedLit {
pub fn to_fir_lit(&self) -> fir::Expression {
fir::Expression::literal(
match self.ty {
Type::UInt(_) => fir::Sign::Unsigned,
Type::SInt(_) => fir::Sign::Signed,
_ => unreachable!(),
},
self.lit.is_neg(),
radix_int_lit_to_logic_values(self.lit.clone()),
Some(self.ty.int_width() as usize),
)
}
}
pub fn radix_int_lit_to_logic_values(lit: RadixIntLit) -> fir::LogicValues {
let mut logic_values = Vec::new();
let mut bits = lit.to_binary_digits();
if bits.is_empty() {
bits = vec![false];
}
for bit in bits.iter().rev() {
logic_values.push(fir::LogicValue::from_bool(*bit));
}
fir::LogicValues::new(logic_values)
}