Simplify {clz,clo,se}XX parsing and exec, add simple unit test example scripts

This commit is contained in:
2020-10-16 00:18:38 +02:00
parent 768f36ae18
commit 26616e20cb
14 changed files with 233 additions and 376 deletions
+48 -1
View File
@@ -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()));