next up previous contents
Next: Type Specifications in Hoof Up: Hoof Files in Detail Previous: Module Definitions   Contents

Class Definitions

        <declaration> ::= <construct_declaration> | <value_declaration> | ;

The (obscurely named) <construct_declaration> declares a class. The <value_declaration> declares a union.

        <value_declaration> ::= value <identifier> = <clauses>;
        <clauses> ::= <type_specification> <forwarders>
                    | <type_specification> <forwarders> "|" <clauses>

The <identifier> is the name given to the union. Each clause in <clauses> defines one field of the union.

The <forwarders> describe fields of the type which are to be forwarded as if they were present in the union.

Construct declarations take the form:

        <construct_declaration> ::=
                  <construct_type> <identifier> <rename> <parent>
                  "{"
                       <construct_parts>
                       <member_declarations>
                       <member_definitions>
                  "}" ;
        <construct_type> ::= abstract | concrete
        <rename> ::= [ <identifier> ] | <empty>
        <parent> ::= : <identifier> | <empty>

The <construct_type> is ignored, as is the <rename> clause. The <parent> field gives the name of the class from which this is derived. If a class does not derive from another Hoof defined class, the parent must be given as SuifObject.

The body of the declarations contains a set of fields (<construct_parts>) and occasionally a list of member declarations and definitions. The declarations are just a way of introducing extra members into the classes.

The <construct_parts> contains a list of fields.

        <construct_parts> ::= <construct_part>
                            | <construct_part> <construct_parts>

        <construct_part> ::= <regular_field_declaration>
                            | <friend_declaration>
                            | <empty>

        <regular_field_declaration> ::= <virtual> <type_specification>
                             <identifier> <in_clause> <implements_clause>
                             <may_be_present> <key_dec> <notify>;

        <virtual> ::= virtual | virtual default "{" <verbatim> "}" | <empty>
        <in_clause> ::= in <identifier> | <empty>
        <implements_clause> ::= implements <identifier> | <empty>
        <key_dec> ::= key | <empty>
        <notify> ::= notify | <empty>

A <friend_declaration> just allows you to declare a friend class as you would in C++. The field declarations are all <regular_field_declarations>.

A field declaration may be virtual. This means that the field does not actually exist in the class but will exist in classes derived from this one. The methods that would be associated with such a field are declared in this class in the resulting code but they are virtual and will be overridden in the derived classes. This is useful when various derived classes will require different implementations of the virtual field.

You can give a default as part of the virtual field. Normally, if you call the get method associated with a virtual field, you will receive an assertion failure. The default associated with the virtual keyword allows you to give some other code to be performed. A common case is to write:

        virtual default return 0;

The <type_specification> gives the type of the field. These are discussed in the section of type specifications below.

The <identifier> in the field declaration is the name to be given to the field. This name is used in all the methods. The name of the field in the generated code will have an underline added at the start.

The <in_clause> is used to specify that this field is part of a group of fields that can be iterated over. For example, the declaration of conditional statements states the field condition is an operand:          Expression owner * condition in operands;

The <implements> clause declares that this field implements a field that has been declared virtual in a parent class. The identifier in the implements clause is the name of the implemented field.

The <key_dec> clause declares that this field is a key for this class. An equality operator will be defined for this class which takes the field type as parameter and, if the class is used as the element type of a searchable_list find routine will be generated for the searchable list using this field type as key.

The <may_be_present> clause defines a number of possible options for the initialization of the field when an object of the class is constructed using the create_ routine defined in the object factory.

        <may_be_present> ::= optional | <default_value> | <build_value> |
                             <omitted> |
        <omitted> ::= omitted
        <default_value> ::= default "{"<verbatim>"}"
        <build_value> ::= build "{"<verbatim>"}"

A field which is declared optional will be given a default value of 0 in the create_ routine. The type must be such that this is acceptable. If some other default value is wanted, the default_value qualifier should be used instead.

The build_value qualifier is used for fields that require the default value to be built in the context of the object factory rather than the context of the call. This is usually only used for pointers. The default value will be 0 (NULL) but a real value will be build inside the create routine. This is used, for example, when building a definition block to avoid having to build the symbol tables that it will contain explicitly.

Finally, if a field is declared as omitted it will not appear in the list of parameters in the create routine at all. Instead, it will be assigned the value 0 in the create routine.

Default values are a problem with C++ because of the lack of named parameters. A derived class's default parameters will appear before the non-defaulted parameters of the parent. This causes compilation errors on some compilers.


next up previous contents
Next: Type Specifications in Hoof Up: Hoof Files in Detail Previous: Module Definitions   Contents
David Heine
1999-11-22