Type declarationsRecord typesRecord types are structures that contain named components. The named components can be of different types. The components of a record are called fields. Parts of a record can have multiple definitions to allow the information stored in a record to vary according to different needs. These parts are called variant sections. The identifier following CASE in variant sections is called the tag field of the variant section. Its value indicates which variant is present in the record. To specify record types, use: RECORD FieldListSequence is: FieldList {;FieldList} FieldList is either of the following: identifier {,identifier}: TypeSpecification or CASE [identifier] : TypeName OF Variant is: [ CaseRange {,CaseRange}: FieldListSequence ] CaseRange is: expression [..expression] {, expression [..expression]} Examples: RECORD This record has two fields, X and Y, both of type REAL. This record might be used to represent a point in a plane. RECORD This record has one field, NEXT, followed by a variant section. The variant section has two variants, one for the NodeType Operator and one for Operand. A variant in a RECORD must handle all possible values of the tag field type. Thus if the CASE selector arms do not handle all possible values you must have an ELSE section in the CASE. The ELSE section can be empty. In this way you are informing the compiler you understand that all values are not handled and this is the necessary behavior. Field selectionYou can select a field of a record type variable as follows: variable.field Where variable is a record variable and field is the name of the field. If the field is a part of a variant section with a tag field specified, it is an error to refer to any field in a variant other than the one specified by the tag field. If you refer to a field in an incorrect variant, and the module was compiled with variant checking on, the program generates a runtime error. Copying of variant recordsThe compiler allocates variables of variant record types the maximum amount of memory needed by any variant. These variables are, therefore, capable of holding any variant, and copying one record to another will work correctly. If you use the NEW standard procedure to allocate a variant record and specify the values of the tag fields, the compiler allocates only enough memory for the specific variants you selected. You cannot do assignments of the entire record to records allocated in that way, because the amount of space allocated might not be large enough to hold the record you are assigning. If you intend to do an assignment of the whole record, use NEW without specifying any tags. In this case, the compiler allocates space for the largest variant. Example: TYPE VARREC = RECORD CASE Tag : INTEGER OF 1: R : REAL; | 2: L : LONGREAL; ELSE END; END; VAR A : VARREC; B : POINTER TO VARREC; BEGIN NEW(B); B^ := A; (* Correct *) NEW(B, 1); B^ := A; (* Incorrect *) END; Source:
|