1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48: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); BfTypedValue initValue = GetResult(true);
bool isFirstAdd = true; bool isFirstAdd = true;
BfFunctionBindResult addFunctionBindResult;
addFunctionBindResult.mWantsArgs = true;
for (auto elementExpr : initExpr->mValues) for (auto elementExpr : initExpr->mValues)
{ {
@ -11604,6 +11602,26 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
findName.c_str()), identifierNode); 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 else
{ {
@ -11622,40 +11640,13 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
} }
} }
bool wasFirstAdd = isFirstAdd; BfExprEvaluator exprEvaluator(mModule);
if (isFirstAdd) SizedArray<BfExpression*, 2> argExprs;
{ argExprs.push_back(elementExpr);
BfExprEvaluator exprEvaluator(mModule); BfSizedArray<BfExpression*> sizedArgExprs(argExprs);
exprEvaluator.mFunctionBindResult = &addFunctionBindResult; BfResolvedArgs argValues(&sizedArgExprs);
SizedArray<BfExpression*, 2> argExprs; exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
argExprs.push_back(elementExpr); exprEvaluator.MatchMethod(elementExpr, NULL, initValue, false, false, "Add", argValues, BfMethodGenericArguments());
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);
}
}
wasValidInitKind = true; wasValidInitKind = true;
} }
@ -21664,30 +21655,38 @@ void BfExprEvaluator::Visit(BfMemberReferenceExpression* memberRefExpr)
void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr) void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
{ {
BfTypedValue target; HandleIndexerExpression(indexerExpr, BfTypedValue());
}
void BfExprEvaluator::HandleIndexerExpression(BfIndexerExpression* indexerExpr, BfTypedValue target)
{
bool wantStatic = false; bool wantStatic = false;
// Try first as a non-static indexer, then as a static indexer // 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; SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_NoLookupError | BfEvalExprFlags_AllowBase), pass == 0);
target.mType = staticType; VisitChild(indexerExpr->mTarget);
}
ResolveGenericType();
target = GetResult(true);
if (target)
break; 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 CheckDotToken(BfTokenNode* tokenNode);
void DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue); void DoMemberReference(BfMemberReferenceExpression* memberRefExpr, BfTypedValue* outCascadeValue);
void CreateObject(BfObjectCreateExpression* objCreateExpr, BfAstNode* allocNode, BfType* allocType); 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) 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) else if (token == BfToken_FatArrow)
{ {
@ -7570,7 +7575,7 @@ BfInitializerExpression* BfReducer::TryCreateInitializerExpression(BfAstNode* ta
BfAstNode* node = mVisitorPos.GetCurrent(); BfAstNode* node = mVisitorPos.GetCurrent();
initializerExpr->mSrcEnd = node->mSrcEnd; initializerExpr->mSrcEnd = node->mSrcEnd;
auto expr = CreateExpression(node); auto expr = CreateExpression(node, BfReducer::CreateExprFlags_AllowAnonymousIndexer);
isDone = !mVisitorPos.MoveNext(); isDone = !mVisitorPos.MoveNext();
if (expr != NULL) if (expr != NULL)
values.Add(expr); values.Add(expr);
@ -8167,15 +8172,24 @@ BfObjectCreateExpression* BfReducer::CreateObjectCreateExpression(BfAstNode* all
return objectCreateExpr; 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>(); auto indexerExpr = mAlloc->Alloc<BfIndexerExpression>();
BfDeferredAstSizedArray<BfExpression*> arguments(indexerExpr->mArguments, mAlloc); BfDeferredAstSizedArray<BfExpression*> arguments(indexerExpr->mArguments, mAlloc);
BfDeferredAstSizedArray<BfTokenNode*> commas(indexerExpr->mCommas, mAlloc); BfDeferredAstSizedArray<BfTokenNode*> commas(indexerExpr->mCommas, mAlloc);
indexerExpr->mTarget = target; if (target != NULL)
ReplaceNode(target, indexerExpr); {
indexerExpr->mTarget = target;
ReplaceNode(target, indexerExpr);
}
else
{
ReplaceNode(openBracketNode, indexerExpr);
}
indexerExpr->mOpenBracket = tokenNode; indexerExpr->mOpenBracket = tokenNode;
MoveNode(indexerExpr->mOpenBracket, indexerExpr); MoveNode(indexerExpr->mOpenBracket, indexerExpr);

View file

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

View file

@ -420,6 +420,10 @@ namespace Tests
list.Sort(); list.Sort();
List<float> floatList = scope .() {1, 2, 3}; 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 .(); ClassA ca = scope .();
ClassB cb = scope .(); ClassB cb = scope .();
Test.Assert(LibA.LibA0.GetVal(ca) == 123); Test.Assert(LibA.LibA0.GetVal(ca) == 123);

View file

@ -25,9 +25,9 @@ namespace Tests
mD += (int)val2 * 10; 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.mA == 123);
Test.Assert(sa.mB == 345); Test.Assert(sa.mB == 345);
Test.Assert(sa.mC == 456); Test.Assert(sa.mC == 456);
Test.Assert(sa.mD == 6036); Test.Assert(sa.mD == 791907);
} }
} }
} }