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

Last change on this file was 3947, checked in by yura, 9 years ago
  • bug fixed
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1/* $Id: trefal.hh 3947 2008-09-19 12:24:52Z yura $ */
2/* vim: set syntax=cpp shiftwidth=4 expandtab tabstop=4: */
3
4#ifndef __trefal_hh__
5#define __trefal_hh__
6
7#include <iostream>
8#include <sstream>
9#include <vector>
10
11#define DBG fprintf(stderr,"%d: %d\n",ts::myRank,__LINE__)
12
13class Expr;
14class GExpr;
15class Term;
16class GlobalExprs;
17
18extern GlobalExprs global_exprs;
19
20class TExpr : public ts::TVar<Expr> {
21  public:
22   inline TExpr () {};
23   inline TExpr (const GExpr& _e);
24   inline TExpr (TExpr& _e, size_t _start, size_t len); // subexpression
25   inline TExpr (Term& _t);                             // dereference: _t is EXPR or CONST
26   inline bool operator== (TExpr& _e);
27   inline bool eq (TExpr& _e, size_t _start);
28   inline TExpr operator+ (TExpr& _e);
29   inline TExpr operator() ();
30   inline TExpr& get_ref () { return *this; }
31};
32
33struct Term {
34    enum Type {
35        CHAR, INT, EXPR, CONST
36    } type;
37    int data;
38    TExpr e;
39
40    void init_char (char _c) {
41        type = CHAR;
42        data = _c;
43        (Expr&)e;
44    }
45
46    void init_int (int _i) {
47        type = INT;
48        data = _i;
49        (Expr&)e;
50    }
51
52    void init_expr (const TExpr& _e) {
53        type = EXPR;
54        data = 0;
55        e = _e;
56    }
57
58    void init_const (int _idx) {
59        type = CONST;
60        data = _idx;
61        (Expr&)e;
62    }
63};
64
65struct GExpr {
66    Term* terms;
67    size_t size;
68
69    GExpr () : terms(0), size(0) {}
70
71    inline GExpr (TExpr& _e);
72
73    inline GExpr (int size);
74
75    Term& operator[] (int i) const {
76        return terms[i];
77    }
78
79    GExpr& add (const Term& t) {
80        terms[size++] = t;
81        return *this;
82    }
83
84    GExpr& add (char c) {
85        Term t;
86        t.init_char(c);
87        return add(t);
88    }
89
90    GExpr& add (char* s, size_t len) {
91        while (len--)
92            add(*s++);
93        return *this;
94    }
95
96    GExpr& add (int i) {
97        Term t;
98        t.init_int(i);
99        return add(t);
100    }
101
102    inline GExpr& add (GExpr& e);
103
104    GExpr& concat (const GExpr& x) {
105        for (size_t i = 0; i < x.size; i++)
106            add(x.terms[i]);
107        return *this;
108    }
109
110    GExpr subexpr (size_t from, size_t len) {
111        GExpr e;
112        e.terms = terms + from;
113        e.size = len;
114        return e;
115    }
116};
117
118class GlobalExprs {
119    std::vector<GExpr> exprs;
120    std::vector<Term*> memory;
121
122  public:
123
124    GlobalExprs () : exprs(), memory() {}
125
126    int add_global_expr (GExpr& expr) {
127        exprs.push_back(expr);
128        return exprs.size() - 1;
129    }
130
131    Term* create_new_array (size_t size) {
132        Term* array = new Term[size];
133        memory.push_back(array);
134        return array;
135    }
136
137    GExpr& operator[] (size_t i) {
138        return exprs[i];
139    }
140
141    void clear () {
142        for (size_t i = 0, size = memory.size(); i < size; i++)
143            delete[] memory[i];
144    }
145};
146
147class Expr : private ts::TExtData {
148    bool is_const;
149    Term* terms;
150
151    void copyFrom (const Expr& e, size_t start, size_t length) {
152        Term* p = *this;
153        const Term* q = ((const Term*) e) + start;
154        if (terms)
155            for (unsigned i = 0; i < length; i++)
156                *(p++) = *(q++);
157        else
158            for (unsigned i = 0; i < length; i++)
159                new (p++) Term(*q++);
160    }
161
162    void clear () {
163        if (terms) {
164            if (!is_const)
165                delete[] terms;
166            terms = 0;
167            is_const = false;
168        } else {
169            Term* p = *this;
170            size_t length = get_len();
171            for (unsigned i = 0; i < length; i++)
172                p++->~Term();
173        }
174    }
175
176  public:
177
178    Expr () : is_const(false), terms(0) {};
179
180    void init (size_t s) {
181        assert(!terms);
182        terms = new Term[s];
183        extDataSize() = s * sizeof(Term);
184    };
185
186    void init_str (const char* str, size_t len) {
187        init(len);
188        for (unsigned i = 0; i < len; i++)
189            terms[i].init_char(str[i]);
190    }
191
192    void init_subexpr (const Expr& e, size_t start, size_t len) {
193        init(len);
194        copyFrom(e, start, len);
195    }
196
197    void init_paren (const TExpr& te) {
198        init(1);
199        terms[0].init_expr(te);
200    }
201
202    void init_concat (const Expr** exprs, size_t num) {
203        assert(!terms);
204        size_t len = 0;
205        for (unsigned i = 0; i < num; i++)
206            len += exprs[i]->get_len();
207        terms = new Term[len];
208        extDataSize() = len * sizeof(Term);
209        Term* p = terms;
210        for (unsigned i = 0; i < num; i++) {
211            const Term* q = *exprs[i];
212            for (unsigned j = 0; j < exprs[i]->get_len(); j++)
213                *p++ = *q++;
214        }
215    }
216
217    void init_const (int idx) {
218        terms = global_exprs[idx].terms;
219        extDataSize() = global_exprs[idx].size * sizeof(Term);
220        is_const = true;
221    }
222
223    void init_const (const GExpr& e) {
224        terms = e.terms;
225        extDataSize() = e.size * sizeof(Term);
226        is_const = true;
227    }
228
229    operator const Term* () const { return terms ? terms : (Term*)extData(); }
230    operator       Term* ()       { return terms ? terms : (Term*)extData(); }
231
232    Expr (const Expr& e) : is_const(false), terms(0) {
233        copyFrom(e, 0, e.get_len());
234    }
235
236    Expr& operator= (const Expr& e) {
237        if (this != &e) {
238            clear();
239            init(e.get_len());
240            copyFrom(e, 0, e.get_len());
241        }
242        return *this;
243    }
244
245    Expr subexpr (size_t start, size_t length) const {
246        Expr e;
247        e.init(length);
248        e.copyFrom(*this, start, length);
249        return e;
250    }
251
252    size_t get_len () const {
253        return extDataSize() / sizeof(Term);
254    }
255
256    Term& operator[] (int i) {
257        return ((Term *)*this)[i];
258    }
259
260    bool symbol_at (size_t pos) {
261        return ((Term *)*this)[pos].type < Term::EXPR;
262    }
263
264    ~Expr () {
265        clear();
266    }
267};
268
269
270// ================================= operator<< ================================
271
272// (TExpr)e and t are intentionally not const!
273
274std::ostream& operator<< (std::ostream& os, const GExpr& e);
275
276std::ostream& operator<< (std::ostream& os, Term& t) {
277    switch (t.type) {
278        case Term::CHAR: os << (char)t.data; break;
279        case Term::INT:  os << t.data; break;
280        case Term::EXPR: os << GExpr(t.e); break;
281        case Term::CONST: os << global_exprs[t.data]; break;
282    }
283    return os;
284}
285
286std::ostream& operator<< (std::ostream& os, const GExpr& e) {
287    os << "(";
288    Term* p = e.terms;
289    for (unsigned i = 0; i < e.size; i++)
290        os << (i > 0 ? " " : "") << p[i];
291    os << ")";
292    return os;
293}
294
295std::ostream& operator<< (std::ostream& os, TExpr& e) {
296    return os << GExpr(e);
297}
298
299// ================================= operator>> ================================
300
301std::istream& operator>> (std::istream& is, GExpr& e);
302
303std::istream& operator>> (std::istream& is, Term& t) {
304    char c;
305    is >> c;
306    is.putback(c);
307    if ('A' <= c && c <= 'Z') {
308        is >> c;
309        t.init_char(c);
310    } else if ('0' <= c && c <= '9') {
311        int i;
312        is >> i;
313        t.init_int(i);
314    } else if (c == '(') {
315        GExpr ge;
316        is >> ge;
317        t.init_const(global_exprs.add_global_expr(ge));
318    } else {
319        throw 0; //FIXME
320    }
321    return is;
322}
323
324std::istream& operator>> (std::istream& is, GExpr& e) {
325    int buffer_size = 30;
326    e.terms = new Term[buffer_size];
327    char c;
328    is >> c;
329    assert(c == '(');
330    int len = 0;
331    for (;len < buffer_size; len++) {
332        is >> c;
333        if (c == ')')
334            break;
335        is.putback(c);
336        is >> e.terms[len];
337    }
338    e.size = len;
339    return is;
340}
341
342// ================================= operator== ================================
343
344inline bool operator== (const GExpr& _e1, const GExpr& _e2);
345
346inline bool operator== (Term& _t1, Term& _t2) {
347    if (_t1.type < Term::EXPR || _t2.type < Term::EXPR)
348        return _t1.type == _t2.type && _t1.data == _t2.data;
349    if (_t1.type == Term::EXPR) {
350        if (_t2.type == Term::EXPR)
351            return _t1.e == _t2.e;
352        return GExpr(_t1.e) == global_exprs[_t2.data];
353    }
354    if (_t2.type == Term::EXPR)
355        return global_exprs[_t1.data] == _t2.e;
356    return _t1.data == _t2.data || global_exprs[_t1.data] == global_exprs[_t2.data];
357}
358
359inline bool operator!= (Term& _t1, Term& _t2) {
360    return !(_t1 == _t2);
361}
362
363inline bool operator== (const GExpr& _e1, const GExpr& _e2) {
364    if (_e1.size != _e2.size)
365        return false;
366    Term* p = _e1.terms;
367    Term* q = _e2.terms;
368    for (unsigned i = _e1.size; i; i--)
369        if (*p++ != *q++)
370            return false;
371    return true;
372}
373
374// =================================== GExpr ===================================
375
376inline GExpr::GExpr (TExpr& _e) : terms((Expr&)_e), size(((Expr&)_e).get_len()) {}
377inline GExpr::GExpr (int size) : terms(global_exprs.create_new_array(size)), size(0) {};
378
379GExpr& GExpr::add (GExpr& e) {
380    Term t;
381    t.init_const(global_exprs.add_global_expr(e));
382    return add(t);
383}
384
385// =================================== TExpr ===================================
386
387inline TExpr::TExpr (const GExpr& _e) {
388    ((Expr&)*this).init_const(_e);
389}
390
391inline TExpr::TExpr (TExpr& _e, size_t _start, size_t _len) {
392    ((Expr&)*this).init_subexpr(_e, _start, _len);
393}
394
395inline TExpr::TExpr (Term& _t) {
396    if (_t.type == Term::CONST)
397        ((Expr&)*this).init_const(_t.data);
398    else
399        (Expr&)*this = (Expr&)_t.e;
400}
401
402inline bool TExpr::operator== (TExpr& _e) {
403    std::cout << "== this: " << (Expr&)*this << std::endl;
404    std::cout << "== _e: " << (Expr&)_e << std::endl;
405    return d.cellOffset == _e.d.cellOffset || GExpr(*this) == GExpr(_e);
406}
407
408inline bool TExpr::eq (TExpr& _e, size_t _start) {
409    GExpr l(*this);
410    GExpr r(_e);
411    r = r.subexpr(_start, l.size);
412    return l == r;
413}
414
415inline TExpr TExpr::operator+ (TExpr& _e) {
416    const Expr* exprs[] = { &(Expr&)*this, &(Expr&)_e };
417    TExpr e;
418    ((Expr&)e).init_concat(exprs, 2);
419    return e;
420}
421
422inline TExpr TExpr::operator() () {
423    TExpr e;
424    ((Expr&)e).init_paren(*this);
425    return e;
426}
427
428#include "access.hh"
429#include "arithm.hh"
430#include "compare.hh"
431#include "stdio.hh"
432
433#endif // __trefal_hh__
434
Note: See TracBrowser for help on using the repository browser.