mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-06-26 17:29:50 +00:00
expanded Value interface
This commit is contained in:
parent
ba5ba04ddc
commit
9db35ede39
|
@ -2,19 +2,17 @@ package com.bytezone.diskbrowser.visicalc;
|
||||||
|
|
||||||
class Cell implements Comparable<Cell>, Value
|
class Cell implements Comparable<Cell>, Value
|
||||||
{
|
{
|
||||||
// private static final Pattern cellContents =
|
|
||||||
// Pattern.compile ("([-+/*]?)(([A-Z]{1,2}[0-9]{1,3})|([0-9.]+)|(@[^-+/*]+))");
|
|
||||||
|
|
||||||
final Address address;
|
final Address address;
|
||||||
private final Sheet parent;
|
private final Sheet parent;
|
||||||
|
|
||||||
private String label;
|
|
||||||
private char format = ' ';
|
private char format = ' ';
|
||||||
private char repeatingChar;
|
private char repeatingChar;
|
||||||
private String repeat = "";
|
private String repeat = "";
|
||||||
|
|
||||||
|
private String label;
|
||||||
private String expressionText;
|
private String expressionText;
|
||||||
private Expression expression;
|
private Value value;
|
||||||
|
// private boolean hasValue;
|
||||||
|
|
||||||
public Cell (Sheet parent, Address address)
|
public Cell (Sheet parent, Address address)
|
||||||
{
|
{
|
||||||
|
@ -44,7 +42,7 @@ class Cell implements Comparable<Cell>, Value
|
||||||
System.out.printf ("Unexpected format [%s]%n", format);
|
System.out.printf ("Unexpected format [%s]%n", format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void doCommand (String command)
|
void setValue (String command)
|
||||||
{
|
{
|
||||||
switch (command.charAt (0))
|
switch (command.charAt (0))
|
||||||
{
|
{
|
||||||
|
@ -92,12 +90,6 @@ class Cell implements Comparable<Cell>, Value
|
||||||
expressionText = "11.9";
|
expressionText = "11.9";
|
||||||
else if (address.sortValue == 579)
|
else if (address.sortValue == 579)
|
||||||
expressionText = "D9*G5/(1-((1+G5)^-D4))";
|
expressionText = "D9*G5/(1-((1+G5)^-D4))";
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hasValue ()
|
|
||||||
{
|
|
||||||
return expressionText != null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char getFormat ()
|
char getFormat ()
|
||||||
|
@ -105,6 +97,7 @@ class Cell implements Comparable<Cell>, Value
|
||||||
return format;
|
return format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this should be called by Sheet when drawing, so do all formatting here
|
||||||
String getText ()
|
String getText ()
|
||||||
{
|
{
|
||||||
if (label != null)
|
if (label != null)
|
||||||
|
@ -114,20 +107,44 @@ class Cell implements Comparable<Cell>, Value
|
||||||
return "?";
|
return "?";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasValue ()
|
||||||
|
{
|
||||||
|
if (label != null || repeatingChar > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (value == null)
|
||||||
|
createValue ();
|
||||||
|
return value.hasValue ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// this should be called when doing calculations
|
||||||
@Override
|
@Override
|
||||||
public double getValue ()
|
public double getValue ()
|
||||||
{
|
{
|
||||||
if (expression == null)
|
if (value == null)
|
||||||
|
createValue ();
|
||||||
|
return value.getValue ();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getError ()
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
createValue ();
|
||||||
|
return hasValue () ? "" : "@NA";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createValue ()
|
||||||
|
{
|
||||||
|
if (expressionText == null)
|
||||||
{
|
{
|
||||||
if (expressionText == null)
|
System.out.printf ("%s null expression text %n", address);
|
||||||
{
|
value = Function.getInstance (parent, "@ERROR()");
|
||||||
System.out.printf ("%s null expression text %n", address);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// System.out.printf ("%s Instantiating [%s]%n", address, expressionText);
|
|
||||||
expression = new Expression (parent, expressionText);
|
|
||||||
}
|
}
|
||||||
return expression.getValue ();
|
else
|
||||||
|
// System.out.printf ("%s Instantiating [%s]%n", address, expressionText);
|
||||||
|
value = new Expression (parent, expressionText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -10,9 +10,8 @@ public class Expression implements Value
|
||||||
// cell address
|
// cell address
|
||||||
// function
|
// function
|
||||||
// expression [+-*/^] expression
|
// expression [+-*/^] expression
|
||||||
// [+-=] expression
|
// [+-] expression
|
||||||
// ( expression )
|
// ( expression )
|
||||||
// -expression
|
|
||||||
|
|
||||||
// From the reference card:
|
// From the reference card:
|
||||||
// Expressions are evaluated strictly from left to right except as modified by
|
// Expressions are evaluated strictly from left to right except as modified by
|
||||||
|
@ -33,34 +32,18 @@ public class Expression implements Value
|
||||||
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 boolean hasValue;
|
||||||
|
|
||||||
public Expression (Sheet parent, String input)
|
public Expression (Sheet parent, String input)
|
||||||
{
|
{
|
||||||
String line = input.trim ();
|
|
||||||
|
|
||||||
// System.out.printf ("New expression [%s]%n", input);
|
|
||||||
|
|
||||||
int leftBracket = 0;
|
|
||||||
int rightBracket = 0;
|
|
||||||
|
|
||||||
for (char c : input.toCharArray ())
|
|
||||||
if (c == '(')
|
|
||||||
leftBracket++;
|
|
||||||
else if (c == ')')
|
|
||||||
rightBracket++;
|
|
||||||
|
|
||||||
if (leftBracket != rightBracket)
|
|
||||||
{
|
|
||||||
System.out.printf ("**** Unbalanced brackets: left:%d, right:%d ****%n",
|
|
||||||
leftBracket, rightBracket);
|
|
||||||
line = "@ERROR()";
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.out.printf ("Exp [%s]%n", line);
|
// System.out.printf ("Exp [%s]%n", line);
|
||||||
|
String line = checkBrackets (input);
|
||||||
|
|
||||||
int ptr = 0;
|
int ptr = 0;
|
||||||
while (ptr < line.length ())
|
while (ptr < line.length ())
|
||||||
{
|
{
|
||||||
|
// check for optional leading + or -
|
||||||
char ch = line.charAt (ptr);
|
char ch = line.charAt (ptr);
|
||||||
|
|
||||||
if (ch == '-')
|
if (ch == '-')
|
||||||
{
|
{
|
||||||
signs.add ("(-)");
|
signs.add ("(-)");
|
||||||
|
@ -73,6 +56,7 @@ public class Expression implements Value
|
||||||
ch = line.charAt (++ptr);
|
ch = line.charAt (++ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for mandatory function/sub-expression/number/cell reference
|
||||||
switch (ch)
|
switch (ch)
|
||||||
{
|
{
|
||||||
case '@': // function
|
case '@': // function
|
||||||
|
@ -84,12 +68,13 @@ public class Expression implements Value
|
||||||
case '(': // parentheses block
|
case '(': // parentheses block
|
||||||
String bracketText = getFunctionText (line.substring (ptr));
|
String bracketText = getFunctionText (line.substring (ptr));
|
||||||
ptr += bracketText.length ();
|
ptr += bracketText.length ();
|
||||||
bracketText = bracketText.substring (1, bracketText.length () - 1);
|
values.add (new Expression (parent,
|
||||||
values.add (new Expression (parent, bracketText));
|
bracketText.substring (1, bracketText.length () - 1)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '#':
|
case '#':
|
||||||
System.out.printf ("Hash character [%s] in [%s]%n", ch, line);
|
System.out.printf ("Hash character [%s] in [%s]%n", ch, line);
|
||||||
|
ptr++; // no idea
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -97,21 +82,22 @@ public class Expression implements Value
|
||||||
{
|
{
|
||||||
String numberText = getNumberText (line.substring (ptr));
|
String numberText = getNumberText (line.substring (ptr));
|
||||||
ptr += numberText.length ();
|
ptr += numberText.length ();
|
||||||
values.add (new Number (Double.parseDouble (numberText)));
|
values.add (new Number (numberText));
|
||||||
}
|
}
|
||||||
else if (ch >= 'A' && ch <= 'Z') // cell address
|
else if (ch >= 'A' && ch <= 'Z') // cell address
|
||||||
{
|
{
|
||||||
String addressText = getAddressText (line.substring (ptr));
|
String addressText = getAddressText (line.substring (ptr));
|
||||||
ptr += addressText.length ();
|
ptr += addressText.length ();
|
||||||
values.add (parent.getCell (new Address (addressText)));
|
values.add (parent.getCell (addressText));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
System.out.printf ("Unknown character [%s] in [%s]%n", ch, line);
|
System.out.printf ("Unexpected character [%s] in [%s]%n", ch, line);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for optional continuation operator
|
||||||
if (ptr < line.length ())
|
if (ptr < line.length ())
|
||||||
{
|
{
|
||||||
ch = line.charAt (ptr);
|
ch = line.charAt (ptr);
|
||||||
|
@ -126,6 +112,7 @@ public class Expression implements Value
|
||||||
}
|
}
|
||||||
|
|
||||||
assert values.size () > 0;
|
assert values.size () > 0;
|
||||||
|
hasValue = true;
|
||||||
|
|
||||||
if (false)
|
if (false)
|
||||||
{
|
{
|
||||||
|
@ -177,12 +164,47 @@ public class Expression implements Value
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasValue ()
|
||||||
|
{
|
||||||
|
return hasValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getError ()
|
||||||
|
{
|
||||||
|
return hasValue ? "" : "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String checkBrackets (String input)
|
||||||
|
{
|
||||||
|
String line = input.trim ();
|
||||||
|
|
||||||
|
int leftBracket = 0;
|
||||||
|
int rightBracket = 0;
|
||||||
|
|
||||||
|
for (char c : line.toCharArray ())
|
||||||
|
if (c == '(')
|
||||||
|
leftBracket++;
|
||||||
|
else if (c == ')')
|
||||||
|
rightBracket++;
|
||||||
|
|
||||||
|
if (leftBracket != rightBracket)
|
||||||
|
{
|
||||||
|
System.out.printf ("**** Unbalanced brackets: left:%d, right:%d ****%n",
|
||||||
|
leftBracket, rightBracket);
|
||||||
|
return "@ERROR()";
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
private String getFunctionText (String text)
|
private String getFunctionText (String text)
|
||||||
{
|
{
|
||||||
int ptr = text.indexOf ('('); // find first left parenthesis
|
int ptr = text.indexOf ('('); // find first left parenthesis
|
||||||
if (ptr < 0)
|
if (ptr < 0)
|
||||||
return "";
|
return "";
|
||||||
int depth = 1;
|
int depth = 1;
|
||||||
|
|
||||||
while (++ptr < text.length ()) // find matching right parenthesis
|
while (++ptr < text.length ()) // find matching right parenthesis
|
||||||
{
|
{
|
||||||
if (text.charAt (ptr) == ')')
|
if (text.charAt (ptr) == ')')
|
||||||
|
|
|
@ -32,6 +32,7 @@ abstract class Function implements Value
|
||||||
|
|
||||||
Sheet parent;
|
Sheet parent;
|
||||||
String functionText;
|
String functionText;
|
||||||
|
boolean hasValue;
|
||||||
|
|
||||||
static Function getInstance (Sheet parent, String text)
|
static Function getInstance (Sheet parent, String text)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +79,18 @@ abstract class Function implements Value
|
||||||
this.functionText = text.substring (pos + 1, text.length () - 1);
|
this.functionText = text.substring (pos + 1, text.length () - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasValue ()
|
||||||
|
{
|
||||||
|
return hasValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getError ()
|
||||||
|
{
|
||||||
|
return hasValue ? "" : "Error";
|
||||||
|
}
|
||||||
|
|
||||||
protected Range getRange (String text)
|
protected Range getRange (String text)
|
||||||
{
|
{
|
||||||
Range range = null;
|
Range range = null;
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
package com.bytezone.diskbrowser.visicalc;
|
package com.bytezone.diskbrowser.visicalc;
|
||||||
|
|
||||||
public class Number implements Value
|
class Number implements Value
|
||||||
{
|
{
|
||||||
private final double value;
|
private double value;
|
||||||
|
private boolean hasValue;
|
||||||
|
|
||||||
public Number (double value)
|
public Number (String text)
|
||||||
{
|
{
|
||||||
this.value = value;
|
try
|
||||||
|
{
|
||||||
|
this.value = Double.parseDouble (text);
|
||||||
|
hasValue = true;
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e)
|
||||||
|
{
|
||||||
|
hasValue = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -20,4 +29,16 @@ public class Number implements Value
|
||||||
{
|
{
|
||||||
return String.format ("Number: %f", value);
|
return String.format ("Number: %f", value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasValue ()
|
||||||
|
{
|
||||||
|
return hasValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getError ()
|
||||||
|
{
|
||||||
|
return hasValue ? "" : "@NA";
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -309,18 +309,21 @@ public class Sheet implements Iterable<Cell>
|
||||||
if (!command.isEmpty ())
|
if (!command.isEmpty ())
|
||||||
currentCell.format (command); // formatting command
|
currentCell.format (command); // formatting command
|
||||||
if (!line.isEmpty ())
|
if (!line.isEmpty ())
|
||||||
currentCell.doCommand (line); // expression
|
currentCell.setValue (line); // expression
|
||||||
|
}
|
||||||
|
|
||||||
|
Cell getCell (String addressText)
|
||||||
|
{
|
||||||
|
Address address = new Address (addressText);
|
||||||
|
return getCell (address);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cell getCell (Address address)
|
Cell getCell (Address address)
|
||||||
{
|
{
|
||||||
Cell cell = sheet.get (address.sortValue);
|
Cell cell = sheet.get (address.sortValue);
|
||||||
if (cell == null)
|
if (cell == null)
|
||||||
{
|
|
||||||
// cell = new Cell (this, address);
|
|
||||||
// sheet.put (address.sortValue, cell);
|
|
||||||
System.out.printf ("Nonexistent cell requested [%s]%n", address);
|
System.out.printf ("Nonexistent cell requested [%s]%n", address);
|
||||||
}
|
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,5 +2,9 @@ package com.bytezone.diskbrowser.visicalc;
|
||||||
|
|
||||||
public interface Value
|
public interface Value
|
||||||
{
|
{
|
||||||
|
public boolean hasValue ();
|
||||||
|
|
||||||
public double getValue ();
|
public double getValue ();
|
||||||
|
|
||||||
|
public String getError ();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user