These cases are handled using a combination of the CommonMetaType and
CommonOperator node packets: MP_MetaOperator
(Mop) and
MP_CommonMetaOperator
(Cmop). Meta operator node packets may
only meaningfully appear in a prototype tree where they serve as a
``place holder'' for an operator which otherwise would appear at data
communication time. Meta operators have two defining characteristics
which distinguish them from operator and meta type packets. First,
unlike a meta type packet, a meta operator packet does not
specify a leaf in the corresponding prototyped data tree.
Instead, a meta operator specifies an inner node (operator) in the
prototyped data tree where the communication of the node (operator)
itself is
shifted from data communication time to prototype specification time.
Second, unlike an operator packet, a meta operator packet has no
actual arguments. Instead, the number-of-arguments-field encodes
information about the number of arguments which are
communicated at the corresponding place in the prototyped data tree.
There are two cases to consider:
Furthermore, annotations given to a meta operator at prototype specification time fullfill the role of the annotations which otherwise would have been given to the actual operator at data communication time. This applies in particular to the prototype annotation: If a meta operator appearing in a prototype tree has an attached prototype annotation, then the corresponding arguments appearing at data communication time are of the type specified by the prototype tree following the prototype annotation. An example where annotations are attached to meta operators is shown in figure 10.
The concept of type specifications based on meta operators is very powerful and flexible. It can be used, among others, to specify the structure and content of data structures built from pointers and (even- and uneven-length) arrays, which we illustrate in the following two examples.