Revert "Replace legacy Evaluator with IntegerExpressions."
This reverts commit cd0898236d.
This commit is contained in:
@@ -297,6 +297,7 @@
|
|||||||
<Compile Include="Primitives\TypeDictionary.cs" />
|
<Compile Include="Primitives\TypeDictionary.cs" />
|
||||||
<Compile Include="Map\ActorInitializer.cs" />
|
<Compile Include="Map\ActorInitializer.cs" />
|
||||||
<Compile Include="Map\ActorReference.cs" />
|
<Compile Include="Map\ActorReference.cs" />
|
||||||
|
<Compile Include="Support\Evaluator.cs" />
|
||||||
<Compile Include="Settings.cs" />
|
<Compile Include="Settings.cs" />
|
||||||
<Compile Include="Graphics\PlayerColorRemap.cs" />
|
<Compile Include="Graphics\PlayerColorRemap.cs" />
|
||||||
<Compile Include="Graphics\Palette.cs" />
|
<Compile Include="Graphics\Palette.cs" />
|
||||||
|
|||||||
109
OpenRA.Game/Support/Evaluator.cs
Normal file
109
OpenRA.Game/Support/Evaluator.cs
Normal file
@@ -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<string, int>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Evaluate(string expr, Dictionary<string, int> syms)
|
||||||
|
{
|
||||||
|
var toks = Tokens(expr, "+-*/()");
|
||||||
|
var postfix = ToPostfix(toks, syms);
|
||||||
|
|
||||||
|
var s = new Stack<int>();
|
||||||
|
|
||||||
|
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<int> s, Func<int, int, int> f)
|
||||||
|
{
|
||||||
|
var x = s.Pop();
|
||||||
|
var y = s.Pop();
|
||||||
|
s.Push(f(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
static IEnumerable<string> ToPostfix(IEnumerable<string> toks, Dictionary<string, int> syms)
|
||||||
|
{
|
||||||
|
var s = new Stack<string>();
|
||||||
|
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<string, int> Prec
|
||||||
|
= new Dictionary<string, int> { { "+", 0 }, { "-", 0 }, { "*", 1 }, { "/", 1 }, { "(", -1 } };
|
||||||
|
|
||||||
|
static IEnumerable<string> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -196,10 +196,10 @@ namespace OpenRA.Widgets
|
|||||||
|
|
||||||
// Info defined in YAML
|
// Info defined in YAML
|
||||||
public string Id = null;
|
public string Id = null;
|
||||||
public IntegerExpression X;
|
public string X = "0";
|
||||||
public IntegerExpression Y;
|
public string Y = "0";
|
||||||
public IntegerExpression Width;
|
public string Width = "0";
|
||||||
public IntegerExpression Height;
|
public string Height = "0";
|
||||||
public string[] Logic = { };
|
public string[] Logic = { };
|
||||||
public ChromeLogic[] LogicObjects { get; private set; }
|
public ChromeLogic[] LogicObjects { get; private set; }
|
||||||
public bool Visible = true;
|
public bool Visible = true;
|
||||||
@@ -275,17 +275,16 @@ namespace OpenRA.Widgets
|
|||||||
substitutions.Add("PARENT_LEFT", parentBounds.Left);
|
substitutions.Add("PARENT_LEFT", parentBounds.Left);
|
||||||
substitutions.Add("PARENT_TOP", parentBounds.Top);
|
substitutions.Add("PARENT_TOP", parentBounds.Top);
|
||||||
substitutions.Add("PARENT_BOTTOM", parentBounds.Height);
|
substitutions.Add("PARENT_BOTTOM", parentBounds.Height);
|
||||||
|
var width = Evaluator.Evaluate(Width, substitutions);
|
||||||
var readOnlySubstitutions = new ReadOnlyDictionary<string, int>(substitutions);
|
var height = Evaluator.Evaluate(Height, substitutions);
|
||||||
var width = Width != null ? Width.Evaluate(readOnlySubstitutions) : 0;
|
|
||||||
var height = Height != null ? Height.Evaluate(readOnlySubstitutions) : 0;
|
|
||||||
|
|
||||||
substitutions.Add("WIDTH", width);
|
substitutions.Add("WIDTH", width);
|
||||||
substitutions.Add("HEIGHT", height);
|
substitutions.Add("HEIGHT", height);
|
||||||
|
|
||||||
var x = X != null ? X.Evaluate(readOnlySubstitutions) : 0;
|
Bounds = new Rectangle(Evaluator.Evaluate(X, substitutions),
|
||||||
var y = Y != null ? Y.Evaluate(readOnlySubstitutions) : 0;
|
Evaluator.Evaluate(Y, substitutions),
|
||||||
Bounds = new Rectangle(x, y, width, height);
|
width,
|
||||||
|
height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInit(WidgetArgs args)
|
public void PostInit(WidgetArgs args)
|
||||||
|
|||||||
Reference in New Issue
Block a user