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

View File

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

View File

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

View File

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

View File

@ -1,23 +1,28 @@
package com.bytezone.diskbrowser.visicalc; package com.bytezone.diskbrowser.visicalc;
import java.util.Iterator; import java.util.Iterator;
import java.util.regex.Pattern;
// Predicate // Predicate
class Condition extends AbstractValue implements Iterable<Value> 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 static final String[] comparators = { "<>", "<=", ">=", "=", "<", ">" };
private String comparator; private String comparator;
private String conditionText; private String conditionText;
private String valueText; private String valueText;
private final String fullText; private final String fullText;
// private Address address;
private Expression conditionExpression; private Expression conditionExpression;
private Expression valueExpression; private Expression valueExpression;
public Condition (Cell cell, String text) public Condition (Cell cell, String text)
{ {
super ("Cond"); super (cell, text);
valueType = ValueType.BOOLEAN;
fullText = text; fullText = text;
for (String comp : comparators) for (String comp : comparators)
@ -46,58 +51,105 @@ class Condition extends AbstractValue implements Iterable<Value>
conditionExpression = new Expression (cell, text); conditionExpression = new Expression (cell, text);
values.add (conditionExpression); values.add (conditionExpression);
comparator = "="; // comparator = "=";
//
valueText = "1"; // valueText = "1";
valueExpression = new Expression (cell, valueText); // valueExpression = new Expression (cell, valueText);
values.add (valueExpression); // values.add (valueExpression);
}
else if (cellAddress.matcher (text).matches ())
{
conditionText = text;
conditionExpression = new Expression (cell, text);
conditionExpression.valueType = ValueType.BOOLEAN;
values.add (conditionExpression);
} }
else 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 @Override
public void calculate () public void calculate ()
{ {
value = 0; // System.out.printf ("********Calc: %s%n", fullText);
valueResult = ValueResult.VALID;
conditionExpression.calculate (); conditionExpression.calculate ();
valueExpression.calculate (); if (!conditionExpression.isValid ())
{
if (conditionExpression.isValueType (ValueType.ERROR) valueResult = conditionExpression.getValueResult ();
|| valueExpression.isValueType (ValueType.ERROR))
return; return;
double conditionResult = conditionExpression.getValue ();
double valueResult = valueExpression.getValue ();
if (comparator.equals ("="))
value = conditionResult == valueResult ? 1 : 0;
else if (comparator.equals ("<>"))
value = conditionResult != valueResult ? 1 : 0;
else if (comparator.equals ("<"))
value = conditionResult < valueResult ? 1 : 0;
else if (comparator.equals (">"))
value = conditionResult > valueResult ? 1 : 0;
else if (comparator.equals ("<="))
value = conditionResult <= valueResult ? 1 : 0;
else if (comparator.equals (">="))
value = conditionResult >= valueResult ? 1 : 0;
else
System.out.printf ("Unexpected comparator result [%s]%n", comparator);
} }
String getFullText () // 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 ("="))
bool = conditionResult == expressionResult;
else if (comparator.equals ("<>"))
bool = conditionResult != expressionResult;
else if (comparator.equals ("<"))
bool = conditionResult < expressionResult;
else if (comparator.equals (">"))
bool = conditionResult > expressionResult;
else if (comparator.equals ("<="))
bool = conditionResult <= expressionResult;
else if (comparator.equals (">="))
bool = conditionResult >= expressionResult;
else
System.out.printf ("Unexpected comparator result [%s]%n", comparator);
// System.out.printf ("********Bool: %s%n", bool);
}
@Override
public String getFullText ()
{ {
return fullText; return fullText;
} }
@Override @Override
public String toString () public String getType ()
{ {
return String.format ("[cond=%s, op:%s, value=%s]", conditionText, comparator, return "Condition";
valueText); }
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 @Override
@ -105,4 +157,24 @@ class Condition extends AbstractValue implements Iterable<Value>
{ {
return values.iterator (); 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.Iterator;
import java.util.List; 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) public ConditionList (Cell cell, String text)
{ {
@ -15,14 +15,22 @@ public class ConditionList implements Iterable<Condition>
while (true) while (true)
{ {
String parameter = Expression.getParameter (remainder); String parameter = Expression.getParameter (remainder);
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)); conditions.add (new Condition (cell, parameter));
if (remainder.length () == parameter.length ()) if (remainder.length () == parameter.length ())
break; break;
remainder = remainder.substring (parameter.length () + 1); remainder = remainder.substring (parameter.length () + 1);
} }
} }
public Condition get (int index) public Value get (int index)
{ {
return conditions.get (index); return conditions.get (index);
} }
@ -33,7 +41,7 @@ public class ConditionList implements Iterable<Condition>
} }
@Override @Override
public Iterator<Condition> iterator () public Iterator<Value> iterator ()
{ {
return conditions.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); super (cell, text);
} }
@Override
public String getType ()
{
return "ConstantFunction";
}
} }

