/// <summary>
        /// Process the top operator on the operator stack.
        /// Consume as many operands as needed from the operands stack.
        /// When top-operator is closing bracket, two options:
        ///   a * ( b + c )
        ///   In(a, b)
        /// </summary>
        private void ProcessOperator(OperatorInfo op, Stack <Var> operands)
        {
            ArrayList arglist = new ArrayList();

            if (op.function)
            {
                foreach (Var v in op.parameters)
                {
                    arglist.Add(v);
                }
            }
            else
            {
                // It must be an operator. It can be unary or not, so get at least one operand.
                arglist.Insert(0, operands.Pop());
                if (!op.unary)
                {
                    arglist.Insert(0, operands.Pop());
                }
            }

            if (op.methodname == null && op.function)
            {
                // Process function
                // Haal eerst de functieinformatie op.
                Var result = myTokenResolver.FunctionEvaluator(op.name, arglist);
                System.Diagnostics.Debug.Assert(result != null);
                operands.Push(result);
            }
            else
            {
                Var          o1 = (arglist[0] as Var);
                System.Type  t1 = o1.GetType();
                MemberInfo[] ts = t1.FindMembers(
                    System.Reflection.MemberTypes.Method,
                    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public,
                    new System.Reflection.MemberFilter(FindOperator),
                    op);

                if (ts.GetLength(0) == 0)
                {
                    throw new OperationNotDefinedException(null, op.name, o1.TypeName(), arglist);
                }

                // Find the method taking the right type of parameter
                MethodInfo methodFound = null;
                foreach (MethodInfo method in ts)
                {
                    ParameterInfo[] parms = method.GetParameters();

                    if (parms.GetLength(0) == arglist.Count)
                    {
                        methodFound = method;
                        for (int pi = 0; pi < arglist.Count; pi++)
                        {
                            if (parms[pi].ParameterType != arglist[pi].GetType())
                            {
                                methodFound = null;
                                break;
                            }
                        }
                        if (methodFound != null)
                        {
                            break;
                        }
                    }
                }
                if (methodFound == null)
                {
                    throw new OperationNotDefinedException(null, op.name, o1.TypeName(), arglist);
                }

                // Method found. Apply it
                object[] args = arglist.ToArray();
                //			if (op.unary)
                //				args = new object[] {o1};
                //			else
                //				args = new object[] {o1, o2};

                if (methodFound.ReturnType == typeof(void))
                {
                    methodFound.Invoke(null, args);
                }
                else
                {
                    object result = methodFound.Invoke(null, args);
                    operands.Push(result as Var);
                }
            }
            return;
        }
Exemple #2
0
        /// <summary>
        /// Process the top operator on the operator stack.
        /// Consume as many operands as needed from the operands stack.
        /// When top-operator is closing bracket, two options:
        ///   a * ( b + c )
        ///   In(a, b)
        /// </summary>
        private void ProcessOperator()
        {
            ArrayList arglist = new ArrayList();

            // Process closing bracket. Pop operators and process these
            // until an opening bracket is found on the stack.
            OperatorInfo op = PopOperator();

            if (op.name == ")")
            {
                op = PopOperator();
                while (op.name != "(")
                {
                    System.Diagnostics.Debug.Assert(op.name == ",", "Er zou alleen een ',' op de stack mogen staan of een '(', en niet een '" + op.name + "'");
                    arglist.Insert(0, mOperands.Pop());
                    op = PopOperator();
                }

                if (arglist.Count > 0)
                {
                    if (mTopOperator == null || !mTopOperator.function)
                    {
                        throw new ApplicationException(String.Format("Argument list found but not function call before '('"));
                    }
                }
                else
                {
                    // No arglist found.
                    // If function, pop first argument, else it was () combination. Return
                    if (mTopOperator == null || !mTopOperator.function)
                    {
                        return;
                    }
                }
                // It is a function call
                // Pop first argument
                arglist.Insert(0, mOperands.Pop());
                op = PopOperator();
            }
            else if (op.name == "," || op.name == "(")
            {
                PushOperator(op);                       // do not process yet!
                return;
            }
            else
            {
                // It must be an operator. It can be unary or not, so get at least one operand.
                arglist.Insert(0, mOperands.Pop());
                if (!op.unary)
                {
                    arglist.Insert(0, mOperands.Pop());
                }
            }

            Var o1 = (arglist[0] as Var);

            if (op.methodname == null && op.function)
            {
                // Process function
                // Haal eerst de functieinformatie op.
                Var result = myTokenResolver.FunctionEvaluator(op.name, arglist);
                mOperands.Push(result);
            }
            else
            {
                System.Type  t1 = o1.GetType();
                MemberInfo[] ts = t1.FindMembers(
                    System.Reflection.MemberTypes.Method,
                    System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public,
                    new System.Reflection.MemberFilter(FindOperator),
                    op);

                if (ts.GetLength(0) == 0)
                {
                    throw new ApplicationException(String.Format("Operation '{0}' not defined for '{1}'", op.name, o1.GetType().Name));
                }

                // Find the method taking the right type of parameter
                MethodInfo methodFound = null;
                foreach (MethodInfo method in ts)
                {
                    ParameterInfo[] parms = method.GetParameters();

                    if (parms.GetLength(0) == arglist.Count)
                    {
                        methodFound = method;
                        for (int pi = 0; pi < arglist.Count; pi++)
                        {
                            if (parms[pi].ParameterType != arglist[pi].GetType())
                            {
                                methodFound = null;
                                break;
                            }
                        }
                        if (methodFound != null)
                        {
                            break;
                        }
                    }
                }
                if (methodFound == null)
                {
                    string msg = String.Format("Operation '{0}' not defined for ", op.name);
                    foreach (Var v in arglist)
                    {
                        msg += "'" + v.GetType().Name + "',";
                    }
                    throw new ApplicationException(msg);
                    //				if (op.unary)
                    //					throw new ApplicationException(String.Format("Operation '{0}' not defined for '{1}'", op.name, o1.GetType().Name));
                    //				else
                    //					throw new ApplicationException(String.Format("Operation '{0}' not defined for '{1}' and '{2}'", op.name, o1.GetType().Name, o2.GetType().Name));
                }

                // Method found. Apply it
                object[] args = arglist.ToArray();
                //			if (op.unary)
                //				args = new object[] {o1};
                //			else
                //				args = new object[] {o1, o2};

                if (methodFound.ReturnType == typeof(void))
                {
                    methodFound.Invoke(null, args);
                }
                else
                {
                    object result = methodFound.Invoke(null, args);
                    mOperands.Push(result);
                }
            }
            return;
        }