implement PICK on stacks to make the implementation of I less silly

This commit is contained in:
David 2021-02-14 20:32:38 -05:00
parent 9d3f61338f
commit e5bb216f95
2 changed files with 11 additions and 20 deletions

View File

@ -237,16 +237,10 @@ func (b *Builtins) Swap(s *Stack) func() error {
// Over duplicates NOS to TOS, resulting in NOS TOS NOS // Over duplicates NOS to TOS, resulting in NOS TOS NOS
func (b *Builtins) Over(s *Stack) func() error { func (b *Builtins) Over(s *Stack) func() error {
return func() error { return func() error {
tos, err := s.Pop() nos, err := s.Pick(1)
if err != nil { if err != nil {
return err return err
} }
nos, err := s.Pop()
if err != nil {
return err
}
s.Push(nos)
s.Push(tos)
s.Push(nos) s.Push(nos)
return nil return nil
} }
@ -286,7 +280,7 @@ func (b *Builtins) Rot(s *Stack) func() error {
func (b *Builtins) Words(d Dictionary) func() error { func (b *Builtins) Words(d Dictionary) func() error {
return func() error { return func() error {
for n := range d { for n := range d {
fmt.Printf("%s %s\n", n, d[n].Source) fmt.Printf("%s ", n)
} }
return nil return nil
} }
@ -423,22 +417,11 @@ func (b *Builtins) Loop(s *Stack, r *Stack) func() error {
// I puts the current value of the loop counter on the top of the stack // I puts the current value of the loop counter on the top of the stack
func (b *Builtins) I(s *Stack, r *Stack) func() error { func (b *Builtins) I(s *Stack, r *Stack) func() error {
return func() error { return func() error {
tors, err := r.Pop() counter, err := r.Pick(2)
if err != nil {
return err
}
nors, err := r.Pop()
if err != nil {
return err
}
counter, err := r.Pop()
if err != nil { if err != nil {
return err return err
} }
s.Push(counter) s.Push(counter)
r.Push(counter)
r.Push(nors)
r.Push(tors)
return nil return nil
} }
} }

View File

@ -21,3 +21,11 @@ func (s *Stack) Pop() (int, error) {
func (s *Stack) Push(i int) { func (s *Stack) Push(i int) {
s.values = append([]int{i}, s.values...) s.values = append([]int{i}, s.values...)
} }
// Pick grabs a value from the given depth in the stack, non-destructively.
func (s *Stack) Pick(i int) (int, error) {
if len(s.values) < i {
return 0, fmt.Errorf("cannot pick value from beyond stack depth")
}
return s.values[i], nil
}