View File

@ -11,6 +11,6 @@ public class Cos extends ValueFunction
@Override @Override
public double calculateValue () 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 () public void calculate ()
{ {
value = 0; value = 0;
valueType = ValueType.VALUE; valueType = ValueType.NUMBER;
if (!isRange) if (!isRange)
value = list.size (); value = list.size ();

View File

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

View File

@ -11,6 +11,6 @@ public class Exp extends ValueFunction
@Override @Override
public double calculateValue () 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)] // [.3*(B4+B7+B8+B9)]
// [+N12+(P12*(.2*K12+K9-O12))] // [+N12+(P12*(.2*K12+K9-O12))]
private final Cell cell;
private final List<String> operators = new ArrayList<String> (); private final List<String> operators = new ArrayList<String> ();
private final List<String> signs = new ArrayList<String> (); private final List<String> signs = new ArrayList<String> ();
private final String text;
public Expression (Cell cell, String text) public Expression (Cell cell, String text)
{ {
super ("Exp"); super (cell, text);
this.cell = cell;
this.text = text;
String line = balanceBrackets (text); // add trailing right brackets if necessary 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; int ptr = 0;
while (ptr < line.length ()) while (ptr < line.length ())
{ {
@ -85,7 +87,7 @@ class Expression extends AbstractValue //implements Iterable<Value>
{ {
String numberText = getNumberText (line.substring (ptr)); String numberText = getNumberText (line.substring (ptr));
ptr += numberText.length (); ptr += numberText.length ();
values.add (new Number (numberText)); values.add (new Number (cell, numberText));
} }
else if (ch >= 'A' && ch <= 'Z') // cell address 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 ()) if (ptr < line.length ())
{ {
ch = line.charAt (ptr); ch = line.charAt (ptr);
@ -115,13 +117,12 @@ class Expression extends AbstractValue //implements Iterable<Value>
} }
assert values.size () > 0; assert values.size () > 0;
valueType = values.get (0).getValueType ();
} }
Value reduce () Value reduce ()
{ {
if (values.size () == 1 && signs.get (0).equals ("(+)")) return values.size () == 1 && signs.get (0).equals ("(+)") ? values.get (0) : this;
return values.get (0);
return this;
} }
int size () int size ()
@ -131,48 +132,52 @@ class Expression extends AbstractValue //implements Iterable<Value>
Value get (int index) Value get (int index)
{ {
if (index < 0 || index >= values.size ())
throw new IllegalArgumentException ();
return values.get (index); return values.get (index);
} }
@Override
public String getType ()
{
return "Expression";
}
@Override @Override
public void calculate () public void calculate ()
{ {
if (values.size () == 0) assert values.size () > 0;
{
System.out.println ("nothing to calculate: " + text);
return;
}
try try
{ {
Value thisValue = values.get (0); Value thisValue = values.get (0);
thisValue.calculate (); thisValue.calculate ();
value = 0; value = thisValue.getDouble ();
if (!thisValue.isValueType (ValueType.VALUE)) bool = thisValue.getBoolean ();
if (!thisValue.isValid ()) // ERROR / NA
{ {
valueType = thisValue.getValueType (); valueType = thisValue.getValueType ();
return; return;
} }
value = thisValue.getValue ();
String sign = signs.get (0); String sign = signs.get (0);
if (sign.equals ("(-)")) if (sign.equals ("(-)"))
value *= -1; 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 = values.get (i);
thisValue.calculate (); thisValue.calculate ();
if (!thisValue.isValueType (ValueType.VALUE)) if (!thisValue.isValid ())
{ {
valueType = thisValue.getValueType (); valueType = thisValue.getValueType ();
return; return;
} }
double nextValue = thisValue.getValue (); double nextValue = thisValue.getDouble ();
sign = signs.get (i); sign = signs.get (i);
if (sign.equals ("(-)")) if (sign.equals ("(-)"))
@ -189,23 +194,24 @@ class Expression extends AbstractValue //implements Iterable<Value>
{ {
if (nextValue == 0) if (nextValue == 0)
{ {
valueType = ValueType.ERROR; valueResult = ValueResult.ERROR;
return; return;
} }
value /= nextValue; value /= nextValue;
} }
else if (operator.equals ("^")) else if (operator.equals ("^"))
value = Math.pow (value, nextValue); value = Math.pow (value, nextValue);
}
if (Double.isNaN (value)) if (Double.isNaN (value))
valueType = ValueType.ERROR; {
else valueResult = ValueResult.ERROR;
valueType = ValueType.VALUE; return;
}
}
} }
catch (Exception e) catch (Exception e)
{ {
valueType = ValueType.ERROR; valueResult = ValueResult.ERROR;
e.printStackTrace (); e.printStackTrace ();
return; return;
} }
@ -338,7 +344,7 @@ class Expression extends AbstractValue //implements Iterable<Value>
{ {
assert value != null; assert value != null;
text.append (signs.get (ptr)); text.append (signs.get (ptr));
text.append (value.getValue ()); text.append (value.getDouble ());
if (ptr < operators.size ()) if (ptr < operators.size ())
text.append (operators.get (ptr++)); text.append (operators.get (ptr++));
} }
@ -349,6 +355,25 @@ class Expression extends AbstractValue //implements Iterable<Value>
@Override @Override
public String toString () 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; assert text.equals ("@FALSE") : text;
value = 0; bool = false;
valueType = ValueType.VALUE; valueType = ValueType.BOOLEAN;
}
@Override
public boolean isBoolean ()
{
return true;
}
@Override
public String getText ()
{
return value == 0 ? "FALSE" : "TRUE";
} }
} }

