-
Notifications
You must be signed in to change notification settings - Fork 2
/
Interpreter.ts
85 lines (65 loc) · 2.31 KB
/
Interpreter.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
interface IntegerExpression {
evaluate(context: IntegerContext): number;
replace(character: string, integerExpression: IntegerExpression): IntegerExpression;
copied(): IntegerExpression;
}
class IntegerContext {
data: {[key: string]: number} = {};
lookup(name: string): number {
return this.data[name];
}
assign(expression: IntegerVariableExpression, value: number) {
this.data[expression.name] = value;
}
}
class IntegerVariableExpression implements IntegerExpression {
name: string;
constructor(name: string) {
this.name = name;
}
evaluate(context: IntegerContext): number {
return context.lookup(this.name);
}
replace(character: string, integerExpression: IntegerExpression): IntegerExpression {
return character === this.name ? integerExpression.copied() : new IntegerVariableExpression(this.name);
//****// OR:
// if (name === this.name) {
// return integerExpression.copied();
// } else {
// return new IntegerVariableExpression(this.name);
// }
}
copied(): IntegerExpression {
return new IntegerVariableExpression(this.name);
}
}
class AddExpression implements IntegerExpression {
#operand1: IntegerExpression;
#operand2: IntegerExpression;
constructor(opt1: IntegerExpression, opt2: IntegerExpression) {
this.#operand1 = opt1;
this.#operand2 = opt2;
}
evaluate(context: IntegerContext): number {
return this.#operand1.evaluate(context) + this.#operand2.evaluate(context);
}
replace(character: string, integerExpression: IntegerExpression): IntegerExpression {
return new AddExpression(this.#operand1.replace(character, integerExpression), this.#operand2.replace(character, integerExpression));
}
copied(): IntegerExpression {
return new AddExpression(this.#operand1, this.#operand2);
}
}
// USAGE:
let context = new IntegerContext();
let a = new IntegerVariableExpression("A");
let b = new IntegerVariableExpression("B");
let c = new IntegerVariableExpression("C");
let expression = new AddExpression(a, new AddExpression(b, c));
context.assign(a, 2);
context.assign(b, 1);
context.assign(c, 3);
const result = expression.evaluate(context);
console.log(result);
// OUTPUT:
//6