import { UnknownSymbolError, InvalidType } from '@/utils'; import type { Denotable, DenotableFunction, DenotableFunctionSignature, DenotableType, DenotableValue, } from '.'; export class Environment { private scope: Map; private parent: Environment | null; constructor(parent: Environment | null = null) { this.parent = parent; this.scope = new Map(); } public set(name: string, value: Denotable) { this.scope.set(name, value); } public get(name: string): Denotable { if (this.scope.has(name)) { return this.scope.get(name)!; } if (this.parent) { return this.parent.get(name); } throw new UnknownSymbolError(`Undefined variable: ${name}`); } public has(name: string): boolean { if (this.scope.has(name)) { return true; } if (this.parent) { return this.parent.has(name); } return false; } public createChild(): Environment { return new Environment(this); } public apply(name: string, args: Denotable[]): Denotable { const fn = this.get(name); if (typeof fn.value !== 'object' || !fn.value || !('body' in fn.value)) { throw new InvalidType(name + ' is not a valid function'); } return { type: 'real', value: 0 }; } }