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