示例#1
0
        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));
        }
示例#3
0
        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));
        }
示例#4
0
        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));
        }
示例#5
0
        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));
        }
示例#6
0
        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));
        }
示例#7
0
        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));
        }
示例#8
0
        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"));
        }
示例#9
0
        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));
        }
示例#11
0
        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));
        }
示例#12
0
        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));
        }
示例#13
0
        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));
        }
示例#14
0
        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));
        }
示例#15
0
        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));
        }
示例#16
0
        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));
        }
示例#17
0
        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));
        }
示例#18
0
        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));
        }
示例#19
0
        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));
        }
示例#21
0
        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));
        }
示例#22
0
        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));
        }
示例#23
0
        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)"));
        }
示例#24
0
        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\""));
        }
示例#25
0
        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);
            }
        }
示例#26
0
        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));
        }
示例#28
0
        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));
        }