Fix Binder not allowing setting variables due to parent scope
This commit is contained in:
parent
c4962ac24c
commit
f4ae57c550
|
@ -398,7 +398,8 @@ namespace Upsilon.Binder
|
||||||
var valueType = Type.Unknown;
|
var valueType = Type.Unknown;
|
||||||
var dictionary = new Dictionary<string, bool>();
|
var dictionary = new Dictionary<string, bool>();
|
||||||
var statements = ImmutableArray.CreateBuilder<BoundStatement>();
|
var statements = ImmutableArray.CreateBuilder<BoundStatement>();
|
||||||
Scope = new BoundScope(Scope);
|
var s = Scope;
|
||||||
|
Scope = BoundScope.WithReadOnlyScope(s);
|
||||||
foreach (var expressionSyntax in e.Expressions)
|
foreach (var expressionSyntax in e.Expressions)
|
||||||
{
|
{
|
||||||
var bound = BindStatement((StatementSyntax) expressionSyntax);
|
var bound = BindStatement((StatementSyntax) expressionSyntax);
|
||||||
|
@ -409,7 +410,7 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
dictionary.Add(variable.Key, true);
|
dictionary.Add(variable.Key, true);
|
||||||
}
|
}
|
||||||
Scope = Scope.ParentScope;
|
Scope = s;
|
||||||
return new BoundTableExpression(keyType, valueType, dictionary, statements);
|
return new BoundTableExpression(keyType, valueType, dictionary, statements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,33 +1,51 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Upsilon.BaseTypes;
|
|
||||||
|
|
||||||
namespace Upsilon.Binder
|
namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
internal class BoundScope
|
internal class BoundScope
|
||||||
{
|
{
|
||||||
public readonly BoundScope ParentScope;
|
public readonly BoundScope ParentScope;
|
||||||
|
private BoundScope _readOnlyScope;
|
||||||
internal readonly Dictionary<string, VariableSymbol> Variables;
|
internal readonly Dictionary<string, VariableSymbol> Variables;
|
||||||
|
internal readonly Dictionary<string, VariableSymbol> LocalVariables;
|
||||||
|
|
||||||
|
|
||||||
public BoundScope(BoundScope parentScope)
|
public BoundScope(BoundScope parentScope)
|
||||||
{
|
{
|
||||||
ParentScope = parentScope;
|
ParentScope = parentScope;
|
||||||
Variables = new Dictionary<string, VariableSymbol>();
|
Variables = new Dictionary<string, VariableSymbol>();
|
||||||
|
LocalVariables = new Dictionary<string, VariableSymbol>();
|
||||||
}
|
}
|
||||||
public BoundScope(Dictionary<string, VariableSymbol> variables, BoundScope parentScope)
|
public BoundScope(Dictionary<string, VariableSymbol> variables, BoundScope parentScope)
|
||||||
{
|
{
|
||||||
ParentScope = parentScope;
|
ParentScope = parentScope;
|
||||||
Variables = variables;
|
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)
|
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))
|
if (Variables.ContainsKey(var.Name))
|
||||||
Variables[var.Name] = var;
|
Variables[var.Name] = var;
|
||||||
else
|
else
|
||||||
Variables.Add(var.Name, var);
|
Variables.Add(var.Name, var);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SetGlobalVariable(VariableSymbol var)
|
public void SetGlobalVariable(VariableSymbol var)
|
||||||
{
|
{
|
||||||
|
@ -44,6 +62,10 @@ namespace Upsilon.Binder
|
||||||
|
|
||||||
public bool TryGetVariable(string key, bool allowUpperScopes, out VariableSymbol result)
|
public bool TryGetVariable(string key, bool allowUpperScopes, out VariableSymbol result)
|
||||||
{
|
{
|
||||||
|
if (LocalVariables.TryGetValue(key, out result))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (Variables.TryGetValue(key, out result))
|
if (Variables.TryGetValue(key, out result))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -52,6 +74,10 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
return ParentScope.TryGetVariable(key, true, out result);
|
return ParentScope.TryGetVariable(key, true, out result);
|
||||||
}
|
}
|
||||||
|
if (_readOnlyScope != null && allowUpperScopes)
|
||||||
|
{
|
||||||
|
return _readOnlyScope.TryGetVariable(key, true, out result);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,10 +71,10 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
public bool TryGet(VariableSymbol symbol, out LuaType obj)
|
public bool TryGet(VariableSymbol symbol, out LuaType obj)
|
||||||
{
|
{
|
||||||
if (Variables.TryGetValue(symbol.Name, out obj))
|
|
||||||
return true;
|
|
||||||
if (LocalVariables.TryGetValue(symbol.Name, out obj))
|
if (LocalVariables.TryGetValue(symbol.Name, out obj))
|
||||||
return true;
|
return true;
|
||||||
|
if (Variables.TryGetValue(symbol.Name, out obj))
|
||||||
|
return true;
|
||||||
if (_parentScope != null)
|
if (_parentScope != null)
|
||||||
if (_parentScope.TryGet(symbol, out obj))
|
if (_parentScope.TryGet(symbol, out obj))
|
||||||
return true;
|
return true;
|
||||||
|
@ -86,10 +86,10 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
public bool TryGet(string variable, out LuaType obj)
|
public bool TryGet(string variable, out LuaType obj)
|
||||||
{
|
{
|
||||||
if (Variables.TryGetValue(variable, out obj))
|
|
||||||
return true;
|
|
||||||
if (LocalVariables.TryGetValue(variable, out obj))
|
if (LocalVariables.TryGetValue(variable, out obj))
|
||||||
return true;
|
return true;
|
||||||
|
if (Variables.TryGetValue(variable, out obj))
|
||||||
|
return true;
|
||||||
if (_parentScope != null)
|
if (_parentScope != null)
|
||||||
if (_parentScope.TryGet(variable, out obj))
|
if (_parentScope.TryGet(variable, out obj))
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue