1use crate::aligner::align;
7use std::fmt::{Alignment, Display, Formatter};
8
9pub mod aligner;
10pub mod opcode;
11
12#[repr(C, packed)]
13#[derive(Clone)]
14pub struct BinaryInstruction {
15 pub opcode: u8,
16 pub operands: [u16; 5],
17}
18
19#[derive(Copy, Clone, Debug)]
20pub struct MemoryAddress(pub u16);
21
22#[derive(Copy, Clone)]
23pub struct StackMemoryAddress(pub u16);
24
25#[derive(Copy, Clone)]
26pub struct CountU16(pub u16);
27
28impl StackMemoryAddress {
29 #[must_use]
30 pub const fn add(&self, memory_size: MemorySize) -> Self {
31 Self(self.0 + memory_size.0)
32 }
33}
34
35#[derive(Debug, Copy, Clone)]
36pub struct ConstantMemoryAddress(pub u32);
37
38#[derive(Debug, Copy, Clone)]
39pub struct HeapMemoryAddress(pub u32);
40
41#[derive(Debug, Copy, Clone)]
42pub struct FrameMemoryAddress(pub u16);
43
44impl Display for FrameMemoryAddress {
45 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46 write!(f, "[frame {:04X} ({})]", self.0, self.0)
47 }
48}
49
50#[derive(Debug, Copy, Clone)]
51pub struct FrameMemoryAddressIndirectPointer(pub FrameMemoryAddress);
52
53#[derive(Debug, Copy, Clone)]
54pub struct TempFrameMemoryAddress(pub FrameMemoryAddress);
55
56impl TempFrameMemoryAddress {
57 #[must_use]
58 pub const fn to_addr(&self) -> FrameMemoryAddress {
59 self.0
60 }
61}
62
63impl FrameMemoryAddress {
64 #[must_use]
65 pub fn advance(&self, memory_offset: MemoryOffset) -> FrameMemoryAddress {
66 FrameMemoryAddress(self.0 + memory_offset.0)
67 }
68}
69
70impl FrameMemoryAddress {
72 #[must_use]
73 pub const fn add(&self, memory_size: MemorySize) -> Self {
74 Self(self.0 + memory_size.0)
75 }
76
77 pub const fn add_offset(&self, memory_offset: MemoryOffset) -> Self {
78 Self(self.0 + memory_offset.0)
79 }
80 #[must_use]
81 pub const fn as_size(&self) -> FrameMemorySize {
82 FrameMemorySize(self.0)
83 }
84}
85
86impl MemoryAddress {
87 #[must_use]
88 pub const fn space(&self, memory_size: MemorySize, _alignment: Alignment) -> Self {
89 Self(self.0 + memory_size.0)
90 }
91}
92
93#[derive(Debug, Copy, Clone)]
94pub struct MemoryOffset(pub u16);
95
96impl MemoryOffset {
97 pub fn space(&mut self, memory_size: MemorySize, alignment: MemoryAlignment) -> Self {
98 let start = align(self.0 as usize, alignment.into()) as u16;
99 self.0 = start + memory_size.0;
100 MemoryOffset(start)
101 }
102}
103
104impl MemoryOffset {
105 pub fn as_size(&self) -> MemorySize {
106 MemorySize(self.0)
107 }
108}
109
110impl MemoryOffset {
111 pub fn add(&self, size: MemorySize, alignment: MemoryAlignment) -> MemoryOffset {
112 let new_start = align(self.0 as usize, alignment.into());
113 MemoryOffset(new_start as u16 + size.0)
114 }
115}
116
117#[derive(Debug, Copy, Clone)]
118pub struct MemorySize(pub u16);
119
120#[derive(Debug, Copy, Clone)]
121pub enum MemoryAlignment {
122 U8,
123 U16,
124 U32,
125 U64,
126}
127
128impl MemoryAlignment {
129 #[must_use]
130 const fn rank(&self) -> usize {
131 match self {
132 Self::U8 => 1,
133 Self::U16 => 2,
134 Self::U32 => 3,
135 Self::U64 => 4,
136 }
137 }
138 #[must_use]
139 pub const fn greater_than(&self, other: MemoryAlignment) -> bool {
140 self.rank() > other.rank()
141 }
142}
143
144impl Into<usize> for MemoryAlignment {
145 fn into(self) -> usize {
146 match self {
147 Self::U8 => 1,
148 Self::U16 => 2,
149 Self::U32 => 4,
150 Self::U64 => 8,
151 }
152 }
153}
154
155impl Into<MemoryOffset> for MemoryAlignment {
156 fn into(self) -> MemoryOffset {
157 let octets: usize = self.into();
158 MemoryOffset(octets as u16)
159 }
160}
161
162#[must_use]
163pub fn align_frame_addr(
164 memory_address: FrameMemoryAddress,
165 alignment: MemoryAlignment,
166) -> FrameMemoryAddress {
167 let raw_addr = align(memory_address.0 as usize, alignment.into());
168
169 FrameMemoryAddress(raw_addr as u16)
170}
171
172#[must_use]
173pub fn align_offset(memory_address: MemoryOffset, alignment: MemoryAlignment) -> MemoryOffset {
174 let raw_addr = align(memory_address.0 as usize, alignment.into());
175
176 MemoryOffset(raw_addr as u16)
177}
178
179#[derive(Copy, Clone)]
180pub struct FrameMemorySize(pub u16);
181
182impl Display for FrameMemorySize {
183 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
184 write!(f, "frame size: {:04X}", self.0)
185 }
186}
187
188impl FrameMemorySize {
189 #[must_use]
190 pub const fn add(&self, inc: MemorySize) -> Self {
191 Self(self.0 + inc.0)
192 }
193}
194
195#[derive(Debug, Clone, Eq, PartialEq, Hash)]
196pub struct InstructionPosition(pub u16);
197
198pub const INT_SIZE: u16 = 4;
199pub const FLOAT_SIZE: u16 = 4;
200pub const BOOL_SIZE: u16 = 1;
201
202pub const PTR_SIZE: u16 = 2;
203pub const HEAP_PTR_SIZE: u16 = 4;
204pub const HEAP_PTR_ALIGNMENT: MemoryAlignment = MemoryAlignment::U32;
205
206pub const VEC_ITERATOR_ALIGNMENT: MemoryAlignment = MemoryAlignment::U32;
207
208pub const STR_SIZE: u16 = VEC_HEADER_SIZE; #[repr(C)]
211pub struct VecHeader {
212 pub count: u16, pub capacity: u16,
214 pub heap_offset: u32, pub size: u16, }
217pub const VEC_HEADER_SIZE: u16 = size_of::<VecHeader>() as u16;
218pub const VEC_REFERENCE_SIZE: u16 = HEAP_PTR_SIZE;
219
220pub struct VecIterator {
221 pub data_heap_offset: u32,
222 pub count: u16,
223 pub element_size: u16,
224 pub index: u16,
225}
226
227pub const VEC_ITERATOR_SIZE: u16 = size_of::<VecIterator>() as u16;
228
229pub const MAP_SIZE: u16 = 2 + 2 + 2 + 2 + 2;
230pub const MAP_REFERENCE_SIZE: u16 = HEAP_PTR_SIZE;
231
232pub struct StringHeader {
233 pub byte_count: u16,
234 pub capacity: u16,
235 pub heap_offset: u32, }
237pub const STRING_HEADER_SIZE: u16 = size_of::<StringHeader>() as u16;
238pub const STRING_REFERENCE_SIZE: u16 = HEAP_PTR_SIZE;