Execute SNUSP: Difference between revisions

From Rosetta Code
Content added Content deleted
(Python solution)
No edit summary
Line 12: Line 12:
=={{header|C}}==
=={{header|C}}==
See [[RCSNUSP/C]].
See [[RCSNUSP/C]].

=={{header|C++}}==
See [[RCSNUSP/C++]].


=={{header|COBOL}}==
=={{header|COBOL}}==

Revision as of 10:49, 12 June 2015

Task
Execute SNUSP
You are encouraged to solve this task according to the task description, using any language you may know.
Execute SNUSP is an implementation of SNUSP. Other implementations of SNUSP.

RCSNUSP is a set of SNUSP compilers and interpreters written for Rosetta Code in a variety of languages. Below are links to each of the versions of RCSNUSP.

An implementation need only properly implement the Core SNUSP instructions ('$', '\', '/', '+', '-', '<', '>', ',', '.', '!', and '?'). 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.

Ada

See Execute SNUSP/Ada.

AutoHotkey

See RCSNUSP/AutoHotkey.

C

See RCSNUSP/C.

C++

See RCSNUSP/C++.

COBOL

See RCSNUSP/COBOL.

D

See RCSNUSP/D.

F#

See RCSNUSP/F Sharp.

Go

See RCSNUSP/Go.

Haskell

See RCSNUSP/Haskell.

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. <lang J> Note 'snusp'

   Without $ character the program counter starts at top left (0 0) moving to the right (0 1)
   >       increment the pointer (to point to the next cell to the right).
   <       decrement the pointer (to point to the next cell to the left).
   +       increment (increase by one) the cell at the pointer.
   -       decrement (decrease by one) the cell at the pointer.
   .       output the value of the cell at the pointer as a character.
   ,       accept one character of input, storing its value in the cell at the pointer.
   \/      mirrors
   ?       skip if memory pointer is 0
   !       skip
   $       optional start program here (also heading to the right)

)

smoutput 'Toroidal programs run forever. Use ^C to interrupt.'

main =: 3 : 0 NB. use: main 'program.snusp'

