Skip to content

Commit

Permalink
Make built-in identifiers read-only; return error if trying to write …
Browse files Browse the repository at this point in the history
…to a read-only variable/function
  • Loading branch information
ethanmoffat committed Jan 30, 2022
1 parent 5cc0ffd commit 81a0279
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 23 deletions.
22 changes: 11 additions & 11 deletions EOBot/Interpreter/BuiltInIdentifierConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,27 @@ public class BuiltInIdentifierConfigurator
public void SetupBuiltInFunctions(ProgramState input)
{
var printFunc = new VoidFunctionRef<object>(PredefinedIdentifiers.PRINT_FUNC, param1 => ConsoleHelper.WriteMessage(ConsoleHelper.Type.None, param1.ToString()));
input.SymbolTable[PredefinedIdentifiers.PRINT_FUNC] = printFunc;
input.SymbolTable[PredefinedIdentifiers.PRINT_FUNC] = (false, printFunc);

var lenFunc = new FunctionRef<ArrayVariable, int>(PredefinedIdentifiers.LEN_FUNC, param1 => param1.Value.Count);
input.SymbolTable[PredefinedIdentifiers.LEN_FUNC] = lenFunc;
input.SymbolTable[PredefinedIdentifiers.LEN_FUNC] = (false, lenFunc);

var arrayFunc = new FunctionRef<int, List<IVariable>>(PredefinedIdentifiers.ARRAY_FUNC,
param1 => Enumerable.Repeat(UndefinedVariable.Instance, param1).Cast<IVariable>().ToList());
input.SymbolTable.Add(PredefinedIdentifiers.ARRAY_FUNC, arrayFunc);
input.SymbolTable[PredefinedIdentifiers.ARRAY_FUNC] = (false, arrayFunc);
}

public void SetupBuiltInVariables(ProgramState input, ArgumentsParser parsedArgs)
{
input.SymbolTable[PredefinedIdentifiers.HOST] = new StringVariable(parsedArgs.Host);
input.SymbolTable[PredefinedIdentifiers.PORT] = new IntVariable(parsedArgs.Port);
input.SymbolTable[PredefinedIdentifiers.ARGS] = new ArrayVariable(
parsedArgs.UserArgs.Select(x => new StringVariable(x)).Cast<IVariable>().ToList());
input.SymbolTable[PredefinedIdentifiers.HOST] = (false, new StringVariable(parsedArgs.Host));
input.SymbolTable[PredefinedIdentifiers.PORT] = (false, new IntVariable(parsedArgs.Port));
input.SymbolTable[PredefinedIdentifiers.ARGS] = (false, new ArrayVariable(
parsedArgs.UserArgs.Select(x => new StringVariable(x)).Cast<IVariable>().ToList()));

input.SymbolTable[PredefinedIdentifiers.RESULT] = UndefinedVariable.Instance;
input.SymbolTable[PredefinedIdentifiers.ACCOUNT] = UndefinedVariable.Instance;
input.SymbolTable[PredefinedIdentifiers.CHARACTER] = UndefinedVariable.Instance;
input.SymbolTable[PredefinedIdentifiers.MAPSTATE] = UndefinedVariable.Instance;
input.SymbolTable[PredefinedIdentifiers.RESULT] = (true, UndefinedVariable.Instance);
input.SymbolTable[PredefinedIdentifiers.ACCOUNT] = (false, UndefinedVariable.Instance);
input.SymbolTable[PredefinedIdentifiers.CHARACTER] = (false, UndefinedVariable.Instance);
input.SymbolTable[PredefinedIdentifiers.MAPSTATE] = (false, UndefinedVariable.Instance);
}
}
}
8 changes: 6 additions & 2 deletions EOBot/Interpreter/States/AssignmentEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,21 @@ public bool Evaluate(ProgramState input)
return false;
var variable = (IdentifierBotToken)input.OperationStack.Pop();

if (input.SymbolTable.ContainsKey(variable.TokenValue) &&
input.SymbolTable[variable.TokenValue].ReadOnly)
return false;

if (variable.ArrayIndex != null)
{
if (!input.SymbolTable.ContainsKey(variable.TokenValue))
return false;

((ArrayVariable)input.SymbolTable[variable.TokenValue]).Value[variable.ArrayIndex.Value] = expressionResult.VariableValue;
((ArrayVariable)input.SymbolTable[variable.TokenValue].Identifiable).Value[variable.ArrayIndex.Value] = expressionResult.VariableValue;
}
else
{
// todo: dynamic typing with no warning, or warn if changing typing of variable on assignment?
input.SymbolTable[variable.TokenValue] = expressionResult.VariableValue;
input.SymbolTable[variable.TokenValue] = (false, expressionResult.VariableValue);
}

