In this post, tokumaru wrote:
Garth wrote:
one feature I liked was that it allowed macros to have varying numbers of input parameters.
You can create macros like this in ca65 too, I do it all the time.
How does this work? I thought each macro's declaration specified the maximum number of arguments that it takes. Do you just declare a macro with, say, 32 arguments and say "too bad" to a process that wants to generate more?
For example: By default, the .word command asserts that each argument's value is in the range 0 to 65535. Let's say I want to make a counterpart that instead asserts that each value is in the range -32768 to 32767. The force_range option only switches between no range checking at all and unsigned range checking, not signed range checking. The issue about lack of signed range checking cites a mailing list conversation started by rainwarrior, in which Marc Rintsch recommended that one create a macro that performs the signed range checking.
So here's what I came up with (in small text because it's so wide):
Code:
.macro signedword r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31,r32
.local r1value
.ifblank r1
.exitmacro
.else
r1value = r1
.assert -32768 <= r1value && r1value <= 32767, error, "Range error (value not in [-32768..32767])"
.word r1value & $FFFF
signedword r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31,r32
.endif
.endmacro
.local r1value
.ifblank r1
.exitmacro
.else
r1value = r1
.assert -32768 <= r1value && r1value <= 32767, error, "Range error (value not in [-32768..32767])"
.word r1value & $FFFF
signedword r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r26,r27,r28,r29,r30,r31,r32
.endif
.endmacro
But calling this with more than 32 arguments produces Error: Too many macro parameters. Though source code line length conventions make it unlikely that I'll use more than a dozen or so arguments, a preprocessor for data tables might use that many.
For comparison, C has variadic functions and variadic macros, and Python has def function(arg1, arg2, *restofargs).
If nobody can figure out a better way to make a ca65 macro that takes an arbitrary number of arguments, I plan to report this on cc65's issue tracker on GitHub.