BfReducer.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  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. CreateExprFlags_AllowAnonymousIndexer = 0x1000
  28. };
  29. enum CreateStmtFlags
  30. {
  31. CreateStmtFlags_None,
  32. CreateStmtFlags_NoCaseExpr = 1,
  33. CreateStmtFlags_FindTrailingSemicolon = 2,
  34. CreateStmtFlags_AllowUnterminatedExpression = 4,
  35. CreateStmtFlags_AllowLocalFunction = 8,
  36. CreateStmtFlags_ForceVariableDecl = 0x10,
  37. CreateStmtFlags_CheckStack = 0x20,
  38. CreateStmtFlags_To_CreateExprFlags_Mask = 1
  39. };
  40. enum CreateTypeRefFlags
  41. {
  42. CreateTypeRefFlags_None,
  43. CreateTypeRefFlags_NoParseArrayBrackets = 1,
  44. CreateTypeRefFlags_SafeGenericParse = 2,
  45. CreateTypeRefFlags_AllowSingleMemberTuple = 4,
  46. CreateTypeRefFlags_EarlyExit = 8
  47. };
  48. struct BfVisitorPos
  49. {
  50. BfBlock* mParent;
  51. int mReadPos;
  52. int mWritePos;
  53. int mTotalSize;
  54. BfVisitorPos(BfBlock* parent = NULL)
  55. {
  56. mParent = parent;
  57. mReadPos = -1;
  58. mWritePos = 0;
  59. if (parent != NULL)
  60. mTotalSize = parent->GetSize();
  61. else
  62. mTotalSize = 0;
  63. }
  64. bool MoveNext()
  65. {
  66. mReadPos++;
  67. return mReadPos < mTotalSize;
  68. }
  69. BfAstNode* GetCurrent()
  70. {
  71. if ((uint)mReadPos >= (uint)mTotalSize)
  72. return NULL;
  73. return (*mParent)[mReadPos];
  74. }
  75. BfAstNode* Get(int idx)
  76. {
  77. if (((uint)idx >= (uint)mTotalSize))
  78. return NULL;
  79. return (*mParent)[idx];
  80. }
  81. void Set(int idx, BfAstNode* node)
  82. {
  83. if (((uint)idx >= (uint)mTotalSize))
  84. return;
  85. (*mParent)[idx] = node;
  86. }
  87. void ReplaceCurrent(BfAstNode* node)
  88. {
  89. if ((uint)mReadPos >= (uint)mTotalSize)
  90. return;
  91. (*mParent)[mReadPos] = node;
  92. }
  93. void Write(BfAstNode* node)
  94. {
  95. (*mParent)[mWritePos++] = node;
  96. BF_ASSERT(mWritePos <= mReadPos);
  97. }
  98. BfAstNode* GetNext()
  99. {
  100. if ((uint)(mReadPos + 1) >= (uint)(mTotalSize))
  101. return NULL;
  102. return (*mParent)[mReadPos + 1];
  103. }
  104. int GetReadNodesLeft()
  105. {
  106. return std::max(0, mTotalSize - mReadPos);
  107. }
  108. void Trim()
  109. {
  110. mParent->SetSize(mWritePos);
  111. }
  112. };
  113. struct CurTypeState
  114. {
  115. public:
  116. BfTypeDeclaration* mTypeDeclaration;
  117. BfAstAllocator* mAlloc;
  118. Array<BfTypeDeclaration*> mAnonymousTypeDecls;
  119. public:
  120. CurTypeState()
  121. {
  122. mTypeDeclaration = NULL;
  123. mAlloc = NULL;
  124. }
  125. CurTypeState(BfTypeDeclaration* typeDecl, BfAstAllocator* alloc)
  126. {
  127. mTypeDeclaration = typeDecl;
  128. mAlloc = alloc;
  129. }
  130. ~CurTypeState()
  131. {
  132. if ((mTypeDeclaration != NULL) && (mAnonymousTypeDecls.mSize > 0))
  133. {
  134. BF_ASSERT(mTypeDeclaration->mAnonymousTypes.mSize == 0);
  135. mTypeDeclaration->mAnonymousTypes.mSize = (int)mAnonymousTypeDecls.size();
  136. mTypeDeclaration->mAnonymousTypes.mVals = (BfTypeDeclaration**)mAlloc->AllocBytes(mAnonymousTypeDecls.mSize * sizeof(BfTypeDeclaration*), sizeof(BfTypeDeclaration*));
  137. for (int i = 0; i < mAnonymousTypeDecls.mSize; i++)
  138. mTypeDeclaration->mAnonymousTypes.mVals[i] = mAnonymousTypeDecls[i];
  139. }
  140. }
  141. };
  142. public:
  143. BfAstAllocator* mAlloc;
  144. BfSystem* mSystem;
  145. BfSource* mSource;
  146. BfPassInstance* mPassInstance;
  147. BfResolvePassData* mResolvePassData;
  148. BfAstNode* mTypeMemberNodeStart;
  149. int mClassDepth;
  150. int mMethodDepth;
  151. int mLastErrorSrcEnd;
  152. BfTypeDeclaration* mCurTypeDecl;
  153. CurTypeState* mCurTypeState;
  154. BfTypeDeclaration* mLastTypeDecl;
  155. BfMethodDeclaration* mCurMethodDecl;
  156. BfAstNode* mLastBlockNode;
  157. bool mStmtHasError;
  158. bool mPrevStmtHadError;
  159. bool mCompatMode; // Does C++ compatible parsing
  160. bool mAllowTypeWildcard;
  161. bool mIsFieldInitializer;
  162. bool mInParenExpr;
  163. bool mSkipCurrentNodeAssert;
  164. BfVisitorPos mVisitorPos;
  165. int mDocumentCheckIdx;
  166. SizedArray<BfNamespaceDeclaration*, 4> mCurNamespaceStack;
  167. SizedArray<BfExteriorNode, 4> mExteriorNodes;
  168. int mAssertCurrentNodeIdx;
  169. public:
  170. BfAstNode* Fail(const StringImpl& errorMsg, BfAstNode* refNode);
  171. BfAstNode* FailAfter(const StringImpl& errorMsg, BfAstNode* refNode);
  172. void AddErrorNode(BfAstNode* astNode, bool removeNode = true);
  173. public:
  174. bool StringEquals(BfAstNode* node, BfAstNode* node2);
  175. bool IsSemicolon(BfAstNode* node);
  176. BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken token);
  177. BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB);
  178. BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC);
  179. BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC, BfToken tokenD);
  180. BfIdentifierNode* ExpectIdentifierAfter(BfAstNode* node, const char* typeName = NULL);
  181. BfBlock* ExpectBlockAfter(BfAstNode* node);
  182. BfTokenNode* BreakDoubleChevron(BfTokenNode* tokenNode);
  183. BfTokenNode* BreakQuestionLBracket(BfTokenNode* tokenNode);
  184. BfCommentNode* FindDocumentation(BfAstNode* defNodeHead, BfAstNode* defNodeEnd = NULL, bool checkDocAfter = false);
  185. bool AssertCurrentNode(BfAstNode* node);
  186. bool IsNodeRelevant(BfAstNode* astNode);
  187. bool IsCursorInside(BfAstNode* astNode);
  188. bool IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode);
  189. void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner);
  190. void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode);
  191. void InitAnonymousType(BfTypeDeclaration* typeDecl);
  192. bool CheckInlineTypeRefAttribute(BfAstNode* typeRef, BfAttributeDirective* attributes);
  193. void CheckMultiuseAttributeTypeRef(BfAstNode* typeRef);
  194. bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
  195. BfAstNode* CreateAllocNode(BfTokenNode* newNode);
  196. BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1, bool allowIn = false);
  197. BfEnumCaseBindExpression* CreateEnumCaseBindExpression(BfTokenNode* bindToken);
  198. BfExpression* CheckBinaryOperatorPrecedence(BfBinaryOperatorExpression* binOpExpression);
  199. BfExpression* ApplyToFirstExpression(BfUnaryOperatorExpression* unaryOp, BfExpression* target);
  200. BfIdentifierNode* ExtractExplicitInterfaceRef(BfAstNode* memberDeclaration, BfIdentifierNode* nameIdentifier, BfTypeReference** outExplicitInterface, BfTokenNode** outExplicitInterfaceDotToken);
  201. BfTokenNode* ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, BfToken endToken, bool requireNames);
  202. BfTokenNode* ReadArguments(BfAstNode* parentNode, BfAstNode* afterNode, SizedArrayImpl<BfExpression*>* arguments, SizedArrayImpl<BfTokenNode*>* commas, BfToken endToken, bool allowSkippedArgs = false, CreateExprFlags createExprFlags = CreateExprFlags_None);
  203. void ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, BfBlock* block);
  204. BfAstNode* ReadTypeMember(BfTokenNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
  205. BfAstNode* ReadTypeMember(BfAstNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
  206. BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode, bool allowGlobalLookup = true);
  207. void TryIdentifierConvert(int readPos);
  208. void CreateQualifiedNames(BfAstNode* node);
  209. BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
  210. BfFieldDeclaration* CreateFieldDeclaration(BfTokenNode* tokenNode, BfTypeReference* typeRef, BfIdentifierNode* nameIdentifier, BfFieldDeclaration* prevFieldDeclaration);
  211. BfAttributeDirective* CreateAttributeDirective(BfTokenNode* startToken);
  212. BfStatement* CreateAttributedStatement(BfTokenNode* tokenNode, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
  213. BfExpression* CreateAttributedExpression(BfTokenNode* tokenNode, bool onlyAllowIdentifier);
  214. BfDelegateBindExpression* CreateDelegateBindExpression(BfAstNode* allocNode);
  215. BfLambdaBindExpression* CreateLambdaBindExpression(BfAstNode* allocNode, BfTokenNode* parenToken = NULL);
  216. BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block);
  217. BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfTokenNode* openToken);
  218. BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode, BfAstNode* targetNode = NULL);
  219. BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
  220. BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
  221. BfInitializerExpression* TryCreateInitializerExpression(BfAstNode* target);
  222. BfExpression* CreateIndexerExpression(BfExpression* target, BfTokenNode* openBracketNode = NULL);
  223. BfMemberReferenceExpression* CreateMemberReferenceExpression(BfAstNode* target);
  224. BfTupleExpression* CreateTupleExpression(BfTokenNode* newNode, BfExpression* innerExpr = NULL);
  225. BfExpression* CreateExpression(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);
  226. BfExpression* CreateExpressionAfter(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);
  227. BfSwitchStatement* CreateSwitchStatement(BfTokenNode* tokenNode);
  228. BfAstNode* DoCreateStatement(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
  229. bool IsTerminatingExpression(BfAstNode * node);
  230. BfAstNode* CreateStatement(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
  231. BfAstNode* CreateStatementAfter(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
  232. bool IsExtendedTypeName(BfIdentifierNode* identifierNode);
  233. bool IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode, int* retryNode, int* outEndNode, bool* couldBeExpr, bool* isGenericType, bool* isTuple);
  234. bool IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode = -1, int* outEndNode = NULL, bool* couldBeExpr = NULL, bool* isGenericType = NULL, bool* isTuple = NULL);
  235. bool IsLocalMethod(BfAstNode* nameNode);
  236. int QualifiedBacktrack(BfAstNode* endNode, int checkIdx, bool* outHadChevrons = NULL); // Backtracks to dot token
  237. BfTypeReference* DoCreateNamedTypeRef(BfIdentifierNode* identifierNode);
  238. BfTypeReference* DoCreateTypeRef(BfAstNode* identifierNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None, int endNode = -1);
  239. BfTypeReference* CreateTypeRef(BfAstNode* identifierNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None);
  240. BfTypeReference* CreateTypeRefAfter(BfAstNode* astNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None);
  241. BfTypeReference* CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refToken);
  242. bool ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, bool alwaysIncludeBlock = false);
  243. BfGenericArgumentsNode* CreateGenericArguments(BfTokenNode* tokenNode, bool allowPartial = false);
  244. BfGenericParamsDeclaration* CreateGenericParamsDeclaration(BfTokenNode* tokenNode);
  245. BfGenericConstraintsDeclaration* CreateGenericConstraintsDeclaration(BfTokenNode* tokenNode);
  246. BfForEachStatement* CreateForEachStatement(BfAstNode* node, bool hasTypeDecl);
  247. BfStatement* CreateForStatement(BfAstNode* node);
  248. BfUsingStatement* CreateUsingStatement(BfAstNode* node);
  249. BfWhileStatement* CreateWhileStatement(BfAstNode* node);
  250. BfDoStatement* CreateDoStatement(BfAstNode* node);
  251. BfRepeatStatement* CreateRepeatStatement(BfAstNode* node);
  252. BfAstNode* CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL, bool isAnonymous = false);
  253. BfAstNode* HandleTopLevel(BfBlock* node);
  254. BfInlineAsmStatement* CreateInlineAsmStatement(BfAstNode* asmNode);
  255. void HandleBlock(BfBlock* block, bool allowEndingExpression = false);
  256. bool IsInitializerStatement(int checkIdx);
  257. bool IsInitializerStatement(BfAstNode* node);
  258. bool InitializerBlockHasInlineTypeDecl(BfBlock* block);
  259. void HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL, bool findInitializer = false);
  260. public:
  261. BfReducer();
  262. void HandleRoot(BfRootNode* rootNode);
  263. };
  264. NS_BF_END