public void TestReplaceVariablesDuplicateKeyResolved() { var variable1 = new VariableExpression("variable1"); var variable2 = new VariableExpression("variable2"); var value1 = new IntegerConstantExpression(1); var value3 = new IntegerConstantExpression(3); var value4 = new IntegerConstantExpression(4); var expr = new DictionaryExpression(); expr.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = variable1, Value = value3 }); expr.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = variable2, Value = value4 }); var scope = new InterpreterScope(); scope.AssignVariable(variable1, value1); scope.AssignVariable(variable2, value1); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.False); Assert.That(result, Is.InstanceOf <ParseErrorExpression>()); Assert.That(((ParseErrorExpression)result).Message, Is.EqualTo("1 already exists in dictionary")); }
public void TestReplaceVariables() { var variable1 = new VariableExpression("variable1"); var variable2 = new VariableExpression("variable2"); var value1 = new IntegerConstantExpression(98); var value2 = new IntegerConstantExpression(99); var value3 = new IntegerConstantExpression(1); var value4 = new IntegerConstantExpression(2); var expr = new DictionaryExpression(); expr.Add(variable1, value3); expr.Add(value4, variable2); var scope = new InterpreterScope(); scope.AssignVariable(variable1, value1); scope.AssignVariable(variable2, value2); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <DictionaryExpression>()); var dictResult = (DictionaryExpression)result; Assert.That(dictResult.Count, Is.EqualTo(2)); // resulting list will be sorted for quicker lookups Assert.That(dictResult[0].Key, Is.EqualTo(value4)); Assert.That(dictResult[0].Value, Is.EqualTo(value2)); Assert.That(dictResult[1].Key, Is.EqualTo(value1)); Assert.That(dictResult[1].Value, Is.EqualTo(value3)); }
public void TestReplaceVariables() { var variable1 = new VariableExpression("variable1"); var variable2 = new VariableExpression("variable2"); var value1 = new IntegerConstantExpression(98); var value2 = new IntegerConstantExpression(99); var value3 = new IntegerConstantExpression(1); var expr = new ArrayExpression(); expr.Entries.Add(variable1); expr.Entries.Add(variable2); expr.Entries.Add(value3); var scope = new InterpreterScope(); scope.AssignVariable(variable1, value1); scope.AssignVariable(variable2, value2); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <ArrayExpression>()); var arrayResult = (ArrayExpression)result; Assert.That(arrayResult.Entries.Count, Is.EqualTo(3)); Assert.That(arrayResult.Entries[0], Is.EqualTo(value1)); Assert.That(arrayResult.Entries[1], Is.EqualTo(value2)); Assert.That(arrayResult.Entries[2], Is.EqualTo(value3)); }
public void TestReplaceVariables() { var variable1 = new VariableExpression("variable1"); var variable2 = new VariableExpression("variable2"); var value1 = new IntegerConstantExpression(98); var value2 = new IntegerConstantExpression(99); var value3 = new IntegerConstantExpression(1); var value4 = new IntegerConstantExpression(2); var expr = new DictionaryExpression(); expr.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = variable1, Value = value3 }); expr.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = value4, Value = variable2 }); var scope = new InterpreterScope(); scope.AssignVariable(variable1, value1); scope.AssignVariable(variable2, value2); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <DictionaryExpression>()); var dictResult = (DictionaryExpression)result; Assert.That(dictResult.Entries.Count, Is.EqualTo(2)); Assert.That(dictResult.Entries[0].Key, Is.EqualTo(value1)); Assert.That(dictResult.Entries[0].Value, Is.EqualTo(value3)); Assert.That(dictResult.Entries[1].Key, Is.EqualTo(value4)); Assert.That(dictResult.Entries[1].Value, Is.EqualTo(value2)); }
public void TestReplaceTwoDimensional() { var variable = new VariableExpression("variable"); var key = new StringConstantExpression("key"); var value = new IntegerConstantExpression(99); var dict2 = new DictionaryExpression(); dict2.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = key, Value = value }); var dict1 = new DictionaryExpression(); dict1.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = key, Value = dict2 }); var expr2 = new IndexedVariableExpression(variable, key); var expr = new IndexedVariableExpression(expr2, key); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict1); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(99)); }
public void TestReplaceVariablesIndexFunctionCall() { var input = "function func(i) => 6"; var tokenizer = new PositionalTokenizer(Tokenizer.CreateTokenizer(input)); tokenizer.Match("function"); var functionDefinition = (FunctionDefinitionExpression)FunctionDefinitionExpression.Parse(tokenizer); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { new IntegerConstantExpression(2) }); var value = new IntegerConstantExpression(98); var variable = new VariableExpression("variable"); var dict = new DictionaryExpression(); dict.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = new IntegerConstantExpression(6), Value = value }); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict); scope.AddFunction(functionDefinition); var expr = new IndexedVariableExpression(variable, functionCall); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(98)); }
public void TestReplaceVariablesIndexFunctionCall() { var functionDefinition = UserFunctionDefinitionExpression.ParseForTest("function func(i) => 6"); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { new IntegerConstantExpression(2) }); var value = new IntegerConstantExpression(98); var variable = new VariableExpression("variable"); var dict = new DictionaryExpression(); dict.Add(new IntegerConstantExpression(6), value); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict); scope.AddFunction(functionDefinition); var expr = new IndexedVariableExpression(variable, functionCall); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(98)); }
public void TestFunctionReference() { string input = "once(f)"; var requirements = new List <Requirement>(); var funcDef = new OnceFunction(); var expression = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input))); Assert.That(expression, Is.InstanceOf <FunctionCallExpression>()); var funcCall = (FunctionCallExpression)expression; var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope()); scope.AssignVariable(new VariableExpression("f"), new FunctionReferenceExpression("f2")); ExpressionBase error; scope = funcCall.GetParameters(funcDef, scope, out error); var context = new TriggerBuilderContext { Trigger = requirements }; scope.Context = context; ExpressionBase evaluated; Assert.That(funcDef.ReplaceVariables(scope, out evaluated), Is.True); funcCall = evaluated as FunctionCallExpression; var parseError = funcDef.BuildTrigger(context, scope, funcCall); Assert.That(parseError, Is.Not.Null); Assert.That(parseError.InnermostError.Message, Is.EqualTo("Function used like a variable")); }
public void TestReplaceVariablesNested() { var variable1 = new VariableExpression("variable1"); var variable2 = new VariableExpression("variable2"); var value = new IntegerConstantExpression(99); var scope = new InterpreterScope(); scope.AssignVariable(variable1, variable2); scope.AssignVariable(variable2, value); ExpressionBase result; Assert.That(variable1.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(99)); }
public void TestEvaluateDictionaryByReference() { // ensures the dictionary is passed by reference to func(), so it can be modified // within func(). it's also much more efficient to pass the dictionary by reference // instead of evaluating it (which creates a copy). var functionDefinition = Parse("function func(d) { d[\"key\"] = 2 }"); var scope = new InterpreterScope(); scope.AddFunction(functionDefinition); var dict = new DictionaryExpression(); dict.Add(new StringConstantExpression("key"), new IntegerConstantExpression(1)); scope.AssignVariable(new VariableExpression("dict"), dict); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { new VariableExpression("dict") }); ExpressionBase result; Assert.That(functionCall.Evaluate(scope, out result), Is.True); Assert.That(result, Is.Null); Assert.That(dict.Count, Is.EqualTo(1)); Assert.That(dict[0].Value, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)dict[0].Value).Value, Is.EqualTo(2)); }
public void TestAssignVariableIndexed() { var variable = new VariableExpression("test"); var value = new IntegerConstantExpression(99); var dict = new DictionaryExpression(); var key = new IntegerConstantExpression(6); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict); var index = new IndexedVariableExpression(variable, key); scope.AssignVariable(index, value); Assert.That(dict.Count, Is.EqualTo(1)); Assert.That(dict[0].Value, Is.SameAs(value)); }
public void TestAddVariables() { var value1 = new IntegerConstantExpression(1); var value2 = new IntegerConstantExpression(2); var left = new VariableExpression("left"); var right = new VariableExpression("right"); var expr = new MathematicExpression(left, MathematicOperation.Add, right); var scope = new InterpreterScope(); scope.AssignVariable(left, value1); scope.AssignVariable(right, value2); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(3)); }
public void TestAssignAndGetVariable() { var variable = new VariableExpression("test"); var value = new IntegerConstantExpression(99); var scope = new InterpreterScope(); scope.AssignVariable(variable, value); Assert.That(scope.GetVariable("test"), Is.SameAs(value)); }
public void TestAssignVariableIndexedArrayOutOfRange() { var variable = new VariableExpression("test"); var value = new IntegerConstantExpression(99); var value2 = new IntegerConstantExpression(98); var array = new ArrayExpression(); var key = new IntegerConstantExpression(1); array.Entries.Add(value); var scope = new InterpreterScope(); scope.AssignVariable(variable, array); var index = new IndexedVariableExpression(variable, key); scope.AssignVariable(index, value2); // silently does nothing, TODO: make error Assert.That(array.Entries[0], Is.SameAs(value)); }
public void TestAssignVariableIndexedArrayUpdate() { var variable = new VariableExpression("test"); var value = new IntegerConstantExpression(99); var value2 = new IntegerConstantExpression(98); var array = new ArrayExpression(); var key = new IntegerConstantExpression(0); array.Entries.Add(value); var scope = new InterpreterScope(); scope.AssignVariable(variable, array); var index = new IndexedVariableExpression(variable, key); scope.AssignVariable(index, value2); Assert.That(array.Entries[0], Is.SameAs(value2)); }
public void TestAssignVariableIndexedUpdate() { var variable = new VariableExpression("test"); var value = new IntegerConstantExpression(99); var value2 = new IntegerConstantExpression(98); var dict = new DictionaryExpression(); var key = new IntegerConstantExpression(6); dict.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = key, Value = value }); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict); var index = new IndexedVariableExpression(variable, key); scope.AssignVariable(index, value2); Assert.That(dict.Entries[0].Value, Is.SameAs(value2)); }
public void TestReplaceVariables() { var variable1 = new VariableExpression("variable1"); var variable2 = new VariableExpression("variable2"); var value1 = new IntegerConstantExpression(98); var value2 = new IntegerConstantExpression(99); var expr = new ConditionalExpression(variable1, ConditionalOperation.And, variable2); var scope = new InterpreterScope(); scope.AssignVariable(variable1, value1); scope.AssignVariable(variable2, value2); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <ConditionalExpression>()); Assert.That(((ConditionalExpression)result).Left, Is.EqualTo(value1)); Assert.That(((ConditionalExpression)result).Operation, Is.EqualTo(expr.Operation)); Assert.That(((ConditionalExpression)result).Right, Is.EqualTo(value2)); }
public void TestReplaceVariablesIndexVariable() { var variable = new VariableExpression("variable"); var key = new StringConstantExpression("key"); var index = new VariableExpression("index"); var value = new IntegerConstantExpression(99); var dict = new DictionaryExpression(); dict.Add(key, value); var expr = new IndexedVariableExpression(variable, index); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict); scope.AssignVariable(index, key); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(99)); }
public void TestReplaceVariablesArray() { var variable = new VariableExpression("variable"); var index = new IntegerConstantExpression(0); var indexVariable = new VariableExpression("index"); var value = new IntegerConstantExpression(99); var array = new ArrayExpression(); array.Entries.Add(value); var expr = new IndexedVariableExpression(variable, indexVariable); var scope = new InterpreterScope(); scope.AssignVariable(variable, array); scope.AssignVariable(indexVariable, index); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(99)); }
[TestCase("byte(1) / byte(2) * 100.0 > 75", "byte(1) / 0.75 > byte(2)")] // combine numbers, then move float to avoid integer division public void TestReplaceVariables(string input, string expected) { var tokenizer = Tokenizer.CreateTokenizer(input); var expr = ExpressionBase.Parse(new PositionalTokenizer(tokenizer)); var scope = new InterpreterScope(RATools.Parser.AchievementScriptInterpreter.GetGlobalScope()); scope.Context = new RATools.Parser.TriggerBuilderContext(); scope.AssignVariable(new VariableExpression("variable1"), new IntegerConstantExpression(98)); scope.AssignVariable(new VariableExpression("variable2"), new IntegerConstantExpression(99)); ExpressionBase result; if (!expr.ReplaceVariables(scope, out result)) { Assert.That(result, Is.InstanceOf <ParseErrorExpression>()); } var builder = new StringBuilder(); result.AppendString(builder); Assert.That(builder.ToString(), Is.EqualTo(expected)); }
public void TestReplaceVariables() { var functionDefinition = Parse("function func(i,j,k) => i*j+k"); var variable1 = new VariableExpression("variable1"); var variable2 = new VariableExpression("variable2"); var value1 = new IntegerConstantExpression(98); var value2 = new IntegerConstantExpression(99); var value3 = new IntegerConstantExpression(3); var expr = new FunctionCallExpression("func", new ExpressionBase[] { variable1, value3, variable2 }); var scope = new InterpreterScope(); scope.AssignVariable(variable1, value1); scope.AssignVariable(variable2, value2); scope.AddFunction(functionDefinition); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(98 * 3 + 99)); }
public void TestReplaceVariables() { var variable = new VariableExpression("variable"); var value = new IntegerConstantExpression(99); var expr = new ReturnExpression(variable); var scope = new InterpreterScope(); scope.AssignVariable(variable, value); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <ReturnExpression>()); Assert.That(((ReturnExpression)result).Value, Is.EqualTo(value)); }
public void TestReplaceVariablesNonDictionary() { var variable = new VariableExpression("variable"); var key = new StringConstantExpression("key"); var value = new IntegerConstantExpression(99); var expr = new IndexedVariableExpression(variable, key); var scope = new InterpreterScope(); scope.AssignVariable(variable, value); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.False); Assert.That(result, Is.InstanceOf <ParseErrorExpression>()); Assert.That(((ParseErrorExpression)result).Message, Is.EqualTo("Cannot index: variable (IntegerConstant)")); }
public void TestReplaceVariablesInvalidKey() { var variable = new VariableExpression("variable"); var key = new StringConstantExpression("key"); var dict = new DictionaryExpression(); var expr = new IndexedVariableExpression(variable, key); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.False); Assert.That(result, Is.InstanceOf <ParseErrorExpression>()); Assert.That(((ParseErrorExpression)result).Message, Is.EqualTo("No entry in dictionary for key: \"key\"")); }
private bool Evaluate(ExpressionBase expression, InterpreterScope scope) { switch (expression.Type) { case ExpressionType.Assignment: var assignment = (AssignmentExpression)expression; var assignmentScope = new InterpreterScope(scope) { Context = assignment }; ExpressionBase result; if (!assignment.Value.ReplaceVariables(assignmentScope, out result)) { Error = result as ParseErrorExpression; return(false); } scope.AssignVariable(assignment.Variable, result); return(true); case ExpressionType.FunctionCall: return(CallFunction((FunctionCallExpression)expression, scope)); case ExpressionType.For: return(EvaluateLoop((ForExpression)expression, scope)); case ExpressionType.If: return(EvaluateIf((IfExpression)expression, scope)); case ExpressionType.Return: return(EvaluateReturn((ReturnExpression)expression, scope)); case ExpressionType.ParseError: Error = expression as ParseErrorExpression; return(false); case ExpressionType.FunctionDefinition: return(EvaluateFunctionDefinition((FunctionDefinitionExpression)expression, scope)); default: Error = new ParseErrorExpression("Only assignment statements, function calls and function definitions allowed at outer scope", expression); return(false); } }
public void TestReplaceVariablesArrayIndexString() { var variable = new VariableExpression("variable"); var index = new StringConstantExpression("str"); var value = new IntegerConstantExpression(99); var array = new ArrayExpression(); array.Entries.Add(value); var expr = new IndexedVariableExpression(variable, index); var scope = new InterpreterScope(); scope.AssignVariable(variable, array); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.False); Assert.That(result, Is.InstanceOf <ParseErrorExpression>()); Assert.That(((ParseErrorExpression)result).Message, Is.EqualTo("Index does not evaluate to an integer constant")); }
public void TestEvaluateDictionaryDirect() { // ensures that a dictionary being passed directly to a function is evaluated var functionDefinition = Parse("function func(d) { return d[\"key\"] }"); var scope = new InterpreterScope(); scope.AddFunction(functionDefinition); var dict = new DictionaryExpression(); dict.Add(new StringConstantExpression("key"), new VariableExpression("variable")); scope.AssignVariable(new VariableExpression("variable"), new IntegerConstantExpression(123)); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { dict }); ExpressionBase result; Assert.That(functionCall.Evaluate(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(123)); }
public void TestReplaceVariablesIndexMathematical() { var variable = new VariableExpression("variable"); var key = new IntegerConstantExpression(6); var index = new MathematicExpression(new IntegerConstantExpression(2), MathematicOperation.Add, new IntegerConstantExpression(4)); var value = new IntegerConstantExpression(99); var dict = new DictionaryExpression(); dict.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = key, Value = value }); var expr = new IndexedVariableExpression(variable, index); var scope = new InterpreterScope(); scope.AssignVariable(variable, dict); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); Assert.That(((IntegerConstantExpression)result).Value, Is.EqualTo(99)); }