1 //
2 //      aegis - project change supervisor
3 //      Copyright (C) 1994-1996, 2002-2008 Peter Miller
4 //
5 //      This program is free software; you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation; either version 3 of the License, or
8 //      (at your option) any later version.
9 //
10 //      This program is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with this program. If not, see
17 //      <http://www.gnu.org/licenses/>.
18 //
19 
20 #ifndef AEGIS_AER_EXPR_H
21 #define AEGIS_AER_EXPR_H
22 
23 #include <common/ac/shared_ptr.h>
24 #include <common/ac/stddef.h>
25 
26 #include <libaegis/aer/pos.h>
27 #include <libaegis/aer/value.h>
28 
29 
30 /**
31   * The rpt_expr abstract base class is used to represent a generic
32   * expressson node in the report generator.
33   */
34 class rpt_expr
35 {
36 public:
37     typedef aegis_shared_ptr<rpt_expr> pointer;
38 
39     /**
40       * The destructor.
41       */
42     virtual ~rpt_expr();
43 
44 protected:
45     /**
46       * The default constructor.
47       */
48     rpt_expr();
49 
50 public:
51     /**
52       * The parse_error method is used to report parse errors, reported
53       * against the location of this expression node.
54       */
55     void parse_error(const char *fmt) const;
56 
57     /**
58       * The append method is used to append a sub-mode to the end of the
59       * list of child nodes of this expression node.
60       */
61     void append(const rpt_expr::pointer &child);
62 
63     /**
64       * The prepend method is used to prepend a sub-mode to the front of
65       * the list of child nodes of this expression node.
66       */
67     void prepend(const rpt_expr::pointer &child);
68 
69     /**
70       * The evaluate method may be used to calculate the value of the
71       * expression syntax tree.
72       *
73       * @param undefer
74       *     True if deferred values should be evaluated.
75       * @param dereference
76       *     True if reference values should be replaced with the
77       *     referenced value.
78       */
79     rpt_value::pointer evaluate(bool undefer, bool dereference) const;
80 
81     /**
82       * The get_nchildren method is used to obtain the number of child
83       * nodes associated with this node.
84       */
get_nchildren()85     size_t get_nchildren() const { return nchild; }
86 
87     /**
88       * The get_pos method is used to obtain the source file location
89       * associated with this node.
90       */
get_pos()91     rpt_position::pointer get_pos() const { return pos; }
92 
93     /**
94       * The pos_from_lex method is used to set the exproession node's
95       * source code position from the lexer's current position.
96       */
97     void pos_from_lex();
98 
99     /**
100       * The pos_from method is used to set the exproession node's
101       * source code position from the source code location of another
102       * expression node.
103       */
104     void pos_from(const rpt_expr::pointer &other);
105 
106 protected:
107     /**
108       * The evaluate method may be used to calculate the value of the
109       * expression syntax tree.
110       */
111     virtual rpt_value::pointer evaluate() const = 0;
112 
113 public:
114     /**
115       * The lvalue method may be used to determine whether or not this
116       * expression node is an L-value (something which may appear on the
117       * left hand side of an assigment, a variable).
118       *
119       * The default implementation, which is true for the vast majority
120       * of expression nodes, returns false.
121       */
122     virtual bool lvalue() const;
123 
124     /**
125       * The nth_child method may be used to obtain the specified child
126       * node of this node.
127       *
128       * @param n
129       *     The index of the child desired, zero based.
130       * @returns
131       *     pointer to child, or NULL if index out of range
132       */
133     rpt_expr::pointer nth_child(size_t n) const;
134 
135 private:
136     /**
137       * The pos instance variable is used to remember the location of
138       * this expression in the source code.
139       */
140     rpt_position::pointer pos;
141 
142     /**
143       * The child instance variable is used to remember the base address
144       * of a dynamically allocated array of pointer to child expression
145       * nodes.
146       */
147     rpt_expr::pointer *child;
148 
149     /**
150       * The nchild instance variable is used to remember the number of
151       * elements used to date in the "child" array.
152       */
153     size_t nchild;
154 
155     /**
156       * The nchild_max instance variable is used to remember the
157       * allocated size of the "child" array.
158       */
159     size_t nchild_max;
160 
161     /**
162       * The copy constructor.  Do not use.
163       */
164     rpt_expr(const rpt_expr &);
165 
166     /**
167       * The assignment operator.  Do not use.
168       */
169     rpt_expr &operator=(const rpt_expr &);
170 };
171 
172 #endif // AEGIS_AER_EXPR_H
173