tlang-interperter-cs/ScopeEnvironment.cs

139 lines
3.6 KiB
C#
Raw Normal View History

2023-03-09 19:40:14 +00:00
using System.Collections;
using System.Diagnostics.CodeAnalysis;
namespace tlang
{
public interface IScopeEnvironment : IEnumerable<KeyValuePair<string,TObject>>
{
bool VariableExists(string name);
void SetVariable(string name,TObject obj);
TObject GetVariable(string names);
IScopeEnvironment SubEnv {get;}
IScopeEnvironment RootEnv {get;}
TObject this[string variable] {get;set;}
}
public class SubEnvironment : IScopeEnvironment
{
Dictionary<string,TObject> items = new Dictionary<string, TObject>();
IScopeEnvironment root;
IScopeEnvironment parent;
public SubEnvironment(IScopeEnvironment root,IScopeEnvironment parent)
{
this.root=root;
this.parent = parent;
}
public TObject this[string variable] { get => GetVariable(variable); set => SetVariable(variable,value); }
public IScopeEnvironment SubEnv => new SubEnvironment(root,this);
public IScopeEnvironment RootEnv => root;
public IEnumerator<KeyValuePair<string, TObject>> GetEnumerator()
{
return getVars().GetEnumerator();
}
private IEnumerable<KeyValuePair<string,TObject>> getVars()
{
foreach(var v in parent)
{
yield return v;
}
foreach(var item in items)
{
yield return item;
}
}
public TObject GetVariable(string name)
{
if(parent.VariableExists(name))
{
return parent[name];
}
if(items.ContainsKey(name))
{
return items[name];
}
return TObject.Uninit;
}
public void SetVariable(string name, TObject obj)
{
if(parent.VariableExists(name))
{
parent.SetVariable(name,obj);
}else if(items.ContainsKey(name))
{
items[name] = obj;
}else{
items.Add(name,obj);
}
}
public bool VariableExists(string name)
{
if(parent.VariableExists(name)) return true;
return items.ContainsKey(name);
}
IEnumerator IEnumerable.GetEnumerator()
{
return getVars().GetEnumerator();
}
}
public class RootEnvironment : IScopeEnvironment
{
Dictionary<string,TObject> items = new Dictionary<string, TObject>();
public IScopeEnvironment SubEnv => new SubEnvironment(this,this);
public IScopeEnvironment RootEnv => this;
public IEnumerator<KeyValuePair<string, TObject>> GetEnumerator()
{
return items.GetEnumerator();
}
public TObject GetVariable(string name)
{
if(items.ContainsKey(name))
{
return items[name];
}else{
return TObject.Uninit;
}
}
public void SetVariable(string name, TObject obj)
{
if(items.ContainsKey(name))
{
items[name] = obj;
}
else
{
items.Add(name,obj);
}
}
public bool VariableExists(string name)
{
return items.ContainsKey(name);
}
IEnumerator IEnumerable.GetEnumerator()
{
return items.GetEnumerator();
}
public TObject this[string variable] { get => GetVariable(variable); set => SetVariable(variable,value); }
}
}