Structure References
The basic syntax of a reference to a field within a structure is:
Variable_name . Tag_name
Variable_name must be a variable that contains a structure;
Tag_name is the name of the field and must exist for the structure.
If the field referred to by the tag name is a structure, the tag name may optionally be followed by one or more additional tag names. For example:
VAR.TAG1.TAG2
This nesting of structure references can be continued up to ten levels. Each tag name, except possibly the last, must refer to a field that contains a structure.
Subscripted Structure References
In addition, a subscript specification may be appended to the variable or tag names if the variable is an array of structures, or if the field referred to by the tag contains an array:
Variable_name . Tag_name(Subscripts)
Variable_name(Subscripts) . Tag_name ...
or:
Variable_name(Subscripts) . Tag_name(Subscripts)
Each subscript is applied to the variable or tag name it follows.
The syntax and meaning of the subscript specification is similar to simple array subscripting: it may contain a simple subscript, array of subscripts, or a subscript range. See Chapter 6, Using Subscripts, for more information about subscripts.
If a variable or field containing an array is referenced without a subscript specification, all elements of the item are affected. Similarly, when a variable that contains an array of structures is referenced without a subscript but with a tag name, the designated field in all array elements is affected.
The complete syntax of references to structures is:
Structure_ref  :=  Variable_name [(subscripts)] . Tags
Tags  :=  [Tags . ] Tag
Tag  :=  Tag_name [(subscripts)]
Optional items are enclosed in square brackets, [ ]. For example, all of the following are valid structure references:
A.B
A.B(N, M)
A(12).B
A(3:5).B(*, N)
A(12).B.C(X, *)
The semantics of storing into a structure field using subscript ranges are slightly different than that of simple arrays. This is because the dimension of arrays in fields is fixed. See "Storing into Structure Array Fields".
Examples of Structure References
The name of the star contained in STAR is referenced as STAR.NAME, the entire intensity array is referred to as STAR.INTEN, while the nth element of STAR.INTEN is STAR.INTEN(N). The following are valid statements using the CATALOG structure:
; Store a structure of type CATALOG into variable STAR. Define
; the values of all fields. 
STAR = {CATALOG, NAME: 'SIRIUS', RA: 30., $ 
DEC: 40., INTEN: INDGEN(12)}
 
; Set name field. Other fields remain unchanged. 
STAR.NAME = 'BETELGEUSE' 
; Print name, right ascension, and declination.
PRINT, STAR.NAME, STAR.RA, STAR.DEC 
; Set Q to the value of the 6th element of STAR.INTEN. Q will be 
; a floating-point scalar.
Q = STAR.INTEN(5)
; Set RA field to 23.21.
STAR.RA = 23.21
; Zero all 12 elements of intensity field. Because the type and 
; size of STAR.INTEN are fixed by the structure definition, the 
; semantics of assignment statements are somewhat different than 
; with normal variables.
STAR.INTEN = 0 
; Store 4th through 7th elements of INTEN field in variable B.
B = STAR.INTEN(3:6)
; The integer 12 is converted to string and stored in the name 
; field because the field is defined as a string.
STAR.NAME = 12
; Copy STAR to MOON. The entire structure is copied and MOON
; contains a CATALOG structure.
MOON = STAR
Using INFO with Structures
Use INFO, /Structure to determine the type, structure, and tag name of each field in a structure. In the example above, a structure was stored into variable STAR. The statement:
INFO, /Structure, STAR
prints the following information:
** Structure CATALOG, 4 tags, 60 length:
NAME  STRING (null)'
RA    FLOAT  0.0
DEC   FLOAT  0.0
INTEN FLOAT  Array(12)
Calling INFO with the Structure keyword and no parameters prints a list of all defined structures and tag names. In addition to the Structure keyword, the Userstruct and Sysstruct INFO keywords can also be used to obtain information about structures. See Chapter 13: Getting Session Information, for information on these keywords.
Parameter Passing with Structures
As explained in "Parameter Passing Mechanism", PV-WAVE passes simple variables by reference and everything else by value.
An entire structure is passed by reference by simply using the name of the variable containing the structure as a parameter. Changes to the parameter within the procedure are passed back to the caller.
Fields within a structure are passed by value. For example, to print the value of STAR.NAME:
PRINT, STAR.NAME
Any reference to a structure with a subscript or tag name is evaluated into an expression, hence STAR.NAME is an expression and is passed by value. This works as expected unless the called procedure returns information in the parameter, as in the call to READ:
READ, STAR.NAME
which does not read into STAR.NAME, but interprets its parameter as a prompt string. The proper code to read into the field is:
; Copy type and attributes to variable.
B = STAR.NAME
; Read into a simple variable.
READ, B
; Store result into field.
STAR.NAME = B
Storing into Structure Array Fields
As was mentioned above, the semantics of storing into structure array fields is slightly different than storing into simple arrays. The main difference is that with structures a subscript range must be used when storing an array into part of an array field. With normal arrays, when storing an array inside part of another array, use the subscript of the lower-left corner, not a range specification.
Other differences occur because the size and type of a field are fixed by the original structure definition and the normal PV-WAVE semantics of dynamic binding are not applicable.
The rules for storing into array fields are:
Rule 1
VAR.TAG = scalar_expr 
The field TAG is an array. All elements of VAR .TAG are set to scalar_expr. For, example:
; Sets all 12 elements of STAR.INTEN to 100.
STAR.INTEN = 100
Rule 2
VAR.TAG = array_expr 
Each element of array_expr is copied to the array VAR.TAG. If array_ expr contains more elements than does the destination array an error results. If it contains fewer elements than VAR.TAG, the unmatched elements remain unchanged. Example:
; Sets STAR.INTEN to the 12 numbers 0, 1, 2, ..., 11.
STAR.INTEN = FINDGEN(12)
; Sets STAR.INTEN(0) to 1 and STAR.INTEN(1) to 2. The 
; other elements remain unchanged.
STAR.INTEN = [1, 2]
Rule 3
VAR.TAG(subscript) = scalar_expr
The value of the scalar expression is simply copied into the designated element of the destination. If subscript is an array of subscripts, the scalar expression is copied into the designated elements. Example:
; Sets the 6th element of STAR.INTEN to 100.
STAR.INTEN(5) = 100
; Sets elements 2, 4, and 6 to 100.
STAR.INTEN([2, 4, 6]) = 100.
Rule 4
VAR.TAG(subscript) = array_expr
Unless VAR.TAG is an array of structures, the subscript must be an array. Each element of array_expr is copied into the element of VAR.TAG given by the corresponding element subscript. Example:
; Sets elements 2, 4, and 6 to the values 5, 7, and 9.
STAR.INTEN([2, 4, 6]) = [5, 7, 9]
Rule 5
VAR .TAG (subscript_range) = scalar_expr
The value of the scalar expression is stored into each element specified by the subscript range. Example:
; Sets elements 8, 9, 10, and 11, to the value 5.
STAR.INTEN(8 : *) = 5
Rule 6
VAR.TAG (subscript_range) = array_expr
Each element of the array expression is stored into the element designated by the subscript range. The number of elements in the array expression must agree with the size of the subscript range. Example:
; Sets elements 3, 4, 5, and 6 to the numbers 0, 1, 2, and
; 3, respectively.
STAR.INTEN(3 : 6) = findgen(4)
See "Creating Variable-length Array Fields" for information on placing variable-length arrays in structures.