1 1.12 rillig /* $NetBSD: lsym_binary_op.c,v 1.12 2023/06/14 08:25:15 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.12 rillig * See process_binary_op. 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