1 #include <lib9.h> 2 #include <bio.h> 3 #include <ctype.h> 4 #include "mach.h" 5 #define Extern extern 6 #include "acid.h" 7 8 static int fsize[] = 9 { 10 0,0,0,0,0,0,0,0, /* 0-7 */ 11 0,0,0,0,0,0,0,0, /* 8-15 */ 12 0,0,0,0,0,0,0,0, /* 16-23 */ 13 0,0,0,0,0,0,0,0, /* 24-31 */ 14 0,0,0,0,0,0,0,0, /* 32-39 */ 15 0,0,0,0,0,0,0,0, /* 40-47 */ 16 0,0,0,0,0,0,0,0, /* 48-55 */ 17 0,0,0,0,0,0,0,0, /* 56-63 */ 18 0, /* 64 */ 19 4, /* 65 ['A'] 4, */ 20 4, /* 66 ['B'] 4, */ 21 1, /* 67 ['C'] 1, */ 22 4, /* 68 ['D'] 4, */ 23 0, /* 69 */ 24 8, /* 70 ['F'] 8, */ 25 8, /* 71 ['G'] 8, */ 26 0,0,0,0,0,0,0, /* 72-78 */ 27 4, /* 79 ['O'] 4, */ 28 0, /* 80 */ 29 4, /* 81 ['Q'] 4, */ 30 4, /* 82 ['R'] 4, */ 31 4, /* 83 ['S'] 4, */ 32 0, /* 84 */ 33 4, /* 85 ['U'] 4, */ 34 8, /* 86 ['V'] 8, */ 35 0, /* 87 */ 36 4, /* 88 ['X'] 4, */ 37 8, /* 89 ['Y'] 8, */ 38 8, /* 90 ['Z'] 8, */ 39 0,0,0,0,0,0, /* 91-96 */ 40 4, /* 97 ['a'] 4, */ 41 1, /* 98 ['b'] 1, */ 42 1, /* 99 ['c'] 1, */ 43 2, /* 100 ['d'] 2, */ 44 0, /* 101 */ 45 4, /* 102 ['f'] 4, */ 46 4, /* 103 ['g'] 4, */ 47 0,0,0,0,0,0,0, /* 104-110 */ 48 2, /* 111 ['o'] 2, */ 49 0, /* 112 */ 50 2, /* 113 ['q'] 2, */ 51 2, /* 114 ['r'] 2, */ 52 4, /* 115 ['s'] 4, */ 53 0, /* 116 */ 54 2, /* 117 ['u'] 2, */ 55 0,0, /* 118-119 */ 56 2, /* 120 ['x'] 2, */ 57 }; 58 59 int 60 fmtsize(Value *v) 61 { 62 int ret; 63 64 switch(v->vstore.fmt) { 65 default: 66 return fsize[v->vstore.fmt]; 67 case 'i': 68 case 'I': 69 if(v->type != TINT || machdata == 0) 70 error("no size for i fmt pointer ++/--"); 71 ret = (*machdata->instsize)(cormap, v->vstore.u0.sival); 72 if(ret < 0) { 73 ret = (*machdata->instsize)(symmap, v->vstore.u0.sival); 74 if(ret < 0) 75 error("%r"); 76 } 77 return ret; 78 } 79 } 80 81 void 82 chklval(Node *lp) 83 { 84 if(lp->op != ONAME) 85 error("need l-value"); 86 } 87 88 void 89 olist(Node *n, Node *res) 90 { 91 expr(n->left, res); 92 expr(n->right, res); 93 } 94 95 void 96 oeval(Node *n, Node *res) 97 { 98 expr(n->left, res); 99 if(res->type != TCODE) 100 error("bad type for eval"); 101 expr(res->nstore.u0.scc, res); 102 } 103 104 void 105 ocast(Node *n, Node *res) 106 { 107 if(n->sym->lt == 0) 108 error("%s is not a complex type", n->sym->name); 109 110 expr(n->left, res); 111 res->nstore.comt = n->sym->lt; 112 res->nstore.fmt = 'a'; 113 } 114 115 void 116 oindm(Node *n, Node *res) 117 { 118 Map *m; 119 Node l; 120 121 m = cormap; 122 if(m == 0) 123 m = symmap; 124 expr(n->left, &l); 125 if(l.type != TINT) 126 error("bad type for *"); 127 if(m == 0) 128 error("no map for *"); 129 indir(m, l.nstore.u0.sival, l.nstore.fmt, res); 130 res->nstore.comt = l.nstore.comt; 131 } 132 133 void 134 oindc(Node *n, Node *res) 135 { 136 Map *m; 137 Node l; 138 139 m = symmap; 140 if(m == 0) 141 m = cormap; 142 expr(n->left, &l); 143 if(l.type != TINT) 144 error("bad type for @"); 145 if(m == 0) 146 error("no map for @"); 147 indir(m, l.nstore.u0.sival, l.nstore.fmt, res); 148 res->nstore.comt = l.nstore.comt; 149 } 150 151 void 152 oframe(Node *n, Node *res) 153 { 154 char *p; 155 Node *lp; 156 uvlong ival; 157 Frtype *f; 158 159 p = n->sym->name; 160 while(*p && *p == '$') 161 p++; 162 lp = n->left; 163 if(localaddr(cormap, p, lp->sym->name, &ival, rget) < 0) 164 error("colon: %r"); 165 166 res->nstore.u0.sival = ival; 167 res->op = OCONST; 168 res->nstore.fmt = 'X'; 169 res->type = TINT; 170 171 /* Try and set comt */ 172 for(f = n->sym->local; f; f = f->next) { 173 if(f->var == lp->sym) { 174 res->nstore.comt = f->type; 175 res->nstore.fmt = 'a'; 176 break; 177 } 178 } 179 } 180 181 void 182 oindex(Node *n, Node *res) 183 { 184 Node l, r; 185 186 expr(n->left, &l); 187 expr(n->right, &r); 188 189 if(r.type != TINT) 190 error("bad type for []"); 191 192 switch(l.type) { 193 default: 194 error("lhs[] has bad type"); 195 case TINT: 196 indir(cormap, l.nstore.u0.sival+(r.nstore.u0.sival*fsize[l.nstore.fmt]), l.nstore.fmt, res); 197 res->nstore.comt = l.nstore.comt; 198 res->nstore.fmt = l.nstore.fmt; 199 break; 200 case TLIST: 201 nthelem(l.nstore.u0.sl, r.nstore.u0.sival, res); 202 break; 203 case TSTRING: 204 res->nstore.u0.sival = 0; 205 if(r.nstore.u0.sival >= 0 && r.nstore.u0.sival < l.nstore.u0.sstring->len) { 206 int xx8; /* to get around bug in vc */ 207 xx8 = r.nstore.u0.sival; 208 res->nstore.u0.sival = l.nstore.u0.sstring->string[xx8]; 209 } 210 res->op = OCONST; 211 res->type = TINT; 212 res->nstore.fmt = 'c'; 213 break; 214 } 215 } 216 217 void 218 oappend(Node *n, Node *res) 219 { 220 Node r, l; 221 222 expr(n->left, &l); 223 expr(n->right, &r); 224 if(l.type != TLIST) 225 error("must append to list"); 226 append(res, &l, &r); 227 } 228 229 void 230 odelete(Node *n, Node *res) 231 { 232 Node l, r; 233 234 expr(n->left, &l); 235 expr(n->right, &r); 236 if(l.type != TLIST) 237 error("must delete from list"); 238 if(r.type != TINT) 239 error("delete index must be integer"); 240 241 delete(l.nstore.u0.sl, r.nstore.u0.sival, res); 242 } 243 244 void 245 ohead(Node *n, Node *res) 246 { 247 Node l; 248 249 expr(n->left, &l); 250 if(l.type != TLIST) 251 error("head needs list"); 252 res->op = OCONST; 253 if(l.nstore.u0.sl) { 254 res->type = l.nstore.u0.sl->type; 255 res->nstore = l.nstore.u0.sl->lstore; 256 } 257 else { 258 res->type = TLIST; 259 res->nstore.u0.sl = 0; 260 } 261 } 262 263 void 264 otail(Node *n, Node *res) 265 { 266 Node l; 267 268 expr(n->left, &l); 269 if(l.type != TLIST) 270 error("tail needs list"); 271 res->op = OCONST; 272 res->type = TLIST; 273 if(l.nstore.u0.sl) 274 res->nstore.u0.sl = l.nstore.u0.sl->next; 275 else 276 res->nstore.u0.sl = 0; 277 } 278 279 void 280 oconst(Node *n, Node *res) 281 { 282 res->op = OCONST; 283 res->type = n->type; 284 res->nstore = n->nstore; 285 res->nstore.comt = n->nstore.comt; 286 } 287 288 void 289 oname(Node *n, Node *res) 290 { 291 Value *v; 292 293 v = n->sym->v; 294 if(v->set == 0) 295 error("%s used but not set", n->sym->name); 296 res->op = OCONST; 297 res->type = v->type; 298 res->nstore = v->vstore; 299 res->nstore.comt = v->vstore.comt; 300 } 301 302 void 303 octruct(Node *n, Node *res) 304 { 305 res->op = OCONST; 306 res->type = TLIST; 307 res->nstore.u0.sl = construct(n->left); 308 } 309 310 void 311 oasgn(Node *n, Node *res) 312 { 313 Node *lp, r; 314 Value *v; 315 316 lp = n->left; 317 switch(lp->op) { 318 case OINDM: 319 windir(cormap, lp->left, n->right, res); 320 break; 321 case OINDC: 322 windir(symmap, lp->left, n->right, res); 323 break; 324 default: 325 chklval(lp); 326 v = lp->sym->v; 327 expr(n->right, &r); 328 v->set = 1; 329 v->type = r.type; 330 v->vstore = r.nstore; 331 res->op = OCONST; 332 res->type = v->type; 333 res->nstore = v->vstore; 334 res->nstore.comt = v->vstore.comt; 335 } 336 } 337 338 void 339 oadd(Node *n, Node *res) 340 { 341 Node l, r; 342 343 expr(n->left, &l); 344 expr(n->right, &r); 345 res->nstore.fmt = l.nstore.fmt; 346 res->op = OCONST; 347 res->type = TFLOAT; 348 switch(l.type) { 349 default: 350 error("bad lhs type +"); 351 case TINT: 352 switch(r.type) { 353 case TINT: 354 res->type = TINT; 355 res->nstore.u0.sival = l.nstore.u0.sival+r.nstore.u0.sival; 356 break; 357 case TFLOAT: 358 res->nstore.u0.sfval = l.nstore.u0.sival+r.nstore.u0.sfval; 359 break; 360 default: 361 error("bad rhs type +"); 362 } 363 break; 364 case TFLOAT: 365 switch(r.type) { 366 case TINT: 367 res->nstore.u0.sfval = l.nstore.u0.sfval+r.nstore.u0.sival; 368 break; 369 case TFLOAT: 370 res->nstore.u0.sfval = l.nstore.u0.sfval+r.nstore.u0.sfval; 371 break; 372 default: 373 error("bad rhs type +"); 374 } 375 break; 376 case TSTRING: 377 if(r.type == TSTRING) { 378 res->type = TSTRING; 379 res->nstore.fmt = 's'; 380 res->nstore.u0.sstring = stradd(l.nstore.u0.sstring, r.nstore.u0.sstring); 381 break; 382 } 383 error("bad rhs for +"); 384 case TLIST: 385 res->type = TLIST; 386 switch(r.type) { 387 case TLIST: 388 res->nstore.u0.sl = addlist(l.nstore.u0.sl, r.nstore.u0.sl); 389 break; 390 default: 391 r.left = 0; 392 r.right = 0; 393 res->nstore.u0.sl = addlist(l.nstore.u0.sl, construct(&r)); 394 break; 395 } 396 } 397 } 398 399 void 400 osub(Node *n, Node *res) 401 { 402 Node l, r; 403 404 expr(n->left, &l); 405 expr(n->right, &r); 406 res->nstore.fmt = l.nstore.fmt; 407 res->op = OCONST; 408 res->type = TFLOAT; 409 switch(l.type) { 410 default: 411 error("bad lhs type -"); 412 case TINT: 413 switch(r.type) { 414 case TINT: 415 res->type = TINT; 416 res->nstore.u0.sival = l.nstore.u0.sival-r.nstore.u0.sival; 417 break; 418 case TFLOAT: 419 res->nstore.u0.sfval = l.nstore.u0.sival-r.nstore.u0.sfval; 420 break; 421 default: 422 error("bad rhs type -"); 423 } 424 break; 425 case TFLOAT: 426 switch(r.type) { 427 case TINT: 428 res->nstore.u0.sfval = l.nstore.u0.sfval-r.nstore.u0.sival; 429 break; 430 case TFLOAT: 431 res->nstore.u0.sfval = l.nstore.u0.sfval-r.nstore.u0.sfval; 432 break; 433 default: 434 error("bad rhs type -"); 435 } 436 break; 437 } 438 } 439 440 void 441 omul(Node *n, Node *res) 442 { 443 Node l, r; 444 445 expr(n->left, &l); 446 expr(n->right, &r); 447 res->nstore.fmt = l.nstore.fmt; 448 res->op = OCONST; 449 res->type = TFLOAT; 450 switch(l.type) { 451 default: 452 error("bad lhs type *"); 453 case TINT: 454 switch(r.type) { 455 case TINT: 456 res->type = TINT; 457 res->nstore.u0.sival = l.nstore.u0.sival*r.nstore.u0.sival; 458 break; 459 case TFLOAT: 460 res->nstore.u0.sfval = l.nstore.u0.sival*r.nstore.u0.sfval; 461 break; 462 default: 463 error("bad rhs type *"); 464 } 465 break; 466 case TFLOAT: 467 switch(r.type) { 468 case TINT: 469 res->nstore.u0.sfval = l.nstore.u0.sfval*r.nstore.u0.sival; 470 break; 471 case TFLOAT: 472 res->nstore.u0.sfval = l.nstore.u0.sfval*r.nstore.u0.sfval; 473 break; 474 default: 475 error("bad rhs type *"); 476 } 477 break; 478 } 479 } 480 481 void 482 odiv(Node *n, Node *res) 483 { 484 Node l, r; 485 486 expr(n->left, &l); 487 expr(n->right, &r); 488 res->nstore.fmt = l.nstore.fmt; 489 res->op = OCONST; 490 res->type = TFLOAT; 491 switch(l.type) { 492 default: 493 error("bad lhs type /"); 494 case TINT: 495 switch(r.type) { 496 case TINT: 497 res->type = TINT; 498 if(r.nstore.u0.sival == 0) 499 error("zero divide"); 500 res->nstore.u0.sival = l.nstore.u0.sival/r.nstore.u0.sival; 501 break; 502 case TFLOAT: 503 if(r.nstore.u0.sfval == 0) 504 error("zero divide"); 505 res->nstore.u0.sfval = l.nstore.u0.sival/r.nstore.u0.sfval; 506 break; 507 default: 508 error("bad rhs type /"); 509 } 510 break; 511 case TFLOAT: 512 switch(r.type) { 513 case TINT: 514 res->nstore.u0.sfval = l.nstore.u0.sfval/r.nstore.u0.sival; 515 break; 516 case TFLOAT: 517 res->nstore.u0.sfval = l.nstore.u0.sfval/r.nstore.u0.sfval; 518 break; 519 default: 520 error("bad rhs type /"); 521 } 522 break; 523 } 524 } 525 526 void 527 omod(Node *n, Node *res) 528 { 529 Node l, r; 530 531 expr(n->left, &l); 532 expr(n->right, &r); 533 res->nstore.fmt = l.nstore.fmt; 534 res->op = OCONST; 535 res->type = TINT; 536 if(l.type != TINT || r.type != TINT) 537 error("bad expr type %"); 538 res->nstore.u0.sival = l.nstore.u0.sival%r.nstore.u0.sival; 539 } 540 541 void 542 olsh(Node *n, Node *res) 543 { 544 Node l, r; 545 546 expr(n->left, &l); 547 expr(n->right, &r); 548 res->nstore.fmt = l.nstore.fmt; 549 res->op = OCONST; 550 res->type = TINT; 551 if(l.type != TINT || r.type != TINT) 552 error("bad expr type <<"); 553 res->nstore.u0.sival = l.nstore.u0.sival<<r.nstore.u0.sival; 554 } 555 556 void 557 orsh(Node *n, Node *res) 558 { 559 Node l, r; 560 561 expr(n->left, &l); 562 expr(n->right, &r); 563 res->nstore.fmt = l.nstore.fmt; 564 res->op = OCONST; 565 res->type = TINT; 566 if(l.type != TINT || r.type != TINT) 567 error("bad expr type >>"); 568 res->nstore.u0.sival = l.nstore.u0.sival>>r.nstore.u0.sival; 569 } 570 571 void 572 olt(Node *n, Node *res) 573 { 574 Node l, r; 575 576 expr(n->left, &l); 577 expr(n->right, &r); 578 579 res->nstore.fmt = l.nstore.fmt; 580 res->op = OCONST; 581 res->type = TINT; 582 switch(l.type) { 583 default: 584 error("bad lhs type <"); 585 case TINT: 586 switch(r.type) { 587 case TINT: 588 res->nstore.u0.sival = l.nstore.u0.sival < r.nstore.u0.sival; 589 break; 590 case TFLOAT: 591 res->nstore.u0.sival = l.nstore.u0.sival < r.nstore.u0.sfval; 592 break; 593 default: 594 error("bad rhs type <"); 595 } 596 break; 597 case TFLOAT: 598 switch(r.type) { 599 case TINT: 600 res->nstore.u0.sival = l.nstore.u0.sfval < r.nstore.u0.sival; 601 break; 602 case TFLOAT: 603 res->nstore.u0.sival = l.nstore.u0.sfval < r.nstore.u0.sfval; 604 break; 605 default: 606 error("bad rhs type <"); 607 } 608 break; 609 } 610 } 611 612 void 613 ogt(Node *n, Node *res) 614 { 615 Node l, r; 616 617 expr(n->left, &l); 618 expr(n->right, &r); 619 res->nstore.fmt = 'D'; 620 res->op = OCONST; 621 res->type = TINT; 622 switch(l.type) { 623 default: 624 error("bad lhs type >"); 625 case TINT: 626 switch(r.type) { 627 case TINT: 628 res->nstore.u0.sival = l.nstore.u0.sival > r.nstore.u0.sival; 629 break; 630 case TFLOAT: 631 res->nstore.u0.sival = l.nstore.u0.sival > r.nstore.u0.sfval; 632 break; 633 default: 634 error("bad rhs type >"); 635 } 636 break; 637 case TFLOAT: 638 switch(r.type) { 639 case TINT: 640 res->nstore.u0.sival = l.nstore.u0.sfval > r.nstore.u0.sival; 641 break; 642 case TFLOAT: 643 res->nstore.u0.sival = l.nstore.u0.sfval > r.nstore.u0.sfval; 644 break; 645 default: 646 error("bad rhs type >"); 647 } 648 break; 649 } 650 } 651 652 void 653 oleq(Node *n, Node *res) 654 { 655 Node l, r; 656 657 expr(n->left, &l); 658 expr(n->right, &r); 659 res->nstore.fmt = 'D'; 660 res->op = OCONST; 661 res->type = TINT; 662 switch(l.type) { 663 default: 664 error("bad expr type <="); 665 case TINT: 666 switch(r.type) { 667 case TINT: 668 res->nstore.u0.sival = l.nstore.u0.sival <= r.nstore.u0.sival; 669 break; 670 case TFLOAT: 671 res->nstore.u0.sival = l.nstore.u0.sival <= r.nstore.u0.sfval; 672 break; 673 default: 674 error("bad expr type <="); 675 } 676 break; 677 case TFLOAT: 678 switch(r.type) { 679 case TINT: 680 res->nstore.u0.sival = l.nstore.u0.sfval <= r.nstore.u0.sival; 681 break; 682 case TFLOAT: 683 res->nstore.u0.sival = l.nstore.u0.sfval <= r.nstore.u0.sfval; 684 break; 685 default: 686 error("bad expr type <="); 687 } 688 break; 689 } 690 } 691 692 void 693 ogeq(Node *n, Node *res) 694 { 695 Node l, r; 696 697 expr(n->left, &l); 698 expr(n->right, &r); 699 res->nstore.fmt = 'D'; 700 res->op = OCONST; 701 res->type = TINT; 702 switch(l.type) { 703 default: 704 error("bad lhs type >="); 705 case TINT: 706 switch(r.type) { 707 case TINT: 708 res->nstore.u0.sival = l.nstore.u0.sival >= r.nstore.u0.sival; 709 break; 710 case TFLOAT: 711 res->nstore.u0.sival = l.nstore.u0.sival >= r.nstore.u0.sfval; 712 break; 713 default: 714 error("bad rhs type >="); 715 } 716 break; 717 case TFLOAT: 718 switch(r.type) { 719 case TINT: 720 res->nstore.u0.sival = l.nstore.u0.sfval >= r.nstore.u0.sival; 721 break; 722 case TFLOAT: 723 res->nstore.u0.sival = l.nstore.u0.sfval >= r.nstore.u0.sfval; 724 break; 725 default: 726 error("bad rhs type >="); 727 } 728 break; 729 } 730 } 731 732 void 733 oeq(Node *n, Node *res) 734 { 735 Node l, r; 736 737 expr(n->left, &l); 738 expr(n->right, &r); 739 res->nstore.fmt = 'D'; 740 res->op = OCONST; 741 res->type = TINT; 742 res->nstore.u0.sival = 0; 743 switch(l.type) { 744 default: 745 break; 746 case TINT: 747 switch(r.type) { 748 case TINT: 749 res->nstore.u0.sival = l.nstore.u0.sival == r.nstore.u0.sival; 750 break; 751 case TFLOAT: 752 res->nstore.u0.sival = l.nstore.u0.sival == r.nstore.u0.sfval; 753 break; 754 default: 755 break; 756 } 757 break; 758 case TFLOAT: 759 switch(r.type) { 760 case TINT: 761 res->nstore.u0.sival = l.nstore.u0.sfval == r.nstore.u0.sival; 762 break; 763 case TFLOAT: 764 res->nstore.u0.sival = l.nstore.u0.sfval == r.nstore.u0.sfval; 765 break; 766 default: 767 break; 768 } 769 break; 770 case TSTRING: 771 if(r.type == TSTRING) { 772 res->nstore.u0.sival = scmp(r.nstore.u0.sstring, l.nstore.u0.sstring); 773 break; 774 } 775 break; 776 case TLIST: 777 if(r.type == TLIST) { 778 res->nstore.u0.sival = listcmp(l.nstore.u0.sl, r.nstore.u0.sl); 779 break; 780 } 781 break; 782 } 783 if(n->op == ONEQ) 784 res->nstore.u0.sival = !res->nstore.u0.sival; 785 } 786 787 788 void 789 oland(Node *n, Node *res) 790 { 791 Node l, r; 792 793 expr(n->left, &l); 794 expr(n->right, &r); 795 res->nstore.fmt = l.nstore.fmt; 796 res->op = OCONST; 797 res->type = TINT; 798 if(l.type != TINT || r.type != TINT) 799 error("bad expr type &"); 800 res->nstore.u0.sival = l.nstore.u0.sival&r.nstore.u0.sival; 801 } 802 803 void 804 oxor(Node *n, Node *res) 805 { 806 Node l, r; 807 808 expr(n->left, &l); 809 expr(n->right, &r); 810 res->nstore.fmt = l.nstore.fmt; 811 res->op = OCONST; 812 res->type = TINT; 813 if(l.type != TINT || r.type != TINT) 814 error("bad expr type ^"); 815 res->nstore.u0.sival = l.nstore.u0.sival^r.nstore.u0.sival; 816 } 817 818 void 819 olor(Node *n, Node *res) 820 { 821 Node l, r; 822 823 expr(n->left, &l); 824 expr(n->right, &r); 825 res->nstore.fmt = l.nstore.fmt; 826 res->op = OCONST; 827 res->type = TINT; 828 if(l.type != TINT || r.type != TINT) 829 error("bad expr type |"); 830 res->nstore.u0.sival = l.nstore.u0.sival|r.nstore.u0.sival; 831 } 832 833 void 834 ocand(Node *n, Node *res) 835 { 836 Node l, r; 837 838 res->op = OCONST; 839 res->type = TINT; 840 res->nstore.u0.sival = 0; 841 expr(n->left, &l); 842 res->nstore.fmt = l.nstore.fmt; 843 if(bool(&l) == 0) 844 return; 845 expr(n->right, &r); 846 if(bool(&r) == 0) 847 return; 848 res->nstore.u0.sival = 1; 849 } 850 851 void 852 onot(Node *n, Node *res) 853 { 854 Node l; 855 856 res->op = OCONST; 857 res->type = TINT; 858 res->nstore.u0.sival = 0; 859 expr(n->left, &l); 860 if(bool(&l) == 0) 861 res->nstore.u0.sival = 1; 862 } 863 864 void 865 ocor(Node *n, Node *res) 866 { 867 Node l, r; 868 869 res->op = OCONST; 870 res->type = TINT; 871 res->nstore.u0.sival = 0; 872 expr(n->left, &l); 873 if(bool(&l)) { 874 res->nstore.u0.sival = 1; 875 return; 876 } 877 expr(n->right, &r); 878 if(bool(&r)) { 879 res->nstore.u0.sival = 1; 880 return; 881 } 882 } 883 884 void 885 oeinc(Node *n, Node *res) 886 { 887 Value *v; 888 889 chklval(n->left); 890 v = n->left->sym->v; 891 res->op = OCONST; 892 res->type = v->type; 893 switch(v->type) { 894 case TINT: 895 if(n->op == OEDEC) 896 v->vstore.u0.sival -= fmtsize(v); 897 else 898 v->vstore.u0.sival += fmtsize(v); 899 break; 900 case TFLOAT: 901 if(n->op == OEDEC) 902 v->vstore.u0.sfval--; 903 else 904 v->vstore.u0.sfval++; 905 break; 906 default: 907 error("bad type for pre --/++"); 908 } 909 res->nstore = v->vstore; 910 } 911 912 void 913 opinc(Node *n, Node *res) 914 { 915 Value *v; 916 917 chklval(n->left); 918 v = n->left->sym->v; 919 res->op = OCONST; 920 res->type = v->type; 921 res->nstore = v->vstore; 922 switch(v->type) { 923 case TINT: 924 if(n->op == OPDEC) 925 v->vstore.u0.sival -= fmtsize(v); 926 else 927 v->vstore.u0.sival += fmtsize(v); 928 break; 929 case TFLOAT: 930 if(n->op == OPDEC) 931 v->vstore.u0.sfval--; 932 else 933 v->vstore.u0.sfval++; 934 break; 935 default: 936 error("bad type for post --/++"); 937 } 938 } 939 940 void 941 ocall(Node *n, Node *res) 942 { 943 Lsym *s; 944 Rplace *rsav; 945 946 res->op = OCONST; /* Default return value */ 947 res->type = TLIST; 948 res->nstore.u0.sl = 0; 949 950 chklval(n->left); 951 s = n->left->sym; 952 953 if(s->builtin) { 954 (*s->builtin)(res, n->right); 955 return; 956 } 957 if(s->proc == 0) 958 error("no function %s", s->name); 959 960 rsav = ret; 961 call(s->name, n->right, s->proc->left, s->proc->right, res); 962 ret = rsav; 963 } 964 965 void 966 ofmt(Node *n, Node *res) 967 { 968 expr(n->left, res); 969 res->nstore.fmt = n->right->nstore.u0.sival; 970 } 971 972 void 973 owhat(Node *n, Node *res) 974 { 975 res->op = OCONST; /* Default return value */ 976 res->type = TLIST; 977 res->nstore.u0.sl = 0; 978 whatis(n->sym); 979 } 980 981 void (*expop[])(Node*, Node*) = 982 { 983 oname, /* [ONAME] oname, */ 984 oconst, /* [OCONST] oconst, */ 985 omul, /* [OMUL] omul, */ 986 odiv, /* [ODIV] odiv, */ 987 omod, /* [OMOD] omod, */ 988 oadd, /* [OADD] oadd, */ 989 osub, /* [OSUB] osub, */ 990 orsh, /* [ORSH] orsh, */ 991 olsh, /* [OLSH] olsh, */ 992 olt, /* [OLT] olt, */ 993 ogt, /* [OGT] ogt, */ 994 oleq, /* [OLEQ] oleq, */ 995 ogeq, /* [OGEQ] ogeq, */ 996 oeq, /* [OEQ] oeq, */ 997 oeq, /* [ONEQ] oeq, */ 998 oland, /* [OLAND] oland, */ 999 oxor, /* [OXOR] oxor, */ 1000 olor, /* [OLOR] olor, */ 1001 ocand, /* [OCAND] ocand, */ 1002 ocor, /* [OCOR] ocor, */ 1003 oasgn, /* [OASGN] oasgn, */ 1004 oindm, /* [OINDM] oindm, */ 1005 oeinc, /* [OEDEC] oeinc, */ 1006 oeinc, /* [OEINC] oeinc, */ 1007 opinc, /* [OPINC] opinc, */ 1008 opinc, /* [OPDEC] opinc, */ 1009 onot, /* [ONOT] onot, */ 1010 0, /* [OIF] 0, */ 1011 0, /* [ODO] 0, */ 1012 olist, /* [OLIST] olist, */ 1013 ocall, /* [OCALL] ocall, */ 1014 octruct, /* [OCTRUCT] octruct, */ 1015 0, /* [OWHILE] 0, */ 1016 0, /* [OELSE] 0, */ 1017 ohead, /* [OHEAD] ohead, */ 1018 otail, /* [OTAIL] otail, */ 1019 oappend, /* [OAPPEND] oappend, */ 1020 0, /* [ORET] 0, */ 1021 oindex, /* [OINDEX] oindex, */ 1022 oindc, /* [OINDC] oindc, */ 1023 odot, /* [ODOT] odot, */ 1024 0, /* [OLOCAL] 0, */ 1025 oframe, /* [OFRAME] oframe, */ 1026 0, /* [OCOMPLEX] 0, */ 1027 odelete, /* [ODELETE] odelete, */ 1028 ocast, /* [OCAST] ocast, */ 1029 ofmt, /* [OFMT] ofmt, */ 1030 oeval, /* [OEVAL] oeval, */ 1031 owhat, /* [OWHAT] owhat, */ 1032 }; 1033