Esempio n. 1
0
        private void btnPerfomance_Click(object sender, EventArgs e)
        {
            List <AleToken> list;
            List <AleTerm>  Terms = new List <AleTerm>();
            AleTerm         T     = null;

            /*
             * lblInfo.Text = "";
             * txtResult.Text = "";
             *
             * AP.Options = (AP.IgnoreCase ? AleSimpleLexer.OPTION_IGNORECASE : 0) +
             *  AleExpressionParser.OPTION_ALLOWEMPTYLISTMEMBER +
             *  (chkStrictSyntax.Checked ? AleExpressionParser.OPTION_STRICTSYNTAX : 0) +
             *  AleExpressionParser.OPTION_ALLOWEMPTYPARAMS +
             *  AleExpressionParser.OPTION_ALLOWEMPTYINDEX +
             *  AleExpressionParser.OPTION_ALLOWMULTIDIMINDEXES +
             *  AleExpressionParser.OPTION_STRICTINDEXES;
             *
             * AP.Text = expr_;
             * AP.VarPrefix = cboPrefix.Text == "" ? '\0' : cboPrefix.Text[0];
             * AP.EndOfExpression = "; 'end of expression' 'stoṕ herẽ'";
             */

            AP.Constants = new Dictionary <string, object>(AP.IgnoreCase ? StringComparer.CurrentCultureIgnoreCase : StringComparer.CurrentCulture);
            AP.Constants.Add("true", true);
            AP.Constants.Add("false", false);
            AP.Constants.Add("pi", Math.PI);
            AP.Constants.Add("π", Math.PI);
            //AP.Constants.Add("2pi", 2 * Math.PI);
            //AP.Constants.Add("2π", 2 * Math.PI);
            AP.Constants.Add("e", Math.E);
            AP.Constants.Add("null", null);

            AP.SemanticsValidate += OnSemanticsValidate;

            int res = 0;

            while (res < AP.Text.Length)
            {
                res = AP.Tokenize(out list, res);

                if (AP.ErrorCode == AleExpressionParser.ERROR_OK)
                {
                    T = AP.Parse(list);
                }

                if (AP.ErrorCode != AleExpressionParser.ERROR_OK)
                {
                    ShowError(AP);
                    return;
                }

                if (T != null)
                {
                    Terms.Add(T);
                }
            }

            if (Terms.Count == 0)
            {
                return;
            }

            //btnParse.Enabled = false;
            //btnEval.Enabled = false;
            //btnPerfomance.Enabled = false;

            string        S;
            AleTermResult val = new AleTermResult();
            DateTime      t1  = DateTime.Now;
            int           N   = 1000000;

            for (int i = N; i > 0 && val.ErrorCode == AleTermResult.ERROR_OK; i--)
            {
                if (i % 10000 == 0)
                {
                    //lblInfo.Text = i.ToString();
                    Application.DoEvents();
                }

                foreach (AleTerm t in Terms)
                {
                    t.Evaluate(out val, OnEvaluate, OnAssign);
                    if (val.ErrorCode != AleTermResult.ERROR_OK)
                    {
                        break;
                    }
                }
            }

            DateTime t2 = DateTime.Now;

            if (val.ErrorCode == AleTermResult.ERROR_OK)
            {
                TimeSpan dt = t2.Subtract(t1);
                S = "Evaluation speed: " + (N / dt.TotalSeconds).ToString() + " expressions per second";
                //txtResult.Text = S;
            }
            //else txtResult.Text = "Error \"" + val.ErrorMessage() + "\" in line:" + AP.ErrorPosToLine(val.ErrorPos).ToString() + " col:" + AP.ErrorPosToCol(val.ErrorPos).ToString() + "\u000d\u000a";

            //btnParse.Enabled = true;
            //btnEval.Enabled = true;
            //btnPerfomance.Enabled = true;
        }
