Index: src/classes/Str.pir
===================================================================
--- src/classes/Str.pir	(revision 30136)
+++ src/classes/Str.pir	(working copy)
@@ -205,7 +205,85 @@
     .return(retv)
 .end
 
+=item subst
 
+ our Str method Str::subst ( Str $string: Str $substring, Str $replacement )
+ our Str method Str::subst ( Str $string: Code $regexp,   Str $replacement )
+
+Replaces the first occurrence of a given substring or a regular expression
+match with some other substring.
+
+Partial implementation. The :g modifier on regexps doesn't work, for example.
+
+=cut
+
+.sub subst :method :multi('Perl6Str','Perl6Str')
+    .param string substring
+    .param string replacement
+    .local int pos
+    .local int pos_after
+    .local pmc retv
+
+    retv = new 'Perl6Str'
+
+    $S0 = self
+    pos = index $S0, substring
+    if pos < 0 goto no_match
+
+    pos_after = pos
+    $I0 = length replacement
+    add pos_after, $I0
+
+    $S1 = substr $S0, 0, pos
+    $S2 = substr $S0, pos_after
+    concat retv, $S1
+    concat retv, replacement
+    concat retv, $S2
+
+    goto done
+
+  no_match:
+    retv = self
+
+  done:
+    .return(retv)
+.end
+
+.sub subst :method :lex :multi('Perl6Str','Sub','Perl6Str')
+    .param pmc regexp
+    .param string 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'()
+
+    $S0 = self
+    $S1 = substr $S0, 0, pos
+    $S2 = substr $S0, pos_after
+    concat retv, $S1
+    concat retv, replacement
+    concat retv, $S2
+
+    goto done
+
+  no_match:
+    retv = self
+
+  done:
+    .return(retv)
+.end
+
+
 =item perl()
 
 Returns a Perl representation of the Str.
