1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00
This commit is contained in:
Brian Fiete 2021-09-10 14:21:25 -07:00
parent 507fb82e4a
commit 4cda126188
11 changed files with 156 additions and 10 deletions

View file

@ -346,6 +346,11 @@ void BfStructuralVisitor::Visit(BfStrideOfExpression* strideOfExpr)
Visit(strideOfExpr->ToBase());
}
void BfStructuralVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
{
Visit(offsetOfExpr->ToBase());
}
void BfStructuralVisitor::Visit(BfDefaultExpression* defaultExpr)
{
Visit(defaultExpr->ToBase());
@ -1398,6 +1403,8 @@ const char* Beefy::BfTokenToString(BfToken token)
return "null";
case BfToken_Nullable:
return "nullable";
case BfToken_OffsetOf:
return "offsetof";
case BfToken_Operator:
return "operator";
case BfToken_Out:

View file

@ -158,6 +158,7 @@ enum BfToken : uint8
BfToken_New,
BfToken_Null,
BfToken_Nullable,
BfToken_OffsetOf,
BfToken_Operator,
BfToken_Out,
BfToken_Override,
@ -367,6 +368,7 @@ class BfTypedValueExpression;
class BfTypeAttrExpression;
class BfSizeOfExpression;
class BfAlignOfExpression;
class BfOffsetOfExpression;
class BfStrideOfExpression;
class BfDefaultExpression;
class BfUninitializedExpression;
@ -490,6 +492,7 @@ public:
virtual void Visit(BfSizeOfExpression* sizeOfExpr);
virtual void Visit(BfAlignOfExpression* alignOfExpr);
virtual void Visit(BfStrideOfExpression* strideOfExpr);
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
virtual void Visit(BfDefaultExpression* defaultExpr);
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);
@ -2652,7 +2655,7 @@ public:
class BfAlignOfExpression : public BfTypeAttrExpression
{
public:
BF_AST_TYPE(BfAlignOfExpression, BfTypeAttrExpression);
BF_AST_TYPE(BfAlignOfExpression, BfTypeAttrExpression);
}; BF_AST_DECL(BfAlignOfExpression, BfTypeAttrExpression);
class BfStrideOfExpression : public BfTypeAttrExpression
@ -2661,6 +2664,15 @@ public:
BF_AST_TYPE(BfStrideOfExpression, BfTypeAttrExpression);
}; BF_AST_DECL(BfStrideOfExpression, BfTypeAttrExpression);
class BfOffsetOfExpression : public BfTypeAttrExpression
{
public:
BF_AST_TYPE(BfOffsetOfExpression, BfTypeAttrExpression);
BfTokenNode* mCommaToken;
BfIdentifierNode* mMemberName;
}; BF_AST_DECL(BfOffsetOfExpression, BfTypeAttrExpression);
class BfDefaultExpression : public BfExpression
{
public:

View file

@ -987,11 +987,12 @@ void BfAutoComplete::AddSelfResultTypeMembers(BfTypeInstance* typeInst, BfTypeIn
bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, String& filter)
{
bool isDot = (dotNode != NULL) && (dotNode->mToken == BfToken_Dot);
if (IsAutocompleteNode(nameNode))
{
auto bfParser = nameNode->GetSourceData()->ToParser();
if (mIsGetDefinition)
if ((mIsGetDefinition) || (!isDot))
{
mInsertStartIdx = nameNode->GetSrcStart();
mInsertEndIdx = nameNode->GetSrcEnd();
@ -1002,11 +1003,15 @@ bool BfAutoComplete::InitAutocomplete(BfAstNode* dotNode, BfAstNode* nameNode, S
mInsertEndIdx = std::min(bfParser->mCursorIdx + 1, nameNode->GetSrcEnd());
}
filter.Append(bfParser->mSrc + mInsertStartIdx, mInsertEndIdx - mInsertStartIdx);
filter.Append(bfParser->mSrc + nameNode->GetSrcStart(), mInsertEndIdx - nameNode->GetSrcStart());
return true;
}
if ((dotNode != NULL) && (IsAutocompleteNode(dotNode, 0, 1)))
int lenAdd = 0;
if (!isDot)
lenAdd++;
if ((dotNode != NULL) && (IsAutocompleteNode(dotNode, lenAdd, 1)))
{
mInsertStartIdx = dotNode->GetSrcEnd();
mInsertEndIdx = dotNode->GetSrcEnd();
@ -1558,7 +1563,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
"alignof", "as", "asm", "base", "break", "case", "catch", "checked", "continue", "default", "defer",
"delegate", "delete", "do", "else", "false", "finally",
"fixed", "for", "function", "if", "implicit", "in", "internal", "is", "new", "mixin", "null",
"out", "params", "ref", "rettype", "return",
"offsetof", "out", "params", "ref", "rettype", "return",
"sealed", "sizeof", "scope", "static", "strideof", "struct", "switch", /*"this",*/ "try", "true", "typeof", "unchecked",
"using", "var", "virtual", "volatile", "where", "while",
"alloctype", "comptype", "decltype", "nullable",

View file

@ -492,6 +492,16 @@ void BfElementVisitor::Visit(BfTypeAttrExpression* typeAttrExpr)
VisitChild(typeAttrExpr->mCloseParen);
}
void BfElementVisitor::Visit(BfOffsetOfExpression* offsetOfExpr)
{
VisitChild(offsetOfExpr->mToken);
VisitChild(offsetOfExpr->mOpenParen);
VisitChild(offsetOfExpr->mTypeRef);
VisitChild(offsetOfExpr->mCommaToken);
VisitChild(offsetOfExpr->mMemberName);
VisitChild(offsetOfExpr->mCloseParen);
}
void BfElementVisitor::Visit(BfDefaultExpression* defaultExpr)
{
Visit(defaultExpr->ToBase());

View file

@ -69,6 +69,7 @@ public:
virtual void Visit(BfLocalMethodDeclaration* methodDecl);
virtual void Visit(BfParameterDeclaration* paramDecl);
virtual void Visit(BfTypeAttrExpression* typeAttrExpr);
virtual void Visit(BfOffsetOfExpression* offsetOfExpr);
virtual void Visit(BfDefaultExpression* defaultExpr);
virtual void Visit(BfUninitializedExpression* uninitializedExpr);
virtual void Visit(BfCheckTypeExpression* checkTypeExpr);

View file

@ -10409,8 +10409,11 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
return true;
}
void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token)
{
auto autoComplete = GetAutoComplete();
auto type = mModule->ResolveTypeRef(typeRef, BfPopulateType_Data, BfResolveTypeRefFlag_AutoComplete);
if (type == NULL)
return;
@ -10433,6 +10436,72 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
default: break;
}
if (token == BfToken_OffsetOf)
{
bool found = false;
String findName;
if (memberName != NULL)
findName = memberName->ToString();
BfAstNode* refNode = typeRef;
if (memberName != NULL)
refNode = memberName;
auto checkTypeInst = typeInst;
while (checkTypeInst != NULL)
{
checkTypeInst->mTypeDef->PopulateMemberSets();
String filter;
if ((autoComplete != NULL) && (autoComplete->InitAutocomplete(commaToken, memberName, filter)))
{
auto activeTypeDef = mModule->GetActiveTypeDef();
mModule->PopulateType(checkTypeInst);
BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None;
for (auto fieldDef : checkTypeInst->mTypeDef->mFields)
{
if (fieldDef->mIsStatic)
continue;
if (!mModule->CheckProtection(protectionCheckFlags, typeInst, fieldDef->mDeclaringType->mProject, fieldDef->mProtection, typeInst))
continue;
if ((!typeInst->IsTypeMemberIncluded(fieldDef->mDeclaringType, activeTypeDef, mModule)) ||
(!typeInst->IsTypeMemberAccessible(fieldDef->mDeclaringType, activeTypeDef)))
continue;
auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx];
autoComplete->AddField(checkTypeInst, fieldDef, &fieldInst, filter);
}
}
BfMemberSetEntry* memberSetEntry = NULL;
if (checkTypeInst->mTypeDef->mFieldSet.TryGetWith(findName, &memberSetEntry))
{
auto fieldDef = (BfFieldDef*)memberSetEntry->mMemberDef;
if (fieldDef != NULL)
{
if (fieldDef->mIsStatic)
mModule->Fail(StrFormat("Cannot generate an offset from static field '%s.%s'", mModule->TypeToString(type).c_str(), fieldDef->mName.c_str()), refNode);
mModule->PopulateType(checkTypeInst);
auto& fieldInst = checkTypeInst->mFieldInstances[fieldDef->mIdx];
attrVal = fieldInst.mDataOffset;
found = true;
break;
}
}
checkTypeInst = checkTypeInst->mBaseType;
}
if (!found)
{
mModule->Fail(StrFormat("Unable to locate field '%s.%s'", mModule->TypeToString(type).c_str(), findName.c_str()), refNode);
}
}
bool isUndefVal = false;
if (type->IsGenericParam())
@ -10458,17 +10527,22 @@ void BfExprEvaluator::DoTypeIntAttr(BfTypeReference* typeRef, BfToken token)
void BfExprEvaluator::Visit(BfSizeOfExpression* sizeOfExpr)
{
DoTypeIntAttr(sizeOfExpr->mTypeRef, BfToken_SizeOf);
DoTypeIntAttr(sizeOfExpr->mTypeRef, NULL, NULL, BfToken_SizeOf);
}
void BfExprEvaluator::Visit(BfAlignOfExpression* alignOfExpr)
{
DoTypeIntAttr(alignOfExpr->mTypeRef, BfToken_AlignOf);
DoTypeIntAttr(alignOfExpr->mTypeRef, NULL, NULL, BfToken_AlignOf);
}
void BfExprEvaluator::Visit(BfStrideOfExpression* strideOfExpr)
{
DoTypeIntAttr(strideOfExpr->mTypeRef, BfToken_StrideOf);
DoTypeIntAttr(strideOfExpr->mTypeRef, NULL, NULL, BfToken_StrideOf);
}
void BfExprEvaluator::Visit(BfOffsetOfExpression* offsetOfExpr)
{
DoTypeIntAttr(offsetOfExpr->mTypeRef, offsetOfExpr->mCommaToken, offsetOfExpr->mMemberName, BfToken_OffsetOf);
}
void BfExprEvaluator::Visit(BfDefaultExpression* defaultExpr)

View file

@ -487,7 +487,7 @@ public:
void FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues);
void FinishDeferredEvals(BfResolvedArgs& argValues);
bool LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifierNode* propName);
void DoTypeIntAttr(BfTypeReference* typeRef, BfToken token);
void DoTypeIntAttr(BfTypeReference* typeRef, BfTokenNode* commaToken, BfIdentifierNode* memberName, BfToken token);
//void InitializedSizedArray(BfTupleExpression* createExpr, BfSizedArrayType* arrayType);
void InitializedSizedArray(BfSizedArrayType* sizedArrayType, BfTokenNode* openToken, const BfSizedArray<BfExpression*>& values, const BfSizedArray<BfTokenNode*>& commas, BfTokenNode* closeToken, BfTypedValue* receivingValue = NULL);
void CheckDotToken(BfTokenNode* tokenNode);
@ -518,6 +518,7 @@ public:
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
virtual void Visit(BfAlignOfExpression* alignOfExpr) override;
virtual void Visit(BfStrideOfExpression* strideOfExpr) override;
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
virtual void Visit(BfDefaultExpression* defaultExpr) override;
virtual void Visit(BfUninitializedExpression* uninitialziedExpr) override;
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;

