Re: [cc65] Macro scoping problem...

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2010-07-10 14:28:56
On Sat, Jul 10, 2010 at 01:25:49PM +0200, Christian Krüger wrote:
> in my case, I just like to have labels with a postfix, given by
> using the macro:
>
> .ident(.concat(.string(label, "_SMC")))

You will have to think in terms of tokens when writing macros for cc65. This
is unusual, but it offers a lot of advantages. Because of these advantages,
assemblers and compilers do translate the input into tokens before processing
them.

In your case, the argument "label" passed to the macro is a list of tokens.
What you want to do is to append "_SMC" to the rightmost token in this list.
The rightmost token must be an identifier for this to work. There are some
constraints for the other tokens in the list, but this is checked by the
assembler, so we don't need to care about it.

Using this knowledge, we can come up with a macro as follows:

.macro DoJmp label
        .if .match(.right(1, label), ident)
                jmp     .mid(0, .tcount(label) - 1, label) .ident(.concat(.string(.right(1, label)), "_SMC"))
        .else
                .error "Last token of label must be an identifier"
        .endif
.endmacro

First thing is to check if the rightmost token is an identifier. If not, we
will output an error. Once we know, the rightmost token is an identifier, we
construct a new token list that consists of all tokens up to but not including
the right one, plus the rightmost token, converted to a string, "_SMC"
appended and converted by to an identifier.

If we test the macros using

18: DoJmp  GlobalLabel
19: DoJmp  Test::Label
20: DoJmp  12+24

we get

t.s(20): Error: Argument of .IDENT is not a valid identifier
t.s(20): Error: User error: Last token of label must be an identifier

so this works as expected. We can of course add some improvements, for example
add curly braces around label, but this will only improve handling in case of
errors.

Please note that your naming scheme seems to be somewhat shaky, since adding
another nested scope within Test will break the whole thing. _SMC is the added
to the last identifier, but you yould need something like
Test::Label_SMC::Inner.

Regards


        Uz



P.S.: It seems that .LEFT contains an error that prevents negative token
      counts to be handled correctly. So if you have problems with .LEFT,
      use .MID with a starting index of zero.
-- 
Ullrich von Bassewitz                                  uz@musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Sat Jul 10 14:29:04 2010

This archive was generated by hypermail 2.1.8 : 2010-07-10 14:29:07 CEST