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
{
private final Range range;
// private final Range range;
private final ExpressionList list;
public Average (Sheet parent, Cell cell, String 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
@ -17,20 +19,21 @@ public class Average extends Function
double total = 0.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;
if (!cell.isValueType (ValueType.VALUE))
if (!v.isValueType (ValueType.VALUE))
{
valueType = cell.getValueType ();
valueType = v.getValueType ();
return;
}
total += cell.getValue ();
total += v.getValue ();
totalChecked++;
}

View File

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

View File

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

View File

@ -2,13 +2,15 @@ package com.bytezone.diskbrowser.visicalc;
class Count extends Function
{
private final Range range;
private final ExpressionList list;
private final boolean isRange;
public Count (Sheet parent, Cell cell, String text)
{
super (parent, cell, text);
range = new Range (parent, text);
list = new ExpressionList (parent, cell, functionText);
isRange = functionText.indexOf ("...") > 0;
}
@Override
@ -17,20 +19,23 @@ class Count extends Function
value = 0;
valueType = ValueType.VALUE;
for (Address address : range)
{
Cell cell = parent.getCell (address);
if (cell.isValueType (ValueType.NA))
continue;
if (!cell.isValueType (ValueType.VALUE))
if (!isRange)
value = list.size ();
else
for (Value v : list)
{
valueType = cell.getValueType ();
return;
}
v.calculate ();
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;
import java.util.ArrayList;
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;
List<Expression> expressions = new ArrayList<Expression> ();
private static final Pattern cellAddress = Pattern.compile ("[A-B]?[A-Z][0-9]{1,3}");
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;
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
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);
rangeText = text.substring (pos + 1, text.length () - 1);
range = new Range (parent, rangeText);
range = new Range (parent, cell, rangeText);
values.add (source);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -363,7 +363,7 @@ public class Sheet
if (columnWidths.containsKey (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');
if (width == 1)

View File

@ -2,13 +2,13 @@ package com.bytezone.diskbrowser.visicalc;
class Sum extends Function
{
private final Range range;
private final ExpressionList list;
public Sum (Sheet parent, Cell cell, String text)
{
super (parent, cell, text);
range = new Range (parent, text);
list = new ExpressionList (parent, cell, functionText);
}
@Override
@ -17,20 +17,20 @@ class Sum extends Function
value = 0;
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;
if (!cell.isValueType (ValueType.VALUE))
if (!v.isValueType (ValueType.VALUE))
{
valueType = cell.getValueType ();
valueType = v.getValueType ();
break;
}
value += cell.getValue ();
value += v.getValue ();
}
}
}