forked from MightyPork/crsn
Simplify {clz,clo,se}XX parsing and exec, add simple unit test example scripts
This commit is contained in:
@@ -41,7 +41,7 @@ pub enum LdsValue {
|
||||
Chars(String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct BitSlice {
|
||||
pub width: u32,
|
||||
pub src_pos: u32,
|
||||
@@ -80,7 +80,50 @@ impl BitSlice {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Parse LEN (no SRC and DST)
|
||||
pub fn parse1(src: &str, pos: &SourcePosition) -> Result<Option<Self>, CrsnError> {
|
||||
match Self::parse(src, pos) {
|
||||
Ok(Some(slice)) => {
|
||||
if slice.src_pos != 0 || slice.dst_pos != 0 {
|
||||
return Err(CrsnError::Parse("Excess bit slice modifiers".into(), pos.clone()));
|
||||
}
|
||||
|
||||
Ok(Some(BitSlice {
|
||||
width: slice.width,
|
||||
src_pos: 0,
|
||||
dst_pos: 0
|
||||
}))
|
||||
}
|
||||
other => other
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse LEN/SRC
|
||||
pub fn parse2(src: &str, pos: &SourcePosition) -> Result<Option<Self>, CrsnError> {
|
||||
match Self::parse(src, pos) {
|
||||
Ok(Some(slice)) => {
|
||||
if slice.src_pos != 0 {
|
||||
return Err(CrsnError::Parse("Excess bit slice modifiers".into(), pos.clone()));
|
||||
}
|
||||
|
||||
Ok(Some(BitSlice {
|
||||
width: slice.width,
|
||||
src_pos: slice.dst_pos,
|
||||
dst_pos: 0
|
||||
}))
|
||||
}
|
||||
other => other
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a bit slice LEN/DST/SRC
|
||||
/// - String not starting with a digit is rejected as `Ok(None)`
|
||||
/// - Empty string is parsed as a full slice
|
||||
pub fn parse(src: &str, pos: &SourcePosition) -> Result<Option<Self>, CrsnError> {
|
||||
if src.is_empty() {
|
||||
return Ok(Some(BitSlice::full()));
|
||||
}
|
||||
|
||||
if !src.starts_with(|c: char| c.is_ascii_digit()) {
|
||||
return Ok(None);
|
||||
}
|
||||
@@ -97,6 +140,10 @@ impl BitSlice {
|
||||
dst_pos: numbers.get(1).copied().unwrap_or(0)
|
||||
};
|
||||
|
||||
if slice.width == 0 || slice.width > 64 {
|
||||
return Err(CrsnError::Parse("Bit slice width must be 1-64".into(), pos.clone()));
|
||||
}
|
||||
|
||||
// Validation
|
||||
if slice.src_pos + slice.width > 64 {
|
||||
return Err(CrsnError::Parse("Invalid source bit slice".into(), pos.clone()));
|
||||
|
||||
Reference in New Issue
Block a user