1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-16 23:34:10 +02:00

Improved ambiguous (a*b, c*d) tuple parse

This commit is contained in:
Brian Fiete 2022-06-24 09:25:43 -07:00
parent 7063959762
commit 48635c1939
5 changed files with 93 additions and 12 deletions

View file

@ -19262,6 +19262,8 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE
DeferredTupleAssignData::Entry entry; DeferredTupleAssignData::Entry entry;
entry.mExprEvaluator = NULL; entry.mExprEvaluator = NULL;
entry.mInnerTuple = NULL; entry.mInnerTuple = NULL;
entry.mVarType = NULL;
entry.mVarNameNode = NULL;
BfExpression* valueExpr = tupleExpr->mValues[valueIdx]; BfExpression* valueExpr = tupleExpr->mValues[valueIdx];
entry.mExpr = valueExpr; entry.mExpr = valueExpr;
@ -19295,6 +19297,23 @@ void BfExprEvaluator::PopulateDeferrredTupleAssignData(BfTupleExpression* tupleE
if (resultType == NULL) if (resultType == NULL)
resultType = mModule->GetPrimitiveType(BfTypeCode_Var); resultType = mModule->GetPrimitiveType(BfTypeCode_Var);
} }
entry.mVarType = resultType;
}
if (auto binOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>(valueExpr))
{
if (binOpExpr->mOp == BfBinaryOp_Multiply)
{
SetAndRestoreValue<bool> prevIgnoreError(mModule->mIgnoreErrors, true);
auto resolvedType = mModule->ResolveTypeRef(binOpExpr->mLeft, NULL);
prevIgnoreError.Restore();
if (resolvedType != NULL)
{
resultType = mModule->CreatePointerType(resolvedType);
entry.mVarType = resultType;
entry.mVarNameNode = binOpExpr->mRight;
}
}
} }
if (resultType == NULL) if (resultType == NULL)
@ -19383,11 +19402,19 @@ void BfExprEvaluator::AssignDeferrredTupleAssignData(BfAssignmentExpression* ass
} }
} }
if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(child.mExpr)) if (child.mVarType != NULL)
{ {
if (!elementValue) if (auto varDecl = BfNodeDynCast<BfVariableDeclaration>(child.mExpr))
elementValue = mModule->GetDefaultTypedValue(fieldInstance->GetResolvedType()); {
mModule->HandleVariableDeclaration(varDecl, elementValue); if (!elementValue)
elementValue = mModule->GetDefaultTypedValue(fieldInstance->GetResolvedType());
mModule->HandleVariableDeclaration(varDecl, elementValue);
}
else
{
// This handles the 'a*b' disambiguated variable decl case
mModule->HandleVariableDeclaration(child.mVarType, child.mVarNameNode, elementValue);
}
} }
} }
} }

View file

@ -341,6 +341,8 @@ struct DeferredTupleAssignData
struct Entry struct Entry
{ {
BfExpression* mExpr; BfExpression* mExpr;
BfType* mVarType;
BfAstNode* mVarNameNode;
BfExprEvaluator* mExprEvaluator; BfExprEvaluator* mExprEvaluator;
DeferredTupleAssignData* mInnerTuple; DeferredTupleAssignData* mInnerTuple;
}; };

View file

@ -1893,6 +1893,7 @@ public:
BfTypedValue HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& tagVal, BfEnumCaseBindExpression* bindExpr, BfIRBlock* eqBlock = NULL, BfIRBlock* notEqBlock = NULL, BfIRBlock* matchBlock = NULL, int* outEnumIdx = NULL); BfTypedValue HandleCaseBind(BfTypedValue enumVal, const BfTypedValue& tagVal, BfEnumCaseBindExpression* bindExpr, BfIRBlock* eqBlock = NULL, BfIRBlock* notEqBlock = NULL, BfIRBlock* matchBlock = NULL, int* outEnumIdx = NULL);
void TryInitVar(BfAstNode* checkNode, BfLocalVariable* varDecl, BfTypedValue initValue, BfTypedValue& checkResult); void TryInitVar(BfAstNode* checkNode, BfLocalVariable* varDecl, BfTypedValue initValue, BfTypedValue& checkResult);
BfLocalVariable* HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfExprEvaluator* exprEvaluator = NULL); BfLocalVariable* HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfExprEvaluator* exprEvaluator = NULL);
BfLocalVariable* HandleVariableDeclaration(BfType* type, BfAstNode* nameNode, BfTypedValue val, bool updateSrcLoc = true, bool forceAddr = false);
BfLocalVariable* HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfTypedValue val, bool updateSrcLoc = true, bool forceAddr = false); BfLocalVariable* HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfTypedValue val, bool updateSrcLoc = true, bool forceAddr = false);
void CheckVariableDef(BfLocalVariable* variableDef); void CheckVariableDef(BfLocalVariable* variableDef);
BfScopeData* FindScope(BfAstNode* scopeName, BfMixinState* curMixinState, bool allowAcrossDeferredBlock); BfScopeData* FindScope(BfAstNode* scopeName, BfMixinState* curMixinState, bool allowAcrossDeferredBlock);

