futilehdl/src/literals.rs

48 lines
1.1 KiB
Rust

use std::ops::{RangeFrom, RangeTo};
use nom::{
character::complete::{char, one_of},
combinator::{map_res, recognize},
multi::{many0, many1},
sequence::{preceded, terminated},
AsChar, FindToken, InputIter, InputLength, Offset, Slice
};
use crate::parser::IResult;
pub fn hexadecimal<'a, I>(input: I) -> IResult<I, u64>
where
// TODO: ask if there is any way to avoid this hellish constraint
I: InputIter
+ nom::Slice<RangeFrom<usize>>
+ InputLength
+ Clone
+ Offset
+ Into<&'a str>
+ Slice<RangeTo<usize>>,
<I as InputIter>::Item: AsChar + Copy,
&'a str: FindToken<<I as InputIter>::Item>
{
map_res(
preceded(
char('h'),
recognize(many1(terminated(
one_of("0123456789abcdefABCDEF"),
many0(char('_')),
))),
),
|out: I| u64::from_str_radix(&str::replace(&out.into(), "_", ""), 16),
)(input)
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_hex() {
assert_eq!(hexadecimal("hfF").unwrap().1, 0xff);
assert_eq!(hexadecimal("hF").unwrap().1, 0xf);
}
}