From 2b4e522b12a7eb87e91cd1cdc56064ee429a5212 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Tue, 11 Feb 2025 14:00:20 +1300 Subject: Initial commit --- src/tokens/packed_binary_literal.rs | 60 +++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/tokens/packed_binary_literal.rs (limited to 'src/tokens/packed_binary_literal.rs') diff --git a/src/tokens/packed_binary_literal.rs b/src/tokens/packed_binary_literal.rs new file mode 100644 index 0000000..1252398 --- /dev/null +++ b/src/tokens/packed_binary_literal.rs @@ -0,0 +1,60 @@ +use crate::*; + + +pub struct PackedBinaryLiteral { + pub value: usize, + pub fields: Vec, + pub errors: Vec, +} + +impl PackedBinaryLiteral { + pub fn from_str(string: &str, parent: &Tokeniser) -> Self { + parse_packed_binary_literal(string, parent) + } +} + +pub struct BitField { + pub name: char, + pub source: SourceSpan, + /// Length of field in bits + pub bits: usize, + /// Distance to left-shift field in value + pub shift: usize, +} + +pub struct PackedBinaryLiteralParseError { + pub source: SourceSpan, + pub variant: PackedBinaryLiteralParseErrorVariant, +} + +pub enum PackedBinaryLiteralParseErrorVariant { + DuplicateFieldName(char), + InvalidCharacter(char), +} + + +impl std::fmt::Display for PackedBinaryLiteral { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + if self.value == 0 { + write!(f, "0")?; + } else { + let bitcount = (self.value.ilog2() + 1) as usize; + 'bit: for i in (0..bitcount).rev() { + if (i+1) % 4 == 0 { + write!(f, "_")?; + } + for field in &self.fields { + if i <= field.bits + field.shift - 1 && i >= field.shift { + write!(f, "{}", field.name)?; + continue 'bit; + } + } + match (self.value >> i) & 1 { + 0 => write!(f, "0")?, + _ => write!(f, "1")?, + } + } + } + return Ok(()); + } +} -- cgit v1.2.3-70-g09d2