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