preparing for new function processing

This commit is contained in:
Denis Molony 2016-03-07 23:16:11 +11:00
parent ed94972388
commit fd1ba9c15f
9 changed files with 275 additions and 184 deletions

View File

@ -14,6 +14,7 @@ class Cell implements Comparable<Cell>
private String label;
private double value;
private String formula;
private char format = ' ';
private int width;
private char repeatingChar;
@ -114,7 +115,12 @@ class Cell implements Comparable<Cell>
System.out.printf ("NFE: %s [%s]%n", m.group (4), formula);
}
else
interim = parent.evaluateFunction (m.group (5)); // function
{
// interim = parent.evaluateFunction (m.group (5)); // function
Function function = Function.getInstance (parent, m.group (5));
if (function != null)
interim = function.getValue ();
}
if (operator == '+')
result += interim;
@ -158,8 +164,9 @@ class Cell implements Comparable<Cell>
? formula == null ? ", Value: " + this.value : ", Formula: " + formula
: ", Label: " + label : ", Rpeat: " + repeatingChar;
String format = this.format == ' ' ? "" : ", Format: " + this.format;
String width = this.width == 0 ? "" : ", Width: " + this.width;
return String.format ("[Cell:%5s%s%s%s]", address, format, width, value);
// String width = this.width == 0 ? "" : ", Width: " + this.width;
// return String.format ("[Cell:%5s%s%s%s]", address, format, width, value);
return String.format ("[Cell:%5s%s%s]", address, format, value);
}
@Override

View File

@ -8,7 +8,7 @@ public class Count extends Function
public Count (Sheet parent, String text)
{
this.parent = parent;
range = parent.getRange (text);
range = getRange (text);
}
@Override

View File

@ -33,11 +33,29 @@ public class Expression
this.parent = parent;
String text = input.trim ();
System.out.printf ("New expression:[%s]%n", input);
char firstChar = text.charAt (0);
if (firstChar == '-')
{
operator = '-';
expression1 = new Expression (parent, text.substring (1));
char secondChar = text.charAt (1);
if ((secondChar >= '0' && secondChar <= '9') || secondChar == '.')
{
String text2 = text.substring (1);
String numberText = getNumberText (text2);
char op = getOperator (numberText, text2);
if (op == ' ')
{
value = Double.parseDouble (numberText) * -1;
hasValue = true;
}
else
expression1 = new Expression (parent, "-" + numberText);
}
else
{
operator = '-';
expression1 = new Expression (parent, text.substring (1));
}
}
else if (firstChar == '=' || firstChar == '+')
{
@ -49,8 +67,6 @@ public class Expression
char op = getOperator (functionText, text);
if (op == ' ')
function = Function.getInstance (parent, functionText);
else if (op != '!')
setExpressions (functionText, op, text);
}
else if (firstChar == '(')
{
@ -59,8 +75,6 @@ public class Expression
if (op == ' ')
expression1 =
new Expression (parent, bracketText.substring (1, bracketText.length () - 2));
else if (op != '!')
setExpressions (bracketText, op, text);
}
else if ((firstChar >= '0' && firstChar <= '9') || firstChar == '.')
{
@ -71,8 +85,6 @@ public class Expression
value = Double.parseDouble (numberText);
hasValue = true;
}
else if (op != '!')
setExpressions (numberText, op, text);
}
else if (firstChar >= 'A' && firstChar <= 'Z')
{
@ -80,18 +92,28 @@ public class Expression
char op = getOperator (addressText, text);
if (op == ' ')
address = new Address (addressText);
else if (op != '!')
setExpressions (addressText, op, text);
}
else
System.out.printf ("Error processing [%s]%n", text);
}
private void setExpressions (String text1, char op, String text2)
private char getOperator (String text1, String text2)
{
expression1 = new Expression (parent, text1);
operator = op;
expression2 = new Expression (parent, text2.substring (text1.length () + 2));
if (text1.length () == text2.length ())
return ' ';
char op = text2.charAt (text1.length ());
if (op == '+' || op == '-' || op == '*' || op == '/' || op == '^')
{
expression1 = new Expression (parent, text1);
operator = op;
expression2 = new Expression (parent, text2.substring (text1.length () + 1));
return op;
}
System.out.println ("error");
// error
return '!';
}
double getValue ()
@ -103,7 +125,13 @@ public class Expression
return function.getValue ();
if (address != null)
return parent.getCell (address).getValue ();
{
Cell cell = parent.getCell (address);
if (cell != null)
return parent.getCell (address).getValue ();
System.out.println ("Error with address");
return 0;
}
if (expression2 == null)
{
@ -174,19 +202,25 @@ public class Expression
return text.substring (0, ptr);
}
private char getOperator (String text1, String text2)
@Override
public String toString ()
{
if (text1.length () == text2.length ())
return ' ';
StringBuilder text = new StringBuilder ();
char c = text2.charAt (text1.length ());
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^')
{
setExpressions (text1, c, text2);
return c;
}
text.append (String.format ("Has value ......... %s%n", hasValue));
text.append (String.format ("Value ............. %f%n", value));
text.append (String.format ("Function .......... %s%n", function));
text.append (String.format ("Address ........... %s%n", address));
text.append (String.format ("Operator .......... %s%n", operator));
text.append (String.format ("Expression1 ....... %s%n", expression1));
text.append (String.format ("Expression2 ....... %s%n", expression2));
// error
return '!';
return text.toString ();
}
public static void main (String[] args)
{
Expression ex = new Expression (null, "-5+12-6");
System.out.println (ex.getValue ());
}
}

