g | x | w | all
Bytes Lang Time Link
109Swift 6240401T123632ZmacOSist
039Uiua 0.10.0240331T112316ZRomanPro
167Easyfuck240330T222645ZQuadrupl
049><> Fish230503T150836Zmousetai
144Scala230422T044059Z138 Aspe
055minigolf230422T023955Zuser1176
121*><>220805T181109ZBee H.
057Knight220802T021121Z97.100.9
113Kotlin220719T020342ZEric Xue
019Vyxal O220717T223403ZnaffetS
269Desmos /w ticker220406T191253ZNot A Ch
140Piet with asciipiet encoding220404T140952ZTim Pede
104PHP 7220330T093227Zuser1117
117Python 3.8 prerelease220329T235249ZLarry Ba
160Batch211026T110102ZT3RR0R
083TIBasic211025T214733ZYouserna
074Perl 5 F E210830T125331Zplentyof
6458J210206T061225ZJonah
120Swift210828T231823ZBbrk24
039Pip210828T205324ZDLosc
025Vyxal DO210826T225259Zemanresu
070Julia210301T155102ZMarcMush
115Yabasic210301T093828ZCaleb Fu
028Vyxal210301T034628Zlyxal
030Ohm v2210210T164021ZCinaski
043x8616 machine code210130T204645ZEasyasPi
151Lua LuaJIT210208T032837ZLuaNoob
091C gcc210204T075405ZErikF
098Java JDK210206T192127ZOlivier
119Rust210206T171017ZTechnoha
047APL Dyalog Classic210206T130317Zrak1507
081AWK210131T003707Zcnamejj
02105AB1E210131T141537Zovs
074PowerShell 7210202T183813ZZaelin G
091R210201T090141Zpajonk
035Stax210201T165754ZJoshua
081><>210201T212156ZSE - sto
104Nim210130T222757Zxigoi
178Racket210201T095046ZGalen Iv
074Python 2210130T234213Zovs
059Pyth210201T085922ZIan H.
023MathGolf210201T083315ZKevin Cr
025Husk210201T003226ZLeo
157Batch210131T203316ZNeil
080Arturo210131T184522Zxigoi
068PowerShell210131T160606Zmazzy
082flex210130T173133ZNoodle9
118PowerShell210131T153618Zwasif
051AWK210131T031917ZMukundan
024Jelly210130T221408Zxigoi
106Red210131T102508ZGalen Iv
136PHP210131T100806Zemanresu
095Python 3210130T223631ZGotoro
106Icon210131T094212ZGalen Iv
058Ruby210130T204815ZDingus
060Wolfram Language Mathematica210131T051855Zatt
066JavaScript ES10210130T153022ZArnauld
037Charcoal210130T213215ZNeil
061Retina210130T212155ZNeil
076convey210130T160024Zxash

Swift 6, 119 109 bytes

var a=0,f={(a=0,""+$0).1.reduce([]){"o"==$1 ?$0+[a]:(a="r"<$1 ?a*a:"d"<$1 ?a+1:a-1,a=a<0||a==256 ?0:a,$0).2}}

Try it on SwiftFiddle!

Uiua 0.10.0, 39 bytes

◌∧(⍥⋅0∊,¯1_256⟨-1|+1|&p.|ⁿ2⟩):0⊗:"dios"

Explanation + See it in action

Easyfuck, 167 bytes

