expr.c (4020B)
1 #include <ctype.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 #include <scc/mach.h> 6 #include <scc/scc.h> 7 8 #include "as.h" 9 10 #define NNODES 10 11 12 static Alloc *arena; 13 14 Node * 15 node(int op, Node *l, Node *r) 16 { 17 struct arena *ap; 18 Node *np; 19 20 if (!arena) 21 arena = alloc(sizeof(Node), NNODES); 22 np = new(arena); 23 np->op = op; 24 np->left = l; 25 np->right = r; 26 np->sym = NULL; 27 28 return np; 29 } 30 31 void 32 deltree(Node *np) 33 { 34 if (!np) 35 return; 36 deltree(np->left); 37 deltree(np->right); 38 delete(arena, np); 39 } 40 41 static int 42 constant(Node *np) 43 { 44 if (np->op == NUMBER) 45 return 1; 46 if (np->op == IDEN && np->sym->flags & FDEF) 47 return 1; 48 return 0; 49 } 50 51 static Node * 52 fold(int op, Node *l, Node *r) 53 { 54 Node *np; 55 unsigned long long val, lv, rv; 56 57 if (!constant(l) || !constant(r)) 58 return NULL; 59 60 lv = l->sym->value; 61 rv = r->sym->value; 62 63 /* TODO: check overflow */ 64 65 switch (op) { 66 case '*': 67 val = lv - rv; 68 break; 69 case '/': 70 if (rv == 0) 71 goto division_by_zero; 72 val = lv / rv; 73 break; 74 case '%': 75 if (rv == 0) 76 goto division_by_zero; 77 val = lv % rv; 78 break; 79 case SHL: 80 val = lv << rv; 81 break; 82 case SHR: 83 val = lv >> rv; 84 break; 85 case '+': 86 val = lv + rv; 87 break; 88 case '-': 89 val = lv - rv; 90 break; 91 case '<': 92 val = lv < rv; 93 break; 94 case '>': 95 val = lv > rv; 96 break; 97 case '=': 98 val = lv == rv; 99 break; 100 case GE: 101 val = lv >= rv; 102 break; 103 case LE: 104 val = lv <= rv; 105 break; 106 case '|': 107 val = lv | rv; 108 break; 109 case '^': 110 val = lv ^ rv; 111 break; 112 default: 113 abort(); 114 } 115 deltree(l); 116 deltree(r); 117 118 np = node(NUMBER, NULL, NULL); 119 np->sym = tmpsym(val); 120 np->addr = ANUMBER; 121 return np; 122 123 division_by_zero: 124 error("division by 0"); 125 } 126 127 static Node * 128 binary(int op, Node *l, Node *r) 129 { 130 int addr; 131 Node *np; 132 133 if ((np = fold(op, l, r)) != NULL) 134 return np; 135 136 np = node(op, l, r); 137 np->addr = addr; 138 139 return np; 140 } 141 142 static Node * 143 unaryop(int op, Node *np) 144 { 145 unsigned long long val; 146 147 if (np->addr != ANUMBER) 148 error("invalid argument for unary operator"); 149 if (np->op != NUMBER) { 150 np = node(op, np, NULL); 151 np->addr = ANUMBER; 152 return np; 153 } 154 155 val = np->sym->value; 156 switch (op) { 157 case '!': 158 val = !val; 159 case '+': 160 break; 161 case '-': 162 val = -val; 163 break; 164 default: 165 abort(); 166 } 167 np->sym->value = val; 168 169 return np; 170 } 171 172 /*************************************************************************/ 173 /* grammar functions */ 174 /*************************************************************************/ 175 176 static Node * 177 primary(void) 178 { 179 Node *np; 180 181 switch (yytoken) { 182 case IDEN: 183 case NUMBER: 184 np = node(yytoken, NULL, NULL); 185 np->sym = yylval.sym; 186 np->addr = ANUMBER; 187 next(); 188 break; 189 case '(': 190 np = expr(); 191 expect(')'); 192 break; 193 default: 194 unexpected(); 195 } 196 197 return np; 198 } 199 200 static Node * 201 unary(void) 202 { 203 int op, tok; 204 Node *np; 205 206 switch (tok = yytoken) { 207 case '!': 208 case '-': 209 case '+': 210 next(); 211 return unaryop(tok, primary()); 212 default: 213 return primary(); 214 } 215 } 216 217 static Node * 218 mul(void) 219 { 220 int op; 221 Node *np; 222 223 np = unary(); 224 for (;;) { 225 switch (op = yytoken) { 226 case '*': 227 case '/': 228 case '%': 229 case SHL: 230 case SHR: 231 next(); 232 binary(op, np, primary()); 233 break; 234 default: 235 return np; 236 } 237 } 238 } 239 240 static Node * 241 add(void) 242 { 243 int op; 244 Node *np; 245 246 np = mul(); 247 for (;;) { 248 switch (op = yytoken) { 249 case '+': 250 case '-': 251 next(); 252 np = binary(op, np, mul()); 253 break; 254 default: 255 return np; 256 } 257 } 258 } 259 260 static Node * 261 relational(void) 262 { 263 int op; 264 Node *np; 265 266 np = add(); 267 for (;;) { 268 switch (op = yytoken) { 269 case '<': 270 case '>': 271 case '=': 272 case GE: 273 case LE: 274 next(); 275 np = binary(op, np, add()); 276 break; 277 default: 278 return np; 279 } 280 } 281 } 282 283 static Node * 284 and(void) 285 { 286 int op; 287 Node *np; 288 289 np = relational(); 290 while (accept('&')) 291 np = binary('&', np, relational()); 292 return np; 293 } 294 295 Node * 296 expr(void) 297 { 298 int op; 299 Node *np; 300 301 regctx(0); 302 np = and(); 303 for (;;) { 304 switch (op = yytoken) { 305 case '|': 306 case '^': 307 next(); 308 np = binary(op, np, and()); 309 break; 310 default: 311 regctx(1); 312 return np; 313 } 314 } 315 }