Last active
October 9, 2022 15:21
-
-
Save Movax12/b11687f218f38952ecf2dcb98c1756b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; -------------------------------------------------------------------------------------------- | |
; https://mit-license.org/ | |
; Copyright © 2022 Julian Terrell [email protected] | |
; | |
; Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated | |
; documentation files (the “Software”), to deal in the Software without restriction, including without limitation | |
; the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, | |
; and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above | |
; copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | |
; | |
; THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED | |
; TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | |
; CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
; DEALINGS IN THE SOFTWARE. | |
; -------------------------------------------------------------------------------------------- | |
; File: anonLabels.h | |
; | |
; Implementation of GNU assembler numbered local labels using CA65 macros. | |
; | |
; Known limitations: | |
; - Cheap local labels will not work when interleaved with these labels. | |
; - These labels may not work when interleaved with changes in scope. | |
; - Cannot jump forward to the next numbered label on the same line as a similarly numbered label, ie: | |
; L:1 bcc F 1 ; will branch to itself, and not the next L:1 label | |
; - Cannot jump back to the same numbered label on the same line as a similarly numbered label, ie: | |
; L:1 bcc B 1 ; will not work as the label is not yet properly defined. | |
; - Cannot use L, F, B as macro names or identifiers. | |
; - Instructions/macros on the same line as an 'L' label definition are limited to one additional parameter, ie: | |
; This will work: | |
; L:0 lda foo, x | |
; This will NOT work: | |
; L:0 myMacro foo, bar, #$02 | |
; This will work: | |
; L:0 {myMacro foo, bar, #$02} | |
; Define the label on its own line to avoid this issue. | |
; | |
; User options: | |
; Max labels available, uncomment or define this before including this file: | |
; ::GAS_ANON_LABELS_MAX = 10 | |
; | |
; Usage: | |
; These macros are indented to provide the functionality described here: | |
; https://sourceware.org/binutils/docs/as/Symbol-Names.html | |
; | |
; Example usage: | |
; L:1 | |
; branch F 1 | |
; L:2 branch B 1 | |
; L:1 branch F 2 | |
; L:2 branch B 1 | |
; | |
; Which is the equivalent of: | |
; label_1: branch label_3 | |
; label_2: branch label_1 | |
; label_3: branch label_4 | |
; label_4: branch label_3 | |
; Labels made with the 'L' macro are assembled as: | |
; Number: | |
; This is the number supplied to the macro that is used in label definition. If the label is 'L:55' then the number is '55'. | |
; C_B | |
; This character string is included to reduce the chance you do not accidentally invent a symbol of the same name. | |
; Count: | |
; Each time a label with the same number is used the count for that label number will be increased. This count will be part of the label | |
; to ensure each numbered label is unique. The first definition of 'L:0' gets the number '1'. The 15th definition of 'L:0' | |
; gets the number '15', and so on. Likewise the first definition of 'L:1' gets the number '1' and its 15th definition gets '15' as well. | |
; Example: the first L:1 may be named L1C_B1, and the 9th L:3 may be named L3C_B9. | |
; -------------------------------------------------------------------------------------------- | |
.ifndef ::GAS_ANON_LABELS | |
::GAS_ANON_LABELS = 1 | |
; max labels available, change or define this before including this file: | |
.ifndef ::GAS_ANON_LABELS_MAX | |
::GAS_ANON_LABELS_MAX = 10 | |
.endif | |
; define an array, CA65 style: | |
.define ANON_LABEL_COUNT_FOR_VALUE(c) ::.ident(.sprintf("LABEL_COUNT_FOR_%02X", c)) | |
; init array: | |
.repeat ::GAS_ANON_LABELS_MAX, c | |
ANON_LABEL_COUNT_FOR_VALUE {c} .set 1 | |
.endrepeat | |
; macro for label definitions, does a basic syntax check: | |
.macro L value, p0 | |
.if (!.xmatch({.left(1,{value})}, {:})) | |
.error "`:` followed by a constant expected." | |
.endif | |
.local thisValue | |
thisValue = .mid(1, 1, {value}) ; second token | |
.if thisValue > ::GAS_ANON_LABELS_MAX - 1 | |
.error .sprintf("Max label value is %d. Set GAS_ANON_LABELS_MAX to a higher value.", ::GAS_ANON_LABELS_MAX - 1) | |
.exitmacro | |
.endif | |
.ident( .sprintf("L%dC_B%d", thisValue, ANON_LABEL_COUNT_FOR_VALUE {thisValue})): | |
; anything else on the line with the label? If so, output the tokens | |
.if (.tcount({value}) > 2) | |
.if .paramcount > 1 | |
.mid( 2, .tcount({value}) - 2, {value}) , p0 ; allow indexed to work | |
.else | |
.mid( 2, .tcount({value}) - 2, {value}) | |
.endif | |
.endif | |
ANON_LABEL_COUNT_FOR_VALUE {thisValue} .set ANON_LABEL_COUNT_FOR_VALUE {thisValue} + 1 | |
.endmacro | |
; forward or backward references. Error checking not possible | |
.define F(value) .ident( .sprintf("L%dC_B%d", .right(1,value), ANON_LABEL_COUNT_FOR_VALUE {.right(1,value)} )) | |
.define B(value) .ident( .sprintf("L%dC_B%d", .right(1,value), ANON_LABEL_COUNT_FOR_VALUE {.right(1,value)} - 1 )) | |
.endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment