Page 4 of 4
Re: spca65
Posted: Sat Jan 04, 2014 4:43 pm
by Movax12
blargg wrote:And next, how to define a global symbol within a scope...The context is using scopes in a nice loop macro
By "loop macro" do you mean you are using a
.repeat? You could try recursion instead, since the .repeat is basically a form of recursion. Maybe give a more defined example.
Re: spca65
Posted: Sat Jan 04, 2014 4:51 pm
by tepples
I wouldn't be so sure that ca65's macro processor optimizes tail calls. How deep of recursion were you thinking?
Re: spca65
Posted: Sat Jan 04, 2014 5:04 pm
by Movax12
I'm not sure what you mean with tail calls in this context, tepples.
Example comparison: A macro called
hex as recursive and with
.repeat (untested)
Usage:
Code: Select all
hex 01 03 a0 ba 23 43 fe ee fc 01 03 a0 ba 23 43 fe ee fc
Recursive:
Code: Select all
macro hex data
.ifblank data
.error "Please provide some data!"
.endif
.byte $.left(1,data)
.if .tcount(data) > 1
hex .mid(1, .tcount(data) - 1, data)
.endif
.endmacro
With
.repeat
Code: Select all
macro hex data
.ifblank data
.error "Please provide some data!"
.endif
.repeat .tcount(data), I
.byte $.mid(I, 1, data)
.endrepeat
.endmacro
Both are technically recursive.
Re: spca65
Posted: Sat Jan 04, 2014 5:12 pm
by tepples
Unless ca65's macro expander handles
tail calls specially, your recursive example will eat up about
18 levels of
call stack inside the macro expander when
hex calls itself, one for each byte. The iterative example won't.
Re: spca65
Posted: Sat Jan 04, 2014 5:40 pm
by Movax12
Yes, I'm sure the recursive example will use more memory vs .repeat, but it shouldn't matter much on a modern PC. The benefit being recursive example will allow you to have .local constants defined that are unique for each recursive expansion and hopefully avoid using any unnamed scopes (and making a global definition no problem).
Re: spca65
Posted: Sat Jan 04, 2014 5:59 pm
by tepples
Movax12 wrote:Yes, I'm sure the recursive example will use more memory vs .repeat, but it shouldn't matter much on a modern PC.
Unless you have to recompile ca65 for a greater recursion depth. A lot of interpreters* cap the call stack depth to prevent runaway recursion from making your machine unresponsive from swapping. Good luck getting a recursive macro to run 32768 deep, once for each byte in a bank.
When I try to assemble this, I get an error because ca65 is capping the macro call stack at 255 levels.
Code: Select all
.macro recursefromhell i
.if i > 0
.local i1
i1 = i
.byte <i1
recursefromhell (i1 - 1)
.endif
.endmacro
; this works
recursefromhell 255
; this raises Error: Too many nested macro expansions
recursefromhell 256
The benefit being recursive example will allow you to have .local constants defined that are unique for each recursive expansion and hopefully avoid using any unnamed scopes (and making a global definition no problem).
What does this necessarily provide over
.local once and then
.set within the
.repeat loop?
* ca65 is an assembler, but its macro language is an interpreter within an assembler.
Re: spca65
Posted: Sat Jan 04, 2014 6:17 pm
by blargg
Movax12 wrote:blargg wrote:And next, how to define a global symbol within a scope...The context is using scopes in a nice loop macro
By "loop macro" do you mean you are using a
.repeat? You could try recursion instead, since the .repeat is basically a form of recursion. Maybe give a more defined example.
No, just the equivalent of a for loop with braces for scope, that allows nesting, and doesn't require you to name each loop. I'm writing a CPU instruction tester and want to make several nested for loops to go over arrays of bytes.
Code: Select all
loop_bytes { 0, 1, $7f, $80, $ff }, in_a
loop_bytes { 0, 1, $7f, $80, $ff }, operand
cmp operand
; A operand
; 00 00
; 00 01
; 00 7f
; 00 80
; 00 ff
; 01 00
; 01 01
; ...
loop_end
loop_end
Re: spca65
Posted: Sat Jan 04, 2014 6:27 pm
by Movax12
tepples wrote:
What does this necessarily provide over .local once and then .set within the .repeat loop?
I found it helpful in the instances where the recursive expansion would end and the .local would retain the value from before the expansion call. Not sure if I could come up with a good example vs
.repeat
Re: spca65
Posted: Mon Feb 16, 2015 8:37 pm
by tepples
Back to topic:
What's the license on this set of macros?
(And after how many days since last post must I calculate days since last post?)
Re: spca65
Posted: Sat Jul 18, 2015 1:32 pm
by tepples
The uses of DEFAULT_ABS inside macros need to be changed to ::DEFAULT_ABS so that they'll work even inside a .proc block.