Example #1
0
        /**
         * Constructor for use when this is called when parsing a string
         *
         * @param sf the built in function
         * @param ws the workbook settings
         */
        public Attribute(StringFunction sf, WorkbookSettings ws)
        {
            settings = ws;

            if (sf.getFunction(settings) == Function.SUM)
            {
                options |= SUM_MASK;
            }
            else if (sf.getFunction(settings) == Function.IF)
            {
                options |= IF_MASK;
            }
        }
        /**
         * Handles the case when parsing a string when a token is a function
         *
         * @param sf the string function
         * @param i  the token iterator
         * @param stack the parse tree stack
         * @exception FormulaException if an error occurs
         */
        private void handleFunction(StringFunction sf, IEnumerator <ParseItem> i, Stack <ParseItem> stack)
        {
            ParseItem pi2 = parseCurrent(i);

            // If the function is unknown, then throw an error
            if (sf.getFunction(settings) == Function.UNKNOWN)
            {
                throw new FormulaException(FormulaException.UNRECOGNIZED_FUNCTION);
            }

            // First check for possible optimized functions and possible
            // use of the Attribute token
            if (sf.getFunction(settings) == Function.SUM && arguments == null)
            {
                // this is handled by an attribute
                Attribute a = new Attribute(sf, settings);
                a.add(pi2);
                stack.Push(a);
                return;
            }

            if (sf.getFunction(settings) == Function.IF)
            {
                // this is handled by an attribute
                Attribute a = new Attribute(sf, settings);

                // Add in the if conditions as a var arg function in
                // the correct order
                VariableArgFunction vaf   = new VariableArgFunction(settings);
                object []           items = arguments.ToArray();
                for (int j = 0; j < items.Length; j++)
                {
                    ParseItem pi3 = (ParseItem)items[j];
                    vaf.add(pi3);
                }

                a.setIfConditions(vaf);
                stack.Push(a);
                return;
            }

            int newNumArgs;

            // Function cannot be optimized.  See if it is a variable argument
            // function or not
            if (sf.getFunction(settings).getNumArgs() == 0xff)
            {
                // If the arg stack has not been initialized, it means
                // that there was only one argument, which is the
                // returned parse item
                if (arguments == null)
                {
                    int numArgs             = pi2 != null ? 1 : 0;
                    VariableArgFunction vaf = new VariableArgFunction(sf.getFunction(settings), numArgs, settings);

                    if (pi2 != null)
                    {
                        vaf.add(pi2);
                    }

                    stack.Push(vaf);
                }
                else
                {
                    // Add the args to the function in the correct order
                    newNumArgs = arguments.Count;
                    VariableArgFunction vaf = new VariableArgFunction(sf.getFunction(settings), newNumArgs, settings);

                    ParseItem[] args = new ParseItem[newNumArgs];
                    for (int j = 0; j < newNumArgs; j++)
                    {
                        ParseItem pi3 = (ParseItem)arguments.Pop();
                        args[newNumArgs - j - 1] = pi3;
                    }

                    for (int j = 0; j < args.Length; j++)
                    {
                        vaf.add(args[j]);
                    }
                    stack.Push(vaf);
                    arguments.Clear();
                    arguments = null;
                }
                return;
            }

            // Function is a standard built in function
            BuiltInFunction bif = new BuiltInFunction(sf.getFunction(settings), settings);

            newNumArgs = sf.getFunction(settings).getNumArgs();
            if (newNumArgs == 1)
            {
                // only one item which is the returned ParseItem
                bif.add(pi2);
            }
            else
            {
                if ((arguments == null && newNumArgs != 0) ||
                    (arguments != null && newNumArgs != arguments.Count))
                {
                    throw new FormulaException(FormulaException.INCORRECT_ARGUMENTS);
                }
                // multiple arguments so go to the arguments stack.
                // Unlike the variable argument function, the args are
                // stored in reverse order
                object[] items = arguments.ToArray();
                for (int j = 0; j < newNumArgs; j++)
                {
                    ParseItem pi3 = (ParseItem)items[j];
                    bif.add(pi3);
                }
            }
            stack.Push(bif);
        }