plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

expr.c (19296B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <bio.h>
      4 #include <ctype.h>
      5 #include <mach.h>
      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<<r.store.u.ival;
    574 }
    575 
    576 void
    577 orsh(Node *n, Node *res)
    578 {
    579 	Node l, r;
    580 
    581 	expr(n->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 }