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