-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexec.ts
36 lines (32 loc) · 1.04 KB
/
exec.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
import { Exp, Fn, List, Number, parse, Symbol, tokenize } from "./ast.ts";
import { Heap } from "./heap.ts";
const heap = new Heap();
export function exec(expression: Exp): Exp | undefined {
if (expression.kind === "symbol") {
return heap.getSymbol(expression as Symbol);
} else if (expression.kind === "number") {
return expression;
} else {
const list = (expression as List).val;
const first = list[0];
const symbol = (first as Symbol).val;
if (symbol === "if") {
const [_, test, conseq, alt] = list;
return exec(test) ? conseq : alt;
} else if (symbol === "define") {
const [_, symbol, exp] = list;
heap.setSymbol(symbol as Symbol, exec(exp)!);
} else {
const proc = exec(first);
const args = (list.slice(1)).map((arg) => exec(arg)!);
return callFn(proc as Fn, ...args);
}
}
}
export function callFn(fn: Exp, ...args: Exp[]): Exp {
return (fn as Fn).val(...args);
}
export function runSrc(source: string) {
const exp = parse(tokenize(source));
return exec(exp);
}