View file

@ -3058,6 +3058,10 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
else if (SrcPtrHasToken("nullable"))
mToken = BfToken_Nullable;
break;
case TOKEN_HASH('o', 'f', 'f', 's'):
if (SrcPtrHasToken("offsetof"))
mToken = BfToken_OffsetOf;
break;
case TOKEN_HASH('o', 'p', 'e', 'r'):
if (SrcPtrHasToken("operator"))
mToken = BfToken_Operator;

View file

@ -1653,6 +1653,17 @@ void BfPrinter::Visit(BfSizeOfExpression* sizeOfExpr)
VisitChild(sizeOfExpr->mCloseParen);
}
void BfPrinter::Visit(BfOffsetOfExpression* offsetOfExpr)
{
VisitChild(offsetOfExpr->mToken);
VisitChild(offsetOfExpr->mOpenParen);
VisitChild(offsetOfExpr->mTypeRef);
VisitChild(offsetOfExpr->mCommaToken);
ExpectSpace();
VisitChild(offsetOfExpr->mMemberName);
VisitChild(offsetOfExpr->mCloseParen);
}
void BfPrinter::Visit(BfDefaultExpression* defaultExpr)
{
Visit(defaultExpr->ToBase());

View file

@ -168,6 +168,7 @@ public:
virtual void Visit(BfParameterDeclaration* paramDecl) override;
virtual void Visit(BfTypeOfExpression* typeOfExpr) override;
virtual void Visit(BfSizeOfExpression* sizeOfExpr) override;
virtual void Visit(BfOffsetOfExpression* offsetOfExpr) override;
virtual void Visit(BfDefaultExpression* defaultExpr) override;
virtual void Visit(BfCheckTypeExpression* checkTypeExpr) override;
virtual void Visit(BfDynamicCastExpression* dynCastExpr) override;

View file

@ -1871,6 +1871,26 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
MEMBER_SET_CHECKED(typeAttrExpr, mCloseParen, tokenNode);
exprLeft = typeAttrExpr;
}
else if (token == BfToken_OffsetOf)
{
BfOffsetOfExpression* typeAttrExpr = mAlloc->Alloc<BfOffsetOfExpression>();
ReplaceNode(tokenNode, typeAttrExpr);
typeAttrExpr->mToken = tokenNode;
tokenNode = ExpectTokenAfter(typeAttrExpr, BfToken_LParen);
MEMBER_SET_CHECKED(typeAttrExpr, mOpenParen, tokenNode);
auto typeRef = CreateTypeRefAfter(typeAttrExpr);
MEMBER_SET_CHECKED(typeAttrExpr, mTypeRef, typeRef);
tokenNode = ExpectTokenAfter(typeAttrExpr, BfToken_Comma);
MEMBER_SET_CHECKED(typeAttrExpr, mCommaToken, tokenNode);
auto nameNode = ExpectIdentifierAfter(typeAttrExpr);
MEMBER_SET_CHECKED(typeAttrExpr, mMemberName, nameNode);
tokenNode = ExpectTokenAfter(typeAttrExpr, BfToken_RParen);
MEMBER_SET_CHECKED(typeAttrExpr, mCloseParen, tokenNode);
exprLeft = typeAttrExpr;
}
else if (token == BfToken_Default)
{
auto defaultExpr = mAlloc->Alloc<BfDefaultExpression>();