diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index a82f7fd0..d2c54e4e 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -1068,6 +1068,7 @@ static String DbgNodeToString(BfAstNode* astNode) else if (auto condExpr = BfNodeDynCast(astNode)) { String str; + str += "( "; str += "("; str += DbgNodeToString(condExpr->mConditionExpression); str += ") ? ("; @@ -1075,6 +1076,7 @@ static String DbgNodeToString(BfAstNode* astNode) str += ") : ("; str += DbgNodeToString(condExpr->mFalseExpression); str += ")"; + str += " )"; return str; } @@ -2180,7 +2182,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat unaryOpExpr->mOp = unaryOp; unaryOpExpr->mOpToken = tokenNode; ReplaceNode(tokenNode, unaryOpExpr); - unaryOpExpr->mExpression = CreateExpressionAfter(unaryOpExpr, rhsCreateExprFlags); + // Don't attempt binary or unary operations- they will always be lower precedence + unaryOpExpr->mExpression = CreateExpressionAfter(unaryOpExpr, (CreateExprFlags)(rhsCreateExprFlags | CreateExprFlags_EarlyExit)); if (unaryOpExpr->mExpression == NULL) return NULL; MoveNode(unaryOpExpr->mExpression, unaryOpExpr); @@ -2269,7 +2272,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat if (((createExprFlags & CreateExprFlags_BreakOnRChevron) != 0) && (token == BfToken_RChevron)) return exprLeft; - + if ((token == BfToken_DblPlus) || (token == BfToken_DblMinus)) { // Post-increment, post-decrement @@ -2284,7 +2287,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat } if (token == BfToken_As) - { + { auto dynCastExpr = mAlloc->Alloc(); ReplaceNode(exprLeft, dynCastExpr); dynCastExpr->mTarget = exprLeft; @@ -2298,7 +2301,7 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat } if (token == BfToken_Is) - { + { auto checkTypeExpr = mAlloc->Alloc(); ReplaceNode(exprLeft, checkTypeExpr); checkTypeExpr->mTarget = exprLeft; @@ -2314,6 +2317,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat if (token == BfToken_Question) { + if ((createExprFlags & CreateExprFlags_EarlyExit) != 0) + return exprLeft; auto conditionExpr = mAlloc->Alloc(); ReplaceNode(exprLeft, conditionExpr); conditionExpr->mConditionExpression = exprLeft; @@ -2340,6 +2345,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat if ((token == BfToken_Case) && ((createExprFlags & CreateStmtFlags_NoCaseExpr) == 0)) { + if ((createExprFlags & CreateExprFlags_EarlyExit) != 0) + return exprLeft; // If we have a ".Member case " expression, that is an invalid construct. We bail out here // because it allows the ".Member" to autocomplete because we will treat it as a full expression instead // of making it the target of an illegal expression @@ -2581,6 +2588,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat BfBinaryOp binOp = BfTokenToBinaryOp(tokenNode->GetToken()); if (binOp != BfBinaryOp_None) { + if ((createExprFlags & CreateExprFlags_EarlyExit) != 0) + return exprLeft; auto binOpExpression = mAlloc->Alloc(); ReplaceNode(exprLeft, binOpExpression); binOpExpression->mLeft = exprLeft; @@ -2605,6 +2614,8 @@ BfExpression* BfReducer::CreateExpression(BfAstNode* node, CreateExprFlags creat auto assignmentOp = BfTokenToAssignmentOp(tokenNode->GetToken()); if (assignmentOp != BfAssignmentOp_None) { + if ((createExprFlags & CreateExprFlags_EarlyExit) != 0) + return exprLeft; if ((createExprFlags & CreateExprFlags_NoAssignment) != 0) return exprLeft; diff --git a/IDEHelper/Compiler/BfReducer.h b/IDEHelper/Compiler/BfReducer.h index f3638140..d134ac2a 100644 --- a/IDEHelper/Compiler/BfReducer.h +++ b/IDEHelper/Compiler/BfReducer.h @@ -25,7 +25,8 @@ public: CreateExprFlags_ExitOnBang = 0x40, CreateExprFlags_ExitOnParenExpr = 0x80, CreateExprFlags_NoCheckBinOpPrecedence = 0x100, - CreateExprFlags_BreakOnCascade = 0x200 + CreateExprFlags_BreakOnCascade = 0x200, + CreateExprFlags_EarlyExit = 0x400 // Don't attempt binary or ternary operations }; enum CreateStmtFlags