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