1. my class Regex { # declared in BOOTSTRAP
  2. # class Regex is Method
  3. # has @!caps;
  4. # has Mu $!nfa;
  5. # has %!alt_nfas;
  6. # has str $!source;
  7. # cache cursor initialization lookup
  8. my $cursor-init := Match.^lookup("!cursor_init");
  9. proto method ACCEPTS(|) { * }
  10. multi method ACCEPTS(Regex:D: Mu:U \a) {
  11. False
  12. }
  13. # use of Any on topic to force autothreading
  14. # so that all(@foo) ~~ Type works as expected
  15. multi method ACCEPTS(Regex:U: Any \topic) {
  16. nqp::p6bool(nqp::istype(topic, self))
  17. }
  18. multi method ACCEPTS(Regex:D \SELF: Any \topic) {
  19. nqp::decont(
  20. nqp::getlexrelcaller(nqp::ctxcallerskipthunks(nqp::ctx()),'$/') =
  21. nqp::stmts(
  22. (my \cursor := SELF.($cursor-init(Match, topic, :c(0)))),
  23. nqp::if(
  24. nqp::isge_i(nqp::getattr_i(cursor,Match,'$!pos'),0),
  25. cursor.MATCH,
  26. Nil
  27. )
  28. )
  29. )
  30. }
  31. multi method ACCEPTS(Regex:D \SELF: Uni:D \uni) { # RT #130458
  32. self.ACCEPTS(uni.Str)
  33. }
  34. multi method ACCEPTS(Regex:D \SELF: @a) {
  35. SELF!ACCEPT-ITERATOR(
  36. nqp::getlexrelcaller(nqp::ctxcallerskipthunks(nqp::ctx()),'$/'),
  37. @a.iterator
  38. )
  39. }
  40. multi method ACCEPTS(Regex:D \SELF: %h) {
  41. SELF!ACCEPT-ITERATOR(
  42. nqp::getlexrelcaller(nqp::ctxcallerskipthunks(nqp::ctx()),'$/'),
  43. %h.keys.iterator
  44. )
  45. }
  46. method !ACCEPT-ITERATOR(Regex:D \SELF: \slash, Iterator:D \iter) {
  47. nqp::decont(slash =
  48. nqp::stmts(
  49. nqp::until(
  50. nqp::eqaddr( # nothing to check?
  51. (my $pulled := iter.pull-one),IterationEnd)
  52. || nqp::isge_i( # valid match?
  53. nqp::getattr_i(
  54. (my \cursor := SELF.($cursor-init(Match,$pulled,:0c))),
  55. Match,'$!pos'),
  56. 0),
  57. nqp::null
  58. ),
  59. nqp::if(
  60. nqp::eqaddr($pulled,IterationEnd),
  61. Nil, # no match found
  62. cursor.MATCH # found it!
  63. )
  64. )
  65. )
  66. }
  67. multi method Bool(Regex:D:) {
  68. nqp::stmts(
  69. (my $ctx := nqp::ctx),
  70. nqp::until(
  71. nqp::isnull($ctx := nqp::ctxcallerskipthunks($ctx))
  72. || (my $underscore := nqp::getlexrelcaller($ctx,'$_')).DEFINITE,
  73. nqp::null
  74. ),
  75. nqp::if(
  76. nqp::isnull($ctx),
  77. False,
  78. nqp::stmts(
  79. (my $slash := nqp::getlexrelcaller($ctx,'$/')),
  80. ($slash = $underscore.match(self)).Bool
  81. )
  82. )
  83. )
  84. }
  85. multi method gist(Regex:D:) {
  86. nqp::ifnull($!source,'')
  87. }
  88. multi method perl(Regex:D:) {
  89. nqp::ifnull($!source,'')
  90. }
  91. }
  92. multi sub infix:<~~>(Mu \topic, Regex:D \matcher) {
  93. $/ := nqp::getlexrelcaller(nqp::ctxcallerskipthunks(nqp::ctx()),'$/');
  94. matcher.ACCEPTS(topic)
  95. }