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

Allow mixins and expression blocks to end in a ref expression

This commit is contained in:
Brian Fiete 2022-06-15 06:45:53 -07:00
parent 3cc0ba2ed6
commit 5268e103e9
6 changed files with 60 additions and 18 deletions

View file

@ -3402,6 +3402,7 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr)
}
mModule->VisitEmbeddedStatement(blockExpr, this, BfNodeIsA<BfUnscopedBlock>(blockExpr) ? BfEmbeddedStatementFlags_Unscoped : BfEmbeddedStatementFlags_None);
mResult = mModule->SanitizeAddr(mResult);
}
bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail)
@ -17164,6 +17165,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
if (!exprNode->IsA<BfBlock>())
{
// Mixin expression result
SetAndRestoreValue<BfEvalExprFlags> prevFlags(mBfEvalExprFlags, (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr));
mModule->UpdateSrcPos(exprNode);
VisitChild(exprNode);
FinishExpressionResult();
@ -17187,6 +17189,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
}
mResult = mModule->LoadValue(mResult);
mResult = mModule->SanitizeAddr(mResult);
int localIdx = startLocalIdx;
@ -19497,7 +19500,7 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
}
ResolveGenericType();
auto ptr = mResult;
auto ptr = mModule->RemoveRef(mResult);
mResult = BfTypedValue();
if (mPropDef != NULL)
@ -21569,8 +21572,7 @@ void BfExprEvaluator::PerformUnaryOperation_OnResult(BfExpression* unaryOpExpr,
if (!mResult)
return;
if (mResult.mType->IsRef())
mResult.mType = mResult.mType->GetUnderlyingType();
mResult = mModule->RemoveRef(mResult);
if (mResult.mType->IsVar())
{

View file

@ -8791,13 +8791,26 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator,
{
// Only allow a 'ref' type if we have an explicit 'ref' operator
bool allowRef = false;
BfExpression* checkExpr = expr;
while (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkExpr))
checkExpr = parenExpr->mExpression;
if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(checkExpr))
BfAstNode* checkExpr = expr;
while (checkExpr != NULL)
{
if ((unaryOp->mOp == BfUnaryOp_Ref) || (unaryOp->mOp == BfUnaryOp_Mut))
allowRef = true;
if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkExpr))
checkExpr = parenExpr->mExpression;
else if (auto unaryOp = BfNodeDynCast<BfUnaryOperatorExpression>(checkExpr))
{
if ((unaryOp->mOp == BfUnaryOp_Ref) || (unaryOp->mOp == BfUnaryOp_Mut))
allowRef = true;
break;
}
if (auto block = BfNodeDynCast<BfBlock>(checkExpr))
{
if (block->mChildArr.mSize == 0)
break;
checkExpr = block->mChildArr.back();
}
else
break;
}
if (!allowRef)
typedVal = RemoveRef(typedVal);
@ -12480,6 +12493,23 @@ BfTypedValue BfModule::RemoveRef(BfTypedValue typedValue)
return typedValue;
}
BfTypedValue BfModule::SanitizeAddr(BfTypedValue typedValue)
{
if (!typedValue)
return typedValue;
if (typedValue.mType->IsRef())
{
typedValue = LoadValue(typedValue);
auto copiedVal = BfTypedValue(CreateAlloca(typedValue.mType), typedValue.mType, true);
mBfIRBuilder->CreateStore(typedValue.mValue, copiedVal.mValue);
return copiedVal;
}
return typedValue;
}
BfTypedValue BfModule::ToRef(BfTypedValue typedValue, BfRefType* refType)
{
if (refType == NULL)

View file

@ -1700,6 +1700,7 @@ public:
void EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull);
void CheckStaticAccess(BfTypeInstance* typeInstance);
BfTypedValue RemoveRef(BfTypedValue typedValue);
BfTypedValue SanitizeAddr(BfTypedValue typedValue);
BfTypedValue ToRef(BfTypedValue typedValue, BfRefType* refType = NULL);
BfTypedValue LoadOrAggregateValue(BfTypedValue typedValue);
BfTypedValue LoadValue(BfTypedValue typedValue, BfAstNode* refNode = NULL, bool isVolatile = false);

View file

@ -4427,15 +4427,10 @@ BfAstNode* BfReducer::DoCreateStatement(BfAstNode* node, CreateStmtFlags createS
(unaryOperatorExpr->mOp == BfUnaryOp_Decrement) ||
(unaryOperatorExpr->mOp == BfUnaryOp_PostDecrement);
if ((unaryOperatorExpr->mOp == BfUnaryOp_Ref) || (unaryOperatorExpr->mOp == BfUnaryOp_Mut) || (unaryOperatorExpr->mOp == BfUnaryOp_Out))
if (unaryOperatorExpr->mOp == BfUnaryOp_Out)
{
if (unaryOperatorExpr->mOp == BfUnaryOp_Ref)
Fail("Cannot use 'ref' in this context", unaryOperatorExpr);
else if (unaryOperatorExpr->mOp == BfUnaryOp_Mut)
Fail("Cannot use 'mut' in this context", unaryOperatorExpr);
else
Fail("Cannot use 'out' in this context", unaryOperatorExpr);
return NULL;
unaryOperatorExpr->mOp = BfUnaryOp_Ref;
Fail("Cannot use 'out' in this context", unaryOperatorExpr);
}
}

View file

@ -3538,7 +3538,7 @@ void BfModule::VisitCodeBlock(BfBlock* block)
else if ((mCurMethodInstance != NULL) && (mCurMethodInstance->IsMixin()) && (mCurMethodState->mCurScope == &mCurMethodState->mHeadScope))
{
// Only in mixin definition - result ignored
CreateValueFromExpression(expr);
CreateValueFromExpression(expr, NULL, BfEvalExprFlags_AllowRefExpr);
break;
}
else