From de323dfa87c8d0104d5b2c197481333b024f323b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20S=C3=A9gaud?= Date: Fri, 1 Sep 2017 14:53:01 +0200 Subject: [PATCH 1/8] Added new operations log, log10, exp, floor, ceil, trunc. --- Library/Interpreter.Operators.cs | 85 ++++++++++++++++++++++++++++++++ Test/Program.cs | 34 +++++++++++++ 2 files changed, 119 insertions(+) diff --git a/Library/Interpreter.Operators.cs b/Library/Interpreter.Operators.cs index 461c9e7..0e445b8 100644 --- a/Library/Interpreter.Operators.cs +++ b/Library/Interpreter.Operators.cs @@ -365,6 +365,91 @@ public override double GetValue(Interpreter interpreter) } } + [Operator("ceil", 8)] + private class CeilNode : UnaryNode + { + public CeilNode(Node input) + : base(input) + { + } + + public override double GetValue(Interpreter interpreter) + { + return System.Math.Ceiling(this.input.GetValue(interpreter)); + } + } + + [Operator("floor", 8)] + private class FlorrNode : UnaryNode + { + public FlorrNode(Node input) + : base(input) + { + } + + public override double GetValue(Interpreter interpreter) + { + return System.Math.Floor(this.input.GetValue(interpreter)); + } + } + + [Operator("trunc", 8)] + private class TruncNode : UnaryNode + { + public TruncNode(Node input) + : base(input) + { + } + + public override double GetValue(Interpreter interpreter) + { + return System.Math.Truncate(this.input.GetValue(interpreter)); + } + } + + [Operator("log", 8)] + private class LogNode : UnaryNode + { + public LogNode(Node input) + : base(input) + { + } + + public override double GetValue(Interpreter interpreter) + { + return System.Math.Log(this.input.GetValue(interpreter)); + } + } + + [Operator("log10", 8)] + private class Log10Node : UnaryNode + { + public Log10Node(Node input) + : base(input) + { + } + + public override double GetValue(Interpreter interpreter) + { + return System.Math.Log10(this.input.GetValue(interpreter)); + } + } + + [Operator("e", 8)] + [Operator("exp", 8)] + private class ExpNode : UnaryNode + { + public ExpNode(Node input) + : base(input) + { + } + + public override double GetValue(Interpreter interpreter) + { + return System.Math.Exp(this.input.GetValue(interpreter)); + } + } + #endregion #region BinaryNode diff --git a/Test/Program.cs b/Test/Program.cs index 2877fcd..a37378a 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -165,6 +165,40 @@ static void Main(string[] args) success &= Test("min2,1", System.Math.Min(1, 2)); success &= Test("min2 1", System.Math.Min(1, 2)); + // Rounding + success &= Test("round(1.0)", System.Math.Round(1.0d)); + success &= Test("round(1.1)", System.Math.Round(1.1d)); + success &= Test("round(1.5)", System.Math.Round(1.5d)); + success &= Test("round(1.9)", System.Math.Round(1.9d)); + success &= Test("trunc(1.0)", System.Math.Truncate(1.0d)); + success &= Test("trunc(1.1)", System.Math.Truncate(1.1d)); + success &= Test("trunc(1.5)", System.Math.Truncate(1.5d)); + success &= Test("trunc(1.9)", System.Math.Truncate(1.9d)); + success &= Test("floor(1.0)", System.Math.Floor(1.0d)); + success &= Test("floor(1.1)", System.Math.Floor(1.1d)); + success &= Test("floor(1.5)", System.Math.Floor(1.5d)); + success &= Test("floor(1.9)", System.Math.Floor(1.9d)); + success &= Test("ceil(1.0)", System.Math.Ceiling(1.0d)); + success &= Test("ceil(1.1)", System.Math.Ceiling(1.1d)); + success &= Test("ceil(1.5)", System.Math.Ceiling(1.5d)); + success &= Test("ceil(1.9)", System.Math.Ceiling(1.9d)); + + // Algebra. + success &= Test("log(0.5)", System.Math.Log(.5d)); + success &= Test("log(1.0)", System.Math.Log(1d)); + success &= Test("log(2.0)", System.Math.Log(2d)); + //success &= Test("log10(0.5)", System.Math.Log10(.5d)); + //success &= Test("log10(1.0)", System.Math.Log10(1d)); + //success &= Test("log10(2.0)", System.Math.Log10(2d)); + success &= Test("e(0.0)", System.Math.Exp(0d)); + success &= Test("e(0.5)", System.Math.Exp(.5d)); + success &= Test("e(1.0)", System.Math.Exp(1d)); + success &= Test("e(2.0)", System.Math.Exp(2d)); + success &= Test("exp(0.0)", System.Math.Exp(0d)); + success &= Test("exp(0.5)", System.Math.Exp(.5d)); + success &= Test("exp(1.0)", System.Math.Exp(1d)); + success &= Test("exp(2.0)", System.Math.Exp(2d)); + System.Console.WriteLine("--------------------\nOVERALL RESULT: " + success); } From a55340818f985693f42dab5978dfd3fcfa4c9f21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20S=C3=A9gaud?= Date: Fri, 1 Sep 2017 12:37:13 +0200 Subject: [PATCH 2/8] Fixed #12 --- Library/Interpreter.Operators.cs | 2 ++ Library/Interpreter.cs | 3 ++- Test/Program.cs | 31 ++++++++++++++++++------------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/Library/Interpreter.Operators.cs b/Library/Interpreter.Operators.cs index 461c9e7..f718b07 100644 --- a/Library/Interpreter.Operators.cs +++ b/Library/Interpreter.Operators.cs @@ -295,6 +295,7 @@ public override double GetValue(Interpreter interpreter) } } + [Operator("deg2rad", 13)] [Operator("degrad", 13)] private class Deg2RadNode : UnaryNode { @@ -309,6 +310,7 @@ public override double GetValue(Interpreter interpreter) } } + [Operator("rad2deg", 13)] [Operator("raddeg", 13)] private class Rad2DegNode : UnaryNode { diff --git a/Library/Interpreter.cs b/Library/Interpreter.cs index 17656c4..b5818a3 100644 --- a/Library/Interpreter.cs +++ b/Library/Interpreter.cs @@ -207,7 +207,8 @@ private static bool IsNumeric(char c) private static int SkipString(string value, int index) { // Also alow dots for names context cariable access `$xxx.yyy`. - while (index < value.Length && (Interpreter.IsAlpha(value[index]) || value[index] == '.')) + // [#12] Operators with names containing digits fail -> Fixed by adding IsNumeric(). + while (index < value.Length && (Interpreter.IsAlpha(value[index]) || Interpreter.IsNumeric(value[index]) || value[index] == '.')) { ++index; } diff --git a/Test/Program.cs b/Test/Program.cs index 2877fcd..8209de0 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -43,7 +43,7 @@ static void Main(string[] args) interpreter.SetVar("Foo", foo); interpreter.SetVar("bar", bar); interpreter.SetVar("hundred", hundred); - + bool success = true; // Old tests. @@ -53,13 +53,14 @@ static void Main(string[] args) success &= Test("2 + 2", 2 + 2d); success &= Test("2+2", 2d + 2d); success &= Test("(2+2)", 2d + 2d); - success &= Test("sqrt4+3*4", System.Math.Sqrt(4) + 3 * 4); - success &= Test("(sqrt4+3)*4", (System.Math.Sqrt(4) + 3) * 4); + success &= Test("sqrt 4 + 3 * 4", System.Math.Sqrt(4) + 3 * 4); + success &= Test("sqrt 4+3*4", System.Math.Sqrt(4) + 3 * 4); + success &= Test("(sqrt 4+3)*4", (System.Math.Sqrt(4) + 3) * 4); success &= Test("5 * ±1", 5 * -1d); success &= Test("abs ±1", System.Math.Abs(-1d)); success &= Test("sin(1+2)", System.Math.Sin(1 + 2)); - success &= Test("sin1+2", System.Math.Sin(1) + 2); - success &= Test("sin1*cos2+cos1*sin2", System.Math.Sin(1) * System.Math.Cos(2) + System.Math.Cos(1) * System.Math.Sin(2)); + success &= Test("sin 1+2", System.Math.Sin(1) + 2); + success &= Test("sin 1*cos 2+cos 1*sin 2", System.Math.Sin(1) * System.Math.Cos(2) + System.Math.Cos(1) * System.Math.Sin(2)); success &= Test("(2 * 5 == 10) * 5", (2d * 5d == 10 ? 1d : 0d) * 5d); success &= Test("min 4 6", System.Math.Min(4d, 6d)); success &= Test("max 4 6", System.Math.Max(4d, 6d)); @@ -71,7 +72,7 @@ static void Main(string[] args) success &= Test("sqrt($hundred^2)", System.Math.Sqrt(hundred * hundred)); success &= Test("$Foo + $bar", foo + bar); success &= Test("round (rand * 10 + 90)"); - success &= Test("1d4+1 + 1D6+1"); + success &= Test("1 d 4+1 + 1 D 6+1"); // Comparison. success &= Test("1 == 0", BoolToDouble(1d == 0d)); @@ -144,6 +145,16 @@ static void Main(string[] args) success &= Test("raddeg (pi)", 180d); success &= Test("raddeg (pi * 1.5)", 270d); success &= Test("raddeg (pi * 2)", 360d); + success &= Test("deg2rad 0", 0d); + success &= Test("deg2rad 90", System.Math.PI * .5d); + success &= Test("deg2rad 180", System.Math.PI); + success &= Test("deg2rad 270", System.Math.PI * 1.5d); + success &= Test("deg2rad 360", System.Math.PI * 2d); + success &= Test("rad2deg (0)", 0d); + success &= Test("rad2deg (pi * 0.5)", 90d); + success &= Test("rad2deg (pi)", 180d); + success &= Test("rad2deg (pi * 1.5)", 270d); + success &= Test("rad2deg (pi * 2)", 360d); // Writing style and comma separator. success &= Test("min(1,2)", System.Math.Min(1, 2)); @@ -152,19 +163,13 @@ static void Main(string[] args) success &= Test("min 1 2", System.Math.Min(1, 2)); success &= Test("min 1,2", System.Math.Min(1, 2)); success &= Test("min 1, 2", System.Math.Min(1, 2)); - success &= Test("min1, 2", System.Math.Min(1, 2)); - success &= Test("min1,2", System.Math.Min(1, 2)); - success &= Test("min1 2", System.Math.Min(1, 2)); success &= Test("min(2,1)", System.Math.Min(1, 2)); success &= Test("min(2, 1)", System.Math.Min(1, 2)); success &= Test("min(2 1)", System.Math.Min(1, 2)); success &= Test("min 2 1", System.Math.Min(1, 2)); success &= Test("min 2,1", System.Math.Min(1, 2)); success &= Test("min 2, 1", System.Math.Min(1, 2)); - success &= Test("min2, 1", System.Math.Min(1, 2)); - success &= Test("min2,1", System.Math.Min(1, 2)); - success &= Test("min2 1", System.Math.Min(1, 2)); - + System.Console.WriteLine("--------------------\nOVERALL RESULT: " + success); } From 27c7527810dc6ae901f5bdf1f84f05241d982865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20S=C3=A9gaud?= Date: Sun, 3 Sep 2017 19:07:18 +0200 Subject: [PATCH 3/8] Updated operators priorities. Highest priority is now 0, int.Max being the lowest. --- Library/Interpreter.Operators.cs | 101 +++++++++++++++++-------------- Library/Interpreter.cs | 2 +- Test/Program.cs | 2 +- 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/Library/Interpreter.Operators.cs b/Library/Interpreter.Operators.cs index e79da8e..5256c4b 100644 --- a/Library/Interpreter.Operators.cs +++ b/Library/Interpreter.Operators.cs @@ -101,7 +101,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("pi", 90)] + [Operator("pi", 0)] private class PiNode : ZeroNode { public override double GetValue(Interpreter interpreter) @@ -110,7 +110,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("rand", 90)] + [Operator("rand", 0)] private class RandNode : ZeroNode { public override double GetValue(Interpreter interpreter) @@ -119,7 +119,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("true", 90)] + [Operator("true", 0)] private class TrueNode : ZeroNode { public override double GetValue(Interpreter interpreter) @@ -128,7 +128,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("false", 90)] + [Operator("false", 0)] private class FalseNode : ZeroNode { public override double GetValue(Interpreter interpreter) @@ -141,7 +141,7 @@ public override double GetValue(Interpreter interpreter) #region UnaryNode - [Operator("±", 99)] + [Operator("±", 1)] private class SignNode : UnaryNode { public SignNode(Node input) : @@ -155,7 +155,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("sqrt", 15)] + [Operator("sqrt")] private class SqrtNode : UnaryNode { public SqrtNode(Node input) @@ -169,7 +169,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("cos", 12)] + [Operator("cos")] private class CosNode : UnaryNode { public CosNode(Node input) @@ -183,7 +183,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("sin", 12)] + [Operator("sin")] private class SinNode : UnaryNode { public SinNode(Node input) @@ -197,7 +197,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("tan", 12)] + [Operator("tan")] private class TanNode : UnaryNode { public TanNode(Node input) @@ -211,7 +211,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("acos", 12)] + [Operator("acos")] private class AcosNode : UnaryNode { public AcosNode(Node input) @@ -225,7 +225,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("asin", 12)] + [Operator("asin")] private class AsinNode : UnaryNode { public AsinNode(Node input) @@ -239,7 +239,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("atan", 12)] + [Operator("atan")] private class AtanNode : UnaryNode { public AtanNode(Node input) @@ -253,7 +253,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("cosh", 12)] + [Operator("cosh")] private class CoshNode : UnaryNode { public CoshNode(Node input) @@ -267,7 +267,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("sinh", 12)] + [Operator("sinh")] private class SinhNode : UnaryNode { public SinhNode(Node input) @@ -281,7 +281,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("tanh", 12)] + [Operator("tanh")] private class TanhNode : UnaryNode { public TanhNode(Node input) @@ -295,8 +295,8 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("deg2rad", 13)] - [Operator("degrad", 13)] + [Operator("deg2rad")] + [Operator("degrad")] private class Deg2RadNode : UnaryNode { public Deg2RadNode(Node input) @@ -310,8 +310,8 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("rad2deg", 13)] - [Operator("raddeg", 13)] + [Operator("rad2deg")] + [Operator("raddeg")] private class Rad2DegNode : UnaryNode { public Rad2DegNode(Node input) @@ -325,7 +325,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("abs", 8)] + [Operator("abs")] private class AbsNode : UnaryNode { public AbsNode(Node input) @@ -339,7 +339,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("round", 8)] + [Operator("round")] private class RoundNode : UnaryNode { public RoundNode(Node input) @@ -353,7 +353,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("!", 50)] + [Operator("!")] private class NegNode : UnaryNode { public NegNode(Node input) @@ -367,7 +367,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("ceil", 8)] + [Operator("ceil")] private class CeilNode : UnaryNode { public CeilNode(Node input) @@ -381,7 +381,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("floor", 8)] + [Operator("floor")] private class FlorrNode : UnaryNode { public FlorrNode(Node input) @@ -395,7 +395,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("trunc", 8)] + [Operator("trunc")] private class TruncNode : UnaryNode { public TruncNode(Node input) @@ -409,7 +409,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("log", 8)] + [Operator("log")] private class LogNode : UnaryNode { public LogNode(Node input) @@ -423,7 +423,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("log10", 8)] + [Operator("log10")] private class Log10Node : UnaryNode { public Log10Node(Node input) @@ -437,8 +437,8 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("e", 8)] - [Operator("exp", 8)] + [Operator("e")] + [Operator("exp")] private class ExpNode : UnaryNode { public ExpNode(Node input) @@ -456,7 +456,7 @@ public override double GetValue(Interpreter interpreter) #region BinaryNode - [Operator("+", 2)] + [Operator("+", 6)] private class AddNode : BinaryNode { public AddNode(Node leftInput, Node rightInput) @@ -470,7 +470,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("-", 2)] + [Operator("-", 6)] private class SubNode : BinaryNode { public SubNode(Node leftInput, Node rightInput) @@ -512,7 +512,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("%", 10)] + [Operator("%", 5)] private class ModNode : BinaryNode { public ModNode(Node leftInput, Node rightInput) @@ -526,7 +526,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("^", 15)] + [Operator("^")] private class PowNode : BinaryNode { public PowNode(Node leftInput, Node rightInput) @@ -540,7 +540,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("min", 80)] + [Operator("min")] private class MinNode : BinaryNode { public MinNode(Node leftInput, Node rightInput) @@ -554,7 +554,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("max", 90)] + [Operator("max")] private class MaxNode : BinaryNode { public MaxNode(Node leftInput, Node rightInput) @@ -568,8 +568,8 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("==", 0)] - [Operator("eq", 0)] + [Operator("==", 9)] + [Operator("eq", 9)] private class EqualNode : BinaryNode { public EqualNode(Node leftInput, Node rightInput) @@ -583,7 +583,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("lt", 0)] + [Operator("lt", 8)] private class LtNode : BinaryNode { public LtNode(Node leftInput, Node rightInput) @@ -597,7 +597,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("lte", 0)] + [Operator("lte", 8)] private class LteNode : BinaryNode { public LteNode(Node leftInput, Node rightInput) @@ -611,7 +611,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("gt", 0)] + [Operator("gt", 8)] private class GtNode : BinaryNode { public GtNode(Node leftInput, Node rightInput) @@ -625,7 +625,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("gte", 0)] + [Operator("gte", 8)] private class GteNode : BinaryNode { public GteNode(Node leftInput, Node rightInput) @@ -639,8 +639,8 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("d", 90)] - [Operator("D", 90)] + [Operator("d")] + [Operator("D")] private class DiceNode : BinaryNode { public DiceNode(Node leftInput, Node rightInput) @@ -663,8 +663,8 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("&", 0)] - [Operator("and", 0)] + [Operator("&", 13)] + [Operator("and", 13)] private class AndNode : BinaryNode { public AndNode(Node leftInput, Node rightInput) @@ -678,8 +678,8 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("|", 0)] - [Operator("or", 0)] + [Operator("|", 14)] + [Operator("or", 14)] private class OrNode : BinaryNode { public OrNode(Node leftInput, Node rightInput) @@ -698,6 +698,8 @@ public override double GetValue(Interpreter interpreter) [System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)] private class OperatorAttribute : System.Attribute { + private const int FunctionPriority = 2; + public string Symbol; public int Priority; @@ -706,6 +708,11 @@ public OperatorAttribute(string symbol, int priority) Symbol = symbol; Priority = priority; } + + public OperatorAttribute(string symbol) + : this(symbol, OperatorAttribute.FunctionPriority) + { + } } } } diff --git a/Library/Interpreter.cs b/Library/Interpreter.cs index b5818a3..5c9d147 100644 --- a/Library/Interpreter.cs +++ b/Library/Interpreter.cs @@ -191,7 +191,7 @@ private static int ComparePrecedence(string a, string b) throw new System.Exception(string.Format("Operator '{0}' is not registered.", b)); } - return Interpreter.operators[a].Priority - Interpreter.operators[b].Priority; + return Interpreter.operators[b].Priority - Interpreter.operators[a].Priority; } private static bool IsAlpha(char c) diff --git a/Test/Program.cs b/Test/Program.cs index 587f438..a78592d 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -45,7 +45,7 @@ static void Main(string[] args) interpreter.SetVar("hundred", hundred); bool success = true; - + // Old tests. success &= Test("±1", -1d); success &= Test("1-1", 1d - 1d); From 212e29e5a6246e10c49afb743ea036372c3653ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20S=C3=A9gaud?= Date: Sun, 3 Sep 2017 19:45:23 +0200 Subject: [PATCH 4/8] New operators and fixes - Added the `!=` operator. - Added some operator aliases: `<`, `<=`, `>`, `>=`. - Fixed an issuerelated to mixed operators (e.g.: mixing `!` and `!=`). --- Library/Interpreter.Operators.cs | 22 +++++++++++++++++++++- Library/Interpreter.cs | 23 ++++++++++++++++++++++- Test/Program.cs | 24 +++++++++++++++++++++++- 3 files changed, 66 insertions(+), 3 deletions(-) diff --git a/Library/Interpreter.Operators.cs b/Library/Interpreter.Operators.cs index 5256c4b..2ebaddb 100644 --- a/Library/Interpreter.Operators.cs +++ b/Library/Interpreter.Operators.cs @@ -353,7 +353,8 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("!")] + [Operator("!", 3)] + [Operator("not", 3)] private class NegNode : UnaryNode { public NegNode(Node input) @@ -583,7 +584,23 @@ public override double GetValue(Interpreter interpreter) } } + [Operator("!=", 9)] + [Operator("ne", 9)] + private class NonEqualNode : BinaryNode + { + public NonEqualNode(Node leftInput, Node rightInput) + : base(leftInput, rightInput) + { + } + + public override double GetValue(Interpreter interpreter) + { + return System.Math.Abs(this.leftInput.GetValue(interpreter) - this.rightInput.GetValue(interpreter)) < double.Epsilon ? FALSE : TRUE; + } + } + [Operator("lt", 8)] + [Operator("<", 8)] private class LtNode : BinaryNode { public LtNode(Node leftInput, Node rightInput) @@ -598,6 +615,7 @@ public override double GetValue(Interpreter interpreter) } [Operator("lte", 8)] + [Operator("<=", 8)] private class LteNode : BinaryNode { public LteNode(Node leftInput, Node rightInput) @@ -612,6 +630,7 @@ public override double GetValue(Interpreter interpreter) } [Operator("gt", 8)] + [Operator(">", 8)] private class GtNode : BinaryNode { public GtNode(Node leftInput, Node rightInput) @@ -626,6 +645,7 @@ public override double GetValue(Interpreter interpreter) } [Operator("gte", 8)] + [Operator(">=", 8)] private class GteNode : BinaryNode { public GteNode(Node leftInput, Node rightInput) diff --git a/Library/Interpreter.cs b/Library/Interpreter.cs index 5c9d147..66acc5d 100644 --- a/Library/Interpreter.cs +++ b/Library/Interpreter.cs @@ -215,7 +215,22 @@ private static int SkipString(string value, int index) return index; } - + + private static bool IsSpecial(char c) + { + return !IsNumeric(c) && !IsAlpha(c) && c != OpenBracketChar && c != ClosingBracketChar && c != VarPrefixChar && c != WhiteSpaceChar && c != '.' && c != '±'; + } + + private static int SkipSpecial(string value, int index) + { + while (index < value.Length && IsSpecial(value[index])) + { + ++index; + } + + return index; + } + private static string InfixToRpn(string infix) { // Replace comma separator with white space for function-like use of operators. @@ -234,6 +249,12 @@ private static string InfixToRpn(string infix) index = Interpreter.SkipString(infix, index + 2); infix = infix.Insert(index, Interpreter.LongOpMark1Str); } + else if (Interpreter.IsSpecial(infix[index])) + { + infix = infix.Insert(index, Interpreter.LongOpMark0Str); + index = Interpreter.SkipSpecial(infix, index + 2); + infix = infix.Insert(index, Interpreter.LongOpMark1Str); + } } // Add blank spaces where needed. diff --git a/Test/Program.cs b/Test/Program.cs index a78592d..52ff19a 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -20,6 +20,8 @@ // SOFTWARE. #endregion +using System; + namespace Hef.Math.Test { class Program @@ -43,7 +45,7 @@ static void Main(string[] args) interpreter.SetVar("Foo", foo); interpreter.SetVar("bar", bar); interpreter.SetVar("hundred", hundred); - + bool success = true; // Old tests. @@ -79,6 +81,10 @@ static void Main(string[] args) success &= Test("1 == 1", BoolToDouble(1d == 1d)); success &= Test("1 eq 0", BoolToDouble(1d == 0d)); success &= Test("1 eq 1", BoolToDouble(1d == 1d)); + success &= Test("1 != 0", BoolToDouble(1d != 0d)); + success &= Test("1 != 1", BoolToDouble(1d != 1d)); + success &= Test("1 ne 0", BoolToDouble(1d != 0d)); + success &= Test("1 ne 1", BoolToDouble(1d != 1d)); success &= Test("1 gt 0", BoolToDouble(1d > 0d)); success &= Test("1 gt 1", BoolToDouble(1d > 1d)); success &= Test("1 gt 2", BoolToDouble(1d > 2d)); @@ -91,6 +97,22 @@ static void Main(string[] args) success &= Test("1 lte 0", BoolToDouble(1d <= 0d)); success &= Test("1 lte 1", BoolToDouble(1d <= 1d)); success &= Test("1 lte 2", BoolToDouble(1d <= 2d)); + success &= Test("1 > 0", BoolToDouble(1d > 0d)); + success &= Test("1 > 1", BoolToDouble(1d > 1d)); + success &= Test("1 > 2", BoolToDouble(1d > 2d)); + success &= Test("1 >= 0", BoolToDouble(1d >= 0d)); + success &= Test("1 >= 1", BoolToDouble(1d >= 1d)); + success &= Test("1 >= 2", BoolToDouble(1d >= 2d)); + success &= Test("1 < 0", BoolToDouble(1d < 0d)); + success &= Test("1 < 1", BoolToDouble(1d < 1d)); + success &= Test("1 < 2", BoolToDouble(1d < 2d)); + success &= Test("1 <= 0", BoolToDouble(1d <= 0d)); + success &= Test("1 <= 1", BoolToDouble(1d <= 1d)); + success &= Test("1 <= 2", BoolToDouble(1d <= 2d)); + success &= Test("(1 eq 1) == (1 == 1)", TRUE); + success &= Test("(1 eq 0) == (1 == 0)", TRUE); + success &= Test("(1 eq 1) eq (0 == 0)", TRUE); + success &= Test("(1 eq 0) eq (0 == 1)", TRUE); // Boolean. success &= Test("!1", FALSE); From 8bef935ae0f276c4215ac9473f58de37ea014423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20S=C3=A9gaud?= Date: Sun, 3 Sep 2017 19:55:52 +0200 Subject: [PATCH 5/8] Added `pow` alias --- Library/Interpreter.Operators.cs | 1 + Test/Program.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Library/Interpreter.Operators.cs b/Library/Interpreter.Operators.cs index 2ebaddb..818f93b 100644 --- a/Library/Interpreter.Operators.cs +++ b/Library/Interpreter.Operators.cs @@ -528,6 +528,7 @@ public override double GetValue(Interpreter interpreter) } [Operator("^")] + [Operator("pow")] private class PowNode : BinaryNode { public PowNode(Node leftInput, Node rightInput) diff --git a/Test/Program.cs b/Test/Program.cs index 52ff19a..fd78e46 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -75,6 +75,8 @@ static void Main(string[] args) success &= Test("$Foo + $bar", foo + bar); success &= Test("round (rand * 10 + 90)"); success &= Test("1 d 4+1 + 1 D 6+1"); + success &= Test("10^2"); + success &= Test("pow(10, 2)"); // Comparison. success &= Test("1 == 0", BoolToDouble(1d == 0d)); From c8867d1cd483b4ebc6d97ba8fd280b4a614d3bbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20S=C3=A9gaud?= Date: Sun, 3 Sep 2017 19:56:31 +0200 Subject: [PATCH 6/8] Added binary operators - Added operators `&`, `|`, `<<` and `>>`. --- Library/Interpreter.Operators.cs | 56 ++++++++++++++++++++++++++++++-- Test/Program.cs | 26 ++++++++++----- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/Library/Interpreter.Operators.cs b/Library/Interpreter.Operators.cs index 818f93b..a6c51f9 100644 --- a/Library/Interpreter.Operators.cs +++ b/Library/Interpreter.Operators.cs @@ -684,7 +684,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("&", 13)] + [Operator("&&", 13)] [Operator("and", 13)] private class AndNode : BinaryNode { @@ -699,7 +699,7 @@ public override double GetValue(Interpreter interpreter) } } - [Operator("|", 14)] + [Operator("||", 14)] [Operator("or", 14)] private class OrNode : BinaryNode { @@ -714,6 +714,58 @@ public override double GetValue(Interpreter interpreter) } } + [Operator("<<", 7)] + private class LeftShiftNode : BinaryNode + { + public LeftShiftNode(Node leftInput, Node rightInput) : base(leftInput, rightInput) + { + } + + public override double GetValue(Interpreter interpreter) + { + return (double)((int)this.leftInput.GetValue(interpreter) << (int)this.rightInput.GetValue(interpreter)); + } + } + + [Operator(">>", 7)] + private class RightShiftNode : BinaryNode + { + public RightShiftNode(Node leftInput, Node rightInput) : base(leftInput, rightInput) + { + } + + public override double GetValue(Interpreter interpreter) + { + return (double)((int)this.leftInput.GetValue(interpreter) >> (int)this.rightInput.GetValue(interpreter)); + } + } + + [Operator("|", 12)] + private class BitOrNode : BinaryNode + { + public BitOrNode(Node leftInput, Node rightInput) : base(leftInput, rightInput) + { + } + + public override double GetValue(Interpreter interpreter) + { + return (double)((int)this.leftInput.GetValue(interpreter) | (int)this.rightInput.GetValue(interpreter)); + } + } + + [Operator("&", 10)] + private class BitAndNode : BinaryNode + { + public BitAndNode(Node leftInput, Node rightInput) : base(leftInput, rightInput) + { + } + + public override double GetValue(Interpreter interpreter) + { + return (double)((int)this.leftInput.GetValue(interpreter) & (int)this.rightInput.GetValue(interpreter)); + } + } + #endregion [System.AttributeUsage(System.AttributeTargets.Class, AllowMultiple = true)] diff --git a/Test/Program.cs b/Test/Program.cs index fd78e46..51143de 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -125,23 +125,33 @@ static void Main(string[] args) success &= Test("false", BoolToDouble(false)); success &= Test("!true", BoolToDouble(!true)); success &= Test("!false", BoolToDouble(!false)); - success &= Test("true & true", BoolToDouble(true && true)); - success &= Test("true & false", BoolToDouble(true && false)); - success &= Test("false & true", BoolToDouble(false && true)); - success &= Test("false & false", BoolToDouble(false && false)); + success &= Test("true && true", BoolToDouble(true && true)); + success &= Test("true && false", BoolToDouble(true && false)); + success &= Test("false && true", BoolToDouble(false && true)); + success &= Test("false && false", BoolToDouble(false && false)); success &= Test("true and true", BoolToDouble(true && true)); success &= Test("true and false", BoolToDouble(true && false)); success &= Test("false and true", BoolToDouble(false && true)); success &= Test("false and false", BoolToDouble(false && false)); - success &= Test("true | true", BoolToDouble(true || true)); - success &= Test("true | false", BoolToDouble(true || false)); - success &= Test("false | true", BoolToDouble(false || true)); - success &= Test("false | false", BoolToDouble(false || false)); + success &= Test("true || true", BoolToDouble(true || true)); + success &= Test("true || false", BoolToDouble(true || false)); + success &= Test("false || true", BoolToDouble(false || true)); + success &= Test("false || false", BoolToDouble(false || false)); success &= Test("true or true", BoolToDouble(true || true)); success &= Test("true or false", BoolToDouble(true || false)); success &= Test("false or true", BoolToDouble(false || true)); success &= Test("false or false", BoolToDouble(false || false)); + // Binary + success &= Test("1 << 4", 1 << 4); + success &= Test("32 >> 4", 32 >> 4); + success &= Test("1 << 4 >> 4", 1 << 4 >> 4); + success &= Test("32 >> 4 << 4", 32 >> 4 << 4); + success &= Test("4 | 2", 4 | 2); + success &= Test("6 | 2", 6 | 2); + success &= Test("4 & 2", 4 & 2); + success &= Test("6 & 2", 6 & 2); + // Trigonometry. success &= Test("cos 0", System.Math.Cos(0d)); success &= Test("cos (pi / 2)", System.Math.Cos(System.Math.PI / 2d)); From d1f643cc79e138e2a5a49a73ab1e8f65cec11078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20S=C3=A9gaud?= Date: Sun, 3 Sep 2017 20:00:01 +0200 Subject: [PATCH 7/8] Removed obsolete functions --- Library/Interpreter.Operators.cs | 2 -- Library/Interpreter.cs | 30 ++---------------------------- Test/Program.cs | 10 ---------- 3 files changed, 2 insertions(+), 40 deletions(-) diff --git a/Library/Interpreter.Operators.cs b/Library/Interpreter.Operators.cs index a6c51f9..9dc244e 100644 --- a/Library/Interpreter.Operators.cs +++ b/Library/Interpreter.Operators.cs @@ -296,7 +296,6 @@ public override double GetValue(Interpreter interpreter) } [Operator("deg2rad")] - [Operator("degrad")] private class Deg2RadNode : UnaryNode { public Deg2RadNode(Node input) @@ -311,7 +310,6 @@ public override double GetValue(Interpreter interpreter) } [Operator("rad2deg")] - [Operator("raddeg")] private class Rad2DegNode : UnaryNode { public Rad2DegNode(Node input) diff --git a/Library/Interpreter.cs b/Library/Interpreter.cs index 66acc5d..de71f49 100644 --- a/Library/Interpreter.cs +++ b/Library/Interpreter.cs @@ -56,10 +56,7 @@ public partial class Interpreter private readonly System.Collections.Generic.Dictionary variables; private System.Collections.Generic.Dictionary namedContext; - - [System.Obsolete("use Interpreter.namedContext instead.")] - private IInterpreterContext interpreterContext; - + #endregion #region Enumerations @@ -88,14 +85,7 @@ public Interpreter() this.variables = new System.Collections.Generic.Dictionary(); this.namedContext = new System.Collections.Generic.Dictionary(); } - - [System.Obsolete("Use Interpreter.SetContext(string, IINterpreterContext) instead.")] - public Interpreter(IInterpreterContext interpreterContext) - : this() - { - this.SetContext(interpreterContext); - } - + #endregion #region Public Functions @@ -114,16 +104,6 @@ public void SetVar(string name, double value) } } - /// - /// Sets an interpreter context to be use un variables resolution. - /// - /// An object that implements Hef.Math.IInterpreterContext. - [System.Obsolete("Use Interpreter.SetContext(string, IINterpreterContext) instead.")] - public void SetContext(IInterpreterContext interpreterContext) - { - this.interpreterContext = interpreterContext; - } - /// /// Sets an interpreter context to be use un variables resolution. /// @@ -433,12 +413,6 @@ private bool TryGetVariableValue(string varName, out double value) return true; } - if (this.interpreterContext != null && - this.interpreterContext.TryGetVariable(varName.TrimStart(Interpreter.VarPrefixChar), out value)) - { - return true; - } - if (System.Text.RegularExpressions.Regex.IsMatch(varName, @"\$\w+.\w+")) { string contextName = varName.Substring(varName.IndexOf('$') + 1, varName.IndexOf('.') - 1); diff --git a/Test/Program.cs b/Test/Program.cs index 51143de..425c4ec 100644 --- a/Test/Program.cs +++ b/Test/Program.cs @@ -169,16 +169,6 @@ static void Main(string[] args) success &= Test("tan pi", System.Math.Tan(System.Math.PI)); success &= Test("tan (pi / 4)", System.Math.Tan(System.Math.PI / 4d)); success &= Test("tan (3 * pi / 4)", System.Math.Tan(3 * System.Math.PI / 4d)); - success &= Test("degrad 0", 0d); - success &= Test("degrad 90", System.Math.PI * .5d); - success &= Test("degrad 180", System.Math.PI); - success &= Test("degrad 270", System.Math.PI * 1.5d); - success &= Test("degrad 360", System.Math.PI * 2d); - success &= Test("raddeg (0)", 0d); - success &= Test("raddeg (pi * 0.5)", 90d); - success &= Test("raddeg (pi)", 180d); - success &= Test("raddeg (pi * 1.5)", 270d); - success &= Test("raddeg (pi * 2)", 360d); success &= Test("deg2rad 0", 0d); success &= Test("deg2rad 90", System.Math.PI * .5d); success &= Test("deg2rad 180", System.Math.PI); From 9d1ea8856d4feca5774ea19858806c445752a33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20S=C3=A9gaud?= Date: Sun, 3 Sep 2017 20:47:35 +0200 Subject: [PATCH 8/8] Updated documentation to 1.0.0 - README.md - CHANGELOG.md - Nuspec --- CHANGELOG.md | 27 +++++++ NuGet/Hef.Math.Interpreter.nuspec | 2 +- README.md | 116 +++++++++++++++++------------- 3 files changed, 94 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 444aecc..debb6cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,33 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [1.0.0] 2017.09.?? + +### Added + +- Added binary operators `<<`, `>>`, `&` and `|`. +- Added comparison operator `!=` (with alias `ne`). +- Added new operators `floor`, `ceil`, `trunc`. +- Added new operators `e`, `log`, `log10`. +- Added aliases to existing operators `<`, `<=`, `>` and `>=`. + +### Changed + +- Operators priority is now from lowest (0) to highest (_int.Max_); +- Formula syntax: Alphanumeric operators should now be separated from operants by a blanck space or brackets (e.g.: `e2` should be written `e 2` or `e(2)`). + +### Removed + +- Removed some deprecated operation aliases (`degrad` and `raddeg`). +- Removed some deprecated functions related to unnamed contexts : + - Constructor `Interpreter(IInterpreterContext)`. + - Function `SetContext(IInterpreterContext)`. + +### Fixed + +- Operators that contain digits in their names no longer fail (e.g.: `deg2rad`). +- Fixed an issue related to mixed operators (i.e.: `!` was mixed to `!=`). + ## [0.2.0-alpha] - 2017.08.29 ### Added diff --git a/NuGet/Hef.Math.Interpreter.nuspec b/NuGet/Hef.Math.Interpreter.nuspec index 4404404..bb6e1af 100644 --- a/NuGet/Hef.Math.Interpreter.nuspec +++ b/NuGet/Hef.Math.Interpreter.nuspec @@ -2,7 +2,7 @@ Hef.Math.Interpreter - 0.2.0-alpha + 1.0.0 François Ségaud fseg https://opensource.org/licenses/MIT diff --git a/README.md b/README.md index 54b2582..00584c4 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ You can also install the correpsonding _NuGet_ package at [https://www.nuget.org Or install it using the _NuGet_ console. ``` -Install-Package Hef.Math.Interpreter -Version 0.2.0-alpha +Install-Package Hef.Math.Interpreter -Version 1.0.0-alpha ``` ### Examples @@ -40,7 +40,7 @@ Here is the simplest example. ```csharp Interpreter interpreter = new Interpreter(); double result = interpreter.Calculate("sqrt(4) + 2"); // -> 4 -// "sqrt 4 + 2" or "sqrt4+2" would work as well +// "sqrt 4 + 2" would work as well ``` The following example highlights the use of manually registered variables. @@ -82,66 +82,82 @@ class Player : Hef.Math.IInterpreterContext #### Basic Operators -| Symbol | Operation | Comment | Version | -|:------:|-------------|------------------------------------|:-------:| -| `±` | Sign Change | -1 should be written ±1 (atl+0177) | 0.1.0 | -| `+` | Addition | | 0.1.0 | -| `-` | Subtraction | | 0.1.0 | -| `*` | Product | | 0.1.0 | -| `/` | Division | | 0.1.0 | -| `%` | Modulo | | 0.1.0 | -| `^` | Power | | 0.1.0 | -| `sqrt` | Square Root | | 0.1.0 | +| Symbol | Operation | Comment | Version | +|:-------------:|-------------|------------------------------------|:-------:| +| `±` | Sign Change | -1 should be written ±1 (atl+0177) | 0.1.0 | +| `+` | Addition | | 0.1.0 | +| `-` | Subtraction | | 0.1.0 | +| `*` | Product | | 0.1.0 | +| `/` | Division | | 0.1.0 | +| `%` | Modulo | | 0.1.0 | #### Advanced Operators -| Symbol | Operation | Comment | Version | -|:-------:|----------------|---------|:-------:| -| `abs` | Absolute Value | | 0.1.0 | -| `round` | Round | | 0.1.0 | -| `min` | Minimum | | 0.1.0 | -| `max` | Maximum | | 0.1.0 | +| Symbol | Operation | Comment | Version | +|:------------:|---------------------------|---------|:-------:| +| `^` or `pow` | Power | | 0.1.0 | +| `sqrt` | Square Root | | 0.1.0 | +| `abs` | Absolute Value | | 0.1.0 | +| `round` | Round | | 0.1.0 | +| `min` | Minimum | | 0.1.0 | +| `max` | Maximum | | 0.1.0 | +| `ceil` | Ceil to upper integer | | 1.0.0 | +| `floor` | Floot to lower integer | | 1.0.0 | +| `trunc` | Truncate the decimal part | | 1.0.0 | +| `log` | Logarithm | | 1.0.0 | +| `log10` | Logarithm base 10 | | 1.0.0 | +| `e` or `exp` | Exponential | | 1.0.0 | #### Comparison Operators -| Symbol | Operation | Comment | Version | -|:------------:|------------------|----------------------------|:-------:| -| `==` or `eq` | Equal | 1 == 1 -> 1, 1 eq 2 -> 0 | 0.1.0 | -| `gt` | Greater Than | 1 gt 1 -> 0, 1 gt 2 -> 1 | 0.1.0 | -| `gte` | Greater Or Equal | 1 gte 0 -> 0, 1 gte 1 -> 1 | 0.1.0 | -| `lt` | Less Than | 1 lt 1 -> 0, 1 lt 2 -> 1 | 0.1.0 | -| `lte` | Less Or Equal | 1 lte 1 -> 1, 1 lte 0 -> 0 | 0.1.0 | +| Symbol | Operation | Comment | Version | +|:-------------:|------------------|----------------------------|:-------:| +| `==` or `eq` | Equal | 1 == 1 -> 1, 1 eq 2 -> 0 | 0.1.0 | +| `gt` or `>` | Greater Than | 1 gt 1 -> 0, 1 gt 2 -> 1 | 0.1.0 | +| `gte` or `>=` | Greater Or Equal | 1 gte 0 -> 0, 1 gte 1 -> 1 | 0.1.0 | +| `lt` or `<` | Less Than | 1 lt 1 -> 0, 1 lt 2 -> 1 | 0.1.0 | +| `lte` or `<=` | Less Or Equal | 1 lte 1 -> 1, 1 lte 0 -> 0 | 0.1.0 | +| `!=` or `ne` | Equal | 1 != 1 -> 0, 1 ne 2 -> 1 | 1.0.0 | #### Logical Operators -| Symbol | Operation | Comment | Version | -|:------------:|------------------|----------------------------|:-------:| -| `!` | Not | !0 -> 1, !1 -> 0 | 0.1.0 | -| `&` or `and` | And | true & true -> true | 0.1.1 | -| `\|` or `or` | Or | true & false -> true | 0.1.1 | +| Symbol | Operation | Comment | Version | +|:--------------:|------------------|----------------------------|:-------:| +| `!` | Not | !0 -> 1, !1 -> 0 | 0.1.0 | +| `&&` or `and` | And | true & true -> true | 1.0.0 | +| `\|\|` or `or` | Or | true & false -> true | 1.0.0 | + +#### Bitwise Operators + +| Symbol | Operation | Comment | Version | +|:------:|-----------------|----------------------------|:-------:| +| `<<` | Left Bitshift | | 1.0.0 | +| `>>` | Right Bitshift | | 1.0.0 | +| `&` | And | | 1.0.0 | +| `\|` | Or | | 1.0.0 | #### Trigonometry -| Symbol | Operation | Comment | Version | -|:--------:|--------------------|-----------------------------|:-------:| -| `cos` | Cosine | | 0.1.0 | -| `sin` | Sine | | 0.1.0 | -| `tan` | Tangent | | 0.1.0 | -| `acos` | Arccosine | | 0.1.1 | -| `asin` | Arcsine | | 0.1.1 | -| `atan` | Arctangent | | 0.1.1 | -| `cosh` | Hyperbolic Cosine | | 0.1.1 | -| `sinh` | Hyperbolic Sine | | 0.1.1 | -| `tanh` | Hyperbolic Tangent | | 0.1.1 | -| `degrad` | Deg2Rad | Converts degrees to radians | 0.1.1 | -| `raddeg` | Rad2Deg | Converts radians to degrees | 0.1.1 | +| Symbol | Operation | Comment | Version | +|:---------:|--------------------|-----------------------------|:-------:| +| `cos` | Cosine | | 0.1.0 | +| `sin` | Sine | | 0.1.0 | +| `tan` | Tangent | | 0.1.0 | +| `acos` | Arccosine | | 0.1.1 | +| `asin` | Arcsine | | 0.1.1 | +| `atan` | Arctangent | | 0.1.1 | +| `cosh` | Hyperbolic Cosine | | 0.1.1 | +| `sinh` | Hyperbolic Sine | | 0.1.1 | +| `tanh` | Hyperbolic Tangent | | 0.1.1 | +| `deg2rad` | Deg2Rad | Converts degrees to radians | 1.0.0 | +| `rad2deg` | Rad2Deg | Converts radians to degrees | 1.0.0 | #### Randomization -| Symbol | Operation | Comment | Version | -|:----------:|-----------|-----------------|:-------:| -| `rand` | Random | rand 5 -> [0,5] | 0.1.0 | -| `d` or `D` | Dice | 2d6 -> [2,12] | 0.1.0 | +| Symbol | Operation | Comment | Version | +|:----------:|-----------|-------------------|:-------:| +| `rand` | Random | rand 5 -> [0,5] | 0.1.0 | +| `d` or `D` | Dice | 2 d 6 -> [2,12] | 0.1.0 | #### Constants @@ -176,13 +192,13 @@ Then add the `OperatorAttribute` and fill the symbol and priority. > INFO: The `OperatorAttribute` is stackable. -> INFO: Highest priorities are executed first. +> INFO: Lowest priorities are executed first. Default priority is 2 (functions). The following example show the implementation of an operator that halves an operand (unary operator). Its symbols will be `#` and `half`. ```csharp -[Operator("#", 5)] -[Operator("half", 5)] +[Operator("#", 2)] +[Operator("half", 2)] private class HalfNode : UnaryNode { public HalfNode(Node input)