next up previous contents index
Next: Life Time of Terms Up: Input Previous: Attributes of Terms

Storage Options

The system (currently) provides two storage options, selectable on a per phylum basis. For both of them a C data type is generated for each phylum, together with a `create' function for each operator. In the default storage option each operator `application' just yields a new `memory cell' containing pointers to the arguments of the operator, with initialised attributes. The second storage option, called `uniq',  is more interesting. It will guarantee that if the operator is once called with a certain set of arguments, each additional call with the same arguments will yield a pointer to the cell that was created by the first call. The result is that common (sub)trees are automatically shared. This technique is known as `hashed-consing'  (because consing is the LISP function to create new cells, and hashing is used to implement this uniqueness of representation property). In this storage option attributes will be initialised only at the first call. Obviously, side effects on subterms can jeopardize this scheme: terms maintained under unique storage should not be modified (though their attributes may be modified because they do not contribute to the uniqueness). An example  application is as follows.

ID {uniq}:Str(casestring) { short type = UNDEF;};

Suppose that for each defining occurrence of an identifier a term is created with the attribute type appropriately set, then to check the type one merely has to `create' it again, e.g. through Str(yourstring) and look at the attribute. In the same way one can check if the identifier is already defined at a defining occurrence. A sketch of this code is as follows. It checks that an identifier is defined only once, and defined before its use.   

/* defining occurrence */ id = Str(mkcasestring("foo")); if (id->type != UNDEF) error("doubly defined"); id->type = USED; /* set other attributes here as well */
/* applied occurrence */ id = Str(mkcasestring("foo")); if (id->type == UNDEF) error("undefined");
Of course, this is not the most sophisticated example of a symbol table, but serves as an example.

An essential condition on phyla definitions is that all constituent phyla of a `uniq' phylum are also `uniq'. The term processor warns at generation time about violations of this condition.

As will be explained in Section 4.3, in some cases a phylum that has inherited attributes should not be stored `uniq'. The following example   declares ID as explicitly `non-uniq'.

ID {! uniq}:;
Phyla may not be declared both {uniq} and {!uniq}.

next up previous contents index
Next: Life Time of Terms Up: Input Previous: Attributes of Terms