Add support for multiple integer types.
This commit is contained in:
@@ -66,7 +66,7 @@ pub enum Token {
|
||||
#[regex(r"0d[0-9]+(u8|i8|u16|i16|u32|i32|u64|i64)?", |v| parse_number(Some(10), v))]
|
||||
#[regex(r"0x[0-9a-fA-F]+(u8|i8|u16|i16|u32|i32|u64|i64)?", |v| parse_number(Some(16), v))]
|
||||
#[regex(r"[0-9]+(u8|i8|u16|i16|u32|i32|u64|i64)?", |v| parse_number(None, v))]
|
||||
Number((Option<u8>, Option<ConstantType>, i64)),
|
||||
Number((Option<u8>, Option<ConstantType>, u64)),
|
||||
|
||||
// Variables; this is a very standard, simple set of characters
|
||||
// for variables, but feel free to experiment with more complicated
|
||||
@@ -143,16 +143,59 @@ impl Token {
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(i64)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ConstantType {
|
||||
U8,
|
||||
U16,
|
||||
U32,
|
||||
U64,
|
||||
I8,
|
||||
I16,
|
||||
I32,
|
||||
I64,
|
||||
U8 = 10,
|
||||
U16 = 11,
|
||||
U32 = 12,
|
||||
U64 = 13,
|
||||
I8 = 20,
|
||||
I16 = 21,
|
||||
I32 = 22,
|
||||
I64 = 23,
|
||||
}
|
||||
|
||||
impl From<ConstantType> for cranelift_codegen::ir::Type {
|
||||
fn from(value: ConstantType) -> Self {
|
||||
match value {
|
||||
ConstantType::I8 | ConstantType::U8 => cranelift_codegen::ir::types::I8,
|
||||
ConstantType::I16 | ConstantType::U16 => cranelift_codegen::ir::types::I16,
|
||||
ConstantType::I32 | ConstantType::U32 => cranelift_codegen::ir::types::I32,
|
||||
ConstantType::I64 | ConstantType::U64 => cranelift_codegen::ir::types::I64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ConstantType {
|
||||
/// Returns true if the given type is (a) numeric and (b) signed;
|
||||
pub fn is_signed(&self) -> bool {
|
||||
matches!(self, ConstantType::I8 | ConstantType::I16 | ConstantType::I32 | ConstantType::I64)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, PartialEq)]
|
||||
pub enum InvalidConstantType {
|
||||
#[error("Unrecognized constant {0} for constant type")]
|
||||
Value(i64),
|
||||
}
|
||||
|
||||
impl TryFrom<i64> for ConstantType {
|
||||
type Error = InvalidConstantType;
|
||||
|
||||
fn try_from(value: i64) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
10 => Ok(ConstantType::U8),
|
||||
11 => Ok(ConstantType::U16),
|
||||
12 => Ok(ConstantType::U32),
|
||||
13 => Ok(ConstantType::U64),
|
||||
20 => Ok(ConstantType::I8),
|
||||
21 => Ok(ConstantType::I16),
|
||||
22 => Ok(ConstantType::I32),
|
||||
23 => Ok(ConstantType::I64),
|
||||
_ => Err(InvalidConstantType::Value(value)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a number in the given base, return a pair of the base and the
|
||||
@@ -162,7 +205,7 @@ pub enum ConstantType {
|
||||
fn parse_number(
|
||||
base: Option<u8>,
|
||||
value: &Lexer<Token>,
|
||||
) -> Result<(Option<u8>, Option<ConstantType>, i64), ParseIntError> {
|
||||
) -> Result<(Option<u8>, Option<ConstantType>, u64), ParseIntError> {
|
||||
let (radix, strval) = match base {
|
||||
None => (10, value.slice()),
|
||||
Some(radix) => (radix, &value.slice()[2..]),
|
||||
@@ -188,7 +231,7 @@ fn parse_number(
|
||||
(None, strval)
|
||||
};
|
||||
|
||||
let intval = i64::from_str_radix(strval, radix as u32)?;
|
||||
let intval = u64::from_str_radix(strval, radix as u32)?;
|
||||
Ok((base, declared_type, intval))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user