simple.cc - generated code example
[prop.git] / tests / rewriting4.pcc
blob4b1e1636c74f3f5d96ad4069f640b28974afee1d
1 /////////////////////////////////////////////////////////////////////////////
2 //  This program demonstrates the use of attribute evaluation in Prop's
3 //  rewrite class.
4 /////////////////////////////////////////////////////////////////////////////
6 #include <iostream.h>
8 /////////////////////////////////////////////////////////////////////////////
9 //  The datatype EXP represents a simple expression (with pretty printing.)
10 /////////////////////////////////////////////////////////////////////////////
11 datatype EXP :: rewrite
12              = num (int)       => _
13              | add (EXP, EXP)  => "(" _ " + " _ ")"
14              | sub (EXP, EXP)  => "(" _ " - " _ ")"
15              | mul (EXP, EXP)  => "(" _ " * " _ ")"
16              | div (EXP, EXP)  => "(" _ " / " _ ")"
17              ;
19 /////////////////////////////////////////////////////////////////////////////
20 //  The rewrite class Eval involves the transformation of datatype
21 //  EXP into integers.
22 /////////////////////////////////////////////////////////////////////////////
23 rewrite class Eval (EXP : int) :: treeparser {};
25 /////////////////////////////////////////////////////////////////////////////
26 //  Now, here are the rules.  Pattern variables of the form '$x' refer
27 //  to synthesized attributes.  (Normal pattern variables of the
28 //  form 'x' still refer to the components of a term.)
30 //  Notice that nested attributes and guards on attribute values 
31 //  are both allowed.  (The nested attribute rule is contrived.)
32 /////////////////////////////////////////////////////////////////////////////
33 rewrite Eval {
34    num (x as _):               { ## = x; }
35 |  add (x as _, y as _):       { ## = #x + #y; }
36 |  sub (x as _, y as _):       { ## = #x - #y; }
37 // |  mul (x, add(y,z)):       { ## = $x * (#y + #z); } // nested attributes
38 |  mul (x as _, y as _):       { ## = #x * #y; }
39 |  div (x as _, y as _) where (#y != 0): { ## = #x / #y; }       
40 |  div (x as _, y as _):       { cerr << "Division by zero\n"; ## = 0; }  
43 /////////////////////////////////////////////////////////////////////////////
44 //  Generate the implementation of the datatype. 
45 /////////////////////////////////////////////////////////////////////////////
46 instantiate datatype EXP;
48 /////////////////////////////////////////////////////////////////////////////
49 //  Test the rewriting rules.
50 /////////////////////////////////////////////////////////////////////////////
51 int main()
52 {  // Instantiate a rewriting class.
53    Eval eval;
55    //  e = (1 + 2) * (5 - 3)
56    EXP e = mul(add(num(1), num(2)), sub(num(5),num(3)));
57   
58    cout << e << " = " << eval(e) << '\n'; 
59    return 0;