2024-01-26 05:37:51 +00:00
|
|
|
namespace KumiScript.Interpreter
|
|
|
|
{
|
|
|
|
public class Environment
|
|
|
|
{
|
|
|
|
readonly Environment? _outer;
|
|
|
|
readonly Dictionary<Symbol, Expression> _bindings;
|
|
|
|
public Environment()
|
|
|
|
{
|
2024-07-12 00:17:00 +00:00
|
|
|
_bindings = new Dictionary<Symbol, Expression>(ReferenceEqualityComparer.Instance);
|
2024-01-26 05:37:51 +00:00
|
|
|
}
|
|
|
|
public Environment(Environment outer)
|
|
|
|
{
|
2024-07-12 00:17:00 +00:00
|
|
|
_bindings = new Dictionary<Symbol, Expression>(ReferenceEqualityComparer.Instance);
|
2024-01-26 05:37:51 +00:00
|
|
|
_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))
|
|
|
|
{
|
2024-07-12 00:17:00 +00:00
|
|
|
_bindings[symbol] = value;
|
2024-01-26 05:37:51 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (_outer is null)
|
|
|
|
throw new InterpreterUnboundSymbolException(symbol.ToString());
|
|
|
|
|
|
|
|
_outer.RedefineSymbol(symbol, value);
|
|
|
|
}
|
|
|
|
}
|
2024-07-12 00:17:00 +00:00
|
|
|
}
|