UNPKG

cookeylang-ts

Version:
59 lines (58 loc) 2.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Environment = void 0; const errors_1 = require("./errors"); const token_1 = require("./token"); class Environment { constructor(parent = null) { this.values = new Map(); this.parent = parent; } define(mut, key, val) { if (this.values.has(key.value)) throw new errors_1.CookeyError(key, `${key.value} has already been defined.`); this.values.set(key.value, { mut: mut.type, val }); } get(name) { if (this.values.has(name.value)) return this.values.get(name.value); if (this.parent) return this.parent.get(name); throw new errors_1.CookeyError(name, `Undefined variable ${name.value}.`); } getAt(distance, name) { return this.baseEnv(distance).values.get(name); } getMut(name) { if (this.values.has(name.value)) return this.values.get(name.value).mut; return token_1.TType.VAR; } assign(name, val) { let mut = this.getMut(name); if (mut == token_1.TType.FINAL) throw new errors_1.CookeyError(name, `Assignment to constant variable ${name.value}.`); if (this.values.has(name.value)) { this.values.set(name.value, { mut, val }); return; } if (this.parent) { this.parent.assign(name, val); return; } throw new errors_1.CookeyError(name, `Undefined variable ${name.value}.`); } assignAt(distance, name, val) { let env = this.baseEnv(distance); let mut = env.values.get(name.value).mut; this.baseEnv(distance).values.set(name.value, { mut, val }); } baseEnv(distance) { let env = this; for (let i = 0; i < distance; i++) { env = env.parent; } return env; } } exports.Environment = Environment;