Fix Binder not allowing setting variables due to parent scope

This commit is contained in:
Deukhoofd 2018-11-19 14:45:20 +01:00
parent c4962ac24c
commit f4ae57c550
No known key found for this signature in database
GPG Key ID: B4C087AC81641654
3 changed files with 39 additions and 12 deletions

View File

@ -398,7 +398,8 @@ namespace Upsilon.Binder
var valueType = Type.Unknown;
var dictionary = new Dictionary<string, bool>();
var statements = ImmutableArray.CreateBuilder<BoundStatement>();
Scope = new BoundScope(Scope);
var s = Scope;
Scope = BoundScope.WithReadOnlyScope(s);
foreach (var expressionSyntax in e.Expressions)
{
var bound = BindStatement((StatementSyntax) expressionSyntax);
@ -409,7 +410,7 @@ namespace Upsilon.Binder
{
dictionary.Add(variable.Key, true);
}
Scope = Scope.ParentScope;
Scope = s;
return new BoundTableExpression(keyType, valueType, dictionary, statements);
}

View File

@ -1,33 +1,51 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Upsilon.BaseTypes;
namespace Upsilon.Binder
{
internal class BoundScope
{
public readonly BoundScope ParentScope;
private BoundScope _readOnlyScope;
internal readonly Dictionary<string, VariableSymbol> Variables;
internal readonly Dictionary<string, VariableSymbol> LocalVariables;
public BoundScope(BoundScope parentScope)
{
ParentScope = parentScope;
Variables = new Dictionary<string, VariableSymbol>();
LocalVariables = new Dictionary<string, VariableSymbol>();
}
public BoundScope(Dictionary<string, VariableSymbol> variables, BoundScope parentScope)
{
ParentScope = parentScope;
Variables = variables;
LocalVariables = new Dictionary<string, VariableSymbol>();
}
public static BoundScope WithReadOnlyScope(BoundScope readOnlyScope)
{
var scope = new BoundScope(null) {_readOnlyScope = readOnlyScope};
return scope;
}
public void SetVariable(VariableSymbol var)
{
if (var.Local)
{
if (LocalVariables.ContainsKey(var.Name))
LocalVariables[var.Name] = var;
else
LocalVariables.Add(var.Name, var);
}
else
{
if (Variables.ContainsKey(var.Name))
Variables[var.Name] = var;
else
Variables.Add(var.Name, var);
}
}
public void SetGlobalVariable(VariableSymbol var)
{
@ -44,6 +62,10 @@ namespace Upsilon.Binder
public bool TryGetVariable(string key, bool allowUpperScopes, out VariableSymbol result)
{
if (LocalVariables.TryGetValue(key, out result))
{
return true;
}
if (Variables.TryGetValue(key, out result))
{
return true;
@ -52,6 +74,10 @@ namespace Upsilon.Binder
{
return ParentScope.TryGetVariable(key, true, out result);
}
if (_readOnlyScope != null && allowUpperScopes)
{
return _readOnlyScope.TryGetVariable(key, true, out result);
}
return false;
}

View File

@ -71,10 +71,10 @@ namespace Upsilon.Evaluator
public bool TryGet(VariableSymbol symbol, out LuaType obj)
{
if (Variables.TryGetValue(symbol.Name, out obj))
return true;
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;
@ -86,10 +86,10 @@ namespace Upsilon.Evaluator
public bool TryGet(string variable, out LuaType obj)
{
if (Variables.TryGetValue(variable, out obj))
return true;
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;