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