1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +02:00

Added support for indexer in initializer expression, reeval Add calls

This commit is contained in:
Brian Fiete 2023-03-17 11:13:41 -07:00
parent ac6f58f118
commit 596dd2401d
7 changed files with 85 additions and 66 deletions

View file

@ -11544,8 +11544,6 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
BfTypedValue initValue = GetResult(true);
bool isFirstAdd = true;
BfFunctionBindResult addFunctionBindResult;
addFunctionBindResult.mWantsArgs = true;
for (auto elementExpr : initExpr->mValues)
{
@ -11604,6 +11602,26 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
findName.c_str()), identifierNode);
}
}
else if (auto indexerExpression = BfNodeDynCast<BfIndexerExpression>(assignExpr->mLeft))
{
if (indexerExpression->mTarget == NULL)
{
if ((initValue.mType->IsValueType()) && (!initValue.IsAddr()))
{
initValue = mModule->MakeAddressable(initValue, true, true);
}
mResult = BfTypedValue();
HandleIndexerExpression(indexerExpression, initValue);
wasValidInitKind = true;
if ((mPropDef) || (mResult))
{
PerformAssignment(assignExpr, true, BfTypedValue());
mResult = BfTypedValue();
}
}
}
}
else
{
@ -11622,40 +11640,13 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
}
}
bool wasFirstAdd = isFirstAdd;
if (isFirstAdd)
{
BfExprEvaluator exprEvaluator(mModule);
exprEvaluator.mFunctionBindResult = &addFunctionBindResult;
SizedArray<BfExpression*, 2> argExprs;
argExprs.push_back(elementExpr);
BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
BfResolvedArgs argValues(&sizedArgExprs);
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments());
if (addFunctionBindResult.mMethodInstance != NULL)
CreateCall(initExpr, addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, addFunctionBindResult.mIRArgs);
isFirstAdd = false;
}
else if ((addFunctionBindResult.mMethodInstance == NULL) || (addFunctionBindResult.mMethodInstance->GetParamCount() == 0))
{
mModule->CreateValueFromExpression(elementExpr, NULL, (BfEvalExprFlags)(mBfEvalExprFlags& BfEvalExprFlags_InheritFlags));
}
else
{
auto argValue = mModule->CreateValueFromExpression(elementExpr, addFunctionBindResult.mMethodInstance->GetParamType(0), (BfEvalExprFlags)(mBfEvalExprFlags & BfEvalExprFlags_InheritFlags));
if ((argValue) && (!mModule->mBfIRBuilder->mIgnoreWrites))
{
SizedArray<BfIRValue, 2> irArgs;
PushThis(elementExpr, initValue, addFunctionBindResult.mMethodInstance, irArgs);
PushArg(argValue, irArgs);
for (int argIdx = (int)irArgs.size(); argIdx < (int)addFunctionBindResult.mIRArgs.size(); argIdx++)
irArgs.Add(addFunctionBindResult.mIRArgs[argIdx]);
CreateCall(initExpr, addFunctionBindResult.mMethodInstance, addFunctionBindResult.mFunc, true, irArgs);
}
}
BfExprEvaluator exprEvaluator(mModule);
SizedArray<BfExpression*, 2> argExprs;
argExprs.push_back(elementExpr);
BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
BfResolvedArgs argValues(&sizedArgExprs);
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments());
wasValidInitKind = true;
}
@ -21664,30 +21655,38 @@ void BfExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr)
void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
{
BfTypedValue target;
HandleIndexerExpression(indexerExpr, BfTypedValue());
}
void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target)
{
bool wantStatic = false;
// Try first as a non-static indexer, then as a static indexer
for (int pass = 0; pass < 2; pass++)
{
///
{
SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoLookupError | BfEvalExprFlags_AllowBase), pass == 0);
VisitChild(indexerExpr->mTarget);
}
ResolveGenericType();
target = GetResult(true);
if (target)
break;
if (pass == 0)
if (!target)
{
for (int pass = 0; pass < 2; pass++)
{
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, (mModule->mIgnoreErrors) || (pass == 0));
auto staticType = mModule->ResolveTypeRef(indexerExpr->mTarget, {});
if (staticType != NULL)
///
{
wantStatic = true;
target.mType = staticType;
SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoLookupError | BfEvalExprFlags_AllowBase), pass == 0);
VisitChild(indexerExpr->mTarget);
}
ResolveGenericType();
target = GetResult(true);
if (target)
break;
if (pass == 0)
{
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, (mModule->mIgnoreErrors) || (pass == 0));
auto staticType = mModule->ResolveTypeRef(indexerExpr->mTarget, {});
if (staticType != NULL)
{
wantStatic = true;
target.mType = staticType;
break;
}
}
}
}

View file

@ -538,6 +538,7 @@ public:
void CheckDotToken(BfTokenNode* tokenNode);
void DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue);
void CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* allocType);
void HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target);
//////////////////////////////////////////////////////////////////////////

