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