blob: d4e729b0f810e148907ce3bf9f541adbf9b0b2d4 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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),
}
}
|