diff options
Diffstat (limited to 'src/parsers/packed_binary_literal.rs')
-rw-r--r-- | src/parsers/packed_binary_literal.rs | 43 |
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 } } |