/// <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)); }
private ExpressionGroupCollection Parse(string input) { var tokenizer = Tokenizer.CreateTokenizer(input); var parser = new ExpressionGroupCollection(); parser.Parse(tokenizer); return(parser); }
private ExpressionGroupCollection Parse(string input) { var tokenizer = Tokenizer.CreateTokenizer(input); var parser = new ExpressionGroupCollection(); parser.Scope = new InterpreterScope(); parser.Parse(tokenizer); foreach (var group in parser.Groups) { group.MarkEvaluated(); } return(parser); }
public void TestUpdateErrorLine() { var input = "a = 3\n" + "achievement(\"t\", \"d\", 5, \n" + " once()\n" + ")\n"; var tokenizer = Tokenizer.CreateTokenizer(input); var group = new ExpressionGroupCollection(); group.Scope = RATools.Parser.AchievementScriptInterpreter.GetGlobalScope(); group.Parse(tokenizer); var interpreter = new RATools.Parser.AchievementScriptInterpreter(); interpreter.Run(group, null); Assert.That(group.HasEvaluationErrors, Is.True); Assert.That(group.Errors.First().Location.Start.Line, Is.EqualTo(3)); var updatedInput = "a = 3\n" + "\n" + "\n" + "achievement(\"t\", \"d\", 5, \n" + " once()\n" + ")\n"; group.Update(Tokenizer.CreateTokenizer(updatedInput), new int[] { 2, 3 }); Assert.That(group.HasEvaluationErrors, Is.True); var error = group.Errors.First(); Assert.That(error.Location.Start.Line, Is.EqualTo(5)); Assert.That(error.InnermostError.Location.Start.Line, Is.EqualTo(5)); group.Update(Tokenizer.CreateTokenizer(input), new int[] { 2, 3 }); Assert.That(group.HasEvaluationErrors, Is.True); error = group.Errors.First(); Assert.That(error.Location.Start.Line, Is.EqualTo(3)); Assert.That(error.InnermostError.Location.Start.Line, Is.EqualTo(3)); }
public void TestUpdateSourceLine() { var input = "a = 3\n" + "achievement(\"t\", \"d\", 5, byte(0x1234) == a)\n" + "leaderboard(\"t\", \"d\", byte(0x1234) == a, byte(0x1234) == a + 1, byte(0x1234) == a + 2, byte(0x2345))\n"; var tokenizer = Tokenizer.CreateTokenizer(input); var group = new ExpressionGroupCollection(); group.Scope = RATools.Parser.AchievementScriptInterpreter.GetGlobalScope(); group.Parse(tokenizer); var interpreter = new RATools.Parser.AchievementScriptInterpreter(); interpreter.Run(group, null); Assert.That(group.Groups.Count, Is.EqualTo(3)); Assert.That(group.Groups[1].GeneratedAchievements.First().SourceLine, Is.EqualTo(2)); Assert.That(group.Groups[2].GeneratedLeaderboards.First().SourceLine, Is.EqualTo(3)); var updatedInput = "a = 3\n" + "\n" + "\n" + "achievement(\"t\", \"d\", 5, byte(0x1234) == a)\n" + "leaderboard(\"t\", \"d\", byte(0x1234) == a, byte(0x1234) == a + 1, byte(0x1234) == a + 2, byte(0x2345))\n"; group.Update(Tokenizer.CreateTokenizer(updatedInput), new int[] { 2, 3 }); Assert.That(group.Groups.Count, Is.EqualTo(3)); Assert.That(group.Groups[1].GeneratedAchievements.First().SourceLine, Is.EqualTo(4)); Assert.That(group.Groups[2].GeneratedLeaderboards.First().SourceLine, Is.EqualTo(5)); group.Update(Tokenizer.CreateTokenizer(input), new int[] { 2, 3 }); Assert.That(group.Groups.Count, Is.EqualTo(3)); Assert.That(group.Groups[1].GeneratedAchievements.First().SourceLine, Is.EqualTo(2)); Assert.That(group.Groups[2].GeneratedLeaderboards.First().SourceLine, Is.EqualTo(3)); }
internal bool Run(ExpressionGroupCollection expressionGroups, IScriptInterpreterCallback callback) { AchievementScriptContext scriptContext = null; InterpreterScope scope = expressionGroups.Scope; if (scope != null) { scriptContext = scope.GetContext <AchievementScriptContext>(); } if (scriptContext == null) { scriptContext = new AchievementScriptContext(); scope = new InterpreterScope(expressionGroups.Scope ?? GetGlobalScope()) { Context = scriptContext }; } expressionGroups.ResetErrors(); bool result = true; foreach (var expressionGroup in expressionGroups.Groups) { if (expressionGroup.NeedsEvaluated) { if (scriptContext.Achievements == null) { scriptContext.Achievements = new List <Achievement>(); } if (scriptContext.Leaderboards == null) { scriptContext.Leaderboards = new List <Leaderboard>(); } if (scriptContext.RichPresence == null) { scriptContext.RichPresence = new RichPresenceBuilder(); } if (!Evaluate(expressionGroup.Expressions, scope, callback)) { var error = Error; if (error != null) { expressionGroups.AddEvaluationError(error); } result = false; } if (scriptContext.Achievements.Count > 0) { expressionGroup.GeneratedAchievements = scriptContext.Achievements; scriptContext.Achievements = null; } else if (expressionGroup.GeneratedAchievements != null) { expressionGroup.GeneratedAchievements = null; } if (scriptContext.Leaderboards.Count > 0) { expressionGroup.GeneratedLeaderboards = scriptContext.Leaderboards; scriptContext.Leaderboards = null; } else if (expressionGroup.GeneratedLeaderboards != null) { expressionGroup.GeneratedLeaderboards = null; } if (!scriptContext.RichPresence.IsEmpty) { expressionGroup.GeneratedRichPresence = scriptContext.RichPresence; scriptContext.RichPresence = null; } expressionGroup.MarkEvaluated(); } } if (!ReferenceEquals(scope, expressionGroups.Scope)) { if (scope.FunctionCount > 0 || scope.VariableCount > 0) { if (expressionGroups.Scope != null) { expressionGroups.Scope.Merge(scope); } else { expressionGroups.Scope = scope; } } } _achievements.Clear(); _leaderboards.Clear(); _richPresence.Clear(); foreach (var expressionGroup in expressionGroups.Groups) { if (expressionGroup.GeneratedAchievements != null) { _achievements.AddRange(expressionGroup.GeneratedAchievements); } if (expressionGroup.GeneratedLeaderboards != null) { _leaderboards.AddRange(expressionGroup.GeneratedLeaderboards); } if (expressionGroup.GeneratedRichPresence != null) { var error = _richPresence.Merge(expressionGroup.GeneratedRichPresence); if (error != null) { expressionGroups.AddEvaluationError(error); result = false; } } } double minimumVersion = 0.30; foreach (var achievement in _achievements) { var achievementMinimumVersion = AchievementBuilder.GetMinimumVersion(achievement); if (achievementMinimumVersion > minimumVersion) { minimumVersion = achievementMinimumVersion; } } foreach (var leaderboard in _leaderboards) { var leaderboardMinimumVersion = AchievementBuilder.GetMinimumVersion(leaderboard); if (leaderboardMinimumVersion > minimumVersion) { minimumVersion = leaderboardMinimumVersion; } } _richPresence.DisableLookupCollapsing = (minimumVersion < 0.79); _richPresence.DisableBuiltInMacros = (minimumVersion < 0.80); if (!String.IsNullOrEmpty(_richPresence.DisplayString)) { RichPresence = _richPresence.ToString(); RichPresenceLine = _richPresence.Line; } if (Error == null) { Error = expressionGroups.Errors.FirstOrDefault(); } return(result); }
protected override void OnUpdateSyntax(ContentChangedEventArgs e) { bool needsUpdate = false; // parse immediately so we can update the syntax highlighting var tokenizer = Tokenizer.CreateTokenizer(e.Content); if (_parsedContent == null || e.Type == ContentChangeType.Refresh) { _parsedContent = new ExpressionGroupCollection(); _parsedContent.Scope = new InterpreterScope(AchievementScriptInterpreter.GetGlobalScope()); _parsedContent.Scope.Context = new AchievementScriptContext(); lock (_parsedContent) { _parsedContent.Parse(tokenizer); needsUpdate = true; } } else if (e.Type == ContentChangeType.Update) { lock (_parsedContent) { needsUpdate = _parsedContent.Update(tokenizer, e.AffectedLines); } if (!needsUpdate && !e.IsAborted) { UpdateErrorList(); } } if (needsUpdate && !e.IsAborted) { // running the script can take a lot of time, push that work onto a background thread and show progress bar UpdateProgress(1, 0); // make sure to at least show the script file in the editor list if (!_owner.Editors.Any()) { _owner.PopulateEditorList(null); } ServiceRepository.Instance.FindService <IBackgroundWorkerService>().RunAsync(() => { if (!e.IsAborted) { // run the script var callback = new ScriptInterpreterCallback(this, e); var interpreter = new AchievementScriptInterpreter(); bool hadErrors, hasErrors; lock (_parsedContent) { hadErrors = _parsedContent.HasEvaluationErrors; hasErrors = !interpreter.Run(_parsedContent, callback); } if (!e.IsAborted) { UpdateProgress(100, 0); // if any errors were added or removed, update the highlighting if (hasErrors != hadErrors) { UpdateSyntaxHighlighting(e); } // report any errors UpdateErrorList(); if (!e.IsAborted) { // update the editor list _owner.PopulateEditorList(interpreter); } } } // make sure the progress bar is hidden UpdateProgress(0, 0); }); } base.OnUpdateSyntax(e); }