Execute SNUSP: Difference between revisions
Content added Content deleted
Thundergnat (talk | contribs) (Rename Perl 6 -> Raku, alphabetize, minor clean-up) |
(Add Icon and Unicon) |
||
Line 93: | Line 93: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
See [[RCSNUSP/Haskell]]. |
See [[RCSNUSP/Haskell]]. |
||
=={{header|Icon}} and {{header|Unicon}}== |
|||
<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</lang> |
|||
{{out}} |
|||
Using the Modular SNUSP sample |
|||
<pre>prompt$ unicon -s snusp.icn -x hello.snusp |
|||
Hello, world!</pre> |
|||
=={{header|J}}== |
=={{header|J}}== |