Previous - Up - Next

4.9   Global Declarations

The following sections describe the global declarations in DML. These can only occur on the top level of a DML program, i.e., not within an object or method. Unless otherwise noted, their scope is the entire program.

4.9.1   Import Declarations

import filename;

Imports the contents of the named file. filename must be a string literal, such as "utility.dml". The -I option to the dmlc compiler can be used to specify directories to be searched for import files.

Note that imported files are parsed as separate units, and use their own language version and bit order declarations.

4.9.2   Template Declarations

template name desc { ... }

Defines a named template - a piece of code that can be reused in multiple locations. This is similar to a C preprocessor macro; however, unlike macros, the body cannot consist of arbitrary text, but must have the same form as an object declaration body. Also, DML templates do not take any arguments; instead, the generic DML parameter system is used for such purposes.

Templates are instantiated using is declarations, written as

    is name;
These can be used in any context where an object declaration may be written, and has the effect of expanding the body of the template at the point of the is. Note that the expansion is purely textual, so e.g., two templates which define methods with the same name cannot both be used in the same context.

As in an object declaration, unless the desc string is omitted, it is equivalent to defining the parameter desc, as in

    template name {
        parameter desc = desc;
        ...
    }
Hence, the description does not pertain to the template in itself, but to any object which uses the template.

4.9.3   Bitorder Declarations

bitorder name;

Selects the default bit order to be used for interpreting bit-slicing expressions and bit field declarations in the file. name is one of the identifiers le, be16, be32, and be64, implying either little-endian order with arbitrary default width (le), or big-endian order with a fixed default width in bits (be...). Only the listed widths are allowed.

A bitorder declaration, if present, must follow immediately after the device declaration, preceding any other global declarations. The scope of the declaration is the whole of the file it occurs in. If no bitorder declaration is present in a file, the default bit order is le (little-endian). The bitorder does not extend to imported files; for example, if a file containing a declaration "bitorder be32;" imports a file with no bit order declaration, the latter file will still use the default le order.

Note that it is difficult to write general bit-manipulating methods for arbitrary-width data, if big-endian conventions are used. It is often a better idea to place such code in a separate file which uses little-endian order, and then import that file from a big-endian context.

4.9.4   Constant Declarations

constant name = expr;

Defines a named constant which can be used in C context. expr must be a constant-valued expression.

4.9.5   Loggroup Declarations

loggroup name;

Defines a log group, for use in log statements. More generally, the identifier name is bound to an unsigned integer value that is a power of 2, and can be used anywhere in C context; this is similar to a constant declaration, but the value is allocated automatically so that all log groups are represented by distinct powers of 2 and can be combined with bitwise or (see Section 4.11.7).

4.9.6   Typedef Declarations

typedef declaration;

Defines a name for a data type, as in C.

4.9.7   Struct Declarations

struct name { declarations }

Declares a structure datatype with the given name; this is similar to a C struct declaration, but in DML, there is no separate namespace for structs. The effect is like that of writing "typedef struct { ... } name;" in C, although in DML, name can also be used for recursive definitions within the struct, as in

    struct my_struct {
        my_struct *next;
        ...
    }

4.9.8   Extern Declarations

extern declaration;

Declares an external identifier, similar to a C extern declaration; for example,

    extern int;
    extern char *motd;
    extern double table[16];
    extern conf_object_t *obj;
    extern int foo(int x);
    extern int printf(const char *format, ...);

4.9.9   Header Declarations

header %{
...
%}

Specifies a section of C code which will be included verbatim in the generated C header file for the device. There must be no whitespace between the % and the corresponding brace in the %{ and %} markers. The contents of the header section are not examined in any way by the dmlc compiler; declarations made in C code must also be specified separately in the DML code proper.

This feature should only be used to solve problems that cannot easily be handled directly in DML. It is most often used to make the generated code include particular C header files, as in:

    header %{
    #include "extra_defs.h"
    %}
See also footer declarations, below.

4.9.10   Footer Declarations

footer %{
...
%}

Specifies a piece of C code which will be included verbatim at the end of the generated code for the device. There must be no whitespace between the % and the corresponding brace in the %{ and %} markers. The contents of the footer section are not examined in any way by the dmlc compiler.

This feature should only be used to solve problems that cannot easily be handled directly in DML. See also header declarations, above.

Previous - Up - Next