import java.io.*; import java.util.*; import java.awt.Color; import java.text.DecimalFormat; import edu.jsu.leathrum.mathlets.shared.*; public class TParserInputSet extends InputSet { private static StringReader collector = new StringReader("\n"); private static TParser parser = new TParser(collector); boolean dirty = true; boolean errorDetected = false; Node parseReturn = new Node(); public TParserInputSet(String namestr, int size, boolean chbox, Color c) { super(namestr, size, chbox, c); parser.ReInit(collector); } public TParserInputSet(String namestr, int size, boolean chbox) { super(namestr, size, chbox); parser.ReInit(collector); } public TParserInputSet(String namestr, int size) { super(namestr, size); parser.ReInit(collector); } public TParserInputSet(String namestr, int size, Color c) { super(namestr, size, c); parser.ReInit(collector); } private String msgString = ""; public String getMsgString() { return msgString; } private void addToMsgString(String s) { msgString += s; } boolean dapplied = false; private void evaluate(String expr) { StringReader collector = new StringReader(expr+"\n"); parser.ReInit(collector); parseReturn = parser.getTree(); dapplied = false; parseReturn = dsearch(parseReturn); } public Node dsearch(Node n) { if (!dapplied) { try { if (((Integer) n.type).intValue() == TParser.DERIV) return derivator(n.children[0], ((Integer) n.children[1].type).intValue()); else { for (int i=0; i0.0) && (dd<1.0)) { t.addByNode(s.children[1]); t.addByNode(s.children[0]); t.addNodeByType(new Double(Math.abs(dd-1))); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.NEG)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Integer(TParser.MULT)); chain(s.children[0],t,var); } else { t.addByNode(s.children[1]); t.addByNode(s.children[0]); t.addNodeByType(new Double(dd-1)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Integer(TParser.MULT)); chain(s.children[0],t,var); } } } else if ((((Integer) s.children[1].type).intValue() == TParser.NEG) && (((Integer) s.children[1].children[0].type).intValue() == TParser.DBL) ) { dd = ((Double) s.children[1].children[0].children[0].type).doubleValue(); t.addByNode(s.children[1]); t.addByNode(s.children[0]); t.addNodeByType(new Double(dd+1)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.NEG)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Integer(TParser.MULT)); addToMsgString(AMathlet.getProperty("DerivCalc.powerrule") +" "+AMathlet.getProperty("DerivCalc.negexp")); chain(s.children[0],t,var); } else { t.addByNode(s.children[1]); t.addByNode(s.children[0]); t.addByNode(s.children[1]); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.MINUS)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Integer(TParser.MULT)); addToMsgString(AMathlet.getProperty("DerivCalc.powerrule")+" "+AMathlet.getProperty("constexprexp")); if (hasVar(s.children[1])) addToMsgString(" "+AMathlet.getProperty("DerivCalc.othervarsconst")); addToMsgString(")"); chain(s.children[0],t,var); } } else { addToMsgString(AMathlet.getProperty("DerivCalc.logdiff")); t.addByNode(s); t.addByNode(s.children[1]); nomsgchain(s.children[0],t,var); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.DIV)); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.LN)); nomsgchain(s.children[1],t,var); t.addNodeByType(new Integer(TParser.PLUS)); t.addNodeByType(new Integer(TParser.MULT)); } break; case TParser.EXP: t.addByNode(s); addToMsgString(AMathlet.getProperty("DerivCalc.exprule")); chain(s.children[0],t,var); break; case TParser.LN: t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); addToMsgString(AMathlet.getProperty("DerivCalc.logrule")); chain(s.children[0],t,var); if (((Integer) t.getTop().type).intValue() == TParser.MULT) t.addByNode(t.getTop().children[1]); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.DIV)); break; case TParser.LOG: t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); addToMsgString(AMathlet.getProperty("DerivCalc.logrule")+" "+AMathlet.getProperty("DerivCalc.baseten")); chain(s.children[0],t,var); if (((Integer) t.getTop().type).intValue() == TParser.MULT) t.addByNode(t.getTop().children[1]); t.addByNode(s.children[0]); t.addNodeByType(new Double(10.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.LN)); t.addNodeByType(new Integer(TParser.MULT)); t.addNodeByType(new Integer(TParser.DIV)); break; case TParser.SIN: t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.COS)); addToMsgString(AMathlet.getProperty("DerivCalc.sinrule")); chain(s.children[0],t,var); break; case TParser.COS: t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.SIN)); t.addNodeByType(new Integer(TParser.NEG)); addToMsgString(AMathlet.getProperty("DerivCalc.cosrule")); chain(s.children[0],t,var); break; case TParser.TAN: addToMsgString(AMathlet.getProperty("DerivCalc.tanrule")); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.SEC)); t.addNodeByType(new Double(2.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.POW)); chain(s.children[0],t,var); break; case TParser.SEC: addToMsgString(AMathlet.getProperty("DerivCalc.secrule")); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.SEC)); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.TAN)); t.addNodeByType(new Integer(TParser.MULT)); chain(s.children[0],t,var); break; case TParser.CSC: addToMsgString(AMathlet.getProperty("DerivCalc.cscrule")); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.CSC)); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.COT)); t.addNodeByType(new Integer(TParser.MULT)); t.addNodeByType(new Integer(TParser.NEG)); chain(s.children[0],t,var); break; case TParser.COT: addToMsgString(AMathlet.getProperty("DerivCalc.cotrule")); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.CSC)); t.addNodeByType(new Double(2.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Integer(TParser.NEG)); chain(s.children[0],t,var); break; case TParser.ASIN: addToMsgString(AMathlet.getProperty("DerivCalc.asinrule")); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); chain(s.children[0],t,var); if (((Integer) t.getTop().type).intValue() == TParser.MULT) t.addByNode(t.getTop().children[1]); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addByNode(s.children[0]); t.addNodeByType(new Double(2.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Integer(TParser.MINUS)); t.addNodeByType(new Integer(TParser.SQRT)); t.addNodeByType(new Integer(TParser.DIV)); break; case TParser.ACOS: addToMsgString(AMathlet.getProperty("DerivCalc.acosrule")); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); chain(s.children[0],t,var); if (((Integer) t.getTop().type).intValue() == TParser.MULT) t.addByNode(t.getTop().children[1]); t.addNodeByType(new Integer(TParser.NEG)); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addByNode(s.children[0]); t.addNodeByType(new Double(2.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Integer(TParser.MINUS)); t.addNodeByType(new Integer(TParser.SQRT)); t.addNodeByType(new Integer(TParser.DIV)); break; case TParser.ATAN: addToMsgString(AMathlet.getProperty("DerivCalc.atanrule")); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); chain(s.children[0],t,var); if (((Integer) t.getTop().type).intValue() == TParser.MULT) t.addByNode(t.getTop().children[1]); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addByNode(s.children[0]); t.addNodeByType(new Double(2.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Integer(TParser.PLUS)); t.addNodeByType(new Integer(TParser.DIV)); break; case TParser.ASEC: addToMsgString(AMathlet.getProperty("DerivCalc.asecrule")); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); chain(s.children[0],t,var); if (((Integer) t.getTop().type).intValue() == TParser.MULT) t.addByNode(t.getTop().children[1]); t.addByNode(s.children[0]); t.addByNode(s.children[0]); t.addNodeByType(new Double(2.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.POW)); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addNodeByType(new Integer(TParser.MINUS)); t.addNodeByType(new Integer(TParser.SQRT)); t.addNodeByType(new Integer(TParser.MULT)); t.addNodeByType(new Integer(TParser.DIV)); break; case TParser.ABS: addToMsgString(AMathlet.getProperty("DerivCalc.absvalrule")); t.addByNode(s); chain(s.children[0],t,var); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.DIV)); break; case TParser.SQRT: addToMsgString(AMathlet.getProperty("DerivCalc.sqrtaspower")); t.addNodeByType(new Double(1.0)); t.addNodeByType(new Integer(TParser.DBL)); chain(s.children[0],t,var); if (((Integer) t.getTop().type).intValue() == TParser.MULT) t.addByNode(t.getTop().children[1]); t.addNodeByType(new Double(2.0)); t.addNodeByType(new Integer(TParser.DBL)); t.addByNode(s.children[0]); t.addNodeByType(new Integer(TParser.SQRT)); t.addNodeByType(new Integer(TParser.MULT)); t.addNodeByType(new Integer(TParser.DIV)); break; case TParser.DERIV: int tvar = ((Integer) s.children[1].type).intValue(); t.addByNode(derivator(s.children[0],tvar)); t.addNodeByType(new Integer(var)); t.addNodeByType(new Integer(TParser.DERIV)); break; default: t.addNodeByType(new Integer(TParser.ERROR)); break; } dapplied = true; return (Node) t.getTop().clone(); } public String evaluatef() { msgString=""; if (dirty) { String expr = super.getInput(); if (expr.length() == 0) return ""; else evaluate(expr); dirty = false; } String s = evaluateTree((Node) parseReturn.clone()); if (errorDetected) { msgString = ""; return ""; } else return s; } public void setDirty() { dirty = true; errorDetected = false; } }