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