5

« **on:** March 10, 2008, 10:52:05 PM »
Well, it's good to know that Cypress admit they don't 'fully' support recursion. I will attempt to do their job for them by describing two different ways you can work around the problem.

NOTE: I haven't tested the following code fragments. The syntax may well be wrong. I am composing this email late at night on a different machine from the one I run Mach3 on, which I keep deliberately clean.

1. Use dummy parameters

For all local variables you want to be able to use in a recursively-called sub or function, declare the variable as a parameter.

This is a bit messy in that you have to pass in some, unused, value for the parameter every time you call it, but this can be avoided by having two routines: a top-level one you call only from outside itself, and a recursively-callable one.

For instance, going back to my original problem, I want:

sub divide(byval a as double, byval b as double)

Dim c as double

if abs(b-a)>0.1 then

c=(a+b)/2

call divide (a,c)

call divide (c,b)

else

Code "G1 X" & b

end if

end sub

...

call divide(10,20)

..This doesn't work in Cypress VB because the second recursive call won't have the correct value for c. But this should:

sub divide(byval a as double, byval b as double, byval c as double)

if abs(b-a)>0.1 then

c=(a+b)/2

call divide (a,c,0) 'The value of the third parameter is arbitrary. Might as well make it 0

call divide (c,b,0)

else

Code "G1 X" & b

end if

end sub

...

call divide(10,20,0) 'Again, the value(s) of the parameters that are really local variables is arbitrary so I use 0

But, if you need a lot of locals this gets cumbersome, as calls have to have lots of trailing ,0,0,0,..., so you could hide it:

sub divide(byval a as double, byval b as double)

call divideRecurse(a,b,0)

end sub

sub divideRecurse(byval a as double, byval b as double, byval c as double)

if abs(b-a)>0.1 then

c=(a+b)/2

call divideRecurse (a,c,0) 'The value of the third parameter is arbitrary. Might as well make it 0

call divideRecurse (c,b,0)

else

Code "G1 X" & b

end if

end sub

...

call divide(10,20) 'top-level calls don't need any extra parameters

2. Use an array of parameters:

Dim c(10) as double 'assuming 11 is the deepest recursion needed, declare an array for each local variable

'

sub divide(byval a as double, byval b as double, byval level as integer)

if abs(b-a)>0.1 then

c(level)=(a+b)/2 'You must use only this level's copy of the local parameters

call divide (a,c, level+1) 'The third parameter tells the interpreter which set of locals to use

call divide (c,b, level+1)

else

Code "G1 X" & b

end if

end sub

...

call divide(10,20,0) 'You only need one extra parameter. It must be set to 0 or 1 in top-level calls

Possibly, these techniques will already be known and obvious to anyone who uses recursion, but as nobody had previously raised this whole subject, this may not be as many people as I thought.

Recursion can be a very elegant way to encode the logic of certain operations involving trees or, as in my example, the need to divide a big task into smaller ones until the task is so small it can be performed simply without unacceptable error. The actual code I was using this for, by the way, machines Bezier curves by dividing them into tiny fragments, each of which can be approximated by a straight G1 move. This is an ideal subject for recursion.

Any queries, just ask me.

Chris