Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add local label support within preproc. #1302

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

luckytyphlosion
Copy link
Member

Description

The prefix chosen was $ since it's a valid gnu assembler name character and isn't used by other directives. . would have been preferable but it would require extra coding.

Semantics:

  • Local labels are scoped by a non-local (or global) label. That is, local labels will become undefined when a non-local label is used, which means that the names of local labels can be reused as long as a non-local label is defined.
  • Local labels can be referenced before they are declared, like normal labels. If a local label is referenced but not defined within its scope, then preproc will report an error.
  • Since this is a preproc extension, local labels will not work in macros. If you need this advanced support, I would suggest looking at my fork of PikalaxALT/easyaspi's agbcc + binutils, which implements true local label support within gnu assembler.
  • Internally, preproc will transform a local label into the concatenation of the last non-local label and the local label. E.g. for this input:
    NonlocalLabel1:
        .byte 10
        .word $localLabel @ forward reference
    $localLabel:
        .byte 20
        .word $localLabel @ backwards reference
    
    NonlocalLabel2:
        .hword 30
        .word $localLabel @ forward reference
    $localLabel:
        .hword 40
        .word $localLabel @ backwards reference
    
    preproc will transform it to:
    NonlocalLabel:
        .byte 10
        .word NonlocalLabel$localLabel @ forward reference
    NonlocalLabel$localLabel:
        .byte 20
        .word NonlocalLabel$localLabel @ backwards reference
    
    NonlocalLabel2:
        .hword 30
        .word NonlocalLabel2$localLabel @ forward reference
    NonlocalLabel2$localLabel:
        .hword 40
        .word NonlocalLabel2$localLabel @ backwards reference
    
    This means that you can also reference a local label outside of its scope, but this hasn't been tested. What is guaranteed is that the local label substitution (e.g. .word $localLabel -> .word NonlocalLabel2$localLabel) will only happen if the $ is directly after a non-word character (anything that isn't alphanumeric, _, ., or $).
  • Per file, local labels cannot be defined before a non-local label is defined. Part of this behaviour is a bit weird and not really designed for since it represents an edge case. For example:
    NonlocalLabel1:
        .byte 10
    $localLabel1:
        .byte 20
    
        .include "some_data.inc"
    
    @ in file "some_data.inc"
        .word $localLabel2
    
    would not be valid, however:
    @ in file 
    NonlocalLabel1:
        .byte 10
        .word $localLabel1
    $localLabel2:
        .include "more_data.inc"
    @ in file "more_data.inc"
    NonlocalLabel2:
        .byte 20
    
    @ back to the base file
    $localLabel1:
        .byte 30
    
    is (probably) valid. However, most users will probably never feel the need for cross-file local labels.
  • Tests were done in another, private repository, but if needed I could refactor some scripts to use local labels to show their correctness. The following tests were done:
    • defining a label before it's referenced, then defining the label
    • defining a label before it's referenced, and not defining it (should error)
    • defining multiple of the same label before it's referenced, and not defining it (should error)
    • defining multiple different labels before they're referenced, and not defining them (should error)
    • defining multiple different labels multiple times before they're referenced, and not defining them (should error)
    • defining local label as global (should error)
    • defining local label before a non-local label is defined (should error)
    • defining just the local label prefix (should error)
    • referencing a local label at the end of a file without a newline
    • validating local labels at the end of the file

Discord contact info

luckytyphlosion#1166

cases tested:
- defining a label before it's referenced, then defining the label /
- defining a label before it's referenced, and not defining it /
- defining multiple of the same label before it's referenced, and not defining it /
- defining multiple different labels before they're referenced, and not defining them /
- defining multiple different labels multiple times before they're referenced, and not defining them /
- defining local label as global /
- defining local label before a non-local label is defined /
- defining just the local label prefix /
- referencing a local label at the end of a file /
- validating local labels at the end of the file /
@GriffinRichards
Copy link
Member

When you say it will not work in macros do you mean a label in a macro definition or a label given as an argument to a macro? If the latter I'm struggling to see a use case for this given that the repo's scripts are almost all macro

@luckytyphlosion
Copy link
Member Author

I mean label in a macro definition. So:

  .macro my_macro
$localLabel:
  .byte 10
  .endm

would not work when the macro is actually used.

@rawr51919
Copy link
Contributor

So you're saying with this it's possible to add labels in macro definitions within the macros themselves? Would this PR still be relevant in today's pokeemerald?

@rawr51919
Copy link
Contributor

Either way though it still needs a rebase to fix merge conflicts

@GriffinRichards
Copy link
Member

The above merge conflict was trivial and unrelated; seems like this doesn't build on current pokeemerald. Do you still have any interest in this?

@tustin2121
Copy link
Contributor

What purpose is this for that isn't already possible with GAS's built-in local labels 0 through 9, and referencing them via 0b (backward reference) or 0f (forward reference)? https://ftp.gnu.org/old-gnu/Manuals/gas-2.9.1/html_chapter/as_5.html#SEC48

@luckytyphlosion
Copy link
Member Author

What purpose is this for that isn't already possible with GAS's built-in local labels 0 through 9, and referencing them via 0b (backward reference) or 0f (forward reference)? https://ftp.gnu.org/old-gnu/Manuals/gas-2.9.1/html_chapter/as_5.html#SEC48

gas local labels suck because they can't be named

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants