idk man, intern stuff innit

This commit is contained in:
Janis 2025-08-06 22:27:00 +02:00
parent d124ae2b59
commit 76e50085a0
3 changed files with 178 additions and 148 deletions

View file

@ -15,7 +15,7 @@ use crate::{
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u8)] #[repr(u8)]
pub enum SimpleType { pub enum SimpleType {
F32 = 0, F32,
F64, F64,
Bool, Bool,
Void, Void,
@ -28,11 +28,14 @@ pub enum SimpleType {
/// Bottom type: this is the subtype of all types, and it can coerce into a value of any type. /// Bottom type: this is the subtype of all types, and it can coerce into a value of any type.
/// Akin to Rust's `!`. /// Akin to Rust's `!`.
Bottom, Bottom,
UInt(u16),
SInt(u16),
} }
impl From<u8> for SimpleType { impl From<u32> for SimpleType {
fn from(value: u8) -> Self { fn from(value: u32) -> Self {
match value { let [discriminant, bits] = *crate::common::u32_as_u16_slice(&value);
match discriminant {
0 => Self::F32, 0 => Self::F32,
1 => Self::F64, 1 => Self::F64,
2 => Self::Bool, 2 => Self::Bool,
@ -40,28 +43,49 @@ impl From<u8> for SimpleType {
4 => Self::USize, 4 => Self::USize,
5 => Self::ISize, 5 => Self::ISize,
6 => Self::ComptimeInt, 6 => Self::ComptimeInt,
7 => Self::Top,
8 => Self::Bottom,
9 => Self::UInt(bits),
10 => Self::SInt(bits),
_ => panic!("{value} is not a simple type"), _ => panic!("{value} is not a simple type"),
} }
} }
} }
impl From<SimpleType> for u32 {
fn from(value: SimpleType) -> Self {
match value {
SimpleType::F32 => crate::common::u32_from_u16_slice(&[0, 0]),
SimpleType::F64 => crate::common::u32_from_u16_slice(&[1, 0]),
SimpleType::Bool => crate::common::u32_from_u16_slice(&[2, 0]),
SimpleType::Void => crate::common::u32_from_u16_slice(&[3, 0]),
SimpleType::USize => crate::common::u32_from_u16_slice(&[4, 0]),
SimpleType::ISize => crate::common::u32_from_u16_slice(&[5, 0]),
SimpleType::ComptimeInt => crate::common::u32_from_u16_slice(&[6, 0]),
SimpleType::Top => crate::common::u32_from_u16_slice(&[7, 0]),
SimpleType::Bottom => crate::common::u32_from_u16_slice(&[8, 0]),
SimpleType::UInt(bits) => crate::common::u32_from_u16_slice(&[9, bits]),
SimpleType::SInt(bits) => crate::common::u32_from_u16_slice(&[10, bits]),
}
}
}
impl Display for SimpleType { impl Display for SimpleType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!( let fmt: std::borrow::Cow<str> = match self {
f, SimpleType::F32 => "f32".into(),
"{}", SimpleType::F64 => "f64".into(),
match self { SimpleType::Bool => "bool".into(),
SimpleType::F32 => "f32", SimpleType::Void => "void".into(),
SimpleType::F64 => "f64", SimpleType::USize => "usize".into(),
SimpleType::Bool => "bool", SimpleType::ISize => "isize".into(),
SimpleType::Void => "void", SimpleType::ComptimeInt => "comptime_int".into(),
SimpleType::USize => "usize", SimpleType::Top => "".into(),
SimpleType::ISize => "isize", SimpleType::Bottom => "".into(),
SimpleType::ComptimeInt => "comptime_int", SimpleType::UInt(bits) => format!("u{bits}").into(),
SimpleType::Top => "", SimpleType::SInt(bits) => format!("i{bits}").into(),
SimpleType::Bottom => "", };
} write!(f, "{fmt}",)
)
} }
} }
@ -78,8 +102,6 @@ pub enum Tag {
F64, F64,
PositiveInt, PositiveInt,
NegativeInt, NegativeInt,
UIntType,
SIntType,
SimpleType, SimpleType,
PointerType, PointerType,
ArrayType, ArrayType,
@ -88,9 +110,9 @@ pub enum Tag {
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Item { pub(super) struct Item {
tag: Tag, pub(super) tag: Tag,
index: u32, pub(super) index: u32,
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -126,12 +148,6 @@ pub enum Key<'a> {
NegativeInt { NegativeInt {
bigint: BigInt, bigint: BigInt,
}, },
UIntType {
bit_width: u16,
},
SIntType {
bit_width: u16,
},
SimpleType { SimpleType {
ty: SimpleType, ty: SimpleType,
}, },
@ -178,8 +194,6 @@ impl Display for KeyDisplay<'_> {
Key::F64 { bits } => write!(f, "{bits}")?, Key::F64 { bits } => write!(f, "{bits}")?,
Key::PositiveInt { ref bigint } => write!(f, "{bigint}")?, Key::PositiveInt { ref bigint } => write!(f, "{bigint}")?,
Key::NegativeInt { ref bigint } => write!(f, "{bigint}")?, Key::NegativeInt { ref bigint } => write!(f, "{bigint}")?,
Key::UIntType { bit_width } => write!(f, "u{bit_width}")?,
Key::SIntType { bit_width } => write!(f, "i{bit_width}")?,
Key::SimpleType { ty } => write!(f, "{ty}")?, Key::SimpleType { ty } => write!(f, "{ty}")?,
Key::PointerType { pointee, flags } => { Key::PointerType { pointee, flags } => {
write!(f, "*{flags}{}", self.ip.display_key(pointee))? write!(f, "*{flags}{}", self.ip.display_key(pointee))?
@ -238,8 +252,6 @@ impl Hash for Key<'_> {
Key::F64 { bits } => ordered_float::OrderedFloat(*bits).hash(state), Key::F64 { bits } => ordered_float::OrderedFloat(*bits).hash(state),
Key::PositiveInt { bigint } => bigint.hash(state), Key::PositiveInt { bigint } => bigint.hash(state),
Key::NegativeInt { bigint } => bigint.hash(state), Key::NegativeInt { bigint } => bigint.hash(state),
Key::UIntType { bit_width: bits } => bits.hash(state),
Key::SIntType { bit_width: bits } => bits.hash(state),
Key::SimpleType { ty } => ty.hash(state), Key::SimpleType { ty } => ty.hash(state),
Key::PointerType { pointee, flags } => (pointee, flags).hash(state), Key::PointerType { pointee, flags } => (pointee, flags).hash(state),
Key::ArrayType { Key::ArrayType {
@ -544,20 +556,20 @@ static_keys!(
ISIZE => Key::SimpleType {ty: SimpleType::ISize,}, ISIZE => Key::SimpleType {ty: SimpleType::ISize,},
VOID => Key::SimpleType {ty: SimpleType::Void,}, VOID => Key::SimpleType {ty: SimpleType::Void,},
COMPTIME_INT => Key::SimpleType {ty: SimpleType::ComptimeInt,}, COMPTIME_INT => Key::SimpleType {ty: SimpleType::ComptimeInt,},
I1 => Key::SIntType { bit_width: 1 }, I0 => Key::SimpleType { ty: SimpleType::SInt(0) },
U1 => Key::UIntType { bit_width: 1 }, U0 => Key::SimpleType { ty: SimpleType::UInt(0) },
I0 => Key::SIntType { bit_width: 0 }, I1 => Key::SimpleType { ty: SimpleType::SInt(1) },
U0 => Key::UIntType { bit_width: 0 }, U1 => Key::SimpleType { ty: SimpleType::UInt(1) },
I8 => Key::SIntType { bit_width: 8 }, I8 => Key::SimpleType { ty: SimpleType::SInt(8) },
U8 => Key::UIntType { bit_width: 8 }, U8 => Key::SimpleType { ty: SimpleType::UInt(8) },
I16 => Key::SIntType { bit_width: 16 }, I16 => Key::SimpleType { ty: SimpleType::SInt(16) },
U16 => Key::UIntType { bit_width: 16 }, U16 => Key::SimpleType { ty: SimpleType::UInt(16) },
I32 => Key::SIntType { bit_width: 32 }, I32 => Key::SimpleType { ty: SimpleType::SInt(32) },
U32 => Key::UIntType { bit_width: 32 }, U32 => Key::SimpleType { ty: SimpleType::UInt(32) },
I64 => Key::SIntType { bit_width: 64 }, I64 => Key::SimpleType { ty: SimpleType::SInt(64) },
U64 => Key::UIntType { bit_width: 64 }, U64 => Key::SimpleType { ty: SimpleType::UInt(64) },
I128 => Key::SIntType { bit_width: 128 }, I128 => Key::SimpleType { ty: SimpleType::SInt(128) },
U128 => Key::UIntType { bit_width: 128 }, U128 => Key::SimpleType { ty: SimpleType::UInt(128) },
TRUE => Key::TrueValue, TRUE => Key::TrueValue,
FALSE => Key::FalseValue, FALSE => Key::FalseValue,
EMPTY_STRING => Key::String { str: "" }, EMPTY_STRING => Key::String { str: "" },
@ -606,41 +618,51 @@ impl InternPool {
ty: SimpleType::ISize, ty: SimpleType::ISize,
}) })
} }
// Assumes the type is present in the pool.
fn get_simple_type_unchecked(&self, ty: SimpleType) -> Index {
self.get_assume_present(&Key::SimpleType { ty })
}
pub fn get_u0_type(&self) -> Index { pub fn get_u0_type(&self) -> Index {
self.get_assume_present(&Key::UIntType { bit_width: 0 }) self.get_simple_type_unchecked(SimpleType::UInt(0))
} }
pub fn get_i0_type(&self) -> Index { pub fn get_i0_type(&self) -> Index {
self.get_assume_present(&Key::SIntType { bit_width: 0 }) self.get_simple_type_unchecked(SimpleType::SInt(0))
} }
pub fn get_u1_type(&self) -> Index { pub fn get_u1_type(&self) -> Index {
self.get_assume_present(&Key::UIntType { bit_width: 1 }) self.get_simple_type_unchecked(SimpleType::UInt(1))
} }
pub fn get_i1_type(&self) -> Index { pub fn get_i1_type(&self) -> Index {
self.get_assume_present(&Key::SIntType { bit_width: 1 }) self.get_simple_type_unchecked(SimpleType::SInt(1))
} }
pub fn get_u8_type(&self) -> Index { pub fn get_u8_type(&self) -> Index {
self.get_assume_present(&Key::UIntType { bit_width: 8 }) self.get_simple_type_unchecked(SimpleType::UInt(8))
} }
pub fn get_i8_type(&self) -> Index { pub fn get_i8_type(&self) -> Index {
self.get_assume_present(&Key::SIntType { bit_width: 8 }) self.get_simple_type_unchecked(SimpleType::SInt(8))
} }
pub fn get_u16_type(&self) -> Index { pub fn get_u16_type(&self) -> Index {
self.get_assume_present(&Key::UIntType { bit_width: 16 }) self.get_simple_type_unchecked(SimpleType::UInt(16))
} }
pub fn get_i16_type(&self) -> Index { pub fn get_i16_type(&self) -> Index {
self.get_assume_present(&Key::SIntType { bit_width: 16 }) self.get_simple_type_unchecked(SimpleType::SInt(16))
} }
pub fn get_u32_type(&self) -> Index { pub fn get_u32_type(&self) -> Index {
self.get_assume_present(&Key::UIntType { bit_width: 32 }) self.get_simple_type_unchecked(SimpleType::UInt(32))
} }
pub fn get_i32_type(&self) -> Index { pub fn get_i32_type(&self) -> Index {
self.get_assume_present(&Key::SIntType { bit_width: 32 }) self.get_simple_type_unchecked(SimpleType::SInt(32))
} }
pub fn get_u64_type(&self) -> Index { pub fn get_u64_type(&self) -> Index {
self.get_assume_present(&Key::UIntType { bit_width: 64 }) self.get_simple_type_unchecked(SimpleType::UInt(64))
} }
pub fn get_i64_type(&self) -> Index { pub fn get_i64_type(&self) -> Index {
self.get_assume_present(&Key::SIntType { bit_width: 64 }) self.get_simple_type_unchecked(SimpleType::SInt(64))
}
pub fn get_u128_type(&self) -> Index {
self.get_simple_type_unchecked(SimpleType::UInt(128))
}
pub fn get_i128_type(&self) -> Index {
self.get_simple_type_unchecked(SimpleType::SInt(128))
} }
pub fn get_top_type(&self) -> Index { pub fn get_top_type(&self) -> Index {
@ -700,8 +722,9 @@ impl InternPool {
| Key::SimpleType { | Key::SimpleType {
ty: SimpleType::ISize, ty: SimpleType::ISize,
} }
| Key::SIntType { .. } | Key::SimpleType {
| Key::UIntType { .. }, ty: SimpleType::SInt(_) | SimpleType::UInt(_),
},
) => Some(rhs), ) => Some(rhs),
( (
Key::SimpleType { Key::SimpleType {
@ -716,8 +739,9 @@ impl InternPool {
| Key::SimpleType { | Key::SimpleType {
ty: SimpleType::ISize, ty: SimpleType::ISize,
} }
| Key::SIntType { .. } | Key::SimpleType {
| Key::UIntType { .. }, ty: SimpleType::SInt(_) | SimpleType::UInt(_),
},
Key::SimpleType { Key::SimpleType {
ty: SimpleType::ComptimeInt, ty: SimpleType::ComptimeInt,
}, },
@ -745,15 +769,6 @@ impl InternPool {
pub fn to_mir_type(&self, index: Index, _ptr_size: TypeInfo) -> crate::mir::Type { pub fn to_mir_type(&self, index: Index, _ptr_size: TypeInfo) -> crate::mir::Type {
use crate::mir::Type; use crate::mir::Type;
match self.get_key(index) { match self.get_key(index) {
Key::UIntType { bit_width: bits } => {
let bits = bits as u32;
Type::from_bitsize_int(bits)
}
Key::SIntType { bit_width: bits } => {
let bits = bits as u32;
Type::from_bitsize_int(bits)
}
Key::SimpleType { ty } => match ty { Key::SimpleType { ty } => match ty {
SimpleType::F32 => Type::SinglePrecision, SimpleType::F32 => Type::SinglePrecision,
SimpleType::F64 => Type::DoublePrecision, SimpleType::F64 => Type::DoublePrecision,
@ -762,6 +777,9 @@ impl InternPool {
todo!("void can't be turned into a mir type") todo!("void can't be turned into a mir type")
} }
SimpleType::ISize | SimpleType::USize => Type::QWord, SimpleType::ISize | SimpleType::USize => Type::QWord,
SimpleType::UInt(bits) | SimpleType::SInt(bits) => {
Type::from_bitsize_int(bits as u32)
}
SimpleType::Top | SimpleType::Bottom | SimpleType::ComptimeInt => { SimpleType::Top | SimpleType::Bottom | SimpleType::ComptimeInt => {
panic!("{ty} can't be turned into a mir type") panic!("{ty} can't be turned into a mir type")
} }
@ -782,11 +800,9 @@ impl InternPool {
pub fn is_type_signed(&self, index: Index, _ptr_size: TypeInfo) -> bool { pub fn is_type_signed(&self, index: Index, _ptr_size: TypeInfo) -> bool {
match self.get_key(index) { match self.get_key(index) {
Key::UIntType { .. } => false,
Key::SIntType { .. } => true,
Key::SimpleType { ty } => match ty { Key::SimpleType { ty } => match ty {
SimpleType::USize => false, SimpleType::USize | SimpleType::UInt(_) => false,
SimpleType::ISize => true, SimpleType::ISize | SimpleType::SInt(_) => true,
_ => false, _ => false,
}, },
Key::PointerType { .. } => false, Key::PointerType { .. } => false,
@ -799,23 +815,17 @@ impl InternPool {
pub fn size_of_type(&self, index: Index, ptr_size: TypeInfo) -> TypeInfo { pub fn size_of_type(&self, index: Index, ptr_size: TypeInfo) -> TypeInfo {
match self.get_key(index) { match self.get_key(index) {
Key::UIntType { bit_width: bits } => {
let bits = bits as u32;
TypeInfo {
bitsize: bits,
bitalign: bits.next_multiple_of(8).next_power_of_two(),
signed: false,
}
}
Key::SIntType { bit_width: bits } => {
let bits = bits as u32;
TypeInfo {
bitsize: bits,
bitalign: bits.next_multiple_of(8).next_power_of_two(),
signed: true,
}
}
Key::SimpleType { ty } => match ty { Key::SimpleType { ty } => match ty {
SimpleType::SInt(bits) => TypeInfo {
bitsize: bits as u32,
bitalign: (bits as u32).next_multiple_of(8).next_power_of_two(),
signed: true,
},
SimpleType::UInt(bits) => TypeInfo {
bitsize: bits as u32,
bitalign: (bits as u32).next_multiple_of(8).next_power_of_two(),
signed: false,
},
SimpleType::F32 => TypeInfo { SimpleType::F32 => TypeInfo {
bitsize: 32, bitsize: 32,
bitalign: 32, bitalign: 32,
@ -889,9 +899,13 @@ impl InternPool {
crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(), crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(),
crate::ast::Type::Integer(i) => self.get_or_insert({ crate::ast::Type::Integer(i) => self.get_or_insert({
if i.signed { if i.signed {
Key::SIntType { bit_width: i.bits } Key::SimpleType {
ty: SimpleType::SInt(i.bits),
}
} else { } else {
Key::UIntType { bit_width: i.bits } Key::SimpleType {
ty: SimpleType::UInt(i.bits),
}
} }
}), }),
crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => self.get_f32_type(), crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => self.get_f32_type(),
@ -930,9 +944,13 @@ impl InternPool {
crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(), crate::ast::Type::ComptimeNumber => self.get_comptime_int_type(),
crate::ast::Type::Integer(i) => self.get_assume_present(&{ crate::ast::Type::Integer(i) => self.get_assume_present(&{
if i.signed { if i.signed {
Key::SIntType { bit_width: i.bits } Key::SimpleType {
ty: SimpleType::SInt(i.bits),
}
} else { } else {
Key::UIntType { bit_width: i.bits } Key::SimpleType {
ty: SimpleType::UInt(i.bits),
}
} }
}), }),
crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => self.get_f32_type(), crate::ast::Type::Floating(crate::ast::FloatingType::Binary32) => self.get_f32_type(),
@ -968,11 +986,11 @@ impl InternPool {
pub fn as_ast1_type(&self, pointer_bits: u16, index: Index) -> crate::ast::Type { pub fn as_ast1_type(&self, pointer_bits: u16, index: Index) -> crate::ast::Type {
use crate::ast::Type; use crate::ast::Type;
match self.get_key(index) { match self.get_key(index) {
Key::UIntType { bit_width: bits } => Type::Integer(IntegralType::new(false, bits)),
Key::SIntType { bit_width: bits } => Type::Integer(IntegralType::new(true, bits)),
Key::SimpleType { ty } => match ty { Key::SimpleType { ty } => match ty {
SimpleType::F32 => Type::Floating(crate::ast::FloatingType::Binary32), SimpleType::F32 => Type::Floating(crate::ast::FloatingType::Binary32),
SimpleType::F64 => Type::Floating(crate::ast::FloatingType::Binary64), SimpleType::F64 => Type::Floating(crate::ast::FloatingType::Binary64),
SimpleType::SInt(bits) => Type::Integer(IntegralType::new(true, bits)),
SimpleType::UInt(bits) => Type::Integer(IntegralType::new(false, bits)),
SimpleType::Bool => Type::Bool, SimpleType::Bool => Type::Bool,
SimpleType::Void => Type::Void, SimpleType::Void => Type::Void,
SimpleType::USize => Type::Integer(IntegralType::new(false, pointer_bits)), SimpleType::USize => Type::Integer(IntegralType::new(false, pointer_bits)),
@ -1098,9 +1116,7 @@ impl InternPool {
self.create_item(Tag::NegativeInt, i) self.create_item(Tag::NegativeInt, i)
} }
Key::UIntType { bit_width: bits } => self.create_item(Tag::UIntType, bits as u32), Key::SimpleType { ty } => self.create_item(Tag::SimpleType, ty.into()),
Key::SIntType { bit_width: bits } => self.create_item(Tag::SIntType, bits as u32),
Key::SimpleType { ty } => self.create_item(Tag::SimpleType, ty as u8 as u32),
Key::PointerType { pointee, flags } => { Key::PointerType { pointee, flags } => {
let flags = flags.pack(); let flags = flags.pack();
let i = self.extend_words([pointee.index() as u32, flags as u32]); let i = self.extend_words([pointee.index() as u32, flags as u32]);
@ -1230,17 +1246,11 @@ impl InternPool {
let bigint = BigInt::from_biguint(Sign::Plus, data); let bigint = BigInt::from_biguint(Sign::Plus, data);
Key::PositiveInt { bigint } Key::PositiveInt { bigint }
} }
Tag::SIntType => Key::SIntType {
bit_width: item.index as u16,
},
Tag::UIntType => Key::UIntType {
bit_width: item.index as u16,
},
Tag::SimpleType => { Tag::SimpleType => {
let ty = item.idx() as u8; let ty = item.idx() as u32;
Key::SimpleType { Key::SimpleType {
ty: unsafe { core::mem::transmute::<u8, SimpleType>(ty) }, ty: SimpleType::from(ty),
} }
} }
Tag::PointerType => { Tag::PointerType => {
@ -1337,8 +1347,12 @@ impl InternPool {
pub fn get_int_type(&mut self, signed: bool, bits: u16) -> Index { pub fn get_int_type(&mut self, signed: bool, bits: u16) -> Index {
let key = match signed { let key = match signed {
true => Key::SIntType { bit_width: bits }, true => Key::SimpleType {
false => Key::UIntType { bit_width: bits }, ty: SimpleType::SInt(bits),
},
false => Key::SimpleType {
ty: SimpleType::UInt(bits),
},
}; };
self.get_or_insert(key) self.get_or_insert(key)
@ -1535,7 +1549,7 @@ impl InternPool {
((index.index() as u32) < self.len()).then_some(index) ((index.index() as u32) < self.len()).then_some(index)
} }
fn get_item(&self, index: Index) -> Option<Item> { pub(super) fn get_item(&self, index: Index) -> Option<Item> {
self.check_bounds(index).map(|i| Item { self.check_bounds(index).map(|i| Item {
tag: self.tags[i.index()], tag: self.tags[i.index()],
index: self.indices[i.index()], index: self.indices[i.index()],
@ -1554,8 +1568,6 @@ impl InternPool {
| Key::ArrayType { .. } | Key::ArrayType { .. }
| Key::PointerType { .. } | Key::PointerType { .. }
| Key::SimpleType { .. } | Key::SimpleType { .. }
| Key::SIntType { .. }
| Key::UIntType { .. }
| Key::StructType { .. } | Key::StructType { .. }
) )
} }

View file

@ -2134,36 +2134,6 @@ where
let ty_key = ip.get_key(ty); let ty_key = ip.get_key(ty);
let signed = ip.is_type_signed(ty, AMD64_POINTER_TYPE_INFO); let signed = ip.is_type_signed(ty, AMD64_POINTER_TYPE_INFO);
match ty_key { match ty_key {
intern::Key::SIntType { bit_width: bits } | intern::Key::UIntType { bit_width: bits } => {
let ty = IntegralType::new(signed, bits);
match ip.get_key(val) {
intern::Key::SIntSmall { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
bits: bits as _,
ty,
}),
intern::Key::UIntSmall { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
bits: bits as _,
ty,
}),
intern::Key::SInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
bits: bits as _,
ty,
}),
intern::Key::UInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
bits: bits as _,
ty,
}),
intern::Key::PositiveInt { bigint } => {
ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty })
}
intern::Key::NegativeInt { bigint } => {
ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty })
}
_ => {
unreachable!()
}
}
}
intern::Key::SimpleType { ty } => match ty { intern::Key::SimpleType { ty } => match ty {
intern::SimpleType::F32 => match ip.get_key(val) { intern::SimpleType::F32 => match ip.get_key(val) {
intern::Key::F32 { bits } => { intern::Key::F32 { bits } => {
@ -2256,6 +2226,40 @@ where
intern::SimpleType::Top | intern::SimpleType::Bottom => { intern::SimpleType::Top | intern::SimpleType::Bottom => {
unreachable!() unreachable!()
} }
intern::SimpleType::UInt(bits) | intern::SimpleType::SInt(bits) => {
let ty = IntegralType::new(signed, bits);
match ip.get_key(val) {
intern::Key::SIntSmall { bits } => {
ComptimeNumber::Integral(ComptimeInt::Native {
bits: bits as _,
ty,
})
}
intern::Key::UIntSmall { bits } => {
ComptimeNumber::Integral(ComptimeInt::Native {
bits: bits as _,
ty,
})
}
intern::Key::SInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
bits: bits as _,
ty,
}),
intern::Key::UInt64 { bits } => ComptimeNumber::Integral(ComptimeInt::Native {
bits: bits as _,
ty,
}),
intern::Key::PositiveInt { bigint } => {
ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty })
}
intern::Key::NegativeInt { bigint } => {
ComptimeNumber::Integral(ComptimeInt::BigInt { bits: bigint, ty })
}
_ => {
unreachable!()
}
}
}
}, },
_ => { _ => {
unreachable!() unreachable!()

View file

@ -72,9 +72,7 @@ pub fn is_oct_digit(ch: char) -> bool {
} }
pub fn is_hex_digit(ch: char) -> bool { pub fn is_hex_digit(ch: char) -> bool {
('0'..='9').contains(&ch) ('0'..='9').contains(&ch) || ('a'..='f').contains(&ch) || ('A'..='F').contains(&ch)
|| ('a'..='f').contains(&ch)
|| ('A'..='F').contains(&ch)
} }
/// Trait for only yielding the next item in the Iterator if it tests true for some predicate /// Trait for only yielding the next item in the Iterator if it tests true for some predicate
@ -176,3 +174,19 @@ pub fn from_lo_hi_dwords(lo: u32, hi: u32) -> u64 {
pub fn into_lo_hi_dwords(qword: u64) -> (u32, u32) { pub fn into_lo_hi_dwords(qword: u64) -> (u32, u32) {
(qword as u32, (qword >> 32) as u32) (qword as u32, (qword >> 32) as u32)
} }
pub fn u32_as_u16_slice(value: &u32) -> &[u16; 2] {
// SAFETY: This is safe because u32 is guaranteed to be 4 bytes and
// we are creating a slice of 2 u16s which is also 4 bytes.
unsafe { &*(value as *const u32 as *const [u16; 2]) }
}
// we can't transform any &[u16; 2] into a &u32 because of alignment guarantees
pub fn u32_from_u16_slice(slice: &[u16; 2]) -> u32 {
let mut out = 0u32;
unsafe {
core::ptr::copy_nonoverlapping(slice.as_ptr(), &raw mut out as *mut u16, 2);
}
out
}