===UBound() Function. Returns the Upper-most dimension of an Array.=== Common in other Basic dialects, UBOUND() returns the number of the highest array element, i.e. the value specified in DIM and helpful for working with dynamic arrays. MMBasic on the Micromite series of micro-controllers lacks this function. The below code searches the Variable Table for the named variable, returning the dimension as appropriate. Although not "beginner standard" following the code is quite easy and interesting as it devlves into the innards of one of the mechanisms of MMBasic. The function minimizes the number of checks by only examining variables that start with the same letter - this is a major update over the previous version and reduces the search time in the demo code by 90% - from ~170mS to just 17mS (testing at 5MHz to show granularity). ===Caveats=== *There is no error checking on the type of variable passed in. Shouldn't be a problem since MMBasic variable names must be unique. *Multi-dimensional arrays might cause unexpected results. *The maximum name length in MMBasic is 32 characters (31 if you use explicit typing) if the variable name is 32 characters long, there is no terminating character, if it is 31 or less, the variable name is zero terminated - for speed, I always assume the latter. The function doesn't check for any of this. Simple rule, stick to short variable names (<32 chars) and you'll be fine. *Because we are searching for the variable by name, it must be passed in quotes (i.e. as a string) and without any type indicator... e.g. {{A}} not {{A$}} or {{A%}}. *There is no way to determine the end of the variable table that is exposed to MMBasic, so I simply specify 2KB as the limit. This is good for 32 variables. Increase the "{{For N=}}" in multiples of 64 if you need more. In practice, the name of the variable you pass will be known (and hence found in the table) so the maximum size is seldom reached, therefore, reducing this 2KB limit is unlikely to improve timings (it is fairly swift in any case). *Be aware the function finds the first instance of a name and does not care about type ({{$,%,!}}) or level ({{DIM, CONST, LOCAL, STATIC}}...), so it has no way of knowing the difference between
{{Dim Integer Fred}} and {{Local String Fred}}. Avoid any confusion by having unique variable names where you use UBound(). ===Usage=== x=UBound("MyArray") Returns the highest dimension of the array, or 0 if the array was not found. ===The Code=== 'some demo code 'set up some variables Dim Integer aaaaaaaaaa,bbbbbbbbbb,ccccccccc,ddddddd,eee,ffff,gggg,hhhh,iiiii,j,k,llll Dim a1$(17) 'same size as we put above Print UBound("A1") 'dump the array Erase a1$ 'and re-create with unknown dimensions Dim a1$(Int(Rnd*20)+1) 'not unknown anymore timer=0 k=UBound("A1") ?timer,k 'The function Function UBound(z$) As Integer' warning, destroys z$... shouldn't matter Local q$ Local Integer n,m,p z$=Ucase$(z$)+Chr$(0) p=Asc(Left$(z$,1)) For n=0 To 2047 Step 64 '2K of variable descriptors If p=Peek(VARTBL,n) Then 'potential match q$="" For m=0 To Len(z$)-1 'retrieve full name + NUL q$=q$+Chr$(Peek(VARTBL,n+m)) Next If Ucase$(q$)=z$ Then 'found the variable UBound=Peek(VARTBL,n+35)*256+Peek(VARTBL,n+34) Exit Function End If End If Next UBound=0 End Function