Updated January 2011
A dynamic overlay is similar to a dynamic X variable, except that it is designed specifically for overlaying DIMX arrays. Such an overlay permits you to pass a DIMX array as a parameter to a subroutine or procedure / function.
There are two steps involved in creating a dynamic overlay:
Step 1: Declare the Overlay
Declare the overlay variable using the special ,@0 overlay syntax, e.g.:
MAP1 OVERLAY,X,@0
Note that the size field is optional but ignored, and only S and X variables are allowed. (In most cases, only X makes sense; use S-type overlays only when you are sure that the target variable contains no embedded null bytes.)
Step 2: Assign the Overlay
Assign the overlay at runtime using the "=@" operator, e.g.:
OVERLAY =@ VAR ! or, OVERLAY = @VAR (spaces are not significant)
This effectively gives the OVERLAY variable the same data storage location and size as the VAR variable. As mentioned above, the main motivation is to do this with dynamic arrays, e.g.:
DIMX DYNARY(x,y,z),S,n
...
OVERLAY =@ DYNARY()
Note that you may NOT specify any array subscripts for the array on the right side of the @= operator, since this technique is currently only supported to overlay the ENTIRE array.
Comments
The overlay does not automatically get updated if the target array changes in size—i.e. due to either REDIMX or AUTO_EXTEND (see Dynamic Arrays (DIMX)). However, you can reassign the overlay as needed. For example:
MAP1 AOVL,X,@0 ! declare the dynamic overlay
DIMX A(5,10),S,7 ! dimension an array
AOVL =@A() ! assign the overlay to the array
PRINT LEN(AOVL) ! prints 350 (5 x 10 x 7)
REDIMX A(10,10) ! redimension the array
PRINT LEN(AOVL) ! still prints 350 (still tracking the old allocation)
AOFL =@A() ! reassign the overlay
PRINT LEN(AOVL) ! now prints 700 (10 x 10 x 7)
So the best practice would be to (re)assign the overlay immediately before you need to use it.
Example
There is currently no corresponding operation to overlay a dynamic array on top of an X variable, which admittedly might be handy when passing such an array between routines via parameter lists. But you can get around that limitation using the technique in the following example, which passes a dynamic array to a procedure for processing:
DIMX ARY(X),S,Y
MAP1 OVL,X,@0
...
<load the array with some data>
...
OVL = @ARY() ! overlay the array with the XARY variable
CALL MYPROC(OVL,X,Y) ! pass array plus its dimensions to a function
...
! (our ARY() may have been updated by the MYPROC() procedure)
END
!-----------------
PROCEDURE MYPROC(XXARY AS X0, ELEMENTS AS F, WIDTH AS F)
DIMX LOCARY(ELEMENTS),S,WIDTH ! allocate local array to match array passed in
MAP1 LOCOVL,X,@0
MAP1 I,F
LOCOVL =@ LOCARY() ! overlay the local (currently empty) array
LOCOVL = XXARY ! now copy the data on top of that
FOR I = 1 TO ELEMENTS
<perform operations on LOCARY(I)>
NEXT I
XPUTARG 1,LOCOVL ! update caller's overlay (which is the same as
! caller's actual array) with the local array data
ENDPROCEDURE
History
2010 September, A-Shell 5.1.1192: Added to A-Shell in compiler edit 465.