diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-10-14 21:33:30 +1300 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-10-14 21:33:42 +1300 |
commit | d9e0c4895608cdcb04b868222b49b3f117766ed0 (patch) | |
tree | 57d240b331ced3f4704799a6337c1e90c5c17b42 /src/stages/bytecode.rs | |
parent | 981bb70e5077bd30ef85a0092117a875dcc614fc (diff) | |
download | torque-asm-d9e0c4895608cdcb04b868222b49b3f117766ed0.zip |
Implement new bytecode stage
This completes the Torque version 3 rewrite, other than some extensive
testing that is yet to be done.
Diffstat (limited to 'src/stages/bytecode.rs')
-rw-r--r-- | src/stages/bytecode.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/stages/bytecode.rs b/src/stages/bytecode.rs new file mode 100644 index 0000000..2d73767 --- /dev/null +++ b/src/stages/bytecode.rs @@ -0,0 +1,47 @@ +use crate::*; + + +pub fn parse_bytecode(intermediate: Vec<Tracked<IntermediateToken>>, width: Option<u32>) -> Result<Vec<Segment>, Vec<Tracked<BytecodeError>>> { + let mut segments = Vec::new(); + let mut errors = Vec::new(); + let mut current_segment = Vec::new(); + let mut segment_source = None; + let mut segment_address = 0; + + + for token in intermediate { + match token.value { + IntermediateToken::Word(word) => { + if let Some(width) = width { + if word.width != width { + let error = BytecodeError::IncorrectWidth(width, word.width); + errors.push(Tracked::from(error, token.source.clone())); + } + } + let source = token.source.clone(); + current_segment.push(Tracked::from(word, source)); + } + IntermediateToken::PinnedAddress(pinned_address) => { + if !current_segment.is_empty() { + let address = segment_address; + let words = std::mem::take(&mut current_segment); + let source = std::mem::take(&mut segment_source); + segments.push(Segment { address, source, words }); + segment_address = pinned_address; + } + } + } + } + // Finish final segment. + if !current_segment.is_empty() { + let address = segment_address; + let words = std::mem::take(&mut current_segment); + let source = std::mem::take(&mut segment_source); + segments.push(Segment { address, source, words }); + } + + match errors.is_empty() { + true => Ok(segments), + false => Err(errors), + } +} |