ppc750cl_asm/
types.rs

1use crate::Arguments;
2use core::fmt::Formatter;
3
4#[derive(Debug)]
5pub enum ArgumentError {
6    ArgOutOfRangeUnsigned { index: usize, value: u32, start: u32, end: u32 },
7    ArgOutOfRangeSigned { index: usize, value: i32, start: i32, end: i32 },
8    ArgCount { value: usize, expected: usize },
9    UnknownMnemonic,
10}
11
12impl core::fmt::Display for ArgumentError {
13    fn fmt(&self, _f: &mut Formatter<'_>) -> core::fmt::Result {
14        todo!()
15    }
16}
17
18#[cfg(feature = "std")]
19impl std::error::Error for ArgumentError {}
20
21#[derive(Debug, Default, Clone, Copy, Eq, PartialEq)]
22pub enum Argument {
23    #[default]
24    None,
25    Unsigned(u32),
26    Signed(i32),
27}
28
29pub const fn parse_unsigned(
30    args: &Arguments,
31    index: usize,
32    start: u32,
33    end: u32,
34) -> Result<u32, ArgumentError> {
35    match args[index] {
36        Argument::Unsigned(value) => {
37            if value >= start && value <= end {
38                Ok(value)
39            } else {
40                Err(ArgumentError::ArgOutOfRangeUnsigned { index, value, start, end })
41            }
42        }
43        Argument::Signed(value) => {
44            if value >= start as i32 && value <= end as i32 {
45                Ok(value as u32)
46            } else {
47                Err(ArgumentError::ArgOutOfRangeUnsigned { index, value: value as u32, start, end })
48            }
49        }
50        Argument::None => Err(ArgumentError::ArgCount { value: index, expected: index + 1 }),
51    }
52}
53
54pub const fn parse_signed(
55    args: &Arguments,
56    index: usize,
57    start: i32,
58    end: i32,
59) -> Result<i32, ArgumentError> {
60    match args[index] {
61        Argument::Unsigned(value) => {
62            if (start < 0 || value >= start as u32) && value <= end as u32 {
63                Ok(value as i32)
64            } else {
65                Err(ArgumentError::ArgOutOfRangeSigned { index, value: value as i32, start, end })
66            }
67        }
68        Argument::Signed(value) => {
69            if value >= start && value <= end {
70                Ok(value)
71            } else {
72                Err(ArgumentError::ArgOutOfRangeSigned { index, value, start, end })
73            }
74        }
75        Argument::None => Err(ArgumentError::ArgCount { value: index, expected: index + 1 }),
76    }
77}
78
79pub const fn arg_count(args: &Arguments) -> usize {
80    let mut i = 0;
81    while i < args.len() && !matches!(args[i], Argument::None) {
82        i += 1;
83    }
84    i
85}
86
87pub const fn check_arg_count(args: &Arguments, expected: usize) -> Result<(), ArgumentError> {
88    let value = arg_count(args);
89    if value == expected {
90        Ok(())
91    } else {
92        Err(ArgumentError::ArgCount { value, expected })
93    }
94}