jetcrab\vm\types/
addresses.rs1use serde::{Deserialize, Serialize};
2use std::fmt;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub struct CodeAddress(usize);
6
7impl CodeAddress {
8 pub fn new(address: usize) -> Self {
9 Self(address)
10 }
11
12 pub fn as_usize(&self) -> usize {
13 self.0
14 }
15
16 pub fn increment(&mut self) {
17 self.0 += 1;
18 }
19
20 pub fn add(&self, offset: usize) -> Self {
21 Self(self.0 + offset)
22 }
23}
24
25impl From<usize> for CodeAddress {
26 fn from(address: usize) -> Self {
27 Self(address)
28 }
29}
30
31impl From<CodeAddress> for usize {
32 fn from(addr: CodeAddress) -> Self {
33 addr.0
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
38pub struct LineNumber(usize);
39
40impl LineNumber {
41 pub fn new(line: usize) -> Self {
42 Self(line)
43 }
44
45 pub fn as_usize(&self) -> usize {
46 self.0
47 }
48
49 pub fn is_valid(&self) -> bool {
50 self.0 > 0
51 }
52}
53
54impl From<usize> for LineNumber {
55 fn from(line: usize) -> Self {
56 Self(line)
57 }
58}
59
60impl From<LineNumber> for usize {
61 fn from(line: LineNumber) -> Self {
62 line.0
63 }
64}
65
66impl fmt::Display for LineNumber {
67 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68 write!(f, "{}", self.0)
69 }
70}
71
72impl std::ops::AddAssign<usize> for LineNumber {
73 fn add_assign(&mut self, rhs: usize) {
74 self.0 += rhs;
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
79pub struct ColumnNumber(usize);
80
81impl ColumnNumber {
82 pub fn new(column: usize) -> Self {
83 Self(column)
84 }
85
86 pub fn as_usize(&self) -> usize {
87 self.0
88 }
89
90 pub fn is_valid(&self) -> bool {
91 self.0 > 0
92 }
93}
94
95impl From<usize> for ColumnNumber {
96 fn from(column: usize) -> Self {
97 Self(column)
98 }
99}
100
101impl From<ColumnNumber> for usize {
102 fn from(col: ColumnNumber) -> Self {
103 col.0
104 }
105}
106
107impl fmt::Display for ColumnNumber {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 write!(f, "{}", self.0)
110 }
111}
112
113impl std::ops::AddAssign<usize> for ColumnNumber {
114 fn add_assign(&mut self, rhs: usize) {
115 self.0 += rhs;
116 }
117}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
120pub struct SourcePosition {
121 pub line: LineNumber,
122 pub column: ColumnNumber,
123}
124
125impl SourcePosition {
126 pub fn new(line: usize, column: usize) -> Self {
127 Self {
128 line: LineNumber::new(line),
129 column: ColumnNumber::new(column),
130 }
131 }
132
133 pub fn as_tuple(&self) -> (usize, usize) {
134 (self.line.as_usize(), self.column.as_usize())
135 }
136}
137
138impl From<(usize, usize)> for SourcePosition {
139 fn from((line, column): (usize, usize)) -> Self {
140 Self::new(line, column)
141 }
142}
143
144impl fmt::Display for SourcePosition {
145 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
146 write!(f, "{}:{}", self.line, self.column)
147 }
148}
149
150#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
151pub struct CharOffset(usize);
152
153impl CharOffset {
154 pub fn new(offset: usize) -> Self {
155 Self(offset)
156 }
157
158 pub fn as_usize(&self) -> usize {
159 self.0
160 }
161
162 pub fn is_zero(&self) -> bool {
163 self.0 == 0
164 }
165
166 pub fn is_positive(&self) -> bool {
167 self.0 > 0
168 }
169
170 pub fn increment(&mut self) {
171 self.0 += 1;
172 }
173
174 pub fn decrement(&mut self) {
175 if self.0 > 0 {
176 self.0 -= 1;
177 }
178 }
179
180 pub fn add(&self, other: usize) -> Self {
181 Self(self.0 + other)
182 }
183
184 pub fn sub(&self, other: usize) -> Self {
185 Self(self.0.saturating_sub(other))
186 }
187}
188
189impl From<usize> for CharOffset {
190 fn from(offset: usize) -> Self {
191 Self(offset)
192 }
193}
194
195impl From<CharOffset> for usize {
196 fn from(offset: CharOffset) -> Self {
197 offset.0
198 }
199}
200
201impl std::ops::Add<usize> for CharOffset {
202 type Output = Self;
203
204 fn add(self, other: usize) -> Self {
205 Self(self.0 + other)
206 }
207}
208
209impl std::ops::Sub<usize> for CharOffset {
210 type Output = Self;
211
212 fn sub(self, other: usize) -> Self {
213 Self(self.0.saturating_sub(other))
214 }
215}
216
217impl std::ops::AddAssign<usize> for CharOffset {
218 fn add_assign(&mut self, rhs: usize) {
219 self.0 += rhs;
220 }
221}
222
223impl std::ops::SubAssign<usize> for CharOffset {
224 fn sub_assign(&mut self, rhs: usize) {
225 self.0 = self.0.saturating_sub(rhs);
226 }
227}
228
229impl fmt::Display for CharOffset {
230 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231 write!(f, "{}", self.0)
232 }
233}