/* $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