AST: assignment operators are executed from right to left

This commit is contained in:
Daniel Marjamäki 2014-05-03 12:08:42 +02:00
parent d3e8bbdc51
commit 4b7aaba159
2 changed files with 16 additions and 2 deletions

View File

@ -417,6 +417,14 @@ static void compileUnaryOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &
op.push(unaryop);
}
static bool isAssignment(const Token *tok)
{
return (tok->str() == "=" ||
tok->str() == "<<=" ||
tok->str() == ">>=" ||
(tok->str().size() == 2U && tok->str()[1] == '=' && std::strchr("+-*/%&|^",tok->str()[0])));
}
static void compileBinOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &, unsigned int depth), std::stack<Token*> &op, unsigned int depth)
{
Token *binop = tok;
@ -424,6 +432,10 @@ static void compileBinOp(Token *&tok, void (*f)(Token *&, std::stack<Token*> &,
if (tok)
f(tok,op, depth);
// Assignment operators are executed in right-to-left order
if (tok && isAssignment(binop) && isAssignment(tok))
compileBinOp(tok,f,op,depth);
// TODO: Should we check if op is empty.
// * Is it better to add assertion that it isn't?
// * Write debug warning if it's empty?
@ -714,8 +726,7 @@ static void compileAssign(Token *&tok, std::stack<Token*> &op, unsigned int dept
{
compileTernaryOp(tok,op, depth);
while (tok) {
if (tok->str() == "=" || tok->str() == "<<=" || tok->str() == ">>=" ||
(tok->str().size() == 2U && tok->str()[1] == '=' && std::strchr("+-*/%&|^",tok->str()[0]))) {
if (isAssignment(tok)) {
compileBinOp(tok, compileTernaryOp, op, depth);
} else break;
}

View File

@ -10332,6 +10332,9 @@ private:
ASSERT_EQUALS("ab|=", testAst("a|=b;"));
ASSERT_EQUALS("ab^=", testAst("a^=b;"));
// assignments are executed from right to left
ASSERT_EQUALS("abc==", testAst("a=b=c;"));
ASSERT_EQUALS("a\"\"=", testAst("a=\"\""));
ASSERT_EQUALS("a\'\'=", testAst("a=\'\'"));
testAst("char a[1]=\"\";"); // don't crash