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 #include "stdafx.h"
17
18 #include "functions/udf.h"
19
20 #include "compiler/expression/var_expr.h"
21 #include "compiler/expression/update_exprs.h"
22 #include "compiler/expression/flwor_expr.h"
23 #include "compiler/expression/expr_visitor.h"
24 #include "compiler/api/compilercb.h"
25
26 #include "types/typeops.h"
27
28 #include "context/static_context.h"
29
30 #include "diagnostics/assert.h"
31
32
33 namespace zorba
34 {
35
36
37 /*******************************************************************************
38
39 ********************************************************************************/
decode_var_kind(enum var_kind k)40 std::string var_expr::decode_var_kind(enum var_kind k)
41 {
42 switch (k)
43 {
44 case for_var: return "FOR"; break;
45 case let_var: return "LET"; break;
46 case win_var: return "WIN"; break;
47 case pos_var: return "POS"; break;
48 case wincond_out_var: return "WINCOND"; break;
49 case wincond_in_var: return "WINCOND IN"; break;
50 case wincond_out_pos_var: return "WINCOND POS"; break;
51 case wincond_in_pos_var: return "WINCOND IN POS"; break;
52 case count_var: return "CNT"; break;
53 case score_var: return "SCORE"; break;
54 case prolog_var: return "PROLOG"; break;
55 case local_var: return "LOCAL"; break;
56 case catch_var: return "CATCH"; break;
57 case copy_var: return "COPY"; break;
58 case groupby_var: return "GROUPBY"; break;
59 case non_groupby_var: return "NON-GROUPBY"; break;
60 case arg_var: return "ARG"; break;
61 case eval_var: return "EVAL"; break;
62 default: return "???";
63 }
64 }
65
66
67 /*******************************************************************************
68
69 ********************************************************************************/
var_expr(CompilerCB * ccb,static_context * sctx,const QueryLoc & loc,var_kind k,store::Item * name)70 var_expr::var_expr(
71 CompilerCB* ccb,
72 static_context* sctx,
73 const QueryLoc& loc,
74 var_kind k,
75 store::Item* name)
76 :
77 expr(ccb, sctx, loc, var_expr_kind),
78 theUniqueId(0),
79 theVarKind(k),
80 theName(name),
81 theDeclaredType(NULL),
82 theFlworClause(NULL),
83 theCopyClause(NULL),
84 theParamPos(0),
85 theUDF(NULL),
86 theVarInfo(NULL),
87 theIsExternal(false),
88 theIsPrivate(false),
89 theIsMutable(true),
90 theHasInitializer(false)
91 {
92 compute_scripting_kind();
93
94 setUnfoldable(ANNOTATION_TRUE_FIXED);
95 }
96
97
98 /*******************************************************************************
99
100 ********************************************************************************/
var_expr(const var_expr & source)101 var_expr::var_expr(const var_expr& source)
102 :
103 expr(source),
104 theUniqueId(0),
105 theVarKind(source.theVarKind),
106 theName(source.theName),
107 theDeclaredType(source.theDeclaredType),
108 theFlworClause(NULL),
109 theCopyClause(NULL),
110 theParamPos(source.theParamPos),
111 theUDF(source.theUDF),
112 theVarInfo(NULL),
113 theIsExternal(source.theIsExternal),
114 theIsPrivate(source.theIsPrivate),
115 theIsMutable(source.theIsMutable),
116 theHasInitializer(source.theHasInitializer)
117 {
118 }
119
120
121 /*******************************************************************************
122
123 ********************************************************************************/
~var_expr()124 var_expr::~var_expr()
125 {
126 if (theVarInfo)
127 {
128 assert(theVarKind == prolog_var);
129 assert(theVarInfo->getName() != NULL);
130 theVarInfo->clearVar();
131 }
132 }
133
134
135 /*******************************************************************************
136
137 ********************************************************************************/
set_var_info(VarInfo * v)138 void var_expr::set_var_info(VarInfo* v)
139 {
140 assert(theVarInfo == NULL);
141 theVarInfo = v;
142 }
143
144
145 /*******************************************************************************
146
147 ********************************************************************************/
get_name() const148 store::Item* var_expr::get_name() const
149 {
150 return theName.getp();
151 }
152
153
154 /*******************************************************************************
155
156 ********************************************************************************/
set_unique_id(ulong v)157 void var_expr::set_unique_id(ulong v)
158 {
159 assert(theUniqueId == 0);
160
161 theUniqueId = v;
162
163 if (theVarInfo)
164 {
165 assert(theVarKind == prolog_var);
166 theVarInfo->setId(v);
167 }
168 }
169
170
171 /*******************************************************************************
172
173 ********************************************************************************/
set_external(bool v)174 void var_expr::set_external(bool v)
175 {
176 assert(theVarKind == prolog_var);
177 theIsExternal = v;
178
179 if (theVarInfo)
180 {
181 assert(theVarKind == prolog_var);
182 theVarInfo->setIsExternal(v);
183 }
184 }
185
186
187 /*******************************************************************************
188
189 ********************************************************************************/
set_has_initializer(bool v)190 void var_expr::set_has_initializer(bool v)
191 {
192 theHasInitializer = v;
193
194 if (theVarInfo)
195 {
196 assert(theVarKind == prolog_var);
197 theVarInfo->setHasInitializer(v);
198 }
199 }
200
201
202 /*******************************************************************************
203
204 ********************************************************************************/
set_type(xqtref_t t)205 void var_expr::set_type(xqtref_t t)
206 {
207 theDeclaredType = t;
208
209 if (theVarInfo)
210 {
211 assert(theVarKind == prolog_var);
212 theVarInfo->setType(t);
213 }
214 }
215
216
217 /*******************************************************************************
218
219 ********************************************************************************/
get_type() const220 xqtref_t var_expr::get_type() const
221 {
222 return theDeclaredType;
223 }
224
225
226 /*******************************************************************************
227
228 ********************************************************************************/
get_pos_var() const229 const var_expr* var_expr::get_pos_var() const
230 {
231 if (theVarKind == for_var)
232 {
233 return reinterpret_cast<for_clause*>(theFlworClause)->get_pos_var();
234 }
235 else
236 {
237 return NULL;
238 }
239 }
240
241
242 /*******************************************************************************
243
244 ********************************************************************************/
get_domain_expr() const245 expr* var_expr::get_domain_expr() const
246 {
247 if (theFlworClause)
248 {
249 if (theVarKind == for_var ||
250 theVarKind == let_var ||
251 theVarKind == win_var ||
252 theVarKind == wincond_in_var ||
253 theVarKind == wincond_out_var)
254 {
255 return reinterpret_cast<forletwin_clause*>(theFlworClause)->get_expr();
256 }
257 else if (theVarKind == groupby_var)
258 {
259 return reinterpret_cast<group_clause*>(theFlworClause)->
260 get_input_for_group_var(this);
261 }
262 else if (theVarKind == non_groupby_var)
263 {
264 return reinterpret_cast<group_clause*>(theFlworClause)->
265 get_input_for_nongroup_var(this);
266 }
267 }
268 else if (theCopyClause)
269 {
270 return theCopyClause->getExpr();
271 }
272
273 return NULL;
274 }
275
276
277 /*******************************************************************************
278
279 ********************************************************************************/
get_forletwin_clause() const280 forletwin_clause* var_expr::get_forletwin_clause() const
281 {
282 return dynamic_cast<forletwin_clause*>(theFlworClause);
283 }
284
285
286 /*******************************************************************************
287
288 ********************************************************************************/
get_for_clause() const289 for_clause* var_expr::get_for_clause() const
290 {
291 return dynamic_cast<for_clause*>(theFlworClause);
292 }
293
294
295 /*******************************************************************************
296
297 ********************************************************************************/
remove_set_expr(expr * e)298 void var_expr::remove_set_expr(expr* e)
299 {
300 assert(theVarKind == local_var || theVarKind == prolog_var);
301
302 bool found = false;
303 std::vector<expr*>::iterator ite = theSetExprs.begin();
304 std::vector<expr*>::iterator end = theSetExprs.end();
305 for (; ite != end; ++ite)
306 {
307 if (*ite == e)
308 {
309 theSetExprs.erase(ite);
310 found = true;
311 break;
312 }
313 }
314
315 ZORBA_ASSERT(found);
316 }
317
318
319 /*******************************************************************************
320
321 ********************************************************************************/
is_context_item() const322 bool var_expr::is_context_item() const
323 {
324 return theName->getLocalName() == ".";
325 }
326
327
328 /*******************************************************************************
329
330 ********************************************************************************/
compute_scripting_kind()331 void var_expr::compute_scripting_kind()
332 {
333 theScriptingKind = SIMPLE_EXPR;
334 }
335
336
337 /*******************************************************************************
338
339 ********************************************************************************/
cloneImpl(expr::substitution_t & subst) const340 expr* var_expr::cloneImpl(expr::substitution_t& subst) const
341 {
342 expr::subst_iter_t i = subst.find(this);
343
344 if (i == subst.end())
345 return const_cast<var_expr*>(this);
346
347 return i->second;
348 }
349
350
351 /*******************************************************************************
352
353 ********************************************************************************/
accept(expr_visitor & v)354 void var_expr::accept(expr_visitor& v)
355 {
356 if (v.begin_visit(*this))
357 accept_children(v);
358
359 v.end_visit(*this);
360 }
361
362
363 }
364
365 /* vim:set et sw=2 ts=2: */
366