Upsilon/Upsilon/Evaluator/EvaluationScope.cs

102 lines
3.1 KiB
C#

using System.Collections.Generic;
using Upsilon.BaseTypes;
using Upsilon.Binder;
namespace Upsilon.Evaluator
{
internal class EvaluationScope
{
private readonly EvaluationScope _parentScope;
private EvaluationScope _getOnlyParentScope;
internal readonly Dictionary<string, LuaType> Variables;
internal readonly Dictionary<string, LuaType> LocalVariables;
internal EvaluationScope(EvaluationScope parentScope)
{
_parentScope = parentScope;
Variables = new Dictionary<string, LuaType>();
LocalVariables = new Dictionary<string, LuaType>();
}
internal EvaluationScope(Dictionary<string, LuaType> vars)
{
Variables = vars;
LocalVariables = new Dictionary<string, LuaType>();
}
internal static EvaluationScope CreateWithGetOnlyParent(EvaluationScope parent)
{
var scope = new EvaluationScope(new Dictionary<string, LuaType>()) {_getOnlyParentScope = parent};
return scope;
}
public void Set(VariableSymbol symbol, LuaType obj)
{
if (symbol.Local)
{
if (LocalVariables.ContainsKey(symbol.Name))
{
LocalVariables[symbol.Name] = obj;
}
else
{
LocalVariables.Add(symbol.Name, obj);
}
}
else
{
if (Variables.ContainsKey(symbol.Name))
{
Variables[symbol.Name] = obj;
}
else
{
Variables.Add(symbol.Name, obj);
}
}
}
public void SetGlobal(VariableSymbol symbol, LuaType obj)
{
if (_parentScope != null)
_parentScope.SetGlobal(symbol, obj);
else
{
Set(symbol, obj);
}
}
public bool TryGet(VariableSymbol symbol, out LuaType obj)
{
if (LocalVariables.TryGetValue(symbol.Name, out obj))
return true;
if (Variables.TryGetValue(symbol.Name, out obj))
return true;
if (_parentScope != null)
if (_parentScope.TryGet(symbol, out obj))
return true;
if (_getOnlyParentScope != null)
if (_getOnlyParentScope.TryGet(symbol, out obj))
return true;
return false;
}
public bool TryGet(string variable, out LuaType obj)
{
if (LocalVariables.TryGetValue(variable, out obj))
return true;
if (Variables.TryGetValue(variable, out obj))
return true;
if (_parentScope != null)
if (_parentScope.TryGet(variable, out obj))
return true;
if (_getOnlyParentScope != null)
if (_getOnlyParentScope.TryGet(variable, out obj))
return true;
return false;
}
}
}