예제 #1
0
        /// <summary> Constructor for use when this is called when parsing a string
        ///
        /// </summary>
        /// <param name="sf">the built in function
        /// </param>
        /// <param name="ws">the workbook settings
        /// </param>
        public Attribute(StringFunction sf, WorkbookSettings ws)
        {
            settings = ws;

            if (sf.getFunction(settings) == NExcel.Biff.Formula.Function.SUM)
            {
                options |= sumMask;
            }
            else if (sf.getFunction(settings) == NExcel.Biff.Formula.Function.IF)
            {
                options |= ifMask;
            }
        }
예제 #2
0
        /// <summary> Handles the case when parsing a string when a token is a function
        ///
        /// </summary>
        /// <param name="sf">the string function
        /// </param>
        /// <param name="i"> the token iterator
        /// </param>
        /// <param name="stack">the parse tree stack
        /// </param>
        /// <exception cref=""> FormulaException if an error occurs
        /// </exception>
        private void  handleFunction(StringFunction sf, ArrayList pis, Stack stack)
        {
            ParseItem pi2 = parseCurrent(pis);

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

            // 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);

                // [TODO] TEST is the order the same as in Java?
                object[] argumentsArray = arguments.ToArray();
                for (int j = 0; j < argumentsArray.Length; j++)
                {
                    vaf.add((ParseItem)argumentsArray[j]);
                }


                a.IfConditions = vaf;
                stack.Push(a);
                return;
            }

            // Function cannot be optimized.  See if it is a variable argument
            // function or not
            if (sf.getFunction(settings).NumArgs == 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)
                {
                    VariableArgFunction vaf = new VariableArgFunction(sf.getFunction(settings), 1, settings);
                    vaf.add(pi2);
                    stack.Push(vaf);
                }
                else
                {
                    // Add the args to the function in reverse order.  The
                    // VariableArgFunction will reverse these when it writes out the
                    // byte version as they are stored in the correct order
                    // within Excel
                    int numargs             = arguments.Count;
                    VariableArgFunction vaf = new VariableArgFunction(sf.getFunction(settings), numargs, settings);

                    for (int j = 0; j < numargs; j++)
                    {
                        ParseItem pi3 = (ParseItem)arguments.Pop();
                        vaf.add(pi3);
                    }
                    stack.Push(vaf);
                    // [TODO] - check it
                    //		arguments.empty();
                    arguments.Clear();
                    arguments = null;
                }
                return;
            }

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

            int numargs2 = sf.getFunction(settings).NumArgs;

            if (numargs2 == 1)
            {
                // only one item which is the returned ParseItem
                bif.add(pi2);
            }
            else
            {
                if ((arguments == null && numargs2 != 0) || (arguments != null && numargs2 != arguments.Count))
                {
                    throw new FormulaException(FormulaException.incorrectArguments);
                }
                // multiple arguments so go to the arguments stack.
                // Unlike the variable argument function, the args are
                // stored in reverse order
                // [TODO] TEST is the order the same as in Java?
                object[] argumentsArray = arguments.ToArray();
                for (int j = 0; j < numargs2; j++)
                {
                    bif.add((ParseItem)argumentsArray[j]);
                }
            }
            stack.Push(bif);
        }