xref: /plan9/sys/src/cmd/acid/expr.c (revision f9e1cf08d3be51592e03e639fc848a68dc31a55e)
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
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
66 chklval(Node *lp)
67 {
68 	if(lp->op != ONAME)
69 		error("need l-value");
70 }
71 
72 void
73 olist(Node *n, Node *res)
74 {
75 	expr(n->left, res);
76 	expr(n->right, res);
77 }
78 
79 void
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
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
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
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
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
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
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
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
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
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
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
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
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
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
332 oadd(Node *n, Node *res)
333 {
334 	Node l, r;
335 
336 	expr(n->left, &l);
337 	expr(n->right, &r);
338 	res->fmt = l.fmt;
339 	res->op = OCONST;
340 	res->type = TFLOAT;
341 	switch(l.type) {
342 	default:
343 		error("bad lhs type +");
344 	case TINT:
345 		switch(r.type) {
346 		case TINT:
347 			res->type = TINT;
348 			res->ival = l.ival+r.ival;
349 			break;
350 		case TFLOAT:
351 			res->fval = l.ival+r.fval;
352 			break;
353 		default:
354 			error("bad rhs type +");
355 		}
356 		break;
357 	case TFLOAT:
358 		switch(r.type) {
359 		case TINT:
360 			res->fval = l.fval+r.ival;
361 			break;
362 		case TFLOAT:
363 			res->fval = l.fval+r.fval;
364 			break;
365 		default:
366 			error("bad rhs type +");
367 		}
368 		break;
369 	case TSTRING:
370 		if(r.type == TSTRING) {
371 			res->type = TSTRING;
372 			res->fmt = 's';
373 			res->string = stradd(l.string, r.string);
374 			break;
375 		}
376 		if(r.type == TINT) {
377 			res->type = TSTRING;
378 			res->fmt = 's';
379 			res->string = straddrune(l.string, r.ival);
380 			break;
381 		}
382 		error("bad rhs for +");
383 	case TLIST:
384 		res->type = TLIST;
385 		switch(r.type) {
386 		case TLIST:
387 			res->l = addlist(l.l, r.l);
388 			break;
389 		default:
390 			r.left = 0;
391 			r.right = 0;
392 			res->l = addlist(l.l, construct(&r));
393 			break;
394 		}
395 	}
396 }
397 
398 void
399 osub(Node *n, Node *res)
400 {
401 	Node l, r;
402 
403 	expr(n->left, &l);
404 	expr(n->right, &r);
405 	res->fmt = l.fmt;
406 	res->op = OCONST;
407 	res->type = TFLOAT;
408 	switch(l.type) {
409 	default:
410 		error("bad lhs type -");
411 	case TINT:
412 		switch(r.type) {
413 		case TINT:
414 			res->type = TINT;
415 			res->ival = l.ival-r.ival;
416 			break;
417 		case TFLOAT:
418 			res->fval = l.ival-r.fval;
419 			break;
420 		default:
421 			error("bad rhs type -");
422 		}
423 		break;
424 	case TFLOAT:
425 		switch(r.type) {
426 		case TINT:
427 			res->fval = l.fval-r.ival;
428 			break;
429 		case TFLOAT:
430 			res->fval = l.fval-r.fval;
431 			break;
432 		default:
433 			error("bad rhs type -");
434 		}
435 		break;
436 	}
437 }
438 
439 void
440 omul(Node *n, Node *res)
441 {
442 	Node l, r;
443 
444 	expr(n->left, &l);
445 	expr(n->right, &r);
446 	res->fmt = l.fmt;
447 	res->op = OCONST;
448 	res->type = TFLOAT;
449 	switch(l.type) {
450 	default:
451 		error("bad lhs type *");
452 	case TINT:
453 		switch(r.type) {
454 		case TINT:
455 			res->type = TINT;
456 			res->ival = l.ival*r.ival;
457 			break;
458 		case TFLOAT:
459 			res->fval = l.ival*r.fval;
460 			break;
461 		default:
462 			error("bad rhs type *");
463 		}
464 		break;
465 	case TFLOAT:
466 		switch(r.type) {
467 		case TINT:
468 			res->fval = l.fval*r.ival;
469 			break;
470 		case TFLOAT:
471 			res->fval = l.fval*r.fval;
472 			break;
473 		default:
474 			error("bad rhs type *");
475 		}
476 		break;
477 	}
478 }
479 
480 void
481 odiv(Node *n, Node *res)
482 {
483 	Node l, r;
484 
485 	expr(n->left, &l);
486 	expr(n->right, &r);
487 	res->fmt = l.fmt;
488 	res->op = OCONST;
489 	res->type = TFLOAT;
490 	switch(l.type) {
491 	default:
492 		error("bad lhs type /");
493 	case TINT:
494 		switch(r.type) {
495 		case TINT:
496 			res->type = TINT;
497 			if(r.ival == 0)
498 				error("zero divide");
499 			res->ival = l.ival/r.ival;
500 			break;
501 		case TFLOAT:
502 			if(r.fval == 0)
503 				error("zero divide");
504 			res->fval = l.ival/r.fval;
505 			break;
506 		default:
507 			error("bad rhs type /");
508 		}
509 		break;
510 	case TFLOAT:
511 		switch(r.type) {
512 		case TINT:
513 			res->fval = l.fval/r.ival;
514 			break;
515 		case TFLOAT:
516 			res->fval = l.fval/r.fval;
517 			break;
518 		default:
519 			error("bad rhs type /");
520 		}
521 		break;
522 	}
523 }
524 
525 void
526 omod(Node *n, Node *res)
527 {
528 	Node l, r;
529 
530 	expr(n->left, &l);
531 	expr(n->right, &r);
532 	res->fmt = l.fmt;
533 	res->op = OCONST;
534 	res->type = TINT;
535 	if(l.type != TINT || r.type != TINT)
536 		error("bad expr type %");
537 	res->ival = l.ival%r.ival;
538 }
539 
540 void
541 olsh(Node *n, Node *res)
542 {
543 	Node l, r;
544 
545 	expr(n->left, &l);
546 	expr(n->right, &r);
547 	res->fmt = l.fmt;
548 	res->op = OCONST;
549 	res->type = TINT;
550 	if(l.type != TINT || r.type != TINT)
551 		error("bad expr type <<");
552 	res->ival = l.ival<<r.ival;
553 }
554 
555 void
556 orsh(Node *n, Node *res)
557 {
558 	Node l, r;
559 
560 	expr(n->left, &l);
561 	expr(n->right, &r);
562 	res->fmt = l.fmt;
563 	res->op = OCONST;
564 	res->type = TINT;
565 	if(l.type != TINT || r.type != TINT)
566 		error("bad expr type >>");
567 	res->ival = (uvlong)l.ival>>r.ival;
568 }
569 
570 void
571 olt(Node *n, Node *res)
572 {
573 	Node l, r;
574 
575 	expr(n->left, &l);
576 	expr(n->right, &r);
577 
578 	res->fmt = l.fmt;
579 	res->op = OCONST;
580 	res->type = TINT;
581 	switch(l.type) {
582 	default:
583 		error("bad lhs type <");
584 	case TINT:
585 		switch(r.type) {
586 		case TINT:
587 			res->ival = l.ival < r.ival;
588 			break;
589 		case TFLOAT:
590 			res->ival = l.ival < r.fval;
591 			break;
592 		default:
593 			error("bad rhs type <");
594 		}
595 		break;
596 	case TFLOAT:
597 		switch(r.type) {
598 		case TINT:
599 			res->ival = l.fval < r.ival;
600 			break;
601 		case TFLOAT:
602 			res->ival = l.fval < r.fval;
603 			break;
604 		default:
605 			error("bad rhs type <");
606 		}
607 		break;
608 	}
609 }
610 
611 void
612 ogt(Node *n, Node *res)
613 {
614 	Node l, r;
615 
616 	expr(n->left, &l);
617 	expr(n->right, &r);
618 	res->fmt = 'D';
619 	res->op = OCONST;
620 	res->type = TINT;
621 	switch(l.type) {
622 	default:
623 		error("bad lhs type >");
624 	case TINT:
625 		switch(r.type) {
626 		case TINT:
627 			res->ival = l.ival > r.ival;
628 			break;
629 		case TFLOAT:
630 			res->ival = l.ival > r.fval;
631 			break;
632 		default:
633 			error("bad rhs type >");
634 		}
635 		break;
636 	case TFLOAT:
637 		switch(r.type) {
638 		case TINT:
639 			res->ival = l.fval > r.ival;
640 			break;
641 		case TFLOAT:
642 			res->ival = l.fval > r.fval;
643 			break;
644 		default:
645 			error("bad rhs type >");
646 		}
647 		break;
648 	}
649 }
650 
651 void
652 oleq(Node *n, Node *res)
653 {
654 	Node l, r;
655 
656 	expr(n->left, &l);
657 	expr(n->right, &r);
658 	res->fmt = 'D';
659 	res->op = OCONST;
660 	res->type = TINT;
661 	switch(l.type) {
662 	default:
663 		error("bad expr type <=");
664 	case TINT:
665 		switch(r.type) {
666 		case TINT:
667 			res->ival = l.ival <= r.ival;
668 			break;
669 		case TFLOAT:
670 			res->ival = l.ival <= r.fval;
671 			break;
672 		default:
673 			error("bad expr type <=");
674 		}
675 		break;
676 	case TFLOAT:
677 		switch(r.type) {
678 		case TINT:
679 			res->ival = l.fval <= r.ival;
680 			break;
681 		case TFLOAT:
682 			res->ival = l.fval <= r.fval;
683 			break;
684 		default:
685 			error("bad expr type <=");
686 		}
687 		break;
688 	}
689 }
690 
691 void
692 ogeq(Node *n, Node *res)
693 {
694 	Node l, r;
695 
696 	expr(n->left, &l);
697 	expr(n->right, &r);
698 	res->fmt = 'D';
699 	res->op = OCONST;
700 	res->type = TINT;
701 	switch(l.type) {
702 	default:
703 		error("bad lhs type >=");
704 	case TINT:
705 		switch(r.type) {
706 		case TINT:
707 			res->ival = l.ival >= r.ival;
708 			break;
709 		case TFLOAT:
710 			res->ival = l.ival >= r.fval;
711 			break;
712 		default:
713 			error("bad rhs type >=");
714 		}
715 		break;
716 	case TFLOAT:
717 		switch(r.type) {
718 		case TINT:
719 			res->ival = l.fval >= r.ival;
720 			break;
721 		case TFLOAT:
722 			res->ival = l.fval >= r.fval;
723 			break;
724 		default:
725 			error("bad rhs type >=");
726 		}
727 		break;
728 	}
729 }
730 
731 void
732 oeq(Node *n, Node *res)
733 {
734 	Node l, r;
735 
736 	expr(n->left, &l);
737 	expr(n->right, &r);
738 	res->fmt = 'D';
739 	res->op = OCONST;
740 	res->type = TINT;
741 	res->ival = 0;
742 	switch(l.type) {
743 	default:
744 		break;
745 	case TINT:
746 		switch(r.type) {
747 		case TINT:
748 			res->ival = l.ival == r.ival;
749 			break;
750 		case TFLOAT:
751 			res->ival = l.ival == r.fval;
752 			break;
753 		default:
754 			break;
755 		}
756 		break;
757 	case TFLOAT:
758 		switch(r.type) {
759 		case TINT:
760 			res->ival = l.fval == r.ival;
761 			break;
762 		case TFLOAT:
763 			res->ival = l.fval == r.fval;
764 			break;
765 		default:
766 			break;
767 		}
768 		break;
769 	case TSTRING:
770 		if(r.type == TSTRING) {
771 			res->ival = scmp(r.string, l.string);
772 			break;
773 		}
774 		break;
775 	case TLIST:
776 		if(r.type == TLIST) {
777 			res->ival = listcmp(l.l, r.l);
778 			break;
779 		}
780 		break;
781 	}
782 	if(n->op == ONEQ)
783 		res->ival = !res->ival;
784 }
785 
786 
787 void
788 oland(Node *n, Node *res)
789 {
790 	Node l, r;
791 
792 	expr(n->left, &l);
793 	expr(n->right, &r);
794 	res->fmt = l.fmt;
795 	res->op = OCONST;
796 	res->type = TINT;
797 	if(l.type != TINT || r.type != TINT)
798 		error("bad expr type &");
799 	res->ival = l.ival&r.ival;
800 }
801 
802 void
803 oxor(Node *n, Node *res)
804 {
805 	Node l, r;
806 
807 	expr(n->left, &l);
808 	expr(n->right, &r);
809 	res->fmt = l.fmt;
810 	res->op = OCONST;
811 	res->type = TINT;
812 	if(l.type != TINT || r.type != TINT)
813 		error("bad expr type ^");
814 	res->ival = l.ival^r.ival;
815 }
816 
817 void
818 olor(Node *n, Node *res)
819 {
820 	Node l, r;
821 
822 	expr(n->left, &l);
823 	expr(n->right, &r);
824 	res->fmt = l.fmt;
825 	res->op = OCONST;
826 	res->type = TINT;
827 	if(l.type != TINT || r.type != TINT)
828 		error("bad expr type |");
829 	res->ival = l.ival|r.ival;
830 }
831 
832 void
833 ocand(Node *n, Node *res)
834 {
835 	Node l, r;
836 
837 	res->fmt = l.fmt;
838 	res->op = OCONST;
839 	res->type = TINT;
840 	res->ival = 0;
841 	expr(n->left, &l);
842 	if(bool(&l) == 0)
843 		return;
844 	expr(n->right, &r);
845 	if(bool(&r) == 0)
846 		return;
847 	res->ival = 1;
848 }
849 
850 void
851 onot(Node *n, Node *res)
852 {
853 	Node l;
854 
855 	res->op = OCONST;
856 	res->type = TINT;
857 	res->ival = 0;
858 	expr(n->left, &l);
859 	if(bool(&l) == 0)
860 		res->ival = 1;
861 }
862 
863 void
864 ocor(Node *n, Node *res)
865 {
866 	Node l, r;
867 
868 	res->op = OCONST;
869 	res->type = TINT;
870 	res->ival = 0;
871 	expr(n->left, &l);
872 	if(bool(&l)) {
873 		res->ival = 1;
874 		return;
875 	}
876 	expr(n->right, &r);
877 	if(bool(&r)) {
878 		res->ival = 1;
879 		return;
880 	}
881 }
882 
883 void
884 oeinc(Node *n, Node *res)
885 {
886 	Value *v;
887 
888 	chklval(n->left);
889 	v = n->left->sym->v;
890 	res->op = OCONST;
891 	res->type = v->type;
892 	switch(v->type) {
893 	case TINT:
894 		if(n->op == OEDEC)
895 			v->ival -= fmtsize(v);
896 		else
897 			v->ival += fmtsize(v);
898 		break;
899 	case TFLOAT:
900 		if(n->op == OEDEC)
901 			v->fval--;
902 		else
903 			v->fval++;
904 		break;
905 	default:
906 		error("bad type for pre --/++");
907 	}
908 	res->Store = v->Store;
909 }
910 
911 void
912 opinc(Node *n, Node *res)
913 {
914 	Value *v;
915 
916 	chklval(n->left);
917 	v = n->left->sym->v;
918 	res->op = OCONST;
919 	res->type = v->type;
920 	res->Store = v->Store;
921 	switch(v->type) {
922 	case TINT:
923 		if(n->op == OPDEC)
924 			v->ival -= fmtsize(v);
925 		else
926 			v->ival += fmtsize(v);
927 		break;
928 	case TFLOAT:
929 		if(n->op == OPDEC)
930 			v->fval--;
931 		else
932 			v->fval++;
933 		break;
934 	default:
935 		error("bad type for post --/++");
936 	}
937 }
938 
939 void
940 ocall(Node *n, Node *res)
941 {
942 	Lsym *s;
943 	Rplace *rsav;
944 
945 	res->op = OCONST;		/* Default return value */
946 	res->type = TLIST;
947 	res->l = 0;
948 
949 	chklval(n->left);
950 	s = n->left->sym;
951 
952 	if(n->builtin && !s->builtin){
953 		error("no builtin %s", s->name);
954 		return;
955 	}
956 	if(s->builtin && (n->builtin || s->proc == 0)) {
957 		(*s->builtin)(res, n->right);
958 		return;
959 	}
960 	if(s->proc == 0)
961 		error("no function %s", s->name);
962 
963 	rsav = ret;
964 	call(s->name, n->right, s->proc->left, s->proc->right, res);
965 	ret = rsav;
966 }
967 
968 void
969 ofmt(Node *n, Node *res)
970 {
971 	expr(n->left, res);
972 	res->fmt = n->right->ival;
973 }
974 
975 void
976 owhat(Node *n, Node *res)
977 {
978 	res->op = OCONST;		/* Default return value */
979 	res->type = TLIST;
980 	res->l = 0;
981 	whatis(n->sym);
982 }
983 
984 void (*expop[])(Node*, Node*) =
985 {
986 	[ONAME]		oname,
987 	[OCONST]	oconst,
988 	[OMUL]		omul,
989 	[ODIV]		odiv,
990 	[OMOD]		omod,
991 	[OADD]		oadd,
992 	[OSUB]		osub,
993 	[ORSH]		orsh,
994 	[OLSH]		olsh,
995 	[OLT]		olt,
996 	[OGT]		ogt,
997 	[OLEQ]		oleq,
998 	[OGEQ]		ogeq,
999 	[OEQ]		oeq,
1000 	[ONEQ]		oeq,
1001 	[OLAND]		oland,
1002 	[OXOR]		oxor,
1003 	[OLOR]		olor,
1004 	[OCAND]		ocand,
1005 	[OCOR]		ocor,
1006 	[OASGN]		oasgn,
1007 	[OINDM]		oindm,
1008 	[OEDEC]		oeinc,
1009 	[OEINC]		oeinc,
1010 	[OPINC]		opinc,
1011 	[OPDEC]		opinc,
1012 	[ONOT]		onot,
1013 	[OIF]		0,
1014 	[ODO]		0,
1015 	[OLIST]		olist,
1016 	[OCALL]		ocall,
1017 	[OCTRUCT]	octruct,
1018 	[OWHILE]	0,
1019 	[OELSE]		0,
1020 	[OHEAD]		ohead,
1021 	[OTAIL]		otail,
1022 	[OAPPEND]	oappend,
1023 	[ORET]		0,
1024 	[OINDEX]	oindex,
1025 	[OINDC]		oindc,
1026 	[ODOT]		odot,
1027 	[OLOCAL]	0,
1028 	[OFRAME]	oframe,
1029 	[OCOMPLEX]	0,
1030 	[ODELETE]	odelete,
1031 	[OCAST]		ocast,
1032 	[OFMT]		ofmt,
1033 	[OEVAL]		oeval,
1034 	[OWHAT]		owhat,
1035 };
1036