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_EXPR_BASE 18 #define ZORBA_COMPILER_EXPR_BASE 19 20 #include <zorba/config.h> 21 22 #include "common/shared_types.h" 23 24 #include "compiler/parser/query_loc.h" 25 #include "compiler/parser/parse_constants.h" 26 #include "compiler/expression/expr_consts.h" 27 28 #include "functions/function_consts.h" 29 30 #include "types/typeimpl.h" 31 32 #include "context/static_context_consts.h" 33 34 35 namespace zorba 36 { 37 38 class static_context; 39 40 class expr; 41 42 class wrapper_expr; 43 44 class expr_visitor; 45 46 class CompilerCB; 47 48 enum expr_kind_t 49 { 50 const_expr_kind, 51 52 var_expr_kind, 53 54 doc_expr_kind, 55 elem_expr_kind, 56 attr_expr_kind, 57 text_expr_kind, 58 pi_expr_kind, 59 60 relpath_expr_kind, 61 axis_step_expr_kind, 62 match_expr_kind, 63 64 flwor_expr_kind, 65 gflwor_expr_kind, 66 if_expr_kind, 67 trycatch_expr_kind, 68 69 fo_expr_kind, 70 dynamic_function_invocation_expr_kind, 71 function_item_expr_kind, 72 73 castable_expr_kind, 74 cast_expr_kind, 75 instanceof_expr_kind, 76 treat_expr_kind, 77 promote_expr_kind, 78 name_cast_expr_kind, 79 80 validate_expr_kind, 81 82 extension_expr_kind, 83 84 order_expr_kind, 85 86 #ifndef ZORBA_NO_FULL_TEXT 87 ft_expr_kind, 88 #endif /* ZORBA_NO_FULL_TEXT */ 89 90 delete_expr_kind, 91 insert_expr_kind, 92 rename_expr_kind, 93 replace_expr_kind, 94 transform_expr_kind, 95 96 block_expr_kind, 97 var_decl_expr_kind, 98 var_set_expr_kind, 99 apply_expr_kind, 100 exit_expr_kind, 101 exit_catcher_expr_kind, 102 flowctl_expr_kind, 103 while_expr_kind, 104 105 eval_expr_kind, 106 debugger_expr_kind, 107 wrapper_expr_kind, 108 function_trace_expr_kind, 109 110 #ifdef ZORBA_WITH_JSON 111 json_direct_object_expr_kind, 112 json_object_expr_kind, 113 json_array_expr_kind, 114 #endif 115 116 unknown_expr_kind 117 }; 118 119 120 /******************************************************************************* 121 Base class for the expression tree node hierarchy 122 ********************************************************************************/ 123 class expr 124 { 125 friend class expr_iterator_data; 126 friend class ExprIterator; 127 friend class forletwin_clause; 128 friend class for_clause; 129 friend class let_clause; 130 friend class where_clause; 131 friend class function_trace_expr; 132 133 public: 134 typedef std::map<const expr *, expr*> substitution_t; 135 136 typedef substitution_t::iterator subst_iter_t; 137 138 typedef std::set<const var_expr *> FreeVars; 139 140 typedef enum 141 { 142 PRODUCES_SORTED_NODES = 0, 143 PRODUCES_DISTINCT_NODES = 2, 144 IGNORES_SORTED_NODES = 4, 145 IGNORES_DUPLICATE_NODES = 6, 146 NON_DISCARDABLE = 8, 147 UNFOLDABLE = 10, 148 CONTAINS_RECURSIVE_CALL = 12, 149 PROPAGATES_INPUT_NODES = 14, 150 IN_UNSAFE_CONTEXT = 16, 151 MUST_COPY_NODES = 18, 152 CONTAINS_PRAGMA = 20 153 } Annotationkey; 154 155 typedef enum 156 { 157 PRODUCES_SORTED_NODES_MASK = 0x003, 158 PRODUCES_DISTINCT_NODES_MASK = 0x00C, 159 IGNORES_SORTED_NODES_MASK = 0x030, 160 IGNORES_DUPLICATE_NODES_MASK = 0x0C0, 161 NON_DISCARDABLE_MASK = 0x300, 162 UNFOLDABLE_MASK = 0xC00, 163 CONTAINS_RECURSIVE_CALL_MASK = 0x3000, 164 PROPAGATES_INPUT_NODES_MASK = 0xC000, 165 IN_UNSAFE_CONTEXT_MASK = 0x30000, 166 MUST_COPY_NODES_MASK = 0xC0000, 167 CONTAINS_PRAGMA_MASK = 0x300000 168 } AnnotationMask; 169 170 171 protected: 172 static expr* iter_end_expr; 173 static expr* * iter_done; 174 175 protected: 176 static_context * theSctx; 177 178 QueryLoc theLoc; 179 180 unsigned short theKind; 181 unsigned short theScriptingKind; 182 183 xqtref_t theType; 184 185 uint32_t theFlags1; 186 187 FreeVars theFreeVars; 188 189 CompilerCB *const theCCB; 190 191 public: 192 static bool is_sequential(unsigned short theScriptingKind); 193 194 static void checkSimpleExpr(const expr* e); 195 196 static void checkNonUpdating(const expr* e); 197 198 protected: 199 expr(CompilerCB*, static_context*, const QueryLoc&, expr_kind_t); 200 expr()201 expr() : theSctx(NULL), theFlags1(0), theCCB(NULL) {} 202 203 public: 204 virtual ~expr(); 205 get_ccb()206 CompilerCB* get_ccb() {return theCCB;} 207 get_expr_kind()208 expr_kind_t get_expr_kind() const { return static_cast<expr_kind_t>(theKind); } 209 get_loc()210 const QueryLoc& get_loc() const { return theLoc; } 211 set_loc(const QueryLoc & loc)212 void set_loc(const QueryLoc& loc) { theLoc = loc; } 213 get_sctx()214 static_context* get_sctx() const { return theSctx; } 215 216 TypeManager* get_type_manager() const; 217 getFlags()218 uint32_t getFlags() const { return theFlags1; } 219 setFlags(uint32_t flags)220 void setFlags(uint32_t flags) { theFlags1 = flags; } 221 get_scripting_detail()222 unsigned short get_scripting_detail() const { return theScriptingKind; } 223 224 bool is_updating() const; 225 226 bool is_sequential() const; 227 228 bool is_vacuous() const; 229 230 bool is_simple() const; 231 232 bool is_updating_or_vacuous() const; 233 234 void set_not_exiting(); 235 236 void adjustSequential(); 237 238 void checkScriptingKind() const; 239 240 void compute_return_type(bool deep, bool* modified); 241 242 xqtref_t get_return_type(); 243 244 expr* clone() const; 245 246 expr* clone(substitution_t&) const; 247 248 virtual expr* cloneImpl(substitution_t& substitution) const; 249 250 virtual void accept(expr_visitor& v) = 0; 251 252 void accept_children(expr_visitor& v); 253 254 virtual std::ostream& put(std::ostream&) const = 0; 255 256 std::string toString() const; 257 258 public: 259 // Annotation : produces-sorted-nodes 260 BoolAnnotationValue getProducesSortedNodes() const; 261 262 void setProducesSortedNodes(BoolAnnotationValue v); 263 264 bool producesSortedNodes() const; 265 266 // Annotation : produces-distinct-nodes 267 BoolAnnotationValue getProducesDistinctNodes() const; 268 269 void setProducesDistinctNodes(BoolAnnotationValue v); 270 271 bool producesDistinctNodes() const; 272 273 // Annotation : propagatesInputNodes 274 BoolAnnotationValue getPropagatesInputNodes() const; 275 276 void setPropagatesInputNodes(BoolAnnotationValue v); 277 278 // Annotation : ignores-sorted-nodes 279 BoolAnnotationValue getIgnoresSortedNodes() const; 280 281 void setIgnoresSortedNodes(BoolAnnotationValue v); 282 283 bool ignoresSortedNodes() const; 284 285 // Annotation : ignores-duplicated-nodes 286 BoolAnnotationValue getIgnoresDuplicateNodes() const; 287 288 void setIgnoresDuplicateNodes(BoolAnnotationValue v); 289 290 bool ignoresDuplicateNodes() const; 291 292 // Annotation : non-discardable 293 BoolAnnotationValue getNonDiscardable() const; 294 295 bool isNonDiscardable() const; 296 297 void setNonDiscardable(BoolAnnotationValue v); 298 299 // Annotation : unfoldable 300 BoolAnnotationValue getUnfoldable() const; 301 302 void setUnfoldable(BoolAnnotationValue v); 303 304 bool isUnfoldable() const; 305 306 // Annotation : contains-recursive-call 307 BoolAnnotationValue getContainsRecursiveCall() const; 308 309 void setContainsRecursiveCall(BoolAnnotationValue v); 310 311 bool containsRecursiveCall() const; 312 313 // Annotation : mustCopyNodes 314 BoolAnnotationValue getMustCopyNodes() const; 315 316 void setMustCopyNodes(BoolAnnotationValue v); 317 318 // Annotation : inUnsafeContext 319 BoolAnnotationValue getInUnsafeContext() const; 320 321 void setInUnsafeContext(BoolAnnotationValue v); 322 323 bool inUnsafeContext() const; 324 325 // Annotation : containsPragma 326 BoolAnnotationValue getContainsPragma() const; 327 328 void setContainsPragma(BoolAnnotationValue v); 329 330 bool containsPragma() const; 331 332 // Annotation : free vars getFreeVars()333 const FreeVars& getFreeVars() const { return theFreeVars; } 334 getFreeVars()335 FreeVars& getFreeVars() { return theFreeVars; } 336 337 void setFreeVars(FreeVars& s); 338 339 bool is_constant() const; 340 341 bool is_nondeterministic() const; 342 343 void replace_expr(expr* oldExpr, expr* newExpr); 344 345 bool contains_expr(const expr* e) const; 346 347 bool contains_node_construction() const; 348 349 void get_exprs_of_kind( 350 expr_kind_t kind, 351 bool deep, 352 std::vector<expr*>& exprs) const; 353 354 void get_fo_exprs_of_kind( 355 FunctionConsts::FunctionKind kind, 356 bool deep, 357 std::vector<expr*>& exprs) const; 358 359 bool is_map(expr* e, static_context* sctx) const; 360 361 FunctionConsts::FunctionKind get_function_kind() const; 362 363 const var_expr* get_var() const; 364 365 const store::Item* getQName(static_context* sctx) const; 366 367 void clear_annotations(); 368 369 xqtref_t get_return_type_with_empty_input(const expr* input) const; 370 371 protected: 372 virtual void compute_scripting_kind() = 0; 373 374 bool is_map_internal(const expr* e, bool& found) const; 375 }; 376 377 378 /******************************************************************************* 379 380 ********************************************************************************/ 381 #define DEF_EXPR_ACCEPT( type ) \ 382 void type::accept(expr_visitor& v) \ 383 { \ 384 if (v.begin_visit(*this)) \ 385 accept_children(v); \ 386 \ 387 v.end_visit(*this); \ 388 } 389 390 391 } 392 #endif 393 394 /* 395 * Local variables: 396 * mode: c++ 397 * End: 398 */ 399 /* vim:set et sw=2 ts=2: */ 400