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