Execute SNUSP: Difference between revisions

m
 
(21 intermediate revisions by 13 users not shown)
Line 3:
 
An implementation need only properly implement the Core SNUSP instructions <nowiki>('$', '\', '/', '+', '-', '<', '>', ',', '.', '!', and '?')</nowiki>. Modular SNUSP ('#', '@') and Bloated SNUSP (':', ';', '%', and '&') are also allowed, but not required. Any extra characters that you implement should be noted in the description of your implementation. Any cell size is allowed, EOF support is optional, as is whether you have bounded or unbounded memory.
 
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">V HW = ‘
/++++!/===========?\>++.>+.+++++++..+++\
\+++\ | /+>+++++++>/ /++++++++++<<.++>./
$+++/ | \+++++++++>\ \+++++.>.+++.-----\
\==-<<<<+>+++/ /=.>.+>.--------.-/’
 
F snusp(store, code)
V ds = [Byte(0)] * store
V dp = 0
V cs = code.split("\n")
V ipr = 0
V ipc = 0
 
L(row) cs
ipc = row.findi(‘$’)
I ipc != -1
ipr = L.index
L.break
 
V id = 0
 
F step()
I @id [&] 1
@ipr += 1 - (@id [&] 2)
E
@ipc += 1 - (@id [&] 2)
 
L ipr >= 0 & ipr < cs.len & ipc >= 0 & ipc < cs[ipr].len
S cs[ipr][ipc]
‘>’
dp++
‘<’
dp--
‘+’
ds[dp]++
‘-’
ds[dp]--
‘.’
:stdout.write(Char(code' ds[dp]))
‘,’
ds[dp] = Byte(:stdin.read(1).code)
‘/’
id = ~id
‘\’
id (+)= 1
‘!’
step()
‘?’
I !(ds[dp])
step()
step()
 
snusp(5, HW)</syntaxhighlight>
{{out}}
<pre>
Hello World!
</pre>
 
=={{header|Ada}}==
See [[Execute SNUSP/Ada]].
 
=={{header|ALGOL 68}}==
See [[Execute SNUSP/Algol68]].
 
=={{header|AutoHotkey}}==
Line 21 ⟶ 84:
=={{header|D}}==
See [[RCSNUSP/D]].
 
=={{header|EasyLang}}==
{{trans|Go}}
<syntaxhighlight>
proc snusp dlen raw$ . .
len ds[] dlen
is$[] = strsplit raw$ "\n"
for s$ in is$[]
is$[][] &= strchars s$
.
for ipr to len is$[][]
for ipc to len is$[ipr][]
if is$[ipr][ipc] = "$"
break 2
.
.
.
dp = 1
id = 0
#
subr step
if id mod 2 = 0
ipc += 1 - bitand id 2
else
ipr += 1 - bitand id 2
.
.
while ipr >= 1 and ipr <= len is$[][] and ipc >= 1 and ipc <= len is$[ipr][]
c$ = is$[ipr][ipc]
if c$ = ">"
dp += 1
elif c$ = "<"
dp -= 1
elif c$ = "+"
ds[dp] += 1
elif c$ = "-"
ds[dp] -= 1
elif c$ = "."
write strchar ds[dp]
elif c$ = ","
# ds[dp] = strcode input
elif c$ = "/"
id = bitxor id 3
elif c$ = "\\"
id = bitxor id 1
elif c$ = "!"
step
elif c$ = "?"
if ds[dp] = 0
step
.
.
step
.
.
s$ = input
while s$ <> ""
cod$ &= "\n" & s$
s$ = input
.
snusp 5 cod$
#
input_data
/++++!/===========?\>++.>+.+++++++..+++\
\+++\ | /+>+++++++>/ /++++++++++<<.++>./
$+++/ | \+++++++++>\ \+++++.>.+++.-----\
\==-<<<<+>+++/ /=.>.+>.--------.-/
 
</syntaxhighlight>
 
=={{header|F_Sharp|F#}}==
See [[RCSNUSP/F Sharp]].
 
=={{header|Factor}}==
See [[RCSNUSP/Factor]].
 
=={{header|Go}}==
See [[RCSNUSP/Go]].
Line 29 ⟶ 165:
=={{header|Haskell}}==
See [[RCSNUSP/Haskell]].
 
=={{header|Icon}} and {{header|Unicon}}==
<syntaxhighlight lang="icon">#
# snusp.icn, A Modular SNUSP interpreter
#
 
$define VERSION 0.6
 
# allow a couple of cli options
link options
 
# directions
$define DRIGHT 1
$define DLEFT 2
$define DUP 3
$define DDOWN 4
 
record position(row, col)
global dir, ip, ram
 
procedure main(argv)
local ch, codespace, col, dp, fn, line
local row := 1
local wid := 0
local dirs := []
local ips := []
local opts, verbose, debug
 
opts := options(argv, "-h! -v! -d!", errorproc)
\opts["v"] & verbose := 1
\opts["h"] & show_help(verbose)
\opts["d"] & debug := 1
ip := position(1,1)
 
# initial direction
dir := DRIGHT
 
# prepare initial memory
ram := list(1, 0)
 
# prepare code field
codespace := []
 
fn := open(argv[1], "r") | &input
if (fn === &input) & \opts["h"] then return
 
while line := read(fn) do {
put(codespace, line)
wid := max(*line, wid)
}
if *codespace = 0 then return
every line := !codespace do {
codespace[row] := left(codespace[row], wid)
# track starting indicator
if /col := find("$", codespace[row]) then {
ip.row := row
ip.col := col
}
row +:= 1
}
 
if \verbose then {
write("Starting at ", ip.row, ", ", ip.col, " with codespace:")
every write(!codespace)
}
 
dp := 1
repeat {
if not (ch := codespace[ip.row][ip.col]) then break
if \debug then {
write(&errout, "dir: ", dir, " ch: ", ch, " [", ord(ch), "]",
" row: ", ip.row, " col: ", ip.col,
" dp: ", dp, " ram[dp]: ", ram[dp])
}
case ch of {
# six of the bf instructions
"+": ram[dp] +:= 1
"-": ram[dp] -:= 1
">": resize(dp +:= 1)
"<": dp -:= 1
".": writes(char(ram[dp]) | char(0))
",": ram[dp] := getche()
# direction change, LURD, RULD, SKIP, SKIPZ
"\\": { # LURD
case dir of {
DRIGHT: dir := DDOWN
DLEFT: dir := DUP
DUP: dir := DLEFT
DDOWN: dir := DRIGHT
}
}
"/": { # RULD
case dir of {
DRIGHT: dir := DUP
DLEFT: dir := DDOWN
DUP: dir := DRIGHT
DDOWN: dir := DLEFT
}
}
"!": step()
"?": { # skipz
if ram[dp] = 0 then {
step()
}
}
# modular SNUSP
"@": { # Enter
push(dirs, dir)
push(ips, copy(ip))
}
"#": { # Leave
if *dirs < 1 then break
dir := pop(dirs)
ip := pop(ips)
step()
}
}
step()
}
end
 
# advance the ip depending on direction
procedure step()
case dir of {
DRIGHT: ip.col +:= 1
DLEFT: ip.col -:= 1
DUP: ip.row -:= 1
DDOWN: ip.row +:= 1
}
end
 
# enlarge memory when needed
procedure resize(elements)
until *ram >= elements do put(ram, 0)
end
 
# quick help or verbose help
procedure show_help(verbose)
write("SNUSP interpeter in Unicon, version ", VERSION)
write("CORE and MODULAR, not yet BLOATED")
write()
write("Usage: unicon snusp.icn -x [filename] [-h|-v|-d]")
write(" -h, help")
write(" -v, verbose (and verbose help")
write(" -d, debug (step tracer)")
if \verbose then {
write()
write("Instructions:")
write(" + INCR, Increment current memory location")
write(" - DECR, Decrement current memory location")
write(" > RIGHT, Advance memory pointer")
write(" < LEFT, Retreat memory pointer")
write(" . WRITE, Output contents of current memory cell, in ASCII")
write(" , READ, Accept key and place byte value in current memory cell")
write(" \\ LURD, If going:")
write(" left, go up")
write(" up, go left")
write(" right, go down")
write(" down, go right")
write(" / RULD, If going:")
write(" right, go up")
write(" up, go right")
write(" left, go down")
write(" down, go left")
write(" !, SKIP, Move forward one step in current direction")
write(" ?, SKIPZ, If current memory cell is zero then SKIP")
write("Modular SNUSP adds:")
write(" @, ENTER, Push direction and instruction pointer")
write(" #, LEAVE, Pop direction and instruction pointer and SKIP")
write()
write("All other characters are NOOP, explicitly includes =,|,spc")
write(" $, can set the starting location; first one found")
write()
write("Hello world examples:")
write()
write("CORE SNUSP:")
write("/++++!/===========?\\>++.>+.+++++++..+++\\")
write("\\+++\\ | /+>+++++++>/ /++++++++++<<.++>./")
write("$+++/ | \\+++++++++>\\ \\+++++.>.+++.-----\\")
write(" \\==-<<<<+>+++/ /=.>.+>.--------.-/")
write()
write("Modular SNUSP:")
write(" /@@@@++++# #+++@@\ #-----@@@\\n")
write("$@\\H.@/e.+++++++l.l.+++o.>>++++.< .<@/w.@\\o.+++r.++@\\l.@\\d.>+.@/.#")
write(" \\@@@@=>++++>+++++<<@+++++# #---@@/!=========/!==/")
write()
}
end</syntaxhighlight>
 
{{out}}
Using the Modular SNUSP sample
<pre>prompt$ unicon -s snusp.icn -x hello.snusp
Hello, world!</pre>
 
=={{header|J}}==
This program places no limits on the program or data size. Perhaps I'll revisit and write a tacit version of the SNUSP interpreter.
<syntaxhighlight lang="j">
<lang J>
Note 'snusp'
 
Line 86 ⟶ 416:
end.
)
</syntaxhighlight>
</lang>
Store <langsyntaxhighlight SNUSPlang="snusp">\ display JJ and linefeed, then loop forever
\ +++++++++++++++++++++++++++++++++++++\
! /+++++++++++++++++++++++++++++++++++++/
/ \..<+++++\
\ . +++++/
</langsyntaxhighlight> as J.snusp
<pre>
load'snusp.ijs' NB. the j code above
Line 109 ⟶ 439:
=={{header|JavaScript}}==
See [[RCSNUSP/JavaScript]].
 
=={{header|Julia}}==
This Modular SNUSP interpreter uses modular calls to echo the first 2 characters entered. Try typing "Hi" at the prompt.
<syntaxhighlight lang="julia">const echo2 = raw"""
/==!/======ECHO==,==.==#
| |
$==>==@/==@/==<==#"""
 
@enum Direction left up right down
 
function snusp(datalength, progstring)
stack = Vector{Tuple{Int, Int, Direction}}()
data = zeros(datalength)
dp = ipx = ipy = 1
direction = right # default to go to right at beginning
 
lines = split(progstring, "\n")
lmax = maximum(map(length, lines))
lines = map(x -> rpad(x, lmax), lines)
for (y, li) in enumerate(lines)
if (x = findfirst("\$", li)) != nothing
(ipx, ipy) = (x[1], y)
end
end
 
instruction = Dict([('>', ()-> dp += 1),
('<', ()-> (dp -= 1; if dp < 0 running = false end)), ('+', ()-> data[dp] += 1),
('-', ()-> data[dp] -= 1), (',', ()-> (data[dp] = read(stdin, UInt8))),
('.', ()->print(Char(data[dp]))),
('/', ()-> (d = Int(direction); d += (iseven(d) ? 3 : 5); direction = Direction(d % 4))),
('\\', ()-> (d = Int(direction); d += (iseven(d) ? 1 : -1); direction = Direction(d))),
('!', () -> ipnext()), ('?', ()-> if data[dp] == 0 ipnext() end),
('@', ()-> push!(stack, (ipx, ipy, direction))),
('#', ()-> if length(stack) > 0 (ipx, ipy, direction) = pop!(stack) end),
('\n', ()-> (running = false))])
 
inboundsx(plus) = (plus ? (ipx < lmax) : (ipx > 1)) ? true : exit(data[dp])
inboundsy(plus) = (plus ? (ipy < length(lines)) : (ipy > 1)) ? true : exit(data[dp])
function ipnext()
if direction == right && inboundsx(true) ipx += 1
elseif direction == left && inboundsx(false) ipx -= 1
elseif direction == down && inboundsy(true) ipy += 1
elseif direction == up && inboundsy(false) ipy -= 1
end
end
 
running = true
while running
cmdcode = lines[ipy][ipx]
if haskey(instruction, cmdcode)
instruction[cmdcode]()
end
ipnext()
end
exit(data[dp])
end
 
snusp(100, echo2)</syntaxhighlight> {{output}} <pre>
> Hi
Hi
>
</pre>
 
=={{header|Kotlin}}==
{{trans|Go}}
<syntaxhighlight lang ="scala">// version 1.1.12
 
// requires 5 chars (10 bytes) of data store
Line 141 ⟶ 533:
ipr = r
ipc = i
break@findStart
}
}
}
Line 148 ⟶ 540:
var id = 0
val step = fun() {
if (id and 1 == 0)
ipc += 1 - (id and 2)
else
ipr += 1 - (id and 2)
}
 
// execute
while ((ipr in 0 until cs.size) && (ipc in 0 until cs[ipr].length)) {
Line 174 ⟶ 566:
fun main(args: Array<String>) {
snusp(5, hw)
}</langsyntaxhighlight>
 
{{out}}
Line 181 ⟶ 573:
</pre>
 
=={{header|MathematicaLua}}==
See [[RCSNUSP/Lua]].
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
See [[RCSNUSP/Mathematica]].
 
=={{header|OCamlNim}}==
{{trans|Python}}
See [[RCSNUSP/OCaml]].
<syntaxhighlight lang="nim">import strutils
 
# Requires 5 bytes of data store.
=={{header|Perl}}==
const Hw = r"""
See [[RCSNUSP/Perl]].
/++++!/===========?\>++.>+.+++++++..+++\
\+++\ | /+>+++++++>/ /++++++++++<<.++>./
$+++/ | \+++++++++>\ \+++++.>.+++.-----\
\==-<<<<+>+++/ /=.>.+>.--------.-/"""
 
#---------------------------------------------------------------------------------------------------
=={{header|Perl 6}}==
{{works with|Rakudo|2017.02}}
Implementation of modular SNUSP.
<lang perl6>class SNUSP {
 
proc snusp(dsLen: int; code: string) =
has @!inst-pointer;
## The interpreter.
has @!call-stack;
has @!direction;
has @!memory;
has $!mem-pointer;
 
var
method run ($code) {
ds = newSeq[byte](dsLen) # Data store.
init();
dp = 0 # Data pointer.
my @code = pad( |$code.lines );
cs = code.splitLines() # Two dimensional code store.
for @code.kv -> $r, @l {
ipr, ipc = 0 # Instruction pointers in row ans column.
my $index = @l.grep( /'$'/, :k );
dir = 0 # Direction (0 = right, 1 = down, 2 = left, 3 = up).
if $index {
@!inst-pointer = $r, $index;
last
}
}
 
# Initialize instruction pointers.
loop {
for r, row in cs:
my $instruction = @code[@!inst-pointer[0]; @!inst-pointer[1]];
ipc = row.find('$')
given $instruction {
if ipc >= 0:
when '>' { $!mem-pointer++ }
ipr = r
when '<' { $!mem-pointer-- }
break
when '+' { @!memory[$!mem-pointer]++ }
when '-' { @!memory[$!mem-pointer]-- }
when '.' { print @!memory[$!mem-pointer].chr }
when ',' { @!memory[$!mem-pointer] = $*IN.getc.ord }
when '/' { @!direction = @!direction.reverse «*» -1 }
when '\\' { @!direction = @!direction.reverse }
when '!' { nexti() }
when '?' { nexti() unless @!memory[$!mem-pointer] }
when '@' { @!call-stack.push: @!inst-pointer.Array }
when '#' {
last unless +@!call-stack;
@!inst-pointer = |@!call-stack.pop;
nexti();
}
}
nexti();
last if @!inst-pointer[0] > +@code or
@!inst-pointer[1] > +@code[0];
}
 
#.................................................................................................
sub init () {
@!inst-pointer = 0, 0;
@!direction = 0, 1;
$!mem-pointer = 0;
@!memory = ()
}
 
func step() =
sub nexti () { @!inst-pointer Z+= @!direction }
## Update the instruction pointers acccording to the direction.
 
sub padif (dir *@linesand 1) {== 0:
inc ipc, 1 - (dir and my $max = max @lines».chars;2)
else:
my @pad = @lines.map: $max - *.chars;
inc ipr, 1 - (dir and 2)
map -> $i { flat @lines[$i].comb, ' ' xx @pad[$i] }, ^@lines;
}
}
}
 
#.................................................................................................
# TESTING
my $hw = q:to/END/;
/++++!/===========?\>++.>+.+++++++..+++\
\+++\ | /+>+++++++>/ /++++++++++<<.++>./
$+++/ | \+++++++++>\ \+++++.>.+++.-----\
\==-<<<<+>+++/ /=.>.+>.--------.-/
END
 
# Interpreter loop.
my $snusp = SNUSP.new;
while ipr in 0..cs.high and ipc in 0..cs[ipr].high:
$snusp.run($hw)</lang>
case cs[ipr][ipc]
{{out}}
of '>': inc dp
<pre>Hello World!</pre>
of '<': dec dp
of '+': inc ds[dp]
of '-': dec ds[dp]
of '.': stdout.write chr(ds[dp])
of ',': ds[dp] = byte(stdin.readLine()[0])
of '/': dir = not dir
of '\\': dir = dir xor 1
of '!': step()
of '?': (if ds[dp] == 0: step())
else: discard
step()
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
=={{header|Phix}}==
{{trans|Go}}<lang Phix>integer id = 0, ipr = 1, ipc = 1
 
when isMainModule:
procedure step()
snusp(5, Hw)</syntaxhighlight>
if and_bits(id,1) == 0 then
ipc += 1 - and_bits(id,2)
else
ipr += 1 - and_bits(id,2)
end if
end procedure
 
{{out}}
procedure snusp(integer dlen, string s)
<pre>Hello World!</pre>
sequence ds = repeat(0,dlen) -- data store
integer dp = 1 -- data pointer
-- remove leading '\n' from string if present
s = trim_head(s,'\n')
-- make 2 dimensional instruction store and set instruction pointers
sequence cs = split(s,'\n')
ipr = 1
ipc = 1
-- look for starting instruction
for i=1 to length(cs) do
ipc = find('$',cs[i])
if ipc then
ipr = i
exit
end if
end for
 
=={{header|OCaml}}==
id = 0
See [[RCSNUSP/OCaml]].
-- execute
while ipr>=1 and ipr<=length(cs)
and ipc>=1 and ipc<=length(cs[ipr]) do
integer op = cs[ipr][ipc]
switch op do
case '>' : dp += 1
case '<' : dp -= 1
case '+' : ds[dp] += 1
case '-' : ds[dp] -= 1
case '.' : puts(1,ds[dp])
case ',' : ds[dp] = getc(0)
case '/' : id = not_bits(id)
case '\\': id = xor_bits(id,1)
case '!' : step()
case '?' : if ds[dp]=0 then step() end if
end switch
step()
end while
end procedure
constant hw = """
/++++!/===========?\>++.>+.+++++++..+++\
\+++\ | /+>+++++++>/ /++++++++++<<.++>./
$+++/ | \+++++++++>\ \+++++.>.+++.-----\
\==-<<<<+>+++/ /=.>.+>.--------.-/"""
 
=={{header|Perl}}==
snusp(5, hw)</lang>
See [[RCSNUSP/Perl]].
 
=={{header|Phix}}==
{{trans|Go}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">id</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ipr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ipc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">ipc</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">ipr</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">snusp</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">dlen</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ds</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dlen</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- data store</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">dp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #000080;font-style:italic;">-- data pointer
-- remove leading '\n' from string if present</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim_head</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- make 2 dimensional instruction store and set instruction pointers</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">cs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">ipr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">ipc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #000080;font-style:italic;">-- look for starting instruction</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cs</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">ipc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">'$'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ipc</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">ipr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">id</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000080;font-style:italic;">-- execute</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">ipr</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ipr</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cs</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">and</span> <span style="color: #000000;">ipc</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">ipc</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ipr</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">op</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">cs</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ipr</span><span style="color: #0000FF;">][</span><span style="color: #000000;">ipc</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">op</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'&gt;'</span> <span style="color: #0000FF;">:</span> <span style="color: #000000;">dp</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'&lt;'</span> <span style="color: #0000FF;">:</span> <span style="color: #000000;">dp</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'+'</span> <span style="color: #0000FF;">:</span> <span style="color: #000000;">ds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dp</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'-'</span> <span style="color: #0000FF;">:</span> <span style="color: #000000;">ds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dp</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'.'</span> <span style="color: #0000FF;">:</span> <span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dp</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">','</span> <span style="color: #0000FF;">:</span> <span style="color: #000000;">ds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dp</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'/'</span> <span style="color: #0000FF;">:</span> <span style="color: #000000;">id</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">not_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'\\'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">id</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'!'</span> <span style="color: #0000FF;">:</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'?'</span> <span style="color: #0000FF;">:</span> <span style="color: #008080;">if</span> <span style="color: #000000;">ds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dp</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">step</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #000000;">step</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">hw</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
/++++!/===========?\&gt;++.&gt;+.+++++++..+++\
\+++\ | /+&gt;+++++++&gt;/ /++++++++++&lt;&lt;.++&gt;./
$+++/ | \+++++++++&gt;\ \+++++.&gt;.+++.-----\
\==-&lt;&lt;&lt;&lt;+&gt;+++/ /=.&gt;.+&gt;.--------.-/"""</span>
<span style="color: #000000;">snusp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hw</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 338 ⟶ 726:
=={{header|Python}}==
{{trans|Go}}
<langsyntaxhighlight lang="python">#!/usr/bin/env python3
 
HW = r'''
Line 392 ⟶ 780:
 
if __name__ == '__main__':
snusp(5, HW)</langsyntaxhighlight>
{{out}}
<pre>
Line 400 ⟶ 788:
=={{header|Racket}}==
See [[RCSNUSP/Racket]].
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2017.02}}
Implementation of modular SNUSP.
<syntaxhighlight lang="raku" line>class SNUSP {
 
has @!inst-pointer;
has @!call-stack;
has @!direction;
has @!memory;
has $!mem-pointer;
 
method run ($code) {
init();
my @code = pad( |$code.lines );
for @code.kv -> $r, @l {
my $index = @l.grep( /'$'/, :k );
if $index {
@!inst-pointer = $r, $index;
last
}
}
 
loop {
my $instruction = @code[@!inst-pointer[0]; @!inst-pointer[1]];
given $instruction {
when '>' { $!mem-pointer++ }
when '<' { $!mem-pointer-- }
when '+' { @!memory[$!mem-pointer]++ }
when '-' { @!memory[$!mem-pointer]-- }
when '.' { print @!memory[$!mem-pointer].chr }
when ',' { @!memory[$!mem-pointer] = $*IN.getc.ord }
when '/' { @!direction = @!direction.reverse «*» -1 }
when '\\' { @!direction = @!direction.reverse }
when '!' { nexti() }
when '?' { nexti() unless @!memory[$!mem-pointer] }
when '@' { @!call-stack.push: @!inst-pointer.Array }
when '#' {
last unless +@!call-stack;
@!inst-pointer = |@!call-stack.pop;
nexti();
}
}
nexti();
last if @!inst-pointer[0] > +@code or
@!inst-pointer[1] > +@code[0];
}
 
sub init () {
@!inst-pointer = 0, 0;
@!direction = 0, 1;
$!mem-pointer = 0;
@!memory = ()
}
 
sub nexti () { @!inst-pointer Z+= @!direction }
 
sub pad ( *@lines ) {
my $max = max @lines».chars;
my @pad = @lines.map: $max - *.chars;
map -> $i { flat @lines[$i].comb, ' ' xx @pad[$i] }, ^@lines;
}
}
}
 
# TESTING
my $hw = q:to/END/;
/++++!/===========?\>++.>+.+++++++..+++\
\+++\ | /+>+++++++>/ /++++++++++<<.++>./
$+++/ | \+++++++++>\ \+++++.>.+++.-----\
\==-<<<<+>+++/ /=.>.+>.--------.-/
END
 
my $snusp = SNUSP.new;
$snusp.run($hw)</syntaxhighlight>
{{out}}
<pre>Hello World!</pre>
 
=={{header|Ruby}}==
Line 407 ⟶ 873:
The interpreter below implements Core SNUSP:
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const proc: snusp (in string: sourceCode, in integer: memSize, inout file: input, inout file: output) is func
Line 467 ⟶ 933:
begin
snusp(helloWorld, 5, IN, OUT);
end func;</langsyntaxhighlight>
 
{{out}}
Line 476 ⟶ 942:
=={{header|Tcl}}==
See [[RCSNUSP/Tcl]].
 
=={{header|Wren}}==
{{trans|Go}}
<syntaxhighlight lang="wren">import "io" for Stdin
 
// 'raw' is a multi-line string
var snusp = Fn.new { |dlen, raw|
var ds = List.filled(dlen, 0) // data store
var dp = 0 // data pointer
 
// remove leading \n if it's there
if (raw[0] == "\n") raw = raw[1..-1]
 
// make 2 dimensional instruction store & declare instruction pointers
var s = raw.split("\n")
var ipr = 0
var ipc = 0
 
// look for starting instruction
for (r in 0...s.count) {
var row = s[r]
var outer = false
for (c in 0...row.count) {
var i = row[c]
if (i == "$") {
ipr = r
ipc = c
outer = true
break
}
}
if (outer) break
}
 
var id = 0
var step = Fn.new {
if (id&1 == 0) {
ipc = ipc + 1 - (id&2)
} else {
ipr = ipr + 1 - (id&2)
}
}
 
// execute
while (ipr >= 0 && ipr < s.count && ipc >= 0 && ipc < s[ipr].count) {
var c = s[ipr][ipc]
if (c == ">") {
dp = dp + 1
} else if (c == "<") {
dp = dp - 1
} else if (c == "+") {
ds[dp] = ds[dp] + 1
} else if (c == "-") {
ds[dp] = ds[dp] - 1
} else if (c == ".") {
System.write(String.fromByte(ds[dp]))
} else if (c == ",") {
ds[dp] = Stdin.readByte()
} else if (c == "/") {
id = ~id
} else if (c == "\\") {
id = id ^ 1
} else if (c == "!") {
step.call()
} else if (c == "?") {
if (ds[dp] == 0) step.call()
}
step.call()
}
}
 
var hw =
"/++++!/===========?\\>++.>+.+++++++..+++\\\n" +
"\\+++\\ | /+>+++++++>/ /++++++++++<<.++>./\n" +
"$+++/ | \\+++++++++>\\ \\+++++.>.+++.-----\\\n" +
" \\==-<<<<+>+++/ /=.>.+>.--------.-/"
snusp.call(5, hw)</syntaxhighlight>
 
{{out}}
<pre>
Hello World!
</pre>
 
{{omit from|GUISS}}
1,983

edits