summaryrefslogtreecommitdiff
path: root/src/formats/inhx.rs
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-03-06 20:33:27 +1300
committerBen Bridle <ben@derelict.engineering>2025-03-11 16:59:26 +1300
commit1ecee352f5844b0809d7ae66df52e34f42b44c8e (patch)
tree472b6fd57ff7f64ac3f8cd676cbe7a113ba01f05 /src/formats/inhx.rs
parentf2ed89083f5326a7a6f0a1720033d3388aa431fb (diff)
downloadtorque-asm-1ecee352f5844b0809d7ae66df52e34f42b44c8e.zip
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
Diffstat (limited to 'src/formats/inhx.rs')
-rw-r--r--src/formats/inhx.rs28
1 files changed, 18 insertions, 10 deletions
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<Vec<u8>, 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<Word>], address: usize) -> Result<InhxRecord, FormatError> {
+ 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 {