Skip to content

Commit 8917ae3

Browse files
authored
Allow underscores in decimal bit strings (#333)
1 parent 8f7c103 commit 8917ae3

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

vhdl_lang/src/analysis/static_expression.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fn byte_is_odd_decimal(byte: u8) -> bool {
1313

1414
/// Converts a decimal string (i.e. "123") to a binary string (i.e. "1111011").
1515
///
16-
/// When there are illegal characters in the string (i.e. non decimal characters),
16+
/// When there are illegal characters in the string (i.e. non-decimal characters),
1717
/// returns an `Err` with the position of the first character.
1818
///
1919
/// # Special cases
@@ -22,7 +22,7 @@ fn byte_is_odd_decimal(byte: u8) -> bool {
2222
/// - For a string that is padded with zeros, return a string without the padding. If the
2323
/// String without the padding is empty, rule 1 applies.
2424
pub(crate) fn decimal_str_to_binary_str(
25-
value: &Latin1String,
25+
value: &[u8],
2626
) -> Result<Latin1String, BitStringConversionError> {
2727
/// Divides `value` by two where `value` is a vector of u8's representing decimals.
2828
/// Returns an empty string when `value` is zero
@@ -44,16 +44,11 @@ pub(crate) fn decimal_str_to_binary_str(
4444
new_s
4545
}
4646

47-
if let Some(idx) = value.bytes.iter().position(|b| *b < b'0' || *b > b'9') {
47+
if let Some(idx) = value.iter().position(|b| *b < b'0' || *b > b'9') {
4848
return Err(BitStringConversionError::IllegalDecimalCharacter(idx));
4949
}
5050

51-
let mut num: Vec<u8> = value
52-
.bytes
53-
.clone()
54-
.into_iter()
55-
.skip_while(|el| *el == b'0')
56-
.collect();
51+
let mut num: Vec<u8> = value.iter().copied().skip_while(|el| *el == b'0').collect();
5752

5853
if num.is_empty() {
5954
return Ok(Latin1String::new(b"0"));
@@ -91,7 +86,7 @@ fn test_decimal_to_binary() {
9186

9287
for (dec, bin) in test_cases {
9388
assert_eq!(
94-
decimal_str_to_binary_str(&Latin1String::from_utf8_unchecked(dec)),
89+
decimal_str_to_binary_str(dec.as_bytes()),
9590
Ok(Latin1String::from_utf8_unchecked(bin))
9691
);
9792
}
@@ -234,7 +229,7 @@ pub(crate) fn bit_string_to_string(
234229
let mut extended_value = Vec::new();
235230

236231
if bit_string.base == BaseSpecifier::D {
237-
match decimal_str_to_binary_str(&bit_string.value) {
232+
match decimal_str_to_binary_str(&simplified_value) {
238233
Err(e) => return Err(e),
239234
Ok(binary_string) => extended_value = binary_string.bytes,
240235
}
@@ -247,8 +242,8 @@ pub(crate) fn bit_string_to_string(
247242
// append, truncate or leave the bit-string dependent on the user-specified length
248243
match bit_string.length {
249244
None => Ok(Latin1String::from_vec(extended_value)),
250-
Some(_length) => {
251-
let length = _length as usize;
245+
Some(length) => {
246+
let length = length as usize;
252247
match length.cmp(&extended_value.len()) {
253248
Ordering::Equal => Ok(Latin1String::from_vec(extended_value)),
254249
Ordering::Less => {
@@ -474,4 +469,13 @@ mod test_mod {
474469
)
475470
}
476471
}
472+
473+
// Issue 332
474+
#[test]
475+
fn underscore_in_decimal_bit_string() {
476+
assert!(
477+
bit_string_to_string(&BitString::new(Some(32), BaseSpecifier::D, "1_000_000_000"))
478+
.is_ok()
479+
);
480+
}
477481
}

0 commit comments

Comments
 (0)