View file

@ -1598,14 +1598,6 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat
if (isTuple) if (isTuple)
isLocalVariable = true; isLocalVariable = true;
} }
else if (endingToken == BfToken_Star)
{
// Check spacing for "a* b" to determine if it's a pointer definition or a multiply
auto beforeStarNode = mVisitorPos.Get(outEndNode - 2);
if ((endingTokenNode->GetSrcStart() == beforeStarNode->GetSrcEnd()) &&
(identifierNode->GetSrcStart() > endingTokenNode->GetSrcEnd()))
isLocalVariable = true;
}
else if ((endingToken != BfToken_Star) && (endingToken != BfToken_Question)) else if ((endingToken != BfToken_Star) && (endingToken != BfToken_Question))
isLocalVariable = true; isLocalVariable = true;
} }

View file

@ -1932,6 +1932,40 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
return localVar; return localVar;
} }
BfLocalVariable* BfModule::HandleVariableDeclaration(BfType* type, BfAstNode* nameNode, BfTypedValue val, bool updateSrcLoc, bool forceAddr)
{
BfLocalVariable* localDef = new BfLocalVariable();
nameNode->ToString(localDef->mName);
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(nameNode);
localDef->mResolvedType = type;
localDef->mAssignedKind = BfLocalVarAssignKind_Unconditional;
localDef->mValue = val.mValue;
if ((!localDef->mIsReadOnly) || (mHasFullDebugInfo))
{
localDef->mAddr = AllocLocalVariable(localDef->mResolvedType, localDef->mName);
if ((val.mValue) && (!localDef->mResolvedType->IsValuelessType()) && (!localDef->mResolvedType->IsVar()))
{
if (localDef->mResolvedType->IsRef())
val = MakeAddressable(val, true, true);
if (val.IsSplat())
{
AggregateSplatIntoAddr(val, localDef->mAddr);
}
else
mBfIRBuilder->CreateAlignedStore(val.mValue, localDef->mAddr, localDef->mResolvedType->mAlign);
}
}
CheckVariableDef(localDef);
if (nameNode->GetSourceData() != NULL)
UpdateSrcPos(nameNode);
localDef->Init();
return AddLocalVariableDef(localDef, true);
}
BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfTypedValue val, bool updateSrcLoc, bool forceAddr) BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varDecl, BfTypedValue val, bool updateSrcLoc, bool forceAddr)
{ {
if (varDecl->mEqualsNode != NULL) if (varDecl->mEqualsNode != NULL)
@ -2337,6 +2371,31 @@ void BfModule::HandleCaseEnumMatch_Tuple(BfTypedValue tupleVal, const BfSizedArr
continue; continue;
} }
if (auto binOpExpr = BfNodeDynCast<BfBinaryOperatorExpression>(expr))
{
if (binOpExpr->mOp == BfBinaryOp_Multiply)
{
SetAndRestoreValue<bool> prevIgnoreError(mIgnoreErrors, true);
auto resolvedType = ResolveTypeRef(binOpExpr->mLeft, NULL);
prevIgnoreError.Restore();
if (resolvedType != NULL)
{
resolvedType = CreatePointerType(resolvedType);
PopulateType(tupleElement.mType);
tupleElement = LoadValue(tupleElement);
tupleElement = Cast(binOpExpr->mLeft, tupleElement, resolvedType);
if (prevHadFallthrough)
Fail("Destructuring cannot be used when the previous case contains a fallthrough", expr);
auto localVar = HandleVariableDeclaration(resolvedType, binOpExpr->mRight, tupleElement, false, true);
localVar->mReadFromId = 0; // Don't give usage errors for binds
continue;
}
}
}
if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr)) if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(expr))
{ {
continue; continue;