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