Datatypes can be interfaced with the persistent object library supplied with the translator using the persistent qualifier. A persistent object defines the protocol for serializing its representation into an architecture independent format on a persistence stream.
For example, the following datatype declaration defines a persistent
type Exp
. Note that a pointer to the symbol table
is annotated with the persisent qualifier to signify that the object
associated with the pointer should be traversed during the serialization
phase.
// SymbolTable is persistent class SymbolTable: public PObject { public: class Id : public PObject { ... }; ... }; datatype Exp :: persistent = INT int | VAR (persistent SymbolTable::Id, persistent SymbolTable *) | ADD Exp, Exp | SUB Exp, Exp | MUL Exp, Exp | DIV Exp, Exp ;
A persistent object id must be provided with each distinct datatype. Object ids are used to identify the classes of persistent objects. Thus they must be unique within an application. Each persistent type tag is simply a string, and can be defined using the refine persistent statement.
For example, the following statement declares the persistent object
id for type Exp
above to be "Simple expressions"
.
refine persistent Exp => "Simple expressions";
The corresponding instantiate datatype statement will generate the appropriate methods to communicate with a persistent stream.
instantiate datatype Exp;
To write an object e to the datafile "foo"
, we can say:
#include <AD/persist/postream.h> ofstream out("foo"); Postream pout(out); pout << e; out.close();
To read the object back from the file, we can say:
#include <AD/persist/pistream.h> EXP e; ifstream in("foo"); Pistream pin(in); e = (Exp)read_object(pin); in.close();
For more details concerning persistent streams and persist objects,
please see directory <AD/persist>
for details.