コード例 #1
0
        /// <summary>
        /// Differentiate operation for function.
        /// </summary>
        /// <param name="value">object of <see cref="QsScalar"/> that hold <see cref="AnyQuantity&lt;SymbolicVariable&gt;"/></param>
        /// <returns></returns>
        public override QsValue DifferentiateOperation(QsValue value)
        {
            QsScalar sval = (QsScalar)value;

            if (sval.ScalarType == ScalarTypes.SymbolicQuantity)
            {
                var dsv = sval.SymbolicQuantity.Value;

                string fname         = "_";
                string WholeFunction = string.Empty;
                if (this.FunctionBodyToken[0].TokenClassType == typeof(CurlyBracketGroupToken))
                {
                    // vector differentiation
                    // take every term in the vector and differentiate it
                    var           vcs = QsVar.VectorComponents(this.FunctionBodyToken[0]);
                    StringBuilder sc  = new StringBuilder();
                    sc.Append(fname + "(" + RemoveRedundantParameters(this.ParametersNames) + ") = ");
                    sc.Append("{ ");
                    foreach (var c in vcs)
                    {
                        SymbolicVariable nsv = SymbolicVariable.Parse(c);
                        int times            = (int)dsv.SymbolPower;
                        while (times > 0)
                        {
                            nsv = nsv.Differentiate(dsv.Symbol);
                            times--;
                        }
                        sc.Append(nsv.ToString());
                        sc.Append(" ");
                    }
                    sc.Append("}");

                    WholeFunction = sc.ToString();
                }
                else
                {
                    SymbolicVariable nsv = ToSymbolicVariable();
                    int times            = (int)dsv.SymbolPower;
                    while (times > 0)
                    {
                        nsv = nsv.Differentiate(dsv.Symbol);
                        times--;
                    }

                    WholeFunction = fname + "(" + RemoveRedundantParameters(this.ParametersNames) + ") = " + nsv.ToString();
                }


                return(QsFunction.ParseFunction(QsEvaluator.CurrentEvaluator, WholeFunction));
            }
            else
            {
                return(base.DifferentiateOperation(value));
            }
        }
コード例 #2
0
        /// <summary>
        /// Parse the element text and make the element point to delegate which evaluate the text if necessary.
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public static QsSequenceElement Parse(string element, QsEvaluator qse, QsSequence sequence)
        {
            if (string.IsNullOrEmpty(element))
            {
                throw new QsException("Can't create element from empty string.");
            }

            //try direct quantity
            AnyQuantity <double> v;

            if (Unit.TryParseQuantity(element, out v))
            {
                var el = QsSequenceElement.FromQuantity(new QsScalar {
                    NumericalQuantity = v
                });
                el.ElementDeclaration = element;

                el.IndexEvaluation     = false;
                el.ParameterEvaluation = false;
                return(el);
            }
            else
            {
                QsSequenceElement se = new QsSequenceElement();

                //try one index delegate without parameters
                //Create the lambda function that will pass the index and parameters to the expression.
                SimpleLambdaBuilder lb = SimpleLambdaBuilder.Create(typeof(QsValue), "ElementValue");

                //add the index parameter
                lb.Parameter(typeof(int), sequence.SequenceIndexName);


                //find the index parameter in line to know if it will be evaluated or not
                if (element.IndexOf(sequence.SequenceIndexName) > -1)
                {
                    se.IndexEvaluation = true;
                }


                //make the sequence parameters.
                foreach (var seqParam in sequence.Parameters)
                {
                    lb.Parameter(typeof(QsValue), seqParam.Name);
                    if (element.IndexOf(seqParam.Name) > -1)
                    {
                        se.ParameterEvaluation = true;
                    }
                }

                QsVar pvar = new QsVar(qse, element, sequence, lb);

                lb.Body = pvar.ResultExpression;

                LambdaExpression le = lb.MakeLambda();

                se.ElementDeclaration = element;
                se.ElementExpression  = pvar.ResultExpression;
                se.ElementValue       = le.Compile();

                return(se);
            }

            throw new QsException("Check me in sequence element :( :( :( ");
        }
