diff options
author | Ben Bridle <ben@derelict.engineering> | 2025-04-26 14:44:50 +1200 |
---|---|---|
committer | Ben Bridle <ben@derelict.engineering> | 2025-04-26 14:45:05 +1200 |
commit | 50592a5184e701dd09eee024bb773ec57c1cd6bf (patch) | |
tree | f5fa0bb446fe34243fb9963070ceba85d89b4277 /src/stages/intermediate.rs | |
parent | e5447e2568e24db9a5218bbe452b856266ca39ae (diff) | |
download | torque-asm-50592a5184e701dd09eee024bb773ec57c1cd6bf.zip |
Allow label references in pinned address calculations
This is a relaxation of the rule where a label reference could not
be used in any context that could change the length of an assembled
program.
We implement this in the bytecode stage by naively calculating an
initial address for each label as before. If a pinned address is
calculated from a label reference, some of the calculated addresses
could be incorrect. We then attempt to run the bytecode stage, which
will calculate a more accurate address for each label based on how
pinned addresses are calculated. If the address of any label was
changed by running this stage, we re-run the stage up to three more
times until all labels stabilise. If the labels fail to stabilise, we
return an error.
Diffstat (limited to 'src/stages/intermediate.rs')
-rw-r--r-- | src/stages/intermediate.rs | 17 |
1 files changed, 2 insertions, 15 deletions
diff --git a/src/stages/intermediate.rs b/src/stages/intermediate.rs index c4bb74d..cfe33b7 100644 --- a/src/stages/intermediate.rs +++ b/src/stages/intermediate.rs @@ -197,21 +197,8 @@ impl<'a> Environment<'a> { } BlockToken::PinnedAddress(address) => { if let Some(integer) = self.parse_integer_token(address, &address.source) { - if let Some(source) = integer_contains_label_reference(&integer) { - let error = IntermediateError::LabelReferenceInPinnedAddress; - let new_source = address.source.clone().wrap(source); - self.errors.push(Tracked::from(error, new_source)); - } else { - match evaluate_integer(&integer, source) { - Ok(value) => { - let value = usize::try_from(value).unwrap_or(0); - let tracked = Tracked::from(value, address.source.clone()); - let token = IntermediateToken::PinnedAddress(tracked); - intermediate.push(Tracked::from(token, source.clone())); - } - Err(error) => self.errors.push(error), - } - } + let token = IntermediateToken::PinnedAddress(integer); + intermediate.push(Tracked::from(token, source.clone())); } } BlockToken::ConditionalBlock(cond) => { |