Loading src/com/android/calculator2/CalculatorExpr.java +21 −18 Original line number Original line Diff line number Diff line Loading @@ -914,30 +914,24 @@ class CalculatorExpr { final BoundedRational mRatVal; final BoundedRational mRatVal; } } // Return the starting position of the sequence of trailing operators /** // that cannot be meaningfully evaluated. * Return the starting position of the sequence of trailing binary operators. private int trailingOpsStart() { */ private int trailingBinaryOpsStart() { int result = mExpr.size(); int result = mExpr.size(); while (result > 0) { while (result > 0) { Token last = mExpr.get(result - 1); Token last = mExpr.get(result - 1); if (!(last instanceof Operator)) break; if (!(last instanceof Operator)) break; Operator o = (Operator)last; Operator o = (Operator)last; if (KeyMaps.isSuffix(o.mId) || o.mId == R.id.const_pi if (!KeyMaps.isBinary(o.mId)) break; || o.mId == R.id.const_e) { break; } --result; --result; } } return result; return result; } } public boolean hasTrailingOperators() { return trailingOpsStart() != mExpr.size(); } // Is the current expression worth evaluating? // Is the current expression worth evaluating? public boolean hasInterestingOps() { public boolean hasInterestingOps() { int last = trailingOpsStart(); int last = trailingBinaryOpsStart(); int first = 0; int first = 0; if (last > first && isOperatorUnchecked(first, R.id.op_sub)) { if (last > first && isOperatorUnchecked(first, R.id.op_sub)) { // Leading minus is not by itself interesting. // Leading minus is not by itself interesting. Loading @@ -953,16 +947,25 @@ class CalculatorExpr { return false; return false; } } // Evaluate the entire expression, returning null in the event /** // of an error. * Evaluate the expression excluding trailing binary operators. // Not called from the UI thread, but should not be called * Errors result in exceptions, most of which are unchecked. // concurrently with modifications to the expression. * Should not be called concurrently with modification of the expression. EvalResult eval(boolean degreeMode, boolean required) throws SyntaxException * May take a very long time; avoid calling from UI thread. * * @param degreeMode use degrees rather than radians */ EvalResult eval(boolean degreeMode) throws SyntaxException // And unchecked exceptions thrown by CR // And unchecked exceptions thrown by CR // and BoundedRational. // and BoundedRational. { { try { try { int prefixLen = required ? mExpr.size() : trailingOpsStart(); // We currently never include trailing binary operators, but include // other trailing operators. // Thus we usually, but not always, display results for prefixes // of valid expressions, and don't generate an error where we previously // displayed an instant result. This reflects the Android L design. int prefixLen = trailingBinaryOpsStart(); EvalContext ec = new EvalContext(degreeMode, prefixLen); EvalContext ec = new EvalContext(degreeMode, prefixLen); EvalRet res = evalExpr(0, ec); EvalRet res = evalExpr(0, ec); if (res.mPos != prefixLen) { if (res.mPos != prefixLen) { Loading src/com/android/calculator2/Evaluator.java +4 −6 Original line number Original line Diff line number Diff line Loading @@ -382,7 +382,7 @@ class Evaluator { @Override @Override protected InitialResult doInBackground(Void... nothing) { protected InitialResult doInBackground(Void... nothing) { try { try { CalculatorExpr.EvalResult res = mExpr.eval(mDm, mRequired); CalculatorExpr.EvalResult res = mExpr.eval(mDm); int prec = INIT_PREC; int prec = INIT_PREC; String initCache = res.mVal.toString(prec); String initCache = res.mVal.toString(prec); int msd = getMsdPos(initCache); int msd = getMsdPos(initCache); Loading Loading @@ -810,9 +810,8 @@ class Evaluator { // We presume that any prior result was computed using the same // We presume that any prior result was computed using the same // expression. // expression. void requireResult() { void requireResult() { if (mCache == null || mExpr.hasTrailingOperators()) { if (mCache == null) { // Restart evaluator in requested mode, i.e. with // Restart evaluator in requested mode, i.e. with longer timeout. // longer timeout, not ignoring trailing operators. cancelAll(true); cancelAll(true); clearCache(); clearCache(); mEvaluator = new AsyncDisplayResult(mDegreeMode, true); mEvaluator = new AsyncDisplayResult(mDegreeMode, true); Loading Loading @@ -895,8 +894,7 @@ class Evaluator { add10pow(); // Handled as macro expansion. add10pow(); // Handled as macro expansion. return true; return true; } else { } else { mChangedValue = mChangedValue || (KeyMaps.digVal(id) != KeyMaps.NOT_DIGIT mChangedValue = mChangedValue || !KeyMaps.isBinary(id); || KeyMaps.isSuffix(id) || id == R.id.const_pi || id == R.id.const_e); return mExpr.add(id); return mExpr.add(id); } } } } Loading Loading
src/com/android/calculator2/CalculatorExpr.java +21 −18 Original line number Original line Diff line number Diff line Loading @@ -914,30 +914,24 @@ class CalculatorExpr { final BoundedRational mRatVal; final BoundedRational mRatVal; } } // Return the starting position of the sequence of trailing operators /** // that cannot be meaningfully evaluated. * Return the starting position of the sequence of trailing binary operators. private int trailingOpsStart() { */ private int trailingBinaryOpsStart() { int result = mExpr.size(); int result = mExpr.size(); while (result > 0) { while (result > 0) { Token last = mExpr.get(result - 1); Token last = mExpr.get(result - 1); if (!(last instanceof Operator)) break; if (!(last instanceof Operator)) break; Operator o = (Operator)last; Operator o = (Operator)last; if (KeyMaps.isSuffix(o.mId) || o.mId == R.id.const_pi if (!KeyMaps.isBinary(o.mId)) break; || o.mId == R.id.const_e) { break; } --result; --result; } } return result; return result; } } public boolean hasTrailingOperators() { return trailingOpsStart() != mExpr.size(); } // Is the current expression worth evaluating? // Is the current expression worth evaluating? public boolean hasInterestingOps() { public boolean hasInterestingOps() { int last = trailingOpsStart(); int last = trailingBinaryOpsStart(); int first = 0; int first = 0; if (last > first && isOperatorUnchecked(first, R.id.op_sub)) { if (last > first && isOperatorUnchecked(first, R.id.op_sub)) { // Leading minus is not by itself interesting. // Leading minus is not by itself interesting. Loading @@ -953,16 +947,25 @@ class CalculatorExpr { return false; return false; } } // Evaluate the entire expression, returning null in the event /** // of an error. * Evaluate the expression excluding trailing binary operators. // Not called from the UI thread, but should not be called * Errors result in exceptions, most of which are unchecked. // concurrently with modifications to the expression. * Should not be called concurrently with modification of the expression. EvalResult eval(boolean degreeMode, boolean required) throws SyntaxException * May take a very long time; avoid calling from UI thread. * * @param degreeMode use degrees rather than radians */ EvalResult eval(boolean degreeMode) throws SyntaxException // And unchecked exceptions thrown by CR // And unchecked exceptions thrown by CR // and BoundedRational. // and BoundedRational. { { try { try { int prefixLen = required ? mExpr.size() : trailingOpsStart(); // We currently never include trailing binary operators, but include // other trailing operators. // Thus we usually, but not always, display results for prefixes // of valid expressions, and don't generate an error where we previously // displayed an instant result. This reflects the Android L design. int prefixLen = trailingBinaryOpsStart(); EvalContext ec = new EvalContext(degreeMode, prefixLen); EvalContext ec = new EvalContext(degreeMode, prefixLen); EvalRet res = evalExpr(0, ec); EvalRet res = evalExpr(0, ec); if (res.mPos != prefixLen) { if (res.mPos != prefixLen) { Loading
src/com/android/calculator2/Evaluator.java +4 −6 Original line number Original line Diff line number Diff line Loading @@ -382,7 +382,7 @@ class Evaluator { @Override @Override protected InitialResult doInBackground(Void... nothing) { protected InitialResult doInBackground(Void... nothing) { try { try { CalculatorExpr.EvalResult res = mExpr.eval(mDm, mRequired); CalculatorExpr.EvalResult res = mExpr.eval(mDm); int prec = INIT_PREC; int prec = INIT_PREC; String initCache = res.mVal.toString(prec); String initCache = res.mVal.toString(prec); int msd = getMsdPos(initCache); int msd = getMsdPos(initCache); Loading Loading @@ -810,9 +810,8 @@ class Evaluator { // We presume that any prior result was computed using the same // We presume that any prior result was computed using the same // expression. // expression. void requireResult() { void requireResult() { if (mCache == null || mExpr.hasTrailingOperators()) { if (mCache == null) { // Restart evaluator in requested mode, i.e. with // Restart evaluator in requested mode, i.e. with longer timeout. // longer timeout, not ignoring trailing operators. cancelAll(true); cancelAll(true); clearCache(); clearCache(); mEvaluator = new AsyncDisplayResult(mDegreeMode, true); mEvaluator = new AsyncDisplayResult(mDegreeMode, true); Loading Loading @@ -895,8 +894,7 @@ class Evaluator { add10pow(); // Handled as macro expansion. add10pow(); // Handled as macro expansion. return true; return true; } else { } else { mChangedValue = mChangedValue || (KeyMaps.digVal(id) != KeyMaps.NOT_DIGIT mChangedValue = mChangedValue || !KeyMaps.isBinary(id); || KeyMaps.isSuffix(id) || id == R.id.const_pi || id == R.id.const_e); return mExpr.add(id); return mExpr.add(id); } } } } Loading