From 4f16b0d46486c22c13e093243f858aa96e5d6a41 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Fri, 7 Jul 2017 21:47:16 +0100 Subject: [PATCH] Revert "Replace legacy Evaluator with IntegerExpressions." This reverts commit cd0898236d934cfe5701b1d90a051bc5004a5348. --- OpenRA.Game/OpenRA.Game.csproj | 1 + OpenRA.Game/Support/Evaluator.cs | 109 +++++++++++++++++++++++++++++++ OpenRA.Game/Widgets/Widget.cs | 21 +++--- 3 files changed, 120 insertions(+), 11 deletions(-) create mode 100644 OpenRA.Game/Support/Evaluator.cs diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index dd5530d090..5c2fc91229 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -297,6 +297,7 @@ + diff --git a/OpenRA.Game/Support/Evaluator.cs b/OpenRA.Game/Support/Evaluator.cs new file mode 100644 index 0000000000..40a235634c --- /dev/null +++ b/OpenRA.Game/Support/Evaluator.cs @@ -0,0 +1,109 @@ +#region Copyright & License Information +/* + * Copyright 2007-2017 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace OpenRA.Support +{ + public static class Evaluator + { + public static int Evaluate(string expr) + { + return Evaluate(expr, new Dictionary()); + } + + public static int Evaluate(string expr, Dictionary syms) + { + var toks = Tokens(expr, "+-*/()"); + var postfix = ToPostfix(toks, syms); + + var s = new Stack(); + + foreach (var t in postfix) + { + switch (t[0]) + { + case '+': ApplyBinop(s, (x, y) => y + x); break; + case '-': ApplyBinop(s, (x, y) => y - x); break; + case '*': ApplyBinop(s, (x, y) => y * x); break; + case '/': ApplyBinop(s, (x, y) => y / x); break; + default: s.Push(Exts.ParseIntegerInvariant(t)); break; + } + } + + return s.Pop(); + } + + static void ApplyBinop(Stack s, Func f) + { + var x = s.Pop(); + var y = s.Pop(); + s.Push(f(x, y)); + } + + static IEnumerable ToPostfix(IEnumerable toks, Dictionary syms) + { + var s = new Stack(); + foreach (var t in toks) + { + if (t[0] == '(') s.Push(t); + else if (t[0] == ')') + { + var temp = ""; + while ((temp = s.Pop()) != "(") yield return temp; + } + else if (char.IsNumber(t[0])) yield return t; + else if (char.IsLetter(t[0])) + { + if (!syms.ContainsKey(t)) + throw new InvalidOperationException("Substitution `{0}` undefined".F(t)); + + yield return syms[t].ToString(); + } + else + { + while (s.Count > 0 && Prec[t] <= Prec[s.Peek()]) yield return s.Pop(); + s.Push(t); + } + } + + while (s.Count > 0) yield return s.Pop(); + } + + static readonly Dictionary Prec + = new Dictionary { { "+", 0 }, { "-", 0 }, { "*", 1 }, { "/", 1 }, { "(", -1 } }; + + static IEnumerable Tokens(string expr, string ops) + { + var s = ""; + foreach (var c in expr) + { + if (char.IsWhiteSpace(c)) + { + if (s != "") yield return s; + s = ""; + } + else if (ops.Contains(c)) + { + if (s != "") yield return s; + s = ""; + yield return "" + c; + } + else + s += c; + } + + if (s != "") yield return s; + } + } +} diff --git a/OpenRA.Game/Widgets/Widget.cs b/OpenRA.Game/Widgets/Widget.cs index 1a20c6fe06..41a099a9ea 100644 --- a/OpenRA.Game/Widgets/Widget.cs +++ b/OpenRA.Game/Widgets/Widget.cs @@ -196,10 +196,10 @@ namespace OpenRA.Widgets // Info defined in YAML public string Id = null; - public IntegerExpression X; - public IntegerExpression Y; - public IntegerExpression Width; - public IntegerExpression Height; + public string X = "0"; + public string Y = "0"; + public string Width = "0"; + public string Height = "0"; public string[] Logic = { }; public ChromeLogic[] LogicObjects { get; private set; } public bool Visible = true; @@ -275,17 +275,16 @@ namespace OpenRA.Widgets substitutions.Add("PARENT_LEFT", parentBounds.Left); substitutions.Add("PARENT_TOP", parentBounds.Top); substitutions.Add("PARENT_BOTTOM", parentBounds.Height); - - var readOnlySubstitutions = new ReadOnlyDictionary(substitutions); - var width = Width != null ? Width.Evaluate(readOnlySubstitutions) : 0; - var height = Height != null ? Height.Evaluate(readOnlySubstitutions) : 0; + var width = Evaluator.Evaluate(Width, substitutions); + var height = Evaluator.Evaluate(Height, substitutions); substitutions.Add("WIDTH", width); substitutions.Add("HEIGHT", height); - var x = X != null ? X.Evaluate(readOnlySubstitutions) : 0; - var y = Y != null ? Y.Evaluate(readOnlySubstitutions) : 0; - Bounds = new Rectangle(x, y, width, height); + Bounds = new Rectangle(Evaluator.Evaluate(X, substitutions), + Evaluator.Evaluate(Y, substitutions), + width, + height); } public void PostInit(WidgetArgs args)