Use section numbers when resolving local labels
This changes the semantics of local labels. Previously, local labels were just shorthand for writing out `name.local`, which meant if there were multiple sections named "name", there could potentially be name collisions. This commit adds a unique numeric suffix to each section's ID string. This guarantees that locals in one section won't interfere with those in a different section.
This commit is contained in:
@@ -43,7 +43,8 @@ pub fn process_labels(board: &mut Board) {
|
||||
/// Resolve ".local" labels to "name.local" form.
|
||||
fn resolve_local_labels(stats: &mut [ParsedStat]) {
|
||||
for stat in stats.iter_mut() {
|
||||
let mut section = CompactString::const_new("");
|
||||
let mut section_counter = 0;
|
||||
let mut section = CompactString::const_new("$0");
|
||||
for chunk in stat.iter_mut() {
|
||||
match chunk {
|
||||
Chunk::Label {
|
||||
@@ -57,12 +58,13 @@ fn resolve_local_labels(stats: &mut [ParsedStat]) {
|
||||
if label.name.is_empty() {
|
||||
// Expand :.local to :name.local
|
||||
assert!(label.local.is_some());
|
||||
label.name = section.clone()
|
||||
label.name = section.clone();
|
||||
} else if label.local.is_none() {
|
||||
// Interpret label :name as start of new section.
|
||||
// Only label definitions do this; label references have no effect.
|
||||
if !*is_ref {
|
||||
section = label.name.clone();
|
||||
section_counter += 1;
|
||||
section = format!("{}${}", &label.name, section_counter).into();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,3 +18,38 @@ expression: board_to_text(board)
|
||||
'
|
||||
:stop
|
||||
#walk i
|
||||
---
|
||||
'Using locals before any globals are defined
|
||||
:_loop1
|
||||
#take gems 1 _break
|
||||
#_loop1
|
||||
:_break
|
||||
---
|
||||
'Multiple sections with the same name
|
||||
#end
|
||||
:touch
|
||||
Trying to sell you some ammo...
|
||||
#take gems 10 _skip
|
||||
#give ammo 10
|
||||
:_skip
|
||||
#zap touch
|
||||
#end
|
||||
:touch
|
||||
Trying to sell you some torches...
|
||||
#take gems 15 _skip0
|
||||
#give torches 5
|
||||
:_skip0
|
||||
#restore touch
|
||||
---
|
||||
'Multiple locals with the same name
|
||||
#end
|
||||
:repeat3
|
||||
:_z
|
||||
:_z
|
||||
:_z
|
||||
#take gems 1 _skip1
|
||||
#give score 1
|
||||
:_skip1
|
||||
#zap _z
|
||||
#_z
|
||||
:_z
|
||||
|
||||
Reference in New Issue
Block a user