Jump to content

Mutual recursion: Difference between revisions

Add MAD
No edit summary
(Add MAD)
Line 1,995:
loop(0,20,`female')
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}}==
2,115

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.