Small Basic: How to Simulate Local Variables
This articles assumes knowledge of another article titled Small Basic: How to Simulate Parameters. Please read that article first.
Let's see what a simple VB function would look like that uses local variables. Here's a VB function called GetSum() which returns the sum of the first 10 positive integers:
Function GetSum()
i = 0
sum = 0
while i < 10
i = i + 1
sum = sum + i
wend
return sum
End Function
When a similar subroutine is created in Small Basic, the variables i and sum end up being global, instead of local. That's because Small Basic currently doesn't support local variables. This means that if you had another Subroutine that used the variable i, it would refer to the same variable.
You can work around this by making the name of the variable unique. For instance, instead of i and sum, name them GetSum_i and GetSum_sum. This seems to solve the problem with multiple functions using the same variable name, but it doesn't work if any of the functions are called recursively. That is, what if GetSum() calls itself. Or it calls another function, which in turn ends up calling GetSum() again. These types of reentrancy and nesting of functions is not unusual.
So to simulate local variables like in VB, it's best to store the values in an entirely different place, and the Small Basic "Array" comes in handy for this.
So instead of writing code like this:
i = 0
You'd write code like this:
Array.SetValue( , "i", 0 )
The Array class requires that we specify a arrayname. First, we know that each function should have it's own local variables, so the arrayname must at a minimum be unique for each function. Second, we know that we need to support nesting that way when the function is called a second time, recursively, the array name will be different. So, let's say that we want the array name to be "GetSum1" the first time and "GetSum2" the second time. Here's a way to construct such an array name:
Sub GetSum
GetSum_Locals = GetSum_Locals + 1
' Array name expression:
Text.Append( "GetSum", GetSum_Locals)
GetSum_Locals = GetSum_Locals - 1
EndSub
So the function with only "i=0" in it, would look like this:
Sub GetSum
GetSum_Locals = GetSum_Locals + 1
' i = 0
Array.SetValue( Text.Append( "GetSum", GetSum_Locals), "i", 0 )
GetSum_Locals = GetSum_Locals - 1
EndSub
The statement i=i+1 would look like this:
Array.SetValue( Text.Append( "GetSum", GetSum_Locals), "i", Array.GetValue( Text.Append( "GetSum", GetSum_Locals), "i" ) + 1 )
The entire GetSum Subroutine would look like this:
Sub GetSum
GetSum_Locals = GetSum_Locals + 1
' i = 0
Array.SetValue( Text.Append( "GetSum", GetSum_Locals), "i", 0 )
' sum = 0
Array.SetValue( Text.Append( "GetSum", GetSum_Locals), "sum", 0 )
' while i < 10
While Array.GetValue( Text.Append( "GetSum", GetSum_Locals), "i" ) < 10
' i = i + 1
Array.SetValue( Text.Append( "GetSum", GetSum_Locals), "i", Array.GetValue( Text.Append( "GetSum", GetSum_Locals), "i" ) + 1 )
' sum = sum + i
Array.SetValue( Text.Append( "GetSum", GetSum_Locals), "sum", Array.GetValue( Text.Append( "GetSum", GetSum_Locals), "sum" ) + Array.GetValue( Text.Append( "GetSum", GetSum_Locals), "i" ) )
EndWhile
'Return Sum
Stack.PushValue( "p", Array.GetValue( Text.Append( "GetSum", GetSum_Locals), "sum" ) )
GetSum_Locals = GetSum_Locals - 1
EndSub
And you can call it like this:
GetSum()
TextWindow.WriteLine( Stack.PopValue( "p" ) )
By Kenny Kasajian http://kasajian.com