Merge remote branch 'master'
[prop.git] / tests / persist1.pcc
blobf9fc2d7324f96145559d7cd2f8b62e1f73e08ab0
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 //////////////////////////////////////////////////////////////////////////////
17 //  Define a datatype with pretty printing.
18 //////////////////////////////////////////////////////////////////////////////
19 datatype EXP = num (int)      => _
20              | var (ID)       => _
21              | add (EXP, EXP) => "(" _ "+" _ ")"
22              | sub (EXP, EXP) => "(" _ "-" _ ")"
23              | mul (EXP, EXP) => "(" _ "*" _ ")"
24              | div (EXP, EXP) => "(" _ "/" _ ")"
25 where type ID = const char *
28 //////////////////////////////////////////////////////////////////////////////
29 //  Make the datatype persistent by defining the persistence type tag for 
30 //  its constructors. 
32 //  The persistence type tag *must* be unique for each constructor.
34 //  The datatype definition together with the following refinement
35 //  declaration can together serve as some sort of interface definition.
36 //  The type EXP can now be communicated between programs through persistent
37 //  streams.
38 //////////////////////////////////////////////////////////////////////////////
39 refine persistent EXP => "Simple expressions";
41 //////////////////////////////////////////////////////////////////////////////
42 //  Instantiate the datatype.  This declaration will generate all
43 //  necessary pretty printing and persistence serialization methods.
44 //////////////////////////////////////////////////////////////////////////////
45 instantiate datatype EXP;
47 //////////////////////////////////////////////////////////////////////////////
48 //  A simple rewrite class to verify pointer sharing between nodes.
49 //////////////////////////////////////////////////////////////////////////////
50 rewrite class VerifySharing (EXP) 
52 public:
53    VerifySharing() {}
55 rewrite VerifySharing {
56    sub (x,y):  { assert(x == y); }
57 |  mul (x,y):  { assert(x == y); }
58 |  div (x,y):  { assert(x == y); }
61 //////////////////////////////////////////////////////////////////////////////
62 //  Equality between expressions.
63 //////////////////////////////////////////////////////////////////////////////
64 Bool equal(EXP a, EXP b) 
65 {  match (a) and (b) {
66       num i,    num j:    { return i == j; }
67    |  var x,    var y:    { return strcmp(x,y) == 0; }
68    |  add(a,b), add(c,d): { return equal(a,c) && equal(b,d); }
69    |  sub(a,b), sub(c,d): { return equal(a,c) && equal(b,d); }
70    |  mul(a,b), mul(c,d): { return equal(a,c) && equal(b,d); }
71    |  div(a,b), div(c,d): { return equal(a,c) && equal(b,d); }
72    |  _,        _       : { return false; }
73    }
76 //////////////////////////////////////////////////////////////////////////////
77 //  The main program just writes out an expression; then read it back.
78 //////////////////////////////////////////////////////////////////////////////
79 int main()
80 {  
81    // Create an expression with sharing
82    EXP e1 = add(num(1), var("x"));
83    EXP e2 = mul(e1,e1);
84    EXP e3 = div(e2,e2);
85    EXP e4 = sub(e3,e3);
86    EXP e5 = mul(e4,e4);
87    EXP e6 = div(e5,e5);
88    EXP e7 = sub(e6,e6);
89    EXP e8 = add(var("foo"),e7);
91    ///////////////////////////////////////////////////////////////////////////
92    // Write the expression to a file.
93    ///////////////////////////////////////////////////////////////////////////
94    cout << "Original = " << e8 << '\n';
95    {  ofstream out("persist1.dat");
96       Postream pout(out);
97       pout << e8;
98       out.close();
99    }
101    ///////////////////////////////////////////////////////////////////////////
102    // Read the expression back from the same file 
103    ///////////////////////////////////////////////////////////////////////////
104    EXP e;
105    {  ifstream in("persist1.dat");
106       Pistream pin(in);
107       e = (EXP)read_object(pin);
108       in.close();
109    } 
111    ///////////////////////////////////////////////////////////////////////////
112    //  Verify the structure
113    ///////////////////////////////////////////////////////////////////////////
114    cout << "Copy = " << e << '\n';
115    VerifySharing v;
116    v(e);
117    assert(equal(e8,e));
119    cout << "Persistence seems to be working on your platform\n";
120    return 0;