Initial check-in of perl compiler.
[p5sagit/p5-mst-13.2.git] / ccop.c
1 /*      ccop.c
2  *
3  *      Copyright (c) 1996 Malcolm Beattie
4  *
5  *      You may distribute under the terms of either the GNU General Public
6  *      License or the Artistic License, as specified in the README file.
7  *
8  */
9
10 #include "EXTERN.h"
11 #include "perl.h"
12 #include "XSUB.h"
13 #include "ccop.h"
14
15 static char *opclassnames[] = {
16     "B::NULL",
17     "B::OP",
18     "B::UNOP",
19     "B::BINOP",
20     "B::LOGOP",
21     "B::CONDOP",
22     "B::LISTOP",
23     "B::PMOP",
24     "B::SVOP",
25     "B::GVOP",
26     "B::PVOP",
27     "B::CVOP",
28     "B::LOOP",
29     "B::COP"    
30 };
31
32 static opclass
33 cc_baseop(o)
34 OP *o;
35 {
36     return OPc_BASEOP;
37 }
38
39 static opclass
40 cc_unop(o)
41 OP *o;
42 {
43     return OPc_UNOP;
44 }
45
46 static opclass
47 cc_binop(o)
48 OP *o;
49 {
50     return OPc_BINOP;
51 }
52
53 static opclass
54 cc_logop(o)
55 OP *o;
56 {
57     return OPc_LOGOP;
58 }
59
60 static opclass
61 cc_condop(o)
62 OP *o;
63 {
64     return OPc_CONDOP;
65 }
66
67 static opclass
68 cc_listop(o)
69 OP *o;
70 {
71     return OPc_LISTOP;
72 }
73
74 static opclass
75 cc_pmop(o)
76 OP *o;
77 {
78     return OPc_PMOP;
79 }
80
81 static opclass
82 cc_svop(o)
83 OP *o;
84 {
85     return OPc_SVOP;
86 }
87
88 static opclass
89 cc_gvop(o)
90 OP *o;
91 {
92     return OPc_GVOP;
93 }
94
95 static opclass
96 cc_pvop(o)
97 OP *o;
98 {
99     return OPc_PVOP;
100 }
101
102 static opclass
103 cc_cvop(o)
104 OP *o;
105 {
106     return OPc_CVOP;
107 }
108
109 static opclass
110 cc_loop(o)
111 OP *o;
112 {
113     return OPc_LOOP;
114 }
115
116 static opclass
117 cc_cop(o)
118 OP *o;
119 {
120     return OPc_COP;
121 }
122
123 /* Nullified ops with children still need to be able to find o->op_first */
124 static opclass
125 cc_nullop(o)
126 OP *o;
127 {
128     return ((o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP);
129 }
130
131 static opclass
132 cc_stub(o)
133 OP *o;
134 {
135     warn("compiler stub for %s, assuming BASEOP\n", ppnames[o->op_type]);
136     return OPc_BASEOP;          /* XXX lie */
137 }
138
139 /*
140  * UNI(OP_foo) in toke.c returns token UNI or FUNC1 depending on whether
141  * bare parens were seen. perly.y uses OPf_SPECIAL to signal whether an
142  * OP or an UNOP was chosen.
143  * Frederic.Chauveau@pasteur.fr says we need to check for OPf_KIDS too.
144  */
145 static opclass
146 cc_baseop_or_unop(o)
147 OP *o;
148 {
149     return ((o->op_flags & OPf_SPECIAL) ? OPc_BASEOP :
150             (o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP);
151 }
152
153 /*
154  * The file stat OPs are created via UNI(OP_foo) in toke.c but use
155  * the OPf_REF flag to distinguish between OP types instead of the
156  * usual OPf_SPECIAL flag. As usual, if OPf_KIDS is set, then we
157  * return OPc_UNOP so that walkoptree can find our children. If
158  * OPf_KIDS is not set then we check OPf_REF. Without OPf_REF set
159  * (no argument to the operator) it's an OP; with OPf_REF set it's
160  * a GVOP (and op_gv is the GV for the filehandle argument).
161  */
162 static opclass
163 cc_filestatop(o)
164 OP *o;
165 {
166     return ((o->op_flags & OPf_KIDS) ? OPc_UNOP :
167             (o->op_flags & OPf_REF) ? OPc_GVOP : OPc_BASEOP);
168 }
169
170 /*
171  * next, last, redo, dump and goto use OPf_SPECIAL to indicate that a
172  * label was omitted (in which case it's a BASEOP) or else a term was
173  * seen. In this last case, all except goto are definitely PVOP but goto
174  * is either a PVOP (with an ordinary constant label), an UNOP with
175  * OPf_STACKED (with a non-constant non-sub) or an UNOP for OP_REFGEN
176  * (with goto &sub) in which case OPf_STACKED also seems to get set.
177  */
178
179 static opclass
180 cc_loopexop(o)
181 OP *o;
182 {
183     if (o->op_flags & OPf_STACKED)
184         return OPc_UNOP;
185     else if (o->op_flags & OPf_SPECIAL)
186         return OPc_BASEOP;
187     else
188         return OPc_PVOP;
189 }
190
191 static opclass
192 cc_sassign(o)
193 OP *o;
194 {
195     return ((o->op_private & OPpASSIGN_BACKWARDS) ? OPc_UNOP : OPc_BINOP);
196 }
197
198 static opclass (*ccopaddr[])_((OP *o)) = {
199         cc_nullop,              /* null */
200         cc_baseop,              /* stub */
201         cc_baseop_or_unop,      /* scalar */
202         cc_baseop,              /* pushmark */
203         cc_baseop,              /* wantarray */
204         cc_svop,                /* const */
205         cc_gvop,                /* gvsv */
206         cc_gvop,                /* gv */
207         cc_binop,               /* gelem */
208         cc_baseop,              /* padsv */
209         cc_baseop,              /* padav */
210         cc_baseop,              /* padhv */
211         cc_baseop,              /* padany */
212         cc_pmop,                /* pushre */
213         cc_unop,                /* rv2gv */
214         cc_unop,                /* rv2sv */
215         cc_unop,                /* av2arylen */
216         cc_unop,                /* rv2cv */
217         cc_svop,                /* anoncode */
218         cc_baseop_or_unop,      /* prototype */
219         cc_unop,                /* refgen */
220         cc_unop,                /* srefgen */
221         cc_baseop_or_unop,      /* ref */
222         cc_listop,              /* bless */
223         cc_baseop_or_unop,      /* backtick */
224         cc_listop,              /* glob */
225         cc_baseop_or_unop,      /* readline */
226         cc_stub,                /* rcatline */
227         cc_unop,                /* regcmaybe */
228         cc_logop,               /* regcomp */
229         cc_pmop,                /* match */
230         cc_pmop,                /* subst */
231         cc_logop,               /* substcont */
232         cc_pvop,                /* trans */
233         cc_sassign,             /* sassign */
234         cc_binop,               /* aassign */
235         cc_baseop_or_unop,      /* chop */
236         cc_baseop_or_unop,      /* schop */
237         cc_baseop_or_unop,      /* chomp */
238         cc_baseop_or_unop,      /* schomp */
239         cc_baseop_or_unop,      /* defined */
240         cc_baseop_or_unop,      /* undef */
241         cc_baseop_or_unop,      /* study */
242         cc_baseop_or_unop,      /* pos */
243         cc_unop,                /* preinc */
244         cc_unop,                /* i_preinc */
245         cc_unop,                /* predec */
246         cc_unop,                /* i_predec */
247         cc_unop,                /* postinc */
248         cc_unop,                /* i_postinc */
249         cc_unop,                /* postdec */
250         cc_unop,                /* i_postdec */
251         cc_binop,               /* pow */
252         cc_binop,               /* multiply */
253         cc_binop,               /* i_multiply */
254         cc_binop,               /* divide */
255         cc_binop,               /* i_divide */
256         cc_binop,               /* modulo */
257         cc_binop,               /* i_modulo */
258         cc_binop,               /* repeat */
259         cc_binop,               /* add */
260         cc_binop,               /* i_add */
261         cc_binop,               /* subtract */
262         cc_binop,               /* i_subtract */
263         cc_binop,               /* concat */
264         cc_listop,              /* stringify */
265         cc_binop,               /* left_shift */
266         cc_binop,               /* right_shift */
267         cc_binop,               /* lt */
268         cc_binop,               /* i_lt */
269         cc_binop,               /* gt */
270         cc_binop,               /* i_gt */
271         cc_binop,               /* le */
272         cc_binop,               /* i_le */
273         cc_binop,               /* ge */
274         cc_binop,               /* i_ge */
275         cc_binop,               /* eq */
276         cc_binop,               /* i_eq */
277         cc_binop,               /* ne */
278         cc_binop,               /* i_ne */
279         cc_binop,               /* ncmp */
280         cc_binop,               /* i_ncmp */
281         cc_binop,               /* slt */
282         cc_binop,               /* sgt */
283         cc_binop,               /* sle */
284         cc_binop,               /* sge */
285         cc_binop,               /* seq */
286         cc_binop,               /* sne */
287         cc_binop,               /* scmp */
288         cc_binop,               /* bit_and */
289         cc_binop,               /* bit_xor */
290         cc_binop,               /* bit_or */
291         cc_unop,                /* negate */
292         cc_unop,                /* i_negate */
293         cc_unop,                /* not */
294         cc_unop,                /* complement */
295         cc_listop,              /* atan2 */
296         cc_baseop_or_unop,      /* sin */
297         cc_baseop_or_unop,      /* cos */
298         cc_baseop_or_unop,      /* rand */
299         cc_baseop_or_unop,      /* srand */
300         cc_baseop_or_unop,      /* exp */
301         cc_baseop_or_unop,      /* log */
302         cc_baseop_or_unop,      /* sqrt */
303         cc_baseop_or_unop,      /* int */
304         cc_baseop_or_unop,      /* hex */
305         cc_baseop_or_unop,      /* oct */
306         cc_baseop_or_unop,      /* abs */
307         cc_baseop_or_unop,      /* length */
308         cc_listop,              /* substr */
309         cc_listop,              /* vec */
310         cc_listop,              /* index */
311         cc_listop,              /* rindex */
312         cc_listop,              /* sprintf */
313         cc_listop,              /* formline */
314         cc_baseop_or_unop,      /* ord */
315         cc_baseop_or_unop,      /* chr */
316         cc_listop,              /* crypt */
317         cc_baseop_or_unop,      /* ucfirst */
318         cc_baseop_or_unop,      /* lcfirst */
319         cc_baseop_or_unop,      /* uc */
320         cc_baseop_or_unop,      /* lc */
321         cc_baseop_or_unop,      /* quotemeta */
322         cc_unop,                /* rv2av */
323         cc_gvop,                /* aelemfast */
324         cc_binop,               /* aelem */
325         cc_listop,              /* aslice */
326         cc_baseop_or_unop,      /* each */
327         cc_baseop_or_unop,      /* values */
328         cc_baseop_or_unop,      /* keys */
329         cc_baseop_or_unop,      /* delete */
330         cc_baseop_or_unop,      /* exists */
331         cc_unop,                /* rv2hv */
332         cc_binop,               /* helem */
333         cc_listop,              /* hslice */
334         cc_listop,              /* unpack */
335         cc_listop,              /* pack */
336         cc_listop,              /* split */
337         cc_listop,              /* join */
338         cc_listop,              /* list */
339         cc_binop,               /* lslice */
340         cc_listop,              /* anonlist */
341         cc_listop,              /* anonhash */
342         cc_listop,              /* splice */
343         cc_listop,              /* push */
344         cc_baseop_or_unop,      /* pop */
345         cc_baseop_or_unop,      /* shift */
346         cc_listop,              /* unshift */
347         cc_listop,              /* sort */
348         cc_listop,              /* reverse */
349         cc_listop,              /* grepstart */
350         cc_logop,               /* grepwhile */
351         cc_listop,              /* mapstart */
352         cc_logop,               /* mapwhile */
353         cc_condop,              /* range */
354         cc_unop,                /* flip */
355         cc_unop,                /* flop */
356         cc_logop,               /* and */
357         cc_logop,               /* or */
358         cc_logop,               /* xor */
359         cc_condop,              /* cond_expr */
360         cc_logop,               /* andassign */
361         cc_logop,               /* orassign */
362         cc_unop,                /* method */
363         cc_unop,                /* entersub */
364         cc_unop,                /* leavesub */
365         cc_baseop_or_unop,      /* caller */
366         cc_listop,              /* warn */
367         cc_listop,              /* die */
368         cc_baseop_or_unop,      /* reset */
369         cc_listop,              /* lineseq */
370         cc_cop,                 /* nextstate */
371         cc_cop,                 /* dbstate */
372         cc_baseop,              /* unstack */
373         cc_baseop,              /* enter */
374         cc_listop,              /* leave */
375         cc_listop,              /* scope */
376         cc_loop,                /* enteriter */
377         cc_baseop,              /* iter */
378         cc_loop,                /* enterloop */
379         cc_binop,               /* leaveloop */
380         cc_listop,              /* return */
381         cc_loopexop,            /* last */
382         cc_loopexop,            /* next */
383         cc_loopexop,            /* redo */
384         cc_loopexop,            /* dump */
385         cc_loopexop,            /* goto */
386         cc_baseop_or_unop,      /* exit */
387         cc_listop,              /* open */
388         cc_baseop_or_unop,      /* close */
389         cc_listop,              /* pipe_op */
390         cc_baseop_or_unop,      /* fileno */
391         cc_baseop_or_unop,      /* umask */
392         cc_baseop_or_unop,      /* binmode */
393         cc_listop,              /* tie */
394         cc_baseop_or_unop,      /* untie */
395         cc_baseop_or_unop,      /* tied */
396         cc_listop,              /* dbmopen */
397         cc_baseop_or_unop,      /* dbmclose */
398         cc_listop,              /* sselect */
399         cc_listop,              /* select */
400         cc_baseop_or_unop,      /* getc */
401         cc_listop,              /* read */
402         cc_baseop_or_unop,      /* enterwrite */
403         cc_unop,                /* leavewrite */
404         cc_listop,              /* prtf */
405         cc_listop,              /* print */
406         cc_listop,              /* sysopen */
407         cc_listop,              /* sysread */
408         cc_listop,              /* syswrite */
409         cc_listop,              /* send */
410         cc_listop,              /* recv */
411         cc_baseop_or_unop,      /* eof */
412         cc_baseop_or_unop,      /* tell */
413         cc_listop,              /* seek */
414         cc_listop,              /* truncate */
415         cc_listop,              /* fcntl */
416         cc_listop,              /* ioctl */
417         cc_listop,              /* flock */
418         cc_listop,              /* socket */
419         cc_listop,              /* sockpair */
420         cc_listop,              /* bind */
421         cc_listop,              /* connect */
422         cc_listop,              /* listen */
423         cc_listop,              /* accept */
424         cc_listop,              /* shutdown */
425         cc_listop,              /* gsockopt */
426         cc_listop,              /* ssockopt */
427         cc_baseop_or_unop,      /* getsockname */
428         cc_baseop_or_unop,      /* getpeername */
429         cc_filestatop,          /* lstat */
430         cc_filestatop,          /* stat */
431         cc_filestatop,          /* ftrread */
432         cc_filestatop,          /* ftrwrite */
433         cc_filestatop,          /* ftrexec */
434         cc_filestatop,          /* fteread */
435         cc_filestatop,          /* ftewrite */
436         cc_filestatop,          /* fteexec */
437         cc_filestatop,          /* ftis */
438         cc_filestatop,          /* fteowned */
439         cc_filestatop,          /* ftrowned */
440         cc_filestatop,          /* ftzero */
441         cc_filestatop,          /* ftsize */
442         cc_filestatop,          /* ftmtime */
443         cc_filestatop,          /* ftatime */
444         cc_filestatop,          /* ftctime */
445         cc_filestatop,          /* ftsock */
446         cc_filestatop,          /* ftchr */
447         cc_filestatop,          /* ftblk */
448         cc_filestatop,          /* ftfile */
449         cc_filestatop,          /* ftdir */
450         cc_filestatop,          /* ftpipe */
451         cc_filestatop,          /* ftlink */
452         cc_filestatop,          /* ftsuid */
453         cc_filestatop,          /* ftsgid */
454         cc_filestatop,          /* ftsvtx */
455         cc_filestatop,          /* fttty */
456         cc_filestatop,          /* fttext */
457         cc_filestatop,          /* ftbinary */
458         cc_baseop_or_unop,      /* chdir */
459         cc_listop,              /* chown */
460         cc_baseop_or_unop,      /* chroot */
461         cc_listop,              /* unlink */
462         cc_listop,              /* chmod */
463         cc_listop,              /* utime */
464         cc_listop,              /* rename */
465         cc_listop,              /* link */
466         cc_listop,              /* symlink */
467         cc_baseop_or_unop,      /* readlink */
468         cc_listop,              /* mkdir */
469         cc_baseop_or_unop,      /* rmdir */
470         cc_listop,              /* open_dir */
471         cc_baseop_or_unop,      /* readdir */
472         cc_baseop_or_unop,      /* telldir */
473         cc_listop,              /* seekdir */
474         cc_baseop_or_unop,      /* rewinddir */
475         cc_baseop_or_unop,      /* closedir */
476         cc_baseop,              /* fork */
477         cc_baseop,              /* wait */
478         cc_listop,              /* waitpid */
479         cc_listop,              /* system */
480         cc_listop,              /* exec */
481         cc_listop,              /* kill */
482         cc_baseop,              /* getppid */
483         cc_baseop_or_unop,      /* getpgrp */
484         cc_listop,              /* setpgrp */
485         cc_listop,              /* getpriority */
486         cc_listop,              /* setpriority */
487         cc_baseop,              /* time */
488         cc_baseop,              /* tms */
489         cc_baseop_or_unop,      /* localtime */
490         cc_baseop_or_unop,      /* gmtime */
491         cc_baseop_or_unop,      /* alarm */
492         cc_baseop_or_unop,      /* sleep */
493         cc_listop,              /* shmget */
494         cc_listop,              /* shmctl */
495         cc_listop,              /* shmread */
496         cc_listop,              /* shmwrite */
497         cc_listop,              /* msgget */
498         cc_listop,              /* msgctl */
499         cc_listop,              /* msgsnd */
500         cc_listop,              /* msgrcv */
501         cc_listop,              /* semget */
502         cc_listop,              /* semctl */
503         cc_listop,              /* semop */
504         cc_baseop_or_unop,      /* require */
505         cc_unop,                /* dofile */
506         cc_baseop_or_unop,      /* entereval */
507         cc_unop,                /* leaveeval */
508         cc_logop,               /* entertry */
509         cc_listop,              /* leavetry */
510         cc_baseop_or_unop,      /* ghbyname */
511         cc_listop,              /* ghbyaddr */
512         cc_baseop,              /* ghostent */
513         cc_baseop_or_unop,      /* gnbyname */
514         cc_listop,              /* gnbyaddr */
515         cc_baseop,              /* gnetent */
516         cc_baseop_or_unop,      /* gpbyname */
517         cc_listop,              /* gpbynumber */
518         cc_baseop,              /* gprotoent */
519         cc_listop,              /* gsbyname */
520         cc_listop,              /* gsbyport */
521         cc_baseop,              /* gservent */
522         cc_baseop_or_unop,      /* shostent */
523         cc_baseop_or_unop,      /* snetent */
524         cc_baseop_or_unop,      /* sprotoent */
525         cc_baseop_or_unop,      /* sservent */
526         cc_baseop,              /* ehostent */
527         cc_baseop,              /* enetent */
528         cc_baseop,              /* eprotoent */
529         cc_baseop,              /* eservent */
530         cc_baseop_or_unop,      /* gpwnam */
531         cc_baseop_or_unop,      /* gpwuid */
532         cc_baseop,              /* gpwent */
533         cc_baseop,              /* spwent */
534         cc_baseop,              /* epwent */
535         cc_baseop_or_unop,      /* ggrnam */
536         cc_baseop_or_unop,      /* ggrgid */
537         cc_baseop,              /* ggrent */
538         cc_baseop,              /* sgrent */
539         cc_baseop,              /* egrent */
540         cc_baseop,              /* getlogin */
541         cc_listop,              /* syscall */
542 };
543
544 opclass
545 cc_opclass(o)
546 OP *    o;
547 {
548     return o ? (*ccopaddr[o->op_type])(o) : OPc_NULL;
549 }
550
551 char *
552 cc_opclassname(o)
553 OP *    o;
554 {
555     return opclassnames[o ? (*ccopaddr[o->op_type])(o) : OPc_NULL];
556 }
557