Пример #1
0
        public void Parse_AllFunctions()
        {
            string[] functions =
            {
                "abs",   "sqrt",  "exp",  "ln", "log",
                "sin",   "cos",   "tan",
                "asin",  "acos",  "atan",
                "sinh",  "cosh",  "tanh",
                "round", "floor", "ceil"
            };

            string input = "";

            for (int i = 0; i < functions.Length; i++)
            {
                if (i > 0)
                {
                    input += " + ";
                }

                input += functions[i] + "(x)";
            }

            ArithmeticExpression ae = ArithmeticExpression.Parse(input);

            Assert.IsNotNull(ae);

            for (int i = 0; i < functions.Length; i++)
            {
                Assert.IsTrue(ae.IsCallbackUsed("operator_" + functions[i]));
            }

            Assert.IsFalse(ae.IsCallbackUsed("unknown"));
        }
Пример #2
0
        private void OnDuplicateButtonClick(object sender, EventArgs e)
        {
            ListView.Item selected = listView.FocusedItem;
            if (selected != null && selected.NumericValueSource is ArithmeticExpression)
            {
                ArithmeticExpression ae = ArithmeticExpression.Parse(selected.Text);
                ae.Callbacks = selected.OperatorCallbacks;

                ListView.Item item = new ListView.Item {
                    OperatorCallbacks     = selected.OperatorCallbacks,
                    Color                 = FindNewColor(),
                    CheckState            = selected.CheckState,
                    CheckEnabled          = selected.CheckEnabled,
                    ImageResourceCallback = OnImageResourceCallback,

                    Description        = selected.Description,
                    NumericValueSource = ae,
                    Text        = selected.Text,
                    TextDisplay = selected.TextDisplay
                };

                listView.Items.Add(item);

                listView.FocusedItem = item;

                listView.Invalidate();
                listView.Update();

                listView.EnsureVisible(item);
            }
        }
