From 77efe0fa4e9c6c485421cc7950c9853e30faab49 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sun, 23 Sep 2018 07:21:57 +0200 Subject: collect errors --- go/forth/forth.go | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/go/forth/forth.go b/go/forth/forth.go index e9a32da..9bfba42 100644 --- a/go/forth/forth.go +++ b/go/forth/forth.go @@ -2,11 +2,18 @@ package forth import ( "errors" - "io" "strconv" "strings" ) +var ( + ErrEOL = errors.New("end of line") + ErrStack = errors.New("stack underflow") + ErrZero = errors.New("division by zero") + ErrWord = errors.New("name cannot be a number") + ErrUnknown = errors.New("unknown word") +) + type stack []int func (s *stack) push(n ...int) error { @@ -17,7 +24,7 @@ func (s *stack) push(n ...int) error { func (s *stack) pop() (int, error) { depth := len(*s) if depth < 1 { - return 0, errors.New("stack underflow") + return 0, ErrStack } tos := (*s)[depth-1] *s = (*s)[:depth-1] @@ -83,7 +90,7 @@ func div(s *stack) error { return err } if tos == 0 { - return errors.New("division by zero") + return ErrZero } return s.push(nos / tos) } @@ -134,7 +141,7 @@ func colon(dict dictionary, l *lexer) error { return err } if _, ok := number(name); ok { - return errors.New("name cannot be a number") + return ErrWord } w, err := compile(dict, l) if err != nil { @@ -148,7 +155,7 @@ func compile(dict dictionary, l *lexer) ([]word, error) { var words []word for { v, err := l.Next() - if err == io.EOF { + if err == ErrEOL { return words, nil } // colon operator @@ -171,7 +178,7 @@ func compile(dict dictionary, l *lexer) ([]word, error) { words = append(words, literal(n)) continue } - return nil, errors.New("unknown word") + return nil, ErrUnknown } } @@ -186,7 +193,7 @@ func NewLexer(line string) *lexer { func (l *lexer) Next() (string, error) { if l.pos >= len(l.fields) { - return "", io.EOF + return "", ErrEOL } s := l.fields[l.pos] l.pos++ @@ -203,19 +210,18 @@ func Forth(v []string) ([]int, error) { dict.add("drop", drop) dict.add("swap", swap) dict.add("over", over) - var words []word + s := new(stack) for _, line := range v { - l := NewLexer(line) - w, err := compile(dict, l) + // compile + words, err := compile(dict, NewLexer(line)) if err != nil { return nil, err } - words = append(words, w...) - } - s := new(stack) - for _, w := range words { - if err := w(s); err != nil { - return nil, err + // execute + for _, w := range words { + if err := w(s); err != nil { + return nil, err + } } } return s.values(), nil -- cgit v1.2.3