Dynamic Overlays

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. 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.