g | x | w | all
Bytes Lang Time Link
056APLDyalog Unicode240728T190608Zakamayu
037K ngn/k240728T190503Zovs
190Pascal240728T180000ZKai Burg
013Vyxal rDO210512T002334ZAaroneou
012Stax210512T020428ZRazetime
129Java210226T145136ZUnmitiga
066Perl 5 a210301T221807ZXcali
130YaBASIC210301T183717ZCaleb Fu
01705AB1E210226T170418Zcaird co
nanPython 3210226T095827ZSevC_10
111C gcc210226T132644ZNoodle9
029Japt210227T100533ZAZTECCO
nanPowerShell210226T160009ZWasif
071Bash210226T102901Zuser1009
071JavaScript V8210226T095850ZArnauld
089Bash + GNU utils210226T170054ZDigital
018Jelly210226T162030Zcaird co
080PHP210226T132741ZCray
206Batch210226T120006ZNeil
031Charcoal210226T112340ZNeil
082Python 3210226T094549ZDanis
086PHP210226T095947ZKaddath

APL(Dyalog Unicode), 56 bytes SBCS

{⍎∊(↓8 3⍴' 0⊣1+ -1-2× .5×⎕← {} 0')[7,⌽8,10|≢¨' '(≠⊆⊢)⍵]}

Try it on APLgolf!

K (ngn/k), 37 bytes

0{y@x}/( \;0.5*;2*;-1+;1+;0*)6!#'" "\

Try it online!

Pascal, 190 B

Like other submissions, we count the number of characters between each space. This is a full program in accordance to ISO standard 7185 Standard Pascal. Note the empty statement (;) for the zero length case. There must be a case label for every value of the selector expression; otherwise the program experiences an error at the end of input. The last character read from input is always a space.

program p(input,output);var n,x:real;begin
repeat n:=0;repeat n:=n+1;get(input)until' '=input^;case trunc(n/11)of
0:;1:x:=0;2:x:=x+1;3:x:=x-1;4:x:=x*2;5:x:=x/2;6:writeLn(x)end until EOF end.

And now the legible ungolfed version. Note, this version uses integer for the length counter.

program interpreterInterpreter(input, output);
    var
        characterCount: integer;
        accumulator:    real;
    begin
        repeat
        begin
            characterCount ≔ 0;
            
            repeat
            begin
                characterCount ≔ characterCount + 1;
                get(input)
            end
            until input↑ = ' ';
            
            case characterCount div 11 of
                0: ;
                1: accumulator ≔ 0.0;
                2: accumulator ≔ accumulator + 1;
                3: accumulator ≔ accumulator - 1;
                4: accumulator ≔ accumulator * 2;
                5: accumulator ≔ accumulator ∕ 2;
                6: writeLn(output, accumulator)
            end
        end
        until EOF(input)
    end.

Vyxal rDO, 13 bytes

⌈vL`…½d‹›0`İĖ

Try it Online!

Vyxal port of @caird coinheringaahing’s 05AB1E answer.

Explanation:

               # Implicit input
⌈              # Split on " "
 vL            # Length of each command
   `…½d‹›0`    # Push "…½d‹›0" 'D' flag - treat as raw string
           İ   # Index into string
            Ė  # Exec as Vyxal code
               # 'O' flag - disable implicit output


The commands in `…½d‹›0`:
… - Print without popping
½ - Halve
d - Double
‹ - Decrement
› - Increment
0 - Push 0

Stax, 12 bytes

î╜║µI*▄mß┘r>

Run and debug it

Who needs flags when compression? :P

Java, 137 129 bytes

s->{var x=0d;int l;for(var w:s.split(" ")){if((l=w.length()/11)==6)System.out.println(x);x-=new double[]{x,-1,1,-x,x/2,0}[l-1];}}

Try it online!

Saved 8 bytes thanks to branboyer.

Perl 5 -a, 66 bytes

