Skip to content

Commit 1b4ad9d

Browse files
committed
Add Interpreter pattern
1 parent a3b0037 commit 1b4ad9d

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

source/behavioral/interpreter.swift

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*:
2+
🎶 Interpreter
3+
--------------
4+
5+
The interpreter pattern is used to evaluate sentences in a language.
6+
7+
### Example
8+
*/
9+
10+
protocol IntegerExp {
11+
func evaluate(context: IntegerContext) -> Int
12+
func replace(character: Character, integerExp: IntegerExp) -> IntegerExp
13+
func copy() -> IntegerExp
14+
}
15+
16+
class IntegerContext {
17+
private var data: [Character:Int] = [:]
18+
19+
func lookup(name: Character) -> Int {
20+
return self.data[name]!
21+
}
22+
23+
func assign(integerVarExp: IntegerVarExp, value: Int) {
24+
self.data[integerVarExp.name] = value
25+
}
26+
}
27+
28+
class IntegerVarExp: IntegerExp {
29+
let name: Character
30+
31+
init(name: Character) {
32+
self.name = name
33+
}
34+
35+
func evaluate(context: IntegerContext) -> Int {
36+
return context.lookup(self.name)
37+
}
38+
39+
func replace(name: Character, integerExp: IntegerExp) -> IntegerExp {
40+
if name == self.name {
41+
return integerExp.copy()
42+
} else {
43+
return IntegerVarExp(name: self.name)
44+
}
45+
}
46+
47+
func copy() -> IntegerExp {
48+
return IntegerVarExp(name: self.name)
49+
}
50+
}
51+
52+
class AddExp: IntegerExp {
53+
private var operand1: IntegerExp
54+
private var operand2: IntegerExp
55+
56+
init(op1: IntegerExp, op2: IntegerExp) {
57+
self.operand1 = op1
58+
self.operand2 = op2
59+
}
60+
61+
func evaluate(context: IntegerContext) -> Int {
62+
return self.operand1.evaluate(context) + self.operand2.evaluate(context)
63+
}
64+
65+
func replace(character: Character, integerExp: IntegerExp) -> IntegerExp {
66+
return AddExp(op1: operand1.replace(character, integerExp: integerExp),
67+
op2: operand2.replace(character, integerExp: integerExp))
68+
}
69+
70+
func copy() -> IntegerExp {
71+
return AddExp(op1: self.operand1, op2: self.operand2)
72+
}
73+
}
74+
/*:
75+
### Usage
76+
*/
77+
var expression: IntegerExp?
78+
var context = IntegerContext()
79+
80+
var a = IntegerVarExp(name: "A")
81+
var b = IntegerVarExp(name: "B")
82+
var c = IntegerVarExp(name: "C")
83+
84+
expression = AddExp(op1: a, op2: AddExp(op1: b, op2: c)) // a + (b + c)
85+
86+
context.assign(a, value: 2)
87+
context.assign(b, value: 1)
88+
context.assign(c, value: 3)
89+
90+
var result = expression?.evaluate(context)

0 commit comments

Comments
 (0)