Updated July 2010
See Update Notes at bottom.
As of A-Shell build 1123 of September 2008, it is 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
FUNCTION 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.
Defined structure names may end in $, but the $ is dropped when referencing the individual fields. For example:
defstruct ST_CUS
map2 id,s,10
map2 name$,s,30
endstruct
map1 cus$,ST_CUS ! structure names may end in $
map1 tmpcus,ST_CUS ! (or not)
! use the $ when referring to the structure as a whole
tmpcus = cus$
! drop the $ from structure name when referring to individual fields
cus.id = "A12345"
! field names may end in $, just like any other variable
cus.name$ = "Agamemnon"
(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.
Update Notes
A-Shell build 1187 of July 2010 (compiler enhancement (456)): reserved words are now allowed for field names within a DEFSTRUCT. For example:
DEFSTRUCT ST_TIMEDATE
MAP2 TIME,B,4
MAP2 DATE,B,4
ENDSTRUCT
Normally TIME and DATE would be disallowed since they are reserved words, but since they get appended to the structure instance name before really being used, there is no conflict here.
A-Shell build 1124 of September 2008: Initial values and overlays are now supported within DEFSTRUCT / ENDSTRUCT.
A-Shell build 1123 of September 2008: DEFSTRUCT now allows upper and lower case (or mixed case) formal structure names, and STATIC and PRIVATE instances of structures now allowed. Note that DIMX does not support structures.