Ì¡n␅␏␖SHYÀ¡kæ␋^)VSHYòMWo␒>|NELâGÉAPCE³ù忸␔>VñM×É␖àPñâ¥2PU2>|§:NELwAPC^RPU1ãåPLD¯[¼ùbë×ZÙ]nSŸ␝«¶òëêl%!}yn␅␏APC>|ù^␅␏␕¾SSGCIâSTëp(|ùóå¸␔<ZùNe9ÖàPùòGÏDCS¼I5óä/␒>SCIPU1ãÇSS3_f|§:Ü␊␟>APCMPU2êyAPC>R®õØ␃täç¼␀␀␀␀

due to lack of unicode representations for c1 control characters, they have been replaced by their superscripted abbreviations

Decompressed:

f(-`(<--`(->0-<)++>)+<$>>!<$>&>EY~<[}`(>+<)]>$-`(<<*)J$>>)g(+^>^)$<>,.^[^>,.^]5Y.[J<-`;+[<]>S0J!>^-`(>>>>>+`(<+>)f<)g-`(>>>>-`(<->)f)g-`(>>$>>!<$M>>!<$>M$<<<=>f>)g-`(>>OS2.Sf>>)+^]@␍idso␀␀␀␀

><> (Fish), 49 bytes

05i8%.
1+v

:*v
1-v


:nv
0.\:01-=}:"Ā"={+0$?$~0

Try it

Beats the existing answer by about 30 bytes. Branchless -1 and 256 checking logic copied from this excellent answer

Scala, 144 bytes

Modified from @Gotoro's answer.


Golfed version. Attempt it online!

var n=0;for(x<-readLine()){if(n== -1||n==256)n=0;if(x=='o')println(n)else n=((x.toInt%4)^1)match{case 0=>n+1;case 1=>n-1;case 2=>n*n;case _=>n}}

Ungolfed version. Attempt it online!

import scala.io.StdIn.readLine

object Main {
  def main(args: Array[String]): Unit = {
    var n = 0
    for (x <- readLine()) {
      if (n == -1 || n == 256) n = 0
      if (x == 'o') println(n)
      else n = ((x.toInt % 4)^1) match {
        case 0 => n + 1
        case 1 => n - 1
        case 2 => n * n
        case _ => n
      }
    }
  }
}

minigolf, 55 bytes

Had to do this because it's ridiculously easy to do in minigolf.

0i,nWT*+1,;,nB=,:_n0=,T+_n5=,1+_nF=,:*__::V=sT=+,0*__,_

Try it online!

(For the iiii case, though, it produces an index out of bounds error to STDERR, but nothing is outputted to STDOUT.)

Explanation

0               Push 0 as initial accumulator
i,              For each item in the (inputted) command sequence:
  n               Push current command
  WT*+            Subtract by 100
                  (since we have constants 0 thru 17
                  as convenient 1-byte builtins)
  1,;             Wrap it into a singleton list
                  (because we want to re-use it several times)
  ,               Fry sequence:
    nB=,          If current result is 11 (aka. `o`)
      :             Duplicate the current accumulator value.
                    (which effectively outputs the accumulator as it's not changed later)
    _             End if
    n0=,          If curr = 0 (aka. `d`):
      T+            Add acc by -1
    _             End if
    n5=,          If curr = 5 (aka. `i`)
      1+            Add acc by 1
    _             End if
    nF=,          If curr = 15 (aka. `s`)
      :*            Square the acc
    _             End if
  _               End fry sequence
  ::              Triplicate the acc
  V=              Is it equal to 256?
  sT=             Swap, is it equal to -1?
  +               Add them together
  ,               Repeat n times:
                  (we definitely only have one condition satisfied, so the value of + must be either 0 or 1)
    0*              Multiply acc by 0 (i.e. set it to 0)
  _               End repeat
_               End foreach loop
,_              Drop the last acc value (so that it's not outputted to STDOUT)

Implicit output stack

*><>, 121 bytes

I didn't check before writing this, and now see that I was already long ago beat by ><> but oh well. I'm not going to not post this after all that effort.

r01[D63.
>:884**=  ?!\~0v
^v0~u!?=-10:<u <
^>  OD~l0=?!\;
^+1I/!?="i":/
^   \:"d"=?!\I1-
^*:I/!?="s":/
^   \:"o"=?!;I:aon

Explanation

The program works through 3 main sections, and one initialization section. It uses two stacks: one input stack, and one accumulator stack.

Breakdown

; Initialize
r01[D63.

; Bounds Check
>:884**=  ?!\~0v
^v0~u!?=-10:<u <

; End of input check
^>  OD~l0=?!\;

; Main look
^+1I/!?="i":/
^   \:"d"=?!\I1-
^*:I/!?="s":/
^   \:"o"=?!;I:aon

Initialization

r         Reverse the input
 0        Push the accumulator onto the stack
  1[      Move the accumulator to a new stack
    D     Return to the input stack
     63.  Move to [3,6] in the code block (pushing the length of the stack onto the stack in the input check)

Bounds check

>                 Set the IP direction rightward
 :                Duplicate the accumulator
  884**           Push 256 onto the stack
       =          Is the accumulator 256
          ?!\     If not, mirror the IP downward
                  Else
             ~      Remove the accumulator from the stack
              0     Push 0 onto the stack
               v    Change IP direction downward

               <    Change IP direction leftward
             u      Dive, and ignore any non-movement instructions until we rise
            <     Change IP direction leftward
           :      Duplicate the accumulator
        -10       Push -1 onto the stack
       =          Is the accumulator -1
    u!?           If not, dive
                  Else
   ~                Remove the accumulator from the stack
  0                 Push 0 onto the stack
 v                  Change IP direction downward
^                 Change IP direction upward (Used when returning to the top of the bounds check)

End of Input check

^                 Change IP direction upward (Used when returning to the top of the bounds check)
 >                Set the IP direction rightward
    O             Rise from any potential dive we may have done (ignored if there was none)
     D            Change to the input stack
      ~           Remove the an instruction from the top of the stack
       l          Push the length of the stack onto the stack
        0         Push 0 onto the stack
         =        Is the length of the stack 0
          ?!\     If not, mirror the IP downward
             ;    Else, halt execution

Main block

I've condensed the main block's explanation for the sake of brevity.

            /       Mirror IP to the left
       ="i":        Is our current instruction i
    /!?             If not, mirror IP downward
                    Else
^+1I                  Switch to accumulator stack, add 1, and set IP direction upward (returning to bounds check)

    \               Mirror IP to the right
     :"d"=          Is our current instruction d
          ?!\       If not, mirror IP downward
                    Else
^            I1-      Switch to accumulator stack, subtract 1, and set IP direction upward

            /       Mirror IP to the left
       ="s":        Is our current instruction s
    /!?             If not, mirror IP downward
                    Else
^*:I                  Switch to accumulator stack, duplicate the accumulator and multiply it against itself, set IP direction upward

    \               Mirror IP to the right
     :"o"=          Is our current instruction o
          ?!;       If not, halt execution
                    Else
             I:a      Switch to accumulator stack, duplicate the accumulator, push 10 onto the stack
^               on    Print the 10 (newline) and our accumulator value, and set IP direction upward

Try it online!

Knight, 57 bytes

;=a 0W=cP I?c"o"Oa=a*=a I?c"d"-a 1I?c"i"+1a^a 2!|?256a>0a

Takes in each character on a separate input line.

Explanation

Here's the code with generous whitespace and comments added:

;=a 0       #set a to 0
W=cP        #  while the next input character `c` is not null:
 I?c"o"     #    if c is "o": 
  Oa        #      output a
  =a        #    else...
   *=a      #      set a to the following:
   I?c"d"   #      (if a is "d": 
    -a 1    #         a-1
    I?c"i"  #       else if a is "i":
     +1a    #         a+1
     ^a 2   #       else a^2)
   !|?256a>0a   #    multiply a by (not (a is 256) or (0>a)), which is 1 when a is within bounds and 0 otherwise

An earlier version where I tried to use some more clever tricks which ended up being longer (66 bytes):

;=a 0W =cP I?c"o"Oa=a*=aE S G"^2-1+1"/%Ac 23 3 2 1 0"a "!|?256a>0a

Kotlin, 113 bytes

{var o=listOf<Int>();var a=0;for(s in it){when(s){'i'->a++;'d'->a--;'s'->a*=a;'o'->o+=a};if(a==-1||a==256)a=0};o}

Type signature: String -> List<Int>

Vyxal O, 19 bytes

0?(n`ḟ``ġ`ĿĖ:₈u"c[0

Try it Online!

This is really cheating, but whatever. Short dictionary abuse ftw

Vyxal OD, 20 bytes

0?(n½`›²‹…`iĖ:₈u"c[0

Try it Online!

Input as list of codepoints, no cheating.

Desmos /w ticker, 269 bytes

try it online

Code in ticker:

\left\{I[n]=4:T,\ I[n]=3:v->\left\{v^2=256:-1,v^2\right\},I[n]=2:v->\left\{v-1=-1:0,v-1=256:0,v-1\right\},I[n]=1:v->\left\{v+1=-1:0,\ v+1=256:0,\ v+1\right\}\right\},\ n-> n+1

Code in list:

I=[]
O=[]
i=1
d=2
s=3
o=4
n=0
v=0
T=O->\operatorname{join}(O,\left\{v=-1:0,v=256:0,v\right\})

Piet with ascii-piet encoding, 140 bytes

Outputs numbers with a space as a separator. Goes into an infinite loop once it runs out of input. (If using npiet, the -q flag will suppress the "?" prompts, and -e will set a number of execution steps to kill the program after. 1300 steps is enough to run the longest test case.)

Piet code (codel size 4):

A Deadfish interpreter written in Piet, the abstract-art programming language.

ascii-piet version (with line breaks added):

vnmdeusausejbsvcldvufktdtqeC
eeeee     jjllllltln  tdt  A
e dde     jjrjc?????  dda  K
e dmn????c       mmiii  m  N
e ??narvfctisjicemmnaai??ctD

Try it online!

Explanation

After initialising the accumulator with 0, a character is read from standard input. Its value is then decremented by 100 (for "d"), by another 5 ("i"), and by another 6 ("o"), branching once it hits zero. If it still hasn't hit zero, it's assumed to be "s".

(Actually, I messed up and put the "s" code on the branch and the "o" code on the straight path, which runs all the way around the outside. This was convenient, since output takes more code than squaring, so I left it that way and just negated the relevant check.)

Coming back across the bottom, after some codel-chooser twiddling, the new accumulator value is compared to 256 and then (if that didn't branch) to -1. If either one compares equal, it branches again into code that resets the accumulator to 0.

And then it repeats from the character read.

PHP 7 (104 chars)

Given argv[1] as a command line argument :

for($r=0,$s=$argv[1];@$a=$s[$i++];$r*=$r-256&&~$r)@($a>i?$a>o?$r*=$r:print$s[$i]?"$r,":$r:$r+=$a>d?:-1);

Try it online

Python 3.8 (pre-release), 117 bytes

def f(x,o=0):
	for c in x:
		if o>256or o<0:o=0
		if(v:=ord(c)&6)<1:o+=1
		if v<3:o**=2
		if v<5:o-=1
		else:print(o)

Try it online!

Batch 160 bytes

@Set v=0&@Set i=v+=1&@Set d=v-=1&@Set s=v*=v&2>nul (@For %%i in (%*)Do @Set/A"-1/(v+1)"||Set v=0&Set/A"256/(v-256)"||Set v=0&Call Set/A%%%%i%%||Call Echo(%%v%%)

How? :

TI-Basic, 83 bytes

Input Str1
For(I,1,length(Str1
inString("ids",sub(Str1,I,1→J
If Ans:Then
{A+1,A-1,A²
Ans(J
max(0,Ans)(Ans≠256→A
Else
Disp A
End
End

Input is taken as a string and outputs are printed and separated with newlines.

Perl 5 -F -E, 96 91 90 79 74 bytes

(+4 bytes for switches included)

Saved 5 bytes by using a built-in variable that defaults to 0 ($- / $FORMAT_LINES_LEFT) instead of $a
Saved 1 byte by using print and $/ instead of CORE::say
Saved 11 bytes by using -F and -E switches
Saved 4 bytes by (ab)using regex match return value coercion. Saved 0 bytes but improved readability by changing $- to $% ($FORMAT_PAGE_NUMBER)

for(@F){$%+=/i/;$%-=/d/;$%*=$%if/s/;say$%if/o/;$%=0if$%=~/^(-1|256)$/}

Try it online!

More-readable version:

for (@F) {
    $% += /i/;
    $% -= /d/;
    $% *= $% if /s/;
    say($%) if /o/;
    $% = 0 if $% =~ /^(-1|256)$/;
}

J, 64 58 bytes

g=:]e.&256 _1|]
i=:g>:
d=:g<:
s=:g*:
o=:1!:2&2
f=:'0'".@|.@,]

Try it online!

-6 thanks to FrownyFrog!

Note: -3 off TIO count for f=:

This stores each Deadfish command in a variable of the same name, followed by the -1/256 check. Then we just prepend 0, reverse, and eval.

Takes input with spaces between the letters.

Swift, 120 bytes

{(s:String)in var i=0
s.forEach{switch $0{case"i":i+=1 case"d":i-=1 case"s":i*=i default:print(i)}
if i==256||i<0{i=0}}}

Returns a closure that takes the input as an argument. If the input contains o multiple times, the numbers are separated by newlines.
Try it online (full program that uses hardcoded input)

Ungolfed:

{ (str: String) in
    var i = 0
    str.forEach { (char: Character) in
        switch char {
        case "i":
            i += 1
        case "d":
            i -= 1
        case "s":
            i *= i
        default: // "o"
            print(i)
        }
        
        if i == 256 || i < 0 {
            i = 0
        }
    }
}

Pip, 39 bytes

Fca;V("U  i&D SQ:   P"^sAc)."i*:i!=256"

Takes the Deadfish program as a command-line argument. Try it here! Or, here's a 42-byte version in Pip Classic: Try it online!

Explanation

The variable i is preset to 0, so we'll use it for the accumulator.

Fca;V("U  i&D SQ:   P"^sAc)."i*:i!=256"
Fca;                                     For each c in command-line argument a:
      "U  i&D SQ:   P"                    Take this string
                      ^s                  Split on spaces into a list of 7 strings
     (                    )               Index (0-based, modular) into that list using
                        Ac                the ASCII code of c
                           .              Concatenate
                            "i*:i!=256"   this string
    V                                     Eval as Pip code

The code snippets for each command are:

i -> index 0 -> Ui*:i!=256
d -> index 2 -> i&Di*:i!=256
s -> index 3 -> SQ:i*:i!=256
o -> index 6 -> Pi*:i!=256

The first three expressions change the value of i and then multiply it by 0 if the new value equals 256:

Ui    Increment i
i&Di  If i is not 0, decrement i
SQ:i  Square i in place

The fourth expression parses a little differently: since P is lower precedence than assignment, it works out to "multiply i by 0 if it equals 256, and then print." Fortunately, since printing doesn't change the value of i, the order doesn't matter.

Vyxal DO, 25 bytes

0Ȯ(n«ƛ√J«`›‹²…`ĿĖ:₈u"=a[0

Try it Online!

Saved a byte thanks to Aaron Miller.

0                         # Push 0
 Ȯ(n                      # Iterating over the input
    «ƛ√J«`›‹²…`Ŀ          # Transliterate into appropriate Vyxal instruction
                Ė         # Evaluate
                 :₈u"=a[  # If 256 or negative
                        0 # Push 0

Julia, 70 bytes

s->(a=0;!c=a=[a*=a⊻256>0,a-1,a*a,a+1,c%5>0&&print(a,-)][c÷2%6];.!s)

Based on ovs's answer

Try it online!

Yabasic, 119 115 bytes

a=0
for j=1 to len(i$)
c=instr("isdo",mid$(i$,j,1))
if c<4 a=a+2-c
if c=2 a=a*a
if c=4 ?a;
if a<0 or a=256 a=0
next

Try it online!

The actual input is done via reading DATA statements for each Deadfish program. For an interactive version I'd just replace that with an INPUT i$ statement, and calling RUN at the end should re-run the program, initializing variables to 0 and removing the need for the a=0 statement.

I feel this could be more compact, but everything else I try actually makes it bigger. The only really "golf-y" thing is the line:

if c<4 a=a+2-c

which for command 2=square has no effect, avoiding the need for one IF evaluation and saving 11 bytes vs the more straightforward implementation.

Even the XOR 256 trick works out identical in length to the more straightforward version above so I stuck with the simpler code.

edit - I did save 4 bytes because the BASIC interpreter I'm using puts a space as a seperator between numbers automatically, so no need to add it.

Vyxal, 28 bytes

❝,(\&`\⨥\⨪\²\₴`ni+ₑuγd‿¥c[0£

Try it Online!

Takes a list of numbers, where 0 represents i, 1 represents d, 2 represents s and 3 represents o

Ohm v2, 30 bytes

ÝL}`7%5%›0s:_ΦD256â0>*
›
=
‹
²

Try it online!

x86-16 machine code, 45 43 bytes

Source-compatible with x86 and x86_64.

Fails one test due to integer overflow, but instructions are given to switch it to 64-bit arithmetic in the demo.

00000000: 31 d2 ac 3c 64 72 23 74 0d 3c 69 74 0c 3c 6f 92  1..<dr#t.<it.<o.
00000010: 74 0a f7 e0 eb 07 4a eb 05 42 eb 02 ab 92 85 d2  t.....J..B......
00000020: 78 de 81 fa 00 01 74 d8 eb d8 c3                 x.....t....

        // "//" comments are solely for syntax highlighting
        // sed -i -e 's#//#;#g' deadfish.asm
        // nasm compatible
        [bits 16]
        [cpu 8086]
        global deadfish
        // Input:
        //    si: input, null terminated string
        //    di: output, uint16_t array
        // Output:
        //
        //    di: points past the last value in the array
deadfish:
.Lzero:
        // Set accumulator to 0
        xor     dx, dx
.Lloop:
        // Load byte
        lodsb
        // Check for null terminator and for 'd'
        cmp     al, 'd'
        // Below means null terminator, return
        jb      .Lret
        // equal means 'd'
        je      .Lop_d
        // check for 'i'
        cmp     al, 'i'
        je      .Lop_i
        // check for 'o'
        cmp     al, 'o'
        // Since O and S both need AX instead of DX, xchg here.
        xchg    dx, ax
        je      .Lop_o
        // assume 's'
.Lop_s:
        // Square
        mul     ax
        // Jump to the end of the o code to swap AX to DX.
        jmp     .Lnext_xchg
.Lop_d:
        // Decrement
        dec     dx
        jmp     .Lnext
.Lop_i:
        // Increment
        inc     dx
        jmp     .Lnext
.Lop_o:
        // Output
        // *di++ = ax
        stosw
        // Swap dx and ax again for o and s
.Lnext_xchg:
        xchg    dx, ax
.Lnext:
        // Check for -1 (less than zero) and 256
        // If equal, jump to the xor dx, dx conveniently placed before the loop
        test    dx, dx
        js      .Lzero
        // Literally the only reason I am using 16-bit is this instruction :P
        cmp     dx, 256
        je      .Lzero
        // Otherwise, jump to the top of the loop
        jmp     .Lloop
.Lret:
        // Return
        ret

The input is a null terminated string in si, and the output is stored to the uint16_t array in di.

di will point to the end of the array to indicate the length (C++ <algorithm> style)

Try it online! Uses GAS Intel syntax because I want to use libc with it, and uses macros for registers to make it possible to switch to 64-bit arithmetic.

Lua (LuaJIT), 153 151 bytes

t={}v=0;loadstring(s:gsub('.',{d='v=v-1;',i='v=v+1;',s='v=v*v;',o='t[#t+1]=v;'}):gsub(';',';v=(v==256 or v<0)and 0 or v;'))()print(table.concat(t,','))

Try it online!

C (gcc), 92 91 bytes

Thanks to ceilingcat for the -1.

Converts each operation into the range [0,3] to simplify the decoding process.

a,b;f(char*s){for(a=0;b=*s++/2;a*=a-256&&~a)(b&=3)?--b?--b?printf("%i ",a):a--:(a*=a):a++;}

Try it online!

Java (JDK), 98 bytes

s->{int a=0;for(var c:s){if((c%=7)>5)System.out.println(a);a=c%5<3?1-c%5+a:a*a;a=a<0|a==256?0:a;}}

Try it online!

Rust, 119 bytes

Closure with a single parameter of type Iterator<Item = u8> with ASCII bytes

|s|{let mut a=0;for c in s{a=match c{105=>a+1,100=>a-1,115=>a*a,111=>{println!("{}",a);a},_=>a};if a==-1||a==256{a=0}}}

Try it online! (with caller function)

Ungolfed version

|s|{
    let mut a = 0;
    for c in s {
        a = match c {
            105 => a + 1,
            100 => a - 1,
            115 => a * a,
            111 => { println!("{}", a); a },
            _ => a
        };
        if a == -1 || a == 256 { a = 0 }
    }
}

APL (Dyalog Classic), 47 bytes

i←+∘1⋄d←-∘1⋄s←×⍨⋄o←⎕∘←⋄{}{0⌈a×256≠a←⍎⍕⍺,⍵}/⌽0,⍞

Try it online!

AWK, 83 81 bytes

Thanks to Dominic van Essen for shaving off 2 bytes...

{for(;c=$++b%9;)printf c-3?(d=(x=c-6?c-1?d*d:--d:++d)<1?0:x==256?0:x)?f:f:+d"\n"}

This is pretty brute force, but it's ugly enough that I wanted to submit it. :) It's mostly abusing ternaries to save characters.

The input is code points separated by spaces as commandline arguments. The code converts them to modulo-9 to shorten the comparisons to the specific command values.

There's a minor trick on the printf line that might be worth highlighting.

printf c-3?..not-a-print-command..:d"\n"

prints the accumulator value when a o command is found.

The logic in the "truthy" part updates the accumulator, but always returns a value of f. Since that's a uninitialized variables, AWK picks a value based on the content where it's used. In this context it turns into a null string, so printf doesn't produce any output for non-o commands.

The code to update the accumulator is bundled into the print statement, so it's only called for a, d, i, and s commands. As result it doesn't have to check for o.

Try it online!

05AB1E, 23 22 21 bytes

-1 -2 bytes thanks to Command Master!

Takes input as a list of codepoints.

õ?Îv">n<="y;è.VD₁^0›*

Try it online!

Commented:

õ?                  # print the empty string without a trailing newline
                    # this is necessary to disable implicit output if no 'o' is in the code
  Î                 # push 0 and the input
   v                # iterate over the instructions y in the input:

">n<="              # push string literal ">n<="
                    # These are the instructions in 05AB1E equivalent to "isdo"
      y             # push the current instruction
       ;            # halve the instruction
        è           # modular index into the instruction string
          .V        # execute the instruction
            D       # duplicate the current value
             ₁^     # XOR with 256
               0›   # is this larger than 0?
                 *  # multiply the result with the current value
                    # x*(x^256>0) maps negative numbers and 256 to 0

PowerShell 7, 74 bytes

$args|%{switch($_){i{$x++}d{$x--}s{$x*=$x}o{+$x}}$x=1+$x-and$x-256?$x :0}

Link is to a slightly longer PS 6 solution, as TIO does not yet have PS 7. Try it online!

R, 111 91 bytes

-20 bytes thanks to CriminallyVulgar

C=scan(,'');n=0;for(x in C){if(n%in%c(-1,256))n=0;n=switch(x,i=n+1,d=n-1,s=n^2,o=print(n))}

Try it online!

Stax, 37 35 bytes

ï☺C£q▒▒v¡ñ|≥íHQ3╤Ä╫Q,§╪c(>∙α._A↓ö≈/

Run and debug it

I only need one more byte to not blow up on a trailing newline in the input

saved two bytes thanks to Razetime

><>, 81 bytes

Not the dead one :)

0v~$?$0+{="Ā":}=-10<
l<n:oav?="i"{v?="d"}:{v?="s"}:{;?=1
{~:*1->  2+0}>{~1-:v  >

Try it online!

Branching is the kryptonite of ><> terseness, so the golfiness here was creating a branchless -1 and 256 check ~$?$0+{="Ā":}=-10 backwards on the first line to get rid of whitespace. The s, i and d commands also feed into each other to make the layout manageable.

Nim, 104 bytes

var r=0
for c in stdin.readAll:
 r=[r*r,r,r+1,r-1][28-c.ord div 4];r*=int (r xor 256)>0;if c=='o':echo r

Try it online!

Based on @ovs's amazing Python answer.

Nim, 120 114 109 bytes

var r=0
for c in stdin.readAll:
 case c
 of'i':r+=1
 of'd':r-=1
 of's':r*=r
 else:r.echo
 if r in[-1,256]:r=0

Try it online!

This is embarassingly readable.

-5 bytes by taking inspiration from @Gotoro's Python answer

Racket, 178 bytes

(define(f s[a 0])(unless(null? s)(let([x(car s)][y(cdr s)][b(match a[-1 0][256 0][_ a])])(match x[105(f y(+ b 1))][100(f y(- b 1))][115(f y(* b b))][_(and(writeln b)(f y b))]))))

Try it online!

More readable:

(define (f s [a 0])
  (unless (empty? s)
    (let ([x (first s)]
          [y (rest s)]
          [b (match a
               [-1  0]
               [256 0]
               [_   a])])
      (match x
        [105 (f y (+ b 1))]
        [100 (f y (- b 1))]
        [115 (f y (* b b))]
        [_   (and (writeln b)
                  (f y b))]))))

Python 2, 83 82 76 74 bytes

Thanks to dingledooper for spotting a bug and -6 bytes!
-2 bytes thanks to Mukundan!

Takes input as a list of codepoints.

a=0
for x in input():
 a=[a-1,a+1,a,a*a][x/6%4];a*=a^256>0
 if x%5:print a

Try it online!

Pyth, 59 bytes

FNz=T%CN4IqN"o"Z=tT)IqT1=hZ)IqT0=tZ)IqT3=*ZZ)I}hZ[0 257)=Z0

