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