-
Notifications
You must be signed in to change notification settings - Fork 0
/
environment.ts
55 lines (49 loc) · 2.1 KB
/
environment.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
import { LispSymbol, LispAtom, LispNumber, LispList } from "./interpreter";
export class LispEnvironment extends Map {
public outerEnvironment: LispEnvironment;
constructor(paramDefinitions?: LispSymbol[],
argsValues?: LispAtom[],
outerEnvironment?: LispEnvironment) {
super();
this.addStandardEnv();
if (outerEnvironment) {
this.outerEnvironment = outerEnvironment;
}
if (paramDefinitions && paramDefinitions?.length > 0
&& argsValues && argsValues.length === paramDefinitions.length) {
this.addArgsToEnv(paramDefinitions, argsValues)
}
}
private addArgsToEnv(
paramDefinitions: LispSymbol[],
argsValues: LispAtom[]) {
for (let index = 0; index < paramDefinitions.length; index++) {
const param = paramDefinitions[index];
const arg = argsValues[index];
this.set(param, arg);
}
}
private addStandardEnv() {
this.set("+", (a: LispNumber, b: LispNumber) => a + b);
this.set("-", (a: LispNumber, b: LispNumber) => a - b);
this.set("/", (a: LispNumber, b: LispNumber) => a / b);
this.set("*", (a: LispNumber, b: LispNumber) => a * b);
this.set("=", (a: LispNumber, b: LispNumber) => a === b);
this.set("<", (a: LispNumber, b: LispNumber) => a < b);
this.set(">", (a: LispNumber, b: LispNumber) => a > b);
this.set("<=", (a: LispNumber, b: LispNumber) => a <= b);
this.set(">=", (a: LispNumber, b: LispNumber) => a >= b);
this.set("cons", (a: LispAtom | LispList, b: LispAtom | LispList) => [a, b]);
this.set("car", (a: LispList) => a[0]);
this.set("cdr", (a: LispList) => a.slice(1));
}
public findEnvironment(variableName: LispSymbol): LispEnvironment {
if (this.get(variableName) !== undefined) {
return this
} else if (this.outerEnvironment) {
return this.outerEnvironment.findEnvironment(variableName);
} else {
throw new Error(`variable ${variableName} is not defined`);
}
}
}