cookeylang-ts
Version:
A dynamic, interpreted language.
59 lines (58 loc) • 2.01 kB
JavaScript
"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;