88 of 208
ZBasic Language Reference 80 ZX Microcontroller Family When thinking about Program Memory data tables, on the other hand, the perception does matter because the initializer data is arranged in rows and columns and you need to know how to get the array element that you want. To do so, always specify the column index first and the row index second. This order was adopted to maintain compatibility with the BasicX compiler. 3.17 Recursion in Subroutines and Functions A subroutine or function may be invoked recursively. This means that among the statements in the routine there is one or more that invokes the same subroutine or function again, either directly or indirectly. Clearly, the recursive invocation must be conditional so that at some point the recursion ceases. In Section 2.3.2, Defining Functions, an example function was given for computing factorial. Here is the same function written using recursion. Function Factorial(ByVal val as Integer) As Integer If (val > 1) Then Factorial = Factorial(val - 1) * val Else Factorial = 1 End If End Function Although it may look confusing at first, the logic is fairly simple. The idea is based on the fact that the value of N factorial is equal to N times the factorial of (N-1). That logic is directly expressed in the second line of code. Note that the identifier Factorial is used in two distinctly different ways in the second line of the function. On the left side of the equal sign, the identifier Factorial refers to the return value variable while that on the right side of the equal sign is a recursive invocation of the Factorial function itself. The compiler is able to distinguish the two uses by the presence of parentheses following the name. Since the return value variable can never be an array, the two types of references are easily distinguishable. The negative aspect of recursion is that it can consume a large amount of stack space. Each time a function or subroutine invocation is performed, the processor allocates additional stack space. The extra space is used to hold some tracking information to allow the processor to return to executing the code that immediately follows the invocation. Also, stack space is required for any parameters that are passed to the subroutine/function and for any variables that are defined inside the subroutine/function. Lastly, in the case of a function only, stack space is required to hold the return value from the function. Clearly, Factorial(10000) would require more stack space than is available even if all the RAM were dedicated to the stack. BasicX Compatibility Note The BasicX compiler does not allow direct recursive invocation of a function but the BasicX mode of the ZBasic compiler does. 3.18 Using Default Parameter Values in Subroutines and Functions ZBasic supports the designation of default values for parameters to subroutines and functions. This saves time when typing statements and makes the code easier to read when a particular routine is usually invoked with one or more parameters having the same constant value. Specification of the default value is done by adding an equal sign and a constant expression following the type specification of the formal parameter in the routine definition as illustrated in the example below. In the first call to the subroutine foo, the second parameter is omitted so the compiler automatically adds the specified default value for the second parameter.