1 /* $NetBSD: lsym_binary_op.c,v 1.12 2023/06/14 08:25:15 rillig Exp $ */
2
3 /*
4 * Tests for the token lsym_binary_op, which represents a binary operator in
5 * an expression. Examples for binary operators are '>>', '=', '+', '&&'.
6 *
7 * Binary operators are surrounded by blanks.
8 *
9 * Some tokens like '+', '*' or '&' can be either binary or unary operators,
10 * with an entirely different meaning.
11 *
12 * The token '*' is not only a binary or a unary operator, it is used in types
13 * as well, to derive a pointer type.
14 *
15 * See also:
16 * lsym_postfix_op.c for postfix unary operators
17 * lsym_unary_op.c for prefix unary operators
18 * lsym_colon.c for ':'
19 * lsym_question.c for '?'
20 * lsym_comma.c for ','
21 * C99 6.4.6 "Punctuators"
22 */
23
24 //indent input
25 void
binary_operators(void)26 binary_operators(void)
27 {
28 /* In the order of appearance in C11 6.5. */
29 a = a * a;
30 a = a / a;
31 a = a % a;
32 a = a + a;
33 a = a - a;
34 a = a << a;
35 a = a >> a;
36 a = a < a;
37 a = a > a;
38 a = a <= a;
39 a = a >= a;
40 a = a == a;
41 a = a != a;
42 a = a & a;
43 a = a ^ a;
44 a = a | a;
45 a = a && a;
46 a = a || a;
47 a = a ? a : a;
48 a = a;
49 a *= a;
50 a /= a;
51 a %= a;
52 a += a;
53 a -= a;
54 a <<= a;
55 a >>= a;
56 a &= a;
57 a ^= a;
58 a |= a;
59 a = a, a;
60 }
61 //indent end
62
63 //indent run-equals-input
64
65
66 /*
67 * If a '*' is immediately followed by another '*', they still form separate
68 * operators. The first is a binary operator, the second is unary.
69 */
70 //indent input
71 int var = expr**ptr;
72 //indent end
73
74 //indent run -di0
75 int var = expr * *ptr;
76 //indent end
77
78
79 /*
80 * Before 2023-06-04, indent allowed for arbitrary repetitions of some operator
81 * characters, followed by an arbitrary amount of '='. This could be used for
82 * operators like '&&' or '|||==='.
83 *
84 * Before 2021-03-07 22:11:01, the comment '//' was treated as a binary
85 * operator as well, and so was the comment '/////', leading to unexpected
86 * spacing.
87 *
88 * See lexi.c, lexi, "default:".
89 */
90 //indent input
91 void
long_run_of_operators(void)92 long_run_of_operators(void)
93 {
94 if (a &&&&&&& b)
95 return;
96 if (a |||=== b)
97 return;
98 }
99 //indent end
100
101 //indent run
102 void
long_run_of_operators(void)103 long_run_of_operators(void)
104 {
105 if (a && && && &b)
106 return;
107 if (a || |= == b)
108 return;
109 }
110 //indent end
111
112
113 /*
114 * Long chains of '+' and '-' must be split into several operators as the
115 * lexer has to distinguish between '++' and '+' early. The following
116 * sequence is thus tokenized as:
117 *
118 * word "a"
119 * postfix_op "++"
120 * binary_op "++"
121 * unary_op "++"
122 * unary_op "+"
123 * word "b"
124 *
125 * See lexi.c, lexi, "case '+':".
126 */
127 //indent input
128 void
joined_unary_and_binary_operators(void)129 joined_unary_and_binary_operators(void)
130 {
131 if (a +++++++ b)
132 return;
133 }
134 //indent end
135
136 //indent run
137 void
joined_unary_and_binary_operators(void)138 joined_unary_and_binary_operators(void)
139 {
140 if (a++ ++ ++ +b)
141 return;
142 }
143 //indent end
144
145
146 /*
147 * Ensure that the result of the indentation does not depend on whether a
148 * token from the input starts in column 1 or 9.
149 *
150 * See process_binary_op.
151 */
152 //indent input
153 int col_1 //
154 = //
155 1;
156
157 int col_9 //
158 = //
159 9;
160 //indent end
161
162 //indent run
163 int col_1 //
164 = //
165 1;
166
167 int col_9 //
168 = //
169 9;
170 //indent end
171
172
173 /*
174 * The ternary conditional operator is not a binary operator, but both its
175 * components '?' and ':' follow the same spacing rules.
176 */
177 //indent input
178 int conditional = condition ? number : number;
179 //indent end
180
181 //indent run-equals-input -di0
182
183
184 // After a ']', a '*' is a binary operator.
185 //indent input
186 int x = arr[3]*y;
187 //indent end
188
189 //indent run -di0
190 int x = arr[3] * y;
191 //indent end
192
193
194 /*
195 * Ensure that after an assignment, a '*=' operator is properly spaced, like
196 * any other binary operator.
197 */
198 //indent input
199 {
200 a = a;
201 a *= b *= c;
202 }
203 //indent end
204
205 //indent run-equals-input -di0
206