1use alloc::{string::String, vec::Vec};
2
3#[cfg(feature = "compiler_utils")]
4use alloc::{borrow::ToOwned, format};
5use core::fmt::{Display, Error, Formatter};
6
7#[cfg(feature = "compiler_utils")]
8use regex::Regex;
9
10#[cfg(feature = "compiler_utils")]
11use serde::{Deserialize, Serialize};
12
13#[cfg(feature = "compiler_utils")]
14#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
15#[derive(Default)]
16pub enum TokenizerType {
17 #[default]
18 Raw,
19 ClassParser,
20 FunctionParser,
21 HeaderParser,
22}
23
24#[cfg(feature = "compiler_utils")]
25
26#[cfg(feature = "compiler_utils")]
27#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
28pub struct TokenizerOptions {
29 pub path: String,
30 pub functions: bool,
31 pub break_on_error: bool,
32 pub loops: bool,
33 pub enums: bool,
34 pub classes: bool,
35 pub getters: bool,
36 pub setters: bool,
37 pub conditions: bool,
38 pub global_variables: bool,
39 pub line_ending: String,
40 pub dynamics: bool,
41 pub collectives: bool,
42 pub variables: bool,
43 pub import_std: bool,
44 pub constants: bool,
45 pub ignore_imports: bool,
46 pub parser_type: TokenizerType,
47 pub allow_import: bool,
48}
49
50#[cfg(feature = "compiler_utils")]
51impl Default for TokenizerOptions {
52 fn default() -> Self {
53 TokenizerOptions {
54 path: "".to_owned(),
55 functions: true,
56 break_on_error: false,
57 loops: true,
58 conditions: true,
59 getters: true,
60 setters: true,
61 classes: true,
62 enums: true,
63 global_variables: true,
64 line_ending: "\\r\\n".to_owned(),
65 dynamics: true,
66 import_std: true,
67 collectives: true,
68 ignore_imports: false,
69 variables: true,
70 constants: true,
71 parser_type: TokenizerType::Raw,
72 allow_import: true,
73 }
74 }
75}
76
77#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize, Default)]
80#[cfg(feature = "compiler_utils")]
81pub struct CursorPosition(pub usize, pub usize);
82
83#[cfg(not(feature = "compiler_utils"))]
86#[derive(PartialEq, Debug, Clone, Copy, Default)]
87pub struct CursorPosition(pub usize, pub usize);
88
89impl core::fmt::Display for CursorPosition {
90 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
91 write!(f, "{}:{}", self.0, self.1)
92 }
93}
94
95impl CursorPosition {
96 pub fn is_bigger(&self, other: &CursorPosition) -> bool {
97 self.0 > other.0 || (self.0 == other.0 && self.1 > other.1)
98 }
99
100 pub fn skip_char(&mut self, n: usize) -> CursorPosition {
101 let mut clone = *self;
102 clone.1 += n;
103 clone
104 }
105
106 pub fn pop_char(&mut self, n: usize) -> CursorPosition {
107 let mut clone = *self;
108 if clone.1 != 0 {
109 clone.1 -= n;
110 }
111 clone
112 }
113
114 pub fn is_zero(&self) -> bool {
115 self.0 == 0 && self.1 == 0
116 }
117
118 pub fn increase_line(&mut self, n: usize) -> CursorPosition {
119 let mut clone = *self;
120 clone.0 += n;
121 clone
122 }
123}
124
125#[derive(PartialEq, Debug, Clone, Copy, Serialize, Deserialize, Default)]
130#[cfg(feature = "compiler_utils")]
131pub struct Cursor {
132 pub range_start: CursorPosition,
133 pub range_end: CursorPosition,
134}
135
136#[derive(PartialEq, Debug, Clone, Copy, Default)]
141#[cfg(not(feature = "compiler_utils"))]
142pub struct Cursor {
143 pub range_start: CursorPosition,
144 pub range_end: CursorPosition,
145}
146
147impl Cursor {
148 pub fn is_zero(&self) -> bool {
150 self.range_start.is_zero() && self.range_end.is_zero()
151 }
152
153 pub fn is_bigger(&self, than: Cursor) -> bool {
157 if than.range_end.0 == self.range_end.0 {
158 self.range_end.1 > than.range_end.1
159 } else {
160 than.range_end.0 <= self.range_end.0
161 }
162 }
163
164 pub fn build_with_skip_char(range_start: CursorPosition) -> Self {
168 Cursor {
169 range_start,
170 range_end: range_start.clone().skip_char(1),
171 }
172 }
173
174 pub fn build_from_cursor(range_start: CursorPosition) -> Self {
178 Cursor {
179 range_start,
180 range_end: range_start,
181 }
182 }
183
184 pub fn range_end_skip_char(&self, n: usize) -> Self {
190 self.range_end.clone().skip_char(n);
191 *self
192 }
193
194 pub fn range_start_skip_char(&self, n: usize) -> Self {
200 self.range_start.clone().skip_char(n);
201 *self
202 }
203}
204
205#[cfg(feature = "compiler_utils")]
211#[derive(Debug, Clone, Serialize, Deserialize)]
212pub struct Version {
213 pub major: usize,
214 pub minor: usize,
215 pub patch: usize,
216 pub pre_release: Option<String>,
217 pub build_metadata: Option<String>,
218}
219
220#[cfg(feature = "compiler_utils")]
221impl PartialEq for Version {
222 fn eq(&self, other: &Self) -> bool {
223 self.minor == other.minor && self.major == other.major
225 }
226}
227
228#[cfg(feature = "compiler_utils")]
229impl Version {
230 pub fn build_from_string(input: &String) -> Version {
234 let semver_regex = Regex::new(r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$").unwrap();
235 let caps = semver_regex.captures(input).unwrap();
236
237 Version {
238 major: caps
239 .name("major")
240 .unwrap()
241 .as_str()
242 .parse::<usize>()
243 .unwrap(),
244 minor: caps
245 .name("minor")
246 .unwrap()
247 .as_str()
248 .parse::<usize>()
249 .unwrap(),
250 patch: caps
251 .name("patch")
252 .unwrap()
253 .as_str()
254 .parse::<usize>()
255 .unwrap(),
256 pre_release: caps.name("prerelease").map(|x| x.as_str().to_owned()),
257 build_metadata: caps.name("buildmetadata").map(|x| x.as_str().to_owned()),
258 }
259 }
260
261 pub fn build_from_string_checked(input: &String) -> Result<Version, u8> {
267 let semver_regex = Regex::new(r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$").unwrap();
268 match semver_regex.captures(input) {
269 Some(caps) => {
270 let major = caps
271 .name("major")
272 .unwrap()
273 .as_str()
274 .parse::<usize>()
275 .unwrap_or(0);
276 let minor = caps
277 .name("minor")
278 .unwrap()
279 .as_str()
280 .parse::<usize>()
281 .unwrap_or(0);
282 let patch = caps
283 .name("patch")
284 .unwrap()
285 .as_str()
286 .parse::<usize>()
287 .unwrap_or(0);
288
289 let pre_release = caps.name("prerelease").map(|x| x.as_str().to_owned());
290 let build_metadata = caps.name("buildmetadata").map(|x| x.as_str().to_owned());
291
292 if major == 0 && minor == 0 && patch == 0 {
293 Err(1)
294 } else {
295 Ok(Version {
296 minor,
297 major,
298 patch,
299 pre_release,
300 build_metadata,
301 })
302 }
303 }
304 None => Err(1),
305 }
306 }
307
308 pub fn to_string(&self) -> String {
309 format!(
310 "{}.{}.{}{}{}",
311 self.major,
312 self.minor,
313 self.patch,
314 if let Some(ref pre_release) = self.pre_release {
315 format!("-{}", pre_release)
316 } else {
317 "".to_owned()
318 },
319 if let Some(ref build_metadata) = self.build_metadata {
320 format!("+{}", build_metadata)
321 } else {
322 "".to_owned()
323 }
324 )
325 }
326}
327
328#[derive(Clone, Debug, PartialEq, Copy)]
329pub enum PlatformArchitecture {
330 B16,
331 B32,
332 B64,
333}
334
335impl Display for PlatformArchitecture {
336 fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
337 match self {
338 PlatformArchitecture::B16 => write!(f, "b16"),
339 PlatformArchitecture::B32 => write!(f, "b32"),
340 PlatformArchitecture::B64 => write!(f, "b64"),
341 }
342 }
343}
344
345impl PlatformArchitecture {
346 pub fn is_16(&self) -> bool {
347 match self {
348 PlatformArchitecture::B16 => true,
349 _ => false,
350 }
351 }
352
353 pub fn is_32(&self) -> bool {
354 match self {
355 PlatformArchitecture::B32 => true,
356 _ => false,
357 }
358 }
359
360 pub fn get_code(&self) -> u8 {
361 match self {
362 PlatformArchitecture::B16 => 16,
363 PlatformArchitecture::B32 => 32,
364 PlatformArchitecture::B64 => 64,
365 }
366 }
367
368 pub fn type_id_size(&self) -> u8 {
369 match self {
370 PlatformArchitecture::B16 => 3,
371 PlatformArchitecture::B32 => 5,
372 PlatformArchitecture::B64 => 9,
373 }
374 }
375
376 pub fn usize_len(&self) -> u8 {
377 match self {
378 PlatformArchitecture::B16 => 2,
379 PlatformArchitecture::B32 => 4,
380 PlatformArchitecture::B64 => 8,
381 }
382 }
383
384 pub fn from_byte(byte: u8) -> Option<PlatformArchitecture> {
385 match byte {
386 16 => Some(PlatformArchitecture::B16),
387 32 => Some(PlatformArchitecture::B32),
388 64 => Some(PlatformArchitecture::B64),
389 _ => None,
390 }
391 }
392}
393
394#[derive(Clone, Debug, PartialEq)]
395pub enum DebugHeaderType {
396 Variable,
397 SetterCall,
398 GetterCall,
399 Class,
400 Parameter,
401 Function,
402 NativeFunction,
403 Condition,
404}
405
406#[derive(Clone, Debug)]
407pub struct DebugHeader {
408 pub rtype: DebugHeaderType,
410 pub hash: usize,
412 pub module_name: String,
414 pub module_hash: usize,
416 pub name: String,
418 pub start_end: (usize, usize),
420 pub pos: Cursor,
422}
423
424#[derive(Debug, Clone)]
425pub struct ModuleMap {
426 pub module_name: String,
427 pub module_hash: usize,
428 pub module_path: Option<String>,
429}
430
431#[derive(Debug, Clone)]
432pub struct NativeCallTrace {
433 pub module_name: String,
434 pub function_hash: usize,
435 pub function_name: String,
436}
437
438#[derive(Debug, Clone)]
439pub struct DebugInfo {
440 pub module_map: Vec<ModuleMap>,
441 pub debug_headers: Vec<DebugHeader>,
442}