Mutual recursion: Difference between revisions
Content added Content deleted
No edit summary |
Not a robot (talk | contribs) (Add MAD) |
||
Line 1,995: | Line 1,995: | ||
loop(0,20,`female') |
loop(0,20,`female') |
||
loop(0,20,`male')</lang> |
loop(0,20,`male')</lang> |
||
=={{header|MAD}}== |
|||
By default, functions in MAD are not reentrant. There is also no variable scope, |
|||
all variables are always global. Functions can call other functions, but on the |
|||
old IBM mainframes this was done by storing the return address in a special |
|||
location (one per function); should a function call itself (either directly or |
|||
indirectly), the return address would be overwritten. |
|||
MAD does include a stack mechanism, but it is entirely manual. The programmer |
|||
must allocate memory for it himself and activate it by hand, by default there |
|||
is no stack. The command for this is <code>SET LIST TO array</code>. |
|||
Once this is done, however, variables can be pushed and popped |
|||
(using the <code>SAVE</code> and <code>RESTORE</code> commands). |
|||
Furthermore, <code>SAVE RETURN</code> and <code>RESTURE RETURN</code> can |
|||
be used to push and pop the current return address, enabling proper recursion, |
|||
as long as the programmer is careful. |
|||
The downside to this is that it does not play well with argument passing. |
|||
All variables are still global. This means that passing arguments to a recursive function |
|||
has to be done either by pushing them on the stack beforehand, or by setting |
|||
global variables that the functions will push and pop themselves. (This program does |
|||
the latter.) |
|||
At the same time, the language syntax demands that all functions take at least one |
|||
argument, so a dummy argument must be passed. To obtain a recursive function that uses the |
|||
argument it is given, it is necessary to write a front-end function that uses its argument |
|||
to pass it through the actual function in the manner described above. This is also shown. |
|||
In this program, <code>F.</code> and <code>M.</code> are the front ends, taking an |
|||
argument and using it to set <code>N</code>, then calling either <code>FREC.</code> |
|||
or <code>MREC.</code>, which are the actual recursive functions, with a dummy zero argument. |
|||
<lang MAD> NORMAL MODE IS INTEGER |
|||
R SET UP STACK SPACE |
|||
DIMENSION STACK(100) |
|||
SET LIST TO STACK |
|||
R DEFINE RECURSIVE FUNCTIONS |
|||
R INPUT ARGUMENT ASSUMED TO BE IN N |
|||
INTERNAL FUNCTION(DUMMY) |
|||
ENTRY TO FREC. |
|||
WHENEVER N.LE.0, FUNCTION RETURN 1 |
|||
SAVE RETURN |
|||
SAVE DATA N |
|||
N = N-1 |
|||
N = FREC.(0) |
|||
X = MREC.(0) |
|||
RESTORE DATA N |
|||
RESTORE RETURN |
|||
FUNCTION RETURN N-X |
|||
END OF FUNCTION |
|||
INTERNAL FUNCTION(DUMMY) |
|||
ENTRY TO MREC. |
|||
WHENEVER N.LE.0, FUNCTION RETURN 0 |
|||
SAVE RETURN |
|||
SAVE DATA N |
|||
N = N-1 |
|||
N = MREC.(0) |
|||
X = FREC.(0) |
|||
RESTORE DATA N |
|||
RESTORE RETURN |
|||
FUNCTION RETURN N-X |
|||
END OF FUNCTION |
|||
R DEFINE FRONT-END FUNCTIONS THAT CAN BE CALLED WITH ARGMT |
|||
INTERNAL FUNCTION(NN) |
|||
ENTRY TO F. |
|||
N = NN |
|||
FUNCTION RETURN FREC.(0) |
|||
END OF FUNCTION |
|||
INTERNAL FUNCTION(NN) |
|||
ENTRY TO M. |
|||
N = NN |
|||
FUNCTION RETURN MREC.(0) |
|||
END OF FUNCTION |
|||
R PRINT F(0..19) AND M(0..19) |
|||
THROUGH SHOW, FOR I=0, 1, I.GE.20 |
|||
SHOW PRINT FORMAT FMT,I,F.(I),I,M.(I) |
|||
VECTOR VALUES FMT = |
|||
0 $2HF(,I2,4H) = ,I2,S8,2HM(,I2,4H) = ,I2*$ |
|||
END OF PROGRAM</lang> |
|||
{{out}} |
|||
<pre>F( 0) = 1 M( 0) = 0 |
|||
F( 1) = 1 M( 1) = 0 |
|||
F( 2) = 2 M( 2) = 1 |
|||
F( 3) = 2 M( 3) = 2 |
|||
F( 4) = 3 M( 4) = 2 |
|||
F( 5) = 3 M( 5) = 3 |
|||
F( 6) = 4 M( 6) = 4 |
|||
F( 7) = 5 M( 7) = 4 |
|||
F( 8) = 5 M( 8) = 5 |
|||
F( 9) = 6 M( 9) = 6 |
|||
F(10) = 6 M(10) = 6 |
|||
F(11) = 7 M(11) = 7 |
|||
F(12) = 8 M(12) = 7 |
|||
F(13) = 8 M(13) = 8 |
|||
F(14) = 9 M(14) = 9 |
|||
F(15) = 9 M(15) = 9 |
|||
F(16) = 10 M(16) = 10 |
|||
F(17) = 11 M(17) = 11 |
|||
F(18) = 11 M(18) = 11 |
|||
F(19) = 12 M(19) = 12</pre> |
|||
=={{header|Maple}}== |
=={{header|Maple}}== |