/* $NetBSD: lsym_binary_op.c,v 1.12 2023/06/14 08:25:15 rillig Exp $ */

/*
* Tests for the token lsym_binary_op, which represents a binary operator in
* an expression.  Examples for binary operators are '>>', '=', '+', '&&'.
*
* Binary operators are surrounded by blanks.
*
* Some tokens like '+', '*' or '&' can be either binary or unary operators,
* with an entirely different meaning.
*
* The token '*' is not only a binary or a unary operator, it is used in types
* as well, to derive a pointer type.
*
* See also:
*      lsym_postfix_op.c       for postfix unary operators
*      lsym_unary_op.c         for prefix unary operators
*      lsym_colon.c            for ':'
*      lsym_question.c         for '?'
*      lsym_comma.c            for ','
*      C99 6.4.6               "Punctuators"
*/

//indent input
void
binary_operators(void)
{
       /* In the order of appearance in C11 6.5. */
       a = a * a;
       a = a / a;
       a = a % a;
       a = a + a;
       a = a - a;
       a = a << a;
       a = a >> a;
       a = a < a;
       a = a > a;
       a = a <= a;
       a = a >= a;
       a = a == a;
       a = a != a;
       a = a & a;
       a = a ^ a;
       a = a | a;
       a = a && a;
       a = a || a;
       a = a ? a : a;
       a = a;
       a *= a;
       a /= a;
       a %= a;
       a += a;
       a -= a;
       a <<= a;
       a >>= a;
       a &= a;
       a ^= a;
       a |= a;
       a = a, a;
}
//indent end

//indent run-equals-input


/*
* If a '*' is immediately followed by another '*', they still form separate
* operators. The first is a binary operator, the second is unary.
*/
//indent input
int var = expr**ptr;
//indent end

//indent run -di0
int var = expr * *ptr;
//indent end


/*
* Before 2023-06-04, indent allowed for arbitrary repetitions of some operator
* characters, followed by an arbitrary amount of '='.  This could be used for
* operators like '&&' or '|||==='.
*
* Before 2021-03-07 22:11:01, the comment '//' was treated as a binary
* operator as well, and so was the comment '/////', leading to unexpected
* spacing.
*
* See lexi.c, lexi, "default:".
*/
//indent input
void
long_run_of_operators(void)
{
       if (a &&&&&&& b)
               return;
       if (a |||=== b)
               return;
}
//indent end

//indent run
void
long_run_of_operators(void)
{
       if (a && && && &b)
               return;
       if (a || |= == b)
               return;
}
//indent end


/*
* Long chains of '+' and '-' must be split into several operators as the
* lexer has to distinguish between '++' and '+' early.  The following
* sequence is thus tokenized as:
*
*      word            "a"
*      postfix_op      "++"
*      binary_op       "++"
*      unary_op        "++"
*      unary_op        "+"
*      word            "b"
*
* See lexi.c, lexi, "case '+':".
*/
//indent input
void
joined_unary_and_binary_operators(void)
{
       if (a +++++++ b)
               return;
}
//indent end

//indent run
void
joined_unary_and_binary_operators(void)
{
       if (a++ ++ ++ +b)
               return;
}
//indent end


/*
* Ensure that the result of the indentation does not depend on whether a
* token from the input starts in column 1 or 9.
*
* See process_binary_op.
*/
//indent input
int col_1 //
= //
1;

int col_9 //
       = //
       9;
//indent end

//indent run
int             col_1           //
=                               //
1;

int             col_9           //
=                               //
9;
//indent end


/*
* The ternary conditional operator is not a binary operator, but both its
* components '?' and ':' follow the same spacing rules.
*/
//indent input
int conditional = condition ? number : number;
//indent end

//indent run-equals-input -di0


// After a ']', a '*' is a binary operator.
//indent input
int x = arr[3]*y;
//indent end

//indent run -di0
int x = arr[3] * y;
//indent end


/*
* Ensure that after an assignment, a '*=' operator is properly spaced, like
* any other binary operator.
*/
//indent input
{
       a = a;
       a *= b *= c;
}
//indent end

//indent run-equals-input -di0