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
|
|
|
{
|
2018-11-17 12:05:08 +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;
|
2018-11-19 13:45:20 +00:00
|
|
|
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-14 16:04:04 +00:00
|
|
|
|
2018-11-23 17:18:07 +00:00
|
|
|
public bool TryGet(string variable, out ScriptType obj)
|
2018-11-14 16:04:04 +00:00
|
|
|
{
|
2018-11-23 11:55:28 +00:00
|
|
|
if (_localVariables.TryGetValue(variable, out obj))
|
2018-11-19 11:49:48 +00:00
|
|
|
return true;
|
2018-11-19 13:45:20 +00:00
|
|
|
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))
|
2018-11-14 16:04:04 +00:00
|
|
|
return true;
|
2018-11-19 11:49:48 +00:00
|
|
|
if (_getOnlyParentScope != null)
|
|
|
|
if (_getOnlyParentScope.TryGet(variable, out obj))
|
|
|
|
return true;
|
2018-11-14 16:04:04 +00:00
|
|
|
return false;
|
|
|
|
}
|
2018-11-14 15:39:52 +00:00
|
|
|
}
|
|
|
|
}
|