public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { var macro = GetStringParameter(scope, "macro", out result); if (macro == null) { return(false); } if (GetValueFormat(macro.Value) == ValueFormat.None) { result = new ParseErrorExpression("Unknown rich presence macro: " + macro.Value); return(false); } var expression = GetParameter(scope, "expression", out result); if (expression == null) { return(false); } result = new FunctionCallExpression(Name.Name, new ExpressionBase[] { macro, expression }); CopyLocation(result); return(true); }
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); } if (array.Entries.Count == 0) { result = new IntegerConstantExpression(0); } else { result = array.Entries[array.Entries.Count - 1]; array.Entries.RemoveAt(array.Entries.Count - 1); } return(true); }
public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { var varargs = GetParameter(scope, "varargs", out result) as ArrayExpression; if (varargs == null) { if (!(result is ParseErrorExpression)) { result = new ParseErrorExpression("unexpected varargs"); } return(false); } var parameters = new List <ExpressionBase>(); foreach (var entry in varargs.Entries) { if (!entry.ReplaceVariables(scope, out result)) { return(false); } parameters.Add(result); } result = new FunctionCallExpression(Name.Name, parameters.ToArray()); CopyLocation(result); return(true); }
private bool Evaluate(ExpressionBase expression, InterpreterScope scope) { switch (expression.Type) { case ExpressionType.Assignment: Error = ((AssignmentExpression)expression).Evaluate(scope); return(Error == null); 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)); case ExpressionType.Comment: return(true); default: Error = new ParseErrorExpression("Only assignment statements, function calls and function definitions allowed at outer scope", expression); return(false); } }
public override bool Evaluate(InterpreterScope scope, out ExpressionBase result) { var context = scope.GetContext <AchievementScriptContext>(); if (context == null) { result = new ParseErrorExpression(Name.Name + " has no meaning outside of an achievement script"); return(false); } scope = new InterpreterScope(scope) { Context = new RichPresenceDisplayContext { RichPresence = context.RichPresence, } }; if (!base.Evaluate(scope, out result)) { return(false); } var displayString = ((StringConstantExpression)result).Value; if (!SetDisplayString(context.RichPresence, displayString, scope, out result)) { return(false); } return(true); }
private bool EvaluateReturn(ReturnExpression expression, InterpreterScope scope) { ExpressionBase result; var returnScope = new InterpreterScope(scope) { Context = new AssignmentExpression(new VariableExpression("@return"), expression.Value) }; if (!expression.Value.ReplaceVariables(returnScope, out result)) { Error = result as ParseErrorExpression; return(false); } var functionCall = result as FunctionCallExpression; if (functionCall != null) { if (!CallFunction(functionCall, returnScope)) { return(false); } scope.ReturnValue = returnScope.ReturnValue; } else { scope.ReturnValue = result; } scope.IsComplete = true; return(true); }
public void TestAddParseError() { var group = new ExpressionGroup(); Assert.That(group.Expressions, Is.Empty); Assert.That(group.ParseErrors, Is.Empty); Assert.That(group.IsEmpty); var parseError = new ParseErrorExpression("oops"); group.AddParseError(parseError); Assert.That(group.ParseErrors.Count(), Is.EqualTo(1)); Assert.That(group.ParseErrors.Contains(parseError)); Assert.That(group.Expressions, Is.Empty); Assert.That(!group.IsEmpty); var parseError2 = new ParseErrorExpression("bad"); group.AddParseError(parseError2); Assert.That(group.ParseErrors.Count(), Is.EqualTo(2)); Assert.That(group.ParseErrors.Contains(parseError)); Assert.That(group.ParseErrors.Contains(parseError2)); Assert.That(group.Expressions, Is.Empty); Assert.That(!group.IsEmpty); }
public ParseErrorExpression CallFunction(FunctionCallExpression functionCall, InterpreterScope scope) { var functionDefinition = scope.GetFunction(functionCall.FunctionName.Name); if (functionDefinition == null) { return(new UnknownVariableParseErrorExpression("Unknown function: " + functionCall.FunctionName.Name, functionCall.FunctionName)); } var triggerBuilderFunction = functionDefinition as FunctionDefinition; if (triggerBuilderFunction == null) { return(new ParseErrorExpression(functionCall.FunctionName.Name + " cannot be called from within a trigger clause", functionCall)); } var error = triggerBuilderFunction.BuildTrigger(this, scope, functionCall); if (error != null) { return(ParseErrorExpression.WrapError(error, "Function call failed.", functionCall)); } return(null); }
public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { var count = GetIntegerParameter(scope, "count", out result); if (count == null) { return(false); } var varargs = GetParameter(scope, "varargs", out result) as ArrayExpression; if (varargs == null) { if (!(result is ParseErrorExpression)) { result = new ParseErrorExpression("unexpected varargs", count); } return(false); } var parameters = new List <ExpressionBase>(); parameters.Add(count); // special case - if there's a single array parameter, assume it's a list of conditions if (varargs.Entries.Count == 1) { var arrayExpression = varargs.Entries[0] as ArrayExpression; if (arrayExpression == null) { var referenceExpression = varargs.Entries[0] as VariableReferenceExpression; if (referenceExpression != null) { arrayExpression = referenceExpression.Expression as ArrayExpression; } } if (arrayExpression != null) { varargs = arrayExpression; } } var tallyScope = new InterpreterScope(scope); tallyScope.Context = this; foreach (var entry in varargs.Entries) { if (!entry.ReplaceVariables(tallyScope, out result)) { return(false); } parameters.Add(result); } result = new FunctionCallExpression(Name.Name, parameters.ToArray()); CopyLocation(result); return(true); }
public override bool Evaluate(InterpreterScope scope, out ExpressionBase result) { var obj = GetParameter(scope, "object", out result); if (obj == null) { return(false); } switch (obj.Type) { case ExpressionType.Array: result = new IntegerConstantExpression(((ArrayExpression)obj).Entries.Count); return(true); case ExpressionType.Dictionary: result = new IntegerConstantExpression(((DictionaryExpression)obj).Count); return(true); case ExpressionType.StringConstant: result = new IntegerConstantExpression(((StringConstantExpression)obj).Value.Length); return(true); default: result = new ParseErrorExpression("Cannot calculate length of " + obj.Type); return(false); } }
public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { 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 }); CopyLocation(result); return(true); }
/// <summary> /// Processes the provided script. /// </summary> /// <returns> /// <c>true</c> if the script was successfully processed, /// <c>false</c> if not - in which case <see cref="ErrorMessage"/> will indicate why. /// </returns> public bool Run(Tokenizer input) { var expressionGroups = new ExpressionGroupCollection(); expressionGroups.Parse(input); if (Error == null) { foreach (var group in expressionGroups.Groups) { Error = group.ParseErrors.FirstOrDefault(); if (Error != null) { return(false); } } } GameTitle = null; foreach (var comment in expressionGroups.Groups.First().Expressions.OfType <CommentExpression>()) { if (comment.Value.Contains("#ID")) { ExtractGameId(new Token(comment.Value, 0, comment.Value.Length)); break; } else if (GameTitle == null) { GameTitle = comment.Value.Substring(2).Trim(); } } return(Run(expressionGroups, null)); }
internal bool PopulateFromExpression(ExpressionBase expression, InterpreterScope scope, out ParseErrorExpression error) { var andedConditions = new List <ExpressionBase>(); var orConditions = new List <ExpressionBase>(); if (!SortConditions(expression, andedConditions, orConditions, out error)) { return(false); } if (orConditions.Count() > 1) { var altPart = CrossMultiplyOrConditions(orConditions); if (altPart.Type == ExpressionType.ParseError) { expression.CopyLocation(altPart); error = (ParseErrorExpression)altPart; return(false); } andedConditions.Add(altPart); } else if (orConditions.Count() == 1) { andedConditions.Add(orConditions[0]); } var context = new TriggerBuilderContext { Trigger = CoreRequirements }; var innerScope = new InterpreterScope(scope) { Context = context }; foreach (var condition in andedConditions) { error = ExecuteAchievementClause(condition, innerScope); if (error != null) { switch (condition.Type) { case ExpressionType.Comparison: case ExpressionType.Conditional: break; default: error = ParseErrorExpression.WrapError(error, "Invalid condition", condition); break; } return(false); } } return(true); }
private bool EvaluateLoop(ForExpression forExpression, InterpreterScope scope) { ExpressionBase range; if (!forExpression.Range.ReplaceVariables(scope, out range)) { Error = range as ParseErrorExpression; return(false); } var iterableExpression = range as IIterableExpression; if (iterableExpression != null) { var iterator = forExpression.IteratorName; var iteratorScope = new InterpreterScope(scope); var iteratorVariable = new VariableExpression(iterator.Name); foreach (var entry in iterableExpression.IterableExpressions()) { iteratorScope.Context = new AssignmentExpression(iteratorVariable, entry); ExpressionBase key; if (!entry.ReplaceVariables(iteratorScope, out key)) { Error = key as ParseErrorExpression; return(false); } var loopScope = new InterpreterScope(scope); loopScope.DefineVariable(iterator, key); if (!Evaluate(forExpression.Expressions, loopScope)) { return(false); } if (loopScope.IsComplete) { if (loopScope.ReturnValue != null) { scope.ReturnValue = loopScope.ReturnValue; scope.IsComplete = true; } break; } } return(true); } Error = new ParseErrorExpression("Cannot iterate over " + forExpression.Range.ToString(), forExpression.Range); return(false); }
public override bool Evaluate(InterpreterScope scope, out ExpressionBase result) { var context = scope.GetContext <RichPresenceDisplayContext>(); if (context == null) { result = new ParseErrorExpression(Name.Name + " has no meaning outside of a rich_presence_display call"); return(false); } return(BuildMacro(context, scope, out result)); }
public override bool Evaluate(InterpreterScope scope, out ExpressionBase result) { var context = scope.GetInterpreterContext <TriggerBuilderContext>(); if (context == null) { result = new ParseErrorExpression(Name.Name + " has no meaning outside of a trigger clause"); return(false); } return(ReplaceVariables(scope, out result)); }
private bool EvaluateIf(IfExpression ifExpression, InterpreterScope scope) { ParseErrorExpression error; bool result = ifExpression.Condition.IsTrue(scope, out error); if (error != null) { Error = error; return(false); } return(Evaluate(result ? ifExpression.Expressions : ifExpression.ElseExpressions, scope)); }
public override bool ReplaceVariables(InterpreterScope scope, out ExpressionBase result) { var tally = scope.GetContext <TallyFunction>(); // explicitly in tally clause if (tally == null) { var assignment = scope.GetInterpreterContext <AssignmentExpression>(); // in generic assignment clause - may be used byte rich_presence_display - will determine later if (assignment == null) { result = new ParseErrorExpression(Name.Name + " has no meaning outside of a tally call"); return(false); } } return(base.ReplaceVariables(scope, out result)); }
protected ParseErrorExpression BuildTriggerCondition(TriggerBuilderContext context, InterpreterScope scope, ExpressionBase condition) { var builder = new ScriptInterpreterAchievementBuilder(); ExpressionBase result; if (!TriggerBuilderContext.ProcessAchievementConditions(builder, condition, scope, out result)) { return((ParseErrorExpression)result); } if (builder.AlternateRequirements.Count > 0) { return(new ParseErrorExpression(Name.Name + " does not support ||'d conditions", condition)); } if (builder.CoreRequirements.Count > 1) { var last = builder.CoreRequirements.Last(); foreach (var requirement in builder.CoreRequirements) { if (requirement.Type == RequirementType.None && !ReferenceEquals(requirement, last)) { requirement.Type = RequirementType.AndNext; } } } ParseErrorExpression error = ValidateSingleCondition(builder.CoreRequirements); if (error != null) { return(new ParseErrorExpression(error, condition)); } error = ModifyRequirements(builder); if (error != null) { return(error); } foreach (var requirement in builder.CoreRequirements) { context.Trigger.Add(requirement); } return(null); }
protected bool IsInRichPresenceDisplayClause(InterpreterScope scope, out ExpressionBase result) { var richPresence = scope.GetContext <RichPresenceDisplayContext>(); // explicitly in rich_presence_display clause if (richPresence == null) { var assignment = scope.GetInterpreterContext <AssignmentExpression>(); // in generic assignment clause - may be used byte rich_presence_display - will determine later if (assignment == null) { result = new ParseErrorExpression(Name.Name + " has no meaning outside of a rich_presence_display call"); return(false); } } result = null; return(true); }
private bool WrapMemoryAccessor(ExpressionBase expression, InterpreterScope scope, out ExpressionBase result) { var functionCall = expression as FunctionCallExpression; if (functionCall == null) { result = new ParseErrorExpression("accessor did not evaluate to a memory accessor", expression); return(false); } var functionDefinition = scope.GetFunction(functionCall.FunctionName.Name); var memoryAccessor = functionDefinition as MemoryAccessorFunction; if (memoryAccessor == null) { if (!(functionDefinition is PrevPriorFunction)) { result = new ParseErrorExpression("accessor did not evaluate to a memory accessor", expression); return(false); } if (this.Name.Name == "bcd" && functionDefinition.Name.Name != "bcd") { // bcd(prev(X)) => no change } else if (functionDefinition.Name.Name == "bcd" && this.Name.Name != "bcd") { // prev(bcd(X)) => bcd(prev(X)) var nestedFunctionCall = new FunctionCallExpression(this.Name.Name, functionCall.Parameters); functionCall.CopyLocation(nestedFunctionCall); result = new FunctionCallExpression(functionDefinition.Name.Name, new[] { nestedFunctionCall }); CopyLocation(result); return(true); } else { result = new ParseErrorExpression("cannot apply multiple modifiers to memory accessor", expression); return(false); } } result = new FunctionCallExpression(Name.Name, new ExpressionBase[] { functionCall }); CopyLocation(result); return(true); }
protected bool IsInTriggerClause(InterpreterScope scope, out ExpressionBase result) { var triggerContext = scope.GetContext <TriggerBuilderContext>(); if (triggerContext == null) // explicitly in trigger clause { var assignment = scope.GetInterpreterContext <AssignmentExpression>(); if (assignment == null) // in generic assignment clause - may be used in a trigger - will determine later { result = new ParseErrorExpression(Name.Name + " has no meaning outside of a trigger clause"); return(false); } } result = null; return(true); }
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); } }
internal bool PopulateFromExpression(ExpressionBase expression, InterpreterScope scope, out ParseErrorExpression error) { if (!NormalizeNots(ref expression, out error)) { return(false); } var andedConditions = new List <ExpressionBase>(); var orConditions = new List <ExpressionBase>(); if (!SortConditions(expression, andedConditions, orConditions, out error)) { return(false); } if (orConditions.Count() != 0) { var altPart = CrossMultiplyOrConditions(orConditions); andedConditions.Add(altPart); } var context = new TriggerBuilderContext { Trigger = CoreRequirements }; var innerScope = new InterpreterScope(scope) { Context = context }; foreach (var condition in andedConditions) { error = ExecuteAchievementExpression(condition, innerScope); if (error != null) { if (error.InnerError != null) { error = new ParseErrorExpression(error.InnermostError.Message, error.Line, error.Column, error.EndLine, error.EndColumn); } return(false); } } return(true); }
private void UpdateErrorList() { ServiceRepository.Instance.FindService <IBackgroundWorkerService>().InvokeOnUiThread(() => { ErrorsToolWindow.References.Clear(); foreach (var error in _parsedContent.Errors) { var errors = new Stack <CodeReferenceViewModel>(); ParseErrorExpression innerError = error; while (innerError != null) { errors.Push(new CodeReferenceViewModel { StartLine = innerError.Location.Start.Line, StartColumn = innerError.Location.Start.Column, EndLine = innerError.Location.End.Line, EndColumn = innerError.Location.End.Column, Message = innerError.Message }); innerError = innerError.InnerError; } int depth = 0; while (errors.Count() > 0) { var errorViewModel = errors.Pop(); if (depth > 0) { errorViewModel.Message = "> " + errorViewModel.Message; if (depth > 1) { errorViewModel.Message = new string(' ', (depth - 1) * 2) + errorViewModel.Message; } } ErrorsToolWindow.References.Add(errorViewModel); depth++; } } }); }
private bool EvaluateIf(IfExpression ifExpression, InterpreterScope scope) { ParseErrorExpression error; bool?result = ifExpression.Condition.IsTrue(scope, out error); if (error != null) { Error = error; return(false); } if (result == null) { Error = new ParseErrorExpression("Condition did not evaluate to a boolean.", ifExpression.Condition); return(false); } return(Evaluate(result.GetValueOrDefault() ? ifExpression.Expressions : ifExpression.ElseExpressions, scope)); }
/// <summary> /// Populates an achievement from an expression. /// </summary> /// <param name="achievement">The achievement to populate.</param> /// <param name="expression">The expression to populate from.</param> /// <param name="scope">The scope.</param> /// <param name="result">[out] The error if not successful.</param> /// <returns><c>true</c> if successful, <c>false</c> if not.</returns> public static bool ProcessAchievementConditions(ScriptInterpreterAchievementBuilder achievement, ExpressionBase expression, InterpreterScope scope, out ExpressionBase result) { ParseErrorExpression parseError; if (!achievement.PopulateFromExpression(expression, scope, out parseError)) { result = parseError; return(false); } var message = achievement.Optimize(); if (message != null) { result = new ParseErrorExpression(message, expression); return(false); } result = null; return(true); }
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 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); }
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); }