expr.c (4004B)
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 TUINT 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 abort(); 136 137 np = node(op, l, r); 138 np->addr = addr; 139 140 return np; 141 } 142 143 static Node * 144 unaryop(int op, Node *np) 145 { 146 TUINT val; 147 148 if (np->addr != ANUMBER) 149 error("invalid argument for unary operator"); 150 if (np->op != NUMBER) { 151 np = node(op, np, NULL); 152 np->addr = ANUMBER; 153 return np; 154 } 155 156 val = np->sym->value; 157 switch (op) { 158 case '!': 159 val = !val; 160 case '+': 161 break; 162 case '-': 163 val = -val; 164 break; 165 default: 166 abort(); 167 } 168 np->sym->value = val; 169 170 return np; 171 } 172 173 /*************************************************************************/ 174 /* grammar functions */ 175 /*************************************************************************/ 176 177 static Node * 178 primary(void) 179 { 180 Node *np; 181 182 switch (yytoken) { 183 case IDEN: 184 case NUMBER: 185 np = node(yytoken, NULL, NULL); 186 np->sym = yylval.sym; 187 np->addr = ANUMBER; 188 next(); 189 break; 190 case '(': 191 np = expr(); 192 expect(')'); 193 break; 194 default: 195 unexpected(); 196 } 197 198 return np; 199 } 200 201 static Node * 202 unary(void) 203 { 204 int op, tok; 205 Node *np; 206 207 switch (tok = yytoken) { 208 case '!': 209 case '-': 210 case '+': 211 next(); 212 return unaryop(tok, primary()); 213 default: 214 return primary(); 215 } 216 } 217 218 static Node * 219 mul(void) 220 { 221 int op; 222 Node *np; 223 224 np = unary(); 225 for (;;) { 226 switch (op = yytoken) { 227 case '*': 228 case '/': 229 case '%': 230 case SHL: 231 case SHR: 232 next(); 233 binary(op, np, primary()); 234 break; 235 default: 236 return np; 237 } 238 } 239 } 240 241 static Node * 242 add(void) 243 { 244 int op; 245 Node *np; 246 247 np = mul(); 248 for (;;) { 249 switch (op = yytoken) { 250 case '+': 251 case '-': 252 next(); 253 np = binary(op, np, mul()); 254 break; 255 default: 256 return np; 257 } 258 } 259 } 260 261 static Node * 262 relational(void) 263 { 264 int op; 265 Node *np; 266 267 np = add(); 268 for (;;) { 269 switch (op = yytoken) { 270 case '<': 271 case '>': 272 case '=': 273 case GE: 274 case LE: 275 next(); 276 np = binary(op, np, add()); 277 break; 278 default: 279 return np; 280 } 281 } 282 } 283 284 static Node * 285 and(void) 286 { 287 int op; 288 Node *np; 289 290 np = relational(); 291 while (accept('&')) 292 np = binary('&', np, relational()); 293 return np; 294 } 295 296 Node * 297 expr(void) 298 { 299 int op; 300 Node *np; 301 302 regctx(0); 303 np = and(); 304 for (;;) { 305 switch (op = yytoken) { 306 case '|': 307 case '^': 308 next(); 309 np = binary(op, np, and()); 310 break; 311 default: 312 regctx(1); 313 return np; 314 } 315 } 316 }