74
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.20 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 an 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.
Sub Main()
Call foo(3)
Call foo(3, 5)
End Sub
Sub foo(ByVal size as Byte, ByVal cnt as Byte = 1)
End Sub
If any parameter has a default value specified, all parameters following that parameter must also have a
default value. Also, only parameters that are passed ByVal may have a default value. Some parameter
types, like arrays and structures for example, are always passed ByRef even if they are defined as ByVal
and therefore cannot have a default value specification.
3.21 Aliases
Occasionally, it is useful to be able to access a variable or parts of a variable as different types at different
times. Although this can be accomplished by using the System Library routines BlockMove() or
RamPeek()/RamPoke() it is simpler and more efficient to use the concept of an alias. Simply stated,
defining an alias tells the compiler to generate code to access a variable or part of a variable as if it were
a different type. To be clear, no new data space is allocated by defining an alias. It simply provides a
different way of accessing previously defined space.
The syntax for defining an alias is similar to that for defining a variable. For example, the syntax for
defining an alias at the module level is shown below.
{Public | Private | Dim} <name>[(<dim-list>)] As <type> Alias <var-ref>
As with normal variables, Dim has exactly the same effect as Private. Within a subroutine, a function
or any block structure, a local alias may be defined using the syntax shown below.
Dim <name>[(<dim-list>)] As <type> Alias <var-ref>
In both cases the <var-ref> element is the name of a RAM variable or the name of another alias
optionally including a parenthesized set of one or more constant index expressions. The parenthesized
index list is only allowed, of course, if the referent item is an array.