2019-08-23 11:56:54 -07:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "BeefySysLib/Common.h"
|
|
|
|
#include "BfAst.h"
|
|
|
|
#include "BfType.h"
|
|
|
|
#include "BeefySysLib/util/BumpAllocator.h"
|
|
|
|
|
|
|
|
NS_BF_BEGIN
|
|
|
|
|
|
|
|
class BfPassInstance;
|
|
|
|
class BfResolvePassData;
|
|
|
|
|
|
|
|
class BfReducer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum CreateExprFlags
|
|
|
|
{
|
|
|
|
CreateExprFlags_None,
|
|
|
|
CreateExprFlags_NoCaseExpr = 1,
|
|
|
|
CreateExprFlags_NoAssignment = 2,
|
|
|
|
CreateExprFlags_AllowVariableDecl = 4,
|
|
|
|
CreateExprFlags_PermissiveVariableDecl = 8,
|
|
|
|
CreateExprFlags_NoCast = 0x10,
|
|
|
|
CreateExprFlags_BreakOnRChevron = 0x20,
|
|
|
|
CreateExprFlags_ExitOnBang = 0x40,
|
|
|
|
CreateExprFlags_ExitOnParenExpr = 0x80,
|
|
|
|
CreateExprFlags_NoCheckBinOpPrecedence = 0x100,
|
2020-07-02 23:34:17 -07:00
|
|
|
CreateExprFlags_BreakOnCascade = 0x200,
|
2021-10-24 08:12:18 -07:00
|
|
|
CreateExprFlags_EarlyExit = 0x400, // Don't attempt binary or ternary operations
|
2023-03-17 11:13:41 -07:00
|
|
|
CreateExprFlags_AllowEmpty = 0x800,
|
|
|
|
CreateExprFlags_AllowAnonymousIndexer = 0x1000
|
2019-08-23 11:56:54 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
enum CreateStmtFlags
|
|
|
|
{
|
|
|
|
CreateStmtFlags_None,
|
|
|
|
CreateStmtFlags_NoCaseExpr = 1,
|
|
|
|
CreateStmtFlags_FindTrailingSemicolon = 2,
|
|
|
|
CreateStmtFlags_AllowUnterminatedExpression = 4,
|
2022-07-26 13:27:03 -04:00
|
|
|
CreateStmtFlags_AllowLocalFunction = 8,
|
|
|
|
CreateStmtFlags_ForceVariableDecl = 0x10,
|
2024-03-18 05:44:02 -04:00
|
|
|
CreateStmtFlags_CheckStack = 0x20,
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
CreateStmtFlags_To_CreateExprFlags_Mask = 1
|
|
|
|
};
|
|
|
|
|
2019-11-21 08:23:18 -08:00
|
|
|
enum CreateTypeRefFlags
|
|
|
|
{
|
|
|
|
CreateTypeRefFlags_None,
|
|
|
|
CreateTypeRefFlags_NoParseArrayBrackets = 1,
|
2020-05-27 09:46:09 -07:00
|
|
|
CreateTypeRefFlags_SafeGenericParse = 2,
|
2020-09-19 10:02:51 -07:00
|
|
|
CreateTypeRefFlags_AllowSingleMemberTuple = 4,
|
|
|
|
CreateTypeRefFlags_EarlyExit = 8
|
2019-11-21 08:23:18 -08:00
|
|
|
};
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
struct BfVisitorPos
|
|
|
|
{
|
|
|
|
BfBlock* mParent;
|
|
|
|
int mReadPos;
|
|
|
|
int mWritePos;
|
|
|
|
int mTotalSize;
|
|
|
|
|
|
|
|
BfVisitorPos(BfBlock* parent = NULL)
|
|
|
|
{
|
|
|
|
mParent = parent;
|
|
|
|
mReadPos = -1;
|
|
|
|
mWritePos = 0;
|
|
|
|
if (parent != NULL)
|
|
|
|
mTotalSize = parent->GetSize();
|
|
|
|
else
|
|
|
|
mTotalSize = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MoveNext()
|
|
|
|
{
|
|
|
|
mReadPos++;
|
|
|
|
return mReadPos < mTotalSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
BfAstNode* GetCurrent()
|
|
|
|
{
|
|
|
|
if ((uint)mReadPos >= (uint)mTotalSize)
|
|
|
|
return NULL;
|
|
|
|
return (*mParent)[mReadPos];
|
|
|
|
}
|
|
|
|
|
|
|
|
BfAstNode* Get(int idx)
|
|
|
|
{
|
|
|
|
if (((uint)idx >= (uint)mTotalSize))
|
|
|
|
return NULL;
|
|
|
|
return (*mParent)[idx];
|
|
|
|
}
|
|
|
|
|
|
|
|
void Set(int idx, BfAstNode* node)
|
|
|
|
{
|
|
|
|
if (((uint)idx >= (uint)mTotalSize))
|
|
|
|
return;
|
|
|
|
(*mParent)[idx] = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ReplaceCurrent(BfAstNode* node)
|
|
|
|
{
|
|
|
|
if ((uint)mReadPos >= (uint)mTotalSize)
|
|
|
|
return;
|
|
|
|
(*mParent)[mReadPos] = node;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Write(BfAstNode* node)
|
|
|
|
{
|
|
|
|
(*mParent)[mWritePos++] = node;
|
|
|
|
BF_ASSERT(mWritePos <= mReadPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
BfAstNode* GetNext()
|
|
|
|
{
|
|
|
|
if ((uint)(mReadPos + 1) >= (uint)(mTotalSize))
|
|
|
|
return NULL;
|
|
|
|
return (*mParent)[mReadPos + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetReadNodesLeft()
|
|
|
|
{
|
|
|
|
return std::max(0, mTotalSize - mReadPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Trim()
|
|
|
|
{
|
|
|
|
mParent->SetSize(mWritePos);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-07-26 13:27:03 -04:00
|
|
|
public:
|
2019-08-23 11:56:54 -07:00
|
|
|
BfAstAllocator* mAlloc;
|
|
|
|
BfSystem* mSystem;
|
|
|
|
BfSource* mSource;
|
|
|
|
BfPassInstance* mPassInstance;
|
|
|
|
BfResolvePassData* mResolvePassData;
|
|
|
|
BfAstNode* mTypeMemberNodeStart;
|
|
|
|
int mClassDepth;
|
|
|
|
int mMethodDepth;
|
|
|
|
BfTypeDeclaration* mCurTypeDecl;
|
|
|
|
BfTypeDeclaration* mLastTypeDecl;
|
|
|
|
BfMethodDeclaration* mCurMethodDecl;
|
2020-01-31 16:10:06 -08:00
|
|
|
BfAstNode* mLastBlockNode;
|
2019-08-23 11:56:54 -07:00
|
|
|
bool mStmtHasError;
|
2022-07-26 13:27:03 -04:00
|
|
|
bool mPrevStmtHadError;
|
2019-08-23 11:56:54 -07:00
|
|
|
bool mCompatMode; // Does C++ compatible parsing
|
|
|
|
bool mAllowTypeWildcard;
|
|
|
|
bool mIsFieldInitializer;
|
|
|
|
bool mInParenExpr;
|
2022-07-26 13:27:03 -04:00
|
|
|
bool mSkipCurrentNodeAssert;
|
2019-08-23 11:56:54 -07:00
|
|
|
BfVisitorPos mVisitorPos;
|
|
|
|
int mDocumentCheckIdx;
|
2022-01-07 08:58:19 -05:00
|
|
|
SizedArray<BfNamespaceDeclaration*, 4> mCurNamespaceStack;
|
|
|
|
SizedArray<BfExteriorNode, 4> mExteriorNodes;
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
int mAssertCurrentNodeIdx;
|
|
|
|
|
2022-07-26 13:27:03 -04:00
|
|
|
public:
|
2019-08-23 11:56:54 -07:00
|
|
|
BfAstNode* Fail(const StringImpl& errorMsg, BfAstNode* refNode);
|
|
|
|
BfAstNode* FailAfter(const StringImpl& errorMsg, BfAstNode* refNode);
|
|
|
|
void AddErrorNode(BfAstNode* astNode, bool removeNode = true);
|
2022-07-26 13:27:03 -04:00
|
|
|
|
|
|
|
public:
|
2019-08-23 11:56:54 -07:00
|
|
|
bool StringEquals(BfAstNode* node, BfAstNode* node2);
|
|
|
|
bool IsSemicolon(BfAstNode* node);
|
2022-07-26 13:27:03 -04:00
|
|
|
BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken token);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB);
|
|
|
|
BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC);
|
|
|
|
BfTokenNode* ExpectTokenAfter(BfAstNode* node, BfToken tokenA, BfToken tokenB, BfToken tokenC, BfToken tokenD);
|
|
|
|
BfIdentifierNode* ExpectIdentifierAfter(BfAstNode* node, const char* typeName = NULL);
|
|
|
|
BfBlock* ExpectBlockAfter(BfAstNode* node);
|
|
|
|
BfTokenNode* BreakDoubleChevron(BfTokenNode* tokenNode);
|
|
|
|
BfTokenNode* BreakQuestionLBracket(BfTokenNode* tokenNode);
|
|
|
|
BfCommentNode* FindDocumentation(BfAstNode* defNodeHead, BfAstNode* defNodeEnd = NULL, bool checkDocAfter = false);
|
|
|
|
|
|
|
|
void AssertCurrentNode(BfAstNode* node);
|
|
|
|
bool IsNodeRelevant(BfAstNode* astNode);
|
|
|
|
bool IsNodeRelevant(BfAstNode* startNode, BfAstNode* endNode);
|
|
|
|
void MoveNode(BfAstNode* srcNode, BfAstNode* newOwner);
|
2022-07-26 13:27:03 -04:00
|
|
|
void ReplaceNode(BfAstNode* prevNode, BfAstNode* newNode);
|
|
|
|
|
2020-12-07 07:53:12 -08:00
|
|
|
bool SetProtection(BfAstNode* parentNode, BfAstNode*& protectionNodeRef, BfTokenNode* tokenNode);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfAstNode* CreateAllocNode(BfTokenNode* newNode);
|
2021-01-27 09:01:47 -08:00
|
|
|
BfAstNode* ReplaceTokenStarter(BfAstNode* astNode, int idx = -1, bool allowIn = false);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfEnumCaseBindExpression* CreateEnumCaseBindExpression(BfTokenNode* bindToken);
|
|
|
|
BfExpression* CheckBinaryOperatorPrecedence(BfBinaryOperatorExpression* binOpExpression);
|
|
|
|
BfExpression* ApplyToFirstExpression(BfUnaryOperatorExpression* unaryOp, BfExpression* target);
|
|
|
|
BfIdentifierNode* ExtractExplicitInterfaceRef(BfAstNode* memberDeclaration, BfIdentifierNode* nameIdentifier, BfTypeReference** outExplicitInterface, BfTokenNode** outExplicitInterfaceDotToken);
|
2020-03-31 07:46:01 -07:00
|
|
|
BfTokenNode* ParseMethodParams(BfAstNode* node, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, BfToken endToken, bool requireNames);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfTokenNode* ReadArguments(BfAstNode* parentNode, BfAstNode* afterNode, SizedArrayImpl<BfExpression*>* arguments, SizedArrayImpl<BfTokenNode*>* commas, BfToken endToken, bool allowSkippedArgs = false, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
|
|
|
void ReadPropertyBlock(BfPropertyDeclaration* propertyDeclaration, BfBlock* block);
|
2021-10-31 07:31:08 -07:00
|
|
|
BfAstNode* ReadTypeMember(BfTokenNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
|
|
|
|
BfAstNode* ReadTypeMember(BfAstNode* node, bool declStarted = false, int depth = 0, BfAstNode* deferredHeadNode = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfIdentifierNode* CompactQualifiedName(BfAstNode* leftNode);
|
2020-05-26 06:10:51 -07:00
|
|
|
void TryIdentifierConvert(int readPos);
|
2019-08-23 11:56:54 -07:00
|
|
|
void CreateQualifiedNames(BfAstNode* node);
|
|
|
|
BfFieldDtorDeclaration* CreateFieldDtorDeclaration(BfAstNode* srcNode);
|
|
|
|
BfFieldDeclaration* CreateFieldDeclaration(BfTokenNode* tokenNode, BfTypeReference* typeRef, BfIdentifierNode* nameIdentifier, BfFieldDeclaration* prevFieldDeclaration);
|
2022-07-26 13:27:03 -04:00
|
|
|
BfAttributeDirective* CreateAttributeDirective(BfTokenNode* startToken);
|
2022-05-27 11:28:53 -07:00
|
|
|
BfStatement* CreateAttributedStatement(BfTokenNode* tokenNode, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfExpression* CreateAttributedExpression(BfTokenNode* tokenNode, bool onlyAllowIdentifier);
|
|
|
|
BfDelegateBindExpression* CreateDelegateBindExpression(BfAstNode* allocNode);
|
|
|
|
BfLambdaBindExpression* CreateLambdaBindExpression(BfAstNode* allocNode, BfTokenNode* parenToken = NULL);
|
2022-07-26 13:27:03 -04:00
|
|
|
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfBlock* block);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfCollectionInitializerExpression* CreateCollectionInitializerExpression(BfTokenNode* openToken);
|
|
|
|
BfObjectCreateExpression* CreateObjectCreateExpression(BfAstNode* allocNode);
|
|
|
|
BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
|
|
|
|
BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
2021-01-02 06:14:29 -08:00
|
|
|
BfInitializerExpression* TryCreateInitializerExpression(BfAstNode* target);
|
2023-03-17 11:13:41 -07:00
|
|
|
BfExpression* CreateIndexerExpression(BfExpression* target, BfTokenNode* openBracketNode = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfMemberReferenceExpression* CreateMemberReferenceExpression(BfAstNode* target);
|
|
|
|
BfTupleExpression* CreateTupleExpression(BfTokenNode* newNode, BfExpression* innerExpr = NULL);
|
|
|
|
BfExpression* CreateExpression(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
|
|
|
BfExpression* CreateExpressionAfter(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);
|
|
|
|
BfSwitchStatement* CreateSwitchStatement(BfTokenNode* tokenNode);
|
|
|
|
BfAstNode* DoCreateStatement(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
|
|
|
|
bool IsTerminatingExpression(BfAstNode * node);
|
|
|
|
BfAstNode* CreateStatement(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
|
|
|
|
BfAstNode* CreateStatementAfter(BfAstNode* node, CreateStmtFlags createStmtFlags = CreateStmtFlags_None);
|
|
|
|
bool IsExtendedTypeName(BfIdentifierNode* identifierNode);
|
2022-02-06 08:21:53 -05:00
|
|
|
bool IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode, int* retryNode, int* outEndNode, bool* couldBeExpr, bool* isGenericType, bool* isTuple);
|
|
|
|
bool IsTypeReference(BfAstNode* checkNode, BfToken successToken, int endNode = -1, int* outEndNode = NULL, bool* couldBeExpr = NULL, bool* isGenericType = NULL, bool* isTuple = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
bool IsLocalMethod(BfAstNode* nameNode);
|
|
|
|
int QualifiedBacktrack(BfAstNode* endNode, int checkIdx, bool* outHadChevrons = NULL); // Backtracks to dot token
|
|
|
|
BfTypeReference* DoCreateNamedTypeRef(BfIdentifierNode* identifierNode);
|
2022-02-06 08:21:53 -05:00
|
|
|
BfTypeReference* DoCreateTypeRef(BfAstNode* identifierNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None, int endNode = -1);
|
2019-11-21 08:23:18 -08:00
|
|
|
BfTypeReference* CreateTypeRef(BfAstNode* identifierNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None);
|
|
|
|
BfTypeReference* CreateTypeRefAfter(BfAstNode* astNode, CreateTypeRefFlags createTypeRefFlags = CreateTypeRefFlags_None);
|
2022-07-26 13:27:03 -04:00
|
|
|
BfTypeReference* CreateRefTypeRef(BfTypeReference* elementType, BfTokenNode* refToken);
|
2019-08-23 11:56:54 -07:00
|
|
|
bool ParseMethod(BfMethodDeclaration* methodDeclaration, SizedArrayImpl<BfParameterDeclaration*>* params, SizedArrayImpl<BfTokenNode*>* commas, bool alwaysIncludeBlock = false);
|
2022-02-05 13:47:19 -05:00
|
|
|
BfGenericArgumentsNode* CreateGenericArguments(BfTokenNode* tokenNode, bool allowPartial = false);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfGenericParamsDeclaration* CreateGenericParamsDeclaration(BfTokenNode* tokenNode);
|
|
|
|
BfGenericConstraintsDeclaration* CreateGenericConstraintsDeclaration(BfTokenNode* tokenNode);
|
|
|
|
BfForEachStatement* CreateForEachStatement(BfAstNode* node, bool hasTypeDecl);
|
|
|
|
BfStatement* CreateForStatement(BfAstNode* node);
|
|
|
|
BfUsingStatement* CreateUsingStatement(BfAstNode* node);
|
|
|
|
BfWhileStatement* CreateWhileStatement(BfAstNode* node);
|
|
|
|
BfDoStatement* CreateDoStatement(BfAstNode* node);
|
|
|
|
BfRepeatStatement* CreateRepeatStatement(BfAstNode* node);
|
2020-09-14 11:54:54 -07:00
|
|
|
BfAstNode* CreateTopLevelObject(BfTokenNode* tokenNode, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
BfAstNode* HandleTopLevel(BfBlock* node);
|
|
|
|
BfInlineAsmStatement* CreateInlineAsmStatement(BfAstNode* asmNode);
|
|
|
|
|
|
|
|
void HandleBlock(BfBlock* block, bool allowEndingExpression = false);
|
2020-09-14 11:54:54 -07:00
|
|
|
void HandleTypeDeclaration(BfTypeDeclaration* typeDecl, BfAttributeDirective* attributes, BfAstNode* deferredHeadNode = NULL);
|
2019-08-23 11:56:54 -07:00
|
|
|
|
|
|
|
public:
|
|
|
|
BfReducer();
|
|
|
|
void HandleRoot(BfRootNode* rootNode);
|
|
|
|
};
|
|
|
|
|
|
|
|
NS_BF_END
|