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