User Tools

Site Tools


mmbasic:ubound_upper_boundary_of_an_array

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.</li>
  • Multi-dimensional arrays might cause unexpected results.</li>
  • 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.</li>
  • 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.</li>
  • 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).</li>
  • Be aware the function finds the first instance of a name and does not care about type (mmbasic) or level (dim_const_local_static…), so it has no way of knowing the difference between <br>dim_integer_fred and local_string_fred. Avoid any confusion by having unique variable names where you use UBound().</li>

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
mmbasic/ubound_upper_boundary_of_an_array.txt · Last modified: 2024/01/19 09:30 by 127.0.0.1