Author: pmichaud
Date: Sun Nov 30 19:47:01 2008
New Revision: 33398

Modified:
   trunk/languages/perl6/src/builtins/any-str.pir

Log:
[rakudo]: Add :g(lobal) flag to .subst( $regex, $repl )


Modified: trunk/languages/perl6/src/builtins/any-str.pir
==============================================================================
--- trunk/languages/perl6/src/builtins/any-str.pir      (original)
+++ trunk/languages/perl6/src/builtins/any-str.pir      Sun Nov 30 19:47:01 2008
@@ -892,7 +892,7 @@
 
 =cut
 
-.sub subst :method :multi(_, _, _)
+.sub 'subst' :method :multi(_, _, _)
     .param string substring
     .param string replacement
     .local int pos
@@ -924,54 +924,72 @@
     .return(retv)
 .end
 
-.sub subst :method :lex :multi(_, 'Sub', _)
-    .param pmc regexp
+.sub 'subst' :method :multi(_, 'Sub', _)
+    .param pmc regex
     .param pmc replacement
-    .local int pos
-    .local int pos_after
-    .local pmc retv
-    .local pmc match
-
-    retv = new 'Perl6Str'
-
-    new $P14, "Perl6Scalar"
-    .lex "$/", $P14
-
-    match = regexp.'ACCEPTS'(self)
-    unless match goto no_match
-    pos = match.'from'()
-    pos_after = match.'to'()
+    .param pmc options         :slurpy :named
 
-    $S0 = self
-    $S1 = substr $S0, 0, pos
-    $S2 = substr $S0, pos_after
-    # pre-match
-    concat retv, $S1
-
-    # match
+    .local pmc global_flag
+    global_flag = options['global']
+    unless null global_flag goto have_global
+    global_flag = options['g']
+    unless null global_flag goto have_global
+    global_flag = get_hll_global ['Bool'], 'False'
+  have_global:
+
+    # build a list of matches
+    .local pmc matchlist, match
+    .local string result
+    matchlist = new 'ResizablePMCArray'
+    result = self
+    match = regex(result)
+    unless match goto matchlist_done
+    push matchlist, match
+    unless global_flag goto matchlist_done
+  matchlist_loop:
+    match = regex(match)
+    unless match goto matchlist_done
+    push matchlist, match
+    goto matchlist_loop
+  matchlist_done:
+
+    # get caller's lexpad
+    .local pmc lexpad
+    $P0 = getinterp
+    lexpad = $P0['lexpad';1]
+
+    # now, perform substitutions on matchlist until done
+    .local int offset
+    offset = 0
+    result = clone result
+  subst_loop:
+    unless matchlist goto subst_done
+    match = shift matchlist
+    lexpad['$/'] = match
+    # get substitution string
+    .local string replacestr
     $I0 = isa replacement, 'Sub'
-    unless $I0 goto is_string
-
-    $S3 = match.'text'()
-    $S3 = replacement($S3)
-    concat retv, $S3
-    goto repl_done
-
-  is_string:
-    concat retv, replacement
-
-  repl_done:
-    # post-match
-    concat retv, $S2
-
-    goto done
-
-  no_match:
-    retv = self
-
-  done:
-    .return(retv)
+    if $I0 goto replacement_sub
+    replacestr = replacement
+    goto have_replacestr
+  replacement_sub:
+    $S0 = match
+    replacestr = replacement($S0)
+  have_replacestr:
+    # perform the replacement
+    $I0 = match.'from'()
+    $I1 = match.'to'()
+    $I2 = $I1 - $I0
+    $I0 += offset
+    substr result, $I0, $I2, replacestr
+    $I3 = length replacestr
+    $I3 -= $I2
+    offset += $I3
+    goto subst_loop
+  subst_done:
+    .return (result)
 .end
+    
 
 =item ord()
 

Reply via email to