1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Argument cascades

This commit is contained in:
Brian Fiete 2021-01-02 08:11:07 -08:00
parent 0692fb44a4
commit 2dbcca8ca4
8 changed files with 98 additions and 8 deletions

View file

@ -1672,6 +1672,7 @@ const char* Beefy::BfGetOpName(BfUnaryOp unaryOp)
case BfUnaryOp_Out: return "out"; case BfUnaryOp_Out: return "out";
case BfUnaryOp_Mut: return "mut"; case BfUnaryOp_Mut: return "mut";
case BfUnaryOp_Params: return "params"; case BfUnaryOp_Params: return "params";
case BfUnaryOp_Cascade: return "..";
default: return "???"; default: return "???";
} }
} }
@ -1759,6 +1760,8 @@ BfUnaryOp Beefy::BfTokenToUnaryOp(BfToken token)
return BfUnaryOp_Out; return BfUnaryOp_Out;
case BfToken_Params: case BfToken_Params:
return BfUnaryOp_Params; return BfUnaryOp_Params;
case BfToken_DotDot:
return BfUnaryOp_Cascade;
default: default:
return BfUnaryOp_None; return BfUnaryOp_None;
} }

View file

@ -1834,7 +1834,8 @@ enum BfUnaryOp
BfUnaryOp_Ref, BfUnaryOp_Ref,
BfUnaryOp_Out, BfUnaryOp_Out,
BfUnaryOp_Mut, BfUnaryOp_Mut,
BfUnaryOp_Params, BfUnaryOp_Params,
BfUnaryOp_Cascade
}; };
class BfTokenNode : public BfAstNode class BfTokenNode : public BfAstNode

View file

@ -4616,8 +4616,7 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr
SizedArray<BfExpression*, 8> deferredArgs; SizedArray<BfExpression*, 8> deferredArgs;
int argIdx = 0; int argIdx = 0;
//for (int argIdx = 0; argIdx < argCount ; argIdx++)
while (true) while (true)
{ {
//printf("Args: %p %p %d\n", resolvedArgs.mArguments, resolvedArgs.mArguments->mVals, resolvedArgs.mArguments->mSize); //printf("Args: %p %p %d\n", resolvedArgs.mArguments, resolvedArgs.mArguments->mVals, resolvedArgs.mArguments->mSize);
@ -4683,6 +4682,15 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr
} }
} }
if (auto unaryOpExpr = BfNodeDynCastExact<BfUnaryOperatorExpression>(argExpr))
{
if (unaryOpExpr->mOp == BfUnaryOp_Cascade)
{
resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_Cascade);
argExpr = unaryOpExpr->mExpression;
}
}
bool deferParamEval = false; bool deferParamEval = false;
if ((flags & BfResolveArgsFlag_DeferParamEval) != 0) if ((flags & BfResolveArgsFlag_DeferParamEval) != 0)
{ {
@ -5899,6 +5907,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
BF_ASSERT(returnType->IsInterface()); BF_ASSERT(returnType->IsInterface());
}*/ }*/
Array<BfTypedValue> argCascades;
BfTypedValue target = inTarget; BfTypedValue target = inTarget;
if (!skipThis) if (!skipThis)
@ -6607,6 +6616,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
argValue = mModule->LoadValue(argValue); argValue = mModule->LoadValue(argValue);
} }
if ((argExprIdx != -1) && (argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_Cascade) != 0))
argCascades.Add(argValue);
if (expandedParamsArray) if (expandedParamsArray)
{ {
@ -6773,8 +6784,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
} }
auto func = moduleMethodInstance.mFunc; auto func = moduleMethodInstance.mFunc;
BfTypedValue result = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs); BfTypedValue callResult = CreateCall(targetSrc, methodInstance, func, bypassVirtual, irArgs);
return result;
if (argCascades.mSize == 1)
return argCascades[0];
if (argCascades.mSize > 1)
return mModule->CreateTuple(argCascades, {});
return callResult;
} }
BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue) BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly, bool allowAppendAlloc, BfTypedValue* appendIndexValue)
@ -19376,7 +19393,11 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
} }
} }
break; break;
case BfUnaryOp_Cascade:
{
mModule->Fail("Illegal use of argument cascade expression", opToken);
}
break;
default: default:
mModule->Fail("INTERNAL ERROR: Unhandled unary operator", unaryOpExpr); mModule->Fail("INTERNAL ERROR: Unhandled unary operator", unaryOpExpr);
break; break;

View file

