ExpressionList

This commit is contained in:
Denis Molony 2017-03-15 11:41:45 +11:00
parent 920d29e52f
commit cad2106c71
12 changed files with 196 additions and 143 deletions

View File

@ -2,13 +2,15 @@ package com.bytezone.diskbrowser.visicalc;
public class Average extends Function public class Average extends Function
{ {
private final Range range; // private final Range range;
private final ExpressionList list;
public Average (Sheet parent, Cell cell, String text) public Average (Sheet parent, Cell cell, String text)
{ {
super (parent, cell, text); super (parent, cell, text);
range = new Range (parent, text); // range = new Range (parent, cell, text); // use list instead
list = new ExpressionList (parent, cell, functionText);
} }
@Override @Override
@ -17,20 +19,21 @@ public class Average extends Function
double total = 0.0; double total = 0.0;
int totalChecked = 0; int totalChecked = 0;
for (Address address : range) for (Value v : list)
{ {
Cell cell = parent.getCell (address); v.calculate ();
// Cell cell = parent.getCell (address);
if (cell.isValueType (ValueType.NA)) if (v.isValueType (ValueType.NA))
continue; continue;
if (!cell.isValueType (ValueType.VALUE)) if (!v.isValueType (ValueType.VALUE))
{ {
valueType = cell.getValueType (); valueType = v.getValueType ();
return; return;
} }
total += cell.getValue (); total += v.getValue ();
totalChecked++; totalChecked++;
} }

View File

@ -165,7 +165,6 @@ class Cell extends AbstractValue implements Comparable<Cell>
switch (cellType) switch (cellType)
{ {
case LABEL: case LABEL:
// if (fmtChar == ' ' || fmtChar == 'I' || fmtChar == '$')
if (fmtChar != 'R') if (fmtChar != 'R')
fmtChar = 'L'; fmtChar = 'L';
return Format.justify (label, colWidth, fmtChar); return Format.justify (label, colWidth, fmtChar);
@ -201,8 +200,10 @@ class Cell extends AbstractValue implements Comparable<Cell>
@Override @Override
public ValueType getValueType () public ValueType getValueType ()
{ {
if (cellType == CellType.EMPTY || cellType == CellType.LABEL if (cellType == CellType.EMPTY)
|| cellType == CellType.REPEATING_CHARACTER) return ValueType.NA;
if (cellType == CellType.LABEL || cellType == CellType.REPEATING_CHARACTER)
return ValueType.VALUE; return ValueType.VALUE;
return value.getValueType (); return value.getValueType ();

View File

@ -15,7 +15,7 @@ public class Choose extends Function
sourceText = text.substring (8, pos); sourceText = text.substring (8, pos);
source = new Number (sourceText); source = new Number (sourceText);
rangeText = text.substring (pos + 1, text.length () - 1); rangeText = text.substring (pos + 1, text.length () - 1);
range = new Range (parent, rangeText); range = new Range (parent, cell, rangeText);
values.add (source); values.add (source);
} }

View File

@ -2,13 +2,15 @@ package com.bytezone.diskbrowser.visicalc;
class Count extends Function class Count extends Function
{ {
private final Range range; private final ExpressionList list;
private final boolean isRange;
public Count (Sheet parent, Cell cell, String text) public Count (Sheet parent, Cell cell, String text)
{ {
super (parent, cell, text); super (parent, cell, text);
range = new Range (parent, text); list = new ExpressionList (parent, cell, functionText);
isRange = functionText.indexOf ("...") > 0;
} }
@Override @Override
@ -17,20 +19,23 @@ class Count extends Function
value = 0; value = 0;
valueType = ValueType.VALUE; valueType = ValueType.VALUE;
for (Address address : range) if (!isRange)
{ value = list.size ();
Cell cell = parent.getCell (address); else
for (Value v : list)
if (cell.isValueType (ValueType.NA))
continue;
if (!cell.isValueType (ValueType.VALUE))
{ {
valueType = cell.getValueType (); v.calculate ();
return;
}
value++; if (v instanceof Cell && v.isValueType (ValueType.NA))
} continue;
if (!v.isValueType (ValueType.VALUE))
{
valueType = v.getValueType ();
return;
}
value++;
}
} }
} }

View File

@ -1,22 +1,55 @@
package com.bytezone.diskbrowser.visicalc; package com.bytezone.diskbrowser.visicalc;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.regex.Pattern;
public class ExpressionList implements Iterable<Expression> public class ExpressionList extends AbstractValue implements Iterable<Value>
{ {
private final Sheet parent; private static final Pattern cellAddress = Pattern.compile ("[A-B]?[A-Z][0-9]{1,3}");
List<Expression> expressions = new ArrayList<Expression> (); private static final Pattern addressList = Pattern.compile ("\\(([^,]+(,[^,]+)*)\\)");
public ExpressionList (Sheet parent, String rangeText) private final Sheet parent;
// private final List<Expression> expressions = new ArrayList<Expression> ();
public ExpressionList (Sheet parent, Cell cell, String text)
{ {
super ("expL");
this.parent = parent; this.parent = parent;
int pos = text.indexOf ("...");
if (pos > 0)
{
String fromAddress = text.substring (0, pos);
String toAddress = text.substring (pos + 3);
Address from = new Address (fromAddress);
Address to = new Address (toAddress);
Range range = new Range (parent, from, to);
for (Address address : range)
values.add (parent.getCell (address));
return;
}
String[] chunks = text.split (",");
for (String s : chunks)
{
// System.out.println (s);
Value v = new Expression (parent, cell, s).reduce ();
// expressions.add (expression);
values.add (v);
}
}
public int size ()
{
return values.size ();
} }
@Override @Override
public Iterator<Expression> iterator () public Iterator<Value> iterator ()
{ {
return expressions.iterator (); return values.iterator ();
} }
} }

View File

@ -17,7 +17,7 @@ class Lookup extends Function
source = new Expression (parent, cell, sourceText); source = new Expression (parent, cell, sourceText);
rangeText = text.substring (pos + 1, text.length () - 1); rangeText = text.substring (pos + 1, text.length () - 1);
range = new Range (parent, rangeText); range = new Range (parent, cell, rangeText);
values.add (source); values.add (source);
} }

