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