diff --git a/builtins.go b/builtins.go index a5692b2..1281887 100644 --- a/builtins.go +++ b/builtins.go @@ -356,6 +356,22 @@ func (b *Builtins) Rot(s *Stack) func() error { } } +// Pick duplicates TOS from within the stack to the top +func (b *Builtins) Pick(s *Stack) func() error { + return func() error { + tos, err := s.Pop() + if err != nil { + return err + } + swp, err := s.Pick(tos) + if err != nil { + return err + } + s.Push(swp) + return nil + } +} + // Words outputs a list of all known words in the dictionary func (b *Builtins) Words(out io.Writer, d Dictionary) func() error { if out == nil { @@ -580,3 +596,11 @@ func (b *Builtins) Debug(out io.Writer, s *Stack) func() error { return nil } } + +// Depth puts the current count of stack items on the stacks +func (b *Builtins) Depth(s *Stack) func() error { + return func() error { + s.Push(len(s.values)) + return nil + } +} diff --git a/main.go b/main.go index 05da1fc..0fc329f 100644 --- a/main.go +++ b/main.go @@ -44,9 +44,9 @@ func main() { dict.AddWord("+1", Word{Name: "+1", Source: []string{"1", "+"}}) dict.AddWord("-1", Word{Name: "-1", Source: []string{"1", "-"}}) dict.AddWord("ABS", Word{Name: "ABS", Source: []string{"DUP", "0<", "IF", "NEGATE", "THEN"}}) - dict.AddWord("NEGATE", Word{Name: "NEGATE", Source: []string{"DUP", "DUP", "-", "SWAP", "-"}}) - dict.AddWord("MAX", Word{Name: "MAX", Source: []string{"OVER", "OVER", "<", "IF", "SWAP", "THEN", "DROP"}}) - dict.AddWord("MIN", Word{Name: "MIN", Source: []string{"OVER", "OVER", ">", "IF", "SWAP", "THEN", "DROP"}}) + dict.AddWord("NEGATE", Word{Name: "NEGATE", Source: []string{"-1", "*"}}) + dict.AddWord("MAX", Word{Name: "MAX", Source: []string{"2DUP", "<", "IF", "SWAP", "THEN", "DROP"}}) + dict.AddWord("MIN", Word{Name: "MIN", Source: []string{"2DUP", ">", "IF", "SWAP", "THEN", "DROP"}}) // output dict.AddWord(".", Word{Name: ".", Impl: b.Print(os.Stdout, &stack)}) dict.AddWord("EMIT", Word{Name: "EMIT", Impl: b.Emit(os.Stdout, &stack)}) @@ -64,16 +64,25 @@ func main() { dict.AddWord("0>", Word{Name: "0>", Source: []string{"0", ">"}}) // stack manipulation dict.AddWord("DUP", Word{Name: "DUP", Impl: b.Dup(&stack)}) + dict.AddWord("?DUP", Word{Name: "?DUP", Source: []string{"DUP", "0<>", "IF", "DUP", "THEN"}}) dict.AddWord("SWAP", Word{Name: "SWAP", Impl: b.Swap(&stack)}) dict.AddWord("OVER", Word{Name: "OVER", Impl: b.Over(&stack)}) dict.AddWord("DROP", Word{Name: "DROP", Impl: b.Drop(&stack)}) dict.AddWord("ROT", Word{Name: "ROT", Impl: b.Rot(&stack)}) + dict.AddWord("PICK", Word{Name: "PICK", Impl: b.Pick(&stack)}) + dict.AddWord("NIP", Word{Name: "NIP", Source: []string{"SWAP", "DROP"}}) + dict.AddWord("TUCK", Word{Name: "TUCK", Source: []string{"SWAP", "OVER"}}) + // paired stack manipulation + dict.AddWord("2DROP", Word{Name: "2DROP", Source: []string{"DROP", "DROP"}}) + dict.AddWord("2DUP", Word{Name: "2DUP", Source: []string{"OVER", "OVER"}}) + dict.AddWord("2OVER", Word{Name: "2OVER", Source: []string{"3", "PICK", "3", "PICK"}}) // debugging dict.AddWord("WORDS", Word{Name: "WORDS", Impl: b.Words(os.Stdout, dict)}) dict.AddWord("FLAGS", Word{Name: "FLAGS", Impl: b.Flags(os.Stdout, c)}) dict.AddWord(".S", Word{Name: ".S", Impl: b.Debug(os.Stdout, &stack)}) dict.AddWord(".R", Word{Name: ".R", Impl: b.Debug(os.Stdout, &rstack)}) dict.AddWord(".I", Word{Name: ".I", Impl: b.Debug(os.Stdout, &ifstack)}) + dict.AddWord("DEPTH", Word{Name: "DEPTH", Impl: b.Depth(&stack)}) dict.AddWord("R>", Word{Name: "R>", Impl: b.RFrom(&stack, &rstack)}) dict.AddWord(">R", Word{Name: ">R", Impl: b.ToR(&stack, &rstack)}) dict.AddWord("R@", Word{Name: "R@", Impl: b.RFetch(&stack, &rstack)})