import java.util.HashMap;
import fit.*;
public class Spreadsheet extends ColumnFixture {
public String address;
public HashMap cells = new HashMap();
// Actor Handlers ///////////////////////////
public void address(String s) {address = s;}
public void cell(String s) {cells.put(address,s);}
public String display() {trace=""; return eval(address);}
public String formula() {return (String)cells.get(address);}
// Column Handlers //////////////////////////
public String a1;
public String a2;
public String a3;
public String a4;
public String a5;
public String b1;
public String c1;
public String d1;
public String e1;
public void reset() {
a1=a2=a3=b1=c1=d1=e1=null;
}
public void execute() {
if (a1!=null) {address("A1"); cell(a1);}
if (a2!=null) {address("A2"); cell(a2);}
if (a3!=null) {address("A3"); cell(a3);}
if (a4!=null) {address("A4"); cell(a4);}
if (a5!=null) {address("A5"); cell(a5);}
if (b1!=null) {address("B1"); cell(b1);}
if (c1!=null) {address("C1"); cell(c1);}
if (d1!=null) {address("D1"); cell(d1);}
if (e1!=null) {address("E1"); cell(e1);}
}
public String a1() {address("A1"); return display();}
public String a2() {address("A2"); return display();}
public String a3() {address("A3"); return display();}
public String a4() {address("A4"); return display();}
public String a5() {address("A5"); return display();}
public String b1() {address("B1"); return display();}
public String c1() {address("C1"); return display();}
public String d1() {address("D1"); return display();}
public String e1() {address("E1"); return display();}
public String a1Formula() {address("A1"); return formula();}
public String b1Formula() {address("B1"); return formula();}
public String comment;
public String Comment;
public static void main(String[] args) {
fit.FileRunner.main(new String[]
{"wake-spreadsheet.html", "wake-spreadsheet-output.html"});
}
public String eval(String start) {
trace("eval "+start);
if (trace.length()>500) {
throw new Error("Loop "+start);
}
String contents =(String)cells.get(start);
if (contents==null) {
//throw new Error("Unbound "+start);
return "#error";
} else if (contents.startsWith("=")) {
return calculate(contents.substring(1));
} else {
return contents;
}
}
public String calculate(String formula){
trace("calculate "+formula);
if (formula.length()==0) {
throw new Error("Empty formula");
} else if (formula.startsWith("(")&&formula.endsWith(")")) {
return calculate(formula.substring(1,formula.length()-1));
} else if (op(formula, "+")) {
String save = right; // save global
return calculate(left)+calculate(save);
} else if (formula.endsWith("’")) {
String operand = formula.substring(0,formula.length()-1);
return reverse(calculate(operand));
} else {
return eval(formula);
}
}
public String left, right;
public boolean op (String formula, String op) {
int i = formula.indexOf(op);
if (i<0) {
return false;
} else {
left = formula.substring(0,i);
right = formula.substring(i+op.length());
return true;
}
}
public String reverse(String s) {
int l = s.length();
if (l<2) {
return s;
} else {
String left = s.substring(0,1);
String middle = s.substring(1,l-1);
String right = s.substring(l-1);
return right+reverse(middle)+left;
}
}
// Trace ////////////////////////////////////
public static String trace = "";
public void trace(String s) {
trace+="
"+escape(s);
}
public void wrong(Parse c, String s){
super.wrong(c, s);
c.addToBody("
"+trace);
}
public void exception(Parse c, Throwable e){
super.exception(c,e);
c.addToBody(trace);
}
}