Skip to content

Commit

Permalink
Reuse code for accessing a variable or an array index
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanmoffat committed Feb 3, 2022
1 parent c0ca597 commit c009218
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 26 deletions.
46 changes: 46 additions & 0 deletions EOBot/Interpreter/Extensions/ProgramStateExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using EOBot.Interpreter.States;
using EOBot.Interpreter.Variables;

namespace EOBot.Interpreter.Extensions
{
Expand All @@ -24,5 +25,50 @@ public static BotToken Current(this ProgramState input)

return input.Program[input.ExecutionIndex];
}

public static (EvalResult Result, string Reason, IVariable Variable) GetVariable(this ProgramState input, string identifier, int? arrayIndex = null)
{
if (!input.SymbolTable.ContainsKey(identifier))
input.SymbolTable[identifier] = (false, UndefinedVariable.Instance);

var variableValue = input.SymbolTable[identifier].Identifiable as IVariable;
if (variableValue == null)
{
return (EvalResult.Failed, $"Identifier {identifier} is not a variable", null);
}

if (arrayIndex != null)
{
var arrayVariable = variableValue as ArrayVariable;
if (arrayVariable == null)
{
return (EvalResult.Failed, $"Identifier {identifier} is not an array", null);
}

if (arrayVariable.Value.Count <= arrayIndex.Value)
{
return (EvalResult.Failed, $"Index {identifier} is out of range of the array {identifier} (size {arrayVariable.Value.Count})", null);
}

variableValue = arrayVariable.Value[arrayIndex.Value];
}

return (EvalResult.Ok, string.Empty, variableValue);
}

public static (EvalResult Result, string Reason, T Variable) GetVariable<T>(this ProgramState input, string identifier, int? arrayIndex = null)
where T : class, IVariable
{
var getResult = GetVariable(input, identifier, arrayIndex);

if (getResult.Result != EvalResult.Ok)
return (getResult.Result, getResult.Reason, null);

var variable = getResult.Variable as T;
if (variable == null)
return (EvalResult.Failed, $"Identifier {identifier} is not a {typeof(T).Name}", null);

return (EvalResult.Ok, string.Empty, variable);
}
}
}
10 changes: 4 additions & 6 deletions EOBot/Interpreter/States/AssignmentEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,11 @@ public AssignmentEvaluator(IEnumerable<IScriptEvaluator> evaluators)
if (!input.SymbolTable.ContainsKey(variable.TokenValue))
return IdentifierNotFoundError(variable);

var targetArray = input.SymbolTable[variable.TokenValue].Identifiable as ArrayVariable;
if (targetArray == null)
return (EvalResult.Failed, $"Identifier {variable.TokenValue} is not an array", variable);

if (targetArray.Value.Count <= variable.ArrayIndex.Value)
return (EvalResult.Failed, $"Index {variable.ArrayIndex} is out of range of the array {variable.TokenValue} (size {targetArray.Value.Count})", variable);
var getVariableResult = input.GetVariable<ArrayVariable>(variable.TokenValue, variable.ArrayIndex);
if (getVariableResult.Result != EvalResult.Ok)
return (getVariableResult.Result, getVariableResult.Reason, variable);

var targetArray = getVariableResult.Variable;
targetArray.Value[variable.ArrayIndex.Value] = expressionResult.VariableValue;
}
else
Expand Down
24 changes: 4 additions & 20 deletions EOBot/Interpreter/States/ExpressionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,27 +157,11 @@ public ExpressionEvaluator(IEnumerable<IScriptEvaluator> evaluators)
if (identifier == null)
return (EvalResult.Failed, $"Expected operand of type Variable or Identifier but got {nextToken.TokenType}", nextToken);

if (!input.SymbolTable.ContainsKey(identifier.TokenValue))
input.SymbolTable[identifier.TokenValue] = (true, UndefinedVariable.Instance);
var getVariableRes = input.GetVariable(identifier.TokenValue, identifier.ArrayIndex);
if (getVariableRes.Result != EvalResult.Ok)
return (getVariableRes.Result, getVariableRes.Reason, identifier);

var variableValue = (IVariable)input.SymbolTable[identifier.TokenValue].Identifiable;
if (identifier.ArrayIndex != null)
{
var arrayVariable = variableValue as ArrayVariable;
if (arrayVariable == null)
{
return (EvalResult.Failed, $"Identifier {identifier.TokenValue} is not an array", identifier);
}

if (arrayVariable.Value.Count <= identifier.ArrayIndex.Value)
{
return (EvalResult.Failed, $"Index {identifier.ArrayIndex} is out of range of the array {identifier.TokenValue} (size {arrayVariable.Value.Count})", identifier);
}

variableValue = arrayVariable.Value[identifier.ArrayIndex.Value];
}

operand = new VariableBotToken(BotTokenType.Literal, variableValue.ToString(), variableValue);
operand = new VariableBotToken(BotTokenType.Literal, getVariableRes.Variable.ToString(), getVariableRes.Variable);
}

return Success(operand);
Expand Down

0 comments on commit c009218

Please sign in to comment.