eval((0,'$a=0','$a++','$a--','$a*=2','$a/=2','say$a')[y/i//])for@F

Try it online!

YaBASIC, 130 bytes

dim c$(1)
n=split(i$,c$())
for j=1 to n
c=mod(len(c$(j)),6)
if c a=a*or(and(6,9/c),c<2)/2+xor(mod(3/2^(c-3),6),2)-2
if !c ?a;
next

A basic interpreter interpreter running in an interpreted Basic interpreter...

Try it online!

Well, thanks to Arnauld's infamous MOD 6 trick, I was able to compress this perfectly readable, easily maintained and expandable 134 byte program:

dim c$(1)
n=split(i$,c$())
for j=1 to n
c=len(c$(j))/11
if c=1 a=0
if c=2 a=a+1
if c=3 a=a-1
if c=4 a=a*2
if c=5 a=a/2
if c=6 ?a;
next

into the 130-byte bit of opaque confusion seen above! 🤣 If I was gonna develop "interpreter" as a product, I know which code-base I'd start with, but really, I'd rather program in DeadFish...

05AB1E, 18 17 bytes

#€g"=;·<>0"sè».Võ

Try it online!

+2 bytes thanks to a bug, corrected by Makonede

-1 byte thanks to Command Master!

How it works

#€g"=;·<>0"sè».Võ - Program. Push the input I to the stack
#                 - Split I on spaces
 €g               - Lengths of €ach
   "=;·<>0"       - Push "=;·<>0"
           s      - Swap, moving the lengths to the top of the stack
            è     - Index into string, 0-based and modularly
             »    - Join by newlines
              .V  - Run as 05AB1E code
                õ - Push the empty string

This takes a similar approach to my Jelly answer, translating into 05AB1E then running. This only beats Jelly because the increment commands can go in strings in 05AB1E, but not in Jelly

We don't need to bother with any syntax nonsense to reset the accumulator in 05AB1E. Instead, as all the commands operate on the top value, we just push a 0 to the top of the stack

interpreter command Equivalent 05AB1E command What it does in 05AB1E
interpreter 0 Pushes 0 to the ToS (top of stack)
interpreterinterpreter > Increments the ToS
interpreterinterpreterinterpreter < Decrements the ToS
interpreterinterpreterinterpreterinterpreter · Doubles the ToS
interpreterinterpreterinterpreterinterpreterinterpreter ; Halves the ToS
interpreterinterpreterinterpreterinterpreterinterpreterinterpreter = Prints the ToS without popping it

We push an empty string at the end to prevent implicit output. If nothing has been output by the transpiled interpreter code, 05AB1E would output the ToS. We push the empty string so that if no output has been produced, 05AB1E outputs the empty string instead

Python 3, 138 bytes

Easy translation of the interpreter language instructions:

for i in[len(o)/11for o in input().split(' ')]:
 if i==1:a=0
 if i==2:a=a+1
 if i==3:a=a-1
 if i==4:a=a*2
 if i==5:a=a/2
 if i==6:print(a)

Try it online!

In the first line:

  1. takes the input
  2. split the instructions separated by a space
  3. divide by 11 (the lenght of the base word interpreter) to get the corresponding operation

The subsequent if execute the operations on the accumulator.

EDIT: theoretical improvements, code not modified (see version 2). Anyway, thanks for the suggestions!

-4 bytes thanks to @expressjs123

-3 bytes thanks to @ElPedro


VERSION 2

Python 3, 97 96 93 bytes

Improved the selection of the instructions simply by using list slicing.

-41 bytes compared to original version.

-1 byte thanks to @ElPedro

-3 bytes thanks to @Zaelin Goodman

a=0
for i in[len(o)//11for o in input().split()]:
 a-=[a,-1,1,-a,a/2,0][i-1]
 if i>5:print(a)

Try it online!

C (gcc), 113 \$\cdots\$ 113 111 bytes

Saved 3 6 bytes thanks to the man himself Arnauld!!!
Added 6 bytes to accommodate floating-point division. Saved 2 bytes thanks to ceilingcat!!!

float a;c;f(char*s){for(;*s;c?a=a*(6&9/c|c<2)/2+(3>>c-3^2)-2:printf("%f ",a),++s)for(c=1;*++s&&*s-32;c=++c%6);}

Try it online!

Japt, 29 bytes

¸®=Êu6)?E=[,E/2EÑEÉEÄT]gZ:OpE

Try it

PowerShell, 83 -> 73 -> NOW 59 bytes

$args|% Le*|%{,$a*!($_%6);$a-=(0,($a/2),-$a,1,-1,$a)[$_%6]}

Try it online!

Thanks to @mazzy and @ZaelinGoodman

Bash, 120 71 bytes

o=(. =0 ++ -- *=2 /=2)
for i;do
((x${o[n=${#i}/11]},n-6))||echo $x
done

Try it online!

Credits

JavaScript (V8), 71 bytes

s=>s.split` `.map(i=>(n=i.length%6)?s=[,s/2,s*2,s-1,s+1,0][n]:print(s))

Try it online!

How?

The length of an interpreter instruction is \$11\times k,\:1\le k \le 6\$, which gives \$[11,22,33,44,55,66]\$. When applying a modulo \$6\$, this maps to \$[5,4,3,2,1,0]\$. This is shorter than dividing by \$11\$ and allows us to easily identify the output instruction (size \$66\$, mapped to \$0\$) which behaves differently from the other ones.


JavaScript (V8), 80 bytes

This version is also based on the length of the instruction modulo \$6\$ but doesn't use any lookup table. It updates the accumulator with a single statement, using arithmetic and bitwise operations.

This is rather pointless in JS but does save a few bytes in C (as opposed to a chain of ternary operators).

s=>s.split` `.map(i=>(n=i.length%6)?A=A*(6&9/n|n<2)/2+(3>>n-3^2)-2:print(A),A=0)

Try it online!

           | n =        | multiply by:  | add:
 operation | length % 6 | (6&9/n|n<2)/2 | (3>>n-3^2)-2
-----------+------------+---------------+--------------
 clear     |      5     |       0       |      0
 increment |      4     |       1       |      1
 decrement |      3     |       1       |     -1
 double    |      2     |       2       |      0
 halve     |      1     |      0.5      |      0

Bash + GNU utils, 89

Transpiles to dc, then interprets:

sed -r 's/\S{11}/x/g;s/x{6}/p/g;s/x{5}/2\//g;s/x{4}/2*/g;s/xxx/1-/g;s/xx/1+/g;s/x/0/g'|dc

Try it online!

Jelly, 18 bytes

ḲẈị“HḤ“øȮ”j⁾’‘¤Vṛ“

Try it online!

How it works

ḲẈị“HḤ“øȮ”j⁾’‘¤Vṛ“ - Main link. Takes a string I on the left
Ḳ                  - Split I at spaces
 Ẉ                 - Get the length of each section
              ¤    - Group into a nilad:
   “HḤ“øȮ”         -   [["H", "Ḥ"], ["ø", "Ȯ"]]
           ⁾’‘     -   ["’", "‘"]
          j        -   Join; ["H", "Ḥ", "’", "‘", "ø", "Ȯ"]
  ị                - Index into the string, modularly and 1-indexed
               V   - Execute as Jelly code
                 “ - Yield the empty string
                ṛ  - Replace with the empty string to suppress automatic output

This program translates interpreter into Jelly and then runs it as Jelly code. First, only the lengths of each command actually matter. The lengths are [11, 22, 33, 44, 55, 66], which are unique modulo 6. The commands are transliterated as follows:

interpreter command Length Length mod 6 Jelly command
interpreter 11 5 ø
interpreterinterpreter 22 4
interpreterinterpreterinterpreter 33 3
interpreterinterpreterinterpreterinterpreter 44 2
interpreterinterpreterinterpreterinterpreterinterpreter 55 1 H
interpreterinterpreterinterpreterinterpreterinterpreterinterpreter 66 0 Ȯ

As Jelly uses modular indexing, we don't need to bother to modulo the lengths, we can just go ahead and into the command list.

Most of these commands are pretty obvious and are direct translations from the spec (e.g. is Jelly's increment command, is double etc.). However, ø is slightly different (and I think this is the only time I've every used it).

ø is a syntax command that tells Jelly to begin a new niladic chain. This basically tells Jelly to throw away everything before it and to reset, using 0 as the argument for the new command. As we're outputting as we go, its actually perfectly fine to "throw away" the previous commands, because they're no longer relevant.

PHP, 80 bytes

foreach(explode(' ',$argn)as$v)$a-=[$a/2,-$a,1,-1,$a][strlen($v)%6-1]??!print$a;

Try it online!

Explanation

$a                 // accumulator
-=                 // subtract operation result and assign to accumulator
[$a/2,-$a,1,-1,$a] // array of operations (divide, multiply, subtract, add, reset)
[strlen($v)%6-1]   // modulo 6 of command length, minus 1
                   // this way the print command (-1) will not be present in array
??                 // array key does not exist?
!print$a;          // print accumulator and toggle the boolean value of print's return
                   // toggle is required, because print always returns 1
                   // and we don't want to modify accumulator value, so !1 == 0

Credits

Batch, 206 bytes

@set/ps=
@set t=@set "s=
%t%%s:nterpreter=%
%t%%s: =&set/an%
%t%%s:set/aniiiiii=call:c%
%t%%s:iiiii=/=2%
%t%%s:iiii=*=2%
%t%%s:iii=-=1%
%t%%s:ii=+=1%
%t%%s:i==0%
@set/an%s%
@exit/b
:c
@echo %n%

Takes input on STDIN. Works by performing substitutions on the input string to produce Batch code which is then executed.

Charcoal, 31 bytes

F⪪S ≡№ιi¹≔⁰θ²≦⊕θ³≦⊖θ⁴≦⊗θ⁵≦⊘θ⟦Iθ

Try it online! Explanation:

F⪪S 

Split the input on spaces and loop over each word.

≡№ιi

Count the number of is in each word.

¹≔⁰θ²≦⊕θ³≦⊖θ⁴≦⊗θ⁵≦⊘θ⟦Iθ

Perform the appropriate operation on the accumulator depending on the number of is.

Note that a switch is shorter than looking up the results in an array as I don't have to initialise the accumulator.

Python 3, 84 82 bytes

n=0
for c in input().split():l=len(c)%10;n+=[-n,1,-1,n,-n/2,0][l-1];l==6==print(n)

Try it online!

-2 bytes Oliver Ni

PHP, 128 105 90 86 bytes

foreach(explode(' ',$argn)as$v)($i=strlen($v)%6)?$c-=[0,$c/2,-$c,1,-1,$c][$i]:print$c;

Try it online!

Actually counting the number of parts split by p rather than counting interpreter, so that any word that contains "p" would work.

EDIT: saved 23 bytes by using an array (inspired by other answers)

EDIT 2: another 15 bytes with @Arnauld the Great's modulo 6. Basically a port of his answer now

EDIT3: 4 bytes less with an array of values to subtract instead of an array to assign