View File

@ -1,7 +1,41 @@
package com.bytezone.diskbrowser.visicalc;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// http://www.bricklin.com/history/refcard1.htm
// Functions:
// @AVERAGE
// @NPV
// @LOOKUP(v,range)
// @NA
// @ERROR
// @PI
// @ABS
// @INT
// @EXP
// @SQRT
// @LN
// @LOG10
// @SIN
// @ASIN
// @COS
// @ACOS
// @TAN
// @ATAN
// Unimplemented functions found so far:
// @IF
// @ISERROR
// @OR
// @AND
public abstract class Function
{
private static final Pattern functionPattern = Pattern
.compile ("\\(([A-B]?[A-Z])([0-9]{1,3})\\.\\.\\.([A-B]?[A-Z])([0-9]{1,3})\\)?");
private static final Pattern addressList = Pattern.compile ("\\(([^,]+(,[^,]+)*)\\)");
static Function getInstance (Sheet parent, String text)
{
if (text.startsWith ("@LOOKUP("))
@ -19,8 +53,50 @@ public abstract class Function
if (text.startsWith ("@SUM("))
return new Sum (parent, text);
System.out.printf ("Unknown function: %s%n", text);
return null;
}
abstract double getValue ();
Range getRange (String text)
{
Range range = null;
Matcher m = functionPattern.matcher (text);
while (m.find ())
{
Address fromAddress = new Address (m.group (1), m.group (2));
Address toAddress = new Address (m.group (3), m.group (4));
range = new Range (fromAddress, toAddress);
}
if (range != null)
return range;
m = addressList.matcher (text);
while (m.find ())
{
String[] cells = m.group (1).split (",");
range = new Range (cells);
}
if (range != null)
return range;
int pos = text.indexOf ("...");
if (pos > 0)
{
String from = text.substring (0, pos);
String to = text.substring (pos + 3);
Address fromAddress = new Address (from);
Address toAddress = new Address (to);
range = new Range (fromAddress, toAddress);
}
if (range != null)
return range;
System.out.println ("null range : " + text);
return range;
}
}

View File

