diff options
| author | Miquel Sabaté Solà <mssola@mssola.com> | 2026-08-18 16:39:37 +0200 |
|---|---|---|
| committer | Miquel Sabaté Solà <mssola@mssola.com> | 2026-08-18 16:39:37 +0200 |
| commit | fcd4c9a267b407e653ed6b21ae87f219f3e4c4af (patch) | |
| tree | 0b5f3e9bf99ab7377fa0bb6d204661ac8fbe3380 /lib/xixanta/src/assembler.rs | |
| parent | d479b0fbd3778f5b6fc8b63f46aa0c5364e4fe7e (diff) | |
| download | tools.nes-fcd4c9a267b407e653ed6b21ae87f219f3e4c4af.tar.gz tools.nes-fcd4c9a267b407e653ed6b21ae87f219f3e4c4af.zip | |
Add global labels
These are labels that are declared by prefixing a '#' symbol to the
name, and it allows the label to be declared at the global scope instead
of the current one.
This is a feature which is not to be abused so to not make scopes
pointless, but it can be quite handy with some optimizations while not
abandoning scopes completely.
Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
Diffstat (limited to 'lib/xixanta/src/assembler.rs')
| -rw-r--r-- | lib/xixanta/src/assembler.rs | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs index 91f1e14..3cf1e0b 100644 --- a/lib/xixanta/src/assembler.rs +++ b/lib/xixanta/src/assembler.rs @@ -523,7 +523,10 @@ impl<'a> Assembler<'a> { accessed: 1, }; - if let Err(err) = self.context.set_variable(&var_name, &var_value, false) { + if let Err(err) = self + .context + .set_variable(&var_name, &var_value, false, false) + { Err(Error { global: true, line: 0, @@ -557,6 +560,7 @@ impl<'a> Assembler<'a> { accessed: 0, }, false, + matches!(node.node_type, NodeType::Label(true)), ) { return Err(Error { message, @@ -585,7 +589,7 @@ impl<'a> Assembler<'a> { // context so it's known. The actual value cannot be computed // right now as we don't know the segment size where it belongs // yet. - NodeType::Label => { + NodeType::Label(_) => { // There's no good reason to declare a named label inside of // a macro. If that's the case, just error out. if (self.macros_seen > 0 || self.repeats_seen > 0) && !node.value.is_empty() { @@ -689,6 +693,7 @@ impl<'a> Assembler<'a> { accessed: 0, }, false, + false, ) { errors.push(Error { message: err, @@ -909,7 +914,12 @@ impl<'a> Assembler<'a> { }; if !node.value.is_empty() - && let Err(message) = self.context.set_variable(&node.value, &object, true) + && let Err(message) = self.context.set_variable( + &node.value, + &object, + true, + matches!(node.node_type, NodeType::Label(true)), + ) { return Err(Error { message, @@ -938,7 +948,7 @@ impl<'a> Assembler<'a> { // segment. Note that this is only the offset from the beginning // of the offset, the effective address will only be available // after calling `Context::get_variable` - NodeType::Label => { + NodeType::Label(_) => { if let Err(e) = self.apply_segment_offset_to_label(node, ObjectType::Address) { errors.push(e); } @@ -1150,11 +1160,16 @@ impl<'a> Assembler<'a> { // value. let mut dobj = d.obj.clone(); dobj.bundle = o; - self.context.set_variable(&d.id, &dobj, true) + self.context.set_variable( + &d.id, + &dobj, + true, + matches!(n.node_type, NodeType::Label(true)), + ) } // No attached node, we can proceed by setting the // variable as is. - None => self.context.set_variable(&d.id, &d.obj, true), + None => self.context.set_variable(&d.id, &d.obj, true, false), }; } } @@ -1714,7 +1729,7 @@ impl<'a> Assembler<'a> { // calls, just in case a macro is applied multiple times and we // need to get the latest value. let id = &margs.next().unwrap().value; - if let Err(message) = self.context.set_variable(id, &obj, true) { + if let Err(message) = self.context.set_variable(id, &obj, true, false) { return Err(Error { line: node.value.line, message, @@ -2618,6 +2633,7 @@ impl<'a> Assembler<'a> { accessed: 0, }, true, + false, ) { return Err(Error { @@ -3099,7 +3115,12 @@ impl<'a> Assembler<'a> { // again. If the variable could not be set, then it's not // that big of a deal at this stage. value.bundle = bundle.clone(); - let _ = self.context.set_variable(&node.value, &value, true); + let _ = self.context.set_variable( + &node.value, + &value, + true, + matches!(node.node_type, NodeType::Label(true)), + ); // And return the computed bundle. Ok(bundle) |
