diff --git a/src/com/bytezone/diskbrowser/visicalc/And.java b/src/com/bytezone/diskbrowser/visicalc/And.java index 624f530..bc8092a 100644 --- a/src/com/bytezone/diskbrowser/visicalc/And.java +++ b/src/com/bytezone/diskbrowser/visicalc/And.java @@ -11,9 +11,18 @@ class And extends Function { super (parent, cell, text); - String list[] = text.split (","); - for (String s : list) - conditions.add (new Condition (parent, cell, s)); + String remainder = functionText; + while (true) + { + String parameter = Expression.getParameter (remainder); + System.out.printf ("cond: [%s]%n", parameter); + conditions.add (new Condition (parent, cell, parameter)); + // System.out.printf (" [%s]%n", remainder); + // System.out.printf (" [%s]%n", parameter); + if (remainder.length () == parameter.length ()) + break; + remainder = remainder.substring (parameter.length () + 1); + } } @Override diff --git a/src/com/bytezone/diskbrowser/visicalc/Expression.java b/src/com/bytezone/diskbrowser/visicalc/Expression.java index 2713805..52bb294 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Expression.java +++ b/src/com/bytezone/diskbrowser/visicalc/Expression.java @@ -310,14 +310,43 @@ class Expression extends AbstractValue implements Iterable return text.substring (0, ptr + 1); // include closing parenthesis } - static String getFunctionName (String text, int offset) + // reads text up to the next comma that is not part of a function + // text does not include the outer brackets or calling function name + static String getParameter (String text) { - int pos1 = text.indexOf ('(', offset); - int pos2 = text.indexOf (',', offset); + int depth = 0; + int ptr = 0; - if (pos1 > offset && pos1 < pos2) - return text.substring (offset, pos1); - return text.substring (offset, pos2); + while (ptr < text.length ()) + { + char c = text.charAt (ptr); + if (c == '(') + ++depth; + else if (c == ')') + --depth; + else if (c == ',' && depth == 0) + break; + ++ptr; + } + + return text.substring (0, ptr); + } + + // receives a string starting with the function call + static String getFunctionCall (String text) + { + if (text.charAt (0) != '@') + throw new IllegalArgumentException ("Bad function name: " + text); + + for (String functionName : Function.functionList) + if (text.startsWith (functionName)) + { + if (functionName.endsWith ("(")) // if function has parameters + return getBalancedText (text); // return full function call + return functionName; // return function name only + } + + throw new IllegalArgumentException ("Bad function name: " + text); } private String getNumberText (String text) diff --git a/src/com/bytezone/diskbrowser/visicalc/False.java b/src/com/bytezone/diskbrowser/visicalc/False.java new file mode 100644 index 0000000..e475d38 --- /dev/null +++ b/src/com/bytezone/diskbrowser/visicalc/False.java @@ -0,0 +1,11 @@ +package com.bytezone.diskbrowser.visicalc; + +public class False extends Function +{ + False (Sheet parent, Cell cell, String text) + { + super (parent, cell, text); + + value = 0; + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/visicalc/Function.java b/src/com/bytezone/diskbrowser/visicalc/Function.java index 072831b..1712038 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Function.java +++ b/src/com/bytezone/diskbrowser/visicalc/Function.java @@ -4,6 +4,12 @@ import java.util.Iterator; abstract class Function extends AbstractValue implements Iterable { + static final String[] functionList = + { "@ABS(", "@ACOS(", "@AND(", "@ASIN(", "@ATAN(", "@AVERAGE(", "@COUNT(", + "@CHOOSE(", "@COS(", "@ERROR", "@EXP(", "@FALSE", "@IF(", "@INT(", "@ISERROR(", + "@ISNA(", "@LOG10(", "@LOOKUP(", "@LN(", "@MIN(", "@MAX(", "@NA", "@NPV", "@OR(", + "@PI", "@SIN(", "@SUM(", "@SQRT(", "@TAN(", "@TRUE" }; + protected final Sheet parent; protected final Cell cell; protected String functionName; @@ -54,9 +60,14 @@ abstract class Function extends AbstractValue implements Iterable if (text.startsWith ("@ERROR")) return new Error (parent, cell, text); - if (text.startsWith ("@EXP")) + if (text.startsWith ("@EXP(")) return new Exp (parent, cell, text); } + else if (text.charAt (1) == 'F') + { + if (text.startsWith ("@FALSE")) + return new False (parent, cell, text); + } else if (text.charAt (1) == 'I') { if (text.startsWith ("@IF(")) @@ -123,6 +134,9 @@ abstract class Function extends AbstractValue implements Iterable { if (text.startsWith ("@TAN(")) return new Tan (parent, cell, text); + + if (text.startsWith ("@TRUE")) + return new True (parent, cell, text); } System.out.printf ("Unknown function: [%s]%n", text); diff --git a/src/com/bytezone/diskbrowser/visicalc/If.java b/src/com/bytezone/diskbrowser/visicalc/If.java index f99a0e3..1e69d09 100644 --- a/src/com/bytezone/diskbrowser/visicalc/If.java +++ b/src/com/bytezone/diskbrowser/visicalc/If.java @@ -14,52 +14,20 @@ class If extends Function { super (parent, cell, text); - int pos1 = functionText.indexOf (','); - int pos2 = -1; - if (pos1 < 0) - throw new IllegalArgumentException ("Not enough parameters for IF: " + text); + conditionText = Expression.getParameter (functionText); + textTrue = + Expression.getParameter (functionText.substring (conditionText.length () + 1)); + textFalse = Expression.getParameter ( + functionText.substring (conditionText.length () + textTrue.length () + 2)); - conditionText = functionText.substring (0, pos1); condition = new Condition (parent, cell, conditionText); - // System.out.printf ("Cond : %s%n", conditionText); values.add (condition); - if (functionText.charAt (pos1 + 1) == '@') - { - String functionName = Expression.getFunctionName (functionText, pos1 + 1); - int nameLength = functionName.length (); - if (functionText.charAt (pos1 + nameLength + 1) == ',') // no brackets or parameters - { - // System.out.printf ("no parameters [%s]%n", functionName); - textTrue = functionName; - } - else - { - textTrue = Expression.getBalancedText (functionText.substring (pos1 + 1)); - // System.out.printf ("parameters [%s]%n", textTrue); - } - // System.out.printf ("True : %s%n", textTrue); - expTrue = new Expression (parent, cell, textTrue); - pos2 = functionText.indexOf (',', pos1 + textTrue.length () + 1); - } - else - { - pos2 = functionText.indexOf (',', pos1 + 1); - textTrue = functionText.substring (pos1 + 1, pos2); - // System.out.printf ("True : %s%n", textTrue); - expTrue = new Expression (parent, cell, functionText.substring (pos1 + 1, pos2)); - } + expTrue = new Expression (parent, cell, textTrue); values.add (expTrue); - if (pos2 < 0) - throw new IllegalArgumentException ("Not enough parameters for IF: " + text); - - textFalse = functionText.substring (pos2 + 1); - // System.out.printf ("False: %s%n", textFalse); expFalse = new Expression (parent, cell, textFalse); values.add (expFalse); - - // System.out.println (); } @Override diff --git a/src/com/bytezone/diskbrowser/visicalc/Or.java b/src/com/bytezone/diskbrowser/visicalc/Or.java index d234d90..7fe6613 100644 --- a/src/com/bytezone/diskbrowser/visicalc/Or.java +++ b/src/com/bytezone/diskbrowser/visicalc/Or.java @@ -11,9 +11,18 @@ class Or extends Function { super (parent, cell, text); - String list[] = text.split (","); - for (String s : list) - conditions.add (new Condition (parent, cell, s)); + String remainder = functionText; + while (true) + { + String parameter = Expression.getParameter (remainder); + System.out.printf ("cond: [%s]%n", parameter); + conditions.add (new Condition (parent, cell, parameter)); + // System.out.printf (" [%s]%n", remainder); + // System.out.printf (" [%s]%n", parameter); + if (remainder.length () == parameter.length ()) + break; + remainder = remainder.substring (parameter.length () + 1); + } } @Override diff --git a/src/com/bytezone/diskbrowser/visicalc/True.java b/src/com/bytezone/diskbrowser/visicalc/True.java new file mode 100644 index 0000000..81fe490 --- /dev/null +++ b/src/com/bytezone/diskbrowser/visicalc/True.java @@ -0,0 +1,11 @@ +package com.bytezone.diskbrowser.visicalc; + +public class True extends Function +{ + True (Sheet parent, Cell cell, String text) + { + super (parent, cell, text); + + value = 1; + } +} \ No newline at end of file