From 1ecee352f5844b0809d7ae66df52e34f42b44c8e Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Thu, 6 Mar 2025 20:33:27 +1300 Subject: Rewrite entire assembler The language is now more general, the code is better structured, error reporting is more detailed, and many new language features have been implemented: - conditional blocks - first-class strings - more expression operators - binary literals - negative values - invocations in constant expressions --- src/formats/inhx.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'src/formats/inhx.rs') diff --git a/src/formats/inhx.rs b/src/formats/inhx.rs index e83e870..fc4791b 100644 --- a/src/formats/inhx.rs +++ b/src/formats/inhx.rs @@ -1,10 +1,15 @@ use crate::*; -pub fn format_inhx(words: &[Word]) -> String { +pub fn format_inhx(segments: &[Segment]) -> Result, FormatError> { let mut records = Vec::new(); - for (i, chunk) in words.chunks(16).enumerate() { - records.push(data_record(chunk, (i * 16) as u16)); + let mut address; + for segment in segments { + address = segment.address; + for chunk in segment.words.chunks(16) { + records.push(data_record(chunk, address)?); + address += 16; + } } records.push(terminating_record()); @@ -12,21 +17,24 @@ pub fn format_inhx(words: &[Word]) -> String { for record in records { output.push_str(&record.to_string()); } - return output; + return Ok(output.as_bytes().to_vec()); } -fn data_record(words: &[Word], address: u16) -> InhxRecord { +fn data_record(words: &[Tracked], address: usize) -> Result { + let Ok(address) = u16::try_from(address) else { + return Err(FormatError::AddressTooLarge(u16::MAX as usize, address)); + }; let mut record = InhxRecord::new(); record.byte((words.len()) as u8); record.be_double(address); record.byte(0x00); for word in words { - match word.bits <= 8 { - true => record.byte(word.value as u8), - false => panic!("Word '{word}' has more than 8 bits."), - }; + if word.value.width > 8 { + return Err(FormatError::WordTooWide(8, word.width, word.source.clone())); + } + record.byte(word.value.value as u8); } - return record; + return Ok(record); } fn terminating_record() -> InhxRecord { -- cgit v1.2.3-70-g09d2