View file

@ -2093,7 +2093,12 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
}
else if (token == BfToken_LBracket)
{
exprLeft = CreateAttributedExpression(tokenNode, false);
if ((createExprFlags & CreateExprFlags_AllowAnonymousIndexer) != 0)
{
exprLeft = CreateIndexerExpression(NULL, tokenNode);
}
else
exprLeft = CreateAttributedExpression(tokenNode, false);
}
else if (token == BfToken_FatArrow)
{
@ -7570,7 +7575,7 @@ BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfAstNode* ta
BfAstNode* node = mVisitorPos.GetCurrent();
initializerExpr->mSrcEnd = node->mSrcEnd;
auto expr = CreateExpression(node);
auto expr = CreateExpression(node, BfReducer::CreateExprFlags_AllowAnonymousIndexer);
isDone = !mVisitorPos.MoveNext();
if (expr != NULL)
values.Add(expr);
@ -8167,15 +8172,24 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
return objectCreateExpr;
}
BfExpression* BfReducer::CreateIndexerExpression(BfExpression* target)
BfExpression* BfReducer::CreateIndexerExpression(BfExpression* target, BfTokenNode* openBracketNode)
{
auto tokenNode = ExpectTokenAfter(target, BfToken_LBracket, BfToken_QuestionLBracket);
auto tokenNode = openBracketNode;
if (openBracketNode == NULL)
tokenNode = ExpectTokenAfter(target, BfToken_LBracket, BfToken_QuestionLBracket);
auto indexerExpr = mAlloc->Alloc<BfIndexerExpression>();
BfDeferredAstSizedArray<BfExpression*> arguments(indexerExpr->mArguments, mAlloc);
BfDeferredAstSizedArray<BfTokenNode*> commas(indexerExpr->mCommas, mAlloc);
indexerExpr->mTarget = target;
ReplaceNode(target, indexerExpr);
if (target != NULL)
{
indexerExpr->mTarget = target;
ReplaceNode(target, indexerExpr);
}
else
{
ReplaceNode(openBracketNode, indexerExpr);
}
indexerExpr->mOpenBracket = tokenNode;
MoveNode(indexerExpr->mOpenBracket, indexerExpr);

View file

@ -27,7 +27,8 @@ public:
CreateExprFlags_NoCheckBinOpPrecedence = 0x100,
CreateExprFlags_BreakOnCascade = 0x200,
CreateExprFlags_EarlyExit = 0x400, // Don't attempt binary or ternary operations
CreateExprFlags_AllowEmpty = 0x800
CreateExprFlags_AllowEmpty = 0x800,
CreateExprFlags_AllowAnonymousIndexer = 0x1000
};
enum CreateStmtFlags
@ -206,7 +207,7 @@ public:
BfScopedInvocationTarget* CreateScopedInvocationTarget(BfAstNode*& targetRef, BfTokenNode* colonToken);
BfInvocationExpression* CreateInvocationExpression(BfAstNode* target, CreateExprFlags createExprFlags = CreateExprFlags_None);
BfInitializerExpression* TryCreateInitializerExpression(BfAstNode* target);
BfExpression* CreateIndexerExpression(BfExpression* target);
BfExpression* CreateIndexerExpression(BfExpression* target, BfTokenNode* openBracketNode = NULL);
BfMemberReferenceExpression* CreateMemberReferenceExpression(BfAstNode* target);
BfTupleExpression* CreateTupleExpression(BfTokenNode* newNode, BfExpression* innerExpr = NULL);
BfExpression* CreateExpression(BfAstNode* node, CreateExprFlags createExprFlags = CreateExprFlags_None);

View file

@ -18,7 +18,7 @@ namespace System.Collections
}
}
extension Dictionary<K, V>
extension Dictionary<TKey, TValue>
{
public static bool operator==(Self lhs, Self rhs)
{

View file

@ -420,6 +420,10 @@ namespace Tests
list.Sort();
List<float> floatList = scope .() {1, 2, 3};
Dictionary<int, String> dict = scope .() { (1, "Foo"), [2]="Bar" };
Test.Assert(dict[1] == "Foo");
Test.Assert(dict[2] == "Bar");
ClassA ca = scope .();
ClassB cb = scope .();
Test.Assert(LibA.LibA0.GetVal(ca) == 123);

View file

@ -25,9 +25,9 @@ namespace Tests
mD += (int)val2 * 10;
}
public void Add(int val)
public void Add(int val) mut
{
Test.FatalError("Shouldn't be called");
mD += (int)val * 1000;
}
}
@ -38,7 +38,7 @@ namespace Tests
Test.Assert(sa.mA == 123);
Test.Assert(sa.mB == 345);
Test.Assert(sa.mC == 456);
Test.Assert(sa.mD == 6036);
Test.Assert(sa.mD == 791907);
}
}
}