[Question]
  [
Because we can't get enough of esoteric language golfs, can we?
///—pronounced *slashes*—is a fun little language based on the `s///` regex-replacement function of Perl fame. It contains only two special characters, slash `/` and backslash `\`. You can find a full article on it at the [esolangs wiki](http://esolangs.org/wiki////), but I will reproduce a description of the language below, as well as some examples.
In short, it works by identifying `/pattern/repl/rest` in the program and making the substitution as many times as possible. No characters are special except `/` and `\`: `/` demarcates patterns and replacements in the program, while `\` allows you to insert literal `/` or `\` characters into your code. Notably, these are not regular expressions, just plain string substitutions.
*Your challenge* is to produce an interpreter for the /// language, as either a program reading STDIN or a function taking a string argument, in as few characters as possible.
You may use any language except for /// itself. You may not use any libraries that interpret ///; you may, however, use regexes, regex libraries, or string-matching libraries.
---
## Execution
There are four states, *print*, *pattern*, *replacement*, and *substitution*. In every state except *substitution*:
* If the program is empty, execution halts.
* Else, if the first character is `\`, do something with the next character (if present) and remove both from the program.
* Else, if the first character is `/`, remove it, and change to the next state.
* Else, do something with the first character and remove it from the program.
* Repeat.
The states cycle through *print*, *pattern*, *replacement*, and *substitution* in order.
* In *print* mode, 'do something' means output the character.
* In *pattern* mode, 'do something' means add the character to the current Pattern.
* In *replacement* mode, 'do something' means add the character to the current Replacement.
In *substitution* mode, you follow a different set of rules. Repeatedly substitute the first occurrence of the current Pattern with the current Replacement in the program, until no more substitutions are possible. At that point, clear the Pattern and Replacement and return to *print* mode.
In the program `/foo/foobar/foo foo foo`, the following happens:
```
/foo/foobar/foo foo foo
foo foo foo
foobar foo foo
foobarbar foo foo
foobarbarbar foo foo
...
```
This loops forever and never exits *substitution* mode. Similarly, if the Pattern is empty, then the first occurrence of the empty string—at the beginning of the program—always matches, so *substitution* mode loops forever, never halting.
---
## Examples
```
no
```
Output: `no`.
```
/ world! world!/Hello,/ world! world! world!
```
Output: `Hello, world!`.
```
/foo/Hello, world!//B\/\\R/foo/B/\R
```
Output: `Hello, world!`.
```
a/ab/bbaa/abb
```
Output: `a`. Program does not halt.
```
//
```
Output: none.
```
///
```
Output: none. Program does not halt.
```
/\\/good/\/
```
Output: `good`.
There is also a quine [on the wiki](http://esolangs.org/wiki////#Quine) you can try.
  
[Answer]
# J - ~~181~~ ~~190~~ 170 char
This was a nightmare. I rewrote it from scratch, twice, because it just kept bugging me. This is a function taking a single string argument, outputting to STDOUT.
```
(0&$`((2{.{:@>&.>)((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i 5;@}.&,'/';"0;&.>)@.(2<#)@}.[4:1!:2~{:@>@p=.>@{.@[)@((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)i=. ::](^:_)
```
To explain, I will break it up into subexpressions.
```
i =. ::](^:_))
parse =: ((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)
print =: 4:1!:2~{:@>@p=.>@{.@[
eval  =: 0&$`((2{.{:@>&.>)sub 5;@}.&,'/';"0;&.>)@.(2<#)@}.
sub   =: ((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i
interp =: (eval [ print) @ parse i
```
* `i` (short for *iterate*) is an adverb. It takes a verb argument on the left and returns a verb `(f)i`, which when applied to an argument, applies `f` repeatedly to the argument until one of two things happens: it finds a fixed point (`y = f y`), or it throws an error. The fixed-point behaviour is inherent to `^:_`, and `::]` does the error handling.
* `parse` tokenizes the input into what I call *half-parsed* form, and then cuts it up at the unescaped '/'. It binds escaping backslashes to their characters, but doesn't get rid of the backslashes—so we can either revert it or finish it depending on which we want.
The bulk of the interesting work occurs in `;:`. This is a sequential-machine interpreter primitive, taking a description of the machine (`(0;(0,:~1 0,.2);'\';&<1 0)`) on the left and something to parse on the right. This does the tokenizing. I will note that this specific machine actually treats the first character unspecial, even if it's a `\` and should bind. I do this for a few reasons: (1) the state table is simpler, so it can be golfed further; (2) we can easily just add a dummy character to the front to dodge the problem; and (3) that dummy-character gets half-parsed at no extra cost, so I can use it to set up for the cutting phase, next.
We also use `<;._1` to cut the tokenized result on unescaped `/` (which is what I choose to be the first char). This is handy for pulling out the output, pattern, and replacement from `out/patt/repl/rest` all in one step, but unfortunately also cuts up the rest of the program, where we need those `/` to stay untouched. I splice these back in during `eval`, because making `<;._1` leave them alone ends up costing a lot more.
* The fork `(eval [ print)` executes `print` on the result from `parse` for its side-effects, and then runs `eval`. `print` is a simple verb that opens up the first box (the one we know for sure is output), finishes parsing it, and sends it to STDOUT. However, we also take the chance to define a utility verb `p`.
`p` is defined as `>@{.@[`, so it takes its left arg (acts like the identity if given only one arg), takes the first item of that (identity when given a scalar), and unboxes it (identity if already unboxed). This will come in very handy in `sub`.
* `eval` evaluates the remainder of the processed program. If we don't have a full pattern or a full replacement, `eval` throws it out and just returns an empty list, which terminates evaluation by making `;:` (from `parse`) error out on the next iteration. Else, `eval` fully parses the pattern and replacement, corrects the remainder of the source, and then passes both to `sub`. By explosion:
```
                                              @}.  NB. throw out printed part
                                       @.(2<#)     NB. if we have a pattern and repl:
      2{.                                          NB.  take the first two cuts:
             &.>                                   NB.   in each cut:
         {:@>                                      NB.    drop escaping \ from chars
     (          )                                  NB.  (these are pattern and repl)
                                   &.>             NB.  in each cut:
                                  ;                NB.   revert to source form
                            '/';"0                 NB.  attach a / to each cut
                          &,                       NB.  linearize (/ before each cut)
                     5  }.                         NB.  drop '/pattern/repl/'
                      ;@                           NB.  splice together
    (            sub                  )            NB.  feed these into sub
   `                                               NB. else:
0&$                                                NB.  truncate to an empty list
```
* `sub` is where one (possibly infinite) round of substitutions happens. Because of the way we set up `eval`, the source is the right argument, and the pattern and replacement are bundled together in the left. Since the arguments are ordered like this and we know the pattern and replacement don't change within a round of substitutions, we can use another feature of `i`—the fact that it modifies only the right argument and keeps passing in the same left—to delegate to J the need to worry about keeping track of the state.
There are two spots of trouble, though. The first is that J verbs can have at most two arguments, so we don't have an easy way to access any that are bundled together, like pattern and replacement, here. Through clever use of the `p` utility we defined, this isn't that big of a problem. In fact, we can access the pattern in one character, just by using `p`, because of its `>@{.@[` definition: the Unbox of the First item of the Left arg. Getting the replacement is tricker, but the shortest way would be `p&|.`, 2 chars shorter than manually getting it out.
The second problem is that `i` exits on fixed points instead of looping forever, and if the pattern and replacement are equal and you make a substitution, that looks like a fixed point to J. We handle this by entering an infinite loop of negating 1 over and over if we detect they are equal: this is the `-i@=`p@.~:~/` portion, replacing `p&|.`.
```
                                    p    E.]    NB. string search, patt in src
                                      I.@       NB. indices of matches
                                  0{            NB. take the first (error if none)
                               j=.              NB. assign to j for later use
                           #@p+                 NB. add length of pattern
                       ]}.~                     NB. drop that many chars from src
                   /@[                          NB. between patt and repl:
                  ~                             NB.  patt as right arg, repl as left
              @.~:                              NB.  if equal:
        -i@=                                    NB.   loop forever
            `p                                  NB.  else: return repl
 (j{.])                                         NB. first j chars of src
       ,              ,                         NB. append all together
(                                           )i  NB. iterate
```
* This cycle repeats due to the use of `i`, until something outside of `sub` errors out. As far as I'm aware, this can only happen when we are out of characters, of when we throw out an incomplete set of pattern-and-replacement.
Fun facts about this golf:
* For once, using `;:` is shorter than manually iterating through the string.
* `0{` should have a chance to error out before `sub` goes into an infinite loop, so this it should work fine if the pattern matches the replacement but never shows up in the remainder of the source. However, this may or may not be unspecified behaviour, since I can't find a citation either way in the docs. Whoopsie.
* Keyboard interrupts are processed as spontaneous errors inside running functions. However, due to the nature of `i`, those errors get trapped too. Depending on when you hit Ctrl+C, you might:
	+ Exit out of the negate-forever loop, error out of the `sub` loop by trying to concatenate a number to a string, and then go on interpreting /// as if you finished substituting a string with itself an infinite number of times.
	+ Leave `sub` halfway through and go on interpreting a half-subbed /// expression.
	+ Break out of the interpreter and return an unevaluated /// program to the REPL (not STDOUT, though).
Example usage:
```
   f=:(0&$`((2{.{:@>&.>)((j{.]),-i@=`p@.~:~/@[,]}.~#@p+j=.0{p I.@E.])i 5;@}.&,'/';"0;&.>)@.(2<#)@}.[4:1!:2~{:@>@p=.>@{.@[)@((0;(0,:~1 0,.2);'\';&<1 0)<;._1@;:'/'&,)i=. ::](^:_)
   f 'no'
no
   f '/ world! world!/Hello,/ world! world! world!'
Hello, world!
   f '/foo/Hello, world!//B\/\\R/foo/B/\R'
Hello, world!
   f '//'  NB. empty string
   f '/\\/good/\/'
good
```
[Answer]
## APL (133)
```
{T←''∘{(0=≢⍵)∨'/'=⊃⍵:(⊂⍺),⊂⍵⋄(⍺,N⌷⍵)∇⍵↓⍨N←1+'\'=⊃⍵}⋄⍞N←T⍵⋄p N←T 1↓N⋄r N←T 1↓N⋄''≡N:→⋄∇{⍵≡p:∇r⋄∨/Z←p⍷⍵:∇(r,⍵↓⍨N+≢p),⍨⍵↑⍨N←1-⍨Z⍳1⋄⍵}1↓N}
```
This is a function that takes the `///` code as its right argument. 
Ungolfed, with explanation:
```
slashes←{
   ⍝ a function to split the input string into 'current' and 'next' parts,
   ⍝ and unescape the 'current' bit
   split←''∘{
       ⍝ if the string is empty, or '/' is reached,
       ⍝ return both strings (⍺=accumulator ⍵=unprocessed)
       (0=≢⍵)∨'/'=⊃⍵:(⊂⍺),⊂⍵
       ⍝ otherwise, add current character to accumulator,
       ⍝ skipping over '\'s. (so if '\/' is reached, it skips '\',
       ⍝ adds '/' and then processes the character *after* that.)
       idx←1+'\'=⊃⍵
       (⍺,idx⌷⍵)∇idx↓⍵
   }
   ⍞   next ← split ⍵      ⍝ output stage
   pat next ← split 1↓next ⍝ pattern stage, and eat the '/'
   rpl next ← split 1↓next ⍝ replacement stage, and eat the '/'
   ⍝ if there are no characters left, halt.
   ''≡next:⍬
   ⍝ otherwise, replace and continue.
   ∇{  ⍝ if the input string equals the pattern, return the replacement and loop
       ⍵≡pat:∇rpl
       ⍝ otherwise, find occurences, if there are, replace the first and loop
       ∨/occ←pat⍷⍵:∇(rpl, (idx+≢pat)↓⍵),⍨ (idx←(occ⍳1)-1)↑⍵
       ⍝ if no occurences, return string
       ⍵
   }1↓next
}
```
[Answer]
# [Pip](http://github.com/dloscutoff/pip), ~~100~~ 102 bytes
I hadn't ever proven Pip to be Turing-complete (though it's pretty obviously so), and instead of going the usual route of BF I thought /// would be interesting. Once I had the solution, I figured I'd golf it and post it here.
101 bytes of code, +1 for `-r` flag:
```
i:gJnf:{a:xW#i&'/NE YPOia.:yQ'\?POiya}W#iI'\Q YPOiOPOiEIyQ'/{p:VfY0s:VfIyQ'/WpNi&YviR:Xp{++y?ps}}E Oy
```
Here's my ungolfed version with copious comments:
```
; Use the -r flag to read the /// program from stdin
; Stdin is read into g as a list of lines; join them on newline and assign to c for code
c : gJn
; Loop while c is nonempty
W #c {
 ; Pop the first character of c and yank into y
 Y POc
 ; If y equals "\"
 I yQ'\
  ; Pop c again and output
  O POc
 ; Else if y equals "/"
 EI yQ'/ {
  ; Build up pattern p from empty string
  p : ""
  ; Pop c, yank into y, loop while that is not equal to "/" and c is nonempty
  W #c & '/ NE Y POc {
   ; If y equals "\"
   I yQ'\
    ; Pop c again and add that character to p
    p .: POc
   ; Else, add y to p
   E p .: y
  }
  ; Yank 0 so we can reliably tell whether the /// construct was completed or not
  Y0
  ; Build up substitution s from empty string
  s : ""
  ; Pop c, yank into y, loop while that is not equal to "/" and c is nonempty
  W #c & '/ NE Y POc {
   ; If y equals "\"
   I yQ'\
    ; Pop c again and add that character to s
    s .: POc
   ; Else, add y to s
   E s .: y
  }
  ; If the last value yanked was "/", then we have a complete substitution
  ; If not, the code must have run out; skip this branch, and then the outer loop
  ; will terminate
  I yQ'/ {
   ; While pattern is found in code:
   W pNc {
    ; Set flag so only one replacement gets done
    i : 0
    ; Convert p to a regex; replace it using a callback function: if ++i is 1,
    ; replace with s; otherwise, leave unchanged
    c R: Xp {++i=1 ? s p}
   }
  }
 }
 ; Else, output y
 E Oy
}
```
[Try it online!](https://tio.run/##NYwxC8IwFIR3f0VFaMHYXrIGxKlDHaw6qIVbulSySLAgltLfHl@qPvKOu/se8c6H4Ox9/@js2Nr3deXSDIcyaY61aws7nDLuxA7tJKjKeJpJLVtWAjF6e@ka3YvO@eoPLm1e7mxvflRq2Pl@msqkHkLAAsASREFqYkNudBTDb2d@XYzRxFKsIhWxJbfxJicW3/QnWM6DQn5XVKI5SOmhYSBvDaUKE/LnBw "Pip - Try It Online") (Note that TIO doesn't give any output when the program is non-terminating, and it also has a time limit. For larger examples and infinite loops, running Pip from the command line is recommended.)
[Answer]
# Perl - 190
```
$|=1;$/=undef;$_=<>;while($_){($d,$_)=/(.)(.*)/;eval(!$e&&({'/','$a++','\\','$e=1'}->{$d})||('print$d','$b.=$d','$c.=$d')[$a].';$e=0');if($a==3){while($b?s/\Q$b/$c/:s/^/$c/){}$a=0;$b=$c=''}}
```
Reads `///` program from stdin until EOF.
[Answer]
# C++ 347
**Edits:**
* **Thanks to @algorithmshark for lots of help making the original shorter**
* **Thanks to @Adalynn for a good suggestion to save bytes**
* **Thanks to @ceilingcat for many, many very nice pieces of golfing - now even shorter**
Here is the code:
```
#import<bits/stdc++.h>
#define N(x)o[i]);else if(n<x)o[i]==92?
#define O (o[++i]):o[i]==47?n++:
char p[198],*q=p,*s=p+99;int i,t;main(int n,char**m){for(std::string o=m[1];i<=o.size();++i){if(!N(3)putchar O putchar(N(4)*q++=O(*q++=N(5)*s++=O(*s++=o[i]);if(n>4){for(n=2;~(t=o.find(p,i+1));o=o.substr(0,t)+s+&o[t+strlen(p)])s=p+99;bzero(q=p,198);}}}
```
[Try it online!](https://tio.run/##PY/BbsIwEETv/QojpGodu6RQqjYxBolTT0HimuQAiQOWEtvERq1A9NdTh6Cedmd3pJlXGPNyKIquG8vG6NYt9tLZ0LqyIGRyXD6NS1FJJVACP1inMsdM1FYgWYFaDBfOo9nq37dBoFNCvDEenvOPlSIkfiqOuxaZdBp95jQ4cUMDyw2JIiaVQ5I61uykgl4o2nuDoMHXSrfgu8Sxda1UB6R5k05zJhdcT6y8CMDMZ@GrrzNK4A2bs7vnbNBjgwTmODgRwjdwHwm848AOuh8DU4@znA95is/YLzif4IFKMFSSKcZM95HnvS8Cr9RhYsmzTh3xuhYKDM7xg2d/Ea2GntCzYna73bquCyutwy9R15qib93W5SgM11mYZdv7Zx1m2z8 "C++ (gcc) – Try It Online")
[Answer]
# Python 2 (236), Python 3 (198?)
```
from __future__ import print_function
def d(i):
 t=0;p=['']*3+[1]
 while i:
  if'/'==i[0]:t+=1
  else:
   if'\\'==i[0]:i=i[1:]
   p[t]+=i[0]
  i=i[1:]
  print(end=p[0]);p[0]=''
  if t>2:
   while p[1]in i:i=i.replace(*p[1:])
   d(i);i=0
```
Called as `d(r"""/foo/Hello, world!//B\/\\R/foo/B/\R""")`. The triple quotes are only needed if the `///` program contains newlines: otherwise simple quotes are ok.
EDIT: This interpreter now prints stuff as expected (previously it only printed at the very end, cf. comments). For Python 3, remove the first line (but I don't have Python 3 on my ancient install, so cannot be sure there is no other change).
[Answer]
# Cobra - 226
```
sig Z as String
def f(l='')
    m=Z(do=[l[:1],l=l[1:]][0])
    n as Z=do
        if'/'<>(a=m())>'',return if(a=='\\',m(),a)+n()
        else,return''
    print n()stop
    p,s=n(),n()
    if''<l
        while p in l,l=l[:l.indexOf(p)+1]+s+l[p.length:]
        .f(l)
```
[Answer]
# **[BaCon](http://www.basic-converter.org), ~~391~~ ~~387~~ 395 bytes**
From the contributions on this page I only got the Python program to work. The others work for some /// samples, or do not work at all. Therefore, I decided to add my version, which is an implementation in BASIC.
To compete in a CodeGolf contest with BASIC is not easy, as BASIC uses long words as statements. The only abbreviation commonly found in BASIC is the '?' sign, which means PRINT.
So the below program may never win, but at least it works with all demonstration code on this Codegolf page and on the [Esolangs Wiki](http://esolangs.org/wiki////). Including all versions of the "99 bottles of beer".
```
p$=""
r$=""
INPUT i$
WHILE LEN(i$)
t$=LEFT$(i$,1)
i$=MID$(i$,2)
IF NOT(e) THEN
IF t$="\\" THEN
e=1
CONTINUE
ELIF t$="/" THEN
o=IIF(o<2,o+1,0)
IF o>0 THEN CONTINUE
FI
FI
IF o=1 THEN
p$=p$&t$
ELIF o=2 THEN
r$=r$&t$
ELIF o=0 THEN
IF LEN(p$) THEN i$=REPLACE$(i$,p$,r$)
IF NOT(INSTR(t$&i$,"/")) THEN
?t$;
BREAK
ELSE
?LEFT$(i$,INSTR(i$,"/")-1);
i$=MID$(i$,INSTR(i$,"/"))
FI
p$=""
r$=""
FI
e=0
WEND
?i$
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~119~~ 110 bytes
Terminates with exception
```
r=->s,o=$>{s[k=s[0]]='';k==?/?o==$>?s.gsub!([r[s,''],e=r[s,'']][0]){e}:t=o:o<<(k==?\\?s[0]+s[0]='':k);t||redo}
```
[Try it online!](https://tio.run/##fZBPb@IwEMXv/hSDbCutGnAIf4eSckaqelpxSaMqgCkRIWZjZ1EFfHZ2AuS00h6ePT/7zfPIZbX8uV7LqP1mfROJt5ONd5GNgySJPO91F0UzNTMRXcxs59tWy9ZTXMbW97zE19GjSsj@fNKXiYvMxEynT3Xb5@esjnmpF4qa7J5f3flc6rW5XDm4bWYhzXNztLAxJeyr3GV5VmjIikPlGL/vQC6X7nQBm9Lswbp1VoAzkP4x2Rqq7/wHtF2lBw1W/650sdKW3Rsj8Dwmph2drrZft@DTOTs/UqdTyC6Mc8bK@HaSXFXCYqUUV7A0zuXagtnAUusSDL241XCkaX2mVOsfB/tFE5JNw9ocCx8OqbWQOUhLUxVrXymhWtQo/xvdYWT5eFfsNshcIXJEgWOJY45jgSOJI44jgUOJQ45DgQOJA44DgX2JfY59gT2JPY49gaHEkGMosCuxy7ErMJAYcAxat/QFPYQo5zXM6wNC0lgt7jAmjRoYkYYNDEmDBgakfgN9Uq@BHilsICR1G@iS2upeUxXwNs1040B9GNibUj9u2/VvkJpPq5sftVr8BQ "Ruby – Try It Online")
Terminates cleanly (116 bytes)
```
r=->s,o=$>{s[k=s[0]||exit]='';k==?/?o==$>?s.gsub!([r[s,''],e=r[s,'']][0]){e}:t=o:o<<(k==?\\?s[0]+s[0]='':k);t||redo}
```
[Try it online!](https://tio.run/##fZBPb@IwEMXv/hSDbCutNuDwn6GknJFWPa24pFEVwJSIELOxs2xF@OzsBMhppR6ePT973vPIRbn6ul6LsP1qfROK17ON9qGNgriq9N/UxaHnvezDcK7mJqTrue182nLVeoqKyPqeF/s6fFQxmZ7P@jJ1oZma2eyptr2/z@uwH/VCUdP984urqkJvzOXKwe1SC0mWmZOFrSngUGYuzdJcQ5ofS8f4fQfqcsle57AtzAGs26Q5OAPJH5NuoPzMvkDbdXLUYPXvUudrbdndGILnMTHr6GS9@7gFn6u0eqTOZpBeGOeMFdHtJL6qmEVKKa5gZZzLtAWzhZXWBRh6cafhRNP6TKnWfx3sF01IbRo25pT7cEyshdRBUpgy3/hKCdUio/w2usOo5e2nYrdBFgqRIwqcSJxwnAgcSxxzHAscSRxxHAkcShxyHAocSBxwHAjsS@xz7AvsSexx7AnsSuxy7AoMJAYcg9YtfUkPIcpFDYv6gJA0Ucs7TEjjBsakUQMj0rCBIWnQwIDUb6BP6jXQI3Ub6JLa6l5TFfA2zXTjQL0ZOJhCP27b9W@Qmk@rzY9aLf8B "Ruby – Try It Online")
[Answer]
# Python 2/3 (211 bytes)
The following code, based on [Bruno Le Floch's answer](https://codegolf.stackexchange.com/a/37093), is Python 2 and Python 3 compatible.
Moreover, being iterative rather than recursive it does not risk hitting the maximum recursion depth of Python.
```
def S(c):
 while c:
  B=["","",1]
  for m in 0,1,2:
   while c:
    if"/"==c[0]:c=c[1:];break
    if"\\"==c[0]:c=c[1:]
    if m:B[m-1]+=c[0]
    else:yield c[0]
    c=c[1:]
  while c and B[0]in c:c=c.replace(*B)
```
]