Author
GO-29, 2019.06.22
support@bigcatos.com
Theory
In GO-29's documentation, Part II - Programmatic Usage, the section Subroutines
describes the nature and limits of the calculator's ¦
and § mechanism. In particular we learned
that on an actual HP-29C, subroutine calls could be nested to a depth of three, although GO-29
extends that number. If the new, larger, subroutime call depth `n_29` had not been documented, how could you determine it?
With the aid of this diagram we discovered that if you wrote and called enough nested subroutines the LIFO
§ queue would lose its earliest entries
and that the program would terminate prematurely before returning to the Main Program:
As it happens, we can couple this observation of early program termination along
with a recursive subroutine to discover `n_29`, GO-29's subroutine call depth,
or § queue size.
Recursion is pretty opaque until you wrap your head around it, then it's amazingly awesome - search the web and read up on the topic! A recursive subroutine typically contains in its definition instructions that do stuff, then a call to itself to do similar stuff based upon what it just did. Makes perfect sense, right?
Study this simple example of a recursive subroutine, named © 9, which counts-up and displays whatever is stored in R₈. It then calls itself and displays R₈ + 1, etcetera. This will be the basis of our limit-testing recursive subroutine:
© 9 |
1 |
d + 8 |
f 8 |
U |
¦ 9 |
§ |
The big problem here (ignoring the fact that R₈ hasn't been initialized) is that the count-up goes on forever, there is no test to exit the virtual loop! If you manually key GSB 9, the subroutine calls itself an infinite number of times. A recursive subroutine always needs a way out, a testable condition that can activate a clean exit from the subroutine. Here, two things should be obvious:
Corollary: We assume that nesting level 0 represents the Main Program.
To do this we must add two small sections of code to subroutine © 9, the first to stop the recursion, and the second to count-down R₈. We stop the recursion by only allowing ¦s to a certain depth, the proposed call back depth, a number that we'll enter from the keyboard and store in R₉. Once the subroutine nesting level reaches this value we'll explicity return, which breaks recursion and initiates the §s that attempt to get back to the Main Program. And counting-down is easy enough, it's the opposite of counting-up!
© 9 |
1 |
d + 8 |
f 8 |
U |
f 9 |
R |
§ |
¦ 9 |
§ |
© 9 |
1 |
d + 8 |
f 8 |
U |
f 9 |
R |
§ |
¦ 9 |
1 |
d - 8 |
f 8 |
U |
§ |
The R₈ rule says always increment before ¦ 9, always decrement afterwards.
And that is the completed recursive subroutine © 9, now it's time to visit the Main Program, consisting of two entry points, © 0 the initializer, and © 1 the recursive subroutine controller code. Note the use of the two 8* extended opcodes, |2 to signal an input error, and |1 to indicate succesful return to the Main Program. Theses opcodes are explained in GO-29's documentation, Part III - GO-29 Programs, in the section Special 8* Opcodes.
© 0 |
Q 0 |
n |
d 9 |
° |
e 1 |
|2 |
§ |
© 1 |
0 |
d 8 |
U |
¦ 9 |
1 |
d - 8 |
f 8 |
U |
|1 |
§ |
The R₈ rule says always increment before ¦ 9, always decrement afterwards.
∴`n_29=n_p-n_f`