コード例 #3
0
        public static QsFunction ParseFunction(QsEvaluator qse, string functionDeclaration, Token functionToken)
        {
            int nsidx = 0; // surve as a base for indexing token if there is namespace it will be 1 otherwise remain 0

            // specify the namespaces end token.
            string functionNamespace = "";

            foreach (var tok in functionToken)
            {
                if (tok.TokenClassType == typeof(NamespaceToken))
                {
                    nsidx++;
                    functionNamespace += tok.TokenValue;
                }
                else
                {
                    break;
                }
            }

            if (
                functionToken[nsidx].TokenClassType == typeof(WordToken) &&
                (functionToken.Count > (nsidx + 1) ? functionToken[nsidx + 1].TokenClassType == typeof(ParenthesisGroupToken) : false) &&
                (functionToken.Count > (nsidx + 2) ? functionToken[nsidx + 2].TokenClassType == typeof(EqualToken) : false)
                )
            {
                //get function name
                // will be the first token after excluding namespace.

                string functionName = string.Empty;


                functionName = functionToken[nsidx].TokenValue;

                //remove the last : from namespace
                functionNamespace = functionNamespace.TrimEnd(':');

                List <string>      textParams = new List <string>();
                List <QsParamInfo> prms       = new List <QsParamInfo>();
                foreach (var c in functionToken[nsidx + 1])
                {
                    if (
                        c.TokenValue.StartsWith("(") ||
                        c.TokenValue.StartsWith(")") ||
                        c.TokenValue.StartsWith(",") ||
                        c.TokenClassType == typeof(MultipleSpaceToken)
                        )
                    {
                        //ignore these things.
                    }
                    else
                    {
                        if (char.IsLetter(c.TokenValue[0]))
                        {
                            textParams.Add(c.TokenValue);
                            prms.Add(new QsParamInfo {
                                Name = c.TokenValue, Type = QsParamType.Value
                            });
                        }
                        else
                        {
                            throw new QsSyntaxErrorException("Parameter name must statrt with a letter");
                        }
                    }
                }

                //declared for first time a default function.
                QsFunction qf = new QsFunction(functionDeclaration)
                {
                    FunctionNamespace = functionNamespace,
                    FunctionName      = functionName,
                    Parameters        = prms.ToArray()
                };


                //LambdaBuilder lb = Utils.Lambda(typeof(QsValue), functionName);
                SimpleLambdaBuilder lb = SimpleLambdaBuilder.Create(typeof(QsValue), functionName);

                foreach (QsParamInfo prm in prms)
                {
                    lb.Parameter(typeof(QsParameter), prm.Name);
                }

                List <Expression> statements = new List <Expression>();

                qf.FunctionBody = functionDeclaration.Substring(functionToken[nsidx + 2].IndexInText + functionToken[nsidx + 2].TokenValueLength).Trim();

                Token functionBodyTokens;
                QsVar qv = new QsVar(qse, qf.FunctionBody, qf, lb, out functionBodyTokens);

                statements.Add(qv.ResultExpression);   //making the variable expression itself make it the return value of the function.

                lb.Body = Expression.Block(statements);



                LambdaExpression lbe = lb.MakeLambda();

                qf.FunctionExpression = lbe;

                qf.FunctionBodyToken = functionBodyTokens;

                return(qf);
            }
            else
            {
                return(null);
            }
        }
コード例 #4
0
        /// <summary>
        /// Evaluate every argument and call the suitable function
        /// </summary>
        /// <param name="vario"></param>
        /// <returns></returns>
        internal Expression GetInvokeExpression(QsVar vario, string[] args)
        {
            List <Expression> parameters = new List <Expression>();

            for (int ip = 0; ip < args.Count(); ip++)
            {
                Expression nakedParameter;
                Expression rawParameter = Expression.Constant(args[ip].Trim());

                if (this.Parameters[ip].Type == QsParamType.Function) //is this parameter in declaration is pointing to function handle
                {
                    //yes: treat this parameter as function handle
                    // get the argument as a string value to be used after that as a function name.
                    nakedParameter = Expression.Constant(args[ip]);  // and I will postpone the evaluation until we process the function.

                    //expression to make parameter from the corresponding naked parameter
                    parameters.Add(Expression.Call(typeof(QsParameter).GetMethod("MakeParameter"),
                                                   nakedParameter,
                                                   rawParameter));
                }
                else if (this.Parameters[ip].Type == QsParamType.Raw)
                {
                    //don't evaluate the parameter
                    // just take the text and pass it to the function as it is.
                    nakedParameter = Expression.Constant(QsParameter.MakeParameter(args[ip], args[ip]));

                    parameters.Add(nakedParameter);
                }
                else
                {
                    //normal variable

                    nakedParameter = vario.ParseArithmatic(args[ip]);

                    // if this was another function name without like  v(c,g,8)  where g is a function name will be passed to c
                    //  then excpetion will occur in GetQuantity that variable was not found in the scope

                    Expression tryBody = Expression.Call(typeof(QsParameter).GetMethod("MakeParameter"),
                                                         nakedParameter,
                                                         rawParameter);


                    // -> Catch(QsVariableNotFoundException e) {QsParameter.MakeParameter(e.ExtraData, args[ip])}

                    var        e         = Expression.Parameter(typeof(QsVariableNotFoundException), "e");
                    Expression catchBody = Expression.Call(typeof(QsParameter).GetMethod("MakeParameter"),
                                                           Expression.Property(e, "ExtraData"),
                                                           rawParameter);

                    // The try catch block when catch exception will execute the call but by passing the parameter as text only

                    /*
                     * var tt = Utils.Try(tryBody);
                     *
                     * tt.Catch(e, catchBody);
                     * Expression tryc  = tt.ToExpression()
                     */
                    Expression tryc = Expression.TryCatch(tryBody, Expression.Catch(e, catchBody));

                    parameters.Add(tryc);
                }
            }


            var qsParamArray = Expression.NewArrayInit(typeof(QsParameter), parameters);

            return(Expression.Call(Expression.Constant(this), this.GetType().GetMethod("InvokeByQsParameters"), qsParamArray));
        }