How to resolve the algorithm Execute SNUSP step by step in the Icon and Unicon programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Execute SNUSP step by step in the Icon and Unicon programming language

Table of Contents

Problem Statement

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.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Execute SNUSP step by step in the Icon and Unicon programming language

Source code in the icon programming language

#
# 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


  

You may also check:How to resolve the algorithm MAC vendor lookup step by step in the Common Lisp programming language
You may also check:How to resolve the algorithm Return multiple values step by step in the Rust programming language
You may also check:How to resolve the algorithm Determine if a string is squeezable step by step in the Lua programming language
You may also check:How to resolve the algorithm Terminal control/Display an extended character step by step in the M2000 Interpreter programming language
You may also check:How to resolve the algorithm Abbreviations, simple step by step in the C++ programming language