summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2018-09-22 20:37:22 +0200
committerDimitri Sokolyuk <demon@dim13.org>2018-09-22 20:37:22 +0200
commit3083cf2e33daa94af7fc8ee89fe82501cc878782 (patch)
treeb6df6e5ff02b6b547400bc30eb503acafa7dea73
parented154369ee1e9de3b43ce6a5be77d42b873175c7 (diff)
...
-rw-r--r--go/forth/forth.go90
1 files 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