PROGRAM =: [;._2 LF ,~ 1!:1 boxopen y
SHAPE =: $PROGRAM
PC =: SHAPE#:(,PROGRAM) i.'$'
PCSTEP =: 0 1
CELL =: 0
CELLS =: ,0
while. 1 do. NB. for_i. i.400 do.
 INSTRUCTION =: (<PC) { PROGRAM
 STEP =: PCSTEP
 select. INSTRUCTION
 case. '<' do.
  CELL =: <: CELL
  if. CELL < 0 do.
   CELL =: 0
   CELLS =: 0 , CELLS
  end.
 case. '>' do.
  CELL =: >: CELL
  if. CELL >: # CELLS do.
   CELLS =: CELLS , 0
  end.
 case. ;/'-+' do. CELLS =: CELL ((<:'- +'i.INSTRUCTION)+{)`[`]} CELLS
 case. '.' do. 1!:2&4 (CELL{CELLS){a.
 case. ',' do. CELLS =: (1!:1<1) CELL } CELLS
 fcase. '/' do. STEP =: - STEP
 case. '\' do. STEP =: PCSTEP =: |. STEP
 case. '?' do. STEP =: +:^:(0 = CELL{CELLS) STEP
 case. '!' do. STEP =: +: STEP
 end.
 PC =: (| (PC + STEP + ])) SHAPE  NB. toroidal
 NB. smoutput PC;CELL;CELLS  NB. debug
end.

) </lang> Store <lang SNUSP>\ display JJ and linefeed, then loop forever \ +++++++++++++++++++++++++++++++++++++\

   ! /+++++++++++++++++++++++++++++++++++++/
   / \..<+++++\
     \ . +++++/

</lang> as J.snusp

   load'snusp.ijs'  NB. the j code above
Toroidal programs run forever.  Use ^C to interrupt.
   
   main'J.snusp'
JJ
^C
|attention interrupt: main
   

Java

See RCSNUSP/Java

JavaScript

See RCSNUSP/JavaScript.

OCaml

See RCSNUSP/OCaml.

Perl

See RCSNUSP/Perl.

PicoLisp

See RCSNUSP/PicoLisp.

Python

Translation of: Go

<lang python>#!/usr/bin/env python3

HW = r /++++!/===========?\>++.>+.+++++++..+++\ \+++\ | /+>+++++++>/ /++++++++++<<.++>./ $+++/ | \+++++++++>\ \+++++.>.+++.-----\

     \==-<<<<+>+++/ /=.>.+>.--------.-/

def snusp(store, code):

   ds = bytearray(store)  # data store
   dp = 0                 # data pointer
   cs = code.splitlines() # 2 dimensional code store
   ipr, ipc = 0, 0        # instruction pointers in row and column
   for r, row in enumerate(cs):
       try:
           ipc = row.index('$')
           ipr = r
           break
       except ValueError:
           pass
   rt, dn, lt, up = range(4)
   id = rt  # instruction direction.  starting direction is always rt
   def step():
       nonlocal ipr, ipc
       if id&1:
           ipr += 1 - (id&2)
       else:
           ipc += 1 - (id&2)
   while ipr >= 0 and ipr < len(cs) and ipc >= 0 and ipc < len(cs[ipr]):
       op = cs[ipr][ipc]
       if op == '>':
           dp += 1
       elif op == '<':
           dp -= 1
       elif op == '+':
           ds[dp] += 1
       elif op == '-':
           ds[dp] -= 1
       elif op == '.':
           print(chr(ds[dp]), end=)
       elif op == ',':
           ds[dp] = input()
       elif op == '/':
           id = ~id
       elif op == '\\':
           id ^= 1
       elif op == '!':
           step()
       elif op == '?':
           if not ds[dp]:
               step()
       step()

if __name__ == '__main__':

   snusp(5, HW)</lang>
Output:
Hello World!

Racket

See RCSNUSP/Racket.

Ruby

See RCSNUSP/Ruby.

Seed7

The interpreter below implements Core SNUSP:

<lang seed7>$ include "seed7_05.s7i";

const proc: snusp (in string: sourceCode, in integer: memSize, inout file: input, inout file: output) is func

 local
   var array string: instructions is 0 times "";
   var array char: memory is 0 times ' ';
   var integer: dataPointer is 1;
   var integer: instrPtrRow is 0;
   var integer: instrPtrColumn is 0;
   var integer: rowDir is 0;
   var integer: columnDir is 1;
   var integer: helpDir is 0;
   var integer: row is 0;
 begin
   instructions := split(sourceCode, "\n");
   memory := memSize times '\0;';
   for key row range instructions do
     if pos(instructions[row], '$') <> 0 then
       instrPtrRow := row;
       instrPtrColumn := pos(instructions[row], '$');
     end if;
   end for;
   while instrPtrRow >= 1 and instrPtrRow <= length(instructions) and
       instrPtrColumn >= 1 and instrPtrColumn <= length(instructions[instrPtrRow]) do
     case instructions[instrPtrRow][instrPtrColumn] of
       when {'>'}:  incr(dataPointer);
       when {'<'}:  decr(dataPointer);
       when {'+'}:  incr(memory[dataPointer]);
       when {'-'}:  decr(memory[dataPointer]);
       when {'.'}:  write(output, memory[dataPointer]);
       when {','}:  memory[dataPointer] := getc(input);
       when {'/'}:  helpDir := rowDir;
                    rowDir := -columnDir;
                    columnDir := -helpDir;
       when {'\\'}: helpDir := rowDir;
                    rowDir := columnDir;
                    columnDir := helpDir;
       when {'!'}:  instrPtrRow +:= rowDir;
                    instrPtrColumn +:= columnDir;
       when {'?'}:  if memory[dataPointer] = '\0;' then
                      instrPtrRow +:= rowDir;
                      instrPtrColumn +:= columnDir;
                    end if;
     end case;
     instrPtrRow +:= rowDir;
     instrPtrColumn +:= columnDir;
   end while;
 end func;
  1. SNUSP implementation of Hello World.

const string: helloWorld is "/++++!/===========?\\>++.>+.+++++++..+++\\\n\

                           \\\+++\\ | /+>+++++++>/ /++++++++++<<.++>./\n\
                           \$+++/ | \\+++++++++>\\ \\+++++.>.+++.-----\\\n\
                           \      \\==-<<<<+>+++/ /=.>.+>.--------.-/";

const proc: main is func

 begin
   snusp(helloWorld, 5, IN, OUT);
 end func;</lang>
Output:
Hello World!

Tcl

See RCSNUSP/Tcl.