From 3083cf2e33daa94af7fc8ee89fe82501cc878782 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 22 Sep 2018 20:37:22 +0200 Subject: ... --- go/forth/forth.go | 90 +++++++++++++++++++++++-------------------------------- 1 file changed, 38 insertions(+), 52 deletions(-) diff --git a/go/forth/forth.go b/go/forth/forth.go index 9059168..e9a32da 100644 --- a/go/forth/forth.go +++ b/go/forth/forth.go @@ -7,16 +7,10 @@ import ( "strings" ) -type stacker interface { - push(int) error - pop() (int, error) - values() []int -} - type stack []int -func (s *stack) push(n int) error { - *s = append(*s, n) +func (s *stack) push(n ...int) error { + *s = append(*s, n...) return nil } @@ -30,11 +24,7 @@ func (s *stack) pop() (int, error) { return tos, nil } -func (s *stack) values() []int { - return []int(*s) -} - -func pop2(s stacker) (int, int, error) { +func (s *stack) pop2() (int, int, error) { tos, err := s.pop() // top on stack if err != nil { return 0, 0, err @@ -46,52 +36,49 @@ func pop2(s stacker) (int, int, error) { return tos, nos, nil } -func pushN(s stacker, n ...int) error { - for _, v := range n { - if err := s.push(v); err != nil { - return err - } - } - return nil +func (s *stack) values() []int { + return []int(*s) } -type dictionary map[string][]func(stacker) error +type word func(*stack) error + +type dictionary map[string][]word -func (d dictionary) find(name string) ([]func(stacker) error, bool) { - fs, ok := d[strings.ToLower(name)] - return fs, ok +func (d dictionary) find(name string) ([]word, bool) { + words, ok := d[strings.ToLower(name)] + return words, ok } -func (d dictionary) add(name string, fs ...func(stacker) error) { - d[strings.ToLower(name)] = fs +func (d dictionary) add(name string, words ...word) { + d[strings.ToLower(name)] = words } -func add(s stacker) error { - tos, nos, err := pop2(s) +func add(s *stack) error { + tos, nos, err := s.pop2() if err != nil { return err } return s.push(nos + tos) } -func sub(s stacker) error { - tos, nos, err := pop2(s) +func sub(s *stack) error { + tos, nos, err := s.pop2() if err != nil { return err } return s.push(nos - tos) } -func mul(s stacker) error { - tos, nos, err := pop2(s) +func mul(s *stack) error { + tos, nos, err := s.pop2() if err != nil { return err } return s.push(nos * tos) } -func div(s stacker) error { - tos, nos, err := pop2(s) +func div(s *stack) error { + tos, nos, err := s.pop2() if err != nil { return err } @@ -101,43 +88,43 @@ func div(s stacker) error { return s.push(nos / tos) } -func dup(s stacker) error { +func dup(s *stack) error { tos, err := s.pop() if err != nil { return err } - return pushN(s, tos, tos) + return s.push(tos, tos) } -func drop(s stacker) error { +func drop(s *stack) error { _, err := s.pop() return err } -func swap(s stacker) error { - tos, nos, err := pop2(s) +func swap(s *stack) error { + tos, nos, err := s.pop2() if err != nil { return err } - return pushN(s, tos, nos) + return s.push(tos, nos) } -func over(s stacker) error { - tos, nos, err := pop2(s) +func over(s *stack) error { + tos, nos, err := s.pop2() if err != nil { return err } - return pushN(s, nos, tos, nos) + return s.push(nos, tos, nos) } -func literal(n int) func(stacker) error { - return func(s stacker) error { +func literal(n int) word { + return func(s *stack) error { return s.push(n) } } -func number(word string) (int, bool) { - n, err := strconv.Atoi(word) +func number(s string) (int, bool) { + n, err := strconv.Atoi(s) return n, err == nil } @@ -157,8 +144,8 @@ func colon(dict dictionary, l *lexer) error { return nil } -func compile(dict dictionary, l *lexer) ([]func(stacker) error, error) { - var words []func(stacker) error +func compile(dict dictionary, l *lexer) ([]word, error) { + var words []word for { v, err := l.Next() if err == io.EOF { @@ -207,7 +194,6 @@ func (l *lexer) Next() (string, error) { } func Forth(v []string) ([]int, error) { - s := new(stack) dict := make(dictionary) dict.add("+", add) dict.add("-", sub) @@ -217,8 +203,7 @@ func Forth(v []string) ([]int, error) { dict.add("drop", drop) dict.add("swap", swap) dict.add("over", over) - - var words []func(stacker) error + var words []word for _, line := range v { l := NewLexer(line) w, err := compile(dict, l) @@ -227,6 +212,7 @@ func Forth(v []string) ([]int, error) { } words = append(words, w...) } + s := new(stack) for _, w := range words { if err := w(s); err != nil { return nil, err -- cgit v1.2.3