109 lines
2 KiB
Go
109 lines
2 KiB
Go
package pointer
|
|
|
|
import (
|
|
"math/rand"
|
|
"time"
|
|
|
|
"git.adyxax.org/adyxax/gofunge98/pkg/field"
|
|
)
|
|
|
|
var myRand = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
|
|
type InputFunction func() int
|
|
type OutputFunction func(v int)
|
|
|
|
type Pointer struct {
|
|
// the position
|
|
x int
|
|
y int
|
|
// The delta
|
|
dx int
|
|
dy int
|
|
// The Storage offset
|
|
sox int
|
|
soy int
|
|
// The stringmode flag
|
|
stringMode bool
|
|
lastCharWasSpace bool
|
|
// The stack
|
|
ss *StackStack
|
|
// The next element for the multi-"threaded" b98 interpreter
|
|
Next *Pointer
|
|
// The input/output functions
|
|
CharacterInput InputFunction
|
|
DecimalInput InputFunction
|
|
CharacterOutput OutputFunction
|
|
DecimalOutput OutputFunction
|
|
// command line arguments
|
|
Argv []string
|
|
}
|
|
|
|
func NewPointer() *Pointer {
|
|
return &Pointer{
|
|
dx: 1,
|
|
ss: NewStackStack(),
|
|
CharacterInput: DefaultCharacterInput,
|
|
DecimalInput: DefaultDecimalInput,
|
|
CharacterOutput: DefaultCharacterOutput,
|
|
DecimalOutput: DefaultDecimalOutput,
|
|
}
|
|
}
|
|
|
|
func (p Pointer) Split() *Pointer {
|
|
return &p // p is already a copy TODO we need to duplicate the stack and handle the Next
|
|
}
|
|
|
|
func (p *Pointer) Step(f field.Field) {
|
|
p.x, p.y = f.Step(p.x, p.y, p.dx, p.dy)
|
|
}
|
|
|
|
func (p Pointer) Get(f field.Field) int {
|
|
return f.Get(p.x, p.y)
|
|
}
|
|
|
|
func (p *Pointer) StepAndGet(f field.Field) int {
|
|
p.Step(f)
|
|
return p.Get(f)
|
|
}
|
|
|
|
func (p *Pointer) Set(x, y int) {
|
|
p.x, p.y = x, y
|
|
}
|
|
|
|
func (p *Pointer) RedirectTo(dx, dy int) {
|
|
p.dx, p.dy = dx, dy
|
|
}
|
|
|
|
func (p *Pointer) Reverse() {
|
|
p.dx, p.dy = -p.dx, -p.dy
|
|
}
|
|
|
|
func (p *Pointer) Redirect(c int) bool {
|
|
switch c {
|
|
case '^':
|
|
p.dx, p.dy = 0, -1
|
|
case '>':
|
|
p.dx, p.dy = 1, 0
|
|
case 'v':
|
|
p.dx, p.dy = 0, 1
|
|
case '<':
|
|
p.dx, p.dy = -1, 0
|
|
case '?':
|
|
directions := []int{0, -1, 1, 0, 0, 1, -1, 0}
|
|
r := 2 * myRand.Intn(4)
|
|
p.dx, p.dy = directions[r], directions[r+1]
|
|
case '[':
|
|
p.dx, p.dy = p.dy, -p.dx
|
|
case ']':
|
|
p.dx, p.dy = -p.dy, p.dx
|
|
case 'r':
|
|
p.Reverse()
|
|
case 'x':
|
|
dy := p.ss.head.Pop()
|
|
dx := p.ss.head.Pop()
|
|
p.RedirectTo(dx, dy)
|
|
default:
|
|
return false
|
|
}
|
|
return true
|
|
}
|