2
0

BfReducer.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. #pragma once
  2. #include "BeefySysLib/Common.h"
  3. #include "BfAst.h"
  4. #include "BfType.h"
  5. #include "BeefySysLib/util/BumpAllocator.h"
  6. NS_BF_BEGIN
  7. class BfPassInstance;
  8. class BfResolvePassData;
  9. class BfReducer
  10. {
  11. public:
  12. enum CreateExprFlags
  13. {
  14. CreateExprFlags_None,
  15. CreateExprFlags_NoCaseExpr = 1,
  16. CreateExprFlags_NoAssignment = 2,
  17. CreateExprFlags_AllowVariableDecl = 4,
  18. CreateExprFlags_PermissiveVariableDecl = 8,
  19. CreateExprFlags_NoCast = 0x10,
  20. CreateExprFlags_BreakOnRChevron = 0x20,
  21. CreateExprFlags_ExitOnBang = 0x40,
  22. CreateExprFlags_ExitOnParenExpr = 0x80,
  23. CreateExprFlags_NoCheckBinOpPrecedence = 0x100,
  24. CreateExprFlags_BreakOnCascade = 0x200,
  25. CreateExprFlags_EarlyExit = 0x400, // Don't attempt binary or ternary operations
  26. CreateExprFlags_AllowEmpty = 0x800
  27. };
  28. enum CreateStmtFlags
  29. {
  30. CreateStmtFlags_None,
  31. CreateStmtFlags_NoCaseExpr = 1,
  32. CreateStmtFlags_FindTrailingSemicolon = 2,
  33. CreateStmtFlags_AllowUnterminatedExpression = 4,
  34. CreateStmtFlags_AllowLocalFunction = 8,
  35. CreateStmtFlags_ForceVariableDecl = 0x10,
  36. CreateStmtFlags_To_CreateExprFlags_Mask = 1
  37. };
  38. enum CreateTypeRefFlags
  39. {
  40. CreateTypeRefFlags_None,
  41. CreateTypeRefFlags_NoParseArrayBrackets = 1,
  42. CreateTypeRefFlags_SafeGenericParse = 2,
  43. CreateTypeRefFlags_AllowSingleMemberTuple = 4,
  44. CreateTypeRefFlags_EarlyExit = 8
  45. };
  46. struct BfVisitorPos
  47. {
  48. BfBlock* mParent;
  49. int mReadPos;
  50. int mWritePos;
  51. int mTotalSize;
  52. BfVisitorPos(BfBlock* parent = NULL)
  53. {
  54. mParent = parent;
  55. mReadPos = -1;
  56. mWritePos = 0;
  57. if (parent != NULL)
  58. mTotalSize = parent->GetSize();
  59. else
  60. mTotalSize = 0;
  61. }
  62. bool MoveNext()
  63. {
  64. mReadPos++;
  65. return mReadPos < mTotalSize;
  66. }
  67. BfAstNode* GetCurrent()
  68. {
  69. if ((uint)mReadPos >= (uint)mTotalSize)
  70. return NULL;
  71. return (*mParent)[mReadPos];
  72. }
  73. BfAstNode* Get(int idx)
  74. {
  75. if (((uint)idx >= (uint)mTotalSize))
  76. return NULL;
  77. return (*mParent)[idx];
  78. }
  79. void Set(int idx, BfAstNode* node)
  80. {
  81. if (((uint)idx >= (uint)mTotalSize))
  82. return;
  83. (*mParent)[idx] = node;
  84. }
  85. void ReplaceCurrent(BfAstNode* node)
  86. {
  87. if ((uint)mReadPos >= (uint)mTotalSize)
  88. return;
  89. (*mParent)[mReadPos] = node;
  90. }
  91. void Write(BfAstNode* node)
  92. {
  93. (*mParent)[mWritePos++] = node;
  94. BF_ASSERT(mWritePos <= mReadPos);
  95. }
  96. BfAstNode* GetNext()
  97. {
  98. if ((uint)(mReadPos + 1) >= (uint)(mTotalSize))
  99. return NULL;
  100. return (*mParent)[mReadPos + 1];
  101. }
  102. int GetReadNodesLeft()
  103. {
  104. return std::max(0, mTotalSize - mReadPos);
  105. }
  106. void Trim()
  107. {
  108. mParent->SetSize(mWritePos);
  109. }
  110. };
  111. public:
  112. BfAstAllocator* mAlloc;
  113. BfSystem* mSystem;
  114. BfSource* mSource;
  115. BfPassInstance* mPassInstance;
  116. BfResolvePassData* mResolvePassData;
  117. BfAstNode* mTypeMemberNodeStart;
  118. int mClassDepth;
  119. int mMethodDepth;
  120. BfTypeDeclaration* mCurTypeDecl;
  121. BfTypeDeclaration* mLastTypeDecl;
  122. BfMethodDeclaration* mCurMethodDecl;
  123. BfAstNode* mLastBlockNode;
  124. bool mStmtHasError;
  125. bool mPrevStmtHadError;
  126. bool mCompatMode; // Does C++ compatible parsing
  127. bool mAllowTypeWildcard;
  128. bool mIsFieldInitializer;
  129. bool mInParenExpr;
  130. bool mSkipCurrentNodeAssert;
  131. BfVisitorPos mVisitorPos;
  132. int mDocumentCheckIdx;
  133. SizedArray<BfNamespaceDeclaration*, 4> mCurNamespaceStack;
  134. SizedArray<BfExteriorNode, 4> mExteriorNodes;
  135. int mAssertCurrentNodeIdx;
  136. public:
  137. BfAstNode* Fail(const StringImpl& errorMsg, BfAstNode* refNode);
  138. BfAstNode* FailAfter(const StringImpl& errorMsg, BfAstNode* refNode);
  139. void AddErrorNode(BfAstNode* astNode, bool removeNode = true);
  140. public:
  141. bool StringEquals(BfAstNode* node, BfAstNode* node2);
  142. bool IsSemicolon(BfAstNode* node);
  143. BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken token);
  144. BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB);
  145. BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC);
  146. BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC, BfToken tokenD);
  147. BfIdentifierNode* ExpectIdentifierAfter(BfAstNode* node, const char* typeName = NULL);
  148. BfBlock* ExpectBlockAfter(BfAstNode* node);
  149. BfTokenNode* BreakDoubleChevron(BfTokenNode* tokenNode);
  150. BfTokenNode* BreakQuestionLBracket(BfTokenNode* tokenNode);
  151. BfCommentNode* FindDocumentation(BfAstNode* defNodeHead, BfAstNode* defNodeEnd = NULL, bool checkDocAfter = false);
  152. void AssertCurrentNode(BfAstNode* node);
  153. bool IsNodeRelevant(BfAstNode* astNode);
  154. bool IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode);
  155. void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner);
  156. void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode);
  157. bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
  158. BfAstNode* CreateAllocNode(BfTokenNode* newNode);
  159. BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1, bool allowIn = false);
  160. BfEnumCaseBindExpression* CreateEnumCaseBindExpression(BfTokenNode* bindToken);
  161. BfExpression* CheckBinaryOperatorPrecedence(BfBinaryOperatorExpression* binOpExpression);
  162. BfExpression* ApplyToFirstExpression(BfUnaryOperatorExpression* unaryOp, BfExpression* target);
  163. BfIdentifierNode* ExtractExplicitInterfaceRef(BfAstNode* memberDeclaration, BfIdentifierNode* nameIdentifier, BfTypeReference** outExplicitInterface, BfTokenNode** outExplicitInterfaceDotToken);
  164. BfTokenNode* ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, BfToken endToken, bool requireNames);
  165. BfTokenNode* ReadArguments(BfAstNode* parentNode, BfAstNode* afterNode, SizedArrayImpl<BfExpression*>* arguments, SizedArrayImpl<BfTokenNode*>* commas, BfToken endToken, bool allowSkippedArgs = false, CreateExprFlags createExprFlags = CreateExprFlags_None);
  166. void ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, BfBlock* block);
  167. BfAstNode* ReadTypeMember(BfTokenNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
  168. BfAstNode* ReadTypeMember(BfAstNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
  169. BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode);
  170. void TryIdentifierConvert(int readPos);
  171. void CreateQualifiedNames(BfAstNode* node);
  172. BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
  173. BfFieldDeclaration* CreateFieldDeclaration(BfTokenNode* tokenNode, BfTypeReference* typeRef, BfIdentifierNode* nameIdentifier, BfFieldDeclaration* prevFieldDeclaration);
  174. BfAttributeDirective* CreateAttributeDirective(BfTokenNode* startToken);
  175. BfStatement* CreateAttributedStatement(BfTokenNode* tokenNode, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
  176. BfExpression* CreateAttributedExpression(BfTokenNode* tokenNode, bool onlyAllowIdentifier);
  177. BfDelegateBindExpression* CreateDelegateBindExpression(BfAstNode* allocNode);
  178. BfLambdaBindExpression* CreateLambdaBindExpression(BfAstNode* allocNode, BfTokenNode* parenToken = NULL);
  179. BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block);
  180. BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfTokenNode* openToken);
  181. BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode);
  182. BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
  183. BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
  184. BfInitializerExpression* TryCreateInitializerExpression(BfAstNode* target);
  185. BfExpression* CreateIndexerExpression(BfExpression* target);
  186. BfMemberReferenceExpression* CreateMemberReferenceExpression(BfAstNode* target);
  187. BfTupleExpression* CreateTupleExpression(BfTokenNode* newNode, BfExpression* innerExpr = NULL);
  188. BfExpression* CreateExpression(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);
  189. BfExpression* CreateExpressionAfter(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);
  190. BfSwitchStatement* CreateSwitchStatement(BfTokenNode* tokenNode);
  191. BfAstNode* DoCreateStatement(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
  192. bool IsTerminatingExpression(BfAstNode * node);
  193. BfAstNode* CreateStatement(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
  194. BfAstNode* CreateStatementAfter(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
  195. bool IsExtendedTypeName(BfIdentifierNode* identifierNode);
  196. bool IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode, int* retryNode, int* outEndNode, bool* couldBeExpr, bool* isGenericType, bool* isTuple);
  197. bool IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode = -1, int* outEndNode = NULL, bool* couldBeExpr = NULL, bool* isGenericType = NULL, bool* isTuple = NULL);
  198. bool IsLocalMethod(BfAstNode* nameNode);
  199. int QualifiedBacktrack(BfAstNode* endNode, int checkIdx, bool* outHadChevrons = NULL); // Backtracks to dot token
  200. BfTypeReference* DoCreateNamedTypeRef(BfIdentifierNode* identifierNode);
  201. BfTypeReference* DoCreateTypeRef(BfAstNode* identifierNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None, int endNode = -1);
  202. BfTypeReference* CreateTypeRef(BfAstNode* identifierNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None);
  203. BfTypeReference* CreateTypeRefAfter(BfAstNode* astNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None);
  204. BfTypeReference* CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refToken);
  205. bool ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, bool alwaysIncludeBlock = false);
  206. BfGenericArgumentsNode* CreateGenericArguments(BfTokenNode* tokenNode, bool allowPartial = false);
  207. BfGenericParamsDeclaration* CreateGenericParamsDeclaration(BfTokenNode* tokenNode);
  208. BfGenericConstraintsDeclaration* CreateGenericConstraintsDeclaration(BfTokenNode* tokenNode);
  209. BfForEachStatement* CreateForEachStatement(BfAstNode* node, bool hasTypeDecl);
  210. BfStatement* CreateForStatement(BfAstNode* node);
  211. BfUsingStatement* CreateUsingStatement(BfAstNode* node);
  212. BfWhileStatement* CreateWhileStatement(BfAstNode* node);
  213. BfDoStatement* CreateDoStatement(BfAstNode* node);
  214. BfRepeatStatement* CreateRepeatStatement(BfAstNode* node);
  215. BfAstNode* CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL);
  216. BfAstNode* HandleTopLevel(BfBlock* node);
  217. BfInlineAsmStatement* CreateInlineAsmStatement(BfAstNode* asmNode);
  218. void HandleBlock(BfBlock* block, bool allowEndingExpression = false);
  219. void HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL);
  220. public:
  221. BfReducer();
  222. void HandleRoot(BfRootNode* rootNode);
  223. };
  224. NS_BF_END