namespace KumiScript.Interpreter { public class Environment { readonly Environment? _outer; readonly Dictionary _bindings; public Environment() { _bindings = new Dictionary(ReferenceEqualityComparer.Instance); } public Environment(Environment outer) { _bindings = new Dictionary(ReferenceEqualityComparer.Instance); _outer = outer; } public Expression Lookup(Symbol symbol) { Expression? result; _bindings.TryGetValue(symbol, out result); if (result is not null) return result; if (_outer is null) throw new InterpreterUnboundSymbolException(); return _outer.Lookup(symbol); } public void AddSymbol(Symbol symbol, Expression value) { _bindings.Add(symbol, value); return; } public void RedefineSymbol(Symbol symbol, Expression value) { if (_bindings.ContainsKey(symbol)) { _bindings[symbol] = value; return; } if (_outer is null) throw new InterpreterUnboundSymbolException(symbol.ToString()); _outer.RedefineSymbol(symbol, value); } } }