source: to-imperative/trunk/opents/samples/trefal.hh @ 3588

Last change on this file since 3588 was 3588, checked in by orlov, 13 years ago
  • operator==
File size: 6.3 KB
Line 
1/* $Id$ */
2/* vim: set syntax=cpp shiftwidth=4 expandtab tabstop=4: */
3
4#include <iostream>
5
6#define DBG fprintf(stderr,"%d: %d\n",ts::myRank,__LINE__)
7
8class Expr;
9
10class TExpr : public ts::TVar<Expr>
11{
12public:
13    bool operator== (TExpr& _e);
14};
15
16struct Term {
17    enum Type {
18        CHAR, INT, EXPR
19    } type;
20    char c;
21    int i;
22    TExpr e;
23
24    void init (char _c) {
25        type = CHAR;
26        c = _c;
27        i = 0;
28        (Expr&)e;
29    }
30
31    void init (int _i) {
32        type = INT;
33        c = 0;
34        i = _i;
35        (Expr&)e;
36    }
37
38    void init (const TExpr& _e) {
39        type = EXPR;
40        c = 0;
41        i = 0;
42        e = _e;
43    }
44};
45
46inline bool operator== (Term& _t1, Term& _t2) {
47    return _t1.type == _t2.type && _t1.c == _t2.c && _t1.i == _t2.i && _t1.e == _t2.e;
48}
49
50inline bool operator!= (Term& _t1, Term& _t2) {
51    return !(_t1 == _t2);
52}
53
54class Expr : private ts::TExtData
55{
56    private:
57
58        Term* terms;
59
60        void copyFrom (const Expr& e, size_t start, size_t length) {
61            Term* p = *this;
62            const Term* q = ((const Term*) e) + start;
63            if (terms)
64                for (unsigned i = 0; i < length; i++)
65                    *(p++) = *(q++);
66            else
67                for (unsigned i = 0; i < length; i++)
68                    new (p++) Term(*q++);
69        }
70
71        void clear () {
72            if (terms) {
73                delete[] terms;
74                terms = 0;
75            } else {
76                Term* p = *this;
77                size_t length = get_len();
78                for (unsigned i = 0; i < length; i++)
79                    p++->~Term();
80            }
81        }
82
83    public:
84
85        Expr () : terms(0) {};
86
87        void init (size_t s) {
88            assert(!terms);
89            terms = new Term[s];
90            extDataSize() = s * sizeof(Term);
91        };
92
93        void init_str (const char* str, size_t len) {
94            init(len);
95            for (unsigned i = 0; i < len; i++)
96                terms[i].init(str[i]);
97        }
98
99        void init_subexpr (const Expr& e, size_t start, size_t len) {
100            init(len);
101            copyFrom(e, start, len);
102        }
103
104        void init_paren (const TExpr& te) {
105            init(1);
106            terms->init(te);
107        }
108
109        void init_concat (const Expr** exprs, size_t num) {
110            assert(!terms);
111            size_t len = 0;
112            for (unsigned i = 0; i < num; i++)
113                len += exprs[i]->get_len();
114            terms = new Term[len];
115            extDataSize() = len * sizeof(Term);
116            Term* p = terms;
117            for (unsigned i = 0; i < num; i++) {
118                const Term* q = *exprs[i];
119                for (unsigned j = 0; j < exprs[i]->get_len(); j++)
120                    *p++ = *q++;
121            }
122        }
123
124        operator const Term* () const { return terms ? terms : (Term*)extData(); }
125        operator       Term* ()       { return terms ? terms : (Term*)extData(); }
126
127        Expr (const Expr& e) : terms(0) {
128            copyFrom(e, 0, e.get_len());
129        }
130
131        Expr& operator= (const Expr& e) {
132            if (this != &e) {
133                clear();
134                init(e.get_len());
135                copyFrom(e, 0, e.get_len());
136            }
137            return *this;
138        }
139
140        Expr subexpr (size_t start, size_t length) const {
141            Expr e;
142            e.init(length);
143            e.copyFrom(*this, start, length);
144            return e;
145        }
146
147//        Expr operator() () const {
148//            Expr e;
149//            e.init(1);
150//            Term* p = (Term *)e;
151//            p->type = Term::EXPR;
152//            p->e = *this;
153//            p->c = 0;
154//            p->i = 0;
155//            return e;
156//        }
157
158        size_t get_len () const {
159            return extDataSize() / sizeof(Term);
160        }
161
162        Term& operator[] (int i) {
163            return ((Term *)*this)[i];
164        }
165
166        bool symbol_at (size_t pos) {
167            return ((Term *)*this)[pos].type != Term::EXPR;
168        }
169
170        ~Expr () {
171            clear();
172        }
173};
174
175// e and t are intentionally not const!
176
177std::ostream& operator<< (std::ostream& os, Expr& e);
178
179std::ostream& operator<< (std::ostream& os, Term& t) {
180    switch (t.type) {
181        case Term::CHAR: os << t.c; break;
182        case Term::INT:  os << t.i; break;
183        case Term::EXPR: os << (Expr &)t.e; break;
184    }
185    return os;
186}
187
188std::ostream& operator<< (std::ostream& os, Expr& e) {
189    os << "(";
190    Term* p = e;
191    for (unsigned i = 0; i < e.get_len(); i++)
192        os << (i > 0 ? " " : "") << p[i];
193    os << ")";
194    return os;
195}
196
197std::istream& operator>> (std::istream& is, Expr& e);
198
199std::istream& operator>> (std::istream& is, Term& t) {
200    char c;
201    is >> c;
202    is.putback(c);
203    if ('A' <= c && c <= 'Z') {
204        t.type = Term::CHAR;
205        is >> t.c;
206        t.i = 0;
207        (Expr &)(t.e);
208    } else if ('0' <= c && c <= '9') {
209        t.type = Term::INT;
210        is >> t.i;
211        t.c = 0;
212        (Expr &)(t.e);
213    } else if (c == '(') {
214        t.type = Term::EXPR;
215        t.c = 0;
216        t.i = 0;
217        is >> (Expr &)(t.e);
218    } else {
219        throw 0; //FIXME
220    }
221    return is;
222}
223
224std::istream& operator>> (std::istream& is, Expr& e) {
225    int buffer_size = 20;
226    Term* buffer = new Term[buffer_size];
227    char c;
228    is >> c;
229    assert(c == '(');
230    int len = 0;
231    for (;len < buffer_size; len++) {
232        is >> c;
233        if (c == ')')
234            break;
235        is.putback(c);
236        is >> buffer[len];
237    }
238    e.init(len);
239    Term* p = e;
240    for (int i = 0; i < len; i++)
241        p[i] = buffer[i];
242    delete[] buffer;
243    return is;
244}
245
246Expr operator+ (const Expr& e1, const Expr& e2) {
247    Expr e;
248    e.init(e1.get_len() + e2.get_len());
249    Term* p = e;
250    const Term* q = e1;
251    for (unsigned i = 0; i < e1.get_len(); i++)
252        new (p++) Term(*q++);
253    q = e2;
254    for (unsigned i = 0; i < e2.get_len(); i++)
255        new (p++) Term(*q++);
256    return e;
257}
258
259inline bool operator== (Expr& _e1, Expr& _e2) {
260    size_t len = _e1.get_len();
261    if (len != _e2.get_len())
262        return false;
263    Term* p = _e1;
264    Term* q = _e2;
265    for (unsigned i = 0; i < len; i++)
266        if (*p++ != *q++)
267            return false;
268    return true;
269}
270
271bool TExpr::operator== (TExpr& _e) {
272    return d.cellOffset == _e.d.cellOffset || (Expr&)*this == (Expr&)_e;
273}
274
Note: See TracBrowser for help on using the repository browser.