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 opcode_count: u8, // It is mainly for alignment, but use it for opcode_count or maybe checksum or extra flags?
11    pub operands: [u16; 4],
12}
13
14#[derive(Copy, Clone)]
15pub struct MemoryAddress(pub u16);
16
17#[derive(Copy, Clone)]
18pub struct StackMemoryAddress(pub u16);
19
20impl StackMemoryAddress {
21    #[must_use]
22    pub const fn add(&self, memory_size: MemorySize) -> Self {
23        Self(self.0 + memory_size.0)
24    }
25}
26// relative to the stack pointer
27
28#[derive(Debug, Copy, Clone)]
29pub struct FrameMemoryAddress(pub u16);
30
31impl FrameMemoryAddress {
32    #[must_use]
33    pub fn advance(&self, memory_offset: MemoryOffset) -> FrameMemoryAddress {
34        FrameMemoryAddress(self.0 + memory_offset.0)
35    }
36}
37// relative to the frame pointer
38
39impl FrameMemoryAddress {
40    #[must_use]
41    pub const fn add(&self, memory_size: MemorySize) -> Self {
42        Self(self.0 + memory_size.0)
43    }
44    #[must_use]
45    pub const fn as_size(&self) -> FrameMemorySize {
46        FrameMemorySize(self.0)
47    }
48}
49
50impl MemoryAddress {
51    #[must_use]
52    pub const fn space(&self, memory_size: MemorySize, alignment: Alignment) -> Self {
53        Self(self.0 + memory_size.0)
54    }
55}
56
57#[derive(Debug, Copy, Clone)]
58pub struct MemoryOffset(pub u16);
59
60impl MemoryOffset {
61    pub fn space(&mut self, memory_size: MemorySize, alignment: MemoryAlignment) -> Self {
62        let start = align(self.0 as usize, alignment.into()) as u16;
63        self.0 = start + memory_size.0;
64        MemoryOffset(start)
65    }
66}
67
68impl MemoryOffset {
69    pub fn as_size(&self) -> MemorySize {
70        MemorySize(self.0)
71    }
72}
73
74impl MemoryOffset {
75    pub fn add(&self, size: MemorySize, alignment: MemoryAlignment) -> MemoryOffset {
76        let new_start = align(self.0 as usize, alignment.into());
77        MemoryOffset(new_start as u16 + size.0)
78    }
79}
80
81#[derive(Debug, Copy, Clone)]
82pub struct MemorySize(pub u16);
83
84#[derive(Debug, Copy, Clone)]
85pub enum MemoryAlignment {
86    U8,
87    U16,
88    U32,
89    U64,
90}
91
92impl MemoryAlignment {
93    #[must_use]
94    const fn rank(&self) -> usize {
95        match self {
96            Self::U8 => 1,
97            Self::U16 => 2,
98            Self::U32 => 3,
99            Self::U64 => 4,
100        }
101    }
102    #[must_use]
103    pub const fn greater_than(&self, other: MemoryAlignment) -> bool {
104        self.rank() > other.rank()
105    }
106}
107
108impl Into<usize> for MemoryAlignment {
109    fn into(self) -> usize {
110        match self {
111            Self::U8 => 1,
112            Self::U16 => 2,
113            Self::U32 => 4,
114            Self::U64 => 8,
115        }
116    }
117}
118
119#[must_use]
120pub fn align_frame_addr(
121    memory_address: FrameMemoryAddress,
122    alignment: MemoryAlignment,
123) -> FrameMemoryAddress {
124    let raw_addr = align(memory_address.0 as usize, alignment.into());
125
126    FrameMemoryAddress(raw_addr as u16)
127}
128
129#[must_use]
130pub fn align_offset(memory_address: MemoryOffset, alignment: MemoryAlignment) -> MemoryOffset {
131    let raw_addr = align(memory_address.0 as usize, alignment.into());
132
133    MemoryOffset(raw_addr as u16)
134}
135
136#[derive(Copy, Clone)]
137pub struct FrameMemorySize(pub u16);
138
139impl Display for FrameMemorySize {
140    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
141        write!(f, "frame size: {:04X}", self.0)
142    }
143}
144
145impl FrameMemorySize {
146    #[must_use]
147    pub const fn add(&self, inc: MemorySize) -> Self {
148        Self(self.0 + inc.0)
149    }
150}
151
152#[derive(Debug, Clone, Eq, PartialEq, Hash)]
153pub struct InstructionPosition(pub u16);