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