View File

@ -2,13 +2,13 @@ package com.bytezone.diskbrowser.visicalc;
class Max extends Function class Max extends Function
{ {
private final Range range; private final ExpressionList list;
public Max (Sheet parent, Cell cell, String text) public Max (Sheet parent, Cell cell, String text)
{ {
super (parent, cell, text); super (parent, cell, text);
range = new Range (parent, text); list = new ExpressionList (parent, cell, functionText);
} }
@Override @Override
@ -17,19 +17,16 @@ class Max extends Function
value = Double.MIN_VALUE; value = Double.MIN_VALUE;
int totalChecked = 0; int totalChecked = 0;
for (Address address : range) for (Value v : list)
{ {
Cell cell = parent.getCell (address); v.calculate ();
if (cell.isValueType (ValueType.NA)) if (!v.isValueType (ValueType.VALUE))
continue;
if (!cell.isValueType (ValueType.VALUE))
{ {
valueType = cell.getValueType (); valueType = cell.getValueType ();
break; break;
} }
double temp = cell.getValue (); double temp = v.getValue ();
if (temp > value) if (temp > value)
value = temp; value = temp;
totalChecked++; totalChecked++;

View File

@ -2,14 +2,14 @@ package com.bytezone.diskbrowser.visicalc;
class Min extends Function class Min extends Function
{ {
private final Range range; private final ExpressionList list;
public Min (Sheet parent, Cell cell, String text) public Min (Sheet parent, Cell cell, String text)
{ {
super (parent, cell, text); super (parent, cell, text);
System.out.println (text); System.out.println (text);
range = new Range (parent, text); list = new ExpressionList (parent, cell, functionText);
} }
@Override @Override
@ -18,19 +18,16 @@ class Min extends Function
value = Double.MAX_VALUE; value = Double.MAX_VALUE;
int totalChecked = 0; int totalChecked = 0;
for (Address address : range) for (Value v : list)
{ {
Cell cell = parent.getCell (address); v.calculate ();
if (cell.isValueType (ValueType.NA)) if (!v.isValueType (ValueType.VALUE))
continue;
if (!cell.isValueType (ValueType.VALUE))
{ {
valueType = cell.getValueType (); valueType = cell.getValueType ();
break; break;
} }
double temp = cell.getValue (); double temp = v.getValue ();
if (temp < value) if (temp < value)
value = temp; value = temp;
totalChecked++; totalChecked++;

View File

@ -17,7 +17,7 @@ public class Npv extends Function
rangeText = text.substring (pos + 1, text.length () - 1); rangeText = text.substring (pos + 1, text.length () - 1);
rateExp = new Expression (parent, cell, valueText); rateExp = new Expression (parent, cell, valueText);
range = new Range (parent, rangeText); range = new Range (parent, cell, rangeText);
values.add (rateExp); values.add (rateExp);
} }

View File

@ -18,44 +18,49 @@ class Range implements Iterable<Address>
private final List<Address> range = new ArrayList<Address> (); private final List<Address> range = new ArrayList<Address> ();
private final Sheet parent; private final Sheet parent;
public Range (Sheet parent, String rangeText) private boolean isHorizontal;
public Range (Sheet parent, Cell cell, String rangeText)
{ {
this.parent = parent; this.parent = parent;
setRange (rangeText);
createCells (); Matcher m = rangePattern.matcher (rangeText);
if (m.find ())
{
from = new Address (m.group (1), m.group (2));
to = new Address (m.group (3), m.group (4));
isHorizontal = from.rowMatches (to);
populateRange ();
}
else
throw new IllegalArgumentException ();
} }
public Range (Sheet parent, Address from, Address to) public Range (Sheet parent, Address from, Address to)
{ {
this.parent = parent;
this.from = from; this.from = from;
this.to = to; this.to = to;
this.parent = parent;
addRange (); isHorizontal = from.rowMatches (to);
populateRange ();
createCells ();
} }
public Range (Sheet parent, String[] cells) // public Range (Sheet parent, String[] cells)
{ // {
this.parent = parent; // this.parent = parent;
//
// for (String s : cells)
// range.add (new Address (s));
//
// createCells ();
// }
for (String s : cells) private void populateRange ()
range.add (new Address (s));
createCells ();
}
private void createCells ()
{
for (Address address : range)
parent.getCell (address);
}
private void addRange ()
{ {
range.add (from); range.add (from);
parent.getCell (from);
Address tempFrom = from; Address tempFrom = from;
if (from.rowMatches (to)) if (from.rowMatches (to))
@ -63,31 +68,43 @@ class Range implements Iterable<Address>
{ {
from = from.nextColumn (); from = from.nextColumn ();
range.add (from); range.add (from);
parent.getCell (from);
} }
else if (from.columnMatches (to)) else if (from.columnMatches (to))
while (from.compareTo (to) < 0) while (from.compareTo (to) < 0)
{ {
from = from.nextRow (); from = from.nextRow ();
range.add (from); range.add (from);
parent.getCell (from);
} }
else else
throw new InvalidParameterException (); throw new InvalidParameterException ();
from = tempFrom; from = tempFrom;
// createCells ();
} }
// private void createCells ()
// {
// for (Address address : range)
// parent.getCell (address); // ensure that the cell exists
// }
boolean isHorizontal () boolean isHorizontal ()
{ {
Address first = range.get (0); // Address first = range.get (0);
Address last = range.get (range.size () - 1); // Address last = range.get (range.size () - 1);
return first.rowMatches (last); // return first.rowMatches (last);
return isHorizontal;
} }
boolean isVertical () boolean isVertical ()
{ {
Address first = range.get (0); // Address first = range.get (0);
Address last = range.get (range.size () - 1); // Address last = range.get (range.size () - 1);
return first.columnMatches (last); // return first.columnMatches (last);
return !isHorizontal;
} }
@Override @Override
@ -98,59 +115,59 @@ class Range implements Iterable<Address>
public int size () public int size ()
{ {
int total = 0; // int total = 0;
//
// for (Address address : range)
// if (parent.getCell (address) != null)
// ++total;
for (Address address : range) return range.size ();
if (parent.getCell (address) != null)
++total;
return total;
} }
private void setRange (String text) // private void setRange (String text)
{ // {
Matcher m = rangePattern.matcher (text); // Matcher m = rangePattern.matcher (text);
if (m.find ()) // if (m.find ())
{ // {
from = new Address (m.group (1), m.group (2)); // from = new Address (m.group (1), m.group (2));
to = new Address (m.group (3), m.group (4)); // to = new Address (m.group (3), m.group (4));
addRange (); // populateRange ();
return; // return;
} // }
//
m = addressList.matcher (text); // // m = addressList.matcher (text);
if (m.find ()) // // if (m.find ())
{ // // {
System.out.printf ("Address list: %s%n", text); // // System.out.printf ("Address list: %s%n", text);
String[] cells = m.group (1).split (","); // // String[] cells = m.group (1).split (",");
for (String s : cells) // // for (String s : cells)
{ // // {
System.out.println (s); // // System.out.println (s);
if (cellAddress.matcher (s).matches ()) // // if (cellAddress.matcher (s).matches ())
range.add (new Address (s)); // // range.add (new Address (s));
else // // else
{ // // {
System.out.println ("Not a cell address: " + s); // // System.out.println ("Not a cell address: " + s);
} // // }
} // // }
// //
System.out.println (); // // System.out.println ();
return; // // return;
} // // }
//
int pos = text.indexOf ("..."); // int pos = text.indexOf ("...");
if (pos > 0) // if (pos > 0)
{ // {
String fromAddress = text.substring (0, pos); // String fromAddress = text.substring (0, pos);
String toAddress = text.substring (pos + 3); // String toAddress = text.substring (pos + 3);
from = new Address (fromAddress); // from = new Address (fromAddress);
to = new Address (toAddress); // to = new Address (toAddress);
addRange (); // populateRange ();
return; // return;
} // }
//
System.out.printf ("null range [%s]%n", text); // System.out.printf ("null range [%s]%n", text);
} // }
@Override @Override
public String toString () public String toString ()

View File

@ -363,7 +363,7 @@ public class Sheet
if (columnWidths.containsKey (column)) if (columnWidths.containsKey (column))
width = columnWidths.get (column); width = columnWidths.get (column);
char letter1 = column < 26 ? ' ' : column < 52 ? 'A' : 'B'; char letter1 = column < 26 ? '-' : column < 52 ? 'A' : 'B';
char letter2 = (char) ((column % 26) + 'A'); char letter2 = (char) ((column % 26) + 'A');
if (width == 1) if (width == 1)

View File

@ -2,13 +2,13 @@ package com.bytezone.diskbrowser.visicalc;
class Sum extends Function class Sum extends Function
{ {
private final Range range; private final ExpressionList list;
public Sum (Sheet parent, Cell cell, String text) public Sum (Sheet parent, Cell cell, String text)
{ {
super (parent, cell, text); super (parent, cell, text);
range = new Range (parent, text); list = new ExpressionList (parent, cell, functionText);
} }
@Override @Override
@ -17,20 +17,20 @@ class Sum extends Function
value = 0; value = 0;
valueType = ValueType.VALUE; valueType = ValueType.VALUE;
for (Address address : range) for (Value v : list)
{ {
Cell cell = parent.getCell (address); v.calculate ();
if (cell.isValueType (ValueType.NA)) if (v.isValueType (ValueType.NA))
continue; continue;
if (!cell.isValueType (ValueType.VALUE)) if (!v.isValueType (ValueType.VALUE))
{ {
valueType = cell.getValueType (); valueType = v.getValueType ();
break; break;
} }
value += cell.getValue (); value += v.getValue ();
} }
} }
} }