Execute SNUSP/Go

From Rosetta Code
Execute SNUSP/Go is an implementation of SNUSP. Other implementations of SNUSP.
Execute SNUSP/Go is part of RCSNUSP. You may find other members of RCSNUSP at Category:RCSNUSP.

Only Core SNUSP today. Fixed size data store, no bounds checking.

package main
 
import (
"fmt"
"strings"
)
 
// lovely Core SNUSP implementation of Hello World,
// taken from the Ruby Execute SNUSP page.
// it happens to run with only 5 bytes of data store!
const hw = `
/++++!/===========?\>++.>+.+++++++..+++\
\+++\ | /+>+++++++>/ /++++++++++<<.++>./
$+++/ | \+++++++++>\ \+++++.>.+++.-----\
\==-<<<<+>+++/ /=.>.+>.--------.-/`

 
func main() {
snusp(5, hw)
}
 
// input is a multi-line string.
func snusp(dLen int, raw string) {
ds := make([]byte, dLen) // data store
var dp int // data pointer
 
// toss leading \n of code if it's there
if raw[0] == '\n' {
raw = raw[1:]
}
 
// make 2 dimensional instruction store, declare instruction pointers
is := strings.Split(raw, "\n")
var ipr, ipc int
 
// look for starting instruction
findStart:
for r, row := range is {
for c, i := range row {
if i == '$' {
ipr, ipc = r, c
break findStart
}
}
}
 
// starting direction is always rt
const (
rt = iota
dn
lt
up
)
id := rt
 
// handy, below
step := func() {
if id&1 == 0 {
ipc += 1 - int(id&2)
} else {
ipr += 1 - int(id&2)
}
}
 
// execute
for ipr >= 0 && ipr < len(is) && ipc >= 0 && ipc < len(is[ipr]) {
switch is[ipr][ipc] {
case '>':
dp++
case '<':
dp--
case '+':
ds[dp]++
case '-':
ds[dp]--
case '.':
fmt.Printf("%c", ds[dp])
case ',':
fmt.Scanf("%c", &ds[dp])
case '/':
id = ^id
case '\\':
id ^= 1
case '!':
step()
case '?':
if ds[dp] == 0 {
step()
}
}
step()
}
}

Output:

Hello World!