diff options
Diffstat (limited to 'src/formats/mod.rs')
-rw-r--r-- | src/formats/mod.rs | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/formats/mod.rs b/src/formats/mod.rs index 82f19f1..132001a 100644 --- a/src/formats/mod.rs +++ b/src/formats/mod.rs @@ -1,8 +1,78 @@ mod inhx; mod inhx32; +mod raw; +mod debug; pub use inhx::*; pub use inhx32::*; +pub use raw::*; +pub use debug::*; + +use crate::*; + +use log::*; + + +#[derive(Clone, Copy, PartialEq)] +pub enum Format { + Debug, + Inhx, + Inhx32, + Raw, + Source, +} + +impl Format { + pub fn from_str(string: &str) -> Self { + match string { + "debug" => Self::Debug, + "inhx" => Self::Inhx, + "inhx32" => Self::Inhx32, + "raw" => Self::Raw, + "source" => Self::Source, + _ => fatal!("Unknown format '{string}', expected 'debug', 'inhx', 'inhx32', 'raw', or 'source'. "), + } + } +} + +impl std::fmt::Display for Format { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + let string = match self { + Self::Debug => "debug", + Self::Inhx => "inhx", + Self::Inhx32 => "inhx32", + Self::Raw => "raw", + Self::Source => "source", + }; + write!(f, "{string}") + } +} + + +pub enum FormatError { + /// (expected, received) + AddressTooLarge(usize, usize), + /// (expected, received) + WordTooWide(u32, u32, SourceSpan), + /// + ExpectedFixedWidth, +} + +pub fn report_format_error(error: &FormatError, format: Format, source_code: &str) { + match error { + FormatError::AddressTooLarge(expected, received) => + error!("The {format} format requires that addresses do not exceed {expected}, but the address {received} was reached"), + FormatError::WordTooWide(expected, received, source) => { + let message = format!("The {format} format requires that words are no wider than {expected} bits, but a {received} bit word was found"); + let context = Context { source_code, source }; + report_source_issue(LogLevel::Error, &context, &message); + } + FormatError::ExpectedFixedWidth => + error!("The {format} format requires all words to be the same width"), + } + std::process::exit(1); +} + pub struct InhxRecord { @@ -43,3 +113,20 @@ impl InhxRecord { format!(":{output}{checksum:0>2X}\n") } } + + +pub fn calculate_fixed_width(segments: &[Segment]) -> Option<u32> { + let mut width = None; + for segment in segments { + for word in &segment.words { + let word_width = word.value.width; + match width { + Some(width) => if word_width != width { + return None; + } + None => width = Some(word_width), + } + } + } + return width.or(Some(0)); +} |