3 * Copyright (c) 1996 Malcolm Beattie
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.
15 static char *opclassnames[] = {
123 /* Nullified ops with children still need to be able to find o->op_first */
128 return ((o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP);
135 warn("compiler stub for %s, assuming BASEOP\n", ppnames[o->op_type]);
136 return OPc_BASEOP; /* XXX lie */
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.
149 return ((o->op_flags & OPf_SPECIAL) ? OPc_BASEOP :
150 (o->op_flags & OPf_KIDS) ? OPc_UNOP : OPc_BASEOP);
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).
166 return ((o->op_flags & OPf_KIDS) ? OPc_UNOP :
167 (o->op_flags & OPf_REF) ? OPc_GVOP : OPc_BASEOP);
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.
183 if (o->op_flags & OPf_STACKED)
185 else if (o->op_flags & OPf_SPECIAL)
195 return ((o->op_private & OPpASSIGN_BACKWARDS) ? OPc_UNOP : OPc_BINOP);
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 */
207 cc_binop, /* gelem */
208 cc_baseop, /* padsv */
209 cc_baseop, /* padav */
210 cc_baseop, /* padhv */
211 cc_baseop, /* padany */
212 cc_pmop, /* pushre */
215 cc_unop, /* av2arylen */
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 */
231 cc_logop, /* substcont */
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 */
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 */
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 */
280 cc_binop, /* i_ncmp */
288 cc_binop, /* bit_and */
289 cc_binop, /* bit_xor */
290 cc_binop, /* bit_or */
291 cc_unop, /* negate */
292 cc_unop, /* i_negate */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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 */
548 return o ? (*ccopaddr[o->op_type])(o) : OPc_NULL;
555 return opclassnames[o ? (*ccopaddr[o->op_type])(o) : OPc_NULL];