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:
parent
ac6f58f118
commit
596dd2401d
7 changed files with 85 additions and 66 deletions
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue