mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
2187 lines
No EOL
47 KiB
C++
2187 lines
No EOL
47 KiB
C++
#define BF_AST_DO_IMPL
|
|
|
|
#include "BfAst.h"
|
|
#include "BfParser.h"
|
|
#include "BfSystem.h"
|
|
|
|
USING_NS_BF;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
BfStructuralVisitor::BfStructuralVisitor()
|
|
{
|
|
std::hash<std::string>();
|
|
|
|
mCapturingChildRef = false;
|
|
mCurChildRef = NULL;
|
|
}
|
|
|
|
void BfStructuralVisitor::VisitMembers(BfBlock* node)
|
|
{
|
|
for (auto& child : *node)
|
|
{
|
|
child->Accept(this);
|
|
}
|
|
}
|
|
|
|
void BfStructuralVisitor::VisitChildNoRef(BfAstNode* node)
|
|
{
|
|
mCurChildRef = NULL;
|
|
node->Accept(this);
|
|
mCurChildRef = NULL;
|
|
}
|
|
|
|
void BfStructuralVisitor::DoVisitChild(BfAstNode*& node)
|
|
{
|
|
if (node == NULL)
|
|
return;
|
|
mCurChildRef = &node;
|
|
node->Accept(this);
|
|
mCurChildRef = NULL;
|
|
}
|
|
|
|
void BfStructuralVisitor::AssertValidChildAddr(BfAstNode** nodeRef)
|
|
{
|
|
//auto bfSource = (*nodeRef)->mSource;
|
|
//BF_ASSERT(bfSource->mAlloc.ContainsPtr(nodeRef));
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfLabeledBlock* labeledBlock)
|
|
{
|
|
Visit(labeledBlock->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfErrorNode* bfErrorNode)
|
|
{
|
|
Visit(bfErrorNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfScopeNode* scopeNode)
|
|
{
|
|
Visit(scopeNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfNewNode* newNode)
|
|
{
|
|
Visit(newNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTypedValueExpression* typedValueExpr)
|
|
{
|
|
Visit(typedValueExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfCommentNode* commentNode)
|
|
{
|
|
Visit(commentNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfPreprocesorIgnoredSectionNode* preprocesorIgnoredSection)
|
|
{
|
|
Visit(preprocesorIgnoredSection->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfPreprocessorNode* preprocessorNode)
|
|
{
|
|
Visit(preprocessorNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfPreprocessorDefinedExpression* definedExpr)
|
|
{
|
|
Visit(definedExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfAttributeDirective* attributeDirective)
|
|
{
|
|
Visit(attributeDirective->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfGenericParamsDeclaration* genericParams)
|
|
{
|
|
Visit(genericParams->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfGenericOperatorConstraint* genericConstraints)
|
|
{
|
|
Visit(genericConstraints->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfGenericConstraintsDeclaration* genericConstraints)
|
|
{
|
|
Visit(genericConstraints->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfGenericArgumentsNode* genericArgumentsNode)
|
|
{
|
|
Visit(genericArgumentsNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfCtorExplicitNode* ctorExplicitNode)
|
|
{
|
|
Visit(ctorExplicitNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfStatement* stmt)
|
|
{
|
|
Visit(stmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfAttributedStatement* attribStmt)
|
|
{
|
|
Visit(attribStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfLabelableStatement* labelableStmt)
|
|
{
|
|
Visit(labelableStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfExpression* expr)
|
|
{
|
|
Visit(expr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfExpressionStatement* exprStmt)
|
|
{
|
|
Visit(exprStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfNamedExpression* namedExpr)
|
|
{
|
|
Visit(namedExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfAttributedExpression* attribExpr)
|
|
{
|
|
Visit(attribExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfEmptyStatement* emptyStmt)
|
|
{
|
|
Visit(emptyStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTokenNode* tokenNode)
|
|
{
|
|
Visit(tokenNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTokenPairNode* tokenPairNode)
|
|
{
|
|
Visit(tokenPairNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfUsingSpecifierNode* usingSpecifier)
|
|
{
|
|
Visit(usingSpecifier->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfLiteralExpression* literalExpr)
|
|
{
|
|
Visit(literalExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfStringInterpolationExpression* stringInterpolationExpression)
|
|
{
|
|
Visit(stringInterpolationExpression->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfIdentifierNode* identifierNode)
|
|
{
|
|
Visit(identifierNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfAttributedIdentifierNode* attrIdentifierNode)
|
|
{
|
|
Visit(attrIdentifierNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfQualifiedNameNode* nameNode)
|
|
{
|
|
Visit(nameNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfThisExpression* thisExpr)
|
|
{
|
|
Visit(thisExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfBaseExpression* baseExpr)
|
|
{
|
|
Visit(baseExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfMixinExpression* mixinExpr)
|
|
{
|
|
Visit(mixinExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfSizedArrayCreateExpression* createExpr)
|
|
{
|
|
Visit(createExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfInitializerExpression* initExpr)
|
|
{
|
|
Visit(initExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfCollectionInitializerExpression* collectionInitExpr)
|
|
{
|
|
Visit(collectionInitExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTypeReference* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfInlineTypeReference* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfNamedTypeReference* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfQualifiedTypeReference* qualifiedTypeRef)
|
|
{
|
|
Visit(qualifiedTypeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDotTypeReference* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfVarTypeReference* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfVarRefTypeReference* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfLetTypeReference* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfConstTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfConstExprTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfRefTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfModifiedTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfArrayTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfGenericInstanceTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTupleTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTagTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDelegateTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfExprModTypeRef* declTypeRef)
|
|
{
|
|
Visit(declTypeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfPointerTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfNullableTypeRef* typeRef)
|
|
{
|
|
Visit(typeRef->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfVariableDeclaration* varDecl)
|
|
{
|
|
Visit(varDecl->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfLocalMethodDeclaration* methodDecl)
|
|
{
|
|
Visit(methodDecl->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfParameterDeclaration* paramDecl)
|
|
{
|
|
Visit(paramDecl->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTypeAttrExpression* typeAttrExpr)
|
|
{
|
|
Visit(typeAttrExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTypeOfExpression* typeOfExpr)
|
|
{
|
|
Visit(typeOfExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfSizeOfExpression* sizeOfExpr)
|
|
{
|
|
Visit(sizeOfExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfAlignOfExpression* alignOfExpr)
|
|
{
|
|
Visit(alignOfExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfStrideOfExpression* strideOfExpr)
|
|
{
|
|
Visit(strideOfExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
|
|
{
|
|
Visit(offsetOfExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfNameOfExpression* nameOfExpr)
|
|
{
|
|
Visit(nameOfExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfIsConstExpression* isConstExpr)
|
|
{
|
|
Visit(isConstExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDefaultExpression* defaultExpr)
|
|
{
|
|
Visit(defaultExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfUninitializedExpression* uninitializedExpr)
|
|
{
|
|
Visit(uninitializedExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfCheckTypeExpression* checkTypeExpr)
|
|
{
|
|
Visit(checkTypeExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDynamicCastExpression* dynCastExpr)
|
|
{
|
|
Visit(dynCastExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfCastExpression* castExpr)
|
|
{
|
|
Visit(castExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDelegateBindExpression* bindExpr)
|
|
{
|
|
Visit(bindExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfLambdaBindExpression* lambdaBindExpr)
|
|
{
|
|
Visit(lambdaBindExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfObjectCreateExpression* newExpr)
|
|
{
|
|
Visit(newExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfBoxExpression* boxExpr)
|
|
{
|
|
Visit(boxExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfThrowStatement* throwStmt)
|
|
{
|
|
Visit(throwStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDeleteStatement* deleteStmt)
|
|
{
|
|
Visit(deleteStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfScopedInvocationTarget* scopedTarget)
|
|
{
|
|
Visit(scopedTarget->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfInvocationExpression* invocationExpr)
|
|
{
|
|
Visit(invocationExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfEnumCaseBindExpression* caseBindExpr)
|
|
{
|
|
Visit(caseBindExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfCaseExpression* caseExpr)
|
|
{
|
|
Visit(caseExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfSwitchCase* switchCase)
|
|
{
|
|
Visit(switchCase->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfWhenExpression* whenExpr)
|
|
{
|
|
Visit(whenExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfSwitchStatement* switchStmt)
|
|
{
|
|
Visit(switchStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTryStatement* tryStmt)
|
|
{
|
|
Visit(tryStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfCatchStatement* catchStmt)
|
|
{
|
|
Visit(catchStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfFinallyStatement* finallyStmt)
|
|
{
|
|
Visit(finallyStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfCheckedStatement* checkedStmt)
|
|
{
|
|
Visit(checkedStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfUncheckedStatement* uncheckedStmt)
|
|
{
|
|
Visit(uncheckedStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfIfStatement* ifStmt)
|
|
{
|
|
Visit(ifStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDeferStatement* deferStmt)
|
|
{
|
|
Visit(deferStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfReturnStatement* returnStmt)
|
|
{
|
|
Visit(returnStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfYieldStatement* yieldStmt)
|
|
{
|
|
Visit(yieldStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfUsingStatement* whileStmt)
|
|
{
|
|
Visit(whileStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDoStatement* doStmt)
|
|
{
|
|
Visit(doStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfRepeatStatement* repeatStmt)
|
|
{
|
|
Visit(repeatStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfWhileStatement* whileStmt)
|
|
{
|
|
Visit(whileStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfBreakStatement* breakStmt)
|
|
{
|
|
Visit(breakStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfContinueStatement* continueStmt)
|
|
{
|
|
Visit(continueStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfFallthroughStatement* fallthroughStmt)
|
|
{
|
|
Visit(fallthroughStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfForStatement* forStmt)
|
|
{
|
|
Visit(forStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfForEachStatement* forEachStmt)
|
|
{
|
|
Visit(forEachStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfConditionalExpression* condExpr)
|
|
{
|
|
Visit(condExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfAssignmentExpression* assignExpr)
|
|
{
|
|
Visit(assignExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfParenthesizedExpression* parenExpr)
|
|
{
|
|
Visit(parenExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTupleExpression* tupleExpr)
|
|
{
|
|
Visit(tupleExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfMemberReferenceExpression* memberRefExpr)
|
|
{
|
|
Visit(memberRefExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfIndexerExpression* indexerExpr)
|
|
{
|
|
Visit(indexerExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfUnaryOperatorExpression* binOpExpr)
|
|
{
|
|
Visit(binOpExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfBinaryOperatorExpression* binOpExpr)
|
|
{
|
|
Visit(binOpExpr->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfConstructorDeclaration* ctorDeclaration)
|
|
{
|
|
Visit(ctorDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfAutoConstructorDeclaration* ctorDeclaration)
|
|
{
|
|
Visit(ctorDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfDestructorDeclaration* dtorDeclaration)
|
|
{
|
|
Visit(dtorDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfMethodDeclaration* methodDeclaration)
|
|
{
|
|
Visit(methodDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfOperatorDeclaration* operatorDeclaration)
|
|
{
|
|
Visit(operatorDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfPropertyMethodDeclaration* propertyMethodDeclaration)
|
|
{
|
|
Visit(propertyMethodDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfPropertyBodyExpression* propertyBodyExpression)
|
|
{
|
|
Visit(propertyBodyExpression->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfPropertyDeclaration* propertyDeclaration)
|
|
{
|
|
Visit(propertyDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfIndexerDeclaration* indexerDeclaration)
|
|
{
|
|
Visit(indexerDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfFieldDeclaration* fieldDeclaration)
|
|
{
|
|
Visit(fieldDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfEnumCaseDeclaration* enumCaseDeclaration)
|
|
{
|
|
Visit(enumCaseDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfFieldDtorDeclaration* fieldDtorDeclaration)
|
|
{
|
|
Visit(fieldDtorDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTypeDeclaration* typeDeclaration)
|
|
{
|
|
Visit(typeDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfTypeAliasDeclaration* typeDeclaration)
|
|
{
|
|
Visit(typeDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfUsingDirective* usingDirective)
|
|
{
|
|
Visit(usingDirective->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfUsingModDirective * usingDirective)
|
|
{
|
|
Visit(usingDirective->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfNamespaceDeclaration* namespaceDeclaration)
|
|
{
|
|
Visit(namespaceDeclaration->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfBlock* block)
|
|
{
|
|
Visit(block->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfUnscopedBlock* block)
|
|
{
|
|
Visit(block->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfBlockExtension* block)
|
|
{
|
|
BF_ASSERT("Shouldn't see this block, BfBlock::Iterator not being used?");
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfRootNode* rootNode)
|
|
{
|
|
Visit(rootNode->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfInlineAsmStatement* asmStmt)
|
|
{
|
|
Visit(asmStmt->ToBase());
|
|
}
|
|
|
|
void BfStructuralVisitor::Visit(BfInlineAsmInstruction* asmInst)
|
|
{
|
|
Visit(asmInst->ToBase());
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
static Array<BfAstTypeInfo*> gTypes;
|
|
static Array<BfAstAcceptFunc> gAcceptFuncs;
|
|
static int sTypeCount;
|
|
|
|
BfAstTypeInfo::BfAstTypeInfo(const char* name, BfAstTypeInfo* baseType, BfAstAcceptFunc acceptFunc)
|
|
{
|
|
mName = name;
|
|
mBaseType = baseType;
|
|
mAcceptFunc = acceptFunc;
|
|
if (mBaseType != NULL)
|
|
{
|
|
mBaseType->mDerivedTypes.Add(this);
|
|
}
|
|
sTypeCount++;
|
|
|
|
#ifdef _DEBUG
|
|
auto checkBase = mBaseType;
|
|
while (checkBase != NULL)
|
|
{
|
|
if (checkBase == &BfAstNode::sTypeInfo)
|
|
break;
|
|
checkBase = checkBase->mBaseType;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void AddTypeInfo(BfAstTypeInfo* typeInfo)
|
|
{
|
|
BF_ASSERT(typeInfo->mTypeId == 0);
|
|
|
|
typeInfo->mTypeId = (uint8)gTypes.size();
|
|
gTypes.Add(typeInfo);
|
|
gAcceptFuncs.Add(typeInfo->mAcceptFunc);
|
|
for (auto derivedType : typeInfo->mDerivedTypes)
|
|
AddTypeInfo(derivedType);
|
|
typeInfo->mFullDerivedCount = (uint8)(gTypes.size() - typeInfo->mTypeId - 1);
|
|
}
|
|
|
|
void BfAstTypeInfo::Init()
|
|
{
|
|
if (!gTypes.IsEmpty())
|
|
return;
|
|
|
|
gTypes.Add(NULL);
|
|
gAcceptFuncs.Add(NULL);
|
|
AddTypeInfo(&BfAstNode::sTypeInfo);
|
|
}
|
|
|
|
BfIdentifierNode* Beefy::BfIdentifierCast(BfAstNode* node)
|
|
{
|
|
if (node == NULL)
|
|
return NULL;
|
|
if (node->GetTypeId() == BfAttributedIdentifierNode::sTypeInfo.mTypeId)
|
|
return ((BfAttributedIdentifierNode*)node)->mIdentifier;
|
|
bool canCast = (uint)node->GetTypeId() - (uint)BfIdentifierNode::sTypeInfo.mTypeId <= (uint)BfIdentifierNode::sTypeInfo.mFullDerivedCount;
|
|
return canCast ? (BfIdentifierNode*)node : NULL;
|
|
}
|
|
|
|
BfAstNode* Beefy::BfNodeToNonTemporary(BfAstNode* node)
|
|
{
|
|
if (node == NULL)
|
|
return NULL;
|
|
if (node->GetTypeId() == BfNamedTypeReference::sTypeInfo.mTypeId)
|
|
{
|
|
auto namedTypeRef = (BfNamedTypeReference*)node;
|
|
if (namedTypeRef->IsTemporary())
|
|
return BfNodeToNonTemporary(namedTypeRef->mNameNode);
|
|
return namedTypeRef;
|
|
}
|
|
if (!node->IsTemporary())
|
|
return node;
|
|
return NULL;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
bool BfAstNode::IsMissingSemicolon()
|
|
{
|
|
if (auto deferStmt = BfNodeDynCast<BfDeferStatement>(this))
|
|
{
|
|
if (BfNodeIsExact<BfBlock>(deferStmt->mTargetNode))
|
|
return false;
|
|
}
|
|
if (auto stmt = BfNodeDynCast<BfCompoundStatement>(this))
|
|
{
|
|
if (auto repeatStmt = BfNodeDynCast<BfRepeatStatement>(this))
|
|
{
|
|
if (repeatStmt->mWhileToken == NULL)
|
|
return false;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
if (auto attribExpr = BfNodeDynCastExact<BfAttributedStatement>(this))
|
|
return (attribExpr->mStatement == NULL) || (attribExpr->mStatement->IsMissingSemicolon());
|
|
|
|
if (auto stmt = BfNodeDynCast<BfStatement>(this))
|
|
return stmt->mTrailingSemicolon == NULL;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool BfAstNode::IsExpression()
|
|
{
|
|
if (auto deferStmt = BfNodeDynCast<BfDeferStatement>(this))
|
|
{
|
|
if (BfNodeIsExact<BfBlock>(deferStmt->mTargetNode))
|
|
return false;
|
|
}
|
|
if (auto block = BfNodeDynCast<BfBlock>(this))
|
|
{
|
|
if (block->mChildArr.mSize == 0)
|
|
return false;
|
|
return block->mChildArr.GetLast()->IsExpression();
|
|
}
|
|
|
|
return IsA<BfExpression>();
|
|
}
|
|
|
|
bool BfAstNode::WantsWarning(int warningNumber)
|
|
{
|
|
auto parserData = GetParserData();
|
|
if (parserData == NULL)
|
|
return true;
|
|
int srcStart = GetSrcStart();
|
|
return (!parserData->IsUnwarnedAt(this)) && (parserData->IsWarningEnabledAtSrcIndex(warningNumber, GetSrcStart()));
|
|
}
|
|
|
|
bool BfAstNode::LocationEquals(BfAstNode* otherNode)
|
|
{
|
|
return (GetSourceData() == otherNode->GetSourceData()) &&
|
|
(GetSrcStart() == otherNode->GetSrcStart()) &&
|
|
(GetSrcEnd() == otherNode->GetSrcEnd());
|
|
}
|
|
|
|
bool BfAstNode::LocationEndEquals(BfAstNode* otherNode)
|
|
{
|
|
return (GetSourceData() == otherNode->GetSourceData()) &&
|
|
(GetSrcEnd() == otherNode->GetSrcEnd());
|
|
}
|
|
|
|
String BfAstNode::LocationToString()
|
|
{
|
|
auto parserData = GetParserData();
|
|
if (parserData == NULL)
|
|
return String();
|
|
|
|
String loc;
|
|
|
|
int line = -1;
|
|
int lineChar = -1;
|
|
parserData->GetLineCharAtIdx(mSrcStart, line, lineChar);
|
|
if (line != -1)
|
|
loc += StrFormat("at line %d:%d", line + 1, lineChar + 1);
|
|
loc += " in ";
|
|
loc += parserData->mFileName;
|
|
|
|
return loc;
|
|
}
|
|
|
|
void BfAstNode::Add(BfAstNode* bfAstNode)
|
|
{
|
|
#ifdef BF_AST_HAS_PARENT_MEMBER
|
|
BF_ASSERT(bfAstNode->mParent == NULL);
|
|
bfAstNode->mParent = this;
|
|
#endif
|
|
|
|
if (!IsInitialized())
|
|
{
|
|
int childTriviaStart;
|
|
int childSrcStart;
|
|
int childSrcEnd;
|
|
bfAstNode->GetSrcPositions(childTriviaStart, childSrcStart, childSrcEnd);
|
|
Init(childTriviaStart, childSrcStart, childSrcEnd);
|
|
return;
|
|
}
|
|
|
|
#ifdef BF_AST_COMPACT
|
|
int childTriviaStart;
|
|
int childSrcStart;
|
|
int childSrcEnd;
|
|
bfAstNode->GetSrcPositions(childTriviaStart, childSrcStart, childSrcEnd);
|
|
|
|
int prevTriviaStart;
|
|
int prevSrcStart;
|
|
int prevSrcEnd;
|
|
GetSrcPositions(prevTriviaStart, prevSrcStart, prevSrcEnd);
|
|
|
|
if (childTriviaStart < prevTriviaStart)
|
|
SetTriviaStart(childTriviaStart);
|
|
if (childSrcStart < prevSrcStart)
|
|
SetSrcStart(childSrcStart);
|
|
if (childSrcEnd > prevSrcEnd)
|
|
SetSrcEnd(childSrcEnd);
|
|
#else
|
|
BF_ASSERT(mSrcStart >= 0);
|
|
BF_ASSERT(bfAstNode->mSrcStart >= 0);
|
|
|
|
mSrcStart = BF_MIN(mSrcStart, bfAstNode->mSrcStart);
|
|
mSrcEnd = BF_MAX(mSrcEnd, bfAstNode->mSrcEnd);
|
|
#endif
|
|
}
|
|
|
|
#ifdef BF_AST_COMPACT
|
|
BfAstInfo* BfAstNode::AllocAstInfo()
|
|
{
|
|
return GetSource()->mAlloc.Alloc<BfAstInfo>();
|
|
}
|
|
#endif
|
|
|
|
void BfAstNode::RemoveSelf()
|
|
{
|
|
//mParent->mChildren.Remove(this);
|
|
#ifdef BF_AST_HAS_PARENT_MEMBER
|
|
mParent = NULL;
|
|
#endif
|
|
}
|
|
|
|
void BfAstNode::DeleteSelf()
|
|
{
|
|
//if (mParent != NULL)
|
|
//mParent->mChildren.Remove(this);
|
|
delete this;
|
|
}
|
|
|
|
void BfAstNode::RemoveNextSibling()
|
|
{
|
|
//mNext->RemoveSelf();
|
|
}
|
|
|
|
void BfAstNode::DeleteNextSibling()
|
|
{
|
|
//mNext->DeleteSelf();
|
|
}
|
|
|
|
void BfAstNode::Init(BfParser* bfParser)
|
|
{
|
|
BF_ASSERT(GetSourceData() == bfParser->mSourceData);
|
|
Init(bfParser->mTriviaStart, bfParser->mTokenStart, bfParser->mTokenEnd);
|
|
}
|
|
|
|
void BfAstNode::Accept(BfStructuralVisitor* bfVisitor)
|
|
{
|
|
(*gAcceptFuncs[GetTypeId()])(this, bfVisitor);
|
|
}
|
|
|
|
bool BfAstNode::IsTemporary()
|
|
{
|
|
#ifdef BF_AST_COMPACT
|
|
return (mIsCompact) && (mCompact_SrcStart == 0) && (mCompact_SrcLen == 0);
|
|
#else
|
|
return (mSrcEnd == 0);
|
|
#endif
|
|
}
|
|
|
|
int BfAstNode::GetStartCharId()
|
|
{
|
|
if (!IsTemporary())
|
|
{
|
|
auto bfParser = GetSourceData()->ToParserData();
|
|
if (bfParser != NULL)
|
|
return bfParser->GetCharIdAtIndex(GetSrcStart());
|
|
}
|
|
return GetSrcStart();
|
|
}
|
|
|
|
BfSourceData* BfAstNode::GetSourceData()
|
|
{
|
|
#ifdef BF_AST_ALLOCATOR_USE_PAGES
|
|
//BF_ASSERT((intptr)this > 0x4200000000);
|
|
BfAstPageHeader* pageHeader = (BfAstPageHeader*)((intptr)this & ~(BfAstAllocManager::PAGE_SIZE - 1));
|
|
return pageHeader->mSourceData;
|
|
#else
|
|
return mSourceData;
|
|
#endif
|
|
}
|
|
|
|
BfParserData* BfAstNode::GetParserData()
|
|
{
|
|
BfSourceData* sourceData = GetSourceData();
|
|
if (sourceData == NULL)
|
|
return NULL;
|
|
return sourceData->ToParserData();
|
|
}
|
|
|
|
BfParser* BfAstNode::GetParser()
|
|
{
|
|
BfSourceData* sourceData = GetSourceData();
|
|
if (sourceData == NULL)
|
|
return NULL;
|
|
return sourceData->ToParser();
|
|
}
|
|
|
|
bool BfAstNode::IsEmitted()
|
|
{
|
|
auto parser = GetParser();
|
|
if (parser == NULL)
|
|
return false;
|
|
return parser->mIsEmitted;
|
|
}
|
|
|
|
bool BfAstNode::IsFromParser(BfParser* parser)
|
|
{
|
|
if (parser == NULL)
|
|
return false;
|
|
if (IsTemporary())
|
|
return false;
|
|
BfSourceData* sourceData = GetSourceData();
|
|
if (sourceData == NULL)
|
|
return false;
|
|
return parser == sourceData->ToParser();
|
|
}
|
|
|
|
String BfAstNode::ToString()
|
|
{
|
|
int srcLen = GetSrcLength();
|
|
if (srcLen <= 0)
|
|
{
|
|
if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(this))
|
|
return namedTypeRef->mNameNode->ToString();
|
|
|
|
return "";
|
|
}
|
|
|
|
auto source = GetSourceData();
|
|
String str(source->mSrc + GetSrcStart(), srcLen);
|
|
return str;
|
|
}
|
|
|
|
StringView BfAstNode::ToStringView()
|
|
{
|
|
int srcLen = GetSrcLength();
|
|
if (srcLen <= 0)
|
|
{
|
|
if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(this))
|
|
return namedTypeRef->mNameNode->ToStringView();
|
|
return StringView();
|
|
}
|
|
|
|
auto source = GetSourceData();
|
|
return StringView(source->mSrc + GetSrcStart(), srcLen);
|
|
}
|
|
|
|
void BfAstNode::ToString(StringImpl& str)
|
|
{
|
|
int srcLen = GetSrcLength();
|
|
if (srcLen <= 0)
|
|
{
|
|
if (auto namedTypeRef = BfNodeDynCast<BfNamedTypeReference>(this))
|
|
namedTypeRef->mNameNode->ToString(str);
|
|
return;
|
|
}
|
|
|
|
auto source = GetSourceData();
|
|
str.Append(source->mSrc + GetSrcStart(), srcLen);
|
|
}
|
|
|
|
bool BfAstNode::Equals(const StringImpl& str)
|
|
{
|
|
int len = mSrcEnd - mSrcStart;
|
|
if (len != str.mLength)
|
|
return false;
|
|
auto source = GetSourceData();
|
|
return strncmp(str.GetPtr(), source->mSrc + mSrcStart, len) == 0;
|
|
}
|
|
|
|
bool BfAstNode::Equals(const StringView& str)
|
|
{
|
|
int len = mSrcEnd - mSrcStart;
|
|
if (len != str.mLength)
|
|
return false;
|
|
auto source = GetSourceData();
|
|
return strncmp(str.mPtr, source->mSrc + mSrcStart, len) == 0;
|
|
}
|
|
|
|
bool BfAstNode::Equals(const char* str)
|
|
{
|
|
if (mSrcEnd == 0)
|
|
return false;
|
|
|
|
auto source = GetSourceData();
|
|
const char* ptrLhs = source->mSrc + mSrcStart;
|
|
const char* ptrLhsEnd = source->mSrc + mSrcEnd;
|
|
const char* ptrRhs = str;
|
|
|
|
while (true)
|
|
{
|
|
char cRhs = *(ptrRhs++);
|
|
if (cRhs == 0)
|
|
return ptrLhs == ptrLhsEnd;
|
|
if (ptrLhs == ptrLhsEnd)
|
|
return false;
|
|
char cLhs = *(ptrLhs++);
|
|
if (cLhs != cRhs)
|
|
return false;
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
void BfBlock::Init(const SizedArrayImpl<BfAstNode*>& vec, BfAstAllocator* alloc)
|
|
{
|
|
#ifdef BF_USE_NEAR_NODE_REF
|
|
int curIdx = 0;
|
|
int elemsLeft = (int)vec.size();
|
|
BfBlockExtension* curExt = NULL;
|
|
|
|
while (elemsLeft > 0)
|
|
{
|
|
int bytesLeft = alloc->GetCurPageBytesLeft();
|
|
int useElems = std::min(bytesLeft / (int)sizeof(ASTREF(BfAstNode*)), elemsLeft);
|
|
BfBlockExtension* nextExt = NULL;
|
|
BfSizedArray<ASTREF(BfAstNode*)>& childArrRef = (curExt != NULL) ? curExt->mChildArr : mChildArr;
|
|
childArrRef.mVals = (ASTREF(BfAstNode*)*)alloc->AllocBytes(useElems * sizeof(ASTREF(BfAstNode*)), sizeof(ASTREF(BfAstNode*)));
|
|
childArrRef.mSize = useElems;
|
|
if (useElems < elemsLeft)
|
|
{
|
|
nextExt = alloc->Alloc<BfBlockExtension>();
|
|
useElems--;
|
|
}
|
|
|
|
for (int i = 0; i < useElems; i++)
|
|
childArrRef[i] = vec[curIdx++];
|
|
if (nextExt != NULL)
|
|
{
|
|
childArrRef[useElems] = nextExt;
|
|
curExt = nextExt;
|
|
}
|
|
elemsLeft -= useElems;
|
|
}
|
|
#else
|
|
BfSizedArrayInitIndirect(mChildArr, vec, alloc);
|
|
#endif
|
|
}
|
|
|
|
BfAstNode* BfBlock::GetFirst()
|
|
{
|
|
if (mChildArr.mSize == 0)
|
|
return NULL;
|
|
return mChildArr.mVals[0];
|
|
}
|
|
|
|
BfAstNode* BfBlock::GetLast()
|
|
{
|
|
if (mChildArr.mSize == 0)
|
|
return NULL;
|
|
auto backNode = mChildArr.mVals[mChildArr.mSize - 1];
|
|
while (auto blockExt = BfNodeDynCastExact<BfBlockExtension>(backNode))
|
|
backNode = blockExt->mChildArr.GetLast();
|
|
return backNode;
|
|
}
|
|
|
|
int BfBlock::GetSize()
|
|
{
|
|
int size = mChildArr.mSize;
|
|
if (mChildArr.mSize == 0)
|
|
return size;
|
|
BfAstNode* backNode = mChildArr.mVals[mChildArr.mSize - 1];
|
|
while (true)
|
|
{
|
|
if (auto blockExt = BfNodeDynCastExact<BfBlockExtension>(backNode))
|
|
{
|
|
size--;
|
|
size += blockExt->mChildArr.mSize;
|
|
backNode = blockExt->mChildArr.mVals[blockExt->mChildArr.mSize - 1];
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
void BfBlock::SetSize(int wantSize)
|
|
{
|
|
int size = mChildArr.mSize;
|
|
if (wantSize == size)
|
|
return;
|
|
|
|
if (wantSize < size)
|
|
{
|
|
mChildArr.mSize = wantSize;
|
|
}
|
|
else
|
|
{
|
|
BfAstNode* backNode = mChildArr.mVals[mChildArr.mSize - 1];
|
|
while (true)
|
|
{
|
|
if (auto blockExt = BfNodeDynCastExact<BfBlockExtension>(backNode))
|
|
{
|
|
size--;
|
|
size += blockExt->mChildArr.mSize;
|
|
|
|
if (wantSize < size)
|
|
{
|
|
blockExt->mChildArr.mSize -= (size - wantSize);
|
|
break;
|
|
}
|
|
|
|
backNode = blockExt->mChildArr.mVals[blockExt->mChildArr.mSize - 1];
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
BF_ASSERT(wantSize == GetSize());
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
bool BfTypeDeclaration::IsAnonymous()
|
|
{
|
|
return (mAnonymousName != NULL);
|
|
}
|
|
|
|
bool BfTypeDeclaration::IsAnonymousInitializerType()
|
|
{
|
|
return (mAnonymousName != NULL) && (mTypeNode == NULL);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
bool BfTypeReference::IsNamedTypeReference()
|
|
{
|
|
return IsA<BfNamedTypeReference>() || IsA<BfDirectStrTypeReference>() || IsA<BfInlineTypeReference>();
|
|
}
|
|
|
|
bool BfTypeReference::IsTypeDefTypeReference()
|
|
{
|
|
return IsA<BfNamedTypeReference>() || IsA<BfDirectStrTypeReference>() || IsA<BfInlineTypeReference>() || IsA<BfDirectTypeDefReference>();
|
|
}
|
|
|
|
String BfTypeReference::ToCleanAttributeString()
|
|
{
|
|
// ToString might return something like "System.InlineAttribute", which we want to clean before we test for "Inline"
|
|
auto typeRefName = ToString();
|
|
if (typeRefName.EndsWith("Attribute"))
|
|
{
|
|
int attribNameStart = (int)typeRefName.LastIndexOf('.');
|
|
if (attribNameStart != -1)
|
|
typeRefName.Remove(0, attribNameStart + 1);
|
|
|
|
if (typeRefName.EndsWith("Attribute"))
|
|
typeRefName.RemoveFromEnd(9);
|
|
}
|
|
if (typeRefName.StartsWith("System."))
|
|
typeRefName.Remove(0, 7);
|
|
return typeRefName;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
BfPropertyMethodDeclaration* BfPropertyDeclaration::GetMethod(const StringImpl& findName)
|
|
{
|
|
String methodName;
|
|
|
|
for (auto& methodDeclaration : mMethods)
|
|
{
|
|
if (methodDeclaration->mNameNode != NULL)
|
|
{
|
|
methodName.Clear();
|
|
methodDeclaration->mNameNode->ToString(methodName);
|
|
|
|
if (methodName == findName)
|
|
return methodDeclaration;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
bool BfExpression::VerifyIsStatement(BfPassInstance* passInstance, bool ignoreError)
|
|
{
|
|
if (auto attribExpr = BfNodeDynCast<BfAttributedExpression>(this))
|
|
{
|
|
return attribExpr->mExpression->VerifyIsStatement(passInstance, ignoreError);
|
|
}
|
|
|
|
if ((!BfNodeIsExact<BfAssignmentExpression>(this)) &&
|
|
(!BfNodeIsExact<BfInvocationExpression>(this)) &&
|
|
(!BfNodeIsExact<BfObjectCreateExpression>(this)))
|
|
{
|
|
if (auto castExpr = BfNodeDynCast<BfCastExpression>(this))
|
|
{
|
|
if ((castExpr->mTypeRef != NULL) && (castExpr->mTypeRef->ToString() == "void"))
|
|
{
|
|
// Is "(void)variable;" expression, used to remove warning about unused local variables
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (!ignoreError)
|
|
passInstance->Fail("This expression cannot be used as a statement", this);
|
|
//passInstance->Fail("Only assignment, call, increment, decrement, and allocation expressions can be used as a statement", this);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
bool BfAttributeDirective::Contains(const StringImpl& findName)
|
|
{
|
|
StringT<128> name;
|
|
|
|
auto attrDirective = this;
|
|
while (attrDirective != NULL)
|
|
{
|
|
name.clear();
|
|
if (attrDirective->mAttributeTypeRef != NULL)
|
|
attrDirective->mAttributeTypeRef->ToString(name);
|
|
|
|
if (findName == name)
|
|
return true;
|
|
if (name.EndsWith("Attribute"))
|
|
{
|
|
int attribNameStart = (int)name.LastIndexOf('.');
|
|
if (attribNameStart != -1)
|
|
name.Remove(0, attribNameStart + 1);
|
|
|
|
name.RemoveToEnd(name.length() - 9);
|
|
if (findName == name)
|
|
return true;
|
|
}
|
|
|
|
attrDirective = attrDirective->mNextAttribute;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
const char* Beefy::BfTokenToString(BfToken token)
|
|
{
|
|
switch (token)
|
|
{
|
|
case BfToken_Abstract:
|
|
return "abstract";
|
|
case BfToken_AlignOf:
|
|
return "alignof";
|
|
case BfToken_AllocType:
|
|
return "alloctype";
|
|
case BfToken_Append:
|
|
return "append";
|
|
case BfToken_As:
|
|
return "as";
|
|
case BfToken_Asm:
|
|
return "asm";
|
|
case BfToken_AsmNewline:
|
|
return "\n";
|
|
case BfToken_Base:
|
|
return "base";
|
|
case BfToken_Box:
|
|
return "box";
|
|
case BfToken_Break:
|
|
return "break";
|
|
case BfToken_Case:
|
|
return "case";
|
|
case BfToken_Catch:
|
|
return "catch";
|
|
case BfToken_Checked:
|
|
return "checked";
|
|
case BfToken_Class:
|
|
return "class";
|
|
case BfToken_Comptype:
|
|
return "comptype";
|
|
case BfToken_Concrete:
|
|
return "concrete";
|
|
case BfToken_Const:
|
|
return "const";
|
|
case BfToken_Continue:
|
|
return "continue";
|
|
case BfToken_Decltype:
|
|
return "decltype";
|
|
case BfToken_Default:
|
|
return "default";
|
|
case BfToken_Defer:
|
|
return "defer";
|
|
case BfToken_Delegate:
|
|
return "delegate";
|
|
case BfToken_Delete:
|
|
return "delete";
|
|
case BfToken_Do:
|
|
return "do";
|
|
case BfToken_Else:
|
|
return "else";
|
|
case BfToken_Enum:
|
|
return "enum";
|
|
case BfToken_Explicit:
|
|
return "explicit";
|
|
case BfToken_Extern:
|
|
return "extern";
|
|
case BfToken_Extension:
|
|
return "extension";
|
|
case BfToken_Fallthrough:
|
|
return "fallthrough";
|
|
case BfToken_Finally:
|
|
return "finally";
|
|
case BfToken_Fixed:
|
|
return "fixed";
|
|
case BfToken_For:
|
|
return "for";
|
|
case BfToken_Function:
|
|
return "function";
|
|
case BfToken_Goto:
|
|
return "goto";
|
|
case BfToken_If:
|
|
return "if";
|
|
case BfToken_Implicit:
|
|
return "implicit";
|
|
case BfToken_In:
|
|
return "in";
|
|
case BfToken_Interface:
|
|
return "interface";
|
|
case BfToken_Internal:
|
|
return "internal";
|
|
case BfToken_Is:
|
|
return "is";
|
|
case BfToken_IsConst:
|
|
return "isconst";
|
|
case BfToken_Let:
|
|
return "let";
|
|
case BfToken_Mixin:
|
|
return "mixin";
|
|
case BfToken_Mut:
|
|
return "mut";
|
|
case BfToken_NameOf:
|
|
return "nameof";
|
|
case BfToken_Namespace:
|
|
return "namespace";
|
|
case BfToken_New:
|
|
return "new";
|
|
case BfToken_Not:
|
|
return "not";
|
|
case BfToken_Null:
|
|
return "null";
|
|
case BfToken_Nullable:
|
|
return "nullable";
|
|
case BfToken_OffsetOf:
|
|
return "offsetof";
|
|
case BfToken_Operator:
|
|
return "operator";
|
|
case BfToken_Out:
|
|
return "out";
|
|
case BfToken_Override:
|
|
return "override";
|
|
case BfToken_Params:
|
|
return "params";
|
|
case BfToken_Private:
|
|
return "private";
|
|
case BfToken_Protected:
|
|
return "protected";
|
|
case BfToken_Public:
|
|
return "public";
|
|
case BfToken_ReadOnly:
|
|
return "readonly";
|
|
case BfToken_Repeat:
|
|
return "repeat";
|
|
case BfToken_Ref:
|
|
return "ref";
|
|
case BfToken_RetType:
|
|
return "rettype";
|
|
case BfToken_Return:
|
|
return "return";
|
|
case BfToken_Scope:
|
|
return "scope";
|
|
case BfToken_Sealed:
|
|
return "sealed";
|
|
case BfToken_SizeOf:
|
|
return "sizeof";
|
|
case BfToken_Static:
|
|
return "static";
|
|
case BfToken_StrideOf:
|
|
return "strideof";
|
|
case BfToken_Struct:
|
|
return "struct";
|
|
case BfToken_Switch:
|
|
return "switch";
|
|
case BfToken_This:
|
|
return "this";
|
|
case BfToken_Throw:
|
|
return "throw";
|
|
case BfToken_Try:
|
|
return "try";
|
|
case BfToken_TypeAlias:
|
|
return "typealias";
|
|
case BfToken_TypeOf:
|
|
return "typeof";
|
|
case BfToken_Unchecked:
|
|
return "unchecked";
|
|
case BfToken_Unsigned:
|
|
return "unsigned";
|
|
case BfToken_Using:
|
|
return "using";
|
|
case BfToken_Var:
|
|
return "var";
|
|
case BfToken_Virtual:
|
|
return "virtual";
|
|
case BfToken_Volatile:
|
|
return "volatile";
|
|
case BfToken_When:
|
|
return "when";
|
|
case BfToken_Where:
|
|
return "where";
|
|
case BfToken_While:
|
|
return "while";
|
|
case BfToken_Yield:
|
|
return "yield";
|
|
case BfToken_AssignEquals:
|
|
return "=";
|
|
case BfToken_CompareEquals:
|
|
return "==";
|
|
case BfToken_CompareStrictEquals:
|
|
return "===";
|
|
case BfToken_CompareNotEquals:
|
|
return "!=";
|
|
case BfToken_CompareStrictNotEquals:
|
|
return "!==";
|
|
case BfToken_LessEquals:
|
|
return "<=";
|
|
case BfToken_GreaterEquals:
|
|
return ">=";
|
|
case BfToken_Spaceship:
|
|
return "<=>";
|
|
case BfToken_PlusEquals:
|
|
return "+=";
|
|
case BfToken_MinusEquals:
|
|
return "-=";
|
|
case BfToken_MultiplyEquals:
|
|
return "*=";
|
|
case BfToken_DivideEquals:
|
|
return "/=";
|
|
case BfToken_ModulusEquals:
|
|
return "%=";
|
|
case BfToken_ShiftLeftEquals:
|
|
return "<<=";
|
|
case BfToken_ShiftRightEquals:
|
|
return ">>=";
|
|
case BfToken_AndEquals:
|
|
return "&=";
|
|
case BfToken_AndMinus:
|
|
return "&-";
|
|
case BfToken_AndPlus:
|
|
return "&+";
|
|
case BfToken_AndStar:
|
|
return "&*";
|
|
case BfToken_AndMinusEquals:
|
|
return "&-=";
|
|
case BfToken_AndPlusEquals:
|
|
return "&+=";
|
|
case BfToken_AndStarEquals:
|
|
return "&*=";
|
|
case BfToken_OrEquals:
|
|
return "|=";
|
|
case BfToken_XorEquals:
|
|
return "^=";
|
|
case BfToken_NullCoalsceEquals:
|
|
return "\?\?=";
|
|
case BfToken_LBrace:
|
|
return "{";
|
|
case BfToken_RBrace:
|
|
return "}";
|
|
case BfToken_LParen:
|
|
return "(";
|
|
case BfToken_RParen:
|
|
return ")";
|
|
case BfToken_LBracket:
|
|
return "[";
|
|
case BfToken_RBracket:
|
|
return "]";
|
|
case BfToken_LChevron:
|
|
return "<";
|
|
case BfToken_RChevron:
|
|
return ">";
|
|
case BfToken_LDblChevron:
|
|
return "<<";
|
|
case BfToken_RDblChevron:
|
|
return ">>";
|
|
case BfToken_Semicolon:
|
|
return ";";
|
|
case BfToken_Colon:
|
|
return ":";
|
|
case BfToken_ColonColon:
|
|
return "::";
|
|
case BfToken_Comma:
|
|
return ",";
|
|
case BfToken_Dot:
|
|
case BfToken_AutocompleteDot:
|
|
return ".";
|
|
case BfToken_DotDot:
|
|
return "..";
|
|
case BfToken_DotDotDot:
|
|
return "...";
|
|
case BfToken_DotDotLess:
|
|
return "..<";
|
|
case BfToken_QuestionDot:
|
|
return "?.";
|
|
case BfToken_QuestionLBracket:
|
|
return "?[";
|
|
case BfToken_Plus:
|
|
return "+";
|
|
case BfToken_Minus:
|
|
return "-";
|
|
case BfToken_DblPlus:
|
|
return "++";
|
|
case BfToken_DblMinus:
|
|
return "--";
|
|
case BfToken_Star:
|
|
return "*";
|
|
case BfToken_ForwardSlash:
|
|
return "/";
|
|
case BfToken_Modulus:
|
|
return "%";
|
|
case BfToken_Ampersand:
|
|
return "&";
|
|
case BfToken_At:
|
|
return "@";
|
|
case BfToken_DblAmpersand:
|
|
return "&&";
|
|
case BfToken_Bar:
|
|
return "|";
|
|
case BfToken_DblBar:
|
|
return "||";
|
|
case BfToken_Bang:
|
|
return "!";
|
|
case BfToken_Carat:
|
|
return "^";
|
|
case BfToken_Tilde:
|
|
return "~";
|
|
case BfToken_Question:
|
|
return "?";
|
|
case BfToken_DblQuestion:
|
|
return "??";
|
|
case BfToken_Arrow:
|
|
return "->";
|
|
case BfToken_FatArrow:
|
|
return "=>";
|
|
default:
|
|
break;
|
|
}
|
|
BF_FATAL("Unknown token");
|
|
return NULL;
|
|
}
|
|
|
|
bool Beefy::BfTokenIsKeyword(BfToken token)
|
|
{
|
|
return (token >= BfToken_Abstract) && (token <= BfToken_Yield);
|
|
}
|
|
|
|
bool Beefy::BfTokenIsTypeDecl(BfToken token)
|
|
{
|
|
return (token == BfToken_Struct) || (token == BfToken_Class) || (token == BfToken_Interface) || (token == BfToken_Enum);
|
|
}
|
|
|
|
BfBinaryOp Beefy::BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp)
|
|
{
|
|
switch (assignmentOp)
|
|
{
|
|
case BfAssignmentOp_Add:
|
|
return BfBinaryOp_Add;
|
|
case BfAssignmentOp_Subtract:
|
|
return BfBinaryOp_Subtract;
|
|
case BfAssignmentOp_Multiply:
|
|
return BfBinaryOp_Multiply;
|
|
case BfAssignmentOp_Divide:
|
|
return BfBinaryOp_Divide;
|
|
case BfAssignmentOp_OverflowAdd:
|
|
return BfBinaryOp_OverflowAdd;
|
|
case BfAssignmentOp_OverflowSubtract:
|
|
return BfBinaryOp_OverflowSubtract;
|
|
case BfAssignmentOp_OverflowMultiply:
|
|
return BfBinaryOp_OverflowMultiply;
|
|
case BfAssignmentOp_Modulus:
|
|
return BfBinaryOp_Modulus;
|
|
case BfAssignmentOp_ShiftLeft:
|
|
return BfBinaryOp_LeftShift;
|
|
case BfAssignmentOp_ShiftRight:
|
|
return BfBinaryOp_RightShift;
|
|
case BfAssignmentOp_BitwiseAnd:
|
|
return BfBinaryOp_BitwiseAnd;
|
|
case BfAssignmentOp_BitwiseOr:
|
|
return BfBinaryOp_BitwiseOr;
|
|
case BfAssignmentOp_ExclusiveOr:
|
|
return BfBinaryOp_ExclusiveOr;
|
|
case BfAssignmentOp_NullCoalesce:
|
|
return BfBinaryOp_NullCoalesce;
|
|
default:
|
|
break;
|
|
}
|
|
return BfBinaryOp_None;
|
|
}
|
|
|
|
int Beefy::BfGetBinaryOpPrecendence(BfBinaryOp binOp)
|
|
{
|
|
switch (binOp)
|
|
{
|
|
case BfBinaryOp_Multiply:
|
|
case BfBinaryOp_OverflowMultiply:
|
|
case BfBinaryOp_Divide:
|
|
case BfBinaryOp_Modulus:
|
|
return 14;
|
|
case BfBinaryOp_Add:
|
|
case BfBinaryOp_Subtract:
|
|
case BfBinaryOp_OverflowAdd:
|
|
case BfBinaryOp_OverflowSubtract:
|
|
return 13;
|
|
case BfBinaryOp_LeftShift:
|
|
case BfBinaryOp_RightShift:
|
|
return 12;
|
|
case BfBinaryOp_BitwiseAnd:
|
|
return 11;
|
|
case BfBinaryOp_ExclusiveOr:
|
|
return 10;
|
|
case BfBinaryOp_BitwiseOr:
|
|
return 9;
|
|
case BfBinaryOp_Range:
|
|
case BfBinaryOp_ClosedRange:
|
|
return 8;
|
|
case BfBinaryOp_Is:
|
|
case BfBinaryOp_As:
|
|
return 7;
|
|
case BfBinaryOp_Compare:
|
|
return 6;
|
|
case BfBinaryOp_GreaterThan:
|
|
case BfBinaryOp_LessThan:
|
|
case BfBinaryOp_GreaterThanOrEqual:
|
|
case BfBinaryOp_LessThanOrEqual:
|
|
return 5;
|
|
case BfBinaryOp_Equality:
|
|
case BfBinaryOp_StrictEquality:
|
|
case BfBinaryOp_InEquality:
|
|
case BfBinaryOp_StrictInEquality:
|
|
return 4;
|
|
case BfBinaryOp_ConditionalAnd:
|
|
return 3;
|
|
case BfBinaryOp_ConditionalOr:
|
|
return 2;
|
|
case BfBinaryOp_NullCoalesce:
|
|
return 1;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
const char* Beefy::BfGetOpName(BfBinaryOp binOp)
|
|
{
|
|
switch (binOp)
|
|
{
|
|
case BfBinaryOp_None: return "";
|
|
case BfBinaryOp_Add: return "+";
|
|
case BfBinaryOp_Subtract: return "-";
|
|
case BfBinaryOp_Multiply: return "*";
|
|
case BfBinaryOp_OverflowAdd: return "&+";
|
|
case BfBinaryOp_OverflowSubtract: return "&-";
|
|
case BfBinaryOp_OverflowMultiply: return "&*";
|
|
case BfBinaryOp_Divide: return "/";
|
|
case BfBinaryOp_Modulus: return "%";
|
|
case BfBinaryOp_BitwiseAnd: return "&";
|
|
case BfBinaryOp_BitwiseOr: return "|";
|
|
case BfBinaryOp_ExclusiveOr: return "^";
|
|
case BfBinaryOp_LeftShift: return "<<";
|
|
case BfBinaryOp_RightShift: return ">>";
|
|
case BfBinaryOp_Equality: return "==";
|
|
case BfBinaryOp_StrictEquality: return "===";
|
|
case BfBinaryOp_InEquality: return "!=";
|
|
case BfBinaryOp_StrictInEquality: return "!==";
|
|
case BfBinaryOp_GreaterThan: return ">";
|
|
case BfBinaryOp_LessThan: return "<";
|
|
case BfBinaryOp_GreaterThanOrEqual: return ">=";
|
|
case BfBinaryOp_LessThanOrEqual: return "<=";
|
|
case BfBinaryOp_Compare: return "<=>";
|
|
case BfBinaryOp_ConditionalAnd: return "&&";
|
|
case BfBinaryOp_ConditionalOr: return "||";
|
|
case BfBinaryOp_NullCoalesce: return "??";
|
|
case BfBinaryOp_Is: return "is";
|
|
case BfBinaryOp_As: return "as";
|
|
case BfBinaryOp_Range: return "..<";
|
|
case BfBinaryOp_ClosedRange: return "...";
|
|
default: return "???";
|
|
}
|
|
}
|
|
|
|
const char* Beefy::BfGetOpName(BfUnaryOp unaryOp)
|
|
{
|
|
switch (unaryOp)
|
|
{
|
|
case BfUnaryOp_None: return "";
|
|
case BfUnaryOp_AddressOf: return "&";
|
|
case BfUnaryOp_Arrow: return "->";
|
|
case BfUnaryOp_Dereference: return "*";
|
|
case BfUnaryOp_Negate: return "-";
|
|
case BfUnaryOp_Not: return "!";
|
|
case BfUnaryOp_Positive: return "+";
|
|
case BfUnaryOp_InvertBits: return "~";
|
|
case BfUnaryOp_Increment: return "++";
|
|
case BfUnaryOp_Decrement: return "--";
|
|
case BfUnaryOp_PostIncrement: return "++";
|
|
case BfUnaryOp_PostDecrement: return "--";
|
|
case BfUnaryOp_NullConditional: return "?";
|
|
case BfUnaryOp_Ref: return "ref";
|
|
case BfUnaryOp_Out: return "out";
|
|
case BfUnaryOp_Mut: return "mut";
|
|
case BfUnaryOp_Params: return "params";
|
|
case BfUnaryOp_Cascade: return "..";
|
|
case BfUnaryOp_FromEnd: return "^";
|
|
case BfUnaryOp_PartialRangeUpTo: return "..<";
|
|
case BfUnaryOp_PartialRangeThrough: return "...";
|
|
case BfUnaryOp_PartialRangeFrom: return "...";
|
|
default: return "???";
|
|
}
|
|
}
|
|
|
|
BfBinaryOp Beefy::BfTokenToBinaryOp(BfToken token)
|
|
{
|
|
switch (token)
|
|
{
|
|
case BfToken_Plus:
|
|
return BfBinaryOp_Add;
|
|
case BfToken_Minus:
|
|
return BfBinaryOp_Subtract;
|
|
case BfToken_Star:
|
|
return BfBinaryOp_Multiply;
|
|
case BfToken_AndPlus:
|
|
return BfBinaryOp_OverflowAdd;
|
|
case BfToken_AndMinus:
|
|
return BfBinaryOp_OverflowSubtract;
|
|
case BfToken_AndStar:
|
|
return BfBinaryOp_OverflowMultiply;
|
|
case BfToken_ForwardSlash:
|
|
return BfBinaryOp_Divide;
|
|
case BfToken_Modulus:
|
|
return BfBinaryOp_Modulus;
|
|
case BfToken_Ampersand:
|
|
return BfBinaryOp_BitwiseAnd;
|
|
case BfToken_Bar:
|
|
return BfBinaryOp_BitwiseOr;
|
|
case BfToken_Carat:
|
|
return BfBinaryOp_ExclusiveOr;
|
|
case BfToken_LDblChevron:
|
|
return BfBinaryOp_LeftShift;
|
|
case BfToken_RDblChevron:
|
|
return BfBinaryOp_RightShift;
|
|
case BfToken_CompareEquals:
|
|
return BfBinaryOp_Equality;
|
|
case BfToken_CompareStrictEquals:
|
|
return BfBinaryOp_StrictEquality;
|
|
case BfToken_CompareNotEquals:
|
|
return BfBinaryOp_InEquality;
|
|
case BfToken_CompareStrictNotEquals:
|
|
return BfBinaryOp_StrictInEquality;
|
|
case BfToken_RChevron:
|
|
return BfBinaryOp_GreaterThan;
|
|
case BfToken_LChevron:
|
|
return BfBinaryOp_LessThan;
|
|
case BfToken_GreaterEquals:
|
|
return BfBinaryOp_GreaterThanOrEqual;
|
|
case BfToken_LessEquals:
|
|
return BfBinaryOp_LessThanOrEqual;
|
|
case BfToken_Spaceship:
|
|
return BfBinaryOp_Compare;
|
|
case BfToken_DblAmpersand:
|
|
return BfBinaryOp_ConditionalAnd;
|
|
case BfToken_DblBar:
|
|
return BfBinaryOp_ConditionalOr;
|
|
case BfToken_DblQuestion:
|
|
return BfBinaryOp_NullCoalesce;
|
|
case BfToken_DotDotLess:
|
|
return BfBinaryOp_Range;
|
|
case BfToken_DotDotDot:
|
|
return BfBinaryOp_ClosedRange;
|
|
default:
|
|
return BfBinaryOp_None;
|
|
}
|
|
}
|
|
|
|
BfUnaryOp Beefy::BfTokenToUnaryOp(BfToken token)
|
|
{
|
|
switch (token)
|
|
{
|
|
case BfToken_Star:
|
|
return BfUnaryOp_Dereference;
|
|
case BfToken_Ampersand:
|
|
return BfUnaryOp_AddressOf;
|
|
case BfToken_Arrow:
|
|
return BfUnaryOp_Arrow;
|
|
case BfToken_Minus:
|
|
return BfUnaryOp_Negate;
|
|
case BfToken_Bang:
|
|
return BfUnaryOp_Not;
|
|
case BfToken_Plus:
|
|
return BfUnaryOp_Positive;
|
|
case BfToken_Tilde:
|
|
return BfUnaryOp_InvertBits;
|
|
case BfToken_DblPlus:
|
|
return BfUnaryOp_Increment;
|
|
case BfToken_DblMinus:
|
|
return BfUnaryOp_Decrement;
|
|
case BfToken_Question:
|
|
return BfUnaryOp_NullConditional;
|
|
case BfToken_Ref:
|
|
return BfUnaryOp_Ref;
|
|
case BfToken_Mut:
|
|
return BfUnaryOp_Mut;
|
|
case BfToken_Out:
|
|
return BfUnaryOp_Out;
|
|
case BfToken_Params:
|
|
return BfUnaryOp_Params;
|
|
case BfToken_DotDot:
|
|
return BfUnaryOp_Cascade;
|
|
case BfToken_Carat:
|
|
return BfUnaryOp_FromEnd;
|
|
case BfToken_DotDotDot:
|
|
return BfUnaryOp_PartialRangeThrough;
|
|
case BfToken_DotDotLess:
|
|
return BfUnaryOp_PartialRangeUpTo;
|
|
default:
|
|
return BfUnaryOp_None;
|
|
}
|
|
}
|
|
|
|
bool Beefy::BfCanOverloadOperator(BfUnaryOp unaryOp)
|
|
{
|
|
switch (unaryOp)
|
|
{
|
|
case BfUnaryOp_Negate:
|
|
case BfUnaryOp_Not:
|
|
case BfUnaryOp_Positive:
|
|
case BfUnaryOp_InvertBits:
|
|
case BfUnaryOp_Increment:
|
|
case BfUnaryOp_Decrement:
|
|
case BfUnaryOp_PostIncrement:
|
|
case BfUnaryOp_PostDecrement:
|
|
case BfUnaryOp_NullConditional:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
BfAssignmentOp Beefy::BfTokenToAssignmentOp(BfToken token)
|
|
{
|
|
switch (token)
|
|
{
|
|
case BfToken_AssignEquals:
|
|
return BfAssignmentOp_Assign;
|
|
case BfToken_PlusEquals:
|
|
return BfAssignmentOp_Add;
|
|
case BfToken_MinusEquals:
|
|
return BfAssignmentOp_Subtract;
|
|
case BfToken_MultiplyEquals:
|
|
return BfAssignmentOp_Multiply;
|
|
case BfToken_AndPlusEquals:
|
|
return BfAssignmentOp_OverflowAdd;
|
|
case BfToken_AndMinusEquals:
|
|
return BfAssignmentOp_OverflowSubtract;
|
|
case BfToken_AndStarEquals:
|
|
return BfAssignmentOp_OverflowMultiply;
|
|
case BfToken_DivideEquals:
|
|
return BfAssignmentOp_Divide;
|
|
case BfToken_ModulusEquals:
|
|
return BfAssignmentOp_Modulus;
|
|
case BfToken_ShiftLeftEquals:
|
|
return BfAssignmentOp_ShiftLeft;
|
|
case BfToken_ShiftRightEquals:
|
|
return BfAssignmentOp_ShiftRight;
|
|
case BfToken_AndEquals:
|
|
return BfAssignmentOp_BitwiseAnd;
|
|
case BfToken_OrEquals:
|
|
return BfAssignmentOp_BitwiseOr;
|
|
case BfToken_XorEquals:
|
|
return BfAssignmentOp_ExclusiveOr;
|
|
case BfToken_NullCoalsceEquals:
|
|
return BfAssignmentOp_NullCoalesce;
|
|
default:
|
|
return BfAssignmentOp_None;
|
|
}
|
|
}
|
|
|
|
BfBinaryOp Beefy::BfGetOppositeBinaryOp(BfBinaryOp origOp)
|
|
{
|
|
switch (origOp)
|
|
{
|
|
case BfBinaryOp_Equality:
|
|
return BfBinaryOp_InEquality;
|
|
case BfBinaryOp_StrictEquality:
|
|
return BfBinaryOp_StrictInEquality;
|
|
case BfBinaryOp_InEquality:
|
|
return BfBinaryOp_Equality;
|
|
case BfBinaryOp_StrictInEquality:
|
|
return BfBinaryOp_StrictEquality;
|
|
case BfBinaryOp_LessThan:
|
|
return BfBinaryOp_GreaterThanOrEqual;
|
|
case BfBinaryOp_LessThanOrEqual:
|
|
return BfBinaryOp_GreaterThan;
|
|
case BfBinaryOp_GreaterThan:
|
|
return BfBinaryOp_LessThanOrEqual;
|
|
case BfBinaryOp_GreaterThanOrEqual:
|
|
return BfBinaryOp_LessThan;
|
|
default: break;
|
|
}
|
|
|
|
return BfBinaryOp_None;
|
|
}
|
|
|
|
BfBinaryOp Beefy::BfGetFlippedBinaryOp(BfBinaryOp origOp)
|
|
{
|
|
switch (origOp)
|
|
{
|
|
case BfBinaryOp_Equality:
|
|
return BfBinaryOp_Equality;
|
|
case BfBinaryOp_InEquality:
|
|
return BfBinaryOp_InEquality;
|
|
case BfBinaryOp_LessThan:
|
|
return BfBinaryOp_GreaterThan;
|
|
case BfBinaryOp_LessThanOrEqual:
|
|
return BfBinaryOp_GreaterThanOrEqual;
|
|
case BfBinaryOp_GreaterThan:
|
|
return BfBinaryOp_LessThan;
|
|
case BfBinaryOp_GreaterThanOrEqual:
|
|
return BfBinaryOp_LessThanOrEqual;
|
|
default: break;
|
|
}
|
|
|
|
return BfBinaryOp_None;
|
|
}
|
|
|
|
bool Beefy::BfBinOpEqualityCheck(BfBinaryOp binOp)
|
|
{
|
|
return (binOp >= BfBinaryOp_Equality) && (binOp <= BfBinaryOp_StrictInEquality);
|
|
}
|
|
|
|
bool Beefy::BfIsCommentBlock(BfCommentKind commentKind)
|
|
{
|
|
return
|
|
(commentKind == BfCommentKind_Block) ||
|
|
(commentKind == BfCommentKind_Documentation_Block_Pre) ||
|
|
(commentKind == BfCommentKind_Documentation_Block_Post);
|
|
}
|
|
|
|
BfInlineAsmInstruction::AsmArg::AsmArg()
|
|
: mType(ARGTYPE_Immediate)
|
|
, mMemFlags(0)
|
|
, mInt(0)
|
|
, mAdjRegScalar(1)
|
|
{}
|
|
|
|
#pragma warning(disable:4996)
|
|
String BfInlineAsmInstruction::AsmArg::ToString()
|
|
{
|
|
String s;
|
|
|
|
if (!mSizePrefix.empty())
|
|
{
|
|
s += mSizePrefix;
|
|
s += " ptr ";
|
|
}
|
|
if (!mSegPrefix.empty())
|
|
{
|
|
s += mSegPrefix;
|
|
s += ":";
|
|
}
|
|
switch(mType)
|
|
{
|
|
case ARGTYPE_Immediate:
|
|
{
|
|
char buf[64];
|
|
sprintf(buf, "%d", mInt);
|
|
s += buf;
|
|
}
|
|
break;
|
|
case ARGTYPE_FloatReg:
|
|
{
|
|
char buf[64];
|
|
sprintf(buf, "st(%d)", mInt);
|
|
s += buf;
|
|
}
|
|
break;
|
|
case ARGTYPE_IntReg:
|
|
{
|
|
s += mReg;
|
|
}
|
|
break;
|
|
case ARGTYPE_Memory:
|
|
{
|
|
s += "[";
|
|
if (mMemFlags & ARGMEMF_BaseReg)
|
|
{
|
|
s += mReg;
|
|
if (mMemFlags != ARGMEMF_BaseReg)
|
|
s += " + ";
|
|
}
|
|
if (mMemFlags & ARGMEMF_AdjReg)
|
|
{
|
|
s += mAdjReg;
|
|
if (mAdjRegScalar != 1)
|
|
{
|
|
char buf[64];
|
|
sprintf(buf, "%d", mAdjRegScalar);
|
|
s += "*";
|
|
s += buf;
|
|
}
|
|
if (mMemFlags & ARGMEMF_ImmediateDisp)
|
|
s += " + ";
|
|
}
|
|
if (mMemFlags & ARGMEMF_ImmediateDisp)
|
|
{
|
|
char buf[64];
|
|
sprintf(buf, "%d", mInt);
|
|
s += buf;
|
|
}
|
|
s += "]";
|
|
if (!mMemberSuffix.empty())
|
|
{
|
|
s += ".";
|
|
s += mMemberSuffix;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
BfInlineAsmInstruction::AsmInst::AsmInst()
|
|
: mDebugLine(0)
|
|
{}
|
|
|
|
String BfInlineAsmInstruction::AsmInst::ToString()
|
|
{
|
|
String s;
|
|
|
|
if (!mLabel.empty())
|
|
{
|
|
s += mLabel;
|
|
s += ": ";
|
|
}
|
|
|
|
for (auto const& p : mOpPrefixes)
|
|
{
|
|
s += p;
|
|
s += " ";
|
|
}
|
|
s += mOpCode;
|
|
s += " ";
|
|
for (int i=0; i<(int)mArgs.size(); ++i)
|
|
{
|
|
if (i > 0)
|
|
s += ", ";
|
|
s += mArgs[i].ToString();
|
|
}
|
|
|
|
return s;
|
|
} |