mirror of
https://github.com/kanaka/mal.git
synced 2024-09-21 02:27:10 +03:00
8a19f60386
- Reorder README to have implementation list after "learning tool" bullet. - This also moves tests/ and libs/ into impls. It would be preferrable to have these directories at the top level. However, this causes difficulties with the wasm implementations which need pre-open directories and have trouble with paths starting with "../../". So in lieu of that, symlink those directories to the top-level. - Move the run_argv_test.sh script into the tests directory for general hygiene.
49 lines
1.1 KiB
TypeScript
49 lines
1.1 KiB
TypeScript
import { MalType, MalSymbol, MalList } from "./types";
|
|
|
|
export class Env {
|
|
data: Map<MalSymbol, MalType>;
|
|
|
|
constructor(public outer?: Env, binds: MalSymbol[] = [], exprts: MalType[] = []) {
|
|
this.data = new Map();
|
|
|
|
for (let i = 0; i < binds.length; i++) {
|
|
const bind = binds[i];
|
|
if (bind.v === "&") {
|
|
this.set(binds[i + 1], new MalList(exprts.slice(i)));
|
|
break;
|
|
}
|
|
this.set(bind, exprts[i]);
|
|
}
|
|
}
|
|
|
|
set(key: MalSymbol, value: MalType): MalType {
|
|
this.data.set(key, value);
|
|
return value;
|
|
}
|
|
|
|
find(key: MalSymbol): Env | undefined {
|
|
if (this.data.has(key)) {
|
|
return this;
|
|
}
|
|
if (this.outer) {
|
|
return this.outer.find(key);
|
|
}
|
|
|
|
return void 0;
|
|
}
|
|
|
|
get(key: MalSymbol): MalType {
|
|
const env = this.find(key);
|
|
if (!env) {
|
|
throw new Error(`'${key.v}' not found`);
|
|
}
|
|
|
|
const v = env.data.get(key);
|
|
if (!v) {
|
|
throw new Error(`'${key.v}' not found`);
|
|
}
|
|
|
|
return v;
|
|
}
|
|
}
|