1 ///////////////////////////////////////////////////////////////////////////////
2 // This file is generated automatically using Prop (version 2.3.4),
3 // last updated on Mar 31, 1997.
4 // The original source file is "T9.pcc".
5 ///////////////////////////////////////////////////////////////////////////////
7 #define PROP_REWRITING_USED
8 #define PROP_GARBAGE_COLLECTION_USED
9 #define PROP_PRINTER_USED
10 #define PROP_QUARK_USED
13 //////////////////////////////////////////////////////////////////////////////
14 // This program tests rewriting and garbage collection by using
15 // the rewriting mechanism to compute the Fibonacci number the hard way.
16 //////////////////////////////////////////////////////////////////////////////
18 #include <AD/gc/gcobject.h>
20 //////////////////////////////////////////////////////////////////////////////
21 // Datatype EXP denotes an expression.
22 //////////////////////////////////////////////////////////////////////////////
25 ///////////////////////////////////////////////////////////////////////////////
27 // Forward class definition for EXP
29 ///////////////////////////////////////////////////////////////////////////////
30 #ifndef datatype_EXP_defined
31 #define datatype_EXP_defined
36 ///////////////////////////////////////////////////////////////////////////////
38 // Base class for datatype EXP
40 ///////////////////////////////////////////////////////////////////////////////
41 class a_EXP
: public GCObject
{
44 tag_num
= 0, tag_fib
= 1, tag_add
= 2
48 const Tag_EXP tag__
; // variant tag
50 inline a_EXP(Tag_EXP t__
) : tag__(t__
) {}
52 inline virtual ~a_EXP()
55 ////////////////////////////////////////////////////////////////////////////
57 // Method for garbage collection tracing
59 ////////////////////////////////////////////////////////////////////////////
61 virtual void trace(GC
*);
64 inline int boxed(const a_EXP
*) { return 1; }
65 inline int untag(const a_EXP
* x
) { return x
->tag__
; }
66 ///////////////////////////////////////////////////////////////////////////////
68 // Pretty printing methods for EXP
70 ///////////////////////////////////////////////////////////////////////////////
72 extern std::ostream
& operator<<(std::ostream
&, EXP
);
73 extern PrettyOStream
& operator<<(PrettyOStream
&, EXP
);
74 ///////////////////////////////////////////////////////////////////////////////
76 // Class for datatype constructor EXP::num
78 ///////////////////////////////////////////////////////////////////////////////
79 class EXP_num
: public a_EXP
{
83 inline EXP_num (int x_num
)
84 : a_EXP(tag_num
), num(x_num
)
90 ////////////////////////////////////////////////////////////////////////////
92 // Method for garbage collection tracing
94 ////////////////////////////////////////////////////////////////////////////
96 virtual void trace(GC
*);
100 ///////////////////////////////////////////////////////////////////////////////
102 // Class for datatype constructor EXP::fib
104 ///////////////////////////////////////////////////////////////////////////////
105 class EXP_fib
: public a_EXP
{
109 inline EXP_fib (EXP x_fib
)
110 : a_EXP(tag_fib
), fib(x_fib
)
116 ////////////////////////////////////////////////////////////////////////////
118 // Method for garbage collection tracing
120 ////////////////////////////////////////////////////////////////////////////
122 virtual void trace(GC
*);
126 ///////////////////////////////////////////////////////////////////////////////
128 // Class for datatype constructor EXP::add
130 ///////////////////////////////////////////////////////////////////////////////
131 class EXP_add
: public a_EXP
{
135 inline EXP_add (EXP x_1
, EXP x_2
)
136 : a_EXP(tag_add
), _1(x_1
), _2(x_2
)
142 ////////////////////////////////////////////////////////////////////////////
144 // Method for garbage collection tracing
146 ////////////////////////////////////////////////////////////////////////////
148 virtual void trace(GC
*);
152 ///////////////////////////////////////////////////////////////////////////////
154 // Datatype constructor functions for EXP
156 ///////////////////////////////////////////////////////////////////////////////
157 inline a_EXP
* num (int x_num
)
159 return new EXP_num (x_num
);
161 inline a_EXP
* fib (EXP x_fib
)
163 return new EXP_fib (x_fib
);
165 inline a_EXP
* add (EXP x_1
, EXP x_2
)
167 return new EXP_add (x_1
, x_2
);
169 ///////////////////////////////////////////////////////////////////////////////
171 // Downcasting functions for EXP
173 ///////////////////////////////////////////////////////////////////////////////
174 inline EXP_num
* _num(const a_EXP
* _x_
) { return (EXP_num
*)_x_
; }
175 inline EXP_fib
* _fib(const a_EXP
* _x_
) { return (EXP_fib
*)_x_
; }
176 inline EXP_add
* _add(const a_EXP
* _x_
) { return (EXP_add
*)_x_
; }
182 //////////////////////////////////////////////////////////////////////////////
183 // Defines the interface to a rewrite class.
184 // A private counter ``rewrite_count'' is encapsulated by the class
186 //////////////////////////////////////////////////////////////////////////////
189 class Fib
: public BURS
{
191 Fib(const Fib
&); // no copy constructor
192 void operator = (const Fib
&); // no assignment
194 struct Fib_StateRec
* stack__
, * stack_top__
;
196 void labeler(const char *, int&, int);
197 void labeler(Quark
, int&, int);
198 void labeler(EXP
& redex
, int&, int);
199 inline virtual void operator () (EXP
& redex
) { int s
; labeler(redex
,s
,0); }
203 int rewrites
; // number of replacements performed during rewriting
205 Fib() : rewrites(0) {}
208 inline int number_of_rewrites() const { return rewrites
; }
216 //////////////////////////////////////////////////////////////////////////////
217 // Specifies the rewrite rules. We'll use rewriting to compute
218 // addition also. The algorithm is exponential in time and generates
219 // a lot of garbage in the process.
221 // Notice that all private data within the rewrite class is visible within
222 // the rewrite rules.
223 //////////////////////////////////////////////////////////////////////////////
226 ///////////////////////////////////////////////////////////////////////////////
228 // This macro can be redefined by the user for debugging
230 ///////////////////////////////////////////////////////////////////////////////
232 #define DEBUG_Fib(repl,redex,file,line,rule) repl
234 static const char * Fib_file_name
= "T9.pcc";
237 static const TreeTables::Offset Fib_accept_base
[ 4 ] = {
240 static const TreeTables::ShortRule Fib_accept_vector
[ 7 ] = {
241 -1, 0, 1, 2, -1, 3, -1
243 static const TreeTables::ShortState Fib_theta_1
[2] = {
248 static const TreeTables::ShortState Fib_theta_2
[2][2] = {
254 static const TreeTables::ShortState Fib_mu_1_0
[4] = {
259 static const TreeTables::ShortState Fib_mu_2_0
[4] = {
264 static const TreeTables::ShortState Fib_mu_2_1
[4] = {
269 inline void Fib::labeler(char const * redex
,int& s__
,int)
276 inline void Fib::labeler(Quark redex
,int& s__
,int)
283 void Fib::labeler (EXP
& redex
, int& s__
, int r__
)
286 switch(redex
->tag__
) {
287 case a_EXP::tag_num
: {
291 case a_EXP::tag_fib
: {
293 labeler(_fib(redex
)->fib
, s0__
, r__
);
294 s__
= Fib_theta_1
[Fib_mu_1_0
[s0__
]]; } break;
298 labeler(_add(redex
)->_1
, s0__
, r__
);
299 labeler(_add(redex
)->_2
, s1__
, r__
);
300 s__
= Fib_theta_2
[Fib_mu_2_0
[s0__
]][Fib_mu_2_1
[s1__
]]; } break;
302 const TreeTables::ShortRule
* o__
= Fib_accept_vector
+ Fib_accept_base
[s__
];
307 { redex
= DEBUG_Fib(num((_num(_add(redex
)->_1
)->num
+ _num(_add(redex
)->_2
)->num
)),redex
,Fib_file_name
,44,"add (num x, num y): ...");
308 r__
= 1; goto replacement__
; }
313 { redex
= DEBUG_Fib(add(fib(num((_num(_fib(redex
)->fib
)->num
- 1))),fib(num((_num(_fib(redex
)->fib
)->num
- 2)))),redex
,Fib_file_name
,43,"fib num n: ...");
314 r__
= 1; goto replacement__
; }
317 case 1: if ((_num(_fib(redex
)->fib
)->num
== 1))
320 { redex
= DEBUG_Fib(_fib(redex
)->fib
,redex
,Fib_file_name
,42,"fib x as num _ | (_num(_fib(redex)->fib)->num == 1): ...");
321 r__
= 1; goto replacement__
; }
324 else { ++o__
; goto accept__
; } break;
325 case 0: if ((_num(_fib(redex
)->fib
)->num
== 0))
328 { redex
= DEBUG_Fib(_fib(redex
)->fib
,redex
,Fib_file_name
,41,"fib x as num _ | (_num(_fib(redex)->fib)->num == 0): ...");
329 r__
= 1; goto replacement__
; }
332 else { ++o__
; goto accept__
; } break;
341 //////////////////////////////////////////////////////////////////////////////
342 // Instantiate the datatype
343 //////////////////////////////////////////////////////////////////////////////
346 ///////////////////////////////////////////////////////////////////////////////
348 // Interface specification of datatype EXP
350 ///////////////////////////////////////////////////////////////////////////////
352 ///////////////////////////////////////////////////////////////////////////////
354 // Pretty printing methods for EXP
356 ///////////////////////////////////////////////////////////////////////////////
357 std::ostream
& operator << (std::ostream
& strm__
, EXP obj__
);
358 PrettyOStream
& operator << (PrettyOStream
& strm__
, EXP obj__
);
360 ///////////////////////////////////////////////////////////////////////////////
362 // Instantiation of datatype EXP
364 ///////////////////////////////////////////////////////////////////////////////
366 void a_EXP::trace(GC
* gc__
)
370 ///////////////////////////////////////////////////////////////////////////////
372 // Pretty printing methods for EXP
374 ///////////////////////////////////////////////////////////////////////////////
375 std::ostream
& operator << (std::ostream
& strm__
, EXP obj__
)
376 { PrettyOStream
S(strm__
); S
<< obj__
; return strm__
; }
378 PrettyOStream
& operator << (PrettyOStream
& strm__
, EXP obj__
)
380 switch (untag(obj__
))
383 strm__
<< _num(obj__
)->num
; // int
387 strm__
<< _fib(obj__
)->fib
; // EXP
391 strm__
<< _add(obj__
)->_1
; // EXP
393 strm__
<< _add(obj__
)->_2
; // EXP
400 void EXP_num::trace(GC
* gc__
)
402 // call to method a_EXP::trace() has been optimized out
406 void EXP_fib::trace(GC
* gc__
)
408 // call to method a_EXP::trace() has been optimized out
409 this->fib
= (EXP
)gc__
->trace(this->fib
); // EXP
412 void EXP_add::trace(GC
* gc__
)
414 // call to method a_EXP::trace() has been optimized out
415 this->_1
= (EXP
)gc__
->trace(this->_1
); // EXP
416 this->_2
= (EXP
)gc__
->trace(this->_2
); // EXP
425 //////////////////////////////////////////////////////////////////////////////
426 // Input a number and test the rewrite rules.
427 //////////////////////////////////////////////////////////////////////////////
430 ///////////////////////////////////////////////////////////////////////////
431 // Give ourselves some more memory (2Meg) to work with.
432 // The default heap size is only 128K. Using a larger heap
433 // can drastically cut down the overhead of GC since almost all
434 // intermediate terms generated can be reclaimed. With the copying
435 // garbage collecting scheme that we are using, the overhead of GC
436 // is proportional to the amount of live data, not the total heap size.
437 ///////////////////////////////////////////////////////////////////////////
438 GC::get_default_gc().set_initial_heap_size(2*1024*1024);
441 cout
<< "This simple benchmark tests the efficiency of rewriting\n"
442 "by computing the Fibonacci numbers with a naive, exponential\n"
443 "algorithm. The goal is to stress the pattern matching and\n"
444 "term replacement facilities.\n"
445 "Please input a small non-negative number(0-25): " << flush
;
450 cout
<< "fib(" << n
<< ") = " << x
<< '\n';
451 cout
<< "Number of replacements = " << F
.number_of_rewrites() << '\n';
456 ------------------------------- Statistics -------------------------------
457 Merge matching rules = yes
458 Number of DFA nodes merged = 0
459 Number of ifs generated = 0
460 Number of switches generated = 0
463 Adaptive matching = disabled
464 Fast string matching = disabled
465 Inline downcasts = disabled
466 --------------------------------------------------------------------------