2 // Test the view mechanism
11 enum Variant { Int, Ident, Add, Sub, Mul, Div };
12 virtual Variant get_variant() const = 0;
13 virtual int number() const;
14 virtual const char * ident() const;
15 virtual const Expression * child(int) const;
16 virtual Expression *& child(int);
19 typedef Expression * Exp;
21 int Expression::number() const
22 { cerr << "unimplement Expression::number()\n"; exit(1); return 0; }
24 const char * Expression::ident() const
25 { cerr << "unimplement Expression::ident()\n"; exit(1); return 0; }
27 const Expression * Expression::child(int) const
28 { cerr << "unimplement Expression::child(int) const\n"; exit(1); return 0; }
30 Expression *& Expression::child(int)
31 { cerr << "unimplement Expression::child(int)\n"; exit(1);
32 static Expression * t = 0;
36 class Number : public Expression {
39 Number(int n) : the_number(n) {}
40 Variant get_variant() const { return Int; }
41 int number() const { return the_number; }
42 friend Expression * INT(int i) { return new Number(i); }
45 class Identifier : public Expression {
46 const char * the_ident;
48 Identifier(const char * ident) : the_ident(ident) {}
49 Variant get_variant() const { return Ident; }
50 const char * ident() const { return the_ident; }
51 friend Expression * ID(const char * id) { return new Identifier(id); }
54 class Operator : public Expression {
56 Expression * children[2];
58 Operator(char o, const Expression* a, const Expression* b) : op(o)
59 { children[0] = (Expression*)a; children[1] = (Expression*)b; }
60 Variant get_variant() const
62 { case '+': return Add;
69 Expression *& child(int i) { return children[i]; }
70 const Expression * child(int i) const { return children[i]; }
72 friend Expression * ADD(const Expression * a, const Expression * b)
73 { return new Operator('+',a,b); }
74 friend Expression * SUB(const Expression * a, const Expression * b)
75 { return new Operator('-',a,b); }
76 friend Expression * MUL(const Expression * a, const Expression * b)
77 { return new Operator('*',a,b); }
78 friend Expression * DIV(const Expression * a, const Expression * b)
79 { return new Operator('/',a,b); }
83 = match (this->get_variant())
84 view Expression::Int => INT (int = this->number())
85 | view Expression::Ident => ID (const char * = this->ident())
86 | view Expression::Add => ADD (Exp = this->child(0), Exp = this->child(1))
87 | view Expression::Sub => SUB (Exp = this->child(0), Exp = this->child(1))
88 | view Expression::Mul => MUL (Exp = this->child(0), Exp = this->child(1))
89 | view Expression::Div => DIV (Exp = this->child(0), Exp = this->child(1))
92 ostream& operator << (ostream& s, Exp e)
94 { INT i: { return s << i; }
95 | ID x: { return s << x; }
96 | ADD (x,y): { return s << '(' << x << " + " << y << ')'; }
97 | SUB (x,y): { return s << '(' << x << " - " << y << ')'; }
98 | MUL (x,y): { return s << '(' << x << " * " << y << ')'; }
99 | DIV (x,y): { return s << '(' << x << " / " << y << ')'; }
105 { INT i: { return i; }
106 | ID x: { return 0; }
107 | ADD (x,y): { return eval(x) + eval(y); }
108 | SUB (x,y): { return eval(x) - eval(y); }
109 | MUL (x,y): { return eval(x) * eval(y); }
110 | DIV (x,INT 0): { cerr << "Division by zero\n"; return 0; }
111 | DIV (x,y): { return eval(x) / eval(y); }
115 void simplify(Exp& e)
118 rewrite (e) type (Exp)
120 ADD(INT i, INT j): INT(i+j)
121 | SUB(INT i, INT j): INT(i-j)
122 | MUL(INT i, INT j): INT(i*j)
123 | DIV(INT i, INT j): INT(i/j)
128 { Exp e = ADD(MUL(INT(5),INT(2)),DIV(INT(30),INT(6)));
129 cout << "Expression = " << e << endl;
130 cout << "Eval(" << e << ") = " << eval(e) << endl;
132 cout << "Simplified = " << e << endl;
133 assert(eval(e) == 15);