Yesterday I was trying to do something using cheap local labels, and ran into something really weird. Here's a piece of code using cheap local labels:
As expected, an error occurs when trying to lda @LocalLabel, because the label is no longer visible.
However, I was writing the global labels from within macros, where I was doing other tasks, and mysteriously enough, the local label became visible outside of the block! After hours of debugging, I found the culprit, a symbol assignment using .set. Then I reproduced the issue in a more concise way:
In this case, the local label is accessible outside of the "block" where it was defined! Weird as fuck! I can only guess it's because the local label was created under "SomeSymbol", so when "SomeSymbol" is used again, the assembler thinks it's still the same block.
Sounds like a bug to me, because the "BlockEnd" label should be ending the scope where "@LocalLabel" is accessible, and you shouldn't be able to go back to that scope. What do you think? Is this a bug or a feature?
Another thing that's bothering me that also involves cheap local labels is that you can't "copy" a cheap local label before it's defined, like you can with other types of labels. For example, this works:
But this doesn't:
It only works if you make the copy after the label is defined:
I wonder if the GlobalCopy := @LocalLabel line is also acting as a "cheap local scope" breaker, so that when used at the top it tries to access the scope created by "BlockStart", which is prematurely ended by the use of "GlobalCopy", so "@LocalLabel" actually exists in the next scope. I gotta do some tests to verify this.
Code:
BlockStart:
@LocalLabel:
.byte $47
BlockEnd:
lda @LocalLabel
@LocalLabel:
.byte $47
BlockEnd:
lda @LocalLabel
As expected, an error occurs when trying to lda @LocalLabel, because the label is no longer visible.
However, I was writing the global labels from within macros, where I was doing other tasks, and mysteriously enough, the local label became visible outside of the block! After hours of debugging, I found the culprit, a symbol assignment using .set. Then I reproduced the issue in a more concise way:
Code:
BlockStart:
SomeSymbol .set 4
@LocalLabel:
.byte $47
BlockEnd:
SomeSymbol .set 5
lda @LocalLabel
SomeSymbol .set 4
@LocalLabel:
.byte $47
BlockEnd:
SomeSymbol .set 5
lda @LocalLabel
In this case, the local label is accessible outside of the "block" where it was defined! Weird as fuck! I can only guess it's because the local label was created under "SomeSymbol", so when "SomeSymbol" is used again, the assembler thinks it's still the same block.
Sounds like a bug to me, because the "BlockEnd" label should be ending the scope where "@LocalLabel" is accessible, and you shouldn't be able to go back to that scope. What do you think? Is this a bug or a feature?
Another thing that's bothering me that also involves cheap local labels is that you can't "copy" a cheap local label before it's defined, like you can with other types of labels. For example, this works:
Code:
.scope
GlobalCopy := LocalLabel
LocalLabel:
.byte $47
.endscope
lda GlobalCopy
GlobalCopy := LocalLabel
LocalLabel:
.byte $47
.endscope
lda GlobalCopy
But this doesn't:
Code:
BlockStart:
GlobalCopy := @LocalLabel
@LocalLabel:
.byte $47
BlockEnd:
lda GlobalCopy
GlobalCopy := @LocalLabel
@LocalLabel:
.byte $47
BlockEnd:
lda GlobalCopy
It only works if you make the copy after the label is defined:
Code:
BlockStart:
@LocalLabel:
.byte $47
GlobalCopy := @LocalLabel
BlockEnd:
lda GlobalCopy
@LocalLabel:
.byte $47
GlobalCopy := @LocalLabel
BlockEnd:
lda GlobalCopy
I wonder if the GlobalCopy := @LocalLabel line is also acting as a "cheap local scope" breaker, so that when used at the top it tries to access the scope created by "BlockStart", which is prematurely ended by the use of "GlobalCopy", so "@LocalLabel" actually exists in the next scope. I gotta do some tests to verify this.