@ -20,7 +20,8 @@ enum BfArgFlags
BfArgFlag_ParamsExpr = 0x200, BfArgFlag_ParamsExpr = 0x200,
BfArgFlag_UninitializedExpr = 0x400, BfArgFlag_UninitializedExpr = 0x400,
BfArgFlag_StringInterpolateFormat = 0x800, BfArgFlag_StringInterpolateFormat = 0x800,
BfArgFlag_StringInterpolateArg = 0x1000 BfArgFlag_StringInterpolateArg = 0x1000,
BfArgFlag_Cascade = 0x2000
}; };
enum BfResolveArgsFlags enum BfResolveArgsFlags

View file

@ -13830,6 +13830,29 @@ void BfModule::CreateDIRetVal()
} }
} }
BfTypedValue BfModule::CreateTuple(const Array<BfTypedValue>& values, const Array<String>& fieldNames)
{
BfTypeVector fieldTypes;
for (auto arg : values)
fieldTypes.Add(arg.mType);
auto tupleType = CreateTupleType(fieldTypes, fieldNames);
auto tupleTypedValue = BfTypedValue(CreateAlloca(tupleType), tupleType, true);
for (int fieldIdx = 0; fieldIdx < tupleType->mFieldInstances.size(); fieldIdx++)
{
auto& fieldInstance = tupleType->mFieldInstances[fieldIdx];
if (fieldInstance.mDataIdx <= 0)
continue;
auto typedVal = values[fieldIdx];
typedVal = LoadOrAggregateValue(typedVal);
mBfIRBuilder->CreateAlignedStore(typedVal.mValue, mBfIRBuilder->CreateInBoundsGEP(tupleTypedValue.mValue, 0, fieldInstance.mDataIdx), typedVal.mType->mAlign);
}
return tupleTypedValue;
}
void BfModule::CheckVariableDef(BfLocalVariable* variableDef) void BfModule::CheckVariableDef(BfLocalVariable* variableDef)
{ {
if (variableDef->mName.IsEmpty()) if (variableDef->mName.IsEmpty())

View file

@ -1737,6 +1737,7 @@ public:
bool TryLocalVariableInit(BfLocalVariable* localVar); bool TryLocalVariableInit(BfLocalVariable* localVar);
void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit); void LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit);
void CreateDIRetVal(); void CreateDIRetVal();
BfTypedValue CreateTuple(const Array<BfTypedValue>& values, const Array<String>& fieldNames);
void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType); void CheckTupleVariableDeclaration(BfTupleExpression* tupleExpr, BfType* initType);
void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, BfTupleExpression* tupleExpr, BfTypedValue initTupleValue, bool isReadOnly, bool isConst, bool forceAddr, BfIRBlock* declBlock = NULL); void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, BfTupleExpression* tupleExpr, BfTypedValue initTupleValue, bool isReadOnly, bool isConst, bool forceAddr, BfIRBlock* declBlock = NULL);
void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl); void HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl);

View file

@ -2250,8 +2250,15 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
unaryOpExpr->mOp = unaryOp; unaryOpExpr->mOp = unaryOp;
unaryOpExpr->mOpToken = tokenNode; unaryOpExpr->mOpToken = tokenNode;
ReplaceNode(tokenNode, unaryOpExpr); ReplaceNode(tokenNode, unaryOpExpr);
CreateExprFlags innerFlags = (CreateExprFlags)(rhsCreateExprFlags | CreateExprFlags_EarlyExit);
if (unaryOp == BfUnaryOp_Cascade)
{
innerFlags = (CreateExprFlags)(innerFlags | (createExprFlags & CreateExprFlags_AllowVariableDecl));
}
// Don't attempt binary or unary operations- they will always be lower precedence // Don't attempt binary or unary operations- they will always be lower precedence
unaryOpExpr->mExpression = CreateExpressionAfter(unaryOpExpr, (CreateExprFlags)(rhsCreateExprFlags | CreateExprFlags_EarlyExit)); unaryOpExpr->mExpression = CreateExpressionAfter(unaryOpExpr, innerFlags);
if (unaryOpExpr->mExpression == NULL) if (unaryOpExpr->mExpression == NULL)
return NULL; return NULL;
MoveNode(unaryOpExpr->mExpression, unaryOpExpr); MoveNode(unaryOpExpr->mExpression, unaryOpExpr);

View file

@ -0,0 +1,33 @@
using System;
namespace Tests
{
class Cascades
{
public static void MethodA(int a, float b)
{
}
public static void MethodB(int a, out float b)
{
b = 100;
}
[Test]
public static void TestBasics()
{
int a = MethodA(.. 12, 2.3f);
Test.Assert(a == 12);
var (b, c) = MethodA(.. 12, .. 2.3f);
Test.Assert(b == 12);
Test.Assert(c == 2.3f);
var d = MethodA(.. 12, .. 2.3f);
Test.Assert(d == (12, 2.3f));
var f = ref MethodB(12, .. var e);
e += 23;
Test.Assert(e == (int)123);
Test.Assert(f == (int)123);
}
}
}