@ -29,7 +29,7 @@ public class Lookup extends Function
{
// source could be a formula - @LOOKUP(.2*K8+K7,H3...H16)
source = parent.getCell (new Address (sourceText));
range = parent.getRange (rangeText);
range = getRange (rangeText);
Address target = null;
for (Address address : range)

View File

@ -8,7 +8,7 @@ public class Max extends Function
public Max (Sheet parent, String text)
{
this.parent = parent;
range = parent.getRange (text);
range = getRange (text);
}
@Override

View File

@ -8,7 +8,7 @@ public class Min extends Function
public Min (Sheet parent, String text)
{
this.parent = parent;
range = parent.getRange (text);
range = getRange (text);
}
@Override

View File

@ -11,9 +11,9 @@ public class Sheet implements Iterable<Cell>
{
private static final Pattern addressPattern =
Pattern.compile ("([A-B]?[A-Z])([0-9]{1,3}):");
private static final Pattern functionPattern = Pattern
.compile ("\\(([A-B]?[A-Z])([0-9]{1,3})\\.\\.\\.([A-B]?[A-Z])([0-9]{1,3})\\)?");
private static final Pattern addressList = Pattern.compile ("\\(([^,]+(,[^,]+)*)\\)");
// private static final Pattern functionPattern = Pattern
// .compile ("\\(([A-B]?[A-Z])([0-9]{1,3})\\.\\.\\.([A-B]?[A-Z])([0-9]{1,3})\\)?");
// private static final Pattern addressList = Pattern.compile ("\\(([^,]+(,[^,]+)*)\\)");
private final Map<Integer, Cell> sheet = new TreeMap<Integer, Cell> ();
private final Map<String, Double> functions = new HashMap<String, Double> ();
@ -275,156 +275,130 @@ public class Sheet implements Iterable<Cell>
currentCell.doCommand (command); // formula
}
double evaluateFunction (String function)
{
if (functions.containsKey (function))
return functions.get (function);
// private double evaluateFunction (String function)
// {
// if (functions.containsKey (function))
// return functions.get (function);
//
// // System.out.println (function);
// double result = 0;
//
// if (function.startsWith ("@IF("))
// {
// return result;
// }
//
// if (function.startsWith ("@LOOKUP("))
// {
// return result;
// }
//
// // Range range = getRange (function);
// // if (range == null)
// // return result;
//
// if (function.startsWith ("@SUM("))
// {
// // for (Address address : range)
// // result += getValue (address);
// String text = function.substring (4, function.length () - 1);
// Sum sum = new Sum (this, text);
// result = sum.getValue ();
// }
// else if (function.startsWith ("@COUNT("))
// {
// // int count = 0;
// // for (Address address : range)
// // {
// // VisicalcCell cell = getCell (address);
// // if (cell != null && cell.hasValue () && cell.getValue () != 0.0)
// // ++count;
// // }
// // result = count;
// String text = function.substring (7, function.length () - 1);
// Count count = new Count (this, text);
// result = count.getValue ();
// }
// else if (function.startsWith ("@MIN("))
// {
// // double min = Double.MAX_VALUE;
// // for (Address address : range)
// // if (min > getValue (address))
// // min = getValue (address);
// String text = function.substring (5, function.length () - 1);
// Min min = new Min (this, text);
// result = min.getValue ();
// }
// else if (function.startsWith ("@MAX("))
// {
// // double max = Double.MIN_VALUE;
// // for (Address address : range)
// // if (max < getValue (address))
// // max = getValue (address);
// // result = max;
// String text = function.substring (5, function.length () - 1);
// Max max = new Max (this, text);
// result = max.getValue ();
// }
// else
// System.out.println ("Unimplemented function: " + function);
//
// functions.put (function, result);
// return result;
// }
// System.out.println (function);
double result = 0;
// Range getRange (String text)
// {
// Range range = null;
// Matcher m = functionPattern.matcher (text);
// while (m.find ())
// {
// Address fromAddress = new Address (m.group (1), m.group (2));
// Address toAddress = new Address (m.group (3), m.group (4));
// range = new Range (fromAddress, toAddress);
// }
//
// if (range != null)
// return range;
//
// m = addressList.matcher (text);
// while (m.find ())
// {
// String[] cells = m.group (1).split (",");
// range = new Range (cells);
// }
//
// if (range != null)
// return range;
//
// int pos = text.indexOf ("...");
// if (pos > 0)
// {
// String from = text.substring (0, pos);
// String to = text.substring (pos + 3);
// Address fromAddress = new Address (from);
// Address toAddress = new Address (to);
// range = new Range (fromAddress, toAddress);
// }
//
// if (range != null)
// return range;
// System.out.println ("null range : " + text);
//
// return range;
// }
if (function.startsWith ("@IF("))
{
return result;
}
// private double getValue (Address address)
// {
// Cell cell = sheet.get (address.sortValue);
// return cell == null ? 0.0 : cell.getValue ();
// }
if (function.startsWith ("@LOOKUP("))
{
return result;
}
// Range range = getRange (function);
// if (range == null)
// return result;
if (function.startsWith ("@SUM("))
{
// for (Address address : range)
// result += getValue (address);
String text = function.substring (4, function.length () - 1);
Sum sum = new Sum (this, text);
result = sum.getValue ();
}
else if (function.startsWith ("@COUNT("))
{
// int count = 0;
// for (Address address : range)
// {
// VisicalcCell cell = getCell (address);
// if (cell != null && cell.hasValue () && cell.getValue () != 0.0)
// ++count;
// }
// result = count;
String text = function.substring (7, function.length () - 1);
Count count = new Count (this, text);
result = count.getValue ();
}
else if (function.startsWith ("@MIN("))
{
// double min = Double.MAX_VALUE;
// for (Address address : range)
// if (min > getValue (address))
// min = getValue (address);
String text = function.substring (5, function.length () - 1);
Min min = new Min (this, text);
result = min.getValue ();
}
else if (function.startsWith ("@MAX("))
{
// double max = Double.MIN_VALUE;
// for (Address address : range)
// if (max < getValue (address))
// max = getValue (address);
// result = max;
String text = function.substring (5, function.length () - 1);
Max max = new Max (this, text);
result = max.getValue ();
}
else
System.out.println ("Unimplemented function: " + function);
// http://www.bricklin.com/history/refcard1.htm
// Functions:
// @AVERAGE
// @NPV
// @LOOKUP(v,range)
// @NA
// @ERROR
// @PI
// @ABS
// @INT
// @EXP
// @SQRT
// @LN
// @LOG10
// @SIN
// @ASIN
// @COS
// @ACOS
// @TAN
// @ATAN
// Unimplemented functions found so far:
// @IF
// @ISERROR
// @OR
// @AND
functions.put (function, result);
return result;
}
Range getRange (String text)
{
Range range = null;
Matcher m = functionPattern.matcher (text);
while (m.find ())
{
Address fromAddress = new Address (m.group (1), m.group (2));
Address toAddress = new Address (m.group (3), m.group (4));
range = new Range (fromAddress, toAddress);
}
if (range != null)
return range;
m = addressList.matcher (text);
while (m.find ())
{
String[] cells = m.group (1).split (",");
range = new Range (cells);
}
if (range != null)
return range;
int pos = text.indexOf ("...");
if (pos > 0)
{
String from = text.substring (0, pos);
String to = text.substring (pos + 3);
Address fromAddress = new Address (from);
Address toAddress = new Address (to);
range = new Range (fromAddress, toAddress);
}
if (range != null)
return range;
System.out.println ("null range : " + text);
return range;
}
private double getValue (Address address)
{
Cell cell = sheet.get (address.sortValue);
return cell == null ? 0.0 : cell.getValue ();
}
private double getValue (String cellName)
{
Address address = new Address (cellName);
return getValue (address);
}
// private double getValue (String cellName)
// {
// Address address = new Address (cellName);
// return getValue (address);
// }
Cell getCell (Address address)
{

View File

@ -8,7 +8,7 @@ public class Sum extends Function
public Sum (Sheet parent, String text)
{
this.parent = parent;
range = parent.getRange (text);
range = getRange (text);
}
@Override