Language enhancement: defined structures. It is now possible to assign a type name to a set of MAP statements and then use that as if it was a data type. This comes in very handy when you need to have multiple copies of a particular data structure.
To define a structure, use the new DEFSTRUCT and ENDSTRUCT keywords, to enclose a set of MAP statements (levels 2 thru 9). For example:
DEFSTRUCT PHONENUMBER
MAP2 DESCR,S,20 ! e.g. Front Office, Accounts Payable, etc.
MAP2 TYPE,S,6 ! e.g. cell, bus, home, pager
MAP2 XNUM
MAP3 COUNTRYCODE,S,3
MAP3 AREA,S,3
MAP3 NUMBER,S,10
ENDSTRUCT
DEFSTRUCT CUSREC
MAP2 ID,S,6
MAP2 NAME,S,30
MAP2 PHNUM(5),PHONENUMBER ! array of PHONENUMBER structures
MAP2 BALANCE,F
ENDSTRUCT
MAP1 SALE,CUSREC ! SALE is an instance of structure CUSREC
MAP1 PROSPECT(10),CUSREC ! PROSPECT() is an array of struct CUSREC
MAP1 PH$,PHONENUMBER ! PH$ is an instance of struct PHONENUMBER
...
PH$ = FN'GETPHONENUM$(SALE,"cell") ! retrieve cell # from customer SALE
DEFINE FN'GETPHONENUM$(cus as CUSREC, type$ as S6) as PHONENUMBER
map1 locals
map2 i,F
! locate phone number by matching type
for i = 1 to 5
if cus.PHNUM.TYPE(i) = type$ then
FN'GETPHONENUM$ = cus.PHNUM(i)
endif
next i
ENDIF
The above example illustrates defining two structures, PHONENUMBER and CUSREC. The CUSREC structure even contains an array of the PHONENUMBER structures in the PHNUM(5) field. Then it defines an instance of the CUSREC structure called SALE, an array of instances called PROSPECT(), and an instance of the PHONENUMBER structure called PH$.
The following shows the equivalent (fully expanded) form of MAP1 SALE,CUSREC:
MAP1 SALE
MAP2 SALE.ID,S,6
MAP2 SALE.NAME,S,30
MAP2 SALE.PHNUM(5)
MAP3 SALE.PHNUM.DESCR,S,20
MAP3 SALE.PHNUM.TYPE,S,6
MAP3 SALE.PHNUM.XNUM
MAP4 SALE.PHNUM.COUNTRYCODE,S,3
MAP4 SALE.PHNUM.AREA,S,3
MAP4 SALE.PHNUM.NUMBER,S,10
Note the use of the period to separate the names of structure instances from the fields in the structure.
Jo, for example, you might read the structure from a disk file and then print out the ID field as follows:
READ #CH, SALE
PRINT "Customer ID = ";SALE.ID
Defined structure names may be used similarly to the unformatted type X, and passed to functions and procedures. In the example above, the function FN'GETPHONENUM$() takes a CUSREC structure as an argument, and returns a PHONENUMBER structure.
(Note that because function names must contain a $ suffix if the function returns an S or X value, and since structures are essentially a special variation of the X type, any function returning a structure must have a $ on the end of the name.)
The formal parameter "cus as CUSREC" essentially creates a set of local map statements which are identical to the ones shown above for SALE, except with "SALE." replaced by "cus." Otherwise, in terms of parameter passing, the "cus as CUSREC" parameter is equivalent to "cus as X246". (Previously, this is how you had to pass the structure, and then you had to repeat the MAP2-MAP9 levels of the structure map statements within the Function. So the new method doesn't exactly add any new capability, but it makes using structures and especially passing them between routines much cleaner and easier.
One way to help clarify the effect of structure definitions is to compile with the /L switch, in which case the expanded forms of the structures will display in the LSX file.