return true;
Expand Down
4 changes: 2 additions & 2 deletions EOBot/Interpreter/States/ExpressionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ private static VariableBotToken GetOperand(ProgramState input)
{
var identifier = (IdentifierBotToken)nextToken;
if (!input.SymbolTable.ContainsKey(identifier.TokenValue))
input.SymbolTable[identifier.TokenValue] = UndefinedVariable.Instance;
input.SymbolTable[identifier.TokenValue] = (true, UndefinedVariable.Instance);

var variableValue = (IVariable)input.SymbolTable[identifier.TokenValue];
var variableValue = (IVariable)input.SymbolTable[identifier.TokenValue].Identifiable;
if (identifier.ArrayIndex != null)
variableValue = ((ArrayVariable)variableValue).Value[identifier.ArrayIndex.Value];
operand = new VariableBotToken(BotTokenType.Literal, variableValue.ToString(), variableValue);
Expand Down
10 changes: 5 additions & 5 deletions EOBot/Interpreter/States/FunctionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public bool Evaluate(ProgramState input)
return false;
var functionName = input.OperationStack.Pop();

var function = input.SymbolTable[functionName.TokenValue];
var function = input.SymbolTable[functionName.TokenValue].Identifiable;
return Call(input, (dynamic)function, parameters.Select(x => x.VariableValue).ToArray());
}

Expand All @@ -77,7 +77,7 @@ private bool Call(ProgramState input, ICallable<int> function, params IVariable[
{
var result = function.Call(variables);
var varResult = new IntVariable(result);
input.SymbolTable[PredefinedIdentifiers.RESULT] = varResult;
input.SymbolTable[PredefinedIdentifiers.RESULT] = (true, varResult);
input.OperationStack.Push(new VariableBotToken(BotTokenType.Literal, varResult.StringValue, varResult));
}
catch (ArgumentException)
Expand All @@ -94,7 +94,7 @@ private bool Call(ProgramState input, ICallable<string> function, params IVariab
{
var result = function.Call(variables);
var varResult = new StringVariable(result);
input.SymbolTable[PredefinedIdentifiers.RESULT] = new StringVariable(result);
input.SymbolTable[PredefinedIdentifiers.RESULT] = (true, varResult);
input.OperationStack.Push(new VariableBotToken(BotTokenType.Literal, varResult.StringValue, varResult));
}
catch (ArgumentException)
Expand All @@ -111,7 +111,7 @@ private bool Call(ProgramState input, ICallable<List<IVariable>> function, param
{
var result = function.Call(variables);
var varResult = new ArrayVariable(result);
input.SymbolTable[PredefinedIdentifiers.RESULT] = new ArrayVariable(result);
input.SymbolTable[PredefinedIdentifiers.RESULT] = (true, varResult);
input.OperationStack.Push(new VariableBotToken(BotTokenType.Literal, varResult.StringValue, varResult));
}
catch (ArgumentException)
Expand All @@ -128,7 +128,7 @@ private bool Call(ProgramState input, ICallable<bool> function, params IVariable
{
var result = function.Call(variables);
var varResult = new BoolVariable(result);
input.SymbolTable[PredefinedIdentifiers.RESULT] = new BoolVariable(result);
input.SymbolTable[PredefinedIdentifiers.RESULT] = (true, varResult);
input.OperationStack.Push(new VariableBotToken(BotTokenType.Literal, varResult.StringValue, varResult));
}
catch (ArgumentException)
Expand Down
5 changes: 2 additions & 3 deletions EOBot/Interpreter/States/ProgramState.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using EOBot.Interpreter.Variables;
using System;
using System.Collections.Generic;

namespace EOBot.Interpreter.States
Expand All @@ -10,7 +9,7 @@ public class ProgramState

public IReadOnlyList<BotToken> Program { get; }

public Dictionary<string, IIdentifiable> SymbolTable { get; }
public Dictionary<string, (bool ReadOnly, IIdentifiable Identifiable)> SymbolTable { get; }

public Dictionary<LabelIdentifier, int> Labels { get; }

Expand All @@ -20,7 +19,7 @@ public ProgramState(IReadOnlyList<BotToken> program)
{
OperationStack = new Stack<BotToken>();
Program = program;
SymbolTable = new Dictionary<string, IIdentifiable>();
SymbolTable = new Dictionary<string, (bool ReadOnly, IIdentifiable Identifiable)>();
Labels = new Dictionary<LabelIdentifier, int>();
ExecutionIndex = 0;
}
Expand Down

0 comments on commit 81a0279

Please sign in to comment.