summaryrefslogtreecommitdiff
path: root/src/parsers/packed_binary_literal.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parsers/packed_binary_literal.rs')
-rw-r--r--src/parsers/packed_binary_literal.rs43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/parsers/packed_binary_literal.rs b/src/parsers/packed_binary_literal.rs
index 9704fc4..18f8da7 100644
--- a/src/parsers/packed_binary_literal.rs
+++ b/src/parsers/packed_binary_literal.rs
@@ -1,53 +1,54 @@
use crate::*;
-pub fn parse_packed_binary_literal(string: &str, parent: &Tokeniser) -> PackedBinaryLiteral {
+/// t is a Tokeniser over the characters of the PBL, excluding the leading hash.
+pub fn parse_packed_binary_literal(mut t: Tokeniser, source: SourceSpan) -> PackedBinaryLiteral {
use PackedBinaryLiteralParseError as ParseError;
use PackedBinaryLiteralParseErrorVariant as ParseErrorVar;
let mut value = 0;
let mut bits = 0;
+ let mut field_bits = 0;
let mut name = '\0';
let mut fields: Vec<BitField> = Vec::new();
let mut errors: Vec<ParseError> = Vec::new();
macro_rules! push_field {
- ($source:expr) => {
+ () => {
if fields.iter().any(|f| f.name == name) {
let variant = ParseErrorVar::DuplicateFieldName(name);
- errors.push(ParseError { source: $source, variant });
+ errors.push(ParseError { source: t.get_source(), variant });
} else {
- fields.push(BitField { name, source: $source, bits, shift: 0 });
+ fields.push(BitField { name, source: t.get_source(), bits: field_bits, shift: 0 });
}
};
}
- let mut t = Tokeniser::new_child(string, parent);
- t.position.to_next_char(); // skip opening hash character
-
while let Some(c) = t.eat_char() {
// Ignore underscores.
if c == '_' {
- t.prev_position = t.prev_prev_position;
+ t.mark.undo();
continue;
}
// Add a bit to the value;
value <<= 1;
+ bits += 1;
for field in &mut fields {
field.shift += 1;
}
// Extend the current field.
if c == name {
- bits += 1;
+ field_bits += 1;
continue;
}
// Commit the current field.
- if bits > 0 {
- push_field!(t.mark_prev_end_position());
- bits = 0;
+ if field_bits > 0 {
+ t.mark_end_prev();
+ push_field!();
+ field_bits = 0;
name = '\0';
}
@@ -60,21 +61,25 @@ pub fn parse_packed_binary_literal(string: &str, parent: &Tokeniser) -> PackedBi
continue;
}
- t.mark_prev_start_position();
+ t.mark_start_prev();
if c.is_alphabetic() {
name = c;
- bits = 1;
+ field_bits = 1;
continue;
} else {
- let source = t.mark_end_position();
- errors.push(ParseError { source, variant: ParseErrorVar::InvalidCharacter(c) });
+ let source = t.get_source();
+ let variant = ParseErrorVar::InvalidCharacter(c);
+ errors.push(ParseError { source, variant });
}
}
// Commit the final field.
- if bits > 0 {
- push_field!(t.mark_end_position());
+ for field in &mut fields {
+ field.shift += 1;
+ }
+ if field_bits > 0 {
+ push_field!();
}
- PackedBinaryLiteral { value, fields, errors }
+ PackedBinaryLiteral { source, bits, value, fields, errors }
}