コード例 #1
0
        /// <summary>
        /// Returns a delegate to native c# function.
        /// </summary>
        /// <param name="method"></param>
        internal static System.Delegate FormNativeFunctionDelegate(MethodInfo method)
        {
            bool DecorateNativeFunction = false;

            if (method.ReturnType != typeof(QsValue))
            {
                DecorateNativeFunction = true;
            }
            //construct the lambda

            SimpleLambdaBuilder lb = SimpleLambdaBuilder.Create(typeof(QsValue), method.Name);


            //prepare parameters with the same name of native function but with qsparameter type
            var parameters = method.GetParameters();

            foreach (var prm in parameters)
            {
                if (prm.ParameterType != typeof(QsParameter))
                {
                    DecorateNativeFunction = true;
                }
                lb.Parameter(typeof(QsParameter), prm.Name);
            }

            if (!DecorateNativeFunction)
            {
                #region Delegate creation section
                switch (parameters.Length)
                {
                case 0:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsValue>),
                               method));

                case 1:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsValue>),
                               method));

                case 2:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsValue>),
                               method));

                case 3:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 4:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 5:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 6:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 7:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 8:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 9:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 10:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 11:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));

                case 12:
                    return(System.Delegate.CreateDelegate(
                               typeof(Func <QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsParameter, QsValue>),
                               method));
                }
                #endregion
            }

            // we will form a function body that
            //    1- check the parameter
            //    2- convert the parameter into native c# during runtime so it can be passed to the desired function

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

            var qns  = typeof(QsNamespace);
            var qsys = typeof(Root);

            var        convparMethod = qsys.GetMethod("QsParametersToNativeValues", BindingFlags.Static | BindingFlags.Public);
            var        NTOQ          = qsys.GetMethod("NativeToQsConvert", BindingFlags.Static | BindingFlags.Public);
            var        iv            = qns.GetMethod("IndirectInvoke", BindingFlags.Static | BindingFlags.NonPublic);
            Expression methodExpress = Expression.Constant(method);

            if (parameters.Length > 0)
            {
                // Take the function parameter values
                //  to convert it to native values if required.

                // convert to array of QsParameter
                var parms = Expression.NewArrayInit(typeof(QsParameter), lb.Parameters.ToArray());


                // Convert to array of Object
                Expression ConvertedParametersExpression = Expression.Call(convparMethod, methodExpress, parms);

                var rr = Expression.Call(iv, methodExpress, ConvertedParametersExpression);

                var vv = Expression.Call(NTOQ, rr);
                statements.Add(vv);
            }
            else
            {
                var parms = Expression.NewArrayInit(typeof(object));

                var rr = Expression.Call(iv, methodExpress, parms);


                //var rr = Expression.Call(null, method);
                var vv = Expression.Call(NTOQ, rr);
                statements.Add(vv);
            }


            lb.Body = Expression.Block(statements);

            LambdaExpression lbe = lb.MakeLambda();

            return(lbe.Compile());
        }
コード例 #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);
            }
        }