Try it online!

Bit out of practice. :)

MathGolf, 23 bytes

0ÿ)²(o▒ê½§"_♠bαm¡╓*"u~╘

Input as a list of codepoint integers.

Try it online.

Explanation:

0                       # Start with 0
 ÿ)²(o                  # Push 4-char string ")²(o"
      ▒                 # Convert it to a list of characters: [")","²","(","o"]
       ê                # Push the input-list of codepoint integers
        ½               # Integer-divide each by 2
         §              # Index (modulair 0-based) them into the list of characters
          "_♠bαm¡╓*"u   # Join these characters with "_♠bαm¡╓*" delimiter
                     ~  # Execute the entire string as MathGolf code
                      ╘ # Discard everything left on the stack (which otherwise would be
                        # output implicitly)

  )                     # Increase by 1
   ²                    # Square
    (                   # Decrease by 1
     o                  # Print without popping

           _            # Duplicate the top of the stack
            ♠bα         # Push 256, push -1, wrap them in a list: [256,-1]
               m        # Map over both of them:
                ¡       #  And check that they're NOT equal to the value we've duplicated
                        #  (0 if the duplicated value is -1 or 256; 1 otherwise)
                 ╓      # Pop and get the minimum of this list
                  *     # Multiply it to the value

Husk, 26 25 bytes

tGF₅0hx'o
S&≠256!ë→a□?←0c

Try it online!

Explanation

The first line is the main program, the second line an helper function that computes the output of a Deadfish command that could be 'i', 'd' or 's'.

Let's start from the first line:

tGF₅0hx'o
      x'o    Split the string on each 'o'
     h       and discard the last part 
              (we don't care what happens after the last 'o')
 G  0        Scan this list of strings using 0 as initial value
  F₅          computing the result of each Deadfish subprogram
t            Discard the first value (0)

What we are doing here is splitting the Deadfish code into the subprograms preceding each output 'o', and then computing the result of each subprogram.

The result of a subprogram is computed by folding the helper function over the commands: the fold will start with the value of the accumulator coming from the previous subprogram (initially 0), and will apply the helper function to the next command and the accumulator to generate the new value for the accumulator.

Lines in a Husk program are zero-indexed and modular: referring to line here is effectively the same as referring to line , but the number of times we "loop around" back to the first line determines how the called function should be modified (in order argdup,flip,map,zip,hook); in this case we loop around 2 times, so we flip the helper function, passing the command ('i','d',or 's') first, and the accumulator second.

We chain together the interpretations of the subprograms by scanning over the list of subprograms. A scan G is the same thing as a fold F, except it returns all partial results instead of only the final one. We explicitly set 0 as the initial value, but then the result of each subprogram will be passed as the accumulator to the next subprogram. The initial value is always part of the output for a scan, so we have to discard it at the end (t).

So, how does the helper function compute the result of a Deadfish command?

S&≠256!ë→a□?←0c     Takes a character (one of "ids") and an accumulator,
                     returns the new value for the accumulator
              c     Convert the character to its codepoint value
      !ë            and use it to index into this list of four functions:
        →            Increment
         a           Absolute value (dummy)
          □          Square
           ?←0       If nonzero then decrement else return 0
S&≠256              Return the result if ≠256, else 0

The trick here is that ord(c)%4 will return a different value for each c in "ids" (respectively 1,0,3). List indexing in Husk is modular so by indexing with this value into the list of functions we will get the function we need. a is there only to pad the list to 4 elements (because otherwise 's' and 'd' would have the same value modulo 3).

We check for -1 by only decreasing the accumulator if its value is not 0, and we check for 256 explicitly after any command.

Batch, 157 bytes

@set a=0
@for %%c in (%*) do @call:%%c
:s
@set/aa=a*a-1
:i
@set/aa+=2
:d
@set/aa-=1
@if %a%==-1 set a=0
@if %a%==256 set a=0
@exit/b
:o
@echo %a%

Takes each Deadfish command as a separate command-line argument. Explanation:

@set a=0

Initialise the accumulator.

@for %%c in (%*) do @call:%%c

Loop through all of the commands, executing each in turn, then fall through into performing an additional s command, whose effect is non-observable.

:s
@set/aa=a*a-1

For the s command, square the accumulator and decrement it, then fall through to the i command, which increments it again.

:i
@set/aa+=2

For the i command, add 2 to the accumulator, then fall through to the d command, which decrements it.

:d
@set/aa-=1

For the d command, decrement the accumulator.

@if %a%==-1 set a=0
@if %a%==256 set a=0
@exit/b

Adjust the accumulator if necessary, then return for the next command.

:o
@echo %a%

For the o command, output the accumulator, then implicitly return for the next command.

204 bytes taking input as a single string (probably actually not the best approach; the call-and-fall through approach above could probably save 10 bytes):

@set/ps=
@set a=0
:l
@if "%s%"=="" exit/b
@for %%a in (1+1.i 1-1.d a.s)do @if %%~xa==.%s:~,1% set/aa=a*%%~na
@if %s:~,1%==o echo %a%
@set s=%s:~1%
@if %a%==-1 set a=0
@if %a%==256 set a=0
@goto l

Takes input on STDIN. Explanation:

@set/ps=
@set a=0

Read the commands and clear the accumulator.

:l
@if "%s%"=="" exit/b

Loop until there are no commands left.

@for %%a in (1+1.i 1-1.d a.s)do @if %%~xa==.%s:~,1% set/aa=a*%%~na

If the command is an arithmetic operation then perform the calculation: a=a*1+1 for i, a=a*1-1 for d and a=a*a for s; it's not possible to use * in a for loop because it's always a wildcard and cannot be quoted (unlike =, which can be quoted).

@if %s:~,1%==o echo %a%

If the command is an o then output the accumulator.

@set s=%s:~1%

Remove the command from the input.

@if %a%==-1 set a=0
@if %a%==256 set a=0
@goto l

Adjust the accumulator if necessary and loop.

Arturo, 80 bytes

$[p][r:0loop p'c[do[[r:r*r][print r][r:r+1][r:r-1]]\28-c/4if or? r<0r=256[r:0]]]

A function that takes an array of codepoints and prints numbers separated by newlines.

PowerShell, 68 bytes

switch -r($args){i{$a++}d{$a--}s{$a*=$a}o{+$a}.{$a*=$a-notin-1,256}}

Try it online!

flex, 86 \$\cdots\$ 83 82 bytes

Saved 2 bytes and got moved into TIO thanks to Mukundan314!!!

%{
a;m(){a*=a!=256;}
%}
%%
i m(++a);
d m(a&&--a);
s m(a*=a);
o printf("%d ",a);
%%

Try it online!

flex stands for fast lexical analyser generator. It takes input as above and generates a lexer in C.

The input comprises of a C declaration section:

%{
a;m(){a*=a!=256;}
%}

where here we simply declare the accumulator a (implicitly as an int) and a function to set the accumulator to \$0\$ if it's \$256\$ after a computation.

This is followed by the rules section comprised of all the regexes that need to be parsed along with their actions (in C):

%%
i m(++a);
d m(a&&--a);
s m(a*=a);
o printf("%d ",a);
%%   

here we have our 4 characters along with the code to run when each is encountered. Decrement will only happen if the accumulator is non-zero.

There's a program section that follows this but it will simply default to a main that runs the parser if left out (as in this case).

You can generate the C-source code lexer from the above (in file deadfish.l) and compile it with the following:

flex deadfish.l
gcc lex.yy.c -o deadfish -lfl  

After compiling, running the following:

echo iissso | ./deadfish
echo diissisdo | ./deadfish
echo iissisdddddddddddddddddddddddddddddddddo | ./deadfish
echo isssoisoisoisoiso | ./deadfish
echo ooooosioiiisooo | ./deadfish
echo iiiiiiiissdiiiiiiiiiiiiiiiiio | ./deadfish  

outputs:

0
288
0
1 4 25 676 458329
0 0 0 0 0 1 16 16 16
4112   

You can also just run it as ./deadfish and have an interactive deadfish environment to play with to your heart's content!

PowerShell, 118 bytes

$args[0]|% t*y|%{if($a-in@(-1,256)){$a=0}if($_-eq'i'){$a+=1}elseif($_-eq'd'){$a-=1}elseif($_-eq's'){$a=$a*$a}else{$a}}

Try it online!

AWK, 55 53 52 51 bytes

Thanks to user41805 for removing awk flags

Expects each operation to be on a separate line

{a*=a!=256}/i/{a++}/d/{a&&a--}/s/{a*=a}/o/{print+a}

Try it online!

Explanation

{a*=a!=256}    # Before each operation multiply a by 0 if it equals 256
/i/{a++}       # If line contains 'i' increase a by 1
/d/{a&&a--}    # If line contains 'd' and a is non-zero decrement a by 1
/s/{a*=a}      # If line contains 's' square a
/o/{print+a}   # If line contains 'o' output a

Jelly, 25 24 bytes

:4ị⁾’‘;⁾Ṅ²¤j“-,⁹¤i¬×Ʋ”VZ

Try it online!

Interprets a Deadfish program given as a list of codepoints in a command-line argument, printing newlines between the numbers, then crashes with a TypeError.

Without the last two characters, it's a Deadfish to Jelly transpiler.

Explanation

:4ị⁾’‘;⁾Ṅ²¤j“-,⁹¤i¬×Ʋ”VZ   Main monadic link
:4                         Integer divide by 4
  ị                        Index into
   ⁾’‘;⁾Ṅ²¤                  "’‘Ṅ²"
    ’                          Decrement
     ‘                         Increment
        Ṅ                      Print with newline
         ²                     Square
           j               Join with separator
            “-,⁹¤i¬×Ʋ”       "-,⁹¤i¬×Ʋ"
             -,⁹¤              [-1, 256]
                 i             Find 1-based index
                  ¬            Negate
                   ×           Multiply by the number
                    Ʋ          Group this into one instruction
                      V    Evaluate (implicitly starting with 0)
                       Z   Zip — a number can't be zipped,
                           so this crashes the program in order to
                           suppress the implicit output

Red, 106 bytes

func[s][a: 0 parse s[any[(if a xor 256 < 1[a: 0])"i"(a: a + 1)|"d"(a: a - 1)|"s"(a: a * a)|"o"(print a)]]]

Try it online!

Pretty simple solution :

f: func[s][
    a: 0
    parse s[
       any[
           (if a xor 256 < 1[a: 0]) 
            "i"(a: a + 1)
           |"d"(a: a - 1)
           |"s"(a: a * a)
           |"o"(print a)
       ]
    ]
]

PHP, 136 bytes

<?php $w=0;foreach(str_split($argv[1])as$v){if($v=='o'){echo$w.' ';}else{$w=$v=='s'?$w**2:($v=='i'?++$w:--$w);}if($w==256||$w<0){$w=0;}}

Example explained:

$w=0;                                   #declare w var, is accumulator
foreach(str_split($argv[1])as$v){       # for each char of first CLI argument
if($v=='o'){                            #if output
echo$w.' ';                             #output w
}else{                                  #otherwise
$w=                                     #set w to
$v=='s'?                                #if input is s
$w**2                                   #squared
:($v=='i'?                              #otherwise if incremented
++$w:                                   #add one
--$w);}                                 #otherwise subtract one
if($w==256||$w<0){$w=0;}}               #if -1 or 256 set 0

PHP is annoying for this. Is run php deadfish.php <program>

Note: run on CLI so no online example.

Python 3, 120 95 bytes

n=0
for x in input():
	if n in(-1,256):n=0
	if"o"==x:print(n)
	else:n=[n+1,n-1,n*n][ord(x)%4^1]

Try it online!

Brought it down by 25 bytes thanks to Danis suggestion!

Using bit manipulation ^ we choose from the list of possible operations. Original suggestion used ord(x)%4^2 which yielded 0,1,2,3 for indexes and required the use of an additional 0 in the list at the index 0;

using ^1 instead yields 0,1,2, which allows to save 2 bytes in comparison.

Maybe it is possible to account for that additional 0 and use it as a condition to print o instead.(?)

Icon, 106 bytes

procedure f(s);a:=0
c:=!s&(if a:=[a+1,a-1,a*a][find(c,"ids")]then 1>ixor(a,256)&a:=0 else write(a))&\z
end

Try it online!

Ruby, 60 58 bytes

Saved 2 bytes thanks to @Sisyphus

a=0;$<.bytes{|b|a=0if(a=eval'~-~p a*'[b%20/3,2]+?a)^256<1}

Try it online or verify all test cases.

Full program that reads a string from STDIN and outputs to STDOUT, one number per line.

Each operation on the accumulator a is carried out by evaling a 3-byte string. The third byte is always a. The first two bytes are extracted from the string ~-~p a* starting at index b%20/3:

Op \$b\$ \$\left\lfloor\frac{b\bmod20}{3}\right\rfloor\$ eval
d \$100\$ \$0\$ ~-a
i \$105\$ \$1\$ -~a
o \$111\$ \$3\$ p a
s \$115\$ \$5\$ a*a

The reset conditions on the accumulator, which might be written a==-1||a==256 in ungolfed form, are replaced by the single condition a^256<1 (^ is bitwise XOR) because negative accumulator values other than \$-1\$ are not possible.

Wolfram Language (Mathematica), 60 bytes

Fold[<|i->#+1,d->#-1,s->#^2,o:>Echo@#|>@#2/.-1|256->0&,0,#]&

Try it online!

Input a list of symbols.

JavaScript (ES10), 66 bytes

Expects a list of codepoints.

a=>a.flatMap(n=>n%5?p:(p=(p=[p-!!p,p+1,,p*p][n&3])-256&&p,[]),p=0)

Try it online!

How?

o is the only command whose codepoint (\$111\$) modulo \$5\$ is not equal to \$0\$. This is also the only command that requires a special operation that doesn't update the accumulator. That's why we first test that.

If the first modulo is \$0\$, we apply a modulo \$4\$ to distinguish between the other commands and update the accumulator accordingly.

 char. | code | mod 5 | mod 4
-------+------+-------+-------
  'd'  |  100 |   0   |   0
  'i'  |  105 |   0   |   1
  'o'  |  111 |   1   |  (3)
  's'  |  115 |   0   |   3

Charcoal, 37 bytes

≔⁰θFS«F№⟦²⁵⁶±¹⟧θ≔⁰θ≡ιi≦⊕θd≦⊖θs≧X²θ⟦Iθ

Try it online! Link is to verbose version of code. Explanation:

≔⁰θ

Initialise the accumulator to 0.

FS«

Loop over the commands.

F№⟦²⁵⁶±¹⟧θ

If the list (256, -1) includes the accumulator...

≔⁰θ

... then set the accumulator to 0. (This is done before the operation because it's golfier, and doesn't change the result, since it still always happens between two operations, and whether it happens after the last operation isn't observable.)

≡ι

Switch on the current operation: ...

i≦⊕θ

... i means increment the accumulator; ...

d≦⊖θ

... d means decrement the accumulator; ...

s≧X²θ

... s means square the accumulator; ...

⟦Iθ

... otherwise print the accumulator on its own line.

Retina, 61 bytes

\bi()|#?\bd|^(#*)s
$#1*#$.2*$2
^#{256}\b

m}`^(#*)o
$.1¶$1
#

Try it online! Link includes test cases, although they can be a bit slow (I think #?\bd is the slow case, but I'm not sure). Explanation:

\bi()|#?\bd|^(#*)s
$#1*#$.2*$2

Handle the i, d and s cases by inserting a # (for the i case), deleting an optional # (for the d case, also handling a d of 0) or squaring the number of #s (for the s case).

^#{256}\b

But if the value is exactly 256, then set it back to 0 (assuming that there's another operation, otherwise the remaining #s are ignored anyway).

^(#*)o
$.1¶$1

Handle the o case by prepending a decimal copy of the current number of #s on a previous line.

m}`

Evaluate the above stages until there are no more letters to process; also turn on multiline matching for all of the stages.

#

Delete any remaining accumulated unary value.

convey, 90 76 bytes

 {"='i'
0+#<
^v"='d'
^-#<
^v"='s'
^*#+1
^.=<'o'
^>@`
^}",
*<<"=256
.="*.
0-1

Try it online!

On the top right side, the input gets compared with idso. The result (0 or 1) then gets combined with the accumulator: a += c == 'i', a -= c == 'd', a = pow(a, (c == 's') + 1) (pow = *.), and o pushes a copy into the output @"}. At the bottom are the checks for -1/256, by calculating a *= a != 256 and a *= a != -1. Then the accumulator loops back to start the next round.

One iteration of the accumulator loop:

one iteration