1bd389b36SDavid du Colombier #include <u.h> 2bd389b36SDavid du Colombier #include <libc.h> 3bd389b36SDavid du Colombier #include <bio.h> 4bd389b36SDavid du Colombier #include <ctype.h> 5bd389b36SDavid du Colombier #include <mach.h> 6bd389b36SDavid du Colombier #define Extern extern 7bd389b36SDavid du Colombier #include "acid.h" 8bd389b36SDavid du Colombier 9219b2ee8SDavid du Colombier static int fsize[] = 10bd389b36SDavid du Colombier { 117dd7cddfSDavid du Colombier ['A'] 4, 127dd7cddfSDavid du Colombier ['B'] 4, 13bd389b36SDavid du Colombier ['C'] 1, 14bd389b36SDavid du Colombier ['D'] 4, 15219b2ee8SDavid du Colombier ['F'] 8, 16219b2ee8SDavid du Colombier ['G'] 8, 17bd389b36SDavid du Colombier ['O'] 4, 18bd389b36SDavid du Colombier ['Q'] 4, 19219b2ee8SDavid du Colombier ['R'] 4, 20219b2ee8SDavid du Colombier ['S'] 4, 21219b2ee8SDavid du Colombier ['U'] 4, 227dd7cddfSDavid du Colombier ['V'] 8, 23219b2ee8SDavid du Colombier ['X'] 4, 247dd7cddfSDavid du Colombier ['Y'] 8, 257dd7cddfSDavid du Colombier ['W'] 8, 267dd7cddfSDavid du Colombier ['Z'] 8, 27219b2ee8SDavid du Colombier ['a'] 4, 28219b2ee8SDavid du Colombier ['b'] 1, 29219b2ee8SDavid du Colombier ['c'] 1, 30219b2ee8SDavid du Colombier ['d'] 2, 31219b2ee8SDavid du Colombier ['f'] 4, 32219b2ee8SDavid du Colombier ['g'] 4, 33219b2ee8SDavid du Colombier ['o'] 2, 34219b2ee8SDavid du Colombier ['q'] 2, 35bd389b36SDavid du Colombier ['r'] 2, 36219b2ee8SDavid du Colombier ['s'] 4, 37219b2ee8SDavid du Colombier ['u'] 2, 38219b2ee8SDavid du Colombier ['x'] 2, 39bd389b36SDavid du Colombier }; 40bd389b36SDavid du Colombier 41bd389b36SDavid du Colombier int 42bd389b36SDavid du Colombier fmtsize(Value *v) 43bd389b36SDavid du Colombier { 44219b2ee8SDavid du Colombier int ret; 45219b2ee8SDavid du Colombier 46bd389b36SDavid du Colombier switch(v->fmt) { 47bd389b36SDavid du Colombier default: 48bd389b36SDavid du Colombier return fsize[v->fmt]; 49bd389b36SDavid du Colombier case 'i': 50bd389b36SDavid du Colombier case 'I': 51219b2ee8SDavid du Colombier if(v->type != TINT || machdata == 0) 52bd389b36SDavid du Colombier error("no size for i fmt pointer ++/--"); 53219b2ee8SDavid du Colombier ret = (*machdata->instsize)(cormap, v->ival); 54219b2ee8SDavid du Colombier if(ret < 0) { 55219b2ee8SDavid du Colombier ret = (*machdata->instsize)(symmap, v->ival); 56219b2ee8SDavid du Colombier if(ret < 0) 57219b2ee8SDavid du Colombier error("%r"); 58219b2ee8SDavid du Colombier } 59219b2ee8SDavid du Colombier return ret; 60bd389b36SDavid du Colombier } 61bd389b36SDavid du Colombier } 62bd389b36SDavid du Colombier 63bd389b36SDavid du Colombier void 64bd389b36SDavid du Colombier chklval(Node *lp) 65bd389b36SDavid du Colombier { 66bd389b36SDavid du Colombier if(lp->op != ONAME) 67bd389b36SDavid du Colombier error("need l-value"); 68bd389b36SDavid du Colombier } 69bd389b36SDavid du Colombier 70bd389b36SDavid du Colombier void 71219b2ee8SDavid du Colombier olist(Node *n, Node *res) 72219b2ee8SDavid du Colombier { 73219b2ee8SDavid du Colombier expr(n->left, res); 74219b2ee8SDavid du Colombier expr(n->right, res); 75219b2ee8SDavid du Colombier } 76219b2ee8SDavid du Colombier 77219b2ee8SDavid du Colombier void 78219b2ee8SDavid du Colombier oeval(Node *n, Node *res) 79219b2ee8SDavid du Colombier { 80219b2ee8SDavid du Colombier expr(n->left, res); 81219b2ee8SDavid du Colombier if(res->type != TCODE) 82219b2ee8SDavid du Colombier error("bad type for eval"); 83219b2ee8SDavid du Colombier expr(res->cc, res); 84219b2ee8SDavid du Colombier } 85219b2ee8SDavid du Colombier 86219b2ee8SDavid du Colombier void 87219b2ee8SDavid du Colombier ocast(Node *n, Node *res) 88219b2ee8SDavid du Colombier { 89219b2ee8SDavid du Colombier if(n->sym->lt == 0) 90219b2ee8SDavid du Colombier error("%s is not a complex type", n->sym->name); 91219b2ee8SDavid du Colombier 92219b2ee8SDavid du Colombier expr(n->left, res); 93219b2ee8SDavid du Colombier res->comt = n->sym->lt; 94219b2ee8SDavid du Colombier res->fmt = 'a'; 95219b2ee8SDavid du Colombier } 96219b2ee8SDavid du Colombier 97219b2ee8SDavid du Colombier void 98219b2ee8SDavid du Colombier oindm(Node *n, Node *res) 99bd389b36SDavid du Colombier { 100bd389b36SDavid du Colombier Map *m; 101219b2ee8SDavid du Colombier Node l; 102bd389b36SDavid du Colombier 103bd389b36SDavid du Colombier m = cormap; 104bd389b36SDavid du Colombier if(m == 0) 105219b2ee8SDavid du Colombier m = symmap; 106219b2ee8SDavid du Colombier expr(n->left, &l); 107219b2ee8SDavid du Colombier if(l.type != TINT) 108219b2ee8SDavid du Colombier error("bad type for *"); 109219b2ee8SDavid du Colombier if(m == 0) 110219b2ee8SDavid du Colombier error("no map for *"); 111bd389b36SDavid du Colombier indir(m, l.ival, l.fmt, res); 112bd389b36SDavid du Colombier res->comt = l.comt; 113219b2ee8SDavid du Colombier } 114219b2ee8SDavid du Colombier 115219b2ee8SDavid du Colombier void 116219b2ee8SDavid du Colombier oindc(Node *n, Node *res) 117219b2ee8SDavid du Colombier { 118219b2ee8SDavid du Colombier Map *m; 119219b2ee8SDavid du Colombier Node l; 120219b2ee8SDavid du Colombier 121219b2ee8SDavid du Colombier m = symmap; 122219b2ee8SDavid du Colombier if(m == 0) 123219b2ee8SDavid du Colombier m = cormap; 124219b2ee8SDavid du Colombier expr(n->left, &l); 125219b2ee8SDavid du Colombier if(l.type != TINT) 126219b2ee8SDavid du Colombier error("bad type for @"); 127219b2ee8SDavid du Colombier if(m == 0) 128219b2ee8SDavid du Colombier error("no map for @"); 129219b2ee8SDavid du Colombier indir(m, l.ival, l.fmt, res); 130219b2ee8SDavid du Colombier res->comt = l.comt; 131219b2ee8SDavid du Colombier } 132219b2ee8SDavid du Colombier 133219b2ee8SDavid du Colombier void 134219b2ee8SDavid du Colombier oframe(Node *n, Node *res) 135219b2ee8SDavid du Colombier { 136219b2ee8SDavid du Colombier char *p; 137219b2ee8SDavid du Colombier Node *lp; 138219b2ee8SDavid du Colombier long ival; 139219b2ee8SDavid du Colombier Frtype *f; 140219b2ee8SDavid du Colombier 141219b2ee8SDavid du Colombier p = n->sym->name; 142219b2ee8SDavid du Colombier while(*p && *p == '$') 143219b2ee8SDavid du Colombier p++; 144219b2ee8SDavid du Colombier lp = n->left; 145219b2ee8SDavid du Colombier if(localaddr(cormap, p, lp->sym->name, &ival, rget) < 0) 146219b2ee8SDavid du Colombier error("colon: %r"); 147219b2ee8SDavid du Colombier 148219b2ee8SDavid du Colombier res->ival = ival; 149219b2ee8SDavid du Colombier res->op = OCONST; 150219b2ee8SDavid du Colombier res->fmt = 'X'; 151219b2ee8SDavid du Colombier res->type = TINT; 152219b2ee8SDavid du Colombier 153219b2ee8SDavid du Colombier /* Try and set comt */ 154219b2ee8SDavid du Colombier for(f = n->sym->local; f; f = f->next) { 155219b2ee8SDavid du Colombier if(f->var == lp->sym) { 156219b2ee8SDavid du Colombier res->comt = f->type; 157219b2ee8SDavid du Colombier res->fmt = 'a'; 158bd389b36SDavid du Colombier break; 159219b2ee8SDavid du Colombier } 160219b2ee8SDavid du Colombier } 161219b2ee8SDavid du Colombier } 162219b2ee8SDavid du Colombier 163219b2ee8SDavid du Colombier void 164219b2ee8SDavid du Colombier oindex(Node *n, Node *res) 165219b2ee8SDavid du Colombier { 166219b2ee8SDavid du Colombier Node l, r; 167219b2ee8SDavid du Colombier 168219b2ee8SDavid du Colombier expr(n->left, &l); 169219b2ee8SDavid du Colombier expr(n->right, &r); 170219b2ee8SDavid du Colombier 171bd389b36SDavid du Colombier if(r.type != TINT) 172bd389b36SDavid du Colombier error("bad type for []"); 173219b2ee8SDavid du Colombier 174bd389b36SDavid du Colombier switch(l.type) { 175bd389b36SDavid du Colombier default: 176bd389b36SDavid du Colombier error("lhs[] has bad type"); 177bd389b36SDavid du Colombier case TINT: 178219b2ee8SDavid du Colombier indir(cormap, l.ival+(r.ival*fsize[l.fmt]), l.fmt, res); 179219b2ee8SDavid du Colombier res->comt = l.comt; 180219b2ee8SDavid du Colombier res->fmt = l.fmt; 181bd389b36SDavid du Colombier break; 182bd389b36SDavid du Colombier case TLIST: 183bd389b36SDavid du Colombier nthelem(l.l, r.ival, res); 184bd389b36SDavid du Colombier break; 185bd389b36SDavid du Colombier case TSTRING: 186bd389b36SDavid du Colombier res->ival = 0; 187219b2ee8SDavid du Colombier if(r.ival >= 0 && r.ival < l.string->len) { 188219b2ee8SDavid du Colombier int xx8; /* to get around bug in vc */ 189219b2ee8SDavid du Colombier xx8 = r.ival; 190219b2ee8SDavid du Colombier res->ival = l.string->string[xx8]; 191219b2ee8SDavid du Colombier } 192bd389b36SDavid du Colombier res->op = OCONST; 193bd389b36SDavid du Colombier res->type = TINT; 194bd389b36SDavid du Colombier res->fmt = 'c'; 195bd389b36SDavid du Colombier break; 196bd389b36SDavid du Colombier } 197219b2ee8SDavid du Colombier } 198219b2ee8SDavid du Colombier 199219b2ee8SDavid du Colombier void 200219b2ee8SDavid du Colombier oappend(Node *n, Node *res) 201219b2ee8SDavid du Colombier { 202219b2ee8SDavid du Colombier Node r, l; 203219b2ee8SDavid du Colombier 204219b2ee8SDavid du Colombier expr(n->left, &l); 205219b2ee8SDavid du Colombier expr(n->right, &r); 206bd389b36SDavid du Colombier if(l.type != TLIST) 207bd389b36SDavid du Colombier error("must append to list"); 208bd389b36SDavid du Colombier append(res, &l, &r); 209219b2ee8SDavid du Colombier } 210219b2ee8SDavid du Colombier 211219b2ee8SDavid du Colombier void 212219b2ee8SDavid du Colombier odelete(Node *n, Node *res) 213219b2ee8SDavid du Colombier { 214219b2ee8SDavid du Colombier Node l, r; 215219b2ee8SDavid du Colombier 216219b2ee8SDavid du Colombier expr(n->left, &l); 217219b2ee8SDavid du Colombier expr(n->right, &r); 218bd389b36SDavid du Colombier if(l.type != TLIST) 219bd389b36SDavid du Colombier error("must delete from list"); 220bd389b36SDavid du Colombier if(r.type != TINT) 221bd389b36SDavid du Colombier error("delete index must be integer"); 222bd389b36SDavid du Colombier 223bd389b36SDavid du Colombier delete(l.l, r.ival, res); 224219b2ee8SDavid du Colombier } 225219b2ee8SDavid du Colombier 226219b2ee8SDavid du Colombier void 227219b2ee8SDavid du Colombier ohead(Node *n, Node *res) 228219b2ee8SDavid du Colombier { 229219b2ee8SDavid du Colombier Node l; 230219b2ee8SDavid du Colombier 231219b2ee8SDavid du Colombier expr(n->left, &l); 232bd389b36SDavid du Colombier if(l.type != TLIST) 233bd389b36SDavid du Colombier error("head needs list"); 234bd389b36SDavid du Colombier res->op = OCONST; 235bd389b36SDavid du Colombier if(l.l) { 236bd389b36SDavid du Colombier res->type = l.l->type; 237bd389b36SDavid du Colombier res->Store = l.l->Store; 238bd389b36SDavid du Colombier } 239bd389b36SDavid du Colombier else { 240bd389b36SDavid du Colombier res->type = TLIST; 241bd389b36SDavid du Colombier res->l = 0; 242bd389b36SDavid du Colombier } 243219b2ee8SDavid du Colombier } 244219b2ee8SDavid du Colombier 245219b2ee8SDavid du Colombier void 246219b2ee8SDavid du Colombier otail(Node *n, Node *res) 247219b2ee8SDavid du Colombier { 248219b2ee8SDavid du Colombier Node l; 249219b2ee8SDavid du Colombier 250219b2ee8SDavid du Colombier expr(n->left, &l); 251bd389b36SDavid du Colombier if(l.type != TLIST) 252bd389b36SDavid du Colombier error("tail needs list"); 253bd389b36SDavid du Colombier res->op = OCONST; 254bd389b36SDavid du Colombier res->type = TLIST; 255bd389b36SDavid du Colombier if(l.l) 256219b2ee8SDavid du Colombier res->l = l.l->next; 257bd389b36SDavid du Colombier else 258219b2ee8SDavid du Colombier res->l = 0; 259219b2ee8SDavid du Colombier } 260219b2ee8SDavid du Colombier 261219b2ee8SDavid du Colombier void 262219b2ee8SDavid du Colombier oconst(Node *n, Node *res) 263219b2ee8SDavid du Colombier { 264219b2ee8SDavid du Colombier res->op = OCONST; 265219b2ee8SDavid du Colombier res->type = n->type; 266219b2ee8SDavid du Colombier res->Store = n->Store; 267219b2ee8SDavid du Colombier res->comt = n->comt; 268219b2ee8SDavid du Colombier } 269219b2ee8SDavid du Colombier 270219b2ee8SDavid du Colombier void 271219b2ee8SDavid du Colombier oname(Node *n, Node *res) 272219b2ee8SDavid du Colombier { 273219b2ee8SDavid du Colombier Value *v; 274219b2ee8SDavid du Colombier 275bd389b36SDavid du Colombier v = n->sym->v; 276bd389b36SDavid du Colombier if(v->set == 0) 277bd389b36SDavid du Colombier error("%s used but not set", n->sym->name); 278bd389b36SDavid du Colombier res->op = OCONST; 279bd389b36SDavid du Colombier res->type = v->type; 280bd389b36SDavid du Colombier res->Store = v->Store; 281219b2ee8SDavid du Colombier res->comt = v->comt; 282219b2ee8SDavid du Colombier } 283219b2ee8SDavid du Colombier 284219b2ee8SDavid du Colombier void 285219b2ee8SDavid du Colombier octruct(Node *n, Node *res) 286219b2ee8SDavid du Colombier { 287bd389b36SDavid du Colombier res->op = OCONST; 288bd389b36SDavid du Colombier res->type = TLIST; 289219b2ee8SDavid du Colombier res->l = construct(n->left); 290219b2ee8SDavid du Colombier } 291219b2ee8SDavid du Colombier 292219b2ee8SDavid du Colombier void 293219b2ee8SDavid du Colombier oasgn(Node *n, Node *res) 294219b2ee8SDavid du Colombier { 295219b2ee8SDavid du Colombier Node *lp, r; 296219b2ee8SDavid du Colombier Value *v; 297219b2ee8SDavid du Colombier 298219b2ee8SDavid du Colombier lp = n->left; 299bd389b36SDavid du Colombier switch(lp->op) { 300bd389b36SDavid du Colombier case OINDM: 301219b2ee8SDavid du Colombier windir(cormap, lp->left, n->right, res); 302bd389b36SDavid du Colombier break; 303bd389b36SDavid du Colombier case OINDC: 304219b2ee8SDavid du Colombier windir(symmap, lp->left, n->right, res); 305bd389b36SDavid du Colombier break; 306bd389b36SDavid du Colombier default: 307bd389b36SDavid du Colombier chklval(lp); 308bd389b36SDavid du Colombier v = lp->sym->v; 309219b2ee8SDavid du Colombier expr(n->right, &r); 310bd389b36SDavid du Colombier v->set = 1; 311bd389b36SDavid du Colombier v->type = r.type; 312bd389b36SDavid du Colombier v->Store = r.Store; 313219b2ee8SDavid du Colombier res->op = OCONST; 314219b2ee8SDavid du Colombier res->type = v->type; 315219b2ee8SDavid du Colombier res->Store = v->Store; 316219b2ee8SDavid du Colombier res->comt = v->comt; 317bd389b36SDavid du Colombier } 318219b2ee8SDavid du Colombier } 319219b2ee8SDavid du Colombier 320219b2ee8SDavid du Colombier void 321219b2ee8SDavid du Colombier oadd(Node *n, Node *res) 322219b2ee8SDavid du Colombier { 323219b2ee8SDavid du Colombier Node l, r; 324219b2ee8SDavid du Colombier 325219b2ee8SDavid du Colombier expr(n->left, &l); 326219b2ee8SDavid du Colombier expr(n->right, &r); 327bd389b36SDavid du Colombier res->fmt = l.fmt; 328bd389b36SDavid du Colombier res->op = OCONST; 329bd389b36SDavid du Colombier res->type = TFLOAT; 330bd389b36SDavid du Colombier switch(l.type) { 331219b2ee8SDavid du Colombier default: 332219b2ee8SDavid du Colombier error("bad lhs type +"); 333bd389b36SDavid du Colombier case TINT: 334bd389b36SDavid du Colombier switch(r.type) { 335bd389b36SDavid du Colombier case TINT: 336bd389b36SDavid du Colombier res->type = TINT; 337bd389b36SDavid du Colombier res->ival = l.ival+r.ival; 338bd389b36SDavid du Colombier break; 339bd389b36SDavid du Colombier case TFLOAT: 340bd389b36SDavid du Colombier res->fval = l.ival+r.fval; 341bd389b36SDavid du Colombier break; 342219b2ee8SDavid du Colombier default: 343219b2ee8SDavid du Colombier error("bad rhs type +"); 344bd389b36SDavid du Colombier } 345bd389b36SDavid du Colombier break; 346bd389b36SDavid du Colombier case TFLOAT: 347bd389b36SDavid du Colombier switch(r.type) { 348bd389b36SDavid du Colombier case TINT: 349bd389b36SDavid du Colombier res->fval = l.fval+r.ival; 350bd389b36SDavid du Colombier break; 351bd389b36SDavid du Colombier case TFLOAT: 352bd389b36SDavid du Colombier res->fval = l.fval+r.fval; 353bd389b36SDavid du Colombier break; 354219b2ee8SDavid du Colombier default: 355219b2ee8SDavid du Colombier error("bad rhs type +"); 356bd389b36SDavid du Colombier } 357bd389b36SDavid du Colombier break; 358bd389b36SDavid du Colombier case TSTRING: 359bd389b36SDavid du Colombier if(r.type == TSTRING) { 360bd389b36SDavid du Colombier res->type = TSTRING; 361bd389b36SDavid du Colombier res->fmt = 's'; 362bd389b36SDavid du Colombier res->string = stradd(l.string, r.string); 363bd389b36SDavid du Colombier break; 364bd389b36SDavid du Colombier } 365*ab3dc52fSDavid du Colombier if(r.type == TINT) { 366*ab3dc52fSDavid du Colombier res->type = TSTRING; 367*ab3dc52fSDavid du Colombier res->fmt = 's'; 368*ab3dc52fSDavid du Colombier res->string = straddrune(l.string, r.ival); 369*ab3dc52fSDavid du Colombier break; 370*ab3dc52fSDavid du Colombier } 371bd389b36SDavid du Colombier error("bad rhs for +"); 372bd389b36SDavid du Colombier case TLIST: 373bd389b36SDavid du Colombier res->type = TLIST; 374bd389b36SDavid du Colombier switch(r.type) { 375bd389b36SDavid du Colombier case TLIST: 376bd389b36SDavid du Colombier res->l = addlist(l.l, r.l); 377bd389b36SDavid du Colombier break; 378bd389b36SDavid du Colombier default: 379bd389b36SDavid du Colombier r.left = 0; 380bd389b36SDavid du Colombier r.right = 0; 381bd389b36SDavid du Colombier res->l = addlist(l.l, construct(&r)); 382bd389b36SDavid du Colombier break; 383bd389b36SDavid du Colombier } 384bd389b36SDavid du Colombier } 385219b2ee8SDavid du Colombier } 386219b2ee8SDavid du Colombier 387219b2ee8SDavid du Colombier void 388219b2ee8SDavid du Colombier osub(Node *n, Node *res) 389219b2ee8SDavid du Colombier { 390219b2ee8SDavid du Colombier Node l, r; 391219b2ee8SDavid du Colombier 392219b2ee8SDavid du Colombier expr(n->left, &l); 393219b2ee8SDavid du Colombier expr(n->right, &r); 394bd389b36SDavid du Colombier res->fmt = l.fmt; 395bd389b36SDavid du Colombier res->op = OCONST; 396bd389b36SDavid du Colombier res->type = TFLOAT; 397bd389b36SDavid du Colombier switch(l.type) { 398219b2ee8SDavid du Colombier default: 399219b2ee8SDavid du Colombier error("bad lhs type -"); 400bd389b36SDavid du Colombier case TINT: 401bd389b36SDavid du Colombier switch(r.type) { 402bd389b36SDavid du Colombier case TINT: 403bd389b36SDavid du Colombier res->type = TINT; 404bd389b36SDavid du Colombier res->ival = l.ival-r.ival; 405bd389b36SDavid du Colombier break; 406bd389b36SDavid du Colombier case TFLOAT: 407bd389b36SDavid du Colombier res->fval = l.ival-r.fval; 408bd389b36SDavid du Colombier break; 409219b2ee8SDavid du Colombier default: 410219b2ee8SDavid du Colombier error("bad rhs type -"); 411bd389b36SDavid du Colombier } 412bd389b36SDavid du Colombier break; 413bd389b36SDavid du Colombier case TFLOAT: 414219b2ee8SDavid du Colombier switch(r.type) { 415bd389b36SDavid du Colombier case TINT: 416bd389b36SDavid du Colombier res->fval = l.fval-r.ival; 417bd389b36SDavid du Colombier break; 418bd389b36SDavid du Colombier case TFLOAT: 419bd389b36SDavid du Colombier res->fval = l.fval-r.fval; 420bd389b36SDavid du Colombier break; 421219b2ee8SDavid du Colombier default: 422219b2ee8SDavid du Colombier error("bad rhs type -"); 423bd389b36SDavid du Colombier } 424bd389b36SDavid du Colombier break; 425bd389b36SDavid du Colombier } 426219b2ee8SDavid du Colombier } 427219b2ee8SDavid du Colombier 428219b2ee8SDavid du Colombier void 429219b2ee8SDavid du Colombier omul(Node *n, Node *res) 430219b2ee8SDavid du Colombier { 431219b2ee8SDavid du Colombier Node l, r; 432219b2ee8SDavid du Colombier 433219b2ee8SDavid du Colombier expr(n->left, &l); 434219b2ee8SDavid du Colombier expr(n->right, &r); 435bd389b36SDavid du Colombier res->fmt = l.fmt; 436bd389b36SDavid du Colombier res->op = OCONST; 437bd389b36SDavid du Colombier res->type = TFLOAT; 438bd389b36SDavid du Colombier switch(l.type) { 439219b2ee8SDavid du Colombier default: 440219b2ee8SDavid du Colombier error("bad lhs type *"); 441bd389b36SDavid du Colombier case TINT: 442bd389b36SDavid du Colombier switch(r.type) { 443bd389b36SDavid du Colombier case TINT: 444bd389b36SDavid du Colombier res->type = TINT; 445bd389b36SDavid du Colombier res->ival = l.ival*r.ival; 446bd389b36SDavid du Colombier break; 447bd389b36SDavid du Colombier case TFLOAT: 448bd389b36SDavid du Colombier res->fval = l.ival*r.fval; 449bd389b36SDavid du Colombier break; 450219b2ee8SDavid du Colombier default: 451219b2ee8SDavid du Colombier error("bad rhs type *"); 452bd389b36SDavid du Colombier } 453bd389b36SDavid du Colombier break; 454bd389b36SDavid du Colombier case TFLOAT: 455219b2ee8SDavid du Colombier switch(r.type) { 456bd389b36SDavid du Colombier case TINT: 457bd389b36SDavid du Colombier res->fval = l.fval*r.ival; 458bd389b36SDavid du Colombier break; 459bd389b36SDavid du Colombier case TFLOAT: 460bd389b36SDavid du Colombier res->fval = l.fval*r.fval; 461bd389b36SDavid du Colombier break; 462219b2ee8SDavid du Colombier default: 463219b2ee8SDavid du Colombier error("bad rhs type *"); 464bd389b36SDavid du Colombier } 465bd389b36SDavid du Colombier break; 466bd389b36SDavid du Colombier } 467219b2ee8SDavid du Colombier } 468219b2ee8SDavid du Colombier 469219b2ee8SDavid du Colombier void 470219b2ee8SDavid du Colombier odiv(Node *n, Node *res) 471219b2ee8SDavid du Colombier { 472219b2ee8SDavid du Colombier Node l, r; 473219b2ee8SDavid du Colombier 474219b2ee8SDavid du Colombier expr(n->left, &l); 475219b2ee8SDavid du Colombier expr(n->right, &r); 476bd389b36SDavid du Colombier res->fmt = l.fmt; 477bd389b36SDavid du Colombier res->op = OCONST; 478bd389b36SDavid du Colombier res->type = TFLOAT; 479bd389b36SDavid du Colombier switch(l.type) { 480219b2ee8SDavid du Colombier default: 481219b2ee8SDavid du Colombier error("bad lhs type /"); 482bd389b36SDavid du Colombier case TINT: 483bd389b36SDavid du Colombier switch(r.type) { 484bd389b36SDavid du Colombier case TINT: 485bd389b36SDavid du Colombier res->type = TINT; 486219b2ee8SDavid du Colombier if(r.ival == 0) 487219b2ee8SDavid du Colombier error("zero divide"); 488bd389b36SDavid du Colombier res->ival = l.ival/r.ival; 489bd389b36SDavid du Colombier break; 490bd389b36SDavid du Colombier case TFLOAT: 491219b2ee8SDavid du Colombier if(r.fval == 0) 492219b2ee8SDavid du Colombier error("zero divide"); 493bd389b36SDavid du Colombier res->fval = l.ival/r.fval; 494bd389b36SDavid du Colombier break; 495219b2ee8SDavid du Colombier default: 496219b2ee8SDavid du Colombier error("bad rhs type /"); 497bd389b36SDavid du Colombier } 498bd389b36SDavid du Colombier break; 499bd389b36SDavid du Colombier case TFLOAT: 500219b2ee8SDavid du Colombier switch(r.type) { 501bd389b36SDavid du Colombier case TINT: 502bd389b36SDavid du Colombier res->fval = l.fval/r.ival; 503bd389b36SDavid du Colombier break; 504bd389b36SDavid du Colombier case TFLOAT: 505bd389b36SDavid du Colombier res->fval = l.fval/r.fval; 506bd389b36SDavid du Colombier break; 507219b2ee8SDavid du Colombier default: 508219b2ee8SDavid du Colombier error("bad rhs type /"); 509bd389b36SDavid du Colombier } 510bd389b36SDavid du Colombier break; 511bd389b36SDavid du Colombier } 512219b2ee8SDavid du Colombier } 513219b2ee8SDavid du Colombier 514219b2ee8SDavid du Colombier void 515219b2ee8SDavid du Colombier omod(Node *n, Node *res) 516219b2ee8SDavid du Colombier { 517219b2ee8SDavid du Colombier Node l, r; 518219b2ee8SDavid du Colombier 519219b2ee8SDavid du Colombier expr(n->left, &l); 520219b2ee8SDavid du Colombier expr(n->right, &r); 521bd389b36SDavid du Colombier res->fmt = l.fmt; 522bd389b36SDavid du Colombier res->op = OCONST; 523bd389b36SDavid du Colombier res->type = TINT; 524bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 525bd389b36SDavid du Colombier error("bad expr type %"); 526bd389b36SDavid du Colombier res->ival = l.ival%r.ival; 527219b2ee8SDavid du Colombier } 528219b2ee8SDavid du Colombier 529219b2ee8SDavid du Colombier void 530219b2ee8SDavid du Colombier olsh(Node *n, Node *res) 531219b2ee8SDavid du Colombier { 532219b2ee8SDavid du Colombier Node l, r; 533219b2ee8SDavid du Colombier 534219b2ee8SDavid du Colombier expr(n->left, &l); 535219b2ee8SDavid du Colombier expr(n->right, &r); 536bd389b36SDavid du Colombier res->fmt = l.fmt; 537bd389b36SDavid du Colombier res->op = OCONST; 538bd389b36SDavid du Colombier res->type = TINT; 539bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 540bd389b36SDavid du Colombier error("bad expr type <<"); 541bd389b36SDavid du Colombier res->ival = l.ival<<r.ival; 542219b2ee8SDavid du Colombier } 543219b2ee8SDavid du Colombier 544219b2ee8SDavid du Colombier void 545219b2ee8SDavid du Colombier orsh(Node *n, Node *res) 546219b2ee8SDavid du Colombier { 547219b2ee8SDavid du Colombier Node l, r; 548219b2ee8SDavid du Colombier 549219b2ee8SDavid du Colombier expr(n->left, &l); 550219b2ee8SDavid du Colombier expr(n->right, &r); 551bd389b36SDavid du Colombier res->fmt = l.fmt; 552bd389b36SDavid du Colombier res->op = OCONST; 553bd389b36SDavid du Colombier res->type = TINT; 554bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 555bd389b36SDavid du Colombier error("bad expr type >>"); 5567dd7cddfSDavid du Colombier res->ival = (unsigned)l.ival>>r.ival; 557219b2ee8SDavid du Colombier } 558219b2ee8SDavid du Colombier 559219b2ee8SDavid du Colombier void 560219b2ee8SDavid du Colombier olt(Node *n, Node *res) 561219b2ee8SDavid du Colombier { 562219b2ee8SDavid du Colombier Node l, r; 563219b2ee8SDavid du Colombier 564219b2ee8SDavid du Colombier expr(n->left, &l); 565219b2ee8SDavid du Colombier expr(n->right, &r); 566219b2ee8SDavid du Colombier 567bd389b36SDavid du Colombier res->fmt = l.fmt; 568bd389b36SDavid du Colombier res->op = OCONST; 569bd389b36SDavid du Colombier res->type = TINT; 570bd389b36SDavid du Colombier switch(l.type) { 571219b2ee8SDavid du Colombier default: 572219b2ee8SDavid du Colombier error("bad lhs type <"); 573bd389b36SDavid du Colombier case TINT: 574bd389b36SDavid du Colombier switch(r.type) { 575bd389b36SDavid du Colombier case TINT: 576bd389b36SDavid du Colombier res->ival = l.ival < r.ival; 577bd389b36SDavid du Colombier break; 578bd389b36SDavid du Colombier case TFLOAT: 579bd389b36SDavid du Colombier res->ival = l.ival < r.fval; 580bd389b36SDavid du Colombier break; 581219b2ee8SDavid du Colombier default: 582219b2ee8SDavid du Colombier error("bad rhs type <"); 583bd389b36SDavid du Colombier } 584bd389b36SDavid du Colombier break; 585bd389b36SDavid du Colombier case TFLOAT: 586219b2ee8SDavid du Colombier switch(r.type) { 587bd389b36SDavid du Colombier case TINT: 588bd389b36SDavid du Colombier res->ival = l.fval < r.ival; 589bd389b36SDavid du Colombier break; 590bd389b36SDavid du Colombier case TFLOAT: 591bd389b36SDavid du Colombier res->ival = l.fval < r.fval; 592bd389b36SDavid du Colombier break; 593219b2ee8SDavid du Colombier default: 594219b2ee8SDavid du Colombier error("bad rhs type <"); 595bd389b36SDavid du Colombier } 596bd389b36SDavid du Colombier break; 597bd389b36SDavid du Colombier } 598219b2ee8SDavid du Colombier } 599219b2ee8SDavid du Colombier 600219b2ee8SDavid du Colombier void 601219b2ee8SDavid du Colombier ogt(Node *n, Node *res) 602219b2ee8SDavid du Colombier { 603219b2ee8SDavid du Colombier Node l, r; 604219b2ee8SDavid du Colombier 605219b2ee8SDavid du Colombier expr(n->left, &l); 606219b2ee8SDavid du Colombier expr(n->right, &r); 607bd389b36SDavid du Colombier res->fmt = 'D'; 608bd389b36SDavid du Colombier res->op = OCONST; 609bd389b36SDavid du Colombier res->type = TINT; 610bd389b36SDavid du Colombier switch(l.type) { 611219b2ee8SDavid du Colombier default: 612219b2ee8SDavid du Colombier error("bad lhs type >"); 613bd389b36SDavid du Colombier case TINT: 614bd389b36SDavid du Colombier switch(r.type) { 615bd389b36SDavid du Colombier case TINT: 616bd389b36SDavid du Colombier res->ival = l.ival > r.ival; 617bd389b36SDavid du Colombier break; 618bd389b36SDavid du Colombier case TFLOAT: 619bd389b36SDavid du Colombier res->ival = l.ival > r.fval; 620bd389b36SDavid du Colombier break; 621219b2ee8SDavid du Colombier default: 622219b2ee8SDavid du Colombier error("bad rhs type >"); 623bd389b36SDavid du Colombier } 624bd389b36SDavid du Colombier break; 625bd389b36SDavid du Colombier case TFLOAT: 626219b2ee8SDavid du Colombier switch(r.type) { 627bd389b36SDavid du Colombier case TINT: 628bd389b36SDavid du Colombier res->ival = l.fval > r.ival; 629bd389b36SDavid du Colombier break; 630bd389b36SDavid du Colombier case TFLOAT: 631bd389b36SDavid du Colombier res->ival = l.fval > r.fval; 632bd389b36SDavid du Colombier break; 633219b2ee8SDavid du Colombier default: 634219b2ee8SDavid du Colombier error("bad rhs type >"); 635bd389b36SDavid du Colombier } 636bd389b36SDavid du Colombier break; 637bd389b36SDavid du Colombier } 638219b2ee8SDavid du Colombier } 639219b2ee8SDavid du Colombier 640219b2ee8SDavid du Colombier void 641219b2ee8SDavid du Colombier oleq(Node *n, Node *res) 642219b2ee8SDavid du Colombier { 643219b2ee8SDavid du Colombier Node l, r; 644219b2ee8SDavid du Colombier 645219b2ee8SDavid du Colombier expr(n->left, &l); 646219b2ee8SDavid du Colombier expr(n->right, &r); 647bd389b36SDavid du Colombier res->fmt = 'D'; 648bd389b36SDavid du Colombier res->op = OCONST; 649bd389b36SDavid du Colombier res->type = TINT; 650bd389b36SDavid du Colombier switch(l.type) { 651219b2ee8SDavid du Colombier default: 652219b2ee8SDavid du Colombier error("bad expr type <="); 653bd389b36SDavid du Colombier case TINT: 654bd389b36SDavid du Colombier switch(r.type) { 655bd389b36SDavid du Colombier case TINT: 656bd389b36SDavid du Colombier res->ival = l.ival <= r.ival; 657bd389b36SDavid du Colombier break; 658bd389b36SDavid du Colombier case TFLOAT: 659bd389b36SDavid du Colombier res->ival = l.ival <= r.fval; 660bd389b36SDavid du Colombier break; 661219b2ee8SDavid du Colombier default: 662bd389b36SDavid du Colombier error("bad expr type <="); 663bd389b36SDavid du Colombier } 664bd389b36SDavid du Colombier break; 665bd389b36SDavid du Colombier case TFLOAT: 666219b2ee8SDavid du Colombier switch(r.type) { 667bd389b36SDavid du Colombier case TINT: 668bd389b36SDavid du Colombier res->ival = l.fval <= r.ival; 669bd389b36SDavid du Colombier break; 670bd389b36SDavid du Colombier case TFLOAT: 671bd389b36SDavid du Colombier res->ival = l.fval <= r.fval; 672bd389b36SDavid du Colombier break; 673219b2ee8SDavid du Colombier default: 674bd389b36SDavid du Colombier error("bad expr type <="); 675bd389b36SDavid du Colombier } 676bd389b36SDavid du Colombier break; 677bd389b36SDavid du Colombier } 678219b2ee8SDavid du Colombier } 679219b2ee8SDavid du Colombier 680219b2ee8SDavid du Colombier void 681219b2ee8SDavid du Colombier ogeq(Node *n, Node *res) 682219b2ee8SDavid du Colombier { 683219b2ee8SDavid du Colombier Node l, r; 684219b2ee8SDavid du Colombier 685219b2ee8SDavid du Colombier expr(n->left, &l); 686219b2ee8SDavid du Colombier expr(n->right, &r); 687bd389b36SDavid du Colombier res->fmt = 'D'; 688bd389b36SDavid du Colombier res->op = OCONST; 689bd389b36SDavid du Colombier res->type = TINT; 690bd389b36SDavid du Colombier switch(l.type) { 691219b2ee8SDavid du Colombier default: 692219b2ee8SDavid du Colombier error("bad lhs type >="); 693bd389b36SDavid du Colombier case TINT: 694bd389b36SDavid du Colombier switch(r.type) { 695bd389b36SDavid du Colombier case TINT: 696bd389b36SDavid du Colombier res->ival = l.ival >= r.ival; 697bd389b36SDavid du Colombier break; 698bd389b36SDavid du Colombier case TFLOAT: 699bd389b36SDavid du Colombier res->ival = l.ival >= r.fval; 700bd389b36SDavid du Colombier break; 701219b2ee8SDavid du Colombier default: 702219b2ee8SDavid du Colombier error("bad rhs type >="); 703bd389b36SDavid du Colombier } 704bd389b36SDavid du Colombier break; 705bd389b36SDavid du Colombier case TFLOAT: 706219b2ee8SDavid du Colombier switch(r.type) { 707bd389b36SDavid du Colombier case TINT: 708bd389b36SDavid du Colombier res->ival = l.fval >= r.ival; 709bd389b36SDavid du Colombier break; 710bd389b36SDavid du Colombier case TFLOAT: 711bd389b36SDavid du Colombier res->ival = l.fval >= r.fval; 712bd389b36SDavid du Colombier break; 713219b2ee8SDavid du Colombier default: 714219b2ee8SDavid du Colombier error("bad rhs type >="); 715bd389b36SDavid du Colombier } 716bd389b36SDavid du Colombier break; 717bd389b36SDavid du Colombier } 718219b2ee8SDavid du Colombier } 719219b2ee8SDavid du Colombier 720219b2ee8SDavid du Colombier void 721219b2ee8SDavid du Colombier oeq(Node *n, Node *res) 722219b2ee8SDavid du Colombier { 723219b2ee8SDavid du Colombier Node l, r; 724219b2ee8SDavid du Colombier 725219b2ee8SDavid du Colombier expr(n->left, &l); 726219b2ee8SDavid du Colombier expr(n->right, &r); 727bd389b36SDavid du Colombier res->fmt = 'D'; 728bd389b36SDavid du Colombier res->op = OCONST; 729bd389b36SDavid du Colombier res->type = TINT; 730219b2ee8SDavid du Colombier res->ival = 0; 731bd389b36SDavid du Colombier switch(l.type) { 732219b2ee8SDavid du Colombier default: 733219b2ee8SDavid du Colombier break; 734bd389b36SDavid du Colombier case TINT: 735bd389b36SDavid du Colombier switch(r.type) { 736bd389b36SDavid du Colombier case TINT: 737bd389b36SDavid du Colombier res->ival = l.ival == r.ival; 738bd389b36SDavid du Colombier break; 739bd389b36SDavid du Colombier case TFLOAT: 740bd389b36SDavid du Colombier res->ival = l.ival == r.fval; 741bd389b36SDavid du Colombier break; 742219b2ee8SDavid du Colombier default: 743219b2ee8SDavid du Colombier break; 744bd389b36SDavid du Colombier } 745bd389b36SDavid du Colombier break; 746bd389b36SDavid du Colombier case TFLOAT: 747219b2ee8SDavid du Colombier switch(r.type) { 748bd389b36SDavid du Colombier case TINT: 749bd389b36SDavid du Colombier res->ival = l.fval == r.ival; 750bd389b36SDavid du Colombier break; 751bd389b36SDavid du Colombier case TFLOAT: 752bd389b36SDavid du Colombier res->ival = l.fval == r.fval; 753bd389b36SDavid du Colombier break; 754219b2ee8SDavid du Colombier default: 755219b2ee8SDavid du Colombier break; 756bd389b36SDavid du Colombier } 757bd389b36SDavid du Colombier break; 758bd389b36SDavid du Colombier case TSTRING: 759bd389b36SDavid du Colombier if(r.type == TSTRING) { 760bd389b36SDavid du Colombier res->ival = scmp(r.string, l.string); 761bd389b36SDavid du Colombier break; 762bd389b36SDavid du Colombier } 763219b2ee8SDavid du Colombier break; 764bd389b36SDavid du Colombier case TLIST: 765bd389b36SDavid du Colombier if(r.type == TLIST) { 766bd389b36SDavid du Colombier res->ival = listcmp(l.l, r.l); 767bd389b36SDavid du Colombier break; 768bd389b36SDavid du Colombier } 769bd389b36SDavid du Colombier break; 770bd389b36SDavid du Colombier } 771219b2ee8SDavid du Colombier if(n->op == ONEQ) 772219b2ee8SDavid du Colombier res->ival = !res->ival; 773bd389b36SDavid du Colombier } 774219b2ee8SDavid du Colombier 775219b2ee8SDavid du Colombier 776219b2ee8SDavid du Colombier void 777219b2ee8SDavid du Colombier oland(Node *n, Node *res) 778219b2ee8SDavid du Colombier { 779219b2ee8SDavid du Colombier Node l, r; 780219b2ee8SDavid du Colombier 781219b2ee8SDavid du Colombier expr(n->left, &l); 782219b2ee8SDavid du Colombier expr(n->right, &r); 783bd389b36SDavid du Colombier res->fmt = l.fmt; 784bd389b36SDavid du Colombier res->op = OCONST; 785bd389b36SDavid du Colombier res->type = TINT; 786bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 787bd389b36SDavid du Colombier error("bad expr type &"); 788bd389b36SDavid du Colombier res->ival = l.ival&r.ival; 789219b2ee8SDavid du Colombier } 790219b2ee8SDavid du Colombier 791219b2ee8SDavid du Colombier void 792219b2ee8SDavid du Colombier oxor(Node *n, Node *res) 793219b2ee8SDavid du Colombier { 794219b2ee8SDavid du Colombier Node l, r; 795219b2ee8SDavid du Colombier 796219b2ee8SDavid du Colombier expr(n->left, &l); 797219b2ee8SDavid du Colombier expr(n->right, &r); 798bd389b36SDavid du Colombier res->fmt = l.fmt; 799bd389b36SDavid du Colombier res->op = OCONST; 800bd389b36SDavid du Colombier res->type = TINT; 801bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 802bd389b36SDavid du Colombier error("bad expr type ^"); 803bd389b36SDavid du Colombier res->ival = l.ival^r.ival; 804219b2ee8SDavid du Colombier } 805219b2ee8SDavid du Colombier 806219b2ee8SDavid du Colombier void 807219b2ee8SDavid du Colombier olor(Node *n, Node *res) 808219b2ee8SDavid du Colombier { 809219b2ee8SDavid du Colombier Node l, r; 810219b2ee8SDavid du Colombier 811219b2ee8SDavid du Colombier expr(n->left, &l); 812219b2ee8SDavid du Colombier expr(n->right, &r); 813bd389b36SDavid du Colombier res->fmt = l.fmt; 814bd389b36SDavid du Colombier res->op = OCONST; 815bd389b36SDavid du Colombier res->type = TINT; 816bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 817bd389b36SDavid du Colombier error("bad expr type |"); 818bd389b36SDavid du Colombier res->ival = l.ival|r.ival; 819219b2ee8SDavid du Colombier } 820219b2ee8SDavid du Colombier 821219b2ee8SDavid du Colombier void 822219b2ee8SDavid du Colombier ocand(Node *n, Node *res) 823219b2ee8SDavid du Colombier { 824219b2ee8SDavid du Colombier Node l, r; 825219b2ee8SDavid du Colombier 826bd389b36SDavid du Colombier res->fmt = l.fmt; 827bd389b36SDavid du Colombier res->op = OCONST; 828bd389b36SDavid du Colombier res->type = TINT; 829219b2ee8SDavid du Colombier res->ival = 0; 830219b2ee8SDavid du Colombier expr(n->left, &l); 831219b2ee8SDavid du Colombier if(bool(&l) == 0) 832219b2ee8SDavid du Colombier return; 833219b2ee8SDavid du Colombier expr(n->right, &r); 834219b2ee8SDavid du Colombier if(bool(&r) == 0) 835219b2ee8SDavid du Colombier return; 836219b2ee8SDavid du Colombier res->ival = 1; 837219b2ee8SDavid du Colombier } 838219b2ee8SDavid du Colombier 839219b2ee8SDavid du Colombier void 840219b2ee8SDavid du Colombier onot(Node *n, Node *res) 841219b2ee8SDavid du Colombier { 842219b2ee8SDavid du Colombier Node l; 843219b2ee8SDavid du Colombier 844bd389b36SDavid du Colombier res->op = OCONST; 845bd389b36SDavid du Colombier res->type = TINT; 846219b2ee8SDavid du Colombier res->ival = 0; 847219b2ee8SDavid du Colombier expr(n->left, &l); 848219b2ee8SDavid du Colombier if(bool(&l) == 0) 849219b2ee8SDavid du Colombier res->ival = 1; 850219b2ee8SDavid du Colombier } 851219b2ee8SDavid du Colombier 852219b2ee8SDavid du Colombier void 853219b2ee8SDavid du Colombier ocor(Node *n, Node *res) 854219b2ee8SDavid du Colombier { 855219b2ee8SDavid du Colombier Node l, r; 856219b2ee8SDavid du Colombier 857219b2ee8SDavid du Colombier res->op = OCONST; 858219b2ee8SDavid du Colombier res->type = TINT; 859219b2ee8SDavid du Colombier res->ival = 0; 860219b2ee8SDavid du Colombier expr(n->left, &l); 861219b2ee8SDavid du Colombier if(bool(&l)) { 862219b2ee8SDavid du Colombier res->ival = 1; 863219b2ee8SDavid du Colombier return; 864219b2ee8SDavid du Colombier } 865219b2ee8SDavid du Colombier expr(n->right, &r); 866219b2ee8SDavid du Colombier if(bool(&r)) { 867219b2ee8SDavid du Colombier res->ival = 1; 868219b2ee8SDavid du Colombier return; 869219b2ee8SDavid du Colombier } 870219b2ee8SDavid du Colombier } 871219b2ee8SDavid du Colombier 872219b2ee8SDavid du Colombier void 873219b2ee8SDavid du Colombier oeinc(Node *n, Node *res) 874219b2ee8SDavid du Colombier { 875219b2ee8SDavid du Colombier Value *v; 876219b2ee8SDavid du Colombier 877219b2ee8SDavid du Colombier chklval(n->left); 878219b2ee8SDavid du Colombier v = n->left->sym->v; 879bd389b36SDavid du Colombier res->op = OCONST; 880bd389b36SDavid du Colombier res->type = v->type; 881bd389b36SDavid du Colombier switch(v->type) { 882bd389b36SDavid du Colombier case TINT: 883bd389b36SDavid du Colombier if(n->op == OEDEC) 884bd389b36SDavid du Colombier v->ival -= fmtsize(v); 885bd389b36SDavid du Colombier else 886bd389b36SDavid du Colombier v->ival += fmtsize(v); 887bd389b36SDavid du Colombier break; 888bd389b36SDavid du Colombier case TFLOAT: 889bd389b36SDavid du Colombier if(n->op == OEDEC) 890bd389b36SDavid du Colombier v->fval--; 891bd389b36SDavid du Colombier else 892bd389b36SDavid du Colombier v->fval++; 893bd389b36SDavid du Colombier break; 894bd389b36SDavid du Colombier default: 895bd389b36SDavid du Colombier error("bad type for pre --/++"); 896bd389b36SDavid du Colombier } 897bd389b36SDavid du Colombier res->Store = v->Store; 898219b2ee8SDavid du Colombier } 899219b2ee8SDavid du Colombier 900219b2ee8SDavid du Colombier void 901219b2ee8SDavid du Colombier opinc(Node *n, Node *res) 902219b2ee8SDavid du Colombier { 903219b2ee8SDavid du Colombier Value *v; 904219b2ee8SDavid du Colombier 905219b2ee8SDavid du Colombier chklval(n->left); 906219b2ee8SDavid du Colombier v = n->left->sym->v; 907bd389b36SDavid du Colombier res->op = OCONST; 908bd389b36SDavid du Colombier res->type = v->type; 909bd389b36SDavid du Colombier res->Store = v->Store; 910bd389b36SDavid du Colombier switch(v->type) { 911bd389b36SDavid du Colombier case TINT: 912bd389b36SDavid du Colombier if(n->op == OPDEC) 913bd389b36SDavid du Colombier v->ival -= fmtsize(v); 914bd389b36SDavid du Colombier else 915bd389b36SDavid du Colombier v->ival += fmtsize(v); 916bd389b36SDavid du Colombier break; 917bd389b36SDavid du Colombier case TFLOAT: 918bd389b36SDavid du Colombier if(n->op == OPDEC) 919bd389b36SDavid du Colombier v->fval--; 920bd389b36SDavid du Colombier else 921bd389b36SDavid du Colombier v->fval++; 922bd389b36SDavid du Colombier break; 923bd389b36SDavid du Colombier default: 924bd389b36SDavid du Colombier error("bad type for post --/++"); 925bd389b36SDavid du Colombier } 926219b2ee8SDavid du Colombier } 927219b2ee8SDavid du Colombier 928219b2ee8SDavid du Colombier void 929219b2ee8SDavid du Colombier ocall(Node *n, Node *res) 930219b2ee8SDavid du Colombier { 931219b2ee8SDavid du Colombier Lsym *s; 932219b2ee8SDavid du Colombier Rplace *rsav; 933219b2ee8SDavid du Colombier 934bd389b36SDavid du Colombier res->op = OCONST; /* Default return value */ 935bd389b36SDavid du Colombier res->type = TLIST; 936bd389b36SDavid du Colombier res->l = 0; 937bd389b36SDavid du Colombier 938219b2ee8SDavid du Colombier chklval(n->left); 939219b2ee8SDavid du Colombier s = n->left->sym; 940bd389b36SDavid du Colombier 9410b459c2cSDavid du Colombier if(n->builtin && !s->builtin){ 9420b459c2cSDavid du Colombier error("no builtin %s", s->name); 9430b459c2cSDavid du Colombier return; 9440b459c2cSDavid du Colombier } 9450b459c2cSDavid du Colombier if(s->builtin && (n->builtin || s->proc == 0)) { 946219b2ee8SDavid du Colombier (*s->builtin)(res, n->right); 947219b2ee8SDavid du Colombier return; 948bd389b36SDavid du Colombier } 949bd389b36SDavid du Colombier if(s->proc == 0) 950bd389b36SDavid du Colombier error("no function %s", s->name); 951bd389b36SDavid du Colombier 952bd389b36SDavid du Colombier rsav = ret; 953219b2ee8SDavid du Colombier call(s->name, n->right, s->proc->left, s->proc->right, res); 954bd389b36SDavid du Colombier ret = rsav; 955bd389b36SDavid du Colombier } 956219b2ee8SDavid du Colombier 957219b2ee8SDavid du Colombier void 958219b2ee8SDavid du Colombier ofmt(Node *n, Node *res) 959219b2ee8SDavid du Colombier { 960219b2ee8SDavid du Colombier expr(n->left, res); 961219b2ee8SDavid du Colombier res->fmt = n->right->ival; 962bd389b36SDavid du Colombier } 963219b2ee8SDavid du Colombier 964219b2ee8SDavid du Colombier void 965219b2ee8SDavid du Colombier owhat(Node *n, Node *res) 966219b2ee8SDavid du Colombier { 967219b2ee8SDavid du Colombier res->op = OCONST; /* Default return value */ 968219b2ee8SDavid du Colombier res->type = TLIST; 969219b2ee8SDavid du Colombier res->l = 0; 970219b2ee8SDavid du Colombier whatis(n->sym); 971219b2ee8SDavid du Colombier } 972219b2ee8SDavid du Colombier 973219b2ee8SDavid du Colombier void (*expop[])(Node*, Node*) = 974219b2ee8SDavid du Colombier { 975219b2ee8SDavid du Colombier [ONAME] oname, 976219b2ee8SDavid du Colombier [OCONST] oconst, 977219b2ee8SDavid du Colombier [OMUL] omul, 978219b2ee8SDavid du Colombier [ODIV] odiv, 979219b2ee8SDavid du Colombier [OMOD] omod, 980219b2ee8SDavid du Colombier [OADD] oadd, 981219b2ee8SDavid du Colombier [OSUB] osub, 982219b2ee8SDavid du Colombier [ORSH] orsh, 983219b2ee8SDavid du Colombier [OLSH] olsh, 984219b2ee8SDavid du Colombier [OLT] olt, 985219b2ee8SDavid du Colombier [OGT] ogt, 986219b2ee8SDavid du Colombier [OLEQ] oleq, 987219b2ee8SDavid du Colombier [OGEQ] ogeq, 988219b2ee8SDavid du Colombier [OEQ] oeq, 989219b2ee8SDavid du Colombier [ONEQ] oeq, 990219b2ee8SDavid du Colombier [OLAND] oland, 991219b2ee8SDavid du Colombier [OXOR] oxor, 992219b2ee8SDavid du Colombier [OLOR] olor, 993219b2ee8SDavid du Colombier [OCAND] ocand, 994219b2ee8SDavid du Colombier [OCOR] ocor, 995219b2ee8SDavid du Colombier [OASGN] oasgn, 996219b2ee8SDavid du Colombier [OINDM] oindm, 997219b2ee8SDavid du Colombier [OEDEC] oeinc, 998219b2ee8SDavid du Colombier [OEINC] oeinc, 999219b2ee8SDavid du Colombier [OPINC] opinc, 1000219b2ee8SDavid du Colombier [OPDEC] opinc, 1001219b2ee8SDavid du Colombier [ONOT] onot, 1002219b2ee8SDavid du Colombier [OIF] 0, 1003219b2ee8SDavid du Colombier [ODO] 0, 1004219b2ee8SDavid du Colombier [OLIST] olist, 1005219b2ee8SDavid du Colombier [OCALL] ocall, 1006219b2ee8SDavid du Colombier [OCTRUCT] octruct, 1007219b2ee8SDavid du Colombier [OWHILE] 0, 1008219b2ee8SDavid du Colombier [OELSE] 0, 1009219b2ee8SDavid du Colombier [OHEAD] ohead, 1010219b2ee8SDavid du Colombier [OTAIL] otail, 1011219b2ee8SDavid du Colombier [OAPPEND] oappend, 1012219b2ee8SDavid du Colombier [ORET] 0, 1013219b2ee8SDavid du Colombier [OINDEX] oindex, 1014219b2ee8SDavid du Colombier [OINDC] oindc, 1015219b2ee8SDavid du Colombier [ODOT] odot, 1016219b2ee8SDavid du Colombier [OLOCAL] 0, 1017219b2ee8SDavid du Colombier [OFRAME] oframe, 1018219b2ee8SDavid du Colombier [OCOMPLEX] 0, 1019219b2ee8SDavid du Colombier [ODELETE] odelete, 1020219b2ee8SDavid du Colombier [OCAST] ocast, 1021219b2ee8SDavid du Colombier [OFMT] ofmt, 1022219b2ee8SDavid du Colombier [OEVAL] oeval, 1023219b2ee8SDavid du Colombier [OWHAT] owhat, 1024219b2ee8SDavid du Colombier }; 1025