hqlstmt.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*##############################################################################
  2. Copyright (C) 2011 HPCC Systems.
  3. All rights reserved. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ############################################################################## */
  14. #ifndef HQLSTMT_HPP
  15. #define HQLSTMT_HPP
  16. #ifdef HQLCPP_EXPORTS
  17. #define HQLCPP_API __declspec(dllexport)
  18. #else
  19. #define HQLCPP_API __declspec(dllimport)
  20. #endif
  21. interface IHqlStmt;
  22. struct BuildOptions;
  23. class BuildCtx;
  24. class HqlStmt;
  25. class HqlCompoundStmt;
  26. class HqlStmts;
  27. class HqlCppInstance;
  28. class CHqlBoundExpr;
  29. class all_result_types;
  30. interface IFunctionInfo;
  31. //---------------------------------------------------------------------------
  32. // used to represent an association of something already calculated in the context
  33. // e.g. a cursor, temporary value, or even dependency information.
  34. enum AssocKind { AssocAny, AssocExpr, AssocActivity, AssocCursor, AssocClass,
  35. AssocRow,
  36. AssocActivityInstance,
  37. AssocExtract,
  38. AssocExtractContext,
  39. AssocSubQuery,
  40. AssocGraphNode,
  41. AssocSubGraph,
  42. AssocStmt,
  43. };
  44. class CHqlBoundExpr;
  45. struct HQLCPP_API HqlExprAssociation : public CInterface
  46. {
  47. public:
  48. HqlExprAssociation(IHqlExpression * _represents) { represents.set(_represents); }
  49. virtual bool isAlias() { return false; }
  50. virtual bool isRowAssociation() { return false; }
  51. virtual AssocKind getKind() = 0;
  52. virtual IHqlExpression * queryExpr() const { UNIMPLEMENTED; }
  53. virtual void getBound(CHqlBoundExpr & result);
  54. public:
  55. HqlExprAttr represents;
  56. };
  57. interface IAssociationVisitor
  58. {
  59. virtual bool visit(HqlExprAssociation & assoc) = 0; // return true if done
  60. };
  61. //---------------------------------------------------------------------------
  62. // Class used to represent current location for generating source code statements.
  63. class CHqlBoundExpr;
  64. class HQLCPP_API BuildCtx : public CInterface
  65. {
  66. friend class AssociationIterator;
  67. public:
  68. BuildCtx(HqlCppInstance & _state, _ATOM section);
  69. BuildCtx(HqlCppInstance & _state);
  70. BuildCtx(BuildCtx & _owner);
  71. ~BuildCtx();
  72. IHqlStmt * addAssign(IHqlExpression * target, IHqlExpression * value);
  73. IHqlStmt * addAssignIncrement(IHqlExpression * target, IHqlExpression * value);
  74. IHqlStmt * addAssignDecrement(IHqlExpression * target, IHqlExpression * value);
  75. IHqlStmt * addAlias(IHqlStmt * stmt);
  76. IHqlStmt * addBlock();
  77. IHqlStmt * addBreak();
  78. IHqlStmt * addCase(IHqlStmt * owner, IHqlExpression * condition);
  79. IHqlStmt * addContinue();
  80. IHqlStmt * addDeclare(IHqlExpression * name, IHqlExpression * value=NULL);
  81. IHqlStmt * addDeclareExternal(IHqlExpression * name);
  82. IHqlStmt * addDeclareAssign(IHqlExpression * name, IHqlExpression * value);
  83. IHqlStmt * addDefault(IHqlStmt * owner);
  84. IHqlStmt * addExpr(IHqlExpression * condition);
  85. IHqlStmt * addExprOwn(IHqlExpression * condition);
  86. IHqlStmt * addReturn(IHqlExpression * value);
  87. IHqlStmt * addFilter(IHqlExpression * condition);
  88. IHqlStmt * addFunction(IHqlExpression * funcdef);
  89. IHqlStmt * addGoto(const char * labelText);
  90. IHqlStmt * addGroup(); // like a block but no {}
  91. IHqlStmt * addGroupPass(IHqlExpression * pass);
  92. IHqlStmt * addIndirection(const BuildCtx & _parent); // pretend this is generated in the parent context (add a modified container)
  93. IHqlStmt * addLabel(const char * labelText);
  94. IHqlStmt * addLine(const char * filename = NULL, unsigned lineNum = 0);
  95. IHqlStmt * addLoop(IHqlExpression * cond, IHqlExpression * next, bool atEnd);
  96. IHqlStmt * addQuoted(const char * text);
  97. IHqlStmt * addQuotedF(const char * text, ...) __attribute__((format(printf, 2, 3)));
  98. IHqlStmt * addQuotedCompound(const char * text, const char * extra = NULL);
  99. IHqlStmt * addQuotedCompoundOpt(const char * text, const char * extra = NULL);
  100. IHqlStmt * addQuoted(StringBuffer & text) { return addQuoted(text.str()); }
  101. IHqlStmt * addQuotedCompound(StringBuffer & text, const char * extra = NULL){ return addQuotedCompound(text.str(), extra); }
  102. IHqlStmt * addSwitch(IHqlExpression * condition);
  103. void associate(HqlExprAssociation & next);
  104. void associateOwn(HqlExprAssociation & next);
  105. HqlExprAssociation * associateExpr(IHqlExpression * represents, IHqlExpression * expr);
  106. HqlExprAssociation * associateExpr(IHqlExpression * represents, const CHqlBoundExpr & bound);
  107. bool hasAssociation(HqlExprAssociation & search, bool unconditional);
  108. HqlExprAssociation * queryAssociation(IHqlExpression * dataset, AssocKind kind, HqlExprCopyArray * selectors);
  109. HqlExprAssociation * queryFirstAssociation(AssocKind kind);
  110. HqlExprAssociation * queryFirstCommonAssociation(AssocKind kind);
  111. HqlExprAssociation * queryMatchExpr(IHqlExpression * expr);
  112. bool getMatchExpr(IHqlExpression * expr, CHqlBoundExpr & bound);
  113. IHqlExpression * getTempDeclare(ITypeInfo * type, IHqlExpression * value);
  114. void needFunction(IFunctionInfo & helper);
  115. void needFunction(_ATOM name);
  116. void removeAssociation(HqlExprAssociation * search);
  117. IHqlStmt * replaceExpr(IHqlStmt * stmt, IHqlExpression * expr); // use with extreme care!
  118. IHqlStmt * selectBestContext(IHqlExpression * expr);
  119. void selectContainer();
  120. void selectElse(IHqlStmt * filter);
  121. void setNextConstructor() { setNextPriority(ConPrio); }
  122. void setNextDestructor() { setNextPriority(DesPrio); }
  123. void setNextNormal() { setNextPriority(NormalPrio); }
  124. void setNextPriority(unsigned newPrio);
  125. unsigned setPriority(unsigned newPrio);
  126. void set(_ATOM section);
  127. void set(BuildCtx & _owner);
  128. void walkAssociations(IAssociationVisitor & visitor);
  129. public:
  130. enum { ConPrio = 1, EarlyPrio =3000, NormalPrio = 5000, LatePrio = 7000, DesPrio = 9999, OutermostScopePrio };
  131. protected:
  132. HqlStmt * appendCompound(HqlCompoundStmt * next);
  133. HqlStmt * appendSimple(HqlStmt * next);
  134. void appendToOutermostScope(HqlStmt * next);
  135. void init(HqlStmts * _root);
  136. bool isChildOf(HqlStmt * stmt, HqlStmts * stmts);
  137. void recordDefine(HqlStmt * declare);
  138. IHqlStmt * recursiveGetBestContext(HqlStmts * searchStmts, HqlExprCopyArray & required);
  139. void selectCompound(IHqlStmt * stmt);
  140. private:
  141. BuildCtx(BuildCtx & owner, HqlStmts * _root);
  142. protected:
  143. HqlStmts * root;
  144. HqlStmts * curStmts;
  145. bool ignoreInput;
  146. unsigned curPriority;
  147. unsigned nextPriority;
  148. HqlCppInstance & state;
  149. };
  150. enum StmtKind {
  151. null_stmt,
  152. assign_stmt, block_stmt, group_stmt, declare_stmt,
  153. expr_stmt,
  154. return_stmt,
  155. quote_stmt,
  156. quote_compound_stmt,
  157. quote_compoundopt_stmt,
  158. filter_stmt,
  159. goto_stmt, label_stmt,
  160. switch_stmt, case_stmt, default_stmt,
  161. loop_stmt, break_stmt,
  162. pass_stmt, external_stmt,
  163. indirect_stmt,
  164. assigninc_stmt, assigndec_stmt,
  165. alias_stmt,
  166. line_stmt,
  167. continue_stmt,
  168. function_stmt,
  169. };
  170. interface IHqlStmt : public IInterface
  171. {
  172. public:
  173. virtual StringBuffer & getTextExtra(StringBuffer & out) = 0;
  174. virtual bool isIncluded() const = 0;
  175. virtual StmtKind getStmt() = 0;
  176. virtual unsigned numChildren() const = 0;
  177. virtual IHqlStmt * queryChild(unsigned index) const = 0;
  178. virtual IHqlExpression *queryExpr(unsigned index) = 0;
  179. //used when creating the statement graph
  180. virtual void mergeScopeWithContainer() = 0;
  181. virtual void setIncomplete(bool incomplete) = 0;
  182. virtual void setIncluded(bool _included) = 0;
  183. };
  184. class HqlCppTranslator;
  185. void peepholeOptimize(HqlCppInstance & instance, HqlCppTranslator & translator);
  186. class AssociationIterator
  187. {
  188. public:
  189. AssociationIterator(BuildCtx & ctx);
  190. bool first();
  191. bool isValid() { return curStmts != NULL; }
  192. inline bool next() { return doNext(); }
  193. HqlExprAssociation & get();
  194. protected:
  195. virtual bool doNext();
  196. protected:
  197. HqlStmts * rootStmts;
  198. unsigned curIdx;
  199. HqlStmts * curStmts;
  200. };
  201. class FilteredAssociationIterator : public AssociationIterator
  202. {
  203. public:
  204. FilteredAssociationIterator(BuildCtx & ctx, AssocKind _searchKind) : AssociationIterator(ctx) { searchKind = _searchKind; }
  205. virtual bool doNext();
  206. protected:
  207. AssocKind searchKind;
  208. };
  209. class BoundRow;
  210. class RowAssociationIterator : public AssociationIterator
  211. {
  212. public:
  213. RowAssociationIterator(BuildCtx & ctx) : AssociationIterator(ctx) {}
  214. virtual bool doNext();
  215. BoundRow & get() { return (BoundRow &)AssociationIterator::get(); }
  216. };
  217. unsigned calcTotalChildren(IHqlStmt * stmt);
  218. IHqlExpression * stripTranslatedCasts(IHqlExpression * e);
  219. IHqlExpression * peepholeAddExpr(IHqlExpression * left, IHqlExpression * right);
  220. bool rightFollowsLeft(IHqlExpression * left, IHqlExpression * leftLen, IHqlExpression * right);
  221. #endif