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, 231bd28109SDavid du Colombier ['W'] 8, 24219b2ee8SDavid du Colombier ['X'] 4, 257dd7cddfSDavid du Colombier ['Y'] 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, 3937e88e97SDavid du Colombier ['3'] 10, 4037e88e97SDavid du Colombier ['8'] 10, 41bd389b36SDavid du Colombier }; 42bd389b36SDavid du Colombier 43bd389b36SDavid du Colombier int 44bd389b36SDavid du Colombier fmtsize(Value *v) 45bd389b36SDavid du Colombier { 46219b2ee8SDavid du Colombier int ret; 47219b2ee8SDavid du Colombier 48bd389b36SDavid du Colombier switch(v->fmt) { 49bd389b36SDavid du Colombier default: 50bd389b36SDavid du Colombier return fsize[v->fmt]; 51bd389b36SDavid du Colombier case 'i': 52bd389b36SDavid du Colombier case 'I': 53219b2ee8SDavid du Colombier if(v->type != TINT || machdata == 0) 54bd389b36SDavid du Colombier error("no size for i fmt pointer ++/--"); 55219b2ee8SDavid du Colombier ret = (*machdata->instsize)(cormap, v->ival); 56219b2ee8SDavid du Colombier if(ret < 0) { 57219b2ee8SDavid du Colombier ret = (*machdata->instsize)(symmap, v->ival); 58219b2ee8SDavid du Colombier if(ret < 0) 59219b2ee8SDavid du Colombier error("%r"); 60219b2ee8SDavid du Colombier } 61219b2ee8SDavid du Colombier return ret; 62bd389b36SDavid du Colombier } 63bd389b36SDavid du Colombier } 64bd389b36SDavid du Colombier 65bd389b36SDavid du Colombier void 66bd389b36SDavid du Colombier chklval(Node *lp) 67bd389b36SDavid du Colombier { 68bd389b36SDavid du Colombier if(lp->op != ONAME) 69bd389b36SDavid du Colombier error("need l-value"); 70bd389b36SDavid du Colombier } 71bd389b36SDavid du Colombier 72bd389b36SDavid du Colombier void 73219b2ee8SDavid du Colombier olist(Node *n, Node *res) 74219b2ee8SDavid du Colombier { 75219b2ee8SDavid du Colombier expr(n->left, res); 76219b2ee8SDavid du Colombier expr(n->right, res); 77219b2ee8SDavid du Colombier } 78219b2ee8SDavid du Colombier 79219b2ee8SDavid du Colombier void 80219b2ee8SDavid du Colombier oeval(Node *n, Node *res) 81219b2ee8SDavid du Colombier { 82219b2ee8SDavid du Colombier expr(n->left, res); 83219b2ee8SDavid du Colombier if(res->type != TCODE) 84219b2ee8SDavid du Colombier error("bad type for eval"); 85219b2ee8SDavid du Colombier expr(res->cc, res); 86219b2ee8SDavid du Colombier } 87219b2ee8SDavid du Colombier 88219b2ee8SDavid du Colombier void 89219b2ee8SDavid du Colombier ocast(Node *n, Node *res) 90219b2ee8SDavid du Colombier { 91219b2ee8SDavid du Colombier if(n->sym->lt == 0) 92219b2ee8SDavid du Colombier error("%s is not a complex type", n->sym->name); 93219b2ee8SDavid du Colombier 94219b2ee8SDavid du Colombier expr(n->left, res); 95219b2ee8SDavid du Colombier res->comt = n->sym->lt; 96219b2ee8SDavid du Colombier res->fmt = 'a'; 97219b2ee8SDavid du Colombier } 98219b2ee8SDavid du Colombier 99219b2ee8SDavid du Colombier void 100219b2ee8SDavid du Colombier oindm(Node *n, Node *res) 101bd389b36SDavid du Colombier { 102bd389b36SDavid du Colombier Map *m; 103219b2ee8SDavid du Colombier Node l; 104bd389b36SDavid du Colombier 105bd389b36SDavid du Colombier m = cormap; 106bd389b36SDavid du Colombier if(m == 0) 107219b2ee8SDavid du Colombier m = symmap; 108219b2ee8SDavid du Colombier expr(n->left, &l); 109219b2ee8SDavid du Colombier if(l.type != TINT) 110219b2ee8SDavid du Colombier error("bad type for *"); 111219b2ee8SDavid du Colombier if(m == 0) 112219b2ee8SDavid du Colombier error("no map for *"); 113bd389b36SDavid du Colombier indir(m, l.ival, l.fmt, res); 114bd389b36SDavid du Colombier res->comt = l.comt; 115219b2ee8SDavid du Colombier } 116219b2ee8SDavid du Colombier 117219b2ee8SDavid du Colombier void 118219b2ee8SDavid du Colombier oindc(Node *n, Node *res) 119219b2ee8SDavid du Colombier { 120219b2ee8SDavid du Colombier Map *m; 121219b2ee8SDavid du Colombier Node l; 122219b2ee8SDavid du Colombier 123219b2ee8SDavid du Colombier m = symmap; 124219b2ee8SDavid du Colombier if(m == 0) 125219b2ee8SDavid du Colombier m = cormap; 126219b2ee8SDavid du Colombier expr(n->left, &l); 127219b2ee8SDavid du Colombier if(l.type != TINT) 128219b2ee8SDavid du Colombier error("bad type for @"); 129219b2ee8SDavid du Colombier if(m == 0) 130219b2ee8SDavid du Colombier error("no map for @"); 131219b2ee8SDavid du Colombier indir(m, l.ival, l.fmt, res); 132219b2ee8SDavid du Colombier res->comt = l.comt; 133219b2ee8SDavid du Colombier } 134219b2ee8SDavid du Colombier 135219b2ee8SDavid du Colombier void 136219b2ee8SDavid du Colombier oframe(Node *n, Node *res) 137219b2ee8SDavid du Colombier { 138219b2ee8SDavid du Colombier char *p; 139219b2ee8SDavid du Colombier Node *lp; 1404de34a7eSDavid du Colombier uvlong ival; 141219b2ee8SDavid du Colombier Frtype *f; 142219b2ee8SDavid du Colombier 143219b2ee8SDavid du Colombier p = n->sym->name; 144219b2ee8SDavid du Colombier while(*p && *p == '$') 145219b2ee8SDavid du Colombier p++; 146219b2ee8SDavid du Colombier lp = n->left; 147219b2ee8SDavid du Colombier if(localaddr(cormap, p, lp->sym->name, &ival, rget) < 0) 148219b2ee8SDavid du Colombier error("colon: %r"); 149219b2ee8SDavid du Colombier 150219b2ee8SDavid du Colombier res->ival = ival; 151219b2ee8SDavid du Colombier res->op = OCONST; 152219b2ee8SDavid du Colombier res->fmt = 'X'; 153219b2ee8SDavid du Colombier res->type = TINT; 154219b2ee8SDavid du Colombier 155219b2ee8SDavid du Colombier /* Try and set comt */ 156219b2ee8SDavid du Colombier for(f = n->sym->local; f; f = f->next) { 157219b2ee8SDavid du Colombier if(f->var == lp->sym) { 158219b2ee8SDavid du Colombier res->comt = f->type; 159219b2ee8SDavid du Colombier res->fmt = 'a'; 160bd389b36SDavid du Colombier break; 161219b2ee8SDavid du Colombier } 162219b2ee8SDavid du Colombier } 163219b2ee8SDavid du Colombier } 164219b2ee8SDavid du Colombier 165219b2ee8SDavid du Colombier void 166219b2ee8SDavid du Colombier oindex(Node *n, Node *res) 167219b2ee8SDavid du Colombier { 168219b2ee8SDavid du Colombier Node l, r; 169219b2ee8SDavid du Colombier 170219b2ee8SDavid du Colombier expr(n->left, &l); 171219b2ee8SDavid du Colombier expr(n->right, &r); 172219b2ee8SDavid du Colombier 173bd389b36SDavid du Colombier if(r.type != TINT) 174bd389b36SDavid du Colombier error("bad type for []"); 175219b2ee8SDavid du Colombier 176bd389b36SDavid du Colombier switch(l.type) { 177bd389b36SDavid du Colombier default: 178bd389b36SDavid du Colombier error("lhs[] has bad type"); 179bd389b36SDavid du Colombier case TINT: 180219b2ee8SDavid du Colombier indir(cormap, l.ival+(r.ival*fsize[l.fmt]), l.fmt, res); 181219b2ee8SDavid du Colombier res->comt = l.comt; 182219b2ee8SDavid du Colombier res->fmt = l.fmt; 183bd389b36SDavid du Colombier break; 184bd389b36SDavid du Colombier case TLIST: 185bd389b36SDavid du Colombier nthelem(l.l, r.ival, res); 186bd389b36SDavid du Colombier break; 187bd389b36SDavid du Colombier case TSTRING: 188bd389b36SDavid du Colombier res->ival = 0; 189219b2ee8SDavid du Colombier if(r.ival >= 0 && r.ival < l.string->len) { 190219b2ee8SDavid du Colombier int xx8; /* to get around bug in vc */ 191219b2ee8SDavid du Colombier xx8 = r.ival; 192219b2ee8SDavid du Colombier res->ival = l.string->string[xx8]; 193219b2ee8SDavid du Colombier } 194bd389b36SDavid du Colombier res->op = OCONST; 195bd389b36SDavid du Colombier res->type = TINT; 196bd389b36SDavid du Colombier res->fmt = 'c'; 197bd389b36SDavid du Colombier break; 198bd389b36SDavid du Colombier } 199219b2ee8SDavid du Colombier } 200219b2ee8SDavid du Colombier 201219b2ee8SDavid du Colombier void 202219b2ee8SDavid du Colombier oappend(Node *n, Node *res) 203219b2ee8SDavid du Colombier { 204*7c70c028SDavid du Colombier Value *v; 205219b2ee8SDavid du Colombier Node r, l; 206*7c70c028SDavid du Colombier int empty; 207219b2ee8SDavid du Colombier 208219b2ee8SDavid du Colombier expr(n->left, &l); 209219b2ee8SDavid du Colombier expr(n->right, &r); 210bd389b36SDavid du Colombier if(l.type != TLIST) 211bd389b36SDavid du Colombier error("must append to list"); 212*7c70c028SDavid du Colombier empty = (l.l == nil && (n->left->op == ONAME)); 213bd389b36SDavid du Colombier append(res, &l, &r); 214*7c70c028SDavid du Colombier if(empty) { 215*7c70c028SDavid du Colombier v = n->left->sym->v; 216*7c70c028SDavid du Colombier v->type = res->type; 217*7c70c028SDavid du Colombier v->Store = res->Store; 218*7c70c028SDavid du Colombier v->comt = res->comt; 219*7c70c028SDavid du Colombier } 220219b2ee8SDavid du Colombier } 221219b2ee8SDavid du Colombier 222219b2ee8SDavid du Colombier void 223219b2ee8SDavid du Colombier odelete(Node *n, Node *res) 224219b2ee8SDavid du Colombier { 225219b2ee8SDavid du Colombier Node l, r; 226219b2ee8SDavid du Colombier 227219b2ee8SDavid du Colombier expr(n->left, &l); 228219b2ee8SDavid du Colombier expr(n->right, &r); 229bd389b36SDavid du Colombier if(l.type != TLIST) 230bd389b36SDavid du Colombier error("must delete from list"); 231bd389b36SDavid du Colombier if(r.type != TINT) 232bd389b36SDavid du Colombier error("delete index must be integer"); 233bd389b36SDavid du Colombier 234bd389b36SDavid du Colombier delete(l.l, r.ival, res); 235219b2ee8SDavid du Colombier } 236219b2ee8SDavid du Colombier 237219b2ee8SDavid du Colombier void 238219b2ee8SDavid du Colombier ohead(Node *n, Node *res) 239219b2ee8SDavid du Colombier { 240219b2ee8SDavid du Colombier Node l; 241219b2ee8SDavid du Colombier 242219b2ee8SDavid du Colombier expr(n->left, &l); 243bd389b36SDavid du Colombier if(l.type != TLIST) 244bd389b36SDavid du Colombier error("head needs list"); 245bd389b36SDavid du Colombier res->op = OCONST; 246bd389b36SDavid du Colombier if(l.l) { 247bd389b36SDavid du Colombier res->type = l.l->type; 248bd389b36SDavid du Colombier res->Store = l.l->Store; 249bd389b36SDavid du Colombier } 250bd389b36SDavid du Colombier else { 251bd389b36SDavid du Colombier res->type = TLIST; 252bd389b36SDavid du Colombier res->l = 0; 253bd389b36SDavid du Colombier } 254219b2ee8SDavid du Colombier } 255219b2ee8SDavid du Colombier 256219b2ee8SDavid du Colombier void 257219b2ee8SDavid du Colombier otail(Node *n, Node *res) 258219b2ee8SDavid du Colombier { 259219b2ee8SDavid du Colombier Node l; 260219b2ee8SDavid du Colombier 261219b2ee8SDavid du Colombier expr(n->left, &l); 262bd389b36SDavid du Colombier if(l.type != TLIST) 263bd389b36SDavid du Colombier error("tail needs list"); 264bd389b36SDavid du Colombier res->op = OCONST; 265bd389b36SDavid du Colombier res->type = TLIST; 266bd389b36SDavid du Colombier if(l.l) 267219b2ee8SDavid du Colombier res->l = l.l->next; 268bd389b36SDavid du Colombier else 269219b2ee8SDavid du Colombier res->l = 0; 270219b2ee8SDavid du Colombier } 271219b2ee8SDavid du Colombier 272219b2ee8SDavid du Colombier void 273219b2ee8SDavid du Colombier oconst(Node *n, Node *res) 274219b2ee8SDavid du Colombier { 275219b2ee8SDavid du Colombier res->op = OCONST; 276219b2ee8SDavid du Colombier res->type = n->type; 277219b2ee8SDavid du Colombier res->Store = n->Store; 278219b2ee8SDavid du Colombier res->comt = n->comt; 279219b2ee8SDavid du Colombier } 280219b2ee8SDavid du Colombier 281219b2ee8SDavid du Colombier void 282219b2ee8SDavid du Colombier oname(Node *n, Node *res) 283219b2ee8SDavid du Colombier { 284219b2ee8SDavid du Colombier Value *v; 285219b2ee8SDavid du Colombier 286bd389b36SDavid du Colombier v = n->sym->v; 287bd389b36SDavid du Colombier if(v->set == 0) 288bd389b36SDavid du Colombier error("%s used but not set", n->sym->name); 289bd389b36SDavid du Colombier res->op = OCONST; 290bd389b36SDavid du Colombier res->type = v->type; 291bd389b36SDavid du Colombier res->Store = v->Store; 292219b2ee8SDavid du Colombier res->comt = v->comt; 293219b2ee8SDavid du Colombier } 294219b2ee8SDavid du Colombier 295219b2ee8SDavid du Colombier void 296219b2ee8SDavid du Colombier octruct(Node *n, Node *res) 297219b2ee8SDavid du Colombier { 298bd389b36SDavid du Colombier res->op = OCONST; 299bd389b36SDavid du Colombier res->type = TLIST; 300219b2ee8SDavid du Colombier res->l = construct(n->left); 301219b2ee8SDavid du Colombier } 302219b2ee8SDavid du Colombier 303219b2ee8SDavid du Colombier void 304219b2ee8SDavid du Colombier oasgn(Node *n, Node *res) 305219b2ee8SDavid du Colombier { 306219b2ee8SDavid du Colombier Node *lp, r; 307219b2ee8SDavid du Colombier Value *v; 308219b2ee8SDavid du Colombier 309219b2ee8SDavid du Colombier lp = n->left; 310bd389b36SDavid du Colombier switch(lp->op) { 311bd389b36SDavid du Colombier case OINDM: 312219b2ee8SDavid du Colombier windir(cormap, lp->left, n->right, res); 313bd389b36SDavid du Colombier break; 314bd389b36SDavid du Colombier case OINDC: 315219b2ee8SDavid du Colombier windir(symmap, lp->left, n->right, res); 316bd389b36SDavid du Colombier break; 317bd389b36SDavid du Colombier default: 318bd389b36SDavid du Colombier chklval(lp); 319bd389b36SDavid du Colombier v = lp->sym->v; 320219b2ee8SDavid du Colombier expr(n->right, &r); 321bd389b36SDavid du Colombier v->set = 1; 322bd389b36SDavid du Colombier v->type = r.type; 323bd389b36SDavid du Colombier v->Store = r.Store; 324219b2ee8SDavid du Colombier res->op = OCONST; 325219b2ee8SDavid du Colombier res->type = v->type; 326219b2ee8SDavid du Colombier res->Store = v->Store; 327219b2ee8SDavid du Colombier res->comt = v->comt; 328bd389b36SDavid du Colombier } 329219b2ee8SDavid du Colombier } 330219b2ee8SDavid du Colombier 331219b2ee8SDavid du Colombier void 332219b2ee8SDavid du Colombier oadd(Node *n, Node *res) 333219b2ee8SDavid du Colombier { 334219b2ee8SDavid du Colombier Node l, r; 335219b2ee8SDavid du Colombier 336219b2ee8SDavid du Colombier expr(n->left, &l); 337219b2ee8SDavid du Colombier expr(n->right, &r); 338bd389b36SDavid du Colombier res->fmt = l.fmt; 339bd389b36SDavid du Colombier res->op = OCONST; 340bd389b36SDavid du Colombier res->type = TFLOAT; 341bd389b36SDavid du Colombier switch(l.type) { 342219b2ee8SDavid du Colombier default: 343219b2ee8SDavid du Colombier error("bad lhs type +"); 344bd389b36SDavid du Colombier case TINT: 345bd389b36SDavid du Colombier switch(r.type) { 346bd389b36SDavid du Colombier case TINT: 347bd389b36SDavid du Colombier res->type = TINT; 348bd389b36SDavid du Colombier res->ival = l.ival+r.ival; 349bd389b36SDavid du Colombier break; 350bd389b36SDavid du Colombier case TFLOAT: 351bd389b36SDavid du Colombier res->fval = l.ival+r.fval; 352bd389b36SDavid du Colombier break; 353219b2ee8SDavid du Colombier default: 354219b2ee8SDavid du Colombier error("bad rhs type +"); 355bd389b36SDavid du Colombier } 356bd389b36SDavid du Colombier break; 357bd389b36SDavid du Colombier case TFLOAT: 358bd389b36SDavid du Colombier switch(r.type) { 359bd389b36SDavid du Colombier case TINT: 360bd389b36SDavid du Colombier res->fval = l.fval+r.ival; 361bd389b36SDavid du Colombier break; 362bd389b36SDavid du Colombier case TFLOAT: 363bd389b36SDavid du Colombier res->fval = l.fval+r.fval; 364bd389b36SDavid du Colombier break; 365219b2ee8SDavid du Colombier default: 366219b2ee8SDavid du Colombier error("bad rhs type +"); 367bd389b36SDavid du Colombier } 368bd389b36SDavid du Colombier break; 369bd389b36SDavid du Colombier case TSTRING: 370bd389b36SDavid du Colombier if(r.type == TSTRING) { 371bd389b36SDavid du Colombier res->type = TSTRING; 372bd389b36SDavid du Colombier res->fmt = 's'; 373bd389b36SDavid du Colombier res->string = stradd(l.string, r.string); 374bd389b36SDavid du Colombier break; 375bd389b36SDavid du Colombier } 376ab3dc52fSDavid du Colombier if(r.type == TINT) { 377ab3dc52fSDavid du Colombier res->type = TSTRING; 378ab3dc52fSDavid du Colombier res->fmt = 's'; 379ab3dc52fSDavid du Colombier res->string = straddrune(l.string, r.ival); 380ab3dc52fSDavid du Colombier break; 381ab3dc52fSDavid du Colombier } 382bd389b36SDavid du Colombier error("bad rhs for +"); 383bd389b36SDavid du Colombier case TLIST: 384bd389b36SDavid du Colombier res->type = TLIST; 385bd389b36SDavid du Colombier switch(r.type) { 386bd389b36SDavid du Colombier case TLIST: 387bd389b36SDavid du Colombier res->l = addlist(l.l, r.l); 388bd389b36SDavid du Colombier break; 389bd389b36SDavid du Colombier default: 390bd389b36SDavid du Colombier r.left = 0; 391bd389b36SDavid du Colombier r.right = 0; 392bd389b36SDavid du Colombier res->l = addlist(l.l, construct(&r)); 393bd389b36SDavid du Colombier break; 394bd389b36SDavid du Colombier } 395bd389b36SDavid du Colombier } 396219b2ee8SDavid du Colombier } 397219b2ee8SDavid du Colombier 398219b2ee8SDavid du Colombier void 399219b2ee8SDavid du Colombier osub(Node *n, Node *res) 400219b2ee8SDavid du Colombier { 401219b2ee8SDavid du Colombier Node l, r; 402219b2ee8SDavid du Colombier 403219b2ee8SDavid du Colombier expr(n->left, &l); 404219b2ee8SDavid du Colombier expr(n->right, &r); 405bd389b36SDavid du Colombier res->fmt = l.fmt; 406bd389b36SDavid du Colombier res->op = OCONST; 407bd389b36SDavid du Colombier res->type = TFLOAT; 408bd389b36SDavid du Colombier switch(l.type) { 409219b2ee8SDavid du Colombier default: 410219b2ee8SDavid du Colombier error("bad lhs type -"); 411bd389b36SDavid du Colombier case TINT: 412bd389b36SDavid du Colombier switch(r.type) { 413bd389b36SDavid du Colombier case TINT: 414bd389b36SDavid du Colombier res->type = TINT; 415bd389b36SDavid du Colombier res->ival = l.ival-r.ival; 416bd389b36SDavid du Colombier break; 417bd389b36SDavid du Colombier case TFLOAT: 418bd389b36SDavid du Colombier res->fval = l.ival-r.fval; 419bd389b36SDavid du Colombier break; 420219b2ee8SDavid du Colombier default: 421219b2ee8SDavid du Colombier error("bad rhs type -"); 422bd389b36SDavid du Colombier } 423bd389b36SDavid du Colombier break; 424bd389b36SDavid du Colombier case TFLOAT: 425219b2ee8SDavid du Colombier switch(r.type) { 426bd389b36SDavid du Colombier case TINT: 427bd389b36SDavid du Colombier res->fval = l.fval-r.ival; 428bd389b36SDavid du Colombier break; 429bd389b36SDavid du Colombier case TFLOAT: 430bd389b36SDavid du Colombier res->fval = l.fval-r.fval; 431bd389b36SDavid du Colombier break; 432219b2ee8SDavid du Colombier default: 433219b2ee8SDavid du Colombier error("bad rhs type -"); 434bd389b36SDavid du Colombier } 435bd389b36SDavid du Colombier break; 436bd389b36SDavid du Colombier } 437219b2ee8SDavid du Colombier } 438219b2ee8SDavid du Colombier 439219b2ee8SDavid du Colombier void 440219b2ee8SDavid du Colombier omul(Node *n, Node *res) 441219b2ee8SDavid du Colombier { 442219b2ee8SDavid du Colombier Node l, r; 443219b2ee8SDavid du Colombier 444219b2ee8SDavid du Colombier expr(n->left, &l); 445219b2ee8SDavid du Colombier expr(n->right, &r); 446bd389b36SDavid du Colombier res->fmt = l.fmt; 447bd389b36SDavid du Colombier res->op = OCONST; 448bd389b36SDavid du Colombier res->type = TFLOAT; 449bd389b36SDavid du Colombier switch(l.type) { 450219b2ee8SDavid du Colombier default: 451219b2ee8SDavid du Colombier error("bad lhs type *"); 452bd389b36SDavid du Colombier case TINT: 453bd389b36SDavid du Colombier switch(r.type) { 454bd389b36SDavid du Colombier case TINT: 455bd389b36SDavid du Colombier res->type = TINT; 456bd389b36SDavid du Colombier res->ival = l.ival*r.ival; 457bd389b36SDavid du Colombier break; 458bd389b36SDavid du Colombier case TFLOAT: 459bd389b36SDavid du Colombier res->fval = l.ival*r.fval; 460bd389b36SDavid du Colombier break; 461219b2ee8SDavid du Colombier default: 462219b2ee8SDavid du Colombier error("bad rhs type *"); 463bd389b36SDavid du Colombier } 464bd389b36SDavid du Colombier break; 465bd389b36SDavid du Colombier case TFLOAT: 466219b2ee8SDavid du Colombier switch(r.type) { 467bd389b36SDavid du Colombier case TINT: 468bd389b36SDavid du Colombier res->fval = l.fval*r.ival; 469bd389b36SDavid du Colombier break; 470bd389b36SDavid du Colombier case TFLOAT: 471bd389b36SDavid du Colombier res->fval = l.fval*r.fval; 472bd389b36SDavid du Colombier break; 473219b2ee8SDavid du Colombier default: 474219b2ee8SDavid du Colombier error("bad rhs type *"); 475bd389b36SDavid du Colombier } 476bd389b36SDavid du Colombier break; 477bd389b36SDavid du Colombier } 478219b2ee8SDavid du Colombier } 479219b2ee8SDavid du Colombier 480219b2ee8SDavid du Colombier void 481219b2ee8SDavid du Colombier odiv(Node *n, Node *res) 482219b2ee8SDavid du Colombier { 483219b2ee8SDavid du Colombier Node l, r; 484219b2ee8SDavid du Colombier 485219b2ee8SDavid du Colombier expr(n->left, &l); 486219b2ee8SDavid du Colombier expr(n->right, &r); 487bd389b36SDavid du Colombier res->fmt = l.fmt; 488bd389b36SDavid du Colombier res->op = OCONST; 489bd389b36SDavid du Colombier res->type = TFLOAT; 490bd389b36SDavid du Colombier switch(l.type) { 491219b2ee8SDavid du Colombier default: 492219b2ee8SDavid du Colombier error("bad lhs type /"); 493bd389b36SDavid du Colombier case TINT: 494bd389b36SDavid du Colombier switch(r.type) { 495bd389b36SDavid du Colombier case TINT: 496bd389b36SDavid du Colombier res->type = TINT; 497219b2ee8SDavid du Colombier if(r.ival == 0) 498219b2ee8SDavid du Colombier error("zero divide"); 499bd389b36SDavid du Colombier res->ival = l.ival/r.ival; 500bd389b36SDavid du Colombier break; 501bd389b36SDavid du Colombier case TFLOAT: 502219b2ee8SDavid du Colombier if(r.fval == 0) 503219b2ee8SDavid du Colombier error("zero divide"); 504bd389b36SDavid du Colombier res->fval = l.ival/r.fval; 505bd389b36SDavid du Colombier break; 506219b2ee8SDavid du Colombier default: 507219b2ee8SDavid du Colombier error("bad rhs type /"); 508bd389b36SDavid du Colombier } 509bd389b36SDavid du Colombier break; 510bd389b36SDavid du Colombier case TFLOAT: 511219b2ee8SDavid du Colombier switch(r.type) { 512bd389b36SDavid du Colombier case TINT: 513bd389b36SDavid du Colombier res->fval = l.fval/r.ival; 514bd389b36SDavid du Colombier break; 515bd389b36SDavid du Colombier case TFLOAT: 516bd389b36SDavid du Colombier res->fval = l.fval/r.fval; 517bd389b36SDavid du Colombier break; 518219b2ee8SDavid du Colombier default: 519219b2ee8SDavid du Colombier error("bad rhs type /"); 520bd389b36SDavid du Colombier } 521bd389b36SDavid du Colombier break; 522bd389b36SDavid du Colombier } 523219b2ee8SDavid du Colombier } 524219b2ee8SDavid du Colombier 525219b2ee8SDavid du Colombier void 526219b2ee8SDavid du Colombier omod(Node *n, Node *res) 527219b2ee8SDavid du Colombier { 528219b2ee8SDavid du Colombier Node l, r; 529219b2ee8SDavid du Colombier 530219b2ee8SDavid du Colombier expr(n->left, &l); 531219b2ee8SDavid du Colombier expr(n->right, &r); 532bd389b36SDavid du Colombier res->fmt = l.fmt; 533bd389b36SDavid du Colombier res->op = OCONST; 534bd389b36SDavid du Colombier res->type = TINT; 535bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 536bd389b36SDavid du Colombier error("bad expr type %"); 537bd389b36SDavid du Colombier res->ival = l.ival%r.ival; 538219b2ee8SDavid du Colombier } 539219b2ee8SDavid du Colombier 540219b2ee8SDavid du Colombier void 541219b2ee8SDavid du Colombier olsh(Node *n, Node *res) 542219b2ee8SDavid du Colombier { 543219b2ee8SDavid du Colombier Node l, r; 544219b2ee8SDavid du Colombier 545219b2ee8SDavid du Colombier expr(n->left, &l); 546219b2ee8SDavid du Colombier expr(n->right, &r); 547bd389b36SDavid du Colombier res->fmt = l.fmt; 548bd389b36SDavid du Colombier res->op = OCONST; 549bd389b36SDavid du Colombier res->type = TINT; 550bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 551bd389b36SDavid du Colombier error("bad expr type <<"); 552bd389b36SDavid du Colombier res->ival = l.ival<<r.ival; 553219b2ee8SDavid du Colombier } 554219b2ee8SDavid du Colombier 555219b2ee8SDavid du Colombier void 556219b2ee8SDavid du Colombier orsh(Node *n, Node *res) 557219b2ee8SDavid du Colombier { 558219b2ee8SDavid du Colombier Node l, r; 559219b2ee8SDavid du Colombier 560219b2ee8SDavid du Colombier expr(n->left, &l); 561219b2ee8SDavid du Colombier expr(n->right, &r); 562bd389b36SDavid du Colombier res->fmt = l.fmt; 563bd389b36SDavid du Colombier res->op = OCONST; 564bd389b36SDavid du Colombier res->type = TINT; 565bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 566bd389b36SDavid du Colombier error("bad expr type >>"); 5674de34a7eSDavid du Colombier res->ival = (uvlong)l.ival>>r.ival; 568219b2ee8SDavid du Colombier } 569219b2ee8SDavid du Colombier 570219b2ee8SDavid du Colombier void 571219b2ee8SDavid du Colombier olt(Node *n, Node *res) 572219b2ee8SDavid du Colombier { 573219b2ee8SDavid du Colombier Node l, r; 574219b2ee8SDavid du Colombier 575219b2ee8SDavid du Colombier expr(n->left, &l); 576219b2ee8SDavid du Colombier expr(n->right, &r); 577219b2ee8SDavid du Colombier 578bd389b36SDavid du Colombier res->fmt = l.fmt; 579bd389b36SDavid du Colombier res->op = OCONST; 580bd389b36SDavid du Colombier res->type = TINT; 581bd389b36SDavid du Colombier switch(l.type) { 582219b2ee8SDavid du Colombier default: 583219b2ee8SDavid du Colombier error("bad lhs type <"); 584bd389b36SDavid du Colombier case TINT: 585bd389b36SDavid du Colombier switch(r.type) { 586bd389b36SDavid du Colombier case TINT: 587bd389b36SDavid du Colombier res->ival = l.ival < r.ival; 588bd389b36SDavid du Colombier break; 589bd389b36SDavid du Colombier case TFLOAT: 590bd389b36SDavid du Colombier res->ival = l.ival < r.fval; 591bd389b36SDavid du Colombier break; 592219b2ee8SDavid du Colombier default: 593219b2ee8SDavid du Colombier error("bad rhs type <"); 594bd389b36SDavid du Colombier } 595bd389b36SDavid du Colombier break; 596bd389b36SDavid du Colombier case TFLOAT: 597219b2ee8SDavid du Colombier switch(r.type) { 598bd389b36SDavid du Colombier case TINT: 599bd389b36SDavid du Colombier res->ival = l.fval < r.ival; 600bd389b36SDavid du Colombier break; 601bd389b36SDavid du Colombier case TFLOAT: 602bd389b36SDavid du Colombier res->ival = l.fval < r.fval; 603bd389b36SDavid du Colombier break; 604219b2ee8SDavid du Colombier default: 605219b2ee8SDavid du Colombier error("bad rhs type <"); 606bd389b36SDavid du Colombier } 607bd389b36SDavid du Colombier break; 608bd389b36SDavid du Colombier } 609219b2ee8SDavid du Colombier } 610219b2ee8SDavid du Colombier 611219b2ee8SDavid du Colombier void 612219b2ee8SDavid du Colombier ogt(Node *n, Node *res) 613219b2ee8SDavid du Colombier { 614219b2ee8SDavid du Colombier Node l, r; 615219b2ee8SDavid du Colombier 616219b2ee8SDavid du Colombier expr(n->left, &l); 617219b2ee8SDavid du Colombier expr(n->right, &r); 618bd389b36SDavid du Colombier res->fmt = 'D'; 619bd389b36SDavid du Colombier res->op = OCONST; 620bd389b36SDavid du Colombier res->type = TINT; 621bd389b36SDavid du Colombier switch(l.type) { 622219b2ee8SDavid du Colombier default: 623219b2ee8SDavid du Colombier error("bad lhs type >"); 624bd389b36SDavid du Colombier case TINT: 625bd389b36SDavid du Colombier switch(r.type) { 626bd389b36SDavid du Colombier case TINT: 627bd389b36SDavid du Colombier res->ival = l.ival > r.ival; 628bd389b36SDavid du Colombier break; 629bd389b36SDavid du Colombier case TFLOAT: 630bd389b36SDavid du Colombier res->ival = l.ival > r.fval; 631bd389b36SDavid du Colombier break; 632219b2ee8SDavid du Colombier default: 633219b2ee8SDavid du Colombier error("bad rhs type >"); 634bd389b36SDavid du Colombier } 635bd389b36SDavid du Colombier break; 636bd389b36SDavid du Colombier case TFLOAT: 637219b2ee8SDavid du Colombier switch(r.type) { 638bd389b36SDavid du Colombier case TINT: 639bd389b36SDavid du Colombier res->ival = l.fval > r.ival; 640bd389b36SDavid du Colombier break; 641bd389b36SDavid du Colombier case TFLOAT: 642bd389b36SDavid du Colombier res->ival = l.fval > r.fval; 643bd389b36SDavid du Colombier break; 644219b2ee8SDavid du Colombier default: 645219b2ee8SDavid du Colombier error("bad rhs type >"); 646bd389b36SDavid du Colombier } 647bd389b36SDavid du Colombier break; 648bd389b36SDavid du Colombier } 649219b2ee8SDavid du Colombier } 650219b2ee8SDavid du Colombier 651219b2ee8SDavid du Colombier void 652219b2ee8SDavid du Colombier oleq(Node *n, Node *res) 653219b2ee8SDavid du Colombier { 654219b2ee8SDavid du Colombier Node l, r; 655219b2ee8SDavid du Colombier 656219b2ee8SDavid du Colombier expr(n->left, &l); 657219b2ee8SDavid du Colombier expr(n->right, &r); 658bd389b36SDavid du Colombier res->fmt = 'D'; 659bd389b36SDavid du Colombier res->op = OCONST; 660bd389b36SDavid du Colombier res->type = TINT; 661bd389b36SDavid du Colombier switch(l.type) { 662219b2ee8SDavid du Colombier default: 663219b2ee8SDavid du Colombier error("bad expr type <="); 664bd389b36SDavid du Colombier case TINT: 665bd389b36SDavid du Colombier switch(r.type) { 666bd389b36SDavid du Colombier case TINT: 667bd389b36SDavid du Colombier res->ival = l.ival <= r.ival; 668bd389b36SDavid du Colombier break; 669bd389b36SDavid du Colombier case TFLOAT: 670bd389b36SDavid du Colombier res->ival = l.ival <= r.fval; 671bd389b36SDavid du Colombier break; 672219b2ee8SDavid du Colombier default: 673bd389b36SDavid du Colombier error("bad expr type <="); 674bd389b36SDavid du Colombier } 675bd389b36SDavid du Colombier break; 676bd389b36SDavid du Colombier case TFLOAT: 677219b2ee8SDavid du Colombier switch(r.type) { 678bd389b36SDavid du Colombier case TINT: 679bd389b36SDavid du Colombier res->ival = l.fval <= r.ival; 680bd389b36SDavid du Colombier break; 681bd389b36SDavid du Colombier case TFLOAT: 682bd389b36SDavid du Colombier res->ival = l.fval <= r.fval; 683bd389b36SDavid du Colombier break; 684219b2ee8SDavid du Colombier default: 685bd389b36SDavid du Colombier error("bad expr type <="); 686bd389b36SDavid du Colombier } 687bd389b36SDavid du Colombier break; 688bd389b36SDavid du Colombier } 689219b2ee8SDavid du Colombier } 690219b2ee8SDavid du Colombier 691219b2ee8SDavid du Colombier void 692219b2ee8SDavid du Colombier ogeq(Node *n, Node *res) 693219b2ee8SDavid du Colombier { 694219b2ee8SDavid du Colombier Node l, r; 695219b2ee8SDavid du Colombier 696219b2ee8SDavid du Colombier expr(n->left, &l); 697219b2ee8SDavid du Colombier expr(n->right, &r); 698bd389b36SDavid du Colombier res->fmt = 'D'; 699bd389b36SDavid du Colombier res->op = OCONST; 700bd389b36SDavid du Colombier res->type = TINT; 701bd389b36SDavid du Colombier switch(l.type) { 702219b2ee8SDavid du Colombier default: 703219b2ee8SDavid du Colombier error("bad lhs type >="); 704bd389b36SDavid du Colombier case TINT: 705bd389b36SDavid du Colombier switch(r.type) { 706bd389b36SDavid du Colombier case TINT: 707bd389b36SDavid du Colombier res->ival = l.ival >= r.ival; 708bd389b36SDavid du Colombier break; 709bd389b36SDavid du Colombier case TFLOAT: 710bd389b36SDavid du Colombier res->ival = l.ival >= r.fval; 711bd389b36SDavid du Colombier break; 712219b2ee8SDavid du Colombier default: 713219b2ee8SDavid du Colombier error("bad rhs type >="); 714bd389b36SDavid du Colombier } 715bd389b36SDavid du Colombier break; 716bd389b36SDavid du Colombier case TFLOAT: 717219b2ee8SDavid du Colombier switch(r.type) { 718bd389b36SDavid du Colombier case TINT: 719bd389b36SDavid du Colombier res->ival = l.fval >= r.ival; 720bd389b36SDavid du Colombier break; 721bd389b36SDavid du Colombier case TFLOAT: 722bd389b36SDavid du Colombier res->ival = l.fval >= r.fval; 723bd389b36SDavid du Colombier break; 724219b2ee8SDavid du Colombier default: 725219b2ee8SDavid du Colombier error("bad rhs type >="); 726bd389b36SDavid du Colombier } 727bd389b36SDavid du Colombier break; 728bd389b36SDavid du Colombier } 729219b2ee8SDavid du Colombier } 730219b2ee8SDavid du Colombier 731219b2ee8SDavid du Colombier void 732219b2ee8SDavid du Colombier oeq(Node *n, Node *res) 733219b2ee8SDavid du Colombier { 734219b2ee8SDavid du Colombier Node l, r; 735219b2ee8SDavid du Colombier 736219b2ee8SDavid du Colombier expr(n->left, &l); 737219b2ee8SDavid du Colombier expr(n->right, &r); 738bd389b36SDavid du Colombier res->fmt = 'D'; 739bd389b36SDavid du Colombier res->op = OCONST; 740bd389b36SDavid du Colombier res->type = TINT; 741219b2ee8SDavid du Colombier res->ival = 0; 742bd389b36SDavid du Colombier switch(l.type) { 743219b2ee8SDavid du Colombier default: 744219b2ee8SDavid du Colombier break; 745bd389b36SDavid du Colombier case TINT: 746bd389b36SDavid du Colombier switch(r.type) { 747bd389b36SDavid du Colombier case TINT: 748bd389b36SDavid du Colombier res->ival = l.ival == r.ival; 749bd389b36SDavid du Colombier break; 750bd389b36SDavid du Colombier case TFLOAT: 751bd389b36SDavid du Colombier res->ival = l.ival == r.fval; 752bd389b36SDavid du Colombier break; 753219b2ee8SDavid du Colombier default: 754219b2ee8SDavid du Colombier break; 755bd389b36SDavid du Colombier } 756bd389b36SDavid du Colombier break; 757bd389b36SDavid du Colombier case TFLOAT: 758219b2ee8SDavid du Colombier switch(r.type) { 759bd389b36SDavid du Colombier case TINT: 760bd389b36SDavid du Colombier res->ival = l.fval == r.ival; 761bd389b36SDavid du Colombier break; 762bd389b36SDavid du Colombier case TFLOAT: 763bd389b36SDavid du Colombier res->ival = l.fval == r.fval; 764bd389b36SDavid du Colombier break; 765219b2ee8SDavid du Colombier default: 766219b2ee8SDavid du Colombier break; 767bd389b36SDavid du Colombier } 768bd389b36SDavid du Colombier break; 769bd389b36SDavid du Colombier case TSTRING: 770bd389b36SDavid du Colombier if(r.type == TSTRING) { 771bd389b36SDavid du Colombier res->ival = scmp(r.string, l.string); 772bd389b36SDavid du Colombier break; 773bd389b36SDavid du Colombier } 774219b2ee8SDavid du Colombier break; 775bd389b36SDavid du Colombier case TLIST: 776bd389b36SDavid du Colombier if(r.type == TLIST) { 777bd389b36SDavid du Colombier res->ival = listcmp(l.l, r.l); 778bd389b36SDavid du Colombier break; 779bd389b36SDavid du Colombier } 780bd389b36SDavid du Colombier break; 781bd389b36SDavid du Colombier } 782219b2ee8SDavid du Colombier if(n->op == ONEQ) 783219b2ee8SDavid du Colombier res->ival = !res->ival; 784bd389b36SDavid du Colombier } 785219b2ee8SDavid du Colombier 786219b2ee8SDavid du Colombier 787219b2ee8SDavid du Colombier void 788219b2ee8SDavid du Colombier oland(Node *n, Node *res) 789219b2ee8SDavid du Colombier { 790219b2ee8SDavid du Colombier Node l, r; 791219b2ee8SDavid du Colombier 792219b2ee8SDavid du Colombier expr(n->left, &l); 793219b2ee8SDavid du Colombier expr(n->right, &r); 794bd389b36SDavid du Colombier res->fmt = l.fmt; 795bd389b36SDavid du Colombier res->op = OCONST; 796bd389b36SDavid du Colombier res->type = TINT; 797bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 798bd389b36SDavid du Colombier error("bad expr type &"); 799bd389b36SDavid du Colombier res->ival = l.ival&r.ival; 800219b2ee8SDavid du Colombier } 801219b2ee8SDavid du Colombier 802219b2ee8SDavid du Colombier void 803219b2ee8SDavid du Colombier oxor(Node *n, Node *res) 804219b2ee8SDavid du Colombier { 805219b2ee8SDavid du Colombier Node l, r; 806219b2ee8SDavid du Colombier 807219b2ee8SDavid du Colombier expr(n->left, &l); 808219b2ee8SDavid du Colombier expr(n->right, &r); 809bd389b36SDavid du Colombier res->fmt = l.fmt; 810bd389b36SDavid du Colombier res->op = OCONST; 811bd389b36SDavid du Colombier res->type = TINT; 812bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 813bd389b36SDavid du Colombier error("bad expr type ^"); 814bd389b36SDavid du Colombier res->ival = l.ival^r.ival; 815219b2ee8SDavid du Colombier } 816219b2ee8SDavid du Colombier 817219b2ee8SDavid du Colombier void 818219b2ee8SDavid du Colombier olor(Node *n, Node *res) 819219b2ee8SDavid du Colombier { 820219b2ee8SDavid du Colombier Node l, r; 821219b2ee8SDavid du Colombier 822219b2ee8SDavid du Colombier expr(n->left, &l); 823219b2ee8SDavid du Colombier expr(n->right, &r); 824bd389b36SDavid du Colombier res->fmt = l.fmt; 825bd389b36SDavid du Colombier res->op = OCONST; 826bd389b36SDavid du Colombier res->type = TINT; 827bd389b36SDavid du Colombier if(l.type != TINT || r.type != TINT) 828bd389b36SDavid du Colombier error("bad expr type |"); 829bd389b36SDavid du Colombier res->ival = l.ival|r.ival; 830219b2ee8SDavid du Colombier } 831219b2ee8SDavid du Colombier 832219b2ee8SDavid du Colombier void 833219b2ee8SDavid du Colombier ocand(Node *n, Node *res) 834219b2ee8SDavid du Colombier { 835219b2ee8SDavid du Colombier Node l, r; 836219b2ee8SDavid du Colombier 837bd389b36SDavid du Colombier res->fmt = l.fmt; 838bd389b36SDavid du Colombier res->op = OCONST; 839bd389b36SDavid du Colombier res->type = TINT; 840219b2ee8SDavid du Colombier res->ival = 0; 841219b2ee8SDavid du Colombier expr(n->left, &l); 842219b2ee8SDavid du Colombier if(bool(&l) == 0) 843219b2ee8SDavid du Colombier return; 844219b2ee8SDavid du Colombier expr(n->right, &r); 845219b2ee8SDavid du Colombier if(bool(&r) == 0) 846219b2ee8SDavid du Colombier return; 847219b2ee8SDavid du Colombier res->ival = 1; 848219b2ee8SDavid du Colombier } 849219b2ee8SDavid du Colombier 850219b2ee8SDavid du Colombier void 851219b2ee8SDavid du Colombier onot(Node *n, Node *res) 852219b2ee8SDavid du Colombier { 853219b2ee8SDavid du Colombier Node l; 854219b2ee8SDavid du Colombier 855bd389b36SDavid du Colombier res->op = OCONST; 856bd389b36SDavid du Colombier res->type = TINT; 857219b2ee8SDavid du Colombier res->ival = 0; 858219b2ee8SDavid du Colombier expr(n->left, &l); 859219b2ee8SDavid du Colombier if(bool(&l) == 0) 860219b2ee8SDavid du Colombier res->ival = 1; 861219b2ee8SDavid du Colombier } 862219b2ee8SDavid du Colombier 863219b2ee8SDavid du Colombier void 864219b2ee8SDavid du Colombier ocor(Node *n, Node *res) 865219b2ee8SDavid du Colombier { 866219b2ee8SDavid du Colombier Node l, r; 867219b2ee8SDavid du Colombier 868219b2ee8SDavid du Colombier res->op = OCONST; 869219b2ee8SDavid du Colombier res->type = TINT; 870219b2ee8SDavid du Colombier res->ival = 0; 871219b2ee8SDavid du Colombier expr(n->left, &l); 872219b2ee8SDavid du Colombier if(bool(&l)) { 873219b2ee8SDavid du Colombier res->ival = 1; 874219b2ee8SDavid du Colombier return; 875219b2ee8SDavid du Colombier } 876219b2ee8SDavid du Colombier expr(n->right, &r); 877219b2ee8SDavid du Colombier if(bool(&r)) { 878219b2ee8SDavid du Colombier res->ival = 1; 879219b2ee8SDavid du Colombier return; 880219b2ee8SDavid du Colombier } 881219b2ee8SDavid du Colombier } 882219b2ee8SDavid du Colombier 883219b2ee8SDavid du Colombier void 884219b2ee8SDavid du Colombier oeinc(Node *n, Node *res) 885219b2ee8SDavid du Colombier { 886219b2ee8SDavid du Colombier Value *v; 887219b2ee8SDavid du Colombier 888219b2ee8SDavid du Colombier chklval(n->left); 889219b2ee8SDavid du Colombier v = n->left->sym->v; 890bd389b36SDavid du Colombier res->op = OCONST; 891bd389b36SDavid du Colombier res->type = v->type; 892bd389b36SDavid du Colombier switch(v->type) { 893bd389b36SDavid du Colombier case TINT: 894bd389b36SDavid du Colombier if(n->op == OEDEC) 895bd389b36SDavid du Colombier v->ival -= fmtsize(v); 896bd389b36SDavid du Colombier else 897bd389b36SDavid du Colombier v->ival += fmtsize(v); 898bd389b36SDavid du Colombier break; 899bd389b36SDavid du Colombier case TFLOAT: 900bd389b36SDavid du Colombier if(n->op == OEDEC) 901bd389b36SDavid du Colombier v->fval--; 902bd389b36SDavid du Colombier else 903bd389b36SDavid du Colombier v->fval++; 904bd389b36SDavid du Colombier break; 905bd389b36SDavid du Colombier default: 906bd389b36SDavid du Colombier error("bad type for pre --/++"); 907bd389b36SDavid du Colombier } 908bd389b36SDavid du Colombier res->Store = v->Store; 909219b2ee8SDavid du Colombier } 910219b2ee8SDavid du Colombier 911219b2ee8SDavid du Colombier void 912219b2ee8SDavid du Colombier opinc(Node *n, Node *res) 913219b2ee8SDavid du Colombier { 914219b2ee8SDavid du Colombier Value *v; 915219b2ee8SDavid du Colombier 916219b2ee8SDavid du Colombier chklval(n->left); 917219b2ee8SDavid du Colombier v = n->left->sym->v; 918bd389b36SDavid du Colombier res->op = OCONST; 919bd389b36SDavid du Colombier res->type = v->type; 920bd389b36SDavid du Colombier res->Store = v->Store; 921bd389b36SDavid du Colombier switch(v->type) { 922bd389b36SDavid du Colombier case TINT: 923bd389b36SDavid du Colombier if(n->op == OPDEC) 924bd389b36SDavid du Colombier v->ival -= fmtsize(v); 925bd389b36SDavid du Colombier else 926bd389b36SDavid du Colombier v->ival += fmtsize(v); 927bd389b36SDavid du Colombier break; 928bd389b36SDavid du Colombier case TFLOAT: 929bd389b36SDavid du Colombier if(n->op == OPDEC) 930bd389b36SDavid du Colombier v->fval--; 931bd389b36SDavid du Colombier else 932bd389b36SDavid du Colombier v->fval++; 933bd389b36SDavid du Colombier break; 934bd389b36SDavid du Colombier default: 935bd389b36SDavid du Colombier error("bad type for post --/++"); 936bd389b36SDavid du Colombier } 937219b2ee8SDavid du Colombier } 938219b2ee8SDavid du Colombier 939219b2ee8SDavid du Colombier void 940219b2ee8SDavid du Colombier ocall(Node *n, Node *res) 941219b2ee8SDavid du Colombier { 942219b2ee8SDavid du Colombier Lsym *s; 943219b2ee8SDavid du Colombier Rplace *rsav; 944219b2ee8SDavid du Colombier 945bd389b36SDavid du Colombier res->op = OCONST; /* Default return value */ 946bd389b36SDavid du Colombier res->type = TLIST; 947bd389b36SDavid du Colombier res->l = 0; 948bd389b36SDavid du Colombier 949219b2ee8SDavid du Colombier chklval(n->left); 950219b2ee8SDavid du Colombier s = n->left->sym; 951bd389b36SDavid du Colombier 9520b459c2cSDavid du Colombier if(n->builtin && !s->builtin){ 9530b459c2cSDavid du Colombier error("no builtin %s", s->name); 9540b459c2cSDavid du Colombier return; 9550b459c2cSDavid du Colombier } 9560b459c2cSDavid du Colombier if(s->builtin && (n->builtin || s->proc == 0)) { 957219b2ee8SDavid du Colombier (*s->builtin)(res, n->right); 958219b2ee8SDavid du Colombier return; 959bd389b36SDavid du Colombier } 960bd389b36SDavid du Colombier if(s->proc == 0) 961bd389b36SDavid du Colombier error("no function %s", s->name); 962bd389b36SDavid du Colombier 963bd389b36SDavid du Colombier rsav = ret; 964219b2ee8SDavid du Colombier call(s->name, n->right, s->proc->left, s->proc->right, res); 965bd389b36SDavid du Colombier ret = rsav; 966bd389b36SDavid du Colombier } 967219b2ee8SDavid du Colombier 968219b2ee8SDavid du Colombier void 969219b2ee8SDavid du Colombier ofmt(Node *n, Node *res) 970219b2ee8SDavid du Colombier { 971219b2ee8SDavid du Colombier expr(n->left, res); 972219b2ee8SDavid du Colombier res->fmt = n->right->ival; 973bd389b36SDavid du Colombier } 974219b2ee8SDavid du Colombier 975219b2ee8SDavid du Colombier void 976219b2ee8SDavid du Colombier owhat(Node *n, Node *res) 977219b2ee8SDavid du Colombier { 978219b2ee8SDavid du Colombier res->op = OCONST; /* Default return value */ 979219b2ee8SDavid du Colombier res->type = TLIST; 980219b2ee8SDavid du Colombier res->l = 0; 981219b2ee8SDavid du Colombier whatis(n->sym); 982219b2ee8SDavid du Colombier } 983219b2ee8SDavid du Colombier 984219b2ee8SDavid du Colombier void (*expop[])(Node*, Node*) = 985219b2ee8SDavid du Colombier { 986219b2ee8SDavid du Colombier [ONAME] oname, 987219b2ee8SDavid du Colombier [OCONST] oconst, 988219b2ee8SDavid du Colombier [OMUL] omul, 989219b2ee8SDavid du Colombier [ODIV] odiv, 990219b2ee8SDavid du Colombier [OMOD] omod, 991219b2ee8SDavid du Colombier [OADD] oadd, 992219b2ee8SDavid du Colombier [OSUB] osub, 993219b2ee8SDavid du Colombier [ORSH] orsh, 994219b2ee8SDavid du Colombier [OLSH] olsh, 995219b2ee8SDavid du Colombier [OLT] olt, 996219b2ee8SDavid du Colombier [OGT] ogt, 997219b2ee8SDavid du Colombier [OLEQ] oleq, 998219b2ee8SDavid du Colombier [OGEQ] ogeq, 999219b2ee8SDavid du Colombier [OEQ] oeq, 1000219b2ee8SDavid du Colombier [ONEQ] oeq, 1001219b2ee8SDavid du Colombier [OLAND] oland, 1002219b2ee8SDavid du Colombier [OXOR] oxor, 1003219b2ee8SDavid du Colombier [OLOR] olor, 1004219b2ee8SDavid du Colombier [OCAND] ocand, 1005219b2ee8SDavid du Colombier [OCOR] ocor, 1006219b2ee8SDavid du Colombier [OASGN] oasgn, 1007219b2ee8SDavid du Colombier [OINDM] oindm, 1008219b2ee8SDavid du Colombier [OEDEC] oeinc, 1009219b2ee8SDavid du Colombier [OEINC] oeinc, 1010219b2ee8SDavid du Colombier [OPINC] opinc, 1011219b2ee8SDavid du Colombier [OPDEC] opinc, 1012219b2ee8SDavid du Colombier [ONOT] onot, 1013219b2ee8SDavid du Colombier [OIF] 0, 1014219b2ee8SDavid du Colombier [ODO] 0, 1015219b2ee8SDavid du Colombier [OLIST] olist, 1016219b2ee8SDavid du Colombier [OCALL] ocall, 1017219b2ee8SDavid du Colombier [OCTRUCT] octruct, 1018219b2ee8SDavid du Colombier [OWHILE] 0, 1019219b2ee8SDavid du Colombier [OELSE] 0, 1020219b2ee8SDavid du Colombier [OHEAD] ohead, 1021219b2ee8SDavid du Colombier [OTAIL] otail, 1022219b2ee8SDavid du Colombier [OAPPEND] oappend, 1023219b2ee8SDavid du Colombier [ORET] 0, 1024219b2ee8SDavid du Colombier [OINDEX] oindex, 1025219b2ee8SDavid du Colombier [OINDC] oindc, 1026219b2ee8SDavid du Colombier [ODOT] odot, 1027219b2ee8SDavid du Colombier [OLOCAL] 0, 1028219b2ee8SDavid du Colombier [OFRAME] oframe, 1029219b2ee8SDavid du Colombier [OCOMPLEX] 0, 1030219b2ee8SDavid du Colombier [ODELETE] odelete, 1031219b2ee8SDavid du Colombier [OCAST] ocast, 1032219b2ee8SDavid du Colombier [OFMT] ofmt, 1033219b2ee8SDavid du Colombier [OEVAL] oeval, 1034219b2ee8SDavid du Colombier [OWHAT] owhat, 1035219b2ee8SDavid du Colombier }; 1036