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