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