flip-flop 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. PP(pp_range)
  2. {
  3. if (GIMME == G_ARRAY)
  4. return NORMAL;
  5. if (SvTRUEx(PAD_SV(PL_op->op_targ)))
  6. return cLOGOP->op_other;
  7. else
  8. return NORMAL;
  9. }
  10. pp_range is a LOGOP.
  11. In list context, it just returns op_next.
  12. In scalar context it checks the truth of targ and returns
  13. op_other if true, op_next if false.
  14. flip is an UNOP.
  15. It "looks after" its child which is always a pp_range LOGOP.
  16. In list context, it just returns the child's op_other.
  17. In scalar context, there are three possible outcomes:
  18. (1) set child's targ to 1, our targ to 1 and return op_next.
  19. (2) set child's targ to 1, our targ to 0, sp-- and return child's op_other.
  20. (3) Blank targ and TOPs and return op_next.
  21. Case 1 happens for a "..." with a matching lineno... or true TOPs.
  22. Case 2 happens for a ".." with a matching lineno... or true TOPs.
  23. Case 3 happens for a non-matching lineno or false TOPs.
  24. $a = lhs..rhs;
  25. ,-------> range
  26. ^ / \
  27. | true/ \false
  28. | / \
  29. first| lhs rhs
  30. | \ first /
  31. ^--- flip <----- flop
  32. \ /
  33. \ /
  34. sassign
  35. /* range */
  36. if (SvTRUE(curpad[op->op_targ]))
  37. goto label(op_other);
  38. /* op_next */
  39. ...
  40. /* flip */
  41. /* For "..." returns op_next. For ".." returns op_next or op_first->op_other */
  42. /* end of basic block */
  43. goto out;
  44. label(range op_other):
  45. ...
  46. /* flop */
  47. out:
  48. ...