View File

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

View File

@ -8,18 +8,12 @@ abstract class Function extends AbstractValue
"@ISNA(", "@LOG10(", "@LOOKUP(", "@LN(", "@MIN(", "@MAX(", "@NA", "@NPV(", "@OR(", "@ISNA(", "@LOG10(", "@LOOKUP(", "@LN(", "@MIN(", "@MAX(", "@NA", "@NPV(", "@OR(",
"@PI", "@SIN(", "@SUM(", "@SQRT(", "@TAN(", "@TRUE" }; "@PI", "@SIN(", "@SUM(", "@SQRT(", "@TAN(", "@TRUE" };
protected final Cell cell;
protected final String fullText;
protected final String functionName; protected final String functionName;
protected final String functionText; protected final String functionText;
Function (Cell cell, String text) Function (Cell cell, String text)
{ {
super ("Function"); super (cell, text);
this.cell = cell;
fullText = text;
// get function's parameter string // get function's parameter string
int pos = text.indexOf ('('); int pos = text.indexOf ('(');
@ -38,6 +32,12 @@ abstract class Function extends AbstractValue
@Override @Override
public String toString () 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 String textFalse;
private final Condition condition; private final Condition condition;
private final Expression expTrue; private final Value expTrue;
private final Expression expFalse; private final Value expFalse;
public If (Cell cell, String text) public If (Cell cell, String text)
{ {
@ -17,50 +17,79 @@ class If extends Function
assert text.startsWith ("@IF(") : text; assert text.startsWith ("@IF(") : text;
conditionText = Expression.getParameter (functionText); conditionText = Expression.getParameter (functionText);
textTrue =
Expression.getParameter (functionText.substring (conditionText.length () + 1)); int ptr = conditionText.length () + 1;
textFalse = Expression.getParameter ( if (ptr >= functionText.length ())
functionText.substring (conditionText.length () + textTrue.length () + 2)); 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); condition = new Condition (cell, conditionText);
values.add (condition); values.add (condition);
expTrue = new Expression (cell, textTrue); expTrue = new Expression (cell, textTrue).reduce ();
values.add (expTrue); values.add (expTrue);
expFalse = new Expression (cell, textFalse); expFalse = new Expression (cell, textFalse).reduce ();
values.add (expFalse); values.add (expFalse);
valueType = expTrue.getValueType ();
} }
@Override @Override
public void calculate () public void calculate ()
{ {
valueType = ValueType.VALUE; valueResult = ValueResult.VALID;
condition.calculate (); condition.calculate ();
if (condition.getValue () == 1) if (condition.getBoolean ()) // true
{ {
expTrue.calculate (); expTrue.calculate ();
if (!expTrue.isValueType (ValueType.VALUE)) if (!expTrue.isValid ())
valueType = expTrue.getValueType (); valueResult = expTrue.getValueResult ();
else else
value = expTrue.getValue (); value = expTrue.getDouble ();
} }
else else // false
{ {
expFalse.calculate (); expFalse.calculate ();
if (!expFalse.isValueType (ValueType.VALUE)) if (!expFalse.isValid ())
valueType = expFalse.getValueType (); valueResult = expTrue.getValueResult ();
else else
value = expFalse.getValue (); value = expFalse.getDouble ();
} }
} }
@Override
public String getType ()
{
return "If";
}
@Override @Override
public String toString () 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 @Override
public double calculateValue () public double calculateValue ()
{ {
return (int) source.getValue (); return (int) source.getDouble ();
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -7,24 +7,27 @@ public class Npv extends ValueListFunction
Npv (Cell cell, String text) Npv (Cell cell, String text)
{ {
super (cell, text); super (cell, text);
assert text.startsWith ("@NPV(") : text; assert text.startsWith ("@NPV(") : text;
valueType = ValueType.NUMBER;
} }
@Override @Override
public void calculate () public void calculate ()
{ {
value = 0; value = 0;
valueType = ValueType.VALUE; valueResult = ValueResult.VALID;
Value source = list.get (0); // first Value is the rate Value source = list.get (0); // first Value is the rate
source.calculate (); source.calculate ();
if (!source.isValueType (ValueType.VALUE))
if (!source.isValid ())
{ {
valueType = source.getValueType (); valueResult = source.getValueResult ();
return; return;
} }
double rate = 1 + source.getValue (); double rate = 1 + source.getDouble ();
int period = 0; int period = 0;
for (int i = 1; i < list.size (); i++) // remaining Values are Cells 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)) if (cell.isCellType (CellType.EMPTY))
continue; continue;
if (!cell.isValueType (ValueType.VALUE)) if (!cell.isValid ())
{ {
valueType = cell.getValueType (); valueResult = source.getValueResult ();
return; 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 class Number extends AbstractValue
{ {
public Number (String text) public Number (Cell cell, String text)
{ {
super ("Constant"); super (cell, text);
try try
{ {
valueType = ValueType.NUMBER;
valueResult = ValueResult.VALID;
value = Double.parseDouble (text); value = Double.parseDouble (text);
} }
catch (NumberFormatException e) catch (NumberFormatException e)
{ {
valueType = ValueType.ERROR; valueResult = ValueResult.ERROR;
e.printStackTrace (); e.printStackTrace ();
} }
} }
@ -23,9 +25,22 @@ class Number extends AbstractValue
return value + ""; return value + "";
} }
@Override
public String getType ()
{
return "Constant";
}
@Override @Override
public String toString () 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; package com.bytezone.diskbrowser.visicalc;
class Or extends Function class Or extends ConditionListFunction
{ {
private final ConditionList conditions;
public Or (Cell cell, String text) public Or (Cell cell, String text)
{ {
super (cell, text); super (cell, text);
assert text.startsWith ("@OR(") : text; assert text.startsWith ("@OR(") : text;
conditions = new ConditionList (cell, functionText);
} }
@Override @Override
public void calculate () public void calculate ()
{ {
for (Condition condition : conditions) for (Value condition : conditions)
{ {
condition.calculate (); condition.calculate ();
if (condition.getValue () == 1) if (condition.getBoolean ())
{ {
value = 1; bool = true;
return; return;
} }
} }
value = 0; bool = false;
}
@Override
public boolean isBoolean ()
{
return true;
}
@Override
public String getText ()
{
return value == 0 ? "FALSE" : "TRUE";
} }
} }

View File

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

View File

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

View File

@ -11,6 +11,6 @@ public class Sin extends ValueFunction
@Override @Override
public double calculateValue () 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 @Override
public double calculateValue () 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) public Sum (Cell cell, String text)
{ {
super (cell, text); super (cell, text);
assert text.startsWith ("@SUM(") : text; assert text.startsWith ("@SUM(") : text;
valueType = ValueType.NUMBER;
} }
@Override @Override
public void calculate () public void calculate ()
{ {
value = 0; value = 0;
valueType = ValueType.VALUE; valueResult = ValueResult.VALID;
for (Value v : list) for (Value v : list)
{ {
v.calculate (); v.calculate ();
if (v.isValueType (ValueType.NA)) if (v.getValueResult () == ValueResult.NA)
continue; continue;
if (!v.isValueType (ValueType.VALUE)) if (!v.isValid ())
{ {
valueType = v.getValueType (); valueResult = v.getValueResult ();
break; return;
} }
value += v.getValue (); value += v.getDouble ();
} }
} }
} }

View File

@ -11,6 +11,6 @@ public class Tan extends ValueFunction
@Override @Override
public double calculateValue () 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; assert text.equals ("@TRUE") : text;
value = 1; bool = true;
valueType = ValueType.VALUE; valueType = ValueType.BOOLEAN;
}
@Override
public boolean isBoolean ()
{
return true;
}
@Override
public String getText ()
{
return value == 0 ? "FALSE" : "TRUE";
} }
} }

View File

@ -4,20 +4,29 @@ interface Value
{ {
enum ValueType enum ValueType
{ {
VALUE, ERROR, NA NUMBER, BOOLEAN
} }
public boolean isValueType (ValueType valueType); enum ValueResult
{
public ValueType getValueType (); ERROR, NA, VALID
}
public double getValue (); // if ValueType == VALUE
public String getText (); // if ValueType != VALUE
public void calculate (); 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); source = cell.getExpressionValue (functionText);
values.add (source); values.add (source);
// is valueType NUMBER?
} }
@Override @Override
public void calculate () public void calculate ()
{ {
valueResult = ValueResult.VALID;
source.calculate (); source.calculate ();
if (!source.isValueType (ValueType.VALUE)) if (!source.isValid ())
{ {
valueType = source.getValueType (); valueResult = source.getValueResult ();
return; return;
} }
value = calculateValue (); value = calculateValue ();
valueType = Double.isNaN (value) ? ValueType.ERROR : ValueType.VALUE;
if (Double.isNaN (value))
valueResult = ValueResult.ERROR;
} }
abstract double calculateValue (); 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) for (Value v : list)
values.add (v); values.add (v);
} }
@Override
public String getType ()
{
return "ValueListFunction";
}
} }