Upsilon/Upsilon/Binder/BoundScope.cs

76 lines
2.1 KiB
C#

using System;
using System.Collections.Generic;
using Upsilon.Binder.VariableSymbols;
using Type = Upsilon.BaseTypes.Type;
namespace Upsilon.Binder
{
public class BoundScope : IDisposable
{
public readonly BoundScope ParentScope;
public BoundScope ReadOnlyScope { get; private set; }
public readonly Dictionary<string, VariableSymbol> Variables;
public Type ReturnType { get; set; } = Type.Nil;
public BoundScope(BoundScope parentScope)
{
ParentScope = parentScope;
Variables = new Dictionary<string, VariableSymbol>();
}
public BoundScope(Dictionary<string, VariableSymbol> variables, BoundScope parentScope)
{
ParentScope = parentScope;
Variables = variables;
}
public static BoundScope WithReadOnlyScope(BoundScope readOnlyScope)
{
var scope = new BoundScope(null) {ReadOnlyScope = readOnlyScope};
return scope;
}
public void Dispose()
{
//Variables.Clear();
}
public void DefineLocalVariable(VariableSymbol var)
{
Variables.Add(var.Name, var);
}
public void AssignToNearest(VariableSymbol var)
{
if (Variables.ContainsKey(var.Name))
{
}
else if (ParentScope != null)
{
ParentScope.AssignToNearest(var);
}
else
{
Variables.Add(var.Name, var);
}
}
public bool TryGetVariable(string key, bool allowUpperScopes, out VariableSymbol result)
{
if (Variables.TryGetValue(key, out result))
{
return true;
}
if (ParentScope != null && allowUpperScopes)
{
return ParentScope.TryGetVariable(key, true, out result);
}
if (ReadOnlyScope != null && allowUpperScopes)
{
return ReadOnlyScope.TryGetVariable(key, true, out result);
}
return false;
}
}
}