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

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