1 //////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.0.6),
3 // last updated on Apr 5th, 1995. Please be sure not to alter this file
4 // directly. Instead, refer to the original source file "hashcons.pcc".
5 //////////////////////////////////////////////////////////////////////////////
6 #define PROP_HASH_CONSING_USED
11 // This is a simple (and useless) example for testing the hash cons feature
16 #line 7 "hashcons.pcc"
17 ////////////////////////////////////////////////////////////////////////
18 // Forward declarations for datatype EXP
19 ////////////////////////////////////////////////////////////////////////
20 #ifndef datatype_EXP_defined
21 #define datatype_EXP_defined
23 typedef const a_EXP
* EXP
;
30 ////////////////////////////////////////////////////////////////////////
31 // Forward declarations for datatype LIST
32 ////////////////////////////////////////////////////////////////////////
33 #ifndef datatype_LIST_defined
34 #define datatype_LIST_defined
36 typedef const a_LIST
* LIST
;
38 ////////////////////////////////////////////////////////////////////////
39 // Definition of datatype EXP
40 ////////////////////////////////////////////////////////////////////////
43 /////////////////////////////////////////////////////////////////
44 // Variant tags for datatype EXP
45 /////////////////////////////////////////////////////////////////
46 #line 7 "hashcons.pcc"
48 tag_num
= 0, tag_add
= 1, tag_sub
= 2, tag_mul
= 3, tag_div
= 4
52 /////////////////////////////////////////////////////////////////
53 // The variant tag and its constructor
54 /////////////////////////////////////////////////////////////////
56 inline a_EXP(Tag_EXP t
) : tag(t
) {}
58 /////////////////////////////////////////////////////////////////
59 // Untagging and variant testing functions
60 /////////////////////////////////////////////////////////////////
61 inline int untag() const { return tag
; }
62 inline friend int boxed(const a_EXP
* x
) { return 1; }
63 inline friend int untag(const a_EXP
* x
) { return x
->tag
; }
64 /////////////////////////////////////////////////////////////////
65 // Downcasting functions for datatype EXP
66 /////////////////////////////////////////////////////////////////
67 inline friend const EXP_num
* _num(const EXP _x_
) { return (const EXP_num
*)_x_
; }
68 inline friend const EXP_add
* _add(const EXP _x_
) { return (const EXP_add
*)_x_
; }
69 inline friend const EXP_sub
* _sub(const EXP _x_
) { return (const EXP_sub
*)_x_
; }
70 inline friend const EXP_mul
* _mul(const EXP _x_
) { return (const EXP_mul
*)_x_
; }
71 inline friend const EXP_div
* _div(const EXP _x_
) { return (const EXP_div
*)_x_
; }
72 ///////////////////////////////////////////////////////////////////////////
73 // Interface for hash consing
74 ///////////////////////////////////////////////////////////////////////////
75 friend Bool
equal(EXP
, EXP
);
76 friend unsigned int hash (EXP
);
77 static const a_EXP
* make_hash_cons(a_EXP
*);
79 /////////////////////////////////////////////////////////////////
81 /////////////////////////////////////////////////////////////////
86 ////////////////////////////////////////////////////////////////////////
87 // Subclass for implementing constructor 'num int ' of EXP
88 ////////////////////////////////////////////////////////////////////////
89 class EXP_num
: public a_EXP
{
91 #line 7 "hashcons.pcc"
94 inline EXP_num(int _x_
)
95 : a_EXP(a_EXP::tag_num
), num(_x_
) {}
96 inline friend const a_EXP
* num(int _x_
)
97 { return a_EXP::make_hash_cons(new EXP_num (_x_
)); }
98 /////////////////////////////////////////////////////////////////
100 /////////////////////////////////////////////////////////////////
105 ////////////////////////////////////////////////////////////////////////
106 // Subclass for implementing constructor 'add (EXP , EXP ) ' of EXP
107 ////////////////////////////////////////////////////////////////////////
108 class EXP_add
: public a_EXP
{
110 #line 8 "hashcons.pcc"
113 inline EXP_add(EXP _x_1
, EXP _x_2
)
114 : a_EXP(a_EXP::tag_add
), _1(_x_1
), _2(_x_2
) {}
115 inline friend const a_EXP
* add(EXP _x_1
, EXP _x_2
)
116 { return a_EXP::make_hash_cons(new EXP_add (_x_1
, _x_2
)); }
117 /////////////////////////////////////////////////////////////////
119 /////////////////////////////////////////////////////////////////
124 ////////////////////////////////////////////////////////////////////////
125 // Subclass for implementing constructor 'sub (EXP , EXP ) ' of EXP
126 ////////////////////////////////////////////////////////////////////////
127 class EXP_sub
: public a_EXP
{
129 #line 9 "hashcons.pcc"
132 inline EXP_sub(EXP _x_1
, EXP _x_2
)
133 : a_EXP(a_EXP::tag_sub
), _1(_x_1
), _2(_x_2
) {}
134 inline friend const a_EXP
* sub(EXP _x_1
, EXP _x_2
)
135 { return a_EXP::make_hash_cons(new EXP_sub (_x_1
, _x_2
)); }
136 /////////////////////////////////////////////////////////////////
138 /////////////////////////////////////////////////////////////////
143 ////////////////////////////////////////////////////////////////////////
144 // Subclass for implementing constructor 'mul (EXP , EXP ) ' of EXP
145 ////////////////////////////////////////////////////////////////////////
146 class EXP_mul
: public a_EXP
{
148 #line 10 "hashcons.pcc"
151 inline EXP_mul(EXP _x_1
, EXP _x_2
)
152 : a_EXP(a_EXP::tag_mul
), _1(_x_1
), _2(_x_2
) {}
153 inline friend const a_EXP
* mul(EXP _x_1
, EXP _x_2
)
154 { return a_EXP::make_hash_cons(new EXP_mul (_x_1
, _x_2
)); }
155 /////////////////////////////////////////////////////////////////
157 /////////////////////////////////////////////////////////////////
162 ////////////////////////////////////////////////////////////////////////
163 // Subclass for implementing constructor 'div (EXP , EXP ) ' of EXP
164 ////////////////////////////////////////////////////////////////////////
165 class EXP_div
: public a_EXP
{
167 #line 11 "hashcons.pcc"
170 inline EXP_div(EXP _x_1
, EXP _x_2
)
171 : a_EXP(a_EXP::tag_div
), _1(_x_1
), _2(_x_2
) {}
172 inline friend const a_EXP
* div(EXP _x_1
, EXP _x_2
)
173 { return a_EXP::make_hash_cons(new EXP_div (_x_1
, _x_2
)); }
174 /////////////////////////////////////////////////////////////////
176 /////////////////////////////////////////////////////////////////
180 ////////////////////////////////////////////////////////////////////////
181 // Definition of datatype LIST
182 ////////////////////////////////////////////////////////////////////////
185 /////////////////////////////////////////////////////////////////
186 // Untagging and variant testing functions
187 /////////////////////////////////////////////////////////////////
188 inline friend int boxed(const a_LIST
* x
) { return x
!= 0; }
189 inline friend int untag(const a_LIST
* x
) { return x
? 1 : 0; }
191 #line 13 "hashcons.pcc"
194 inline a_LIST(EXP _x_1
, LIST _x_2
) : _1(_x_1
), _2(_x_2
) {}
195 inline friend const a_LIST
* list(EXP _x_1
, LIST _x_2
)
196 { return a_LIST::make_hash_cons(new a_LIST (_x_1
, _x_2
)); }
197 ///////////////////////////////////////////////////////////////////////////
198 // Interface for hash consing
199 ///////////////////////////////////////////////////////////////////////////
200 friend Bool
equal(LIST
, LIST
);
201 friend unsigned int hash (LIST
);
202 static const a_LIST
* make_hash_cons(a_LIST
*);
204 /////////////////////////////////////////////////////////////////
206 /////////////////////////////////////////////////////////////////
210 #line 14 "hashcons.pcc"
214 // implement the datatypes.
216 #line 19 "hashcons.pcc"
217 //////////////////////////////////////////////////////////////////////////////
218 // Equality function for EXP
219 // Shallow equality is assumed
220 //////////////////////////////////////////////////////////////////////////////
221 Bool
equal(EXP _x_
, EXP _y_
)
223 int _x_tag_
= untag(_x_
);
224 int _y_tag_
= untag(_y_
);
225 if (_x_tag_
!= _y_tag_
) return false;
228 if (_num(_x_
)->num
!= _num(_y_
)->num
) return false;
231 if (_add(_x_
)->_2
!= _add(_y_
)->_2
) return false;
232 if (_add(_x_
)->_1
!= _add(_y_
)->_1
) return false;
235 if (_sub(_x_
)->_2
!= _sub(_y_
)->_2
) return false;
236 if (_sub(_x_
)->_1
!= _sub(_y_
)->_1
) return false;
239 if (_mul(_x_
)->_2
!= _mul(_y_
)->_2
) return false;
240 if (_mul(_x_
)->_1
!= _mul(_y_
)->_1
) return false;
243 if (_div(_x_
)->_2
!= _div(_y_
)->_2
) return false;
244 if (_div(_x_
)->_1
!= _div(_y_
)->_1
) return false;
250 //////////////////////////////////////////////////////////////////////////////
251 // Hashing function for EXP
252 // Shallow hashing is used
253 //////////////////////////////////////////////////////////////////////////////
254 unsigned int hash(EXP _x_
)
257 switch (_h_
= untag(_x_
)) {
259 _h_
= hash(_num(_x_
)->num
);
262 _h_
+= (unsigned int)(_add(_x_
)->_1
);
263 _h_
+= (unsigned int)(_add(_x_
)->_2
);
266 _h_
+= (unsigned int)(_sub(_x_
)->_1
);
267 _h_
+= (unsigned int)(_sub(_x_
)->_2
);
270 _h_
+= (unsigned int)(_mul(_x_
)->_1
);
271 _h_
+= (unsigned int)(_mul(_x_
)->_2
);
274 _h_
+= (unsigned int)(_div(_x_
)->_1
);
275 _h_
+= (unsigned int)(_div(_x_
)->_2
);
281 //////////////////////////////////////////////////////////////////////////////
282 // Hash consing implementation for EXP
283 //////////////////////////////////////////////////////////////////////////////
284 static LHashTable
<EXP
, EXP
> EXP_universe
;
285 const a_EXP
* a_EXP::make_hash_cons(a_EXP
* _x_
)
286 { Ix i
= EXP_universe
.lookup(_x_
);
287 if (i
== 0) { EXP_universe
.insert(_x_
,_x_
); return _x_
; }
288 else { delete _x_
; return EXP_universe
.value(i
); }
291 ////////////////////////////////////////////////////////////////////
292 // Destructor(s) for class EXP
293 ////////////////////////////////////////////////////////////////////
294 #line 19 "hashcons.pcc"
296 EXP_num::~EXP_num() {}
297 EXP_add::~EXP_add() {}
298 EXP_sub::~EXP_sub() {}
299 EXP_mul::~EXP_mul() {}
300 EXP_div::~EXP_div() {}
301 //////////////////////////////////////////////////////////////////////////////
302 // Equality function for LIST
303 // Shallow equality is assumed
304 //////////////////////////////////////////////////////////////////////////////
305 Bool
equal(LIST _x_
, LIST _y_
)
307 int _x_tag_
= untag(_x_
);
308 int _y_tag_
= untag(_y_
);
309 if (_x_tag_
!= _y_tag_
) return false;
314 if ((_x_
)->_2
!= (_y_
)->_2
) return false;
315 if ((_x_
)->_1
!= (_y_
)->_1
) return false;
321 //////////////////////////////////////////////////////////////////////////////
322 // Hashing function for LIST
323 // Shallow hashing is used
324 //////////////////////////////////////////////////////////////////////////////
325 unsigned int hash(LIST _x_
)
328 switch (_h_
= untag(_x_
)) {
330 _h_
= (unsigned int)_x_
;
333 _h_
+= (unsigned int)((_x_
)->_1
);
334 _h_
+= (unsigned int)((_x_
)->_2
);
340 //////////////////////////////////////////////////////////////////////////////
341 // Hash consing implementation for LIST
342 //////////////////////////////////////////////////////////////////////////////
343 static LHashTable
<LIST
, LIST
> LIST_universe
;
344 const a_LIST
* a_LIST::make_hash_cons(a_LIST
* _x_
)
345 { Ix i
= LIST_universe
.lookup(_x_
);
346 if (i
== 0) { LIST_universe
.insert(_x_
,_x_
); return _x_
; }
347 else { delete _x_
; return LIST_universe
.value(i
); }
350 ////////////////////////////////////////////////////////////////////
351 // Destructor(s) for class LIST
352 ////////////////////////////////////////////////////////////////////
353 #line 19 "hashcons.pcc"
355 #line 19 "hashcons.pcc"
358 ostream
& operator << (ostream
& f
, EXP e
)
361 #line 23 "hashcons.pcc"
362 { switch (e
->untag()) {
363 case a_EXP::tag_num
: {
364 #line 24 "hashcons.pcc"
365 return f
<< (_num(e
)->num
); } break;
366 case a_EXP::tag_add
: {
367 #line 25 "hashcons.pcc"
368 return f
<< '(' << (_add(e
))->_1
<< " + " << (_add(e
))->_2
<< ')'; } break;
369 case a_EXP::tag_sub
: {
370 #line 26 "hashcons.pcc"
371 return f
<< '(' << (_sub(e
))->_1
<< " - " << (_sub(e
))->_2
<< ')'; } break;
372 case a_EXP::tag_mul
: {
373 #line 27 "hashcons.pcc"
374 return f
<< '(' << (_mul(e
))->_1
<< " * " << (_mul(e
))->_2
<< ')'; } break;
376 #line 28 "hashcons.pcc"
377 return f
<< '(' << (_div(e
))->_1
<< " / " << (_div(e
))->_2
<< ')'; }
380 #line 29 "hashcons.pcc"
384 ostream
& operator << (ostream
& f
, LIST l
)
387 #line 34 "hashcons.pcc"
391 #line 37 "hashcons.pcc"
392 return f
<< (l
)->_1
<< ',' << (l
)->_2
;
395 #line 36 "hashcons.pcc"
400 #line 35 "hashcons.pcc"
405 #line 38 "hashcons.pcc"
411 EXP e1
= mul(add(num(1),num(2)), add(num(2), num(3)));
412 EXP e2
= mul(add(num(1),num(2)), add(num(2), num(3)));
413 LIST l1
= list(e1
, list(e2
, nil
));
415 cout
<< ((e1
== e2
) ? "Good!\n" : "Bad boy! Naughty, naughty boy!\n");
416 cout
<< ((num(1) == num(1)) ? "Good!\n" : "Bad boy! Naughty, naughty boy!\n");
417 cout
<< ((num(1) != num(2)) ? "Good!\n" : "Bad boy! Naughty, naughty boy!\n");
418 cout
<< ((add(e1
,e2
) == add(e1
,e2
)) ? "Good!\n" : "Bad boy! Naughty, naughty boy!\n");
419 cout
<< ((add(e1
,e2
) != add(e1
,num(2))) ? "Good!\n" : "Bad boy! Naughty, naughty boy!\n");
423 ----------------------------- Statistics -------------------------------
424 Number of decision nodes merged = 0
425 Number of switches generated = 1
426 Number of ifs generated = 2
427 Number of labels generated = 0
428 Number of gotos generated = 0
429 Number of temporary variables = 0
430 ------------------------------------------------------------------------