Esempio n. 2
0
        private void InitMyOperations()
        {
            AP.AddOperation(new AleOperation(AP.IgnoreCase ? "ITEM" : "Item")
            {
                /* 'Parameters' property describes arguments of operation (function).
                 * Number of Tuples in list defines number of arguments of function.
                 * Each Tuple describes each argument of function.
                 * First item of Tuple describes type of argument for "run-time" checking.
                 * TypeCode.Object value of this item means that any object can be passed as argument and it is concern of 'Evaluator' delegate to check type of passed object and correctly use it.
                 * Second item defines default value for argument. When it is null - argument is required.
                 * When it is not null - argument is not required and second item is a default value passed instead.  */
                Parameters = new List <Tuple <TypeCode, object> >()
                {
                    new Tuple <TypeCode, object>(TypeCode.Int32, null)
                },

                /* 'ObjectTypeCode' defines if operation (function) is a class method.
                 * Default value for 'ObjectTypeCode' set by constructor is TypeCode.Empty. It means that function is not a class method.
                 * 'ObjectTypeCode' is used by parser to correctly select operation and during evaluation for "run-time" checking of class instance passed to delegate in 'parameters' argument.
                 * 'ObjectTypeCode' can be TypeCode.Object. It means that class instance of any type can be passed to delegate. */
                InstanceTypeCode = TypeCode.Object,

                /* delegate which is called to evaluate operation.
                 * 'term' is a element of a parsed expression tree.
                 * 'parameters' is a structure with operation arguments. When number of arguments is 3 or less, they are passed in 'FirstParam', 'SecondParam' and 'ThirdParam' fields.
                 * When number of arguments is 4 or more, they are passed in 'Parameters' field (List<object>)
                 * Store result of evaluation or information about error in 'result' structure */
                Evaluator = delegate(AleTerm term, ref OperationEvalParameters parameters, ref AleTermResult result)
                {
                    Dictionary <string, ChemicalElement> elements = parameters.ClassInstance as Dictionary <string, ChemicalElement>;

                    if (elements != null)
                    {
                        int i = 0;
                        int k = Convert.ToInt32(parameters.FirstParam);

                        foreach (KeyValuePair <string, ChemicalElement> element in elements)
                        {
                            if (i == k)
                            {
                                result.Value = element.Value;
                                return(true);
                            }
                            i++;
                        }

                        result.SetError(AleTermResult.ERROR_KEYNOTFOUND, term.Token.StartInOrigin);
                    }
                    else
                    {
                        result.SetError(AleTermResult.ERROR_UNKNOWNMETHOD, term.Token.StartInOrigin);
                    }

                    return(false);
                }
            });

            AP.AddOperation(new AleOperation(AP.IgnoreCase ? "RAND" : "Rand")
            {
                Parameters = new List <Tuple <TypeCode, object> >()
                {
                    new Tuple <TypeCode, object>(TypeCode.Double, Double.MinValue), new Tuple <TypeCode, object>(TypeCode.Double, Double.MaxValue)
                },
                Evaluator = delegate(AleTerm term, ref OperationEvalParameters parameters, ref AleTermResult result)
                {
                    //if (parameters.ActualParamsCount == 1) result.Value = rnd.Next(Convert.ToInt32(parameters.FirstParam));
                    //else if (parameters.ActualParamsCount == 2) result.Value = rnd.Next(Convert.ToInt32(parameters.FirstParam), Convert.ToInt32(parameters.SecondParam));
                    //else result.Value = rnd.Next();

                    if (parameters.ActualParamsCount == 1)
                    {
                        result.Value = Convert.ToDouble(parameters.FirstParam) * rnd.NextDouble();
                    }
                    else if (parameters.ActualParamsCount == 2)
                    {
                        double a     = Convert.ToDouble(parameters.FirstParam);
                        double b     = Convert.ToDouble(parameters.SecondParam);
                        result.Value = (a - b) * rnd.NextDouble() + b;
                    }
                    else
                    {
                        result.Value = rnd.NextDouble();
                    }

                    return(true);
                }
            });

            AP.AddOperation(new AleOperation(AP.IgnoreCase ? "IIF" : "Iif")
            {
                Parameters = new List <Tuple <TypeCode, object> >()
                {
                    new Tuple <TypeCode, object>(TypeCode.Boolean, null), new Tuple <TypeCode, object>(TypeCode.Object, null),
                    new Tuple <TypeCode, object>(TypeCode.Object, null)
                },
                Evaluator = delegate(AleTerm term, ref OperationEvalParameters parameters, ref AleTermResult result)
                {
                    if ((bool)parameters.FirstParam)
                    {
                        result.Value = parameters.SecondParam;
                    }
                    else
                    {
                        result.Value = parameters.ThirdParam;
                    }
                    return(true);
                }
            });

            // the "↑" power operator. x↑y means Math.Pow(x,y), x↑ means Math.Pow(x,2)
            // this overloaded constructor creates operator (not function) description. First argument is a operator literal, second is a precedence of operator, third is an associativity
            AP.AddOperation(new AleOperation("↑", 2000, AleOperation.OPERATOR_YFX + AleOperation.OPERATOR_YF)
            {
                // there is no need to initialize Parameters field for operators. It is not used for operators evaluation. Only for functions.

                Evaluator = delegate(AleTerm term, ref OperationEvalParameters parameters, ref AleTermResult result)
                {
                    AleTerm t1 = term[0];

                    AleTermResult a;
                    if (!t1.Evaluate(out a, OnEvaluate, OnAssign) && result.SetError(a.ErrorCode, a.ErrorPos))
                    {
                        return(false);
                    }

                    AleTermResult b = new AleTermResult();
                    if (term.Count == 2)
                    {
                        AleTerm t2 = term[1];
                        if (!t2.Evaluate(out b, OnEvaluate, OnAssign) && result.SetError(b.ErrorCode, b.ErrorPos))
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        b.Value = 2.0;
                    }

                    TypeCode optype = AleTerm.OperationType(a.Value, b.Value);

                    switch (optype)
                    {
                    case TypeCode.Double:
                    case TypeCode.Decimal:
                    case TypeCode.UInt64:
                    case TypeCode.Int64:
                    case TypeCode.UInt32:
                    case TypeCode.Int32:
                        result.Value = Math.Pow(Convert.ToDouble(a.Value), Convert.ToDouble(b.Value));
                        return(true);

                    default:
                        result.SetError(AleTermResult.ERROR_INCOMPATIBLETYPES, term.Token.StartInOrigin);
                        return(false);
                    }
                }
            });

            //// "❗" factorial operator (\u2757 char).
            //AP.AddOperation(new AleOperation("❗", 1800, AleOperation.OPERATOR_YF)
            // "!" factorial operator
            AP.AddOperation(new AleOperation("!", 1800, AleOperation.OPERATOR_YF)
            {
                Evaluator = delegate(AleTerm term, ref OperationEvalParameters parameters, ref AleTermResult result)
                {
                    AleTerm t1 = term[0];

                    AleTermResult a;
                    if (!t1.Evaluate(out a, OnEvaluate, OnAssign) && result.SetError(a.ErrorCode, a.ErrorPos))
                    {
                        return(false);
                    }

                    // check if integer value
                    //if (!AleTerm.ValidForOperationType(a.Value, TypeCode.Int32) && result.SetError(AleTermResult.ERROR_INCOMPATIBLETYPES, term.Token.StartInOrigin)) return false;
                    double nDouble = Convert.ToDouble(a.Value);
                    if (nDouble != Math.Floor(nDouble))
                    {
                        result.SetError(AleTermResult.ERROR_INCOMPATIBLETYPES, term.Token.StartInOrigin);
                        return(false);
                    }

                    // check if allowed value
                    int n = Convert.ToInt32(a.Value);
                    if (n < 1 && result.SetError(AleTermResult.ERROR_EVALUATION, term.Token.StartInOrigin))
                    {
                        return(false);
                    }

                    double fac_n = 1;

                    while (n > 1)
                    {
                        fac_n *= n;
                        n--;
                    }

                    result.Value = fac_n;
                    return(true);
                }
            });

            // disabled: not functional
            //// "²" square operator
            //AP.AddOperation(new AleOperation("²", 1800, AleOperation.OPERATOR_YF)
            //{
            //    Evaluator = delegate(AleTerm term, ref OperationEvalParameters parameters, ref AleTermResult result)
            //    {
            //        AleTerm t1 = term[0];

            //        AleTermResult a;
            //        if (!t1.Evaluate(out a, OnEvaluate, OnAssign) && result.SetError(a.ErrorCode, a.ErrorPos)) return false;

            //        TypeCode optype = AleTerm.OperationType(a.Value, null);

            //        switch (optype)
            //        {
            //            case TypeCode.Double:
            //                result.Value = Math.Pow(Convert.ToDouble(a.Value), 2);
            //                return true;
            //            case TypeCode.Decimal:
            //                result.Value = Convert.ToDecimal(Math.Pow(Convert.ToDouble(a.Value), 2));
            //                return true;
            //            case TypeCode.UInt64:
            //                result.Value = Convert.ToUInt64(Math.Pow(Convert.ToUInt64(a.Value), 2));
            //                return true;
            //            case TypeCode.Int64:
            //                result.Value = Convert.ToInt64(Math.Pow(Convert.ToInt64(a.Value), 2));
            //                return true;
            //            case TypeCode.UInt32:
            //                result.Value = Convert.ToUInt32(Math.Pow(Convert.ToUInt32(a.Value), 2));
            //                return true;
            //            case TypeCode.Int32:
            //                result.Value = Convert.ToInt32(Math.Pow(Convert.ToInt32(a.Value), 2));
            //                return true;
            //            default:
            //                result.SetError(AleTermResult.ERROR_INCOMPATIBLETYPES, term.Token.StartInOrigin);
            //                return false;
            //        }
            //    }
            //});

            AP.AddOperation(new AleOperation(AP.IgnoreCase ? "REVERSE" : "Reverse")
            {
                // Parameters = null - method has no parameters
                InstanceTypeCode = TypeCode.String,
                Evaluator        = delegate(AleTerm term, ref OperationEvalParameters parameters, ref AleTermResult result)
                {
                    StringBuilder s = new StringBuilder(parameters.ClassInstance.ToString());
                    int n           = s.Length;
                    int m           = (n--) / 2;
                    char c;

                    for (int i = 0; i < m; i++)
                    {
                        c        = s[i];
                        s[i]     = s[n - i];
                        s[n - i] = c;
                    }

                    result.Value = s;
                    return(true);
                }
            });
        }