Importing Header Files¶
You import C definitions into Dylan by specifying one or more
header files in an #include
clause. This may take one of two
different forms:
define interface
#include "file1.h";
end interface;
or
define interface
#include {"file1.h", "file2.h"};
end interface;
Melange will parse all of the named files in the specified
order, and produce Dylan equivalents for (i.e. “import”) some
fraction of declarations in these files. By default, Melange
will import all of the declarations from the named files, and
any declarations in recursively included files (i.e. those
specified via #include
directives in the .h
file) which are
referenced by imported definitions. It will not, however, import
every declaration in recursively included files. This insures
that you will see a complete, usable, set of declarations
without having to closely control the importation process. If
you wish to exert more control over the set of objects to be
imported, you may do so via the import
, exclude
, and
exclude-file
options.
If you only need a small set of definitions from a set of
imported files, you can explicitly specify the complete list of
declarations to be imported by using the import:
option. You
could, for example, say:
define interface
#include "gc.h",
import: {"scavenge", "transport" => move};
end interface;
This would result in Dylan definitions for scavenge
,
move
, <obj_t>
, and <obj>
. The latter types
would be dragged in because they are referenced by the two
imported functions. Again, if you equated obj_t
to
<object>
then neither of the types would be imported. The
second import in the above example performs a renaming at the
same time as it specifies the object to be imported. Other forms
specify global behaviors. Import: all
will cause Melange to
import every “top level” definition which is not explicitly
excluded. Import: all-recursive
causes it to import
definitions from recursively included files as well. Import:
none
restricts importation to those declarations which are
explicitly imported or are used by an imported declaration. You
may also use the import:
option to specify importation
behavior on a per-file basis. The options
import: "file.h" => {"import1", ...}
import: "file.h" => all
import: "file.h" => none
work like the options described above, except that they
only apply to the symbols in a single imported file. The
exclude:
and exclude-file:
options may be used to keep one
or more unwanted definitions from being imported. For example,
you could use:
define interface
#include "gc.h",
exclude: {"scavenge", "transport"},
exclude-file: "gc1.h";
end interface;
This would prevent the two named functions and everything
in the named file from being imported, while still including all
of the other definitions from gc.h
. Note that these options
should be used with care, as they can easily result in
“incomplete” interfaces in which some declarations refer to
types which are not defined. This could result in errors in the
generated Dylan code. (The import: file => none
option
described above is a safer way of achieving an effect similar to
exclude-file:
.)
You may also prevent some type declarations from being
imported by using the equate:
option (described in a later
section). If, for example, you equated obj_t
to
<object>
, then Melange would ignore the definition for
obj_t
and simply assume that the existing definition for
<object>
was sufficient.
You may have any number of import:
, exclude:
, and
exclude-file:
options, and may name the same declarations in
multiple clauses. Exclude:
options take priority over
import:
. If no import:
options are specified, the system
will import all non-excluded symbols, just as if you had said
import: all
.