swamp_vm_types/
lib.rs

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}
64// relative to the frame pointer
65
66impl 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; // TODO: FIX THIS
204
205#[repr(C)]
206pub struct VecHeader {
207    pub count: u16, // useful for iterator
208    pub capacity: u16,
209    pub heap_offset: u32, // "pointer" to the allocated slice (an offset into memory)
210    pub size: u16,        // size (in bytes) of each element; useful for iterator
211}
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, // "pointer" to the allocated slice (an offset into memory)
231}
232pub const STRING_HEADER_SIZE: u16 = size_of::<StringHeader>() as u16;
233pub const STRING_REFERENCE_SIZE: u16 = HEAP_PTR_SIZE;