Make a +-#$%! interpreter Because we haven't had enough of these, let's do another weird language!


+ increments the accumulator
- decrements the accumulator
# outputs the character with the codepoint of the accumulator modulo 127, and then resets the accumulator
$ is like # but it doesn't reset the accumulator
% reads a single character of input and then set the accumulator to that. If it is EOF, exit the program
! sets the accumulator to 0


At the end of the program, if the accumulator is 0, exit, otherwise, start again from the beginning, preserving the accumulator state.

Note that this language has no implementation so it is defined by this post.

Challenge

Given a valid +-#$%! program (containing only those characters) and the program input (containing only printable ASCII characters), return its output.

Examples

program, input -&gt; output // comments
%$, hello -&gt; hello // CAT program
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#++++++++++++++++++++++++++++++++#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++#, -&gt; Hi there
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$+++++++++++++++++++++++++++++++++$++++++++++++++++++++++++++++++++++++++++++++++++++++++$++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$+++++++++++++$++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++$!, -&gt; Hi there
>&lt;>, 112 bytes

You may be thinking "Is >&lt;> really the best language to write an interpreter in?", to which my answer is "no, but let's try anyway!"

i:}b(?v
0(?;v0&lt;o}\.24;!?:}\    /}~51. /}1-32./}1+32./}~i:
6*bb&lt; o:}\?="#":  \?(b:\?="!":\?="-":\?="+":\?="%":$%+


Try it online, or at the fish pond!

Takes input from STDIN: first the +-#$%! code, then optionally a newline and any extra input.

This could do with some explanation.


The first loop is i:}b(?v. This reads from STDIN to the stack until it hits a character less than b = 11, which means either a newline (charcode 10) or EOF (charcode -1).
Once that's done, the fish swims down…

  v
v0&lt;
&lt;


…into the main loop, adding a 0 to the stack to use as the accumulator.
First, the fish sees bb*6+% — this computes 127 = 11*11+6 and takes the modulus of the accumulator. Then $ brings forward the first character from the stack.
Now, we get to the bulk of the code — reading the character. There are seven branches in this bit of the code. (I think I've tetrissed the branches as much as I can, but there might be more blank space that can be removed here.)

0(?;                                       /}~i:
                                           \?="%":


Note that the fish starts from the bottom right, moving left, and wraps when it hits the side of the code. If the character is a literal "%", we shift it to the back of the stack for safekeeping, delete the accumulator, replace it with the first character in STDIN, check if that's EOF (that is, if its charcode is negative), and end the program if so. We then hit the start of the main loop again.

                             /}1-32./}1+32.
                             \?="-":\?="+":


If the character is "+", we put it on the back of the stack again, add 1 to the accumulator, and jump to the start of the main loop. The "-" case is similar.

                      /}~51.
                      \?="!":


If the character is "!", delete the accumulator and jump to just before the start of the main loop, where we first created the accumulator by adding a 0 to the stack.

         .24;!?:}\
                 \?(b:


If the character is EOF or newline, check if the accumulator is 0, and terminate the program if so; otherwise, jump back to the start of the main loop. We kept all the used characters on the stack, so now we're back at the start of the program anyway.

      o}\
        \?="#":


If the character is "#", output the accumulator as a character. We're then conveniently back just before the main loop, where we created the accumulator with a 0.

 
     o:}


If we've reached this branch, the character can only be "$", since the stack only contained the characters +-#$%! and EOF or linefeed. Therefore we print a copy of the accumulator, and we're back at the start of the main loop.