Skip to content

Commit d6d493b

Browse files
committed
add interpreter pattern
1 parent 19fbd35 commit d6d493b

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

behavioral/interpreter/README.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Behavioral » Interpreter
2+
3+
## Description
4+
5+
The interpreter design pattern is used to solve business cases where it's
6+
useful to have a language to perform common operations. The most famous
7+
intepreter we can talk about is probably SQL.
8+
9+
## Implementation
10+
11+
The implementation is trivial. In the following examples I'll show a very
12+
simple usage of interpreter. In this case we use interpreter to calculate some
13+
mathematical operations. For example the sum and the multiplication operations.
14+
15+
```go
16+
func TestSumOperator(t *testing.T) {
17+
sentence := "5 + 3"
18+
i := interpreter{}
19+
_ = i.of(sentence)
20+
if i.exec() != 8 {
21+
t.Error([]string{
22+
"La somma di 5 con 3",
23+
"non dovrebbe essere",
24+
strconv.Itoa(i.exec()),
25+
})
26+
}
27+
}
28+
```
29+
30+
As you can see, given a sentence like `5 + 3` parsed, it is possible to exec
31+
the string and calculate the result.
32+
33+
```go
34+
func TestMulOperator(t *testing.T) {
35+
sentence := "5 * 3"
36+
i := interpreter{}
37+
_ = i.of(sentence)
38+
if i.exec() != 15 {
39+
t.Error([]string{
40+
"Multiplication between 5 and 3",
41+
"shouldnt be",
42+
strconv.Itoa(i.exec()),
43+
})
44+
}
45+
}
46+
```

behavioral/interpreter/interpreter.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"strconv"
7+
"strings"
8+
)
9+
10+
type interpreter struct {
11+
sentence string
12+
}
13+
14+
func (i *interpreter) tokens() []string {
15+
return strings.Split(i.sentence, " ")
16+
}
17+
18+
func (i *interpreter) exec() int {
19+
sum := 0
20+
tokens := i.tokens()
21+
for k, item := range tokens {
22+
if item == "*" {
23+
fmt.Println(i.tokens())
24+
a, _ := strconv.Atoi(string(tokens[k-1]))
25+
b, _ := strconv.Atoi(string(tokens[k+1]))
26+
return a * b
27+
}
28+
29+
if item != "+" {
30+
number, _ := strconv.Atoi(item)
31+
sum += number
32+
}
33+
}
34+
return sum
35+
}
36+
37+
func (i *interpreter) contains(s string) bool {
38+
return true
39+
}
40+
41+
func (i *interpreter) of(s string) error {
42+
if s == "normal" {
43+
return errors.New("non va")
44+
}
45+
i.sentence = s
46+
return nil
47+
}
48+
49+
func (i *interpreter) numberOfWords() int {
50+
s := i.tokens()
51+
return len(s)
52+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package main
2+
3+
import (
4+
"strconv"
5+
"testing"
6+
)
7+
8+
func TestNodesCantBeNormalString(t *testing.T) {
9+
sentence := "normal"
10+
i := interpreter{}
11+
err := i.of(sentence)
12+
if err == nil {
13+
t.Error("Si doveva spaccare")
14+
}
15+
}
16+
17+
func TestFoo(t *testing.T) {
18+
sentence := "do something"
19+
i := interpreter{}
20+
_ = i.of(sentence)
21+
if i.numberOfWords() != 2 {
22+
t.Error("Guarda che ti stai sbagliando")
23+
}
24+
}
25+
26+
const (
27+
PLUS = "+"
28+
)
29+
30+
func TestPlusOperatorDetector(t *testing.T) {
31+
sentence := "2 + 3"
32+
i := interpreter{}
33+
_ = i.of(sentence)
34+
if i.contains(PLUS) != true {
35+
t.Error("dovrebbe conoscere l'operatore +")
36+
}
37+
}
38+
39+
func TestSplitSentencesInSplice(t *testing.T) {
40+
sentence := "2 + 3"
41+
i := interpreter{}
42+
_ = i.of(sentence)
43+
expected := []string{"2", "+", "3"}
44+
for ind, _ := range expected {
45+
tok := i.tokens()
46+
if expected[ind] != tok[ind] {
47+
t.Error("non ci siamo")
48+
}
49+
}
50+
}
51+
52+
func TestCountNumberOfOperators(t *testing.T) {
53+
sentence := "2 + 3"
54+
i := interpreter{}
55+
_ = i.of(sentence)
56+
expected := []string{"2", "+", "3"}
57+
for ind, _ := range expected {
58+
tok := i.tokens()
59+
if expected[ind] != tok[ind] {
60+
t.Error("non ci siamo")
61+
}
62+
}
63+
}
64+
65+
func TestExec(t *testing.T) {
66+
sentence := "5 + 3"
67+
i := interpreter{}
68+
_ = i.of(sentence)
69+
if i.exec() != 8 {
70+
t.Error([]string{
71+
"La somma di 5 con 3",
72+
"non dovrebbe essere",
73+
strconv.Itoa(i.exec()),
74+
})
75+
}
76+
}
77+
78+
func TestMulOperator(t *testing.T) {
79+
sentence := "5 * 3"
80+
i := interpreter{}
81+
_ = i.of(sentence)
82+
if i.exec() != 15 {
83+
t.Error([]string{
84+
"Multiplication between 5 and 3",
85+
"shouldnt be",
86+
strconv.Itoa(i.exec()),
87+
})
88+
}
89+
}

0 commit comments

Comments
 (0)