simplify feature changes

This commit is contained in:
Sergey Solovyev
2011-10-20 15:59:24 +04:00
parent 1b581304c6
commit 6f4eaec0d4
12 changed files with 217 additions and 40 deletions

View File

@@ -32,10 +32,10 @@ class FromJsclNumericTextProcessor implements TextProcessor<String> {
result = String.valueOf(roundedValue);
}
} catch (NumberFormatException e) {
result = result.replace(MathType.INFINITY_DEF, MathType.INFINITY);
if (result.contains(MathType.IMAGINARY_NUMBER_DEF)) {
result = result.replace(MathType.INFINITY_JSCL, MathType.INFINITY);
if (result.contains(MathType.IMAGINARY_NUMBER_JSCL)) {
try {
result = createResultForComplexNumber(result.replace(MathType.IMAGINARY_NUMBER_DEF, MathType.IMAGINARY_NUMBER));
result = createResultForComplexNumber(result.replace(MathType.IMAGINARY_NUMBER_JSCL, MathType.IMAGINARY_NUMBER));
} catch (NumberFormatException e1) {
// throw original one
throw new ParseException(e);

View File

@@ -8,11 +8,12 @@ package org.solovyev.android.calculator.jscl;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.model.DummyTextProcessor;
import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor;
import org.solovyev.android.calculator.model.TextProcessor;
public enum JsclOperation {
simplify(DummyTextProcessor.instance),
simplify(new FromJsclSimplifyTextProcessor()),
elementary(DummyTextProcessor.instance),
importCommands(DummyTextProcessor.instance),
numeric(new FromJsclNumericTextProcessor());

View File

@@ -31,20 +31,20 @@ public class Functions {
public final static String TANH = "tanh";
public final static String ATAN = "atan";
public final static String ATANH = "atanh";
public final static String LOG = "log";
public final static String LN = "ln";
public final static String LN_JSCL = "log";
public final static String MOD = "mod";
public final static String EXP = "exp";
public final static String SQRT_SIGN = "";
public final static String SQRT = "sqrt";
public final static String E = "E";
public final static String E_POWER = "10^";
public final static String SQRT = "";
public final static String SQRT_JSCL = "sqrt";
public static final List<String> allPrefix;
static {
final List<String> functions = new ArrayList<String>(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP, E));
final List<String> functions = new ArrayList<String>(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LN, LN_JSCL, MOD, SQRT, SQRT_JSCL, EXP));
Collections.sort(functions, new MathEntityComparator());
allPrefix = functions;
}

View File

@@ -19,8 +19,9 @@ import static org.solovyev.common.utils.CollectionsUtils.get;
public enum MathType {
digit,
constant,
dot,
power_10,
constant,
function,
postfix_function,
unary_operation,
@@ -30,13 +31,16 @@ public enum MathType {
close_group_symbol,
text;
public final static Character POWER_10 = 'E';
public final static String POWER_10_JSCL = "10^";
public static final String IMAGINARY_NUMBER = "i";
public static final String IMAGINARY_NUMBER_DEF = "sqrt(-1)";
public static final String IMAGINARY_NUMBER_JSCL = "sqrt(-1)";
public static final String PI = "π";
public static final String E = "e";
public final static String NAN = "NaN";
public final static String INFINITY = "";
public final static String INFINITY_DEF = "Infinity";
public final static String INFINITY_JSCL = "Infinity";
public static final List<String> constants = Arrays.asList(E, PI, IMAGINARY_NUMBER, NAN, INFINITY);
@@ -44,6 +48,7 @@ public enum MathType {
public static final List<Character> dots = Arrays.asList('.');
public static final List<Character> unaryOperations = Arrays.asList('-', '=', '!');
public static final List<Character> binaryOperations = Arrays.asList('-', '+', '*', '×', '∙', '/', '^');
@@ -88,6 +93,11 @@ public enum MathType {
return new Result(dot, String.valueOf(foundCharacter));
}
foundCharacter = characterStartWithFinder.isFound(POWER_10) ? POWER_10 : null;
if (foundCharacter != null) {
return new Result(power_10, String.valueOf(foundCharacter));
}
foundCharacter = get(postfixFunctions, characterStartWithFinder);
if (foundCharacter != null) {
return new Result(postfix_function, String.valueOf(foundCharacter));

View File

@@ -20,6 +20,6 @@ public enum DummyTextProcessor implements TextProcessor<String> {
@NotNull
@Override
public String process(@NotNull String s) throws ParseException {
return s.replace(ToJsclTextProcessor.SPECIAL_STRING, "");
return s;
}
}

View File

@@ -0,0 +1,96 @@
package org.solovyev.android.calculator.model;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.StartsWithFinder;
import org.solovyev.android.calculator.math.MathType;
import org.solovyev.common.utils.CollectionsUtils;
import org.solovyev.common.utils.Finder;
/**
* User: serso
* Date: 10/20/11
* Time: 2:59 PM
*/
public class FromJsclSimplifyTextProcessor implements TextProcessor<String> {
@NotNull
@Override
public String process(@NotNull String s) throws ParseException {
final StringBuilder sb = new StringBuilder();
MathType.Result mathTypeResult = null;
StringBuilder numberBuilder = null;
String number = null;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
mathTypeResult = MathType.getType(s, i);
final MathType mathType = mathTypeResult.getMathType();
number = null;
if (mathType == MathType.digit || mathType == MathType.dot || mathType == MathType.power_10) {
if (numberBuilder == null) {
numberBuilder = new StringBuilder();
}
numberBuilder.append(mathTypeResult.getMatch());
} else {
if (numberBuilder != null) {
try {
number = numberBuilder.toString();
Double.valueOf(number);
} catch (NumberFormatException e) {
number = null;
}
numberBuilder = null;
}
}
replaceSystemVars(sb, number);
if (mathType == MathType.constant) {
sb.append(mathTypeResult.getMatch());
i += mathTypeResult.getMatch().length() - 1;
} else if (ch == '*') {
sb.append("×");
} else {
sb.append(ch);
}
}
if (numberBuilder != null) {
try {
number = numberBuilder.toString();
Double.valueOf(number);
} catch (NumberFormatException e) {
number = null;
}
numberBuilder = null;
}
replaceSystemVars(sb, number);
return sb.toString();
}
private void replaceSystemVars(StringBuilder sb, String number) {
if (number != null) {
final String finalNumber = number;
final Var var = CollectionsUtils.get(CalculatorEngine.instance.getVarsRegister().getSystemVars(), new Finder<Var>() {
@Override
public boolean isFound(@Nullable Var var) {
return var != null && finalNumber.equals(var.getValue());
}
});
if (var != null) {
sb.delete(sb.length() - number.length(), sb.length());
sb.append(var.getName());
}
}
}
}

View File

@@ -14,6 +14,11 @@ import org.solovyev.common.exceptions.SersoException;
* Time: 9:25 PM
*/
public class ParseException extends SersoException {
public ParseException(String message) {
super(message);
}
public ParseException(Throwable cause) {
super(cause);
}

View File

@@ -21,11 +21,9 @@ import java.util.List;
class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
public static final String SPECIAL_STRING = "☀☀☀";
@Override
@NotNull
public PreparedExpression process(@NotNull String s) {
public PreparedExpression process(@NotNull String s) throws ParseException {
final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0);
final StringBuilder sb = new StringBuilder();
@@ -44,6 +42,8 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
sb.append(')');
} else if (ch == '×' || ch == '∙') {
sb.append("*");
} else if (mathType == MathType.power_10) {
sb.append(MathType.POWER_10_JSCL);
} else if (mathType == MathType.function) {
sb.append(toJsclFunction(mathTypeResult.getMatch()));
i += mathTypeResult.getMatch().length() - 1;
@@ -51,9 +51,10 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
// NOTE: fix for jscl for EMPTY functions processing (see tests)
startsWithFinder.setI(i + 1);
if ( i < s.length() && CollectionsUtils.get(MathType.groupSymbols, startsWithFinder) != null) {
i += 2;
throw new ParseException("Empty function: " + mathTypeResult.getMatch());
/*i += 2;
sb.append("(" + SPECIAL_STRING + ")");
mathTypeResult = new MathType.Result(MathType.close_group_symbol, ")");
mathTypeResult = new MathType.Result(MathType.close_group_symbol, ")");*/
}
} else if (mathType == MathType.constant) {
sb.append(mathTypeResult.getMatch());
@@ -167,11 +168,9 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
final String result;
if (function.equals(Functions.LN)) {
result = Functions.LOG;
} else if (function.equals(Functions.SQRT_SIGN)) {
result = Functions.SQRT;
} else if (function.equals(Functions.E)) {
result = Functions.E_POWER;
result = Functions.LN_JSCL;
} else if (function.equals(Functions.SQRT)) {
result = Functions.SQRT_JSCL;
} else {
result = function;
}
@@ -215,11 +214,14 @@ class ToJsclTextProcessor implements TextProcessor<PreparedExpression> {
if (mathTypeBefore == MathType.constant || (mathTypeBefore != MathType.binary_operation &&
mathTypeBefore != MathType.unary_operation &&
mathTypeBefore != MathType.power_10 &&
mathTypeBefore != MathType.function &&
mathTypeBefore != MathType.open_group_symbol)) {
if (mathType == MathType.constant) {
sb.append("*");
} else if (mathType == MathType.power_10) {
sb.append("*");
} else if (mathType == MathType.open_group_symbol && mathTypeBefore != null) {
sb.append("*");
} else if (mathType == MathType.digit && ((mathTypeBefore != MathType.digit && mathTypeBefore != MathType.dot) || mathTypeBefore == MathType.constant)) {

View File

@@ -149,13 +149,13 @@ class VarsRegisterImpl implements VarsRegister {
builder = new Var.Builder(systemVarName, Math.PI);
varDescription = R.string.c_pi_description;
} else if (systemVarName.equals(MathType.IMAGINARY_NUMBER)) {
builder = new Var.Builder(systemVarName, MathType.IMAGINARY_NUMBER_DEF);
builder = new Var.Builder(systemVarName, MathType.IMAGINARY_NUMBER_JSCL);
varDescription = R.string.c_i_description;
} else if (systemVarName.equals(MathType.NAN)) {
builder = new Var.Builder(systemVarName, MathType.NAN);
varDescription = R.string.c_nan_description;
} else if (systemVarName.equals(MathType.INFINITY)) {
builder = new Var.Builder(systemVarName, MathType.INFINITY_DEF);
builder = new Var.Builder(systemVarName, MathType.INFINITY_JSCL);
varDescription = R.string.c_infinity_description;
} else {
throw new IllegalArgumentException(systemVarName + " is not supported yet!");