/////////////////////////////////////////////////////////////////////////////// // This file is generated automatically using Prop (version 2.3.0), // last updated on Feb 5, 1997. // The original source file is "persistence.pC". /////////////////////////////////////////////////////////////////////////////// #define PROP_REWRITING_USED #define PROP_PRINTER_USED #define PROP_PERSISTENCE_USED #define PROP_QUARK_USED #include ////////////////////////////////////////////////////////////////////////////// // Testing persistence in Prop. // // Persistence currently only means that objects are serializable into // a byte stream. Objects are inserted in network byte order so that // they are portable across platforms. Furthermore, pointer sharing // is preserved. ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include // Definition of type Bool #include // persistence streams ////////////////////////////////////////////////////////////////////////////// // // Define a datatype with pretty printing. // ////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Forward class definition for EXP /////////////////////////////////////////////////////////////////////////////// #ifndef datatype_EXP_defined #define datatype_EXP_defined typedef class a_EXP * EXP; #endif /////////////////////////////////////////////////////////////////////////////// // Class hierarchy for datatype EXP /////////////////////////////////////////////////////////////////////////////// class a_EXP; // base class for datatype EXP class EXP_num; // subclass for 'num int' class EXP_var; // subclass for 'var ID' class EXP_add; // subclass for 'add (EXP, EXP)' class EXP_sub; // subclass for 'sub (EXP, EXP)' class EXP_mul; // subclass for 'mul (EXP, EXP)' class EXP_div; // subclass for 'div (EXP, EXP)' /////////////////////////////////////////////////////////////////////////////// // Definition of type ID /////////////////////////////////////////////////////////////////////////////// typedef char const * ID; /////////////////////////////////////////////////////////////////////////////// // Base class for datatype 'EXP' /////////////////////////////////////////////////////////////////////////////// class a_EXP : public PObject { public: enum Tag_EXP { tag_num = 0, tag_var = 1, tag_add = 2, tag_sub = 3, tag_mul = 4, tag_div = 5 }; protected: const Tag_EXP _tag_; inline a_EXP(Tag_EXP _t_) : _tag_(_t_) {} public: inline int untag() const { return _tag_; } inline friend int boxed(const a_EXP * x) { return 1; } inline friend int untag(const a_EXP * x) { return x->_tag_; } //////////////////////////////////////////////////////////////////////////// // Downcasting functions for EXP //////////////////////////////////////////////////////////////////////////// inline friend EXP_num * _num(EXP _x_) { return (EXP_num *)_x_; } inline friend EXP_var * _var(EXP _x_) { return (EXP_var *)_x_; } inline friend EXP_add * _add(EXP _x_) { return (EXP_add *)_x_; } inline friend EXP_sub * _sub(EXP _x_) { return (EXP_sub *)_x_; } inline friend EXP_mul * _mul(EXP _x_) { return (EXP_mul *)_x_; } inline friend EXP_div * _div(EXP _x_) { return (EXP_div *)_x_; } //////////////////////////////////////////////////////////////////////////// // Methods for persistence and object serialization //////////////////////////////////////////////////////////////////////////// protected: virtual const PObjectType& persist_type_id () const; virtual Pistream& persist_read (Pistream&); virtual Postream& persist_write (Postream&) const; public: }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'EXP::num int' /////////////////////////////////////////////////////////////////////////////// class EXP_num : public a_EXP { public: int num; inline EXP_num (int _xnum) : a_EXP(a_EXP::tag_num), num(_xnum) {} inline friend a_EXP * num (int _xnum) { return new EXP_num (_xnum); } //////////////////////////////////////////////////////////////////////////// // Methods for persistence and object serialization //////////////////////////////////////////////////////////////////////////// protected: virtual const PObjectType& persist_type_id () const; virtual Pistream& persist_read (Pistream&); virtual Postream& persist_write (Postream&) const; public: private: //////////////////////////////////////////////////////////////////////////// // Default constructor used in persistence object factory //////////////////////////////////////////////////////////////////////////// friend class PObjectFactory< EXP_num >; inline EXP_num() : a_EXP(a_EXP::tag_num) {} public: }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'EXP::var ID' /////////////////////////////////////////////////////////////////////////////// class EXP_var : public a_EXP { public: ID var; inline EXP_var (ID _xvar) : a_EXP(a_EXP::tag_var), var(_xvar) {} inline friend a_EXP * var (ID _xvar) { return new EXP_var (_xvar); } //////////////////////////////////////////////////////////////////////////// // Methods for persistence and object serialization //////////////////////////////////////////////////////////////////////////// protected: virtual const PObjectType& persist_type_id () const; virtual Pistream& persist_read (Pistream&); virtual Postream& persist_write (Postream&) const; public: private: //////////////////////////////////////////////////////////////////////////// // Default constructor used in persistence object factory //////////////////////////////////////////////////////////////////////////// friend class PObjectFactory< EXP_var >; inline EXP_var() : a_EXP(a_EXP::tag_var) {} public: }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'EXP::add (EXP, EXP)' /////////////////////////////////////////////////////////////////////////////// class EXP_add : public a_EXP { public: EXP _1; EXP _2; inline EXP_add (EXP _x1, EXP _x2) : a_EXP(a_EXP::tag_add), _1(_x1), _2(_x2) {} inline friend a_EXP * add (EXP _x1, EXP _x2) { return new EXP_add (_x1, _x2); } //////////////////////////////////////////////////////////////////////////// // Methods for persistence and object serialization //////////////////////////////////////////////////////////////////////////// protected: virtual const PObjectType& persist_type_id () const; virtual Pistream& persist_read (Pistream&); virtual Postream& persist_write (Postream&) const; public: private: //////////////////////////////////////////////////////////////////////////// // Default constructor used in persistence object factory //////////////////////////////////////////////////////////////////////////// friend class PObjectFactory< EXP_add >; inline EXP_add() : a_EXP(a_EXP::tag_add) {} public: }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'EXP::sub (EXP, EXP)' /////////////////////////////////////////////////////////////////////////////// class EXP_sub : public a_EXP { public: EXP _1; EXP _2; inline EXP_sub (EXP _x1, EXP _x2) : a_EXP(a_EXP::tag_sub), _1(_x1), _2(_x2) {} inline friend a_EXP * sub (EXP _x1, EXP _x2) { return new EXP_sub (_x1, _x2); } //////////////////////////////////////////////////////////////////////////// // Methods for persistence and object serialization //////////////////////////////////////////////////////////////////////////// protected: virtual const PObjectType& persist_type_id () const; virtual Pistream& persist_read (Pistream&); virtual Postream& persist_write (Postream&) const; public: private: //////////////////////////////////////////////////////////////////////////// // Default constructor used in persistence object factory //////////////////////////////////////////////////////////////////////////// friend class PObjectFactory< EXP_sub >; inline EXP_sub() : a_EXP(a_EXP::tag_sub) {} public: }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'EXP::mul (EXP, EXP)' /////////////////////////////////////////////////////////////////////////////// class EXP_mul : public a_EXP { public: EXP _1; EXP _2; inline EXP_mul (EXP _x1, EXP _x2) : a_EXP(a_EXP::tag_mul), _1(_x1), _2(_x2) {} inline friend a_EXP * mul (EXP _x1, EXP _x2) { return new EXP_mul (_x1, _x2); } //////////////////////////////////////////////////////////////////////////// // Methods for persistence and object serialization //////////////////////////////////////////////////////////////////////////// protected: virtual const PObjectType& persist_type_id () const; virtual Pistream& persist_read (Pistream&); virtual Postream& persist_write (Postream&) const; public: private: //////////////////////////////////////////////////////////////////////////// // Default constructor used in persistence object factory //////////////////////////////////////////////////////////////////////////// friend class PObjectFactory< EXP_mul >; inline EXP_mul() : a_EXP(a_EXP::tag_mul) {} public: }; /////////////////////////////////////////////////////////////////////////////// // class for constructor 'EXP::div (EXP, EXP)' /////////////////////////////////////////////////////////////////////////////// class EXP_div : public a_EXP { public: EXP _1; EXP _2; inline EXP_div (EXP _x1, EXP _x2) : a_EXP(a_EXP::tag_div), _1(_x1), _2(_x2) {} inline friend a_EXP * div (EXP _x1, EXP _x2) { return new EXP_div (_x1, _x2); } //////////////////////////////////////////////////////////////////////////// // Methods for persistence and object serialization //////////////////////////////////////////////////////////////////////////// protected: virtual const PObjectType& persist_type_id () const; virtual Pistream& persist_read (Pistream&); virtual Postream& persist_write (Postream&) const; public: private: //////////////////////////////////////////////////////////////////////////// // Default constructor used in persistence object factory //////////////////////////////////////////////////////////////////////////// friend class PObjectFactory< EXP_div >; inline EXP_div() : a_EXP(a_EXP::tag_div) {} public: }; ostream& operator << (ostream&,EXP); ostream& pretty_print(ostream&,EXP,int = 0,int = 0); ////////////////////////////////////////////////////////////////////////////// // Make the datatype persistent by defining the persistence type tag for // its constructors. // // The persistence type tag *must* be unique for each constructor. // // The datatype definition together with the following refinement // declaration can together serve as some sort of interface definition. // The type EXP can now be communicated between programs through persistent // streams. ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // Instantiate the datatype. This declaration will generate all // necessary pretty printing and persistence serialization methods. ////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Pretty printer for type EXP /////////////////////////////////////////////////////////////////////////////// ostream& pretty_print(ostream& _f_, EXP _x_, int _tab_, int _prec_) { switch (untag(_x_)) { case a_EXP::tag_num: _f_ << _num(_x_)->num; break; case a_EXP::tag_var: _f_ << _var(_x_)->var; break; case a_EXP::tag_add: _f_ << "("; pretty_print(_f_, _add(_x_)->_1, _tab_, _prec_); _f_ << " + "; pretty_print(_f_, _add(_x_)->_2, _tab_, _prec_); _f_ << ")"; break; case a_EXP::tag_sub: _f_ << "("; pretty_print(_f_, _sub(_x_)->_1, _tab_, _prec_); _f_ << " - "; pretty_print(_f_, _sub(_x_)->_2, _tab_, _prec_); _f_ << ")"; break; case a_EXP::tag_mul: _f_ << "("; pretty_print(_f_, _mul(_x_)->_1, _tab_, _prec_); _f_ << " * "; pretty_print(_f_, _mul(_x_)->_2, _tab_, _prec_); _f_ << ")"; break; case a_EXP::tag_div: _f_ << "("; pretty_print(_f_, _div(_x_)->_1, _tab_, _prec_); _f_ << " / "; pretty_print(_f_, _div(_x_)->_2, _tab_, _prec_); _f_ << ")"; break; } return _f_; } ostream& operator << (ostream& _f_, EXP _x_) { return pretty_print(_f_,_x_); } /////////////////////////////////////////////////////////////////////////////// // Persistence read/write methods for base class of EXP /////////////////////////////////////////////////////////////////////////////// static PObjectType _T1("Simple expressions" "(EXP::base_class)"); const PObjectType& a_EXP::persist_type_id() const { return _T1; } Pistream& a_EXP::persist_read (Pistream& _f_) { } Postream& a_EXP::persist_write (Postream& _f_) const { } /////////////////////////////////////////////////////////////////////////////// // Persistence read/write methods for EXP::num int /////////////////////////////////////////////////////////////////////////////// static PObjectType _T2("Simple expressions" "(EXP::num)"); const PObjectType& EXP_num::persist_type_id() const { return _T2; } static PObjectFactory< EXP_num > _T3(_T2); Pistream& EXP_num::persist_read (Pistream& _f_) { _f_ >> num; // int } Postream& EXP_num::persist_write (Postream& _f_) const { _f_ << num; // int } /////////////////////////////////////////////////////////////////////////////// // Persistence read/write methods for EXP::var ID /////////////////////////////////////////////////////////////////////////////// static PObjectType _T4("Simple expressions" "(EXP::var)"); const PObjectType& EXP_var::persist_type_id() const { return _T4; } static PObjectFactory< EXP_var > _T5(_T4); Pistream& EXP_var::persist_read (Pistream& _f_) { _f_ >> var; // ID } Postream& EXP_var::persist_write (Postream& _f_) const { _f_ << var; // ID } /////////////////////////////////////////////////////////////////////////////// // Persistence read/write methods for EXP::add (EXP, EXP) /////////////////////////////////////////////////////////////////////////////// static PObjectType _T6("Simple expressions" "(EXP::add)"); const PObjectType& EXP_add::persist_type_id() const { return _T6; } static PObjectFactory< EXP_add > _T7(_T6); Pistream& EXP_add::persist_read (Pistream& _f_) { _1 = (EXP )read_object(_f_); // EXP _2 = (EXP )read_object(_f_); // EXP } Postream& EXP_add::persist_write (Postream& _f_) const { _f_ << _1; // EXP _f_ << _2; // EXP } /////////////////////////////////////////////////////////////////////////////// // Persistence read/write methods for EXP::sub (EXP, EXP) /////////////////////////////////////////////////////////////////////////////// static PObjectType _T8("Simple expressions" "(EXP::sub)"); const PObjectType& EXP_sub::persist_type_id() const { return _T8; } static PObjectFactory< EXP_sub > _T9(_T8); Pistream& EXP_sub::persist_read (Pistream& _f_) { _1 = (EXP )read_object(_f_); // EXP _2 = (EXP )read_object(_f_); // EXP } Postream& EXP_sub::persist_write (Postream& _f_) const { _f_ << _1; // EXP _f_ << _2; // EXP } /////////////////////////////////////////////////////////////////////////////// // Persistence read/write methods for EXP::mul (EXP, EXP) /////////////////////////////////////////////////////////////////////////////// static PObjectType _T10("Simple expressions" "(EXP::mul)"); const PObjectType& EXP_mul::persist_type_id() const { return _T10; } static PObjectFactory< EXP_mul > _T11(_T10); Pistream& EXP_mul::persist_read (Pistream& _f_) { _1 = (EXP )read_object(_f_); // EXP _2 = (EXP )read_object(_f_); // EXP } Postream& EXP_mul::persist_write (Postream& _f_) const { _f_ << _1; // EXP _f_ << _2; // EXP } /////////////////////////////////////////////////////////////////////////////// // Persistence read/write methods for EXP::div (EXP, EXP) /////////////////////////////////////////////////////////////////////////////// static PObjectType _T12("Simple expressions" "(EXP::div)"); const PObjectType& EXP_div::persist_type_id() const { return _T12; } static PObjectFactory< EXP_div > _T13(_T12); Pistream& EXP_div::persist_read (Pistream& _f_) { _1 = (EXP )read_object(_f_); // EXP _2 = (EXP )read_object(_f_); // EXP } Postream& EXP_div::persist_write (Postream& _f_) const { _f_ << _1; // EXP _f_ << _2; // EXP } ////////////////////////////////////////////////////////////////////////////// // A simple rewrite class to verify pointer sharing between nodes. ////////////////////////////////////////////////////////////////////////////// class VerifySharing : public BURS { private: VerifySharing(const VerifySharing&); // no copy constructor void operator = (const VerifySharing&); // no assignment public: struct VerifySharing_StateRec * stack__, * stack_top__; public: void labeler(const char *, int&, int); void labeler(Quark, int&, int); void labeler(EXP & redex, int&, int); inline virtual void operator () (EXP & redex) { int s; labeler(redex,s,0); } private: public: VerifySharing() {} }; inline void VerifySharing::labeler(char const * redex,int& s__,int) { { s__ = 0; } } inline void VerifySharing::labeler(Quark redex,int& s__,int) { { s__ = 0; } } void VerifySharing::labeler (EXP & redex, int& s__, int r__) { replacement__: switch(redex->untag()) { case a_EXP::tag_num: { int s0__; s0__ = 0; // int s__ = 0;} break; case a_EXP::tag_var: { int s0__; labeler(_var(redex)->var, s0__, r__); s__ = 0;} break; case a_EXP::tag_add: { int s0__; int s1__; labeler(_add(redex)->_1, s0__, r__); labeler(_add(redex)->_2, s1__, r__); s__ = 0;} break; case a_EXP::tag_sub: { int s0__; int s1__; labeler(_sub(redex)->_1, s0__, r__); labeler(_sub(redex)->_2, s1__, r__); s__ = 1;} break; case a_EXP::tag_mul: { int s0__; int s1__; labeler(_mul(redex)->_1, s0__, r__); labeler(_mul(redex)->_2, s1__, r__); s__ = 2;} break; default: { int s0__; int s1__; labeler(_div(redex)->_1, s0__, r__); labeler(_div(redex)->_2, s1__, r__); s__ = 3;} break; } switch (s__) { case 3: { assert(_div(redex)->_1 == _div(redex)->_2); } break; case 2: { assert(_mul(redex)->_1 == _mul(redex)->_2); } break; case 1: { assert(_sub(redex)->_1 == _sub(redex)->_2); } break; } } ////////////////////////////////////////////////////////////////////////////// // Equality between expressions. ////////////////////////////////////////////////////////////////////////////// Bool equal(EXP a, EXP b) { { switch (a->untag()) { case a_EXP::tag_num: { switch (b->untag()) { case a_EXP::tag_num: { return _num(a)->num == _num(b)->num; } break; default: { L1:; return false; } break; } } break; case a_EXP::tag_var: { switch (b->untag()) { case a_EXP::tag_var: { return strcmp(_var(a)->var,_var(b)->var) == 0; } break; default: { goto L1; } break; } } break; case a_EXP::tag_add: { switch (b->untag()) { case a_EXP::tag_add: { return equal(_add(a)->_1,_add(b)->_1) && equal(_add(a)->_2,_add(b)->_2); } break; default: { goto L1; } break; } } break; case a_EXP::tag_sub: { switch (b->untag()) { case a_EXP::tag_sub: { return equal(_sub(a)->_1,_sub(b)->_1) && equal(_sub(a)->_2,_sub(b)->_2); } break; default: { goto L1; } break; } } break; case a_EXP::tag_mul: { switch (b->untag()) { case a_EXP::tag_mul: { return equal(_mul(a)->_1,_mul(b)->_1) && equal(_mul(a)->_2,_mul(b)->_2); } break; default: { goto L1; } break; } } break; default: { switch (b->untag()) { case a_EXP::tag_div: { return equal(_div(a)->_1,_div(b)->_1) && equal(_div(a)->_2,_div(b)->_2); } break; default: { goto L1; } break; } } break; } } } ////////////////////////////////////////////////////////////////////////////// // The main program just writes out an expression; then read it back. ////////////////////////////////////////////////////////////////////////////// int main() { // Create an expression with sharing EXP e1 = add(num(1), var("x")); EXP e2 = mul(e1,e1); EXP e3 = div(e2,e2); EXP e4 = sub(e3,e3); EXP e5 = mul(e4,e4); EXP e6 = div(e5,e5); EXP e7 = sub(e6,e6); EXP e8 = add(var("foo"),e7); /////////////////////////////////////////////////////////////////////////// // Write the expression to a file. /////////////////////////////////////////////////////////////////////////// cout << "Original = " << e8 << '\n'; { ofstream out("persistence.dat"); Postream pout(out); pout << e8; out.close(); } /////////////////////////////////////////////////////////////////////////// // Read the expression back from the same file /////////////////////////////////////////////////////////////////////////// EXP e; { ifstream in("persistence.dat"); Pistream pin(in); e = (EXP)read_object(pin); in.close(); } /////////////////////////////////////////////////////////////////////////// // Verify the structure /////////////////////////////////////////////////////////////////////////// cout << "Copy = " << e << '\n'; VerifySharing v; v(e); assert(equal(e8,e)); cout << "Persistence seems to be working on your platform\n"; return 0; } /* ------------------------------- Statistics ------------------------------- Merge matching rules = yes Number of DFA nodes merged = 36 Number of ifs generated = 0 Number of switches generated = 7 Number of labels = 1 Number of gotos = 5 Adaptive matching = disabled Fast string matching = disabled Inline downcasts = disabled -------------------------------------------------------------------------- */