Upsilon/Upsilon/Evaluator/EvaluationScope.cs

110 lines
3.5 KiB
C#
Raw Normal View History

2018-11-14 15:39:52 +00:00
using System.Collections.Generic;
using Upsilon.BaseTypes;
using Upsilon.Binder;
namespace Upsilon.Evaluator
{
2018-11-23 11:55:28 +00:00
public class EvaluationScope
2018-11-14 15:39:52 +00:00
{
2018-11-16 12:55:31 +00:00
private readonly EvaluationScope _parentScope;
2018-11-19 11:17:21 +00:00
private EvaluationScope _getOnlyParentScope;
2018-11-23 17:18:07 +00:00
public readonly Dictionary<string, ScriptType> Variables;
private readonly Dictionary<string, ScriptType> _localVariables;
2018-11-14 15:39:52 +00:00
2018-11-18 13:18:24 +00:00
2018-11-14 15:39:52 +00:00
internal EvaluationScope(EvaluationScope parentScope)
{
2018-11-16 12:55:31 +00:00
_parentScope = parentScope;
2018-11-23 17:18:07 +00:00
Variables = new Dictionary<string, ScriptType>();
_localVariables = new Dictionary<string, ScriptType>();
2018-11-14 15:39:52 +00:00
}
2018-11-19 11:17:21 +00:00
2018-11-23 17:18:07 +00:00
internal EvaluationScope(Dictionary<string, ScriptType> vars)
2018-11-14 15:39:52 +00:00
{
Variables = vars;
2018-11-23 17:18:07 +00:00
_localVariables = new Dictionary<string, ScriptType>();
2018-11-14 15:39:52 +00:00
}
2018-11-19 11:17:21 +00:00
internal static EvaluationScope CreateWithGetOnlyParent(EvaluationScope parent)
{
2018-11-23 17:18:07 +00:00
var scope = new EvaluationScope(new Dictionary<string, ScriptType>()) {_getOnlyParentScope = parent};
2018-11-19 11:17:21 +00:00
return scope;
}
2018-11-23 17:18:07 +00:00
public void Set(VariableSymbol symbol, ScriptType obj, bool createNew)
2018-11-14 15:39:52 +00:00
{
2018-11-23 17:18:07 +00:00
if (symbol.Local && createNew)
2018-11-14 15:39:52 +00:00
{
2018-11-23 11:55:28 +00:00
if (_localVariables.ContainsKey(symbol.Name))
2018-11-19 11:49:48 +00:00
{
2018-11-23 11:55:28 +00:00
_localVariables[symbol.Name] = obj;
2018-11-19 11:49:48 +00:00
}
else
{
2018-11-23 11:55:28 +00:00
_localVariables.Add(symbol.Name, obj);
2018-11-19 11:49:48 +00:00
}
2018-11-14 15:39:52 +00:00
}
else
{
2018-11-19 11:49:48 +00:00
if (Variables.ContainsKey(symbol.Name))
{
Variables[symbol.Name] = obj;
}
2018-11-23 17:18:07 +00:00
else if (_localVariables.ContainsKey(symbol.Name))
{
_localVariables[symbol.Name] = obj;
}
else if (_parentScope != null && _parentScope.TryGet(symbol.Name, out _))
{
_parentScope.Set(symbol, obj, false);
}
2018-11-19 11:49:48 +00:00
else
{
Variables.Add(symbol.Name, obj);
}
2018-11-14 15:39:52 +00:00
}
}
2018-11-23 17:18:07 +00:00
public void SetGlobal(VariableSymbol symbol, ScriptType obj)
2018-11-14 15:39:52 +00:00
{
2018-11-16 12:55:31 +00:00
if (_parentScope != null)
_parentScope.SetGlobal(symbol, obj);
2018-11-14 15:39:52 +00:00
else
{
2018-11-23 17:18:07 +00:00
Set(symbol, obj, true);
2018-11-14 15:39:52 +00:00
}
}
2018-11-23 17:18:07 +00:00
public bool TryGet(VariableSymbol symbol, out ScriptType obj)
2018-11-14 15:39:52 +00:00
{
2018-11-23 11:55:28 +00:00
if (_localVariables.TryGetValue(symbol.Name, out obj))
2018-11-14 15:39:52 +00:00
return true;
if (Variables.TryGetValue(symbol.Name, out obj))
return true;
2018-11-16 12:55:31 +00:00
if (_parentScope != null)
if (_parentScope.TryGet(symbol, out obj))
2018-11-14 15:39:52 +00:00
return true;
2018-11-19 11:17:21 +00:00
if (_getOnlyParentScope != null)
if (_getOnlyParentScope.TryGet(symbol, out obj))
return true;
2018-11-14 15:39:52 +00:00
return false;
}
2018-11-23 17:18:07 +00:00
public bool TryGet(string variable, out ScriptType obj)
{
2018-11-23 11:55:28 +00:00
if (_localVariables.TryGetValue(variable, out obj))
2018-11-19 11:49:48 +00:00
return true;
if (Variables.TryGetValue(variable, out obj))
return true;
2018-11-16 12:55:31 +00:00
if (_parentScope != null)
if (_parentScope.TryGet(variable, out obj))
return true;
2018-11-19 11:49:48 +00:00
if (_getOnlyParentScope != null)
if (_getOnlyParentScope.TryGet(variable, out obj))
return true;
return false;
}
2018-11-14 15:39:52 +00:00
}
}