mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Operator '??=', '?' out discard
This commit is contained in:
parent
f3074986ea
commit
e70394bbf6
5 changed files with 63 additions and 18 deletions
|
@ -1435,6 +1435,8 @@ const char* Beefy::BfTokenToString(BfToken token)
|
||||||
return "|=";
|
return "|=";
|
||||||
case BfToken_XorEquals:
|
case BfToken_XorEquals:
|
||||||
return "^=";
|
return "^=";
|
||||||
|
case BfToken_NullCoalsceEquals:
|
||||||
|
return "??=";
|
||||||
case BfToken_LBrace:
|
case BfToken_LBrace:
|
||||||
return "{";
|
return "{";
|
||||||
case BfToken_RBrace:
|
case BfToken_RBrace:
|
||||||
|
@ -1546,6 +1548,8 @@ BfBinaryOp Beefy::BfAssignOpToBinaryOp(BfAssignmentOp assignmentOp)
|
||||||
return BfBinaryOp_BitwiseOr;
|
return BfBinaryOp_BitwiseOr;
|
||||||
case BfAssignmentOp_ExclusiveOr:
|
case BfAssignmentOp_ExclusiveOr:
|
||||||
return BfBinaryOp_ExclusiveOr;
|
return BfBinaryOp_ExclusiveOr;
|
||||||
|
case BfAssignmentOp_NullCoalesce:
|
||||||
|
return BfBinaryOp_NullCoalesce;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1789,6 +1793,8 @@ BfAssignmentOp Beefy::BfTokenToAssignmentOp(BfToken token)
|
||||||
return BfAssignmentOp_BitwiseOr;
|
return BfAssignmentOp_BitwiseOr;
|
||||||
case BfToken_XorEquals:
|
case BfToken_XorEquals:
|
||||||
return BfAssignmentOp_ExclusiveOr;
|
return BfAssignmentOp_ExclusiveOr;
|
||||||
|
case BfToken_NullCoalsceEquals:
|
||||||
|
return BfAssignmentOp_NullCoalesce;
|
||||||
default:
|
default:
|
||||||
return BfAssignmentOp_None;
|
return BfAssignmentOp_None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,6 +198,7 @@ enum BfToken : uint8
|
||||||
BfToken_PlusEquals,
|
BfToken_PlusEquals,
|
||||||
BfToken_MinusEquals,
|
BfToken_MinusEquals,
|
||||||
BfToken_MultiplyEquals,
|
BfToken_MultiplyEquals,
|
||||||
|
|
||||||
BfToken_DivideEquals,
|
BfToken_DivideEquals,
|
||||||
BfToken_ModulusEquals,
|
BfToken_ModulusEquals,
|
||||||
BfToken_ShiftLeftEquals,
|
BfToken_ShiftLeftEquals,
|
||||||
|
@ -205,6 +206,7 @@ enum BfToken : uint8
|
||||||
BfToken_AndEquals,
|
BfToken_AndEquals,
|
||||||
BfToken_OrEquals,
|
BfToken_OrEquals,
|
||||||
BfToken_XorEquals,
|
BfToken_XorEquals,
|
||||||
|
BfToken_NullCoalsceEquals,
|
||||||
BfToken_LBrace,
|
BfToken_LBrace,
|
||||||
BfToken_RBrace,
|
BfToken_RBrace,
|
||||||
BfToken_LParen,
|
BfToken_LParen,
|
||||||
|
@ -1753,7 +1755,8 @@ enum BfAssignmentOp
|
||||||
BfAssignmentOp_ShiftRight,
|
BfAssignmentOp_ShiftRight,
|
||||||
BfAssignmentOp_BitwiseAnd,
|
BfAssignmentOp_BitwiseAnd,
|
||||||
BfAssignmentOp_BitwiseOr,
|
BfAssignmentOp_BitwiseOr,
|
||||||
BfAssignmentOp_ExclusiveOr
|
BfAssignmentOp_ExclusiveOr,
|
||||||
|
BfAssignmentOp_NullCoalesce
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfUnaryOp
|
enum BfUnaryOp
|
||||||
|
|
|
@ -4382,6 +4382,11 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr
|
||||||
resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_ParamsExpr);
|
resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_ParamsExpr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (auto uninitExpr = BfNodeDynCast<BfUninitializedExpression>(argExpr))
|
||||||
|
{
|
||||||
|
resolvedArg.mArgFlags = (BfArgFlags)(resolvedArg.mArgFlags | BfArgFlag_UninitializedExpr);
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
/*else if (auto castExpr = BfNodeDynCast<BfCastExpression>(argExpr))
|
/*else if (auto castExpr = BfNodeDynCast<BfCastExpression>(argExpr))
|
||||||
{
|
{
|
||||||
|
@ -5983,11 +5988,15 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
else if (argExprIdx >= 0)
|
else if (argExprIdx >= 0)
|
||||||
{
|
{
|
||||||
BfParamKind paramKind = BfParamKind_Normal;
|
BfParamKind paramKind = BfParamKind_Normal;
|
||||||
|
BfIdentifierNode* paramNameNode = NULL;
|
||||||
if (paramIdx < methodInstance->GetParamCount())
|
if (paramIdx < methodInstance->GetParamCount())
|
||||||
|
{
|
||||||
paramKind = methodInstance->GetParamKind(paramIdx);
|
paramKind = methodInstance->GetParamKind(paramIdx);
|
||||||
|
paramNameNode = methodInstance->GetParamNameNode(paramIdx);
|
||||||
|
}
|
||||||
|
|
||||||
argValues[argExprIdx].mExpectedType = wantType;
|
argValues[argExprIdx].mExpectedType = wantType;
|
||||||
argValue = ResolveArgValue(argValues[argExprIdx], wantType, NULL, paramKind);
|
argValue = ResolveArgValue(argValues[argExprIdx], wantType, NULL, paramKind, paramNameNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6103,7 +6112,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
{
|
{
|
||||||
mModule->AssertErrorState();
|
mModule->AssertErrorState();
|
||||||
auto argValue = argValues[argIdx].mTypedValue;
|
auto argValue = argValues[argIdx].mTypedValue;
|
||||||
if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval | BfArgFlag_VariableDeclaration)) != 0)
|
if ((argValues[argIdx].mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval | BfArgFlag_VariableDeclaration | BfArgFlag_UninitializedExpr)) != 0)
|
||||||
{
|
{
|
||||||
if (!argValue)
|
if (!argValue)
|
||||||
{
|
{
|
||||||
|
@ -6364,8 +6373,8 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
||||||
|
|
||||||
static int sInvocationIdx = 0;
|
static int sInvocationIdx = 0;
|
||||||
|
|
||||||
BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue, BfParamKind paramKind)
|
BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue, BfParamKind paramKind, BfIdentifierNode* paramNameNode)
|
||||||
{
|
{
|
||||||
BfTypedValue argValue = resolvedArg.mTypedValue;
|
BfTypedValue argValue = resolvedArg.mTypedValue;
|
||||||
if ((resolvedArg.mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0)
|
if ((resolvedArg.mArgFlags & (BfArgFlag_DelegateBindAttempt | BfArgFlag_LambdaBindAttempt | BfArgFlag_UnqualifiedDotAttempt | BfArgFlag_DeferredEval)) != 0)
|
||||||
{
|
{
|
||||||
|
@ -6410,14 +6419,14 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType
|
||||||
{
|
{
|
||||||
argValue = mModule->GetDefaultTypedValue(wantType);
|
argValue = mModule->GetDefaultTypedValue(wantType);
|
||||||
}
|
}
|
||||||
else if ((resolvedArg.mArgFlags & (BfArgFlag_VariableDeclaration)) != 0)
|
else if ((resolvedArg.mArgFlags & (BfArgFlag_VariableDeclaration | BfArgFlag_UninitializedExpr)) != 0)
|
||||||
{
|
{
|
||||||
auto variableDeclaration = BfNodeDynCast<BfVariableDeclaration>(resolvedArg.mExpression);
|
auto variableDeclaration = BfNodeDynCast<BfVariableDeclaration>(resolvedArg.mExpression);
|
||||||
|
|
||||||
auto variableType = wantType;
|
auto variableType = wantType;
|
||||||
|
|
||||||
bool isLet = variableDeclaration->mTypeRef->IsExact<BfLetTypeReference>();
|
bool isLet = (variableDeclaration != NULL) && (variableDeclaration->mTypeRef->IsExact<BfLetTypeReference>());
|
||||||
bool isVar = variableDeclaration->mTypeRef->IsExact<BfVarTypeReference>();
|
bool isVar = (variableDeclaration == NULL) || (variableDeclaration->mTypeRef->IsExact<BfVarTypeReference>());
|
||||||
|
|
||||||
if (mModule->mCurMethodState->mPendingNullConditional != NULL)
|
if (mModule->mCurMethodState->mPendingNullConditional != NULL)
|
||||||
{
|
{
|
||||||
|
@ -6439,18 +6448,31 @@ BfTypedValue BfExprEvaluator::ResolveArgValue(BfResolvedArg& resolvedArg, BfType
|
||||||
variableType = refType->mElementType;
|
variableType = refType->mElementType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variableDeclaration->mInitializer != NULL)
|
if ((variableDeclaration != NULL) && (variableDeclaration->mInitializer != NULL))
|
||||||
{
|
{
|
||||||
mModule->Fail("Initializers cannot be used when declaring variables for 'out' parameters", variableDeclaration->mEqualsNode);
|
mModule->Fail("Initializers cannot be used when declaring variables for 'out' parameters", variableDeclaration->mEqualsNode);
|
||||||
mModule->CreateValueFromExpression(variableDeclaration->mInitializer, variableType, BfEvalExprFlags_NoCast);
|
mModule->CreateValueFromExpression(variableDeclaration->mInitializer, variableType, BfEvalExprFlags_NoCast);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variableDeclaration->mNameNode == NULL)
|
|
||||||
return argValue;
|
|
||||||
|
|
||||||
BfLocalVariable* localVar = new BfLocalVariable();
|
BfLocalVariable* localVar = new BfLocalVariable();
|
||||||
localVar->mName = variableDeclaration->mNameNode->ToString();
|
if ((variableDeclaration != NULL) && (variableDeclaration->mNameNode != NULL))
|
||||||
localVar->mNameNode = BfNodeDynCast<BfIdentifierNode>(variableDeclaration->mNameNode);
|
{
|
||||||
|
localVar->mName = variableDeclaration->mNameNode->ToString();
|
||||||
|
localVar->mNameNode = BfNodeDynCast<BfIdentifierNode>(variableDeclaration->mNameNode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (paramNameNode != NULL)
|
||||||
|
{
|
||||||
|
localVar->mName = "__";
|
||||||
|
paramNameNode->ToString(localVar->mName);
|
||||||
|
localVar->mName += "_";
|
||||||
|
localVar->mName += StrFormat("%d", mModule->mCurMethodState->GetRootMethodState()->mCurLocalVarId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
localVar->mName = "__" + StrFormat("%d", mModule->mCurMethodState->GetRootMethodState()->mCurLocalVarId);
|
||||||
|
}
|
||||||
|
|
||||||
localVar->mResolvedType = variableType;
|
localVar->mResolvedType = variableType;
|
||||||
if (!variableType->IsValuelessType())
|
if (!variableType->IsValuelessType())
|
||||||
localVar->mAddr = mModule->CreateAlloca(variableType);
|
localVar->mAddr = mModule->CreateAlloca(variableType);
|
||||||
|
@ -16196,6 +16218,13 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
|
||||||
if (!mModule->CanCast(rightValue, paramType))
|
if (!mModule->CanCast(rightValue, paramType))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
mModule->SetElementType(assignExpr->mOpToken, BfSourceElementType_Method);
|
||||||
|
if ((autoComplete != NULL) && (autoComplete->IsAutocompleteNode(assignExpr->mOpToken)))
|
||||||
|
{
|
||||||
|
if (operatorDef->mOperatorDeclaration != NULL)
|
||||||
|
autoComplete->SetDefinitionLocation(operatorDef->mOperatorDeclaration->mOpTypeToken);
|
||||||
|
}
|
||||||
|
|
||||||
auto moduleMethodInstance = mModule->GetMethodInstance(checkTypeInst, operatorDef, BfTypeVector());
|
auto moduleMethodInstance = mModule->GetMethodInstance(checkTypeInst, operatorDef, BfTypeVector());
|
||||||
|
|
||||||
BfExprEvaluator exprEvaluator(mModule);
|
BfExprEvaluator exprEvaluator(mModule);
|
||||||
|
|
|
@ -17,7 +17,8 @@ enum BfArgFlags
|
||||||
BfArgFlag_DeferredEval = 0x40,
|
BfArgFlag_DeferredEval = 0x40,
|
||||||
BfArgFlag_ExpectedTypeCast = 0x80,
|
BfArgFlag_ExpectedTypeCast = 0x80,
|
||||||
BfArgFlag_VariableDeclaration = 0x100,
|
BfArgFlag_VariableDeclaration = 0x100,
|
||||||
BfArgFlag_ParamsExpr = 0x200
|
BfArgFlag_ParamsExpr = 0x200,
|
||||||
|
BfArgFlag_UninitializedExpr = 0x400
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BfResolveArgFlags
|
enum BfResolveArgFlags
|
||||||
|
@ -347,7 +348,7 @@ public:
|
||||||
void ResolveGenericType();
|
void ResolveGenericType();
|
||||||
void ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgFlags flags = BfResolveArgFlag_None);
|
void ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveArgFlags flags = BfResolveArgFlag_None);
|
||||||
BfAllocTarget ResolveAllocTarget(BfAstNode* newNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes = NULL);
|
BfAllocTarget ResolveAllocTarget(BfAstNode* newNode, BfTokenNode*& newToken, BfCustomAttributes** outCustomAttributes = NULL);
|
||||||
BfTypedValue ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue = NULL, BfParamKind paramKind = BfParamKind_Normal);
|
BfTypedValue ResolveArgValue(BfResolvedArg& resolvedArg, BfType* wantType, BfTypedValue* receivingValue = NULL, BfParamKind paramKind = BfParamKind_Normal, BfIdentifierNode* paramNameNode = NULL);
|
||||||
BfMethodDef* GetPropertyMethodDef(BfPropertyDef* propDef, BfMethodType methodType, BfCheckedKind checkedKind, BfTypedValue propTarget);
|
BfMethodDef* GetPropertyMethodDef(BfPropertyDef* propDef, BfMethodType methodType, BfCheckedKind checkedKind, BfTypedValue propTarget);
|
||||||
BfModuleMethodInstance GetPropertyMethodInstance(BfMethodDef* methodDef);
|
BfModuleMethodInstance GetPropertyMethodInstance(BfMethodDef* methodDef);
|
||||||
void CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance* methodInstance, bool checkProt);
|
void CheckPropFail(BfMethodDef* propMethodDef, BfMethodInstance* methodInstance, bool checkProt);
|
||||||
|
|
|
@ -1494,8 +1494,14 @@ void BfParser::NextToken(int endIdx)
|
||||||
case '?':
|
case '?':
|
||||||
if (mSrc[mSrcIdx] == '?')
|
if (mSrc[mSrcIdx] == '?')
|
||||||
{
|
{
|
||||||
mToken = BfToken_DblQuestion;
|
|
||||||
mTokenEnd = ++mSrcIdx;
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
if (mSrc[mSrcIdx] == '=')
|
||||||
|
{
|
||||||
|
mToken = BfToken_NullCoalsceEquals;
|
||||||
|
mTokenEnd = ++mSrcIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mToken = BfToken_DblQuestion;
|
||||||
}
|
}
|
||||||
else if (mSrc[mSrcIdx] == '.')
|
else if (mSrc[mSrcIdx] == '.')
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue