source: to-imperative/trunk/runtime/rf_expr.hh @ 882

Last change on this file since 882 was 882, checked in by orlov, 18 years ago
  • sym_eq is renamed to term_eq.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 KB
Line 
1//-----------------------------------------------------------------------------
2/// @file rf_expr.hh
3///
4/// Refal+ expression interface
5//
6//  $Source$
7//  $Revision: 882 $
8//  $Date: 2003-06-29 01:34:04 +0000 (Sun, 29 Jun 2003) $
9//-----------------------------------------------------------------------------
10
11#ifndef __rf_expr_hh__
12#define __rf_expr_hh__
13
14#include "rf_common.hh"
15#include "rf_term.hh"
16#include "rf_memory_chunk.hh"
17#include "rf_object.hh"
18
19#include <new>
20#include <string.h>
21
22///
23/// A namespace for Refal runtime
24namespace rfrt
25{
26
27using namespace rftype ;
28
29///
30/// Parameter enumeration for SplitIterator template class
31enum Direction {
32  d_lt,         ///< Split from left
33  d_rt          ///< Split from right
34};
35
36///
37/// Refal expression class. This is the main type of Refal runtime objects,
38/// and the only one the user should deal with. Other object types are not
39/// visible from generated code and shouldn't be used directly.
40class Expr
41{
42
43///
44/// We may use expression methods in SplitIterator class. We cannot avoid this
45/// because SplitIterator simultaneously changes two expressions in a way that
46/// adding necessary methods to Expr class will break invariants.
47template <Direction D = d_lt>
48friend class SplitIterator ;
49///
50/// Stack and Arg classes are our friends because they use special copy
51/// constructor which shouldn't be public available.
52friend class Arg ;
53friend class Stack ;
54friend class Term ;
55
56private:
57  ///
58  /// Pointer to the first term
59  Term* first;
60  ///
61  /// Pointer beyond the last term
62  Term* last;
63  ///
64  /// Pointer to a memory block containing an expression
65  MemoryChunk* mem_chunk;
66  ///
67  /// Various expression flags. Currently only REF_BIT is supported, meaning
68  /// that expression is not "flat", i.e. it may contain reference terms.
69  uintptr_t flags;
70
71public:
72
73#if 0
74  ///
75  /// Constructor from character string
76  inline Expr (char const* _string = null) ;
77#endif
78  ///
79  /// Create an empty expression
80  inline Expr () ;
81  ///
82  /// Constructor from expression holder. This constructor does dereference
83  /// operation.
84  /// @param _cp        Pointer to a term containg a reference to expression
85  ///                   to be dereferenced
86  inline Expr (Term const* _cp) ;
87  ///
88  /// Dereference constructor from explicit term in expression. Should be
89  /// called only with valid index argument.
90  /// @param _expr      Source expression
91  /// @param _index     Term index inside expression
92  inline Expr (Expr const& _expr, uintptr_t _index) ;
93  ///
94  /// Subexpression constructor
95  /// @param _expr      Source expression
96  /// @param _index     Index where subexpression started
97  /// @param _length    Subexpression length
98  inline Expr (Expr const& _expr, uintptr_t _index, uintptr_t _length) ;
99  ///
100  /// Copy constructor
101  /// @param _expr      Source expression
102  inline Expr (Expr const& _expr) ;
103  ///
104  /// Constructor from object
105  /// @param _obj       Source object
106  inline Expr (Object* _obj) ;
107  ///
108  /// Destructor
109  inline ~Expr () ;
110  ///
111  /// Assignment operator
112  /// @param _expr      Right side expression
113  inline Expr& operator = (Expr const& _expr) ;
114  ///
115  /// Expression concatenation
116  INLINE Expr operator + (Expr const& _expr) const ;
117  ///
118  /// Operator enclosing an expression into parentheses
119  inline Expr operator () () const ;
120  ///
121  /// Operator that dereferences expression containing a single reference term
122  inline Expr operator * () const ;
123  ///
124  /// Check whether a term at specified index is a symbol
125  inline bool symbol_at (uintptr_t _index) const ;
126  ///
127  /// Check whether an expression is flat
128  inline bool is_flat () const ;
129  ///
130  /// Check whether an expression is empty
131  inline bool is_empty () const ;
132  ///
133  /// Get a pointer to the first term
134  inline Term* get_first () const ;
135  ///
136  /// Get a pointer beyond the last term
137  inline Term* get_last () const ;
138  ///
139  /// Get expression length (in terms)
140  inline uintptr_t get_len () const ;
141private:
142  ///
143  /// Get expression flags
144  inline uintptr_t get_flags () const ;
145public:
146  ///
147  /// Dump expression contents (not recursive)
148  inline void dump () const ;
149  ///
150  /// Write an expression to buffered file stream. This function is incomplete
151  /// and suboptimal.
152  INLINE bool write (FILE* _fp) const ;
153  ///
154  /// The same as write(), but adds new line at the end of output.
155  inline bool writeln (FILE* _fp) const ;
156  INLINE bool print (FILE* _fp) const ;
157  inline bool println (FILE* _fp) const ;
158  INLINE operator WString () const ;
159  ///
160  /// Compute expression hash
161  inline uint32_t hash () const ;
162  ///
163  /// Compare with subexpression of other expression.  Attention: doesn't check
164  /// that our expression is not longer then the rest of the other.
165  inline bool eq (Expr const& _expr, uintptr_t _index) ;
166  ///
167  /// Same method for const expression.
168  inline bool eq (Expr const& _expr, uintptr_t _index) const ;
169  ///
170  /// Compare our first term with some one of another expression.
171  /// Should be called only with valid index argument.
172  inline bool term_eq (Expr const& _expr, uintptr_t _index) const ;
173  ///
174  /// Equality check operator
175  inline bool operator == (Expr& _expr) ;
176  ///
177  /// Inequality check operator
178  inline bool operator != (Expr& _expr) ;
179  ///
180  /// Same methods for const expressions.
181  inline bool operator == (Expr const& _expr) const ;
182  inline bool operator != (Expr const& _expr) const ;
183  ///
184  /// Compare two expressions.  Return 1 if first expression is larger then
185  /// second one, 0 if they are equal, and -1 if first one is smaller then
186  /// second one.
187  static inline int compare (Expr const& _expr1, Expr const& _expr2) ;
188  ///
189  /// Get pointer to a memory block containing an expression
190  inline MemoryChunk* get_mem_chunk () const ;
191  ///
192  /// Set a pointer to a memory block containing an expression. This method is
193  /// used only to set a null pointer for uninitialized results on a stack,
194  /// so if a refal function returns "$fail" we can distinguish whether a
195  /// result expression was already constructed and delete it.
196  /// FIXME: we should avoid this method at all, or at least make it private.
197  inline void set_mem_chunk (MemoryChunk* _ptr) ;
198
199private:
200
201  ///
202  /// Create an unitialized expression with given length. This constructor is
203  /// private because expression body contains garbage. It is used during
204  /// concatenation to allocate memory where resulting expression will be
205  /// constructed.
206  /// @param _len       A length of expression
207  /// @param _align     Indicates how an expression will be aligned in a memory
208  ///                   block: < 0 for left alignment, > 0 for right alignment,
209  ///                   0 for centered alignment
210  inline Expr (size_t _len, int _align = 0) ;
211  ///
212  /// Generic constructor. Should not be called directly because its arguments
213  /// may not be arbitrary.
214  /// @param _first     Pointer to the first term
215  /// @param _last      Pointer to the right margin
216  /// @param _mem_chunk Pointer to the memory block containing an expression
217  /// @param _flags     Expression flags
218  inline Expr (
219    Term* const _first, Term* const _last,
220    MemoryChunk* const _mem_chunk, uintptr_t const _flags
221  ) ;
222  ///
223  /// Constructor from a reference term. This constructor originally was
224  /// public because operator () returned Term instead of Expr, so this
225  /// constructor was actually called from user code. Now the situation is
226  /// changed and operator () now returns Expr. This allows to avoid friend
227  /// operators + () with Term arguments. For a while we left that code,
228  /// because further we may want to use it for optimization. Though we believe
229  /// that compiler should optimize a creation of temporary objects.
230  /// @param _cp        A term to become an expression.
231  inline Expr (Term const& _cp) ;
232  ///
233  /// A special copy constructor from expression pointer. This constructor is
234  /// used only to pop arguments and results from a stack. The trick is that
235  /// we don't increment memory block reference counter when popping arguments
236  /// from a stack. This allows to simply shift a stack pointer rather then
237  /// doing full stack unwind.
238  /// @param _expr      Source expression
239  inline Expr (Expr const* _expr) ;
240  ///
241  /// Initialize new expression with specified length and alignment
242  /// @param _len       A length of expression
243  /// @param _align     Indicates how an expression will be aligned in a memory
244  ///                   block: < 0 for left alignment, > 0 for right alignment,
245  ///                   0 for centered alignment
246  INLINE void init (size_t _len, int _align) ;
247  ///
248  /// Drop an expression contents. Used in destructor and assignment operator.
249  /// After a call to this method expression may be used only to create a new
250  /// expression at old place.
251  inline void drop () ;
252  ///
253  /// Increment reference counters for all expressions referenced from us
254  inline void ref_childs () const ;
255  ///
256  /// Decrement reference counters for all expressions referenced from us.
257  /// This function is called when we lost the last reference to our memory
258  /// block, so it should not only walk through our expression but also look
259  /// beside expression margins.
260  INLINE void deref_childs () const ;
261  static INLINE void deref_childs (
262    Term* _first, Term* _last, MemoryChunk* _mem
263  ) ;
264private:
265  ///
266  /// Check whether we can copy another expression to the right from our
267  /// in the same memory block.
268  inline bool rt_alloc (uintptr_t _len) const ;
269  ///
270  /// Check whether we can copy another expression to the left from our
271  /// in the same memory block.
272  inline bool lt_alloc( uintptr_t _len ) const ;
273
274
275public:
276
277  class TooLargeArgument :
278    public Exception
279  {
280  public:
281    void print()
282      { fprintf(stderr, "Argument too large for conversion\n"); }
283  };
284
285};
286
287///
288/// A class representing a splitting of expression into two parts. This class
289/// is needed to work with "open" expressions. It is closely related to
290/// expression itself, so it is contained in the same file.
291template <Direction D>
292class SplitIterator
293{
294  ///
295  /// Left side of splitted expression
296  Expr lt ;
297  ///
298  /// Right side of splitted expression
299  Expr rt ;
300  ///
301  /// Iterator state
302  bool state ;
303  ///
304  /// Copy constructor and assignment operator do not have any sense for this
305  /// class.
306  NO_COPY_CTOR(SplitIterator)
307  NO_ASSIGN(SplitIterator)
308
309public:
310  ///
311  /// Constructor
312  inline SplitIterator (Expr const& _expr, uintptr_t _min_len = 0) ;
313  ///
314  /// Destructor
315  ~SplitIterator () ;
316  ///
317  /// Increment iterator
318  inline SplitIterator& operator ++ () ;
319  ///
320  /// Postfix form of increment iterator
321  inline SplitIterator& operator ++ (int) ;
322  ///
323  /// Decrement iterator
324  inline SplitIterator& operator -- () ;
325  ///
326  /// Postfix form of decrement iterator
327  inline SplitIterator& operator -- (int) ;
328  ///
329  /// Get iterator state
330  inline operator bool () ;
331  ///
332  /// Get left part of expression
333  inline Expr const& get_left () const ;
334  ///
335  /// Get right part of expression
336  inline Expr const& get_right () const ;
337
338};
339
340///
341/// A macro naming iterator for expression variable
342#define iter(e) e##_iter
343///
344/// A macro splitting an expression variable
345#define lsplit(e, minlen, le, re) \
346  SplitIterator<d_lt> iter(e)(e, minlen); \
347  Expr const& le = iter(e).get_left(); \
348  Expr const& re = iter(e).get_right()
349
350}
351
352#endif // __rf_expr_hh__
Note: See TracBrowser for help on using the repository browser.