Fixed Scoping issue
This commit is contained in:
parent
638394d25b
commit
62a18e22d4
|
@ -45,7 +45,7 @@ namespace Upsilon.BaseTypes
|
||||||
{
|
{
|
||||||
var parameterVariable = Parameters[i];
|
var parameterVariable = Parameters[i];
|
||||||
var parameterValue = variables[i];
|
var parameterValue = variables[i];
|
||||||
innerEvaluator.Scope.Set(parameterVariable, parameterValue, true);
|
innerEvaluator.Scope.CreateLocal(parameterVariable, parameterValue);
|
||||||
}
|
}
|
||||||
return innerEvaluator.EvaluateNode(Block);
|
return innerEvaluator.EvaluateNode(Block);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Upsilon.BaseTypes
|
||||||
public void Set(Diagnostics diagnostics, TextSpan span, ScriptType index, ScriptType value)
|
public void Set(Diagnostics diagnostics, TextSpan span, ScriptType index, ScriptType value)
|
||||||
{
|
{
|
||||||
var s = index.ToString();
|
var s = index.ToString();
|
||||||
EvaluationScope.Set(new VariableSymbol(s, value.Type, false), value, true);
|
EvaluationScope.CreateLocal(new VariableSymbol(s, value.Type, false), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<(string Key, ScriptType value)> GetEnumerator()
|
public IEnumerator<(string Key, ScriptType value)> GetEnumerator()
|
||||||
|
|
|
@ -38,7 +38,7 @@ namespace Upsilon.Binder
|
||||||
Scope = new BoundScope(Scope);
|
Scope = new BoundScope(Scope);
|
||||||
foreach (var valueParameter in unboundFunctionStatement.Value.Parameters)
|
foreach (var valueParameter in unboundFunctionStatement.Value.Parameters)
|
||||||
{
|
{
|
||||||
Scope.SetVariable(valueParameter);
|
Scope.AssignToNearest(valueParameter);
|
||||||
}
|
}
|
||||||
unboundFunctionStatement.Value.Block =
|
unboundFunctionStatement.Value.Block =
|
||||||
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.Value.UnboundBlock);
|
(BoundBlockStatement) BindBlockStatement(unboundFunctionStatement.Value.UnboundBlock);
|
||||||
|
@ -202,7 +202,7 @@ namespace Upsilon.Binder
|
||||||
var functionVariable = function.Parameters[index];
|
var functionVariable = function.Parameters[index];
|
||||||
var callingVariable = parameters[index];
|
var callingVariable = parameters[index];
|
||||||
functionVariable.Type = callingVariable.Type;
|
functionVariable.Type = callingVariable.Type;
|
||||||
Scope.SetVariable(functionVariable);
|
Scope.DefineLocalVariable(functionVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
var unboundFunctionStatement = _unboundFunctions[function.Name];
|
var unboundFunctionStatement = _unboundFunctions[function.Name];
|
||||||
|
@ -253,9 +253,9 @@ namespace Upsilon.Binder
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLocal)
|
if (isLocal)
|
||||||
Scope.SetVariable(variable);
|
Scope.DefineLocalVariable(variable);
|
||||||
else
|
else
|
||||||
Scope.SetGlobalVariable(variable);
|
Scope.AssignToNearest(variable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -299,7 +299,7 @@ namespace Upsilon.Binder
|
||||||
var boundVariable = TryBindVariable(name, isLocal, boundExpression);
|
var boundVariable = TryBindVariable(name, isLocal, boundExpression);
|
||||||
if (boundVariable != null)
|
if (boundVariable != null)
|
||||||
{
|
{
|
||||||
return new BoundVariableAssignment(boundVariable, boundExpression);
|
return new BoundVariableAssignment(boundVariable, boundExpression, isLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -369,7 +369,7 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
var vari = new VariableSymbol(identifierToken.Name, Type.Unknown, true);
|
var vari = new VariableSymbol(identifierToken.Name, Type.Unknown, true);
|
||||||
parameters.Add(vari);
|
parameters.Add(vari);
|
||||||
innerScope.SetVariable(vari);
|
innerScope.DefineLocalVariable(vari);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parameters.Count == 0)
|
if (parameters.Count == 0)
|
||||||
|
@ -408,7 +408,7 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
var vari = new VariableSymbol(identifierToken.Name, Type.Unknown, true);
|
var vari = new VariableSymbol(identifierToken.Name, Type.Unknown, true);
|
||||||
parameters.Add(vari);
|
parameters.Add(vari);
|
||||||
innerScope.SetVariable(vari);
|
innerScope.DefineLocalVariable(vari);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -417,9 +417,9 @@ namespace Upsilon.Binder
|
||||||
variable = new FunctionVariableSymbol(name, Type.Function, isLocal, parameters.ToImmutable());
|
variable = new FunctionVariableSymbol(name, Type.Function, isLocal, parameters.ToImmutable());
|
||||||
((FunctionVariableSymbol) variable).IsBound = !(func is UnboundFunctionExpression);
|
((FunctionVariableSymbol) variable).IsBound = !(func is UnboundFunctionExpression);
|
||||||
if (isLocal)
|
if (isLocal)
|
||||||
Scope.SetVariable(variable);
|
Scope.DefineLocalVariable(variable);
|
||||||
else
|
else
|
||||||
Scope.SetGlobalVariable(variable);
|
Scope.AssignToNearest(variable);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -528,7 +528,7 @@ namespace Upsilon.Binder
|
||||||
var variableName = e.Identifier.Name;
|
var variableName = e.Identifier.Name;
|
||||||
Scope = new BoundScope(Scope);
|
Scope = new BoundScope(Scope);
|
||||||
var variable = new VariableSymbol(variableName, Type.Number, true);
|
var variable = new VariableSymbol(variableName, Type.Number, true);
|
||||||
Scope.SetVariable(variable);
|
Scope.DefineLocalVariable(variable);
|
||||||
var boundStart = BindExpression(e.StartExpression);
|
var boundStart = BindExpression(e.StartExpression);
|
||||||
var boundStop = BindExpression(e.StopExpression);
|
var boundStop = BindExpression(e.StopExpression);
|
||||||
BoundExpression boundStep = null;
|
BoundExpression boundStep = null;
|
||||||
|
@ -546,7 +546,7 @@ namespace Upsilon.Binder
|
||||||
foreach (var variableIdentifier in e.Variables)
|
foreach (var variableIdentifier in e.Variables)
|
||||||
{
|
{
|
||||||
var variable = new VariableSymbol(variableIdentifier.Name, Type.Unknown, true);
|
var variable = new VariableSymbol(variableIdentifier.Name, Type.Unknown, true);
|
||||||
Scope.SetVariable(variable);
|
Scope.DefineLocalVariable(variable);
|
||||||
array.Add(variable);
|
array.Add(variable);
|
||||||
}
|
}
|
||||||
var boundEnumerableExpression = BindExpression(e.EnumerableExpression);
|
var boundEnumerableExpression = BindExpression(e.EnumerableExpression);
|
||||||
|
|
|
@ -7,20 +7,17 @@ namespace Upsilon.Binder
|
||||||
public readonly BoundScope ParentScope;
|
public readonly BoundScope ParentScope;
|
||||||
private BoundScope _readOnlyScope;
|
private BoundScope _readOnlyScope;
|
||||||
public readonly Dictionary<string, VariableSymbol> Variables;
|
public 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)
|
public static BoundScope WithReadOnlyScope(BoundScope readOnlyScope)
|
||||||
|
@ -29,43 +26,29 @@ namespace Upsilon.Binder
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVariable(VariableSymbol var)
|
public void DefineLocalVariable(VariableSymbol var)
|
||||||
{
|
{
|
||||||
if (var.Local)
|
Variables.Add(var.Name, var);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AssignToNearest(VariableSymbol var)
|
||||||
|
{
|
||||||
|
if (Variables.ContainsKey(var.Name))
|
||||||
{
|
{
|
||||||
if (LocalVariables.ContainsKey(var.Name))
|
|
||||||
LocalVariables[var.Name] = var;
|
}
|
||||||
else
|
else if (ParentScope != null)
|
||||||
LocalVariables.Add(var.Name, var);
|
{
|
||||||
|
ParentScope.AssignToNearest(var);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Variables.ContainsKey(var.Name))
|
Variables.Add(var.Name, var);
|
||||||
Variables[var.Name] = var;
|
|
||||||
else
|
|
||||||
Variables.Add(var.Name, var);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetGlobalVariable(VariableSymbol var)
|
|
||||||
{
|
|
||||||
if (ParentScope == null)
|
|
||||||
{
|
|
||||||
SetVariable(var);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ParentScope.SetGlobalVariable(var);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
|
@ -4,11 +4,13 @@ namespace Upsilon.Binder
|
||||||
{
|
{
|
||||||
public VariableSymbol Variable { get; }
|
public VariableSymbol Variable { get; }
|
||||||
public BoundExpression BoundExpression { get; }
|
public BoundExpression BoundExpression { get; }
|
||||||
|
public bool IsLocalDefinition { get; }
|
||||||
|
|
||||||
public BoundVariableAssignment(VariableSymbol variable, BoundExpression boundExpression)
|
public BoundVariableAssignment(VariableSymbol variable, BoundExpression boundExpression, bool isLocalDefinition)
|
||||||
{
|
{
|
||||||
Variable = variable;
|
Variable = variable;
|
||||||
BoundExpression = boundExpression;
|
BoundExpression = boundExpression;
|
||||||
|
IsLocalDefinition = isLocalDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BoundKind Kind => BoundKind.BoundAssignmentStatement;
|
public override BoundKind Kind => BoundKind.BoundAssignmentStatement;
|
||||||
|
|
|
@ -10,20 +10,17 @@ namespace Upsilon.Evaluator
|
||||||
private EvaluationScope _getOnlyParentScope;
|
private EvaluationScope _getOnlyParentScope;
|
||||||
|
|
||||||
public readonly Dictionary<string, ScriptType> Variables;
|
public readonly Dictionary<string, ScriptType> Variables;
|
||||||
private readonly Dictionary<string, ScriptType> _localVariables;
|
|
||||||
|
|
||||||
|
|
||||||
internal EvaluationScope(EvaluationScope parentScope)
|
internal EvaluationScope(EvaluationScope parentScope)
|
||||||
{
|
{
|
||||||
_parentScope = parentScope;
|
_parentScope = parentScope;
|
||||||
Variables = new Dictionary<string, ScriptType>();
|
Variables = new Dictionary<string, ScriptType>();
|
||||||
_localVariables = new Dictionary<string, ScriptType>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal EvaluationScope(Dictionary<string, ScriptType> vars)
|
internal EvaluationScope(Dictionary<string, ScriptType> vars)
|
||||||
{
|
{
|
||||||
Variables = vars;
|
Variables = vars;
|
||||||
_localVariables = new Dictionary<string, ScriptType>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static EvaluationScope CreateWithGetOnlyParent(EvaluationScope parent)
|
internal static EvaluationScope CreateWithGetOnlyParent(EvaluationScope parent)
|
||||||
|
@ -32,55 +29,30 @@ namespace Upsilon.Evaluator
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(VariableSymbol symbol, ScriptType obj, bool createNew)
|
public void AssignToNearest(VariableSymbol symbol, ScriptType value)
|
||||||
{
|
{
|
||||||
if (symbol.Local && createNew)
|
if (Variables.ContainsKey(symbol.Name))
|
||||||
{
|
{
|
||||||
if (_localVariables.ContainsKey(symbol.Name))
|
Variables[symbol.Name] = value;
|
||||||
{
|
}
|
||||||
_localVariables[symbol.Name] = obj;
|
else if (_parentScope != null)
|
||||||
}
|
{
|
||||||
else
|
_parentScope.AssignToNearest(symbol, value);
|
||||||
{
|
|
||||||
_localVariables.Add(symbol.Name, obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Variables.ContainsKey(symbol.Name))
|
Variables.Add(symbol.Name, value);
|
||||||
{
|
|
||||||
Variables[symbol.Name] = obj;
|
|
||||||
}
|
|
||||||
else if (_localVariables.ContainsKey(symbol.Name))
|
|
||||||
{
|
|
||||||
_localVariables[symbol.Name] = obj;
|
|
||||||
}
|
|
||||||
else if (_parentScope != null && _parentScope.TryGet(symbol.Name, out _))
|
|
||||||
{
|
|
||||||
_parentScope.Set(symbol, obj, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Variables.Add(symbol.Name, obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetGlobal(VariableSymbol symbol, ScriptType obj)
|
public void CreateLocal(VariableSymbol symbol, ScriptType value)
|
||||||
{
|
{
|
||||||
if (_parentScope != null)
|
Variables[symbol.Name] = value;
|
||||||
_parentScope.SetGlobal(symbol, obj);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Set(symbol, obj, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool TryGet(VariableSymbol symbol, out ScriptType obj)
|
public bool TryGet(VariableSymbol symbol, out ScriptType obj)
|
||||||
{
|
{
|
||||||
if (_localVariables.TryGetValue(symbol.Name, out obj))
|
|
||||||
return true;
|
|
||||||
if (Variables.TryGetValue(symbol.Name, out obj))
|
if (Variables.TryGetValue(symbol.Name, out obj))
|
||||||
return true;
|
return true;
|
||||||
if (_parentScope != null)
|
if (_parentScope != null)
|
||||||
|
@ -94,8 +66,6 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
public bool TryGet(string variable, out ScriptType obj)
|
public bool TryGet(string variable, out ScriptType obj)
|
||||||
{
|
{
|
||||||
if (_localVariables.TryGetValue(variable, out obj))
|
|
||||||
return true;
|
|
||||||
if (Variables.TryGetValue(variable, out obj))
|
if (Variables.TryGetValue(variable, out obj))
|
||||||
return true;
|
return true;
|
||||||
if (_parentScope != null)
|
if (_parentScope != null)
|
||||||
|
|
|
@ -59,7 +59,7 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
var parameter = parameters[index];
|
var parameter = parameters[index];
|
||||||
var parameterName = function.Parameters[index];
|
var parameterName = function.Parameters[index];
|
||||||
innerEvaluator.Scope.Set(parameterName, parameter, true);
|
innerEvaluator.Scope.CreateLocal(parameterName, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = innerEvaluator.EvaluateNode(function.Block);
|
var result = innerEvaluator.EvaluateNode(function.Block);
|
||||||
|
@ -295,13 +295,13 @@ namespace Upsilon.Evaluator
|
||||||
private void EvaluateAssignmentStatement(BoundVariableAssignment e)
|
private void EvaluateAssignmentStatement(BoundVariableAssignment e)
|
||||||
{
|
{
|
||||||
var val = EvaluateExpression(e.BoundExpression);
|
var val = EvaluateExpression(e.BoundExpression);
|
||||||
if (e.Variable.Local)
|
if (e.IsLocalDefinition)
|
||||||
{
|
{
|
||||||
Scope.Set(e.Variable, val, true);
|
Scope.CreateLocal(e.Variable, val);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Scope.SetGlobal(e.Variable, val);
|
Scope.AssignToNearest(e.Variable, val);
|
||||||
}
|
}
|
||||||
_lastValue = val;
|
_lastValue = val;
|
||||||
}
|
}
|
||||||
|
@ -320,9 +320,9 @@ namespace Upsilon.Evaluator
|
||||||
continue;
|
continue;
|
||||||
var value = table.Get(_diagnostics, e.Span, new ScriptNumberLong(i + 1), Scope);
|
var value = table.Get(_diagnostics, e.Span, new ScriptNumberLong(i + 1), Scope);
|
||||||
if (variableSymbol.Local)
|
if (variableSymbol.Local)
|
||||||
Scope.Set(variableSymbol, value, true);
|
Scope.CreateLocal(variableSymbol, value);
|
||||||
else
|
else
|
||||||
Scope.SetGlobal(variableSymbol, value);
|
Scope.AssignToNearest(variableSymbol, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -374,9 +374,9 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
var func = EvaluateBoundFunctionStatement(e.Func);
|
var func = EvaluateBoundFunctionStatement(e.Func);
|
||||||
if (e.Variable.Local)
|
if (e.Variable.Local)
|
||||||
Scope.Set(e.Variable, func, true);
|
Scope.CreateLocal(e.Variable, func);
|
||||||
else
|
else
|
||||||
Scope.SetGlobal(e.Variable, func);
|
Scope.AssignToNearest(e.Variable, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScriptType EvaluateBoundFunctionStatement(BoundFunctionExpression boundFunctionExpression)
|
private ScriptType EvaluateBoundFunctionStatement(BoundFunctionExpression boundFunctionExpression)
|
||||||
|
@ -434,8 +434,8 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
innerEvaluator.EvaluateStatement(boundStatement);
|
innerEvaluator.EvaluateStatement(boundStatement);
|
||||||
if (innerEvaluator._lastValue != null)
|
if (innerEvaluator._lastValue != null)
|
||||||
tableScope.Set(new VariableSymbol(currentPos.ToString(), innerEvaluator._lastValue.Type, false),
|
tableScope.CreateLocal(new VariableSymbol(currentPos.ToString(), innerEvaluator._lastValue.Type, false),
|
||||||
innerEvaluator._lastValue, true);
|
innerEvaluator._lastValue);
|
||||||
innerEvaluator._lastValue = null;
|
innerEvaluator._lastValue = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -506,7 +506,7 @@ namespace Upsilon.Evaluator
|
||||||
{
|
{
|
||||||
var innerEvaluator = new Evaluator(_diagnostics, Scope);
|
var innerEvaluator = new Evaluator(_diagnostics, Scope);
|
||||||
var startVal = (ScriptNumberLong)innerEvaluator.EvaluateExpression(e.BoundStart);
|
var startVal = (ScriptNumberLong)innerEvaluator.EvaluateExpression(e.BoundStart);
|
||||||
innerEvaluator.Scope.Set(e.Variable, startVal, true);
|
innerEvaluator.Scope.CreateLocal(e.Variable, startVal);
|
||||||
var stopVal = (ScriptNumberLong)innerEvaluator.EvaluateExpression(e.BoundStop);
|
var stopVal = (ScriptNumberLong)innerEvaluator.EvaluateExpression(e.BoundStop);
|
||||||
long step = 1;
|
long step = 1;
|
||||||
if (e.BoundStep != null)
|
if (e.BoundStep != null)
|
||||||
|
@ -546,18 +546,16 @@ namespace Upsilon.Evaluator
|
||||||
|
|
||||||
using (var enumerator = iterable.GetEnumerator())
|
using (var enumerator = iterable.GetEnumerator())
|
||||||
{
|
{
|
||||||
bool first = true;
|
|
||||||
while (enumerator.MoveNext())
|
while (enumerator.MoveNext())
|
||||||
{
|
{
|
||||||
var (key, value) = enumerator.Current;
|
var (key, value) = enumerator.Current;
|
||||||
if (e.Variables[0].Name != "_")
|
if (e.Variables[0].Name != "_")
|
||||||
innerEvaluator.Scope.Set(e.Variables[0], key.ToLuaType(), first);
|
innerEvaluator.Scope.CreateLocal(e.Variables[0], key.ToLuaType());
|
||||||
if (e.Variables[1].Name != "_")
|
if (e.Variables[1].Name != "_")
|
||||||
innerEvaluator.Scope.Set(e.Variables[1], value, first);
|
innerEvaluator.Scope.CreateLocal(e.Variables[1], value);
|
||||||
innerEvaluator.EvaluateBoundBlockStatement((BoundBlockStatement) e.Block);
|
innerEvaluator.EvaluateBoundBlockStatement((BoundBlockStatement) e.Block);
|
||||||
if (innerEvaluator.HasBroken)
|
if (innerEvaluator.HasBroken)
|
||||||
break;
|
break;
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,8 +45,9 @@ namespace Upsilon.StandardLibraries
|
||||||
var scope = new EvaluationScope(basicFunctions.ToDictionary(x => x.Key, x => (ScriptType)x.Value));
|
var scope = new EvaluationScope(basicFunctions.ToDictionary(x => x.Key, x => (ScriptType)x.Value));
|
||||||
var boundScope =
|
var boundScope =
|
||||||
new BoundScope(
|
new BoundScope(
|
||||||
scope.Variables.ToDictionary(x => x.Key
|
scope.Variables.ToDictionary(x => x.Key,
|
||||||
, x => (VariableSymbol)new FunctionVariableSymbol(x.Key, x.Value.Type, false, ImmutableArray<VariableSymbol>.Empty){IsBound = true}),
|
x => (VariableSymbol) new FunctionVariableSymbol(x.Key, x.Value.Type, false,
|
||||||
|
ImmutableArray<VariableSymbol>.Empty) {IsBound = true}),
|
||||||
null);
|
null);
|
||||||
return (scope, boundScope);
|
return (scope, boundScope);
|
||||||
}
|
}
|
||||||
|
@ -55,8 +56,8 @@ namespace Upsilon.StandardLibraries
|
||||||
{
|
{
|
||||||
var luaVariable = value.ToLuaType();
|
var luaVariable = value.ToLuaType();
|
||||||
var varSymbol = new VariableSymbol(name, luaVariable.Type, false);
|
var varSymbol = new VariableSymbol(name, luaVariable.Type, false);
|
||||||
BoundScope.SetVariable(varSymbol);
|
BoundScope.AssignToNearest(varSymbol);
|
||||||
Scope.Set(varSymbol, luaVariable, true);
|
Scope.AssignToNearest(varSymbol, luaVariable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -45,5 +45,23 @@ b = a
|
||||||
Assert.Equal(100, a);
|
Assert.Equal(100, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void InnerScopeDefinesToUpperLocalIfLogical()
|
||||||
|
{
|
||||||
|
const string input = @"
|
||||||
|
arr = {100, 56, 28}
|
||||||
|
local value = 0
|
||||||
|
for key, val in arr do
|
||||||
|
value = value + val
|
||||||
|
end
|
||||||
|
return value
|
||||||
|
";
|
||||||
|
var script = new Script(input, BoundScope, StaticScope);
|
||||||
|
Assert.Empty(script.Diagnostics.Messages);
|
||||||
|
var result = script.Evaluate<long>();
|
||||||
|
Assert.Empty(script.Diagnostics.Messages);
|
||||||
|
Assert.Equal(184, result);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue