Added ValueResult, modified ValueType

This commit is contained in:
Denis Molony 2017-03-24 00:30:41 +11:00
parent 8286ff026f
commit 71ce82ce69
45 changed files with 736 additions and 430 deletions

View File

@ -11,6 +11,6 @@ public class Abs extends ValueFunction
@Override
double calculateValue ()
{
return Math.abs (source.getValue ());
return Math.abs (source.getDouble ());
}
}

View File

@ -6,20 +6,24 @@ import java.util.List;
public abstract class AbstractValue implements Value, Iterable<Value>
{
protected final String typeText;
protected final Cell cell;
protected final String fullText;
protected double value;
protected ValueType valueType = ValueType.VALUE;
protected boolean bool;
protected ValueType valueType = ValueType.NUMBER; // could be BOOLEAN
protected ValueResult valueResult = ValueResult.VALID;
protected List<Value> values = new ArrayList<Value> ();
public AbstractValue (String typeText)
public AbstractValue (Cell cell, String text)
{
this.typeText = typeText;
this.cell = cell;
this.fullText = text;
}
@Override
public String getTypeText ()
public String getFullText ()
{
return typeText;
return fullText;
}
@Override
@ -29,40 +33,63 @@ public abstract class AbstractValue implements Value, Iterable<Value>
}
@Override
public boolean isValueType (ValueType type)
public ValueResult getValueResult ()
{
return valueType == type;
return valueResult;
}
@Override
public double getValue ()
public boolean isValid ()
{
return valueResult == ValueResult.VALID;
}
// @Override
// public boolean isValueType (ValueType type)
// {
// return valueType == type;
// }
@Override
public double getDouble ()
{
return value;
}
@Override
public boolean getBoolean ()
{
return bool;
}
@Override
public String getText ()
{
switch (valueType)
switch (valueResult)
{
case NA:
return "NA";
case ERROR:
return "ERROR";
case VALID:
switch (valueType)
{
case BOOLEAN:
return bool ? "TRUE" : "FALSE";
case NUMBER:
return value + "";
default:
return "impossible";
}
default:
return "";
return "impossible";
}
}
@Override
public void calculate ()
{
}
@Override
public boolean isBoolean ()
{
return false;
// System.out.println ("calculate not overridden: " + cell);
}
@Override
@ -72,41 +99,57 @@ public abstract class AbstractValue implements Value, Iterable<Value>
}
// for debugging
String getValueText (int depth)
{
StringBuilder text = new StringBuilder ();
String typeText = " " + getTypeText ();
if (isValueType (ValueType.VALUE))
{
String valueText = String.format ("%f", getValue ());
text.append (String.format ("| %-10s : %-69s |%n", typeText, valueText));
}
else
text.append (String.format ("| %-10s : %-69s |%n", typeText, getValueType ()));
if (this instanceof Expression)
{
text.append (
String.format ("| Expression : %-69s |%n", ((Expression) this).fullText ()));
for (Value v : (Expression) this)
text.append (((AbstractValue) v).getValueText (depth + 1));
}
else if (this instanceof Function)
{
text.append (
String.format ("| Function : %-69s |%n", ((Function) this).fullText));
for (Value v : (Function) this)
text.append (((AbstractValue) v).getValueText (depth + 1));
}
else if (this instanceof Condition)
{
text.append (
String.format ("| Condition : %-69s |%n", ((Condition) this).getFullText ()));
for (Value v : (Condition) this)
text.append (((AbstractValue) v).getValueText (depth + 1));
}
return text.toString ();
}
// String getValueText (int depth)
// {
// StringBuilder text = new StringBuilder ();
//
// String typeText = " " + getTypeText ();
// if (getValueType () == ValueType.NUMBER)
// {
// String valueText = String.format ("%f", getDouble ());
// text.append (String.format ("| %-10s : %-69s |%n", typeText, valueText));
// }
// else if (getValueType () == ValueType.BOOLEAN)
// {
// String valueText = String.format ("%s", getBoolean ());
// text.append (String.format ("| %-10s : %-69s |%n", typeText, valueText));
// }
// else
// text.append (String.format ("| %-10s : %-69s |%n", typeText, getValueType ()));
//
// if (this instanceof Expression)
// {
// text.append (
// String.format ("| Expression : %-69s |%n", ((Expression) this).fullText ()));
// for (Value v : (Expression) this)
// {
// if (v instanceof Cell)
// {
// Cell c = (Cell) v;
// ValueType vt = c.getValueType ();
// String tx = vt == ValueType.NUMBER ? c.getDouble () + "" : c.getBoolean () + "";
// text.append (
// String.format ("| Cell %-3s : %-69s |%n", c.getAddressText (), tx));
// }
// else
// text.append (((AbstractValue) v).getValueText (depth + 1));
// }
// }
// else if (this instanceof Function)
// {
// text.append (
// String.format ("| Function : %-69s |%n", ((Function) this).fullText));
// for (Value v : (Function) this)
// text.append (((AbstractValue) v).getValueText (depth + 1));
// }
// else if (this instanceof Condition)
// {
// text.append (
// String.format ("| Condition : %-69s |%n", ((Condition) this).getFullText ()));
// for (Value v : (Condition) this)
// text.append (((AbstractValue) v).getValueText (depth + 1));
// }
//
// return text.toString ();
// }
}

View File

@ -11,6 +11,6 @@ public class Acos extends ValueFunction
@Override
public double calculateValue ()
{
return Math.acos (source.getValue ());
return Math.acos (source.getDouble ());
}
}

View File

@ -1,42 +1,25 @@
package com.bytezone.diskbrowser.visicalc;
class And extends Function
class And extends ConditionListFunction
{
private final ConditionList conditions;
public And (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@AND(") : text;
conditions = new ConditionList (cell, functionText);
}
@Override
public void calculate ()
{
for (Condition condition : conditions)
for (Value condition : conditions)
{
condition.calculate ();
if (condition.getValue () == 0)
if (!condition.getBoolean ())
{
value = 0;
bool = false;
return;
}
}
value = 1;
}
@Override
public boolean isBoolean ()
{
return true;
}
@Override
public String getText ()
{
return value == 0 ? "FALSE" : "TRUE";
bool = true;
}
}

View File

@ -11,6 +11,6 @@ public class Asin extends ValueFunction
@Override
public double calculateValue ()
{
return Math.asin (source.getValue ());
return Math.asin (source.getDouble ());
}
}

View File

@ -11,6 +11,6 @@ public class Atan extends ValueFunction
@Override
public double calculateValue ()
{
return Math.atan (source.getValue ());
return Math.atan (source.getDouble ());
}
}

View File

@ -7,7 +7,9 @@ public class Average extends ValueListFunction
public Average (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@AVERAGE(") : text;
valueType = ValueType.NUMBER;
}
@Override
@ -15,6 +17,7 @@ public class Average extends ValueListFunction
{
double total = 0.0;
int totalChecked = 0;
valueResult = ValueResult.VALID;
for (Value v : list)
{
@ -23,26 +26,25 @@ public class Average extends ValueListFunction
v.calculate ();
if (v.isValueType (ValueType.NA))
if (v.getValueResult () == ValueResult.NA)
continue;
if (!v.isValueType (ValueType.VALUE))
if (!v.isValid ())
{
valueType = v.getValueType ();
valueResult = v.getValueResult ();
return;
}
total += v.getValue ();
total += v.getDouble ();
totalChecked++;
}
if (totalChecked == 0)
{
valueType = ValueType.ERROR;
valueResult = ValueResult.ERROR;
return;
}
value = total / totalChecked;
valueType = ValueType.VALUE;
}
}

View File

@ -0,0 +1,27 @@
package com.bytezone.diskbrowser.visicalc;
public class BooleanFunction extends Function
{
protected Value source;
BooleanFunction (Cell cell, String text)
{
super (cell, text);
source = cell.getExpressionValue (functionText);
values.add (source);
valueType = ValueType.BOOLEAN;
}
@Override
public boolean getBoolean ()
{
return bool;
}
@Override
public String getType ()
{
return "BooleanFunction";
}
}

View File

@ -1,6 +1,6 @@
package com.bytezone.diskbrowser.visicalc;
class Cell extends AbstractValue implements Comparable<Cell>
class Cell implements Value, Comparable<Cell>
{
private static final String line = "+----------------------------------------"
+ "--------------------------------------------+";
@ -8,16 +8,16 @@ class Cell extends AbstractValue implements Comparable<Cell>
private final Address address;
private final Sheet parent;
private CellType cellType;
private String expressionText;
private String fullText;
private char cellFormat = ' ';
private String repeatingText;
private String repeat = "";
private String label;
private Value value;
private boolean calculated;
private CellType cellType;
private String repeatingText; // REPEATING_CHARACTER
private String label; // LABEL
private Value value; // VALUE
enum CellType
{
LABEL, REPEATING_CHARACTER, VALUE, EMPTY
@ -25,8 +25,6 @@ class Cell extends AbstractValue implements Comparable<Cell>
public Cell (Sheet parent, Address address)
{
super ("Cell " + address.getText ());
this.parent = parent;
this.address = address;
@ -125,60 +123,66 @@ class Cell extends AbstractValue implements Comparable<Cell>
}
else
{
fullText = command;
cellType = CellType.VALUE;
try
{
expressionText = command;
value = new Expression (this, expressionText).reduce ();
cellType = CellType.VALUE;
value = new Expression (this, fullText).reduce ();
}
catch (IllegalArgumentException e)
{
System.out.println ("ignoring error: " + command);
value = new Error (this, "@ERROR");
}
}
// FUTURE.VC
if (false)
setTestData (0);
}
private void setTestData (int choice)
{
// FUTURE.VC
if (choice == 1)
{
System.out.println ("****** Hardcoded values ******");
if (address.getRowKey () == 67)
expressionText = "1000";
fullText = "1000";
else if (address.getRowKey () == 131)
expressionText = "10.5";
fullText = "10.5";
else if (address.getRowKey () == 195)
expressionText = "12";
fullText = "12";
else if (address.getRowKey () == 259)
expressionText = "8";
fullText = "8";
}
// IRA.VC
if (false)
if (choice == 2)
{
System.out.println ("****** Hardcoded values ******");
if (address.getRowKey () == 66)
expressionText = "10";
fullText = "10";
else if (address.getRowKey () == 130)
expressionText = "30";
fullText = "30";
else if (address.getRowKey () == 194)
expressionText = "65";
fullText = "65";
else if (address.getRowKey () == 258)
expressionText = "1000";
fullText = "1000";
else if (address.getRowKey () == 386)
expressionText = "15";
fullText = "15";
}
// CARLOAN.VC
if (false)
if (choice == 3)
{
System.out.println ("****** Hardcoded values ******");
if (address.getRowKey () == 67)
expressionText = "9375";
fullText = "9375";
else if (address.getRowKey () == 131)
expressionText = "4500";
fullText = "4500";
else if (address.getRowKey () == 195)
expressionText = "24";
fullText = "24";
else if (address.getRowKey () == 259)
expressionText = "11.9";
fullText = "11.9";
}
}
@ -201,58 +205,42 @@ class Cell extends AbstractValue implements Comparable<Cell>
return Format.justify (empty, colWidth, ' ');
case VALUE:
if (!isValueType (ValueType.VALUE))
switch (getValueResult ())
{
if (fmtChar == ' ')
fmtChar = 'R';
return " " + Format.justify (value.getText (), colWidth - 1, fmtChar);
case ERROR:
case NA:
if (fmtChar == ' ')
fmtChar = 'R';
return " " + Format.justify (value.getText (), colWidth - 1, fmtChar);
case VALID:
switch (getValueType ())
{
case BOOLEAN:
if (fmtChar != 'L')
fmtChar = 'R';
return Format.justify (value.getText (), colWidth, fmtChar);
case NUMBER:
if (colWidth == 1)
return ".";
return " " + Format.format (value, fmtChar, colWidth - 1);
default:
assert false;
return "Impossible";
}
default:
assert false;
return "Impossible";
}
if (value.isBoolean ()) // consider ValueType of BOOLEAN
{
if (fmtChar != 'L')
fmtChar = 'R';
return Format.justify (value.getText (), colWidth, fmtChar);
}
if (colWidth == 1)
return ".";
return " " + Format.format (value, fmtChar, colWidth - 1);
default:
assert false;
return "Impossible";
return "impossible";
}
}
@Override
public double getValue ()
{
return cellType == CellType.VALUE ? value.getValue () : 0;
}
@Override
public ValueType getValueType ()
{
return cellType == CellType.VALUE ? value.getValueType () : ValueType.VALUE;
}
@Override
public String getText ()
{
// cell points to another cell which is ERROR or NA
assert cellType == CellType.VALUE;
assert !value.isValueType (ValueType.VALUE);
return value.getText ();
}
@Override
public boolean isValueType (ValueType type)
{
return type == getValueType ();
}
@Override
public void calculate ()
{
@ -263,46 +251,115 @@ class Cell extends AbstractValue implements Comparable<Cell>
}
}
public String getDebugText ()
@Override
public boolean isValid ()
{
StringBuilder text = new StringBuilder ();
text.append (line);
text.append ("\n");
text.append (String.format ("| %-11s %s Format: %s |%n",
address.getText (), address.getDetails (), cellFormat));
text.append (line);
text.append ("\n");
return cellType == CellType.VALUE ? value.isValid () : true;
}
@Override
public ValueResult getValueResult ()
{
return cellType == CellType.VALUE ? value.getValueResult () : ValueResult.VALID;
}
@Override
public ValueType getValueType ()
{
return cellType == CellType.VALUE ? value.getValueType () : ValueType.NUMBER;
}
@Override
public double getDouble ()
{
return cellType == CellType.VALUE ? value.getDouble () : 0;
}
@Override
public boolean getBoolean ()
{
return cellType == CellType.VALUE ? value.getBoolean () : false;
}
@Override
public String getFullText ()
{
switch (cellType)
{
case LABEL:
text.append (String.format ("| LABEL : %-69s |%n", label));
break;
return label;
case REPEATING_CHARACTER:
text.append (String.format ("| REPEAT : %-69s |%n", repeatingText));
break;
return repeatingText;
case EMPTY:
text.append (String.format ("| EMPTY : %-69s |%n", ""));
break;
return "Empty Cell";
case VALUE:
text.append (String.format ("| VALUE : %-69s |%n", expressionText));
if (value == null)
text.append (String.format ("| Value : %-69s |%n", "null"));
else
text.append (((AbstractValue) value).getValueText (0));
break;
return value.getFullText ();
default:
text.append ("Unknown CellType: " + cellType + "\n");
return "impossible";
}
text.append (line);
return text.toString ();
}
@Override
public String getType ()
{
return "Cell";
}
@Override
public String getText ()
{
// cell points to another cell which is ERROR or NA
assert cellType == CellType.VALUE;
// assert !value.isValid ();
return value.getText ();
}
Value getValue ()
{
return value;
}
// public String getDebugText ()
// {
// StringBuilder text = new StringBuilder ();
// text.append (line);
// text.append ("\n");
// text.append (String.format ("| %-11s %s Format: %s |%n",
// address.getText (), address.getDetails (), cellFormat));
// text.append (line);
// text.append ("\n");
//
// switch (cellType)
// {
// case LABEL:
// text.append (String.format ("| LABEL : %-69s |%n", label));
// break;
//
// case REPEATING_CHARACTER:
// text.append (String.format ("| REPEAT : %-69s |%n", repeatingText));
// break;
//
// case EMPTY:
// text.append (String.format ("| EMPTY : %-69s |%n", ""));
// break;
//
// case VALUE:
// text.append (String.format ("| VALUE : %-69s |%n", expressionText));
// if (value == null)
// text.append (String.format ("| Value : %-69s |%n", "null"));
// else
// text.append (((AbstractValue) value).getValueText (0));
// break;
//
// default:
// text.append ("Unknown CellType: " + cellType + "\n");
// }
//
// text.append (line);
// return text.toString ();
// }
@Override
public String toString ()
{
@ -316,14 +373,24 @@ class Cell extends AbstractValue implements Comparable<Cell>
case REPEATING_CHARACTER:
contents = "Rept: " + repeatingText;
break;
case VALUE:
contents = "Exp : " + expressionText;
break;
case EMPTY:
contents = "Empty";
break;
case VALUE:
switch (value.getValueType ())
{
case NUMBER:
contents = "Num : " + fullText;
break;
case BOOLEAN:
contents = "Bool: " + fullText;
break;
}
// contents = "Exp : " + expressionText;
break;
}
return String.format ("[Cell:%5s %s]", address, contents);
return String.format ("Cell:%5s %s", address.getText (), contents);
}
@Override

View File

@ -7,35 +7,38 @@ public class Choose extends ValueListFunction
Choose (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@CHOOSE(") : text;
valueType = ValueType.NUMBER;
}
@Override
public void calculate ()
{
Value source = list.get (0);
valueResult = ValueResult.VALID;
source.calculate ();
if (!source.isValueType (ValueType.VALUE))
if (!source.isValid ())
{
valueType = source.getValueType ();
valueResult = source.getValueResult ();
return;
}
int index = (int) source.getValue ();
int index = (int) source.getDouble ();
if (index < 1 || index >= list.size ())
{
valueType = ValueType.NA;
valueResult = ValueResult.NA;
return;
}
Cell cell = (Cell) list.get (index);
if (cell.isCellType (CellType.EMPTY))
valueType = ValueType.NA;
valueResult = ValueResult.NA;
else
{
valueType = cell.getValueType ();
value = cell.getValue ();
valueResult = cell.getValueResult ();
value = cell.getDouble ();
}
}
}

View File

@ -1,23 +1,28 @@
package com.bytezone.diskbrowser.visicalc;
import java.util.Iterator;
import java.util.regex.Pattern;
// Predicate
class Condition extends AbstractValue implements Iterable<Value>
{
private static final Pattern cellAddress = Pattern.compile ("[A-B]?[A-Z][0-9]{1,3}");
private static final String[] comparators = { "<>", "<=", ">=", "=", "<", ">" };
private String comparator;
private String conditionText;
private String valueText;
private final String fullText;
// private Address address;
private Expression conditionExpression;
private Expression valueExpression;
public Condition (Cell cell, String text)
{
super ("Cond");
super (cell, text);
valueType = ValueType.BOOLEAN;
fullText = text;
for (String comp : comparators)
@ -46,58 +51,105 @@ class Condition extends AbstractValue implements Iterable<Value>
conditionExpression = new Expression (cell, text);
values.add (conditionExpression);
comparator = "=";
valueText = "1";
valueExpression = new Expression (cell, valueText);
values.add (valueExpression);
// comparator = "=";
//
// valueText = "1";
// valueExpression = new Expression (cell, valueText);
// values.add (valueExpression);
}
else if (cellAddress.matcher (text).matches ())
{
conditionText = text;
conditionExpression = new Expression (cell, text);
conditionExpression.valueType = ValueType.BOOLEAN;
values.add (conditionExpression);
}
else
System.out.println ("No comparator and not a function");
{
System.out.println ("No comparator and not a function: " + text);
throw new IllegalArgumentException ("No comparator and not a function: " + text);
}
}
}
@Override
public void calculate ()
{
value = 0;
// System.out.printf ("********Calc: %s%n", fullText);
valueResult = ValueResult.VALID;
conditionExpression.calculate ();
valueExpression.calculate ();
if (conditionExpression.isValueType (ValueType.ERROR)
|| valueExpression.isValueType (ValueType.ERROR))
if (!conditionExpression.isValid ())
{
valueResult = conditionExpression.getValueResult ();
return;
}
double conditionResult = conditionExpression.getValue ();
double valueResult = valueExpression.getValue ();
// a boolean won't have a comparator or a valueExpression
if (conditionExpression.getValueType () == ValueType.BOOLEAN)
{
bool = conditionExpression.getBoolean ();
// System.out.printf ("********Bool: %s%n", bool);
return;
}
valueExpression.calculate ();
if (!valueExpression.isValid ())
{
valueResult = valueExpression.getValueResult ();
return;
}
double conditionResult = conditionExpression.getDouble ();
double expressionResult = valueExpression.getDouble ();
if (comparator.equals ("="))
value = conditionResult == valueResult ? 1 : 0;
bool = conditionResult == expressionResult;
else if (comparator.equals ("<>"))
value = conditionResult != valueResult ? 1 : 0;
bool = conditionResult != expressionResult;
else if (comparator.equals ("<"))
value = conditionResult < valueResult ? 1 : 0;
bool = conditionResult < expressionResult;
else if (comparator.equals (">"))
value = conditionResult > valueResult ? 1 : 0;
bool = conditionResult > expressionResult;
else if (comparator.equals ("<="))
value = conditionResult <= valueResult ? 1 : 0;
bool = conditionResult <= expressionResult;
else if (comparator.equals (">="))
value = conditionResult >= valueResult ? 1 : 0;
bool = conditionResult >= expressionResult;
else
System.out.printf ("Unexpected comparator result [%s]%n", comparator);
// System.out.printf ("********Bool: %s%n", bool);
}
String getFullText ()
@Override
public String getFullText ()
{
return fullText;
}
@Override
public String toString ()
public String getType ()
{
return String.format ("[cond=%s, op:%s, value=%s]", conditionText, comparator,
valueText);
return "Condition";
}
static boolean isCondition (String text)
{
int ptr = 0;
int depth = 0;
while (ptr < text.length ())
{
char c = text.charAt (ptr);
if (c == '(')
++depth;
else if (c == ')')
--depth;
else if (depth == 0 && (c == '=' || c == '<' || c == '>'))
return true;
++ptr;
}
return false;
}
@Override
@ -105,4 +157,24 @@ class Condition extends AbstractValue implements Iterable<Value>
{
return values.iterator ();
}
@Override
public String toString ()
{
String line = "+-------------------------------------------------------------+";
StringBuilder text = new StringBuilder ();
text.append (line + "\n");
text.append (String.format ("| %-10.10s: CND : %-34.34s%-8.8s|%n",
cell.getAddressText (), getFullText (), valueType));
text.append (String.format ("| %-10.10s: %-40.40s%-8.8s|%n", "Condition",
conditionText, conditionExpression.getValueType ()));
if (comparator != null)
{
text.append (String.format ("| %-10.10s: %-60.60s|%n", "Comparatr", comparator));
text.append (String.format ("| %-10.10s: %-40.40s%-8.8s|%n", "Value", valueText,
valueExpression.getValueType ()));
}
text.append (line);
return text.toString ();
}
}

View File

@ -4,9 +4,9 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ConditionList implements Iterable<Condition>
public class ConditionList implements Iterable<Value>
{
private final List<Condition> conditions = new ArrayList<Condition> ();
private final List<Value> conditions = new ArrayList<Value> ();
public ConditionList (Cell cell, String text)
{
@ -15,14 +15,22 @@ public class ConditionList implements Iterable<Condition>
while (true)
{
String parameter = Expression.getParameter (remainder);
conditions.add (new Condition (cell, parameter));
if (Range.isRange (parameter))
for (Address address : new Range (cell, parameter))
{
Cell target = cell.getCell (address);
conditions.add (target);
}
else
conditions.add (new Condition (cell, parameter));
if (remainder.length () == parameter.length ())
break;
remainder = remainder.substring (parameter.length () + 1);
}
}
public Condition get (int index)
public Value get (int index)
{
return conditions.get (index);
}
@ -33,7 +41,7 @@ public class ConditionList implements Iterable<Condition>
}
@Override
public Iterator<Condition> iterator ()
public Iterator<Value> iterator ()
{
return conditions.iterator ();
}

View File

@ -0,0 +1,35 @@
package com.bytezone.diskbrowser.visicalc;
public class ConditionListFunction extends Function
{
protected final ConditionList conditions;
ConditionListFunction (Cell cell, String text)
{
super (cell, text);
conditions = new ConditionList (cell, functionText);
valueType = ValueType.BOOLEAN;
}
@Override
public String getType ()
{
return "ConditionListFunction";
}
@Override
public String toString ()
{
String line = "+-------------------------------------------------------------+";
StringBuilder text = new StringBuilder ();
text.append (line + "\n");
text.append (String.format ("| %-10.10s: CFN : %-34.34s%-8.8s|%n",
cell.getAddressText (), getFullText (), valueType));
for (Value value : conditions)
text.append (String.format ("| %-10.10s: %-40.40s%-8.8s|%n", "Value",
value.getFullText (), value.getValueType ()));
text.append (line);
return text.toString ();
}
}

View File

@ -6,4 +6,10 @@ public abstract class ConstantFunction extends Function
{
super (cell, text);
}
@Override
public String getType ()
{
return "ConstantFunction";
}
}

View File

@ -11,6 +11,6 @@ public class Cos extends ValueFunction
@Override
public double calculateValue ()
{
return Math.cos (source.getValue ());
return Math.cos (source.getDouble ());
}
}

View File

@ -14,7 +14,7 @@ class Count extends ValueListFunction
public void calculate ()
{
value = 0;
valueType = ValueType.VALUE;
valueType = ValueType.NUMBER;
if (!isRange)
value = list.size ();

View File

@ -7,7 +7,6 @@ class Error extends ConstantFunction
super (cell, text);
assert text.startsWith ("@ERROR") : text;
valueType = ValueType.ERROR;
valueResult = ValueResult.ERROR;
}
}

View File

@ -11,6 +11,6 @@ public class Exp extends ValueFunction
@Override
public double calculateValue ()
{
return Math.exp (source.getValue ());
return Math.exp (source.getDouble ());
}
}

View File

@ -28,20 +28,22 @@ class Expression extends AbstractValue //implements Iterable<Value>
// [.3*(B4+B7+B8+B9)]
// [+N12+(P12*(.2*K12+K9-O12))]
private final Cell cell;
private final List<String> operators = new ArrayList<String> ();
private final List<String> signs = new ArrayList<String> ();
private final String text;
public Expression (Cell cell, String text)
{
super ("Exp");
this.cell = cell;
this.text = text;
super (cell, text);
String line = balanceBrackets (text); // add trailing right brackets if necessary
if (Condition.isCondition (text))
{
values.add (new Condition (cell, text));
signs.add ("(+)"); // reduce() needs this
return;
}
int ptr = 0;
while (ptr < line.length ())
{
@ -85,7 +87,7 @@ class Expression extends AbstractValue //implements Iterable<Value>
{
String numberText = getNumberText (line.substring (ptr));
ptr += numberText.length ();
values.add (new Number (numberText));
values.add (new Number (cell, numberText));
}
else if (ch >= 'A' && ch <= 'Z') // cell address
{
@ -100,7 +102,7 @@ class Expression extends AbstractValue //implements Iterable<Value>
}
}
// check for optional continuation operator
// check for possible continuation operator
if (ptr < line.length ())
{
ch = line.charAt (ptr);
@ -115,13 +117,12 @@ class Expression extends AbstractValue //implements Iterable<Value>
}
assert values.size () > 0;
valueType = values.get (0).getValueType ();
}
Value reduce ()
{
if (values.size () == 1 && signs.get (0).equals ("(+)"))
return values.get (0);
return this;
return values.size () == 1 && signs.get (0).equals ("(+)") ? values.get (0) : this;
}
int size ()
@ -131,48 +132,52 @@ class Expression extends AbstractValue //implements Iterable<Value>
Value get (int index)
{
if (index < 0 || index >= values.size ())
throw new IllegalArgumentException ();
return values.get (index);
}
@Override
public String getType ()
{
return "Expression";
}
@Override
public void calculate ()
{
if (values.size () == 0)
{
System.out.println ("nothing to calculate: " + text);
return;
}
assert values.size () > 0;
try
{
Value thisValue = values.get (0);
thisValue.calculate ();
value = 0;
if (!thisValue.isValueType (ValueType.VALUE))
value = thisValue.getDouble ();
bool = thisValue.getBoolean ();
if (!thisValue.isValid ()) // ERROR / NA
{
valueType = thisValue.getValueType ();
return;
}
value = thisValue.getValue ();
String sign = signs.get (0);
if (sign.equals ("(-)"))
value *= -1;
for (int i = 1; i < values.size (); i++)
for (int i = 1; i < values.size (); i++) // only NUMBER will enter here
{
thisValue = values.get (i);
thisValue.calculate ();
if (!thisValue.isValueType (ValueType.VALUE))
if (!thisValue.isValid ())
{
valueType = thisValue.getValueType ();
return;
}
double nextValue = thisValue.getValue ();
double nextValue = thisValue.getDouble ();
sign = signs.get (i);
if (sign.equals ("(-)"))
@ -189,23 +194,24 @@ class Expression extends AbstractValue //implements Iterable<Value>
{
if (nextValue == 0)
{
valueType = ValueType.ERROR;
valueResult = ValueResult.ERROR;
return;
}
value /= nextValue;
}
else if (operator.equals ("^"))
value = Math.pow (value, nextValue);
}
if (Double.isNaN (value))
valueType = ValueType.ERROR;
else
valueType = ValueType.VALUE;
if (Double.isNaN (value))
{
valueResult = ValueResult.ERROR;
return;
}
}
}
catch (Exception e)
{
valueType = ValueType.ERROR;
valueResult = ValueResult.ERROR;
e.printStackTrace ();
return;
}
@ -338,7 +344,7 @@ class Expression extends AbstractValue //implements Iterable<Value>
{
assert value != null;
text.append (signs.get (ptr));
text.append (value.getValue ());
text.append (value.getDouble ());
if (ptr < operators.size ())
text.append (operators.get (ptr++));
}
@ -349,6 +355,25 @@ class Expression extends AbstractValue //implements Iterable<Value>
@Override
public String toString ()
{
return "Expression : " + text;
String line = "+-------------------------------------------------------------+";
StringBuilder text = new StringBuilder ();
text.append (line + "\n");
text.append (String.format ("| %-10.10s: EXP : %-34.34s%-8.8s|%n",
cell.getAddressText (), getFullText (), valueType));
int index = 0;
for (Value value : values)
{
String sign = signs.get (index);
if (!"(+)".equals (sign))
text.append (String.format ("| %-10.10s: %-40.40s|%n", "sign", sign));
text.append (String.format ("| %-10.10s: %-40.40s%-8.8s|%n", "Value",
value.getFullText (), value.getValueType ()));
if (index < operators.size ())
text.append (
String.format ("| %-10.10s: %-48.48s|%n", "operator", operators.get (index)));
++index;
}
text.append (line);
return text.toString ();
}
}

View File

@ -8,19 +8,7 @@ public class False extends ConstantFunction
assert text.equals ("@FALSE") : text;
value = 0;
valueType = ValueType.VALUE;
}
@Override
public boolean isBoolean ()
{
return true;
}
@Override
public String getText ()
{
return value == 0 ? "FALSE" : "TRUE";
bool = false;
valueType = ValueType.BOOLEAN;
}
}

View File

@ -13,7 +13,7 @@ public class Format
static String format (Value value, char formatChar, int colWidth)
{
double actualValue = value.getValue ();
double actualValue = value.getDouble ();
if (actualValue == -0.0)
actualValue = 0;

View File

@ -8,18 +8,12 @@ abstract class Function extends AbstractValue
"@ISNA(", "@LOG10(", "@LOOKUP(", "@LN(", "@MIN(", "@MAX(", "@NA", "@NPV(", "@OR(",
"@PI", "@SIN(", "@SUM(", "@SQRT(", "@TAN(", "@TRUE" };
protected final Cell cell;
protected final String fullText;
protected final String functionName;
protected final String functionText;
Function (Cell cell, String text)
{
super ("Function");
this.cell = cell;
fullText = text;
super (cell, text);
// get function's parameter string
int pos = text.indexOf ('(');
@ -38,6 +32,12 @@ abstract class Function extends AbstractValue
@Override
public String toString ()
{
return String.format ("Function: %s %s", functionName, functionText);
String line = "+-------------------------------------------------------------+";
StringBuilder text = new StringBuilder ();
text.append (line + "\n");
text.append (String.format ("| %-10.10s: FN : %-34.34s%-8.8s|%n",
cell.getAddressText (), getFullText (), valueType));
text.append (line);
return text.toString ();
}
}

View File

@ -7,8 +7,8 @@ class If extends Function
private final String textFalse;
private final Condition condition;
private final Expression expTrue;
private final Expression expFalse;
private final Value expTrue;
private final Value expFalse;
public If (Cell cell, String text)
{
@ -17,50 +17,79 @@ class If extends Function
assert text.startsWith ("@IF(") : text;
conditionText = Expression.getParameter (functionText);
textTrue =
Expression.getParameter (functionText.substring (conditionText.length () + 1));
textFalse = Expression.getParameter (
functionText.substring (conditionText.length () + textTrue.length () + 2));
int ptr = conditionText.length () + 1;
if (ptr >= functionText.length ())
throw new IllegalArgumentException (text);
textTrue = Expression.getParameter (functionText.substring (ptr));
ptr = conditionText.length () + textTrue.length () + 2;
if (ptr >= functionText.length ())
throw new IllegalArgumentException (text);
textFalse = Expression.getParameter (functionText.substring (ptr));
condition = new Condition (cell, conditionText);
values.add (condition);
expTrue = new Expression (cell, textTrue);
expTrue = new Expression (cell, textTrue).reduce ();
values.add (expTrue);
expFalse = new Expression (cell, textFalse);
expFalse = new Expression (cell, textFalse).reduce ();
values.add (expFalse);
valueType = expTrue.getValueType ();
}
@Override
public void calculate ()
{
valueType = ValueType.VALUE;
valueResult = ValueResult.VALID;
condition.calculate ();
if (condition.getValue () == 1)
if (condition.getBoolean ()) // true
{
expTrue.calculate ();
if (!expTrue.isValueType (ValueType.VALUE))
valueType = expTrue.getValueType ();
if (!expTrue.isValid ())
valueResult = expTrue.getValueResult ();
else
value = expTrue.getValue ();
value = expTrue.getDouble ();
}
else
else // false
{
expFalse.calculate ();
if (!expFalse.isValueType (ValueType.VALUE))
valueType = expFalse.getValueType ();
if (!expFalse.isValid ())
valueResult = expTrue.getValueResult ();
else
value = expFalse.getValue ();
value = expFalse.getDouble ();
}
}
@Override
public String getType ()
{
return "If";
}
@Override
public String toString ()
{
return String.format ("[IF:%s, True:%s, False:%s]", condition, textTrue, textFalse);
String line = "+-------------------------------------------------------------+";
StringBuilder text = new StringBuilder ();
text.append (line + "\n");
text.append (String.format ("| %-10.10s: %-40.40s%-8.8s|%n", cell.getAddressText (),
fullText, valueType));
text.append (String.format ("| condition : %-40.40s%-8.8s|%n", conditionText,
condition.getValueType ()));
text.append (String.format ("| true : %-40.40s%-8.8s|%n", textTrue,
expTrue.getValueType ()));
text.append (String.format ("| false : %-40.40s%-8.8s|%n", textFalse,
expFalse.getValueType ()));
text.append (line);
return text.toString ();
}
}

View File

@ -11,6 +11,6 @@ public class Int extends ValueFunction
@Override
public double calculateValue ()
{
return (int) source.getValue ();
return (int) source.getDouble ();
}
}

View File

@ -1,30 +1,19 @@
package com.bytezone.diskbrowser.visicalc;
class IsError extends ValueFunction
class IsError extends BooleanFunction
{
public IsError (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@ISERROR(") : text;
}
@Override
public boolean isBoolean ()
{
return true;
assert text.startsWith ("@ISERROR(") : text;
valueType = ValueType.BOOLEAN;
}
@Override
public void calculate ()
{
source.calculate ();
value = calculateValue ();
valueType = ValueType.VALUE; // do not use source.getValueType()
}
@Override
public double calculateValue ()
{
return source.isValueType (ValueType.ERROR) ? 1 : 0;
bool = source.getValueResult () == ValueResult.ERROR;
}
}

View File

@ -1,30 +1,19 @@
package com.bytezone.diskbrowser.visicalc;
public class IsNa extends ValueFunction
public class IsNa extends BooleanFunction
{
IsNa (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@ISNA(") : text;
}
@Override
public boolean isBoolean ()
{
return true;
assert text.startsWith ("@ISNA(") : text;
valueType = ValueType.BOOLEAN;
}
@Override
public void calculate ()
{
source.calculate ();
value = calculateValue ();
valueType = ValueType.VALUE; // do not use source.getValueType()
}
@Override
public double calculateValue ()
{
return source.isValueType (ValueType.NA) ? 1 : 0;
bool = source.getValueResult () == ValueResult.NA;
}
}

View File

@ -11,6 +11,6 @@ public class Ln extends ValueFunction
@Override
public double calculateValue ()
{
return Math.log (source.getValue ());
return Math.log (source.getDouble ());
}
}

View File

@ -11,6 +11,6 @@ public class Log10 extends ValueFunction
@Override
public double calculateValue ()
{
return Math.log10 (source.getValue ());
return Math.log10 (source.getDouble ());
}
}

View File

@ -5,28 +5,32 @@ class Lookup extends ValueListFunction
public Lookup (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@LOOKUP(") : text;
valueType = ValueType.NUMBER;
}
@Override
public void calculate ()
{
Value source = list.get (0); // first Value is the value to look up
valueResult = ValueResult.VALID;
source.calculate ();
if (!source.isValueType (ValueType.VALUE))
if (!source.isValid ())
{
valueType = source.getValueType ();
valueResult = source.getValueResult ();
return;
}
if (list.size () <= 1)
{
valueType = ValueType.NA;
valueResult = ValueResult.NA;
return;
}
double sourceValue = source.getValue ();
double sourceValue = source.getDouble ();
Address target = null;
// is the range horizontal or vertical?
@ -37,14 +41,14 @@ class Lookup extends ValueListFunction
for (int i = 1; i < list.size (); i++) // skip first entry
{
Cell cell = (Cell) list.get (i);
if (cell.getValue () > sourceValue) // past the value
if (cell.getDouble () > sourceValue) // past the value
break;
target = cell.getAddress (); // this could be the one
}
if (target == null)
{
valueType = ValueType.NA;
valueResult = ValueResult.NA;
return;
}
@ -52,13 +56,11 @@ class Lookup extends ValueListFunction
if (cell.cellExists (adjacentAddress))
{
value = cell.getCell (adjacentAddress).getValue ();
valueType = ValueType.VALUE;
value = cell.getCell (adjacentAddress).getDouble ();
}
else
{
value = 0;
valueType = ValueType.VALUE;
}
}
}

View File

@ -5,7 +5,9 @@ class Max extends ValueListFunction
public Max (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@MAX(") : text;
valueType = ValueType.NUMBER;
}
@Override
@ -13,20 +15,22 @@ class Max extends ValueListFunction
{
value = Double.MIN_VALUE;
int totalChecked = 0;
valueResult = ValueResult.VALID;
for (Value v : list)
{
v.calculate ();
if (!v.isValueType (ValueType.VALUE))
if (!v.isValid ())
{
valueType = cell.getValueType ();
valueResult = cell.getValueResult ();
return;
}
value = Math.max (value, v.getValue ());
value = Math.max (value, v.getDouble ());
totalChecked++;
}
valueType = totalChecked == 0 ? ValueType.NA : ValueType.VALUE;
if (totalChecked == 0)
valueResult = ValueResult.NA;
}
}

View File

@ -5,7 +5,9 @@ class Min extends ValueListFunction
public Min (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@MIN(") : text;
valueType = ValueType.NUMBER;
}
@Override
@ -13,20 +15,22 @@ class Min extends ValueListFunction
{
value = Double.MAX_VALUE;
int totalChecked = 0;
valueResult = ValueResult.VALID;
for (Value v : list)
{
v.calculate ();
if (!v.isValueType (ValueType.VALUE))
if (!v.isValid ())
{
valueType = cell.getValueType ();
valueResult = cell.getValueResult ();
return;
}
value = Math.min (value, v.getValue ());
value = Math.min (value, v.getDouble ());
totalChecked++;
}
valueType = totalChecked == 0 ? ValueType.NA : ValueType.VALUE;
if (totalChecked == 0)
valueResult = ValueResult.NA;
}
}

View File

@ -7,7 +7,6 @@ public class Na extends ConstantFunction
super (cell, text);
assert text.equals ("@NA") : text;
valueType = ValueType.NA;
valueResult = ValueResult.NA;
}
}

View File

@ -7,24 +7,27 @@ public class Npv extends ValueListFunction
Npv (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@NPV(") : text;
valueType = ValueType.NUMBER;
}
@Override
public void calculate ()
{
value = 0;
valueType = ValueType.VALUE;
valueResult = ValueResult.VALID;
Value source = list.get (0); // first Value is the rate
source.calculate ();
if (!source.isValueType (ValueType.VALUE))
if (!source.isValid ())
{
valueType = source.getValueType ();
valueResult = source.getValueResult ();
return;
}
double rate = 1 + source.getValue ();
double rate = 1 + source.getDouble ();
int period = 0;
for (int i = 1; i < list.size (); i++) // remaining Values are Cells
@ -35,13 +38,13 @@ public class Npv extends ValueListFunction
if (cell.isCellType (CellType.EMPTY))
continue;
if (!cell.isValueType (ValueType.VALUE))
if (!cell.isValid ())
{
valueType = cell.getValueType ();
valueResult = source.getValueResult ();
return;
}
value += cell.getValue () / Math.pow (rate, period);
value += cell.getDouble () / Math.pow (rate, period);
}
}
}

View File

@ -2,17 +2,19 @@ package com.bytezone.diskbrowser.visicalc;
class Number extends AbstractValue
{
public Number (String text)
public Number (Cell cell, String text)
{
super ("Constant");
super (cell, text);
try
{
valueType = ValueType.NUMBER;
valueResult = ValueResult.VALID;
value = Double.parseDouble (text);
}
catch (NumberFormatException e)
{
valueType = ValueType.ERROR;
valueResult = ValueResult.ERROR;
e.printStackTrace ();
}
}
@ -23,9 +25,22 @@ class Number extends AbstractValue
return value + "";
}
@Override
public String getType ()
{
return "Constant";
}
@Override
public String toString ()
{
return String.format ("Number: %f", value);
// return String.format ("Number: %f", value);
String line = "+-------------------------------------------------------------+";
StringBuilder text = new StringBuilder ();
text.append (line + "\n");
text.append (String.format ("| %-10.10s: NUM : %-34.34s%-8.8s|%n",
cell.getAddressText (), getFullText (), valueType));
text.append (line);
return text.toString ();
}
}

View File

@ -1,42 +1,25 @@
package com.bytezone.diskbrowser.visicalc;
class Or extends Function
class Or extends ConditionListFunction
{
private final ConditionList conditions;
public Or (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@OR(") : text;
conditions = new ConditionList (cell, functionText);
}
@Override
public void calculate ()
{
for (Condition condition : conditions)
for (Value condition : conditions)
{
condition.calculate ();
if (condition.getValue () == 1)
if (condition.getBoolean ())
{
value = 1;
bool = true;
return;
}
}
value = 0;
}
@Override
public boolean isBoolean ()
{
return true;
}
@Override
public String getText ()
{
return value == 0 ? "FALSE" : "TRUE";
bool = false;
}
}

View File

@ -9,6 +9,6 @@ class Pi extends ConstantFunction
assert text.equals ("@PI") : text;
value = Math.PI;
valueType = ValueType.VALUE;
valueType = ValueType.NUMBER;
}
}

View File

@ -160,6 +160,8 @@ public class Sheet
assert !line.isEmpty ();
lines.add (line);
System.out.println (line);
if (line.startsWith ("/"))
doFormat (line);
else if (line.startsWith (">")) // GOTO cell
@ -172,7 +174,12 @@ public class Sheet
// might have to keep recalculating until nothing changes??
calculate (recalculationOrder);
// calculate (recalculationOrder);
if (false)
{
for (Cell cell : rowOrderCells.values ())
cell.reset ();
calculate (recalculationOrder);
}
}
private void calculate (char order)
@ -466,7 +473,15 @@ public class Sheet
+ " ***\n\n");
last = cell.getAddress ().getColumn ();
}
text.append (cell.getDebugText ());
// text.append (cell.getDebugText ());
// text.append (cell);
// text.append ("\n");
if (cell.isCellType (CellType.VALUE))
{
text.append (cell.getValue ());
text.append ("\n");
}
text.append ("\n");
}

View File

@ -11,6 +11,6 @@ public class Sin extends ValueFunction
@Override
public double calculateValue ()
{
return Math.sin (source.getValue ());
return Math.sin (source.getDouble ());
}
}

View File

@ -11,6 +11,6 @@ public class Sqrt extends ValueFunction
@Override
public double calculateValue ()
{
return Math.sqrt (source.getValue ());
return Math.sqrt (source.getDouble ());
}
}

View File

@ -5,29 +5,31 @@ class Sum extends ValueListFunction
public Sum (Cell cell, String text)
{
super (cell, text);
assert text.startsWith ("@SUM(") : text;
valueType = ValueType.NUMBER;
}
@Override
public void calculate ()
{
value = 0;
valueType = ValueType.VALUE;
valueResult = ValueResult.VALID;
for (Value v : list)
{
v.calculate ();
if (v.isValueType (ValueType.NA))
if (v.getValueResult () == ValueResult.NA)
continue;
if (!v.isValueType (ValueType.VALUE))
if (!v.isValid ())
{
valueType = v.getValueType ();
break;
valueResult = v.getValueResult ();
return;
}
value += v.getValue ();
value += v.getDouble ();
}
}
}

View File

@ -11,6 +11,6 @@ public class Tan extends ValueFunction
@Override
public double calculateValue ()
{
return Math.tan (source.getValue ());
return Math.tan (source.getDouble ());
}
}

View File

@ -8,19 +8,7 @@ public class True extends ConstantFunction
assert text.equals ("@TRUE") : text;
value = 1;
valueType = ValueType.VALUE;
}
@Override
public boolean isBoolean ()
{
return true;
}
@Override
public String getText ()
{
return value == 0 ? "FALSE" : "TRUE";
bool = true;
valueType = ValueType.BOOLEAN;
}
}

View File

@ -4,20 +4,29 @@ interface Value
{
enum ValueType
{
VALUE, ERROR, NA
NUMBER, BOOLEAN
}
public boolean isValueType (ValueType valueType);
public ValueType getValueType ();
public double getValue (); // if ValueType == VALUE
public String getText (); // if ValueType != VALUE
enum ValueResult
{
ERROR, NA, VALID
}
public void calculate ();
public String getTypeText (); // Number/Function/Expression etc
public boolean isValid (); // ValueResult.VALID
public boolean isBoolean (); // display TRUE/FALSE instead of 1/0
public ValueType getValueType (); // NUMBER, BOOLEAN
public ValueResult getValueResult (); // ERROR, NA, VALID
public double getDouble (); // if ValueType == NUMBER
public String getText (); // if ValueType == ERROR / NA / BOOLEAN
public boolean getBoolean (); // if ValueType == BOOLEAN
public String getFullText (); // original text
public String getType (); // FUNCTION, CONDITION, EXPRESSION
}

View File

@ -10,22 +10,33 @@ public abstract class ValueFunction extends Function
source = cell.getExpressionValue (functionText);
values.add (source);
// is valueType NUMBER?
}
@Override
public void calculate ()
{
valueResult = ValueResult.VALID;
source.calculate ();
if (!source.isValueType (ValueType.VALUE))
if (!source.isValid ())
{
valueType = source.getValueType ();
valueResult = source.getValueResult ();
return;
}
value = calculateValue ();
valueType = Double.isNaN (value) ? ValueType.ERROR : ValueType.VALUE;
if (Double.isNaN (value))
valueResult = ValueResult.ERROR;
}
abstract double calculateValue ();
@Override
public String getType ()
{
return "ValueFunction";
}
}

View File

@ -15,4 +15,10 @@ public abstract class ValueListFunction extends Function
for (Value v : list)
values.add (v);
}
@Override
public String getType ()
{
return "ValueListFunction";
}
}