move CPP_OPTS to config
[prop.git] / demos / persistence.pC
blobe341a20469c03e8c0150dfc73072f51a806e7847
1 //////////////////////////////////////////////////////////////////////////////
2 //  Testing persistence in Prop.
3 //
4 //  Persistence currently only means that objects are serializable into
5 //  a byte stream.  Objects are inserted in network byte order so that
6 //  they are portable across platforms.  Furthermore, pointer sharing
7 //  is preserved.
8 //////////////////////////////////////////////////////////////////////////////
9 #include <iostream.h>
10 #include <fstream.h>
11 #include <assert.h>
12 #include <string.h>
13 #include <AD/generic/generic.h>  // Definition of type Bool
14 #include <AD/persist/pstream.h>  // persistence streams
16 //////////////////////////////////////////////////////////////////////////////
18 //  Define a datatype with pretty printing.
20 //////////////////////////////////////////////////////////////////////////////
21 datatype EXP = num (int)      => _
22              | var (ID)       => _
23              | add (EXP, EXP) => "(" _ " + " _ ")"
24              | sub (EXP, EXP) => "(" _ " - " _ ")"
25              | mul (EXP, EXP) => "(" _ " * " _ ")"
26              | div (EXP, EXP) => "(" _ " / " _ ")"
27 where type ID = const char *
30 //////////////////////////////////////////////////////////////////////////////
31 //  Make the datatype persistent by defining the persistence type tag for 
32 //  its constructors. 
34 //  The persistence type tag *must* be unique for each constructor.
36 //  The datatype definition together with the following refinement
37 //  declaration can together serve as some sort of interface definition.
38 //  The type EXP can now be communicated between programs through persistent
39 //  streams.
40 //////////////////////////////////////////////////////////////////////////////
41 refine persistent EXP => "Simple expressions";
43 //////////////////////////////////////////////////////////////////////////////
44 //  Instantiate the datatype.  This declaration will generate all
45 //  necessary pretty printing and persistence serialization methods.
46 //////////////////////////////////////////////////////////////////////////////
47 instantiate datatype EXP;
49 //////////////////////////////////////////////////////////////////////////////
50 //  A simple rewrite class to verify pointer sharing between nodes.
51 //////////////////////////////////////////////////////////////////////////////
52 rewrite class VerifySharing (EXP) 
54 public:
55    VerifySharing() {}
57 rewrite VerifySharing {
58    sub (x,y):  { assert(x == y); }
59 |  mul (x,y):  { assert(x == y); }
60 |  div (x,y):  { assert(x == y); }
63 //////////////////////////////////////////////////////////////////////////////
64 //  Equality between expressions.
65 //////////////////////////////////////////////////////////////////////////////
66 Bool equal(EXP a, EXP b) 
67 {  match (a) and (b) {
68       num i,    num j:    { return i == j; }
69    |  var x,    var y:    { return strcmp(x,y) == 0; }
70    |  add(a,b), add(c,d): { return equal(a,c) && equal(b,d); }
71    |  sub(a,b), sub(c,d): { return equal(a,c) && equal(b,d); }
72    |  mul(a,b), mul(c,d): { return equal(a,c) && equal(b,d); }
73    |  div(a,b), div(c,d): { return equal(a,c) && equal(b,d); }
74    |  _,        _       : { return false; }
75    }
78 //////////////////////////////////////////////////////////////////////////////
79 //  The main program just writes out an expression; then read it back.
80 //////////////////////////////////////////////////////////////////////////////
81 int main()
82 {  
83    // Create an expression with sharing
84    EXP e1 = add(num(1), var("x"));
85    EXP e2 = mul(e1,e1);
86    EXP e3 = div(e2,e2);
87    EXP e4 = sub(e3,e3);
88    EXP e5 = mul(e4,e4);
89    EXP e6 = div(e5,e5);
90    EXP e7 = sub(e6,e6);
91    EXP e8 = add(var("foo"),e7);
93    ///////////////////////////////////////////////////////////////////////////
94    // Write the expression to a file.
95    ///////////////////////////////////////////////////////////////////////////
96    cout << "Original = " << e8 << '\n';
97    {  ofstream out("persistence.dat");
98       Postream pout(out);
99       pout << e8;
100       out.close();
101    }
103    ///////////////////////////////////////////////////////////////////////////
104    // Read the expression back from the same file 
105    ///////////////////////////////////////////////////////////////////////////
106    EXP e;
107    {  ifstream in("persistence.dat");
108       Pistream pin(in);
109       e = (EXP)read_object(pin);
110       in.close();
111    } 
113    ///////////////////////////////////////////////////////////////////////////
114    //  Verify the structure
115    ///////////////////////////////////////////////////////////////////////////
116    cout << "Copy = " << e << '\n';
117    VerifySharing v;
118    v(e);
119    assert(equal(e8,e));
121    cout << "Persistence seems to be working on your platform\n";
122    return 0;