Пример #3
0
        public void Evaluate_Precedence()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("1 / (2 * 4) ^ 2");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(1.0 / Math.Pow(2.0 * 4.0, 2), result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #4
0
        public void Evaluate_SimpleExpression()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("(2 - 1 + 6) % 5");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual((2 - 1 + 6) % 5, result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #5
0
        public void Evaluate_Parentheses()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("((( ((( ((( 1 + 2 ))) + 3 ))) + 4 ))) + 5");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(1 + 2 + 3 + 4 + 5, result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #6
0
        public void Evaluate_Function_Log()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("log(10 * 10 * 10 * 10)");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(4.0, result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #7
0
        public void Evaluate_SimpleFunction_AutoMultiply()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("5sqrt(x)");
            double result           = ae.Evaluate(16);

            Assert.AreEqual(5.0 * Math.Sqrt(16), result);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #8
0
        public void Evaluate_Variable()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("x");
            double result           = ae.Evaluate(-10);

            Assert.AreEqual(-10, result);
            Assert.AreEqual("x", ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #9
0
        public void Evaluate_Constant_AutoMultiply()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("2pi");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(2.0 * Math.PI, result);
            Assert.IsNull(ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #10
0
        public void Evaluate_Constant_3()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("6e-3");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(0.006, result);
            Assert.IsNull(ae.VariableName);
            Assert.IsTrue(ae.IsSimpleConstantOnly);
        }
Пример #11
0
        public void Evaluate_Comment()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("1 + 2 + 3 # This is comment!");
            double result           = ae.Evaluate(double.NaN);

            Assert.AreEqual(6, result);
            Assert.IsNull(ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #12
0
        public void Evaluate_Function_RoundDown()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("round(z)");
            double result           = ae.Evaluate(6.49);

            Assert.AreEqual(6.0, result);
            Assert.AreEqual("z", ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #13
0
        public void Evaluate_SimpleFunction()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("cos(custom)");
            double result           = ae.Evaluate(0);

            Assert.AreEqual(1.0, result);
            Assert.AreEqual("custom", ae.VariableName);
            Assert.IsFalse(ae.IsSimpleConstantOnly);
        }
Пример #14
0
        public void Evaluate_Variable_2()
        {
            ArithmeticExpression ae1 = ArithmeticExpression.Parse("sin(x)");
            double result1           = ae1.Evaluate(10);

            ArithmeticExpression ae2 = ArithmeticExpression.Parse("sin(10)");
            double result2           = ae2.Evaluate(double.NaN);

            Assert.AreEqual(result1, result2);
        }
Пример #15
0
        public void Evaluate_KnownConstants()
        {
            ArithmeticExpression ae1 = ArithmeticExpression.Parse("pi");
            double result1           = ae1.Evaluate(double.NaN);

            Assert.AreEqual(Math.PI, result1);

            ArithmeticExpression ae2 = ArithmeticExpression.Parse("e");
            double result2           = ae2.Evaluate(double.NaN);

            Assert.AreEqual(Math.E, result2);
        }
Пример #16
0
        public void Parse_AllOperators()
        {
            ArithmeticExpression ae = ArithmeticExpression.Parse("0 + 1 - (2 * (3 / 4)) ^ (5 % 6)");

            Assert.IsNotNull(ae);

            Assert.IsTrue(ae.IsCallbackUsed("operator_add"));
            Assert.IsTrue(ae.IsCallbackUsed("operator_subtract"));
            Assert.IsTrue(ae.IsCallbackUsed("operator_multiply"));
            Assert.IsTrue(ae.IsCallbackUsed("operator_divide"));
            Assert.IsTrue(ae.IsCallbackUsed("operator_pow"));
            Assert.IsTrue(ae.IsCallbackUsed("operator_remainder"));

            Assert.IsFalse(ae.IsCallbackUsed("unknown"));
        }
Пример #17
0
        public void Evaluate_Callbacks()
        {
            ArithmeticExpression    ae        = ArithmeticExpression.Parse("(+1) * (-2) * 3");
            DotNetOperatorCallbacks callbacks = new DotNetOperatorCallbacks();

            ae.Callbacks = callbacks;

            double result = ae.Evaluate(0);

            Assert.AreEqual((+1) * (-2) * 3, result);
            Assert.AreEqual(callbacks, ae.Callbacks);

            Assert.IsFalse(callbacks.IsDisposed);

            callbacks.Dispose();

            Assert.IsTrue(callbacks.IsDisposed);
        }
Пример #18
0
 public void Parse_InvalidInput_7()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("sin sin(x)");
 }
Пример #19
0
        private void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "Text")
            {
                ListView.Item item = (ListView.Item)sender;
                if (string.IsNullOrEmpty(item.Text))
                {
                    item.NumericValueSource = null;
                    item.TextDisplay        = "\f[0x999999]" + Tx.T("main.enter expression");
                }
                else
                {
                    try {
                        ArithmeticExpression ae = ArithmeticExpression.Parse(item.Text);
                        ae.Callbacks = item.OperatorCallbacks;

                        item.NumericValueSource = ae;

                        int i = item.Text.IndexOf('#');
                        if (i != -1)
                        {
                            while (i > 0 && item.Text[i - 1] == ' ')
                            {
                                i--;
                            }

                            StringBuilder sb = new StringBuilder();
                            sb.Append(item.Text, 0, i);

                            if (ae.VariableName == null && !ae.IsSimpleConstantOnly)
                            {
                                double result = ae.Evaluate(double.NaN);

                                sb.Append("\f[I]\f[0x999999] = ");
                                sb.Append(result.ToExactString().LimitSize(32));
                                sb.Append(" \f[I]");
                            }

                            sb.Append("\f[0x498E3E]");
                            sb.Append(item.Text, i, item.Text.Length - i);

                            CheckCallbacks(item, sb);

                            item.TextDisplay = sb.ToString();
                        }
                        else
                        {
                            if (ae.VariableName == null && !ae.IsSimpleConstantOnly)
                            {
                                StringBuilder sb = new StringBuilder();
                                sb.Append(item.Text);

                                double result = ae.Evaluate(double.NaN);

                                sb.Append("\f[I]\f[0x999999] = ");
                                if (double.IsPositiveInfinity(result))
                                {
                                    sb.Append("+∞");
                                }
                                else if (double.IsNegativeInfinity(result))
                                {
                                    sb.Append("−∞");
                                }
                                else
                                {
                                    sb.Append(result.ToExactString().LimitSize(32));
                                }
                                sb.Append("\f[I]");

                                CheckCallbacks(item, sb);

                                item.TextDisplay = sb.ToString();
                            }
                            else
                            {
                                StringBuilder sb = new StringBuilder();
                                sb.Append(item.Text);

                                CheckCallbacks(item, sb);

                                item.TextDisplay = sb.ToString();
                            }
                        }
                    } catch (SyntaxException ex) {
                        item.NumericValueSource = null;

                        StringBuilder sb = new StringBuilder();
                        sb.Append("\f[0x8b0000]");

                        int length = ex.Input.IndexOf('#');
                        if (length == -1)
                        {
                            length = ex.Input.Length;
                        }

                        if (length < 3)
                        {
                            sb.Append(ex.Input);
                        }
                        else
                        {
                            if (ex.Index - 1 < 0)
                            {
                                sb.Append("\f[U]");
                            }
                            else
                            {
                                sb.Append(ex.Input, 0, ex.Index - 1);

                                sb.Append("\f[U]\f[0xd00000]");
                                sb.Append(ex.Input[ex.Index - 1]);
                            }

                            sb.Append("\f[0xff0000]");
                            sb.Append(ex.Input[ex.Index]);

                            if (ex.Index + 1 < length)
                            {
                                sb.Append("\f[0xd00000]");
                                sb.Append(ex.Input[ex.Index + 1]);

                                sb.Append("\f[0x8b0000]\f[U]");

                                if (ex.Index + 2 < length)
                                {
                                    sb.Append(ex.Input, ex.Index + 2, length - (ex.Index + 2));
                                }
                            }
                            else
                            {
                                sb.Append("\f[0xd00000] \f[U]");
                            }
                        }

                        switch (ex.ExceptionType)
                        {
                        case SyntaxException.Type.Unknown:
                            break;

                        case SyntaxException.Type.InvalidNumber:
                            sb.Append("      \f[-]\f[image:warning]  \f[0xaa6400]\f[I]");
                            sb.Append(Tx.T("expression.errors.invalid number"));
                            break;

                        case SyntaxException.Type.DistinctVariableCountExceeded:
                            sb.Append("      \f[-]\f[image:warning]  \f[0xaa6400]\f[I]");
                            sb.Append(Tx.T("expression.errors.distinct variable count exceeded"));
                            break;

                        case SyntaxException.Type.ParenthesesCountMismatch:
                            sb.Append("      \f[-]\f[image:warning]  \f[0xaa6400]\f[I]");
                            sb.Append(Tx.T("expression.errors.parentheses count mismatch"));
                            break;

                        default:
                            throw new InvalidEnumArgumentException("ex.ExceptionType", (int)ex.ExceptionType, typeof(SyntaxException.Type));
                        }

                        item.TextDisplay = sb.ToString();
                    } catch (Exception ex) {
                        item.NumericValueSource = null;

                        item.TextDisplay = "\f[0x8b0000]" + item.Text + "      \f[-]\f[image:warning]  \f[0xaa6400]\f[I]" + ex.Message;
                    }
                }

                item.CheckEnabled = (item.NumericValueSource != null);

                RefreshToolStrip();
            }
            else if (e.PropertyName == "OperatorCallbacks")
            {
                ListView.Item        item = (ListView.Item)sender;
                ArithmeticExpression arithmeticExpression = item.NumericValueSource as ArithmeticExpression;
                if (arithmeticExpression != null)
                {
                    arithmeticExpression.Callbacks = item.OperatorCallbacks;

                    OnItemPropertyChanged(item, new PropertyChangedEventArgs("Text"));
                }

                item.Description = item.OperatorCallbacks.ImplementationName;
            }
        }
Пример #20
0
 public void Parse_InvalidNumber()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("5,5");
 }
Пример #21
0
 public void Parse_BadParentheses_2()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("((1 + 2)))");
 }
Пример #22
0
 public void Parse_BadParentheses_1()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("(1 + 2");
 }
Пример #23
0
 public void Parse_UnknownFunction()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("unknown(x)");
 }
Пример #24
0
 public void Parse_Variables()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("x * y");
 }
Пример #25
0
 public void Parse_Empty()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("");
 }
Пример #26
0
 public void Parse_InvalidInput_9()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("(5 * 5) pi");
 }
Пример #27
0
 public void Parse_InvalidInput_10()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("50 50");
 }
Пример #28
0
 public void Parse_InvalidInput_6()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("(2 +)");
 }
Пример #29
0
 public void Parse_InvalidInput_5()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("10 20 + 30");
 }
Пример #30
0
 public void Parse_InvalidInput_8()
 {
     ArithmeticExpression ae = ArithmeticExpression.Parse("(5 * 5) sqrt(16)");
 }