1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 #ifndef ZORBA_COMPILER_VAR_EXPR
18 #define ZORBA_COMPILER_VAR_EXPR
19 
20 #include "compiler/expression/expr_base.h"
21 
22 namespace zorba
23 {
24 
25 class flwor_clause;
26 class forletwin_clause;
27 class for_clause;
28 class copy_clause;
29 class var_expr;
30 class VarInfo;
31 
32 /******************************************************************************
33 
34   var_expr represents a variable. There is one var_expr for each distinct
35   variable declared anywhere inside a query body or prolog.
36 
37   var_expr represents both the var declaration and all references of the var.
38   However, each distinct reference to a var is wrapped in wrapper_expr. For
39   example, the exprs F($x) and G($x) are modelled in the expr tree as:
40 
41        F               G
42        |               |
43    wrapper_expr    wrapper_expr
44          \             /
45           \           /
46            var_expr($x)
47 
48 
49   For context vars with a defining expr, the mapping between the var qname and
50   the defining expr is explicitly stored by creating an
51   fn:ctxvar-assign(qname_expr, def_expr) expr (see method
52   wrap_in_globalvar_assign() in translator.cpp).
53 
54   For vars declared in FOR, LET, or WINDOW clauses, their defining expr is
55   stored in the associated clause (see theForletClause data member below).
56 
57   theUniqueId:
58   ------------
59   A unique numeric id for variales whose value is stored in the dynamic context,
60   ie, prolog and local vars. It is used as an index into an array that stores
61   the values.
62 
63   theKind:
64   --------
65   The kind of the variable (see var_kind enum below)
66 
67   theVarName:
68   -----------
69   The fully expanded qname of the var (qname item)
70 
71   theDeclaredType:
72   ----------------
73   The type, if any, specified in the declaration of the variable
74 
75   theFlworClause:
76   ---------------
77   If this is a var declared in flwor clause, theFlworClause points to the
78   defining clause. That clause also contains the defining expr for the var
79   and a pointer back to this var_exr.
80 
81   theCopyClause:
82   --------------
83   If this is a var declared in a copy clause of a transform expr, theCopyClause
84   points to that clause. That clause contains the defining expr for the var and
85   a pointer back to this var_exr.
86 
87   theParamPos:
88   ------------
89   For arg vars, it is the position, within the param list, of parameter that is
90   bound to this arg var.
91 
92   theUDF:
93   -------
94   For arg vars, the corresponding UDF.
95 
96   theSetExprs:
97   ------------
98   For global and local vars, this vector contains a pointer to the var_decl_expr
99   for the variable and to each var_set_expr for the same var.
100 
101   theIsExternal:
102   --------------
103   Whether this is an external variable or not (for prolog vars only).
104 
105   theIsPrivate:
106   -------------
107   Whether this is a private variable or not (for prolog vars only).
108 
109   theIsMutable:
110   -------------
111   Whether this is a mutable variable or not (for prolog and local vars).
112 
113   theHasInitializer:
114   ------------------
115    Whether the variable has an initializing expr or not (for prolog vars only).
116 *******************************************************************************/
117 class var_expr : public expr
118 {
119   friend class expr;
120   friend class ExprManager;
121 
122 public:
123   enum var_kind
124   {
125     unknown_var = 0,
126 
127     eval_var,  // TODO: remove (it is used only in the debugger_expr)
128 
129     for_var,
130     let_var,
131     pos_var,
132     win_var,
133     score_var,
134     wincond_out_var,
135     wincond_out_pos_var,
136     wincond_in_var,
137     wincond_in_pos_var,
138     count_var,
139     groupby_var,
140     non_groupby_var,
141 
142     copy_var,
143 
144     catch_var,
145 
146     prolog_var,
147 
148     local_var,
149 
150     arg_var
151   };
152 
153 protected:
154   ulong                 theUniqueId;
155 
156   var_kind              theVarKind;
157 
158   store::Item_t         theName;
159 
160   xqtref_t              theDeclaredType;
161 
162   flwor_clause        * theFlworClause;
163 
164   copy_clause         * theCopyClause;
165 
166   csize                 theParamPos;
167 
168   user_function       * theUDF;
169 
170   std::vector<expr*>    theSetExprs;
171 
172   VarInfo             * theVarInfo;
173 
174   bool                  theIsExternal;
175 
176   bool                  theIsPrivate;
177 
178   bool                  theIsMutable;
179 
180   bool                  theHasInitializer;
181 
182 public:
183   static std::string decode_var_kind(enum var_kind);
184 
185 protected:
186   var_expr(
187       CompilerCB* ccb,
188       static_context* sctx,
189       const QueryLoc& loc,
190       var_kind k,
191       store::Item* name);
192 
193   var_expr(const var_expr& source);
194 
195   virtual ~var_expr();
196 
197 public:
198   void set_var_info(VarInfo* v);
199 
get_var_info()200   VarInfo* get_var_info() const { return theVarInfo; }
201 
get_unique_id()202   ulong get_unique_id() const { return theUniqueId; }
203 
204   void set_unique_id(ulong v);
205 
206   store::Item* get_name() const;
207 
get_kind()208   var_kind get_kind() const { return theVarKind; }
209 
set_kind(var_kind k)210   void set_kind(var_kind k) { theVarKind = k; }
211 
is_private()212   bool is_private() const { return theIsPrivate; }
213 
set_private(bool v)214   void set_private(bool v) { theIsPrivate = v; }
215 
is_external()216   bool is_external() const { return theIsExternal; }
217 
218   void set_external(bool v);
219 
has_initializer()220   bool has_initializer() const { return theHasInitializer; }
221 
222   void set_has_initializer(bool v);
223 
is_mutable()224   bool is_mutable() const { return theIsMutable; }
225 
set_mutable(bool v)226   void set_mutable(bool v) { theIsMutable = v; }
227 
228   xqtref_t get_type() const;
229 
230   void set_type(xqtref_t t);
231 
set_flwor_clause(flwor_clause * c)232   void set_flwor_clause(flwor_clause* c) { theFlworClause = c; }
233 
get_flwor_clause()234   flwor_clause* get_flwor_clause() const { return theFlworClause; }
235 
236   forletwin_clause* get_forletwin_clause() const;
237 
238   for_clause* get_for_clause() const;
239 
get_copy_clause()240   copy_clause* get_copy_clause() const { return theCopyClause; }
241 
set_copy_clause(copy_clause * c)242   void set_copy_clause(copy_clause* c) { theCopyClause = c; }
243 
244   expr* get_domain_expr() const;
245 
246   const var_expr* get_pos_var() const;
247 
get_param_pos()248   csize get_param_pos() const { return theParamPos; }
249 
set_param_pos(csize pos)250   void set_param_pos(csize pos) { theParamPos = pos; }
251 
get_udf()252   user_function* get_udf() const { return theUDF; }
253 
set_udf(const user_function * udf)254   void set_udf(const user_function* udf) { theUDF = const_cast<user_function*>(udf); }
255 
add_set_expr(expr * e)256   void add_set_expr(expr* e) { theSetExprs.push_back(e); }
257 
258   void remove_set_expr(expr* e);
259 
num_set_exprs()260   csize num_set_exprs() const { return theSetExprs.size(); }
261 
get_set_expr(csize i)262   expr* get_set_expr(csize i) const { return theSetExprs[i]; }
263 
setExprsBegin()264   std::vector<expr*>::const_iterator setExprsBegin() const { return theSetExprs.begin(); }
265 
setExprsEnd()266   std::vector<expr*>::const_iterator setExprsEnd() const { return theSetExprs.end(); }
267 
268   bool is_context_item() const;
269 
270   void compute_scripting_kind();
271 
272   expr* cloneImpl(substitution_t& subst) const;
273 
274   void accept(expr_visitor&);
275 
276   std::ostream& put(std::ostream&) const;
277 };
278 
279 
280 struct GlobalBinding
281 {
282   var_expr  * theVar;
283   expr      * theExpr;
284   bool        theIsExternal;
285 
286 public:
GlobalBindingGlobalBinding287   GlobalBinding() : theIsExternal(false) {}
288 
GlobalBindingGlobalBinding289   GlobalBinding(var_expr* v, expr* e, bool external)
290     :
291     theVar(v),
292     theExpr(e),
293     theIsExternal(external)
294   {
295   }
296 
~GlobalBindingGlobalBinding297   virtual ~GlobalBinding() {}
298 
is_externGlobalBinding299   bool is_extern() const { return theIsExternal; }
300 };
301 
302 
303 }
304 
305 #endif  // ZORBA_VAR_EXPR_H
306 
307 /*
308  * Local variables:
309  * mode: c++
310  * End:
311  */
312 /* vim:set et sw=2 ts=2: */
313