1use core::{
2 ffi::{CStr, FromBytesWithNulError},
3 slice,
4 fmt::{self, Display},
5 ops::Deref,
6};
7
8pub trait Word: Sized {
10
11 fn from_word(word: u32) -> Self;
12}
13
14impl Word for u32 {
15
16 #[inline]
17 fn from_word(word: u32) -> Self {
18 word
19 }
20}
21
22#[inline]
23pub(crate) fn slice_as_bytes<T>(slice: &[T]) -> &[u8] {
24 unsafe {
25 slice::from_raw_parts(slice.as_ptr() as *const u8, size_of_val(slice))
26 }
27}
28
29#[derive(Default, Clone, Copy, PartialEq, Eq, Debug, Hash)]
33pub struct CompilerStr<'a> {
34 bytes: &'a [u8],
35}
36
37impl<'a> Deref for CompilerStr<'a> {
38
39 type Target = [u8];
40
41 fn deref(&self) -> &Self::Target {
42 self.bytes
43 }
44}
45
46impl<'a> CompilerStr<'a> {
47
48 pub fn new(words: &'a [u32]) -> Self {
50 let bytes = slice_as_bytes(words);
51 let len = bytes
52 .iter()
53 .copied()
54 .take_while(|&byte| byte != 0)
55 .count() + 1;
56 Self {
57 bytes: &bytes[0..len],
58 }
59 }
60
61 #[inline]
63 pub fn to_cstr(&self) -> Result<&'a CStr, FromBytesWithNulError> {
64 CStr::from_bytes_with_nul(
65 self.bytes
66 )
67 }
68}
69
70impl Display for CompilerStr<'_> {
71
72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
73 write!(f, "{}", str
74 ::from_utf8(&self.bytes[0..self.bytes.len().saturating_sub(1)])
75 .unwrap_or("<utf8-error>"
76 ))
77 }
78}
79
80#[derive(Clone, Copy, Debug)]
82pub enum Literal {
83 F16(u16),
87 F32(f32),
89 F64(f64),
91 I8(i8),
93 I16(i16),
95 I32(i32),
97 I64(i64),
99 U8(u8),
101 U16(u16),
103 U32(u32),
105 U64(u64),
107}
108
109impl Literal {
110
111 #[inline]
113 pub fn as_usize(self) -> Option<usize> {
114 match self {
115 Self::I8(x) => Some(x as usize),
116 Self::I16(x) => Some(x as usize),
117 Self::I32(x) => Some(x as usize),
118 Self::I64(x) => Some(x as usize),
119 Self::U8(x) => Some(x as usize),
120 Self::U16(x) => Some(x as usize),
121 Self::U32(x) => Some(x as usize),
122 Self::U64(x) => Some(x as usize),
123 _ => None,
124 }
125 }
126}
127
128impl Display for Literal {
129
130 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131 match self {
132 Self::F16(x) => write!(f, "{x:#x}"),
133 Self::F32(x) => write!(f, "{x}"),
134 Self::F64(x) => write!(f, "{x}"),
135 Self::I8(x) => write!(f, "{x}"),
136 Self::I16(x) => write!(f, "{x}"),
137 Self::I32(x) => write!(f, "{x}"),
138 Self::I64(x) => write!(f, "{x}"),
139 Self::U8(x) => write!(f, "{x}"),
140 Self::U16(x) => write!(f, "{x}"),
141 Self::U32(x) => write!(f, "{x}"),
142 Self::U64(x) => write!(f, "{x}"),
143 }
144 }
145}