private string Evaluate(string formatString, ExpressionBase[] parameters) { var newParameters = new List <ExpressionBase>(); newParameters.Add(new StringConstantExpression(formatString)); newParameters.AddRange(parameters); var expression = new FunctionCallExpression("format", newParameters); var scope = new InterpreterScope(); scope.AddFunction(new FormatFunction()); scope.AddFunction(new AddFunction()); ExpressionBase result; Assert.IsTrue(expression.Evaluate(scope, out result)); Assert.IsTrue(result is StringConstantExpression); return(((StringConstantExpression)result).Value); }
public void TestReplaceVariables() { var variable = new VariableExpression("variable"); var key = new StringConstantExpression("key"); var value = new IntegerConstantExpression(99); var dict = new DictionaryExpression(); dict.Add(key, value); var expr = new IndexedVariableExpression(variable, key); 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)); }
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 TestReplaceVariablesLogicalFunctionCall() { var functionDefinition = UserFunctionDefinitionExpression.ParseForTest("function func(i) => byte(i) == 1"); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { new IntegerConstantExpression(2) }); var value1 = new IntegerConstantExpression(98); var expr = new DictionaryExpression(); expr.Add(functionCall, value1); var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope()); scope.AddFunction(functionDefinition); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.False); Assert.That(result, Is.InstanceOf <ParseErrorExpression>()); Assert.That(((ParseErrorExpression)result).Message, Is.EqualTo("Dictionary key must evaluate to a constant")); }
public void TestReplaceVariablesMemoryAccessor() { var key = new IntegerConstantExpression(6); var value = new FunctionCallExpression("byte", new[] { new IntegerConstantExpression(1) }); var expr = new DictionaryExpression(); expr.Add(key, value); var scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope()); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); Assert.That(result, Is.InstanceOf <DictionaryExpression>()); var arrayResult = (DictionaryExpression)result; Assert.That(arrayResult.Count, Is.EqualTo(1)); Assert.That(arrayResult[0].Value.ToString(), Is.EqualTo(value.ToString())); }
public void TestEvaluateConditional() { var functionDefinition = Parse("function func(i) { if (i < 3) return 4 else return 8 }"); var scope = new InterpreterScope(); scope.AddFunction(functionDefinition); var value = new IntegerConstantExpression(6); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { value }); ExpressionBase result; Assert.That(functionCall.Evaluate(scope, out result), Is.True); Assert.That(result, Is.EqualTo(new IntegerConstantExpression(8))); value = new IntegerConstantExpression(2); functionCall = new FunctionCallExpression("func", new ExpressionBase[] { value }); Assert.That(functionCall.Evaluate(scope, out result), Is.True); Assert.That(result, Is.EqualTo(new IntegerConstantExpression(4))); }
[TestCase("byte(0) & 12 - 5", "byte(0) & 7")] // addition has higher precedence public void TestCombining(string input, string expected) { var expr = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input))); Assert.That(expr, Is.InstanceOf <MathematicExpression>()); var scope = new InterpreterScope(); scope.Context = new TriggerBuilderContext(); scope.AddFunction(new MemoryAccessorFunction("byte", FieldSize.Byte)); ExpressionBase result; Assert.That(expr.ReplaceVariables(scope, out result), Is.True); var builder = new StringBuilder(); result.AppendString(builder); Assert.That(builder.ToString(), Is.EqualTo(expected)); }
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.Add(key, 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)); }
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 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 TestReplaceVariablesNoReturnValue() { var functionDefinition = Parse("function func(i) { j = i }"); var scope = new InterpreterScope(); scope.AddFunction(functionDefinition); var value = new IntegerConstantExpression(6); var functionCall = new FunctionCallExpression("func", new ExpressionBase[] { value }); ExpressionBase result; Assert.That(functionCall.ReplaceVariables(scope, out result), Is.False); Assert.That(result, Is.InstanceOf <ParseErrorExpression>()); var parseError = (ParseErrorExpression)result; while (parseError.InnerError != null) { parseError = parseError.InnerError; } Assert.That(parseError.Message, Is.EqualTo("func did not return a value")); }
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 override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { if (!base.ReplaceVariables(scope, out result)) { return(false); } var func = result as FunctionCallExpression; if (func == null) { return(true); } var until = GetParameter(scope, "until", out result); result = new FunctionCallExpression(Name.Name, new ExpressionBase[] { func.Parameters.First(), until }); CopyLocation(result); return(true); }
internal FunctionInfo(FunctionDefinition node, AnalysisUnit declUnit, InterpreterScope declScope) { _projectEntry = declUnit.ProjectEntry; _functionDefinition = node; _declVersion = declUnit.ProjectEntry.AnalysisVersion; if (_functionDefinition.Name == "__new__") { IsClassMethod = true; } object value; if (!ProjectEntry.Properties.TryGetValue(AnalysisLimits.CallDepthKey, out value) || (_callDepthLimit = (value as int?) ?? -1) < 0) { _callDepthLimit = declUnit.ProjectState.Limits.CallDepth; } _analysisUnit = new FunctionAnalysisUnit(this, declUnit, declScope, _projectEntry); }
private int Evaluate(string input, InterpreterScope scope, string expectedError = null) { var funcDef = new LengthFunction(); var expression = ExpressionBase.Parse(new PositionalTokenizer(Tokenizer.CreateTokenizer(input))); Assert.That(expression, Is.InstanceOf <FunctionCallExpression>()); var funcCall = (FunctionCallExpression)expression; ExpressionBase error; var parameterScope = funcCall.GetParameters(funcDef, scope, out error); if (expectedError == null) { Assert.That(error, Is.Null); ExpressionBase result; Assert.That(funcDef.Evaluate(parameterScope, out result), Is.True); Assert.That(result, Is.InstanceOf <IntegerConstantExpression>()); return(((IntegerConstantExpression)result).Value); } else { if (error == null) { Assert.That(funcDef.Evaluate(parameterScope, out error), Is.False); } Assert.That(error, Is.InstanceOf <ParseErrorExpression>()); var parseError = (ParseErrorExpression)error; while (parseError.InnerError != null) { parseError = parseError.InnerError; } Assert.That(parseError.Message, Is.EqualTo(expectedError)); return(int.MinValue); } }
public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { if (!IsInRichPresenceDisplayClause(scope, out result)) { return(false); } var name = GetStringParameter(scope, "name", out result); if (name == null) { return(false); } var expression = GetParameter(scope, "expression", out result); if (expression == null) { return(false); } var parameter = GetParameter(scope, "dictionary", out result); if (parameter == null) { return(false); } var dictionary = parameter as DictionaryExpression; if (dictionary == null) { result = new ParseErrorExpression("dictionary is not a dictionary", parameter); return(false); } result = new FunctionCallExpression(Name.Name, new ExpressionBase[] { name, expression, dictionary }); return(true); }
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)); }
public override bool Evaluate(InterpreterScope scope, out ExpressionBase result) { var arrayExpression = GetReferenceParameter(scope, "array", out result); if (arrayExpression == null) { return(false); } var array = arrayExpression.Expression as ArrayExpression; if (array == null) { result = new ParseErrorExpression("array did not evaluate to an array", arrayExpression); return(false); } var value = GetParameter(scope, "value", out result); if (value == null) { return(false); } var variableExpression = new VariableExpression("array_push(" + arrayExpression.Variable.Name + ")"); var assignScope = new InterpreterScope(scope) { Context = new AssignmentExpression(variableExpression, value) }; if (!value.ReplaceVariables(assignScope, out result)) { return(false); } array.Entries.Add(result); result = null; return(true); }
public void TestReplaceVariablesDuplicateKey() { 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 = value1, Value = value3 }); expr.Entries.Add(new DictionaryExpression.DictionaryEntry { Key = value1, Value = value4 }); var scope = new InterpreterScope(); 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")); }
private static bool IsInFunctionParameter(InterpreterScope scope, PythonAst tree, SourceLocation location) { var function = scope.Node as FunctionDefinition; if (function == null) { // Not a function return(false); } if (location.Index < function.StartIndex || location.Index >= function.Body.StartIndex) { // Not within the def line return(false); } return(function.Parameters != null && function.Parameters.Any(p => { var paramName = p.GetVerbatimImage(tree) ?? p.Name; return location.Index >= p.StartIndex && location.Index <= p.StartIndex + paramName.Length; })); }
public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { if (!IsInRichPresenceDisplayClause(scope, out result)) { return(false); } var name = GetStringParameter(scope, "name", out result); if (name == null) { return(false); } var format = GetStringParameter(scope, "format", out result); if (format == null) { return(false); } var valueFormat = Leaderboard.ParseFormat(format.Value); if (valueFormat == ValueFormat.None) { result = new ParseErrorExpression(format.Value + " is not a supported rich_presence_value format", format); return(false); } var expression = GetParameter(scope, "expression", out result); if (expression == null) { return(false); } result = new FunctionCallExpression(Name.Name, new ExpressionBase[] { name, expression, format }); return(true); }
public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { var comparison = GetParameter(scope, "comparison", out result); if (comparison == null) { return(false); } // trigger_when(A || B) => trigger_when(A) || trigger_when(B) // trigger_when(A && B) => trigger_when(A) && trigger_when(B) var condition = comparison as ConditionalExpression; if (condition != null && !condition.IsLogicalUnit) { if (condition.Operation == ConditionalOperation.Or) { // OR within an AND must be kept as an OrNext if (scope.GetContext <TriggerWhenFunction>() != null) { condition.IsLogicalUnit = true; return(base.ReplaceVariables(scope, out result)); } return(SplitConditions(scope, condition, ConditionalOperation.Or, out result)); } if (condition.Operation == ConditionalOperation.And) { var newScope = new InterpreterScope(scope) { Context = this }; return(SplitConditions(newScope, condition, ConditionalOperation.And, out result)); } } return(base.ReplaceVariables(scope, out result)); }
internal bool Run(ExpressionGroup expressionGroup, out InterpreterScope scope) { var parseError = expressionGroup.Expressions.OfType <ParseErrorExpression>().FirstOrDefault(); if (parseError != null) { Error = parseError; scope = null; return(false); } scope = new InterpreterScope(GetGlobalScope()); scope.Context = new AchievementScriptContext { Achievements = _achievements, Leaderboards = _leaderboards, RichPresence = _richPresence }; if (!Evaluate(expressionGroup.Expressions, scope)) { var error = Error; if (error != null) { expressionGroup.Errors.Add(error); } return(false); } if (!String.IsNullOrEmpty(_richPresence.DisplayString)) { RichPresence = _richPresence.ToString(); RichPresenceLine = _richPresence.Line; } return(true); }
private bool CallFunction(FunctionCallExpression expression, InterpreterScope scope) { ExpressionBase result; bool success = expression.Invoke(scope, out result); if (!success) { if (scope.GetInterpreterContext <FunctionCallExpression>() != null) { var error = result as ParseErrorExpression; result = new ParseErrorExpression(expression.FunctionName.Name + " call failed: " + error.Message, expression.FunctionName) { InnerError = error }; } Error = result as ParseErrorExpression; return(false); } scope.ReturnValue = result; return(true); }
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.Add(variable1, value3); expr.Add(variable2, 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")); }
[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)); }
private List <Requirement> Evaluate(string input, string expectedError = null) { var requirements = new List <Requirement>(); 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()); var funcDef = scope.GetFunction(funcCall.FunctionName.Name) as MemoryAccessorFunction; Assert.That(funcDef, Is.Not.Null); var context = new TriggerBuilderContext { Trigger = requirements }; scope.Context = context; ExpressionBase evaluated; Assert.That(funcCall.ReplaceVariables(scope, out evaluated), Is.True); if (expectedError == null) { Assert.That(funcDef.BuildTrigger(context, scope, funcCall), Is.Null); } else { var parseError = funcDef.BuildTrigger(context, scope, funcCall); Assert.That(parseError, Is.Not.Null); Assert.That(parseError.Message, Is.EqualTo(expectedError)); } return(requirements); }
// Returns False if no more parameters can be updated for this unit. private bool UpdateSingleDefaultParameter(AnalysisUnit unit, InterpreterScope scope, int index, IParameterInfo info) { if (index >= FunctionDefinition.ParametersInternal.Length) { return(false); } VariableDef param; var name = FunctionDefinition.ParametersInternal[index].Name; if (scope.TryGetVariable(name, out param)) { var av = ProjectState.GetAnalysisSetFromObjects(info.ParameterTypes); if ((info.IsParamArray && !(param is ListParameterVariableDef)) || (info.IsKeywordDict && !(param is DictParameterVariableDef))) { return(false); } param.AddTypes(unit, av, true, DeclaringModule); } return(true); }
public void TestPopFunctionCall() { var scope = new InterpreterScope(); var array = new ArrayExpression(); array.Entries.Add(new FunctionCallExpression("happy", new ExpressionBase[] { new IntegerConstantExpression(1) })); scope.DefineVariable(new VariableDefinitionExpression("arr"), array); var happyFunc = new FunctionDefinitionExpression("happy"); happyFunc.Parameters.Add(new VariableDefinitionExpression("num1")); happyFunc.Expressions.Add(new ReturnExpression(new VariableExpression("num1"))); scope.AddFunction(happyFunc); var entry = Evaluate("array_pop(arr)", scope); // function call should not be evaluated when it's popped off the array Assert.That(entry, Is.InstanceOf <FunctionCallExpression>()); Assert.That(((FunctionCallExpression)entry).FunctionName.Name, Is.EqualTo("happy")); Assert.That(((FunctionCallExpression)entry).Parameters.Count, Is.EqualTo(1)); Assert.That(array.Entries.Count, Is.EqualTo(0)); }
internal bool Evaluate(IEnumerable <ExpressionBase> expressions, InterpreterScope scope, IScriptInterpreterCallback callback = null) { int i = 0; int count = expressions.Count(); foreach (var expression in expressions) { if (callback != null) { if (callback.IsAborted) { return(false); } int progress = (i * 100 / count); if (progress > 0) { callback.UpdateProgress(progress, expression.Location.Start.Line); } i++; } if (!Evaluate(expression, scope)) { return(false); } if (scope.IsComplete) { break; } } return(true); }
public IsInstanceScope(int startIndex, Block effectiveSuite, InterpreterScope outerScope) : base(null, null, outerScope) { _startIndex = _endIndex = startIndex; _effectiveSuite = effectiveSuite; }