diff --git a/res/layout/var_edit.xml b/res/layout/var_edit.xml
index c7910d30..6d5edfad 100644
--- a/res/layout/var_edit.xml
+++ b/res/layout/var_edit.xml
@@ -37,7 +37,7 @@
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java
index 3f195c86..d6798c56 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorModel.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorModel.java
@@ -26,7 +26,10 @@ import org.solovyev.util.math.Complex;
public class CalculatorModel {
@NotNull
- private final Interpreter interpreter;
+ private Interpreter interpreter;
+
+ @NotNull
+ private final Object interpreterMonitor = new Object();
private int numberOfFractionDigits = 5;
@@ -38,30 +41,41 @@ public class CalculatorModel {
private static CalculatorModel instance;
- private CalculatorModel(@Nullable Context context) throws EvalError {
+ private CalculatorModel(@Nullable Context context) {
load(context);
- interpreter = new Interpreter();
- interpreter.eval(ToJsclPreprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands"));
+ reset();
+ }
+
+ public void reset() {
+ synchronized (interpreterMonitor) {
+ try {
+ interpreter = new Interpreter();
+ interpreter.eval(ToJsclPreprocessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands"));
+
+ /*for (Var var : varsRegister.getVars()) {
+ if (!var.isSystem()) {
+ exec(var.getName() + "=" + var.getValue() + ";");
+ }
+ }*/
+ } catch (EvalError evalError) {
+ throw new RuntimeException(evalError);
+ }
+ }
}
public String evaluate(@NotNull JsclOperation operation, @NotNull String expression) throws EvalError, ParseException {
final StringBuilder sb = new StringBuilder();
-/*
- for (Var var : varsRegister.getVars()) {
- if (!var.isSystem()) {
- sb.append(var.getName()).append("=").append(var.getValue()).append(";");
- }
- }
-*/
-
sb.append(preprocessor.process(expression));
//Log.d(CalculatorModel.class.getName(), "Preprocessed expression: " + preprocessedExpression);
- Object evaluationObject = interpreter.eval(ToJsclPreprocessor.wrap(operation, sb.toString()));
+ final Object evaluationObject;
+ synchronized (interpreterMonitor) {
+ evaluationObject = interpreter.eval(ToJsclPreprocessor.wrap(operation, sb.toString()));
+ }
String result = String.valueOf(evaluationObject).trim();
try {
@@ -120,7 +134,7 @@ public class CalculatorModel {
return MathUtils.round(dResult, numberOfFractionDigits);
}
- public synchronized void load(@Nullable Context context) {
+ public synchronized void load(@Nullable Context context) {
if (context != null) {
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
@@ -154,7 +168,7 @@ public class CalculatorModel {
}
public static CalculatorModel getInstance() {
- if (!isLoaded()) {
+ if (!isLoaded()) {
throw new RuntimeException("CalculatorModel must be instantiated!");
}
@@ -165,8 +179,34 @@ public class CalculatorModel {
return instance != null;
}
+
+ private void exec(String str) throws EvalError {
+ interpreter.eval(str);
+ }
+
+ private String eval(String str) throws EvalError {
+ return interpreter.eval(commands(str)).toString();
+ }
+
+
@NotNull
public VarsRegister getVarsRegister() {
return varsRegister;
}
+
+ String commands(String str) {
+ return commands(str, false);
+ }
+
+ String commands(String str, boolean found) {
+ for (int i = 0; i < cmds.length; i++) {
+ int n = str.length() - cmds[i].length() - 1;
+ if (n >= 0 && (" " + cmds[i].toLowerCase()).equals(str.substring(n)))
+ return commands(str.substring(0, n), true) + "." + cmds[i] + "()";
+ }
+ str = str.replaceAll("\n", "");
+ return found ? "jscl.math.Expression.valueOf(\"" + str + "\")" : str;
+ }
+
+ static final String cmds[] = new String[]{"expand", "factorize", "elementary", "simplify", "numeric", "toMathML", "toJava"};
}
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java b/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java
index 3a898056..2d0a36b5 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorVarsActivity.java
@@ -177,10 +177,10 @@ public class CalculatorVarsActivity extends ListActivity {
Toast.makeText(CalculatorVarsActivity.this, error, Toast.LENGTH_LONG).show();
createEditVariableDialog(editedInstance, name, value, description);
} else {
- if (editedInstance != null && !editedInstance.getName().equals(name)) {
- varsRegister.addVar(editedInstance.getName(), varBuilder);
- } else {
+ if ( editedInstance == null ) {
CalculatorVarsActivity.this.adapter.add(varsRegister.addVar(null, varBuilder));
+ } else {
+ varsRegister.addVar(editedInstance.getName(), varBuilder);
}
varsRegister.save(CalculatorVarsActivity.this);
diff --git a/src/main/java/org/solovyev/android/calculator/CalculatorView.java b/src/main/java/org/solovyev/android/calculator/CalculatorView.java
index 8c929e9e..bc6c63b6 100644
--- a/src/main/java/org/solovyev/android/calculator/CalculatorView.java
+++ b/src/main/java/org/solovyev/android/calculator/CalculatorView.java
@@ -192,7 +192,7 @@ public class CalculatorView implements CursorControl, HistoryControl {
+
+ private int i;
+
+ @NotNull
+ private final String targetString;
+
+ public CharacterAtPositionFinder(@NotNull String targetString, int i) {
+ this.targetString = targetString;
+ this.i = i;
+ }
+
+ @Override
+ public boolean isFound(@Nullable Character s) {
+ return s != null && s.equals(targetString.charAt(i));
+ }
+
+ public void setI(int i) {
+ this.i = i;
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/StartsWithFinder.java b/src/main/java/org/solovyev/android/calculator/StartsWithFinder.java
new file mode 100644
index 00000000..c4e7b94e
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/StartsWithFinder.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.solovyev.common.utils.Finder;
+
+/**
+* User: serso
+* Date: 10/3/11
+* Time: 12:49 AM
+*/
+public class StartsWithFinder implements Finder {
+
+ private int i;
+
+ @NotNull
+ private final String targetString;
+
+ public StartsWithFinder(@NotNull String targetString, int i) {
+ this.targetString = targetString;
+ this.i = i;
+ }
+
+ @Override
+ public boolean isFound(@Nullable String s) {
+ return targetString.startsWith(s, i);
+ }
+
+ public void setI(int i) {
+ this.i = i;
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/ToJsclPreprocessor.java b/src/main/java/org/solovyev/android/calculator/ToJsclPreprocessor.java
index 116a2862..0b510d7c 100644
--- a/src/main/java/org/solovyev/android/calculator/ToJsclPreprocessor.java
+++ b/src/main/java/org/solovyev/android/calculator/ToJsclPreprocessor.java
@@ -19,46 +19,88 @@ public class ToJsclPreprocessor implements Preprocessor {
@Override
@NotNull
public String process(@NotNull String s) {
+
+ final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0);
final StringBuilder sb = new StringBuilder();
+ boolean constantBefore = false;
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
- if ( MathEntityType.getType(ch) == MathEntityType.postfix_function ) {
- int start = getPostfixFunctionStart(s, i - 1);
- }
- }
+ startsWithFinder.setI(i);
- final StartsWithFinder startsWithFinder = new StartsWithFinder(s);
- for (int i = 0; i < s.length(); i++) {
- char ch = s.charAt(i);
-
- checkMultiplicationSignBeforeFunction(sb, s, i);
+ checkMultiplicationSignBeforeFunction(sb, s, i, constantBefore);
+ constantBefore = false;
if (MathEntityType.openGroupSymbols.contains(ch)) {
sb.append('(');
} else if (MathEntityType.closeGroupSymbols.contains(ch)) {
sb.append(')');
- } else if (ch == 'π') {
- sb.append("pi");
} else if (ch == '×' || ch == '∙') {
sb.append("*");
} else {
- startsWithFinder.setI(i);
- final String function = CollectionsUtils.get(MathEntityType.prefixFunctions, startsWithFinder);
- if (function != null) {
- sb.append(toJsclFunction(function));
- i += function.length() - 1;
- } else if (ch == 'e') {
- sb.append("exp(1)");
- } else if (ch == 'i') {
- sb.append("sqrt(-1)");
+ String entity = CollectionsUtils.get(MathEntityType.prefixFunctions, startsWithFinder);
+ if (entity == null) {
+ entity = CollectionsUtils.get(CalculatorModel.getInstance().getVarsRegister().getVarNames(), startsWithFinder);
+ if (entity == null) {
+ sb.append(ch);
+ } else {
+ sb.append(entity);
+ i += entity.length() - 1;
+ constantBefore = true;
+ }
} else {
- sb.append(ch);
+ sb.append(toJsclFunction(entity));
+ i += entity.length() - 1;
}
}
}
- return sb.toString();
+ return replaceVariables(sb.toString());
+ }
+
+ private String replaceVariables(@NotNull final String s) {
+ final StartsWithFinder startsWithFinder = new StartsWithFinder(s, 0);
+
+ final StringBuilder result = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ startsWithFinder.setI(i);
+
+ int offset = 0;
+ String functionName = CollectionsUtils.get(MathEntityType.prefixFunctions, startsWithFinder);
+ if (functionName == null) {
+ String varName = CollectionsUtils.get(CalculatorModel.getInstance().getVarsRegister().getVarNames(), startsWithFinder);
+ if (varName != null) {
+ final Var var = CalculatorModel.getInstance().getVarsRegister().getVar(varName);
+ if (var != null) {
+ result.append(var.getValue());
+ offset = varName.length();
+ }
+ }
+ } else {
+ result.append(functionName);
+ offset = functionName.length();
+ }
+
+
+ if (offset == 0) {
+ result.append(s.charAt(i));
+ } else {
+ i += offset - 1;
+ }
+ }
+
+ return result.toString();
+ }
+
+ private void replaceVariables(StringBuilder sb, String s, int i, @NotNull StartsWithFinder startsWithFinder) {
+ for (Var var : CalculatorModel.getInstance().getVarsRegister().getVars()) {
+ if (!var.isSystem()) {
+ if (s.startsWith(var.getName(), i)) {
+ if (CollectionsUtils.get(MathEntityType.prefixFunctions, startsWithFinder) == null) {
+ }
+ }
+ }
+ }
}
public int getPostfixFunctionStart(@NotNull String s, int position) {
@@ -66,17 +108,16 @@ public class ToJsclPreprocessor implements Preprocessor {
int numberOfOpenGroups = 0;
int result = position;
- for ( ; result >= 0; result-- ) {
- char ch = s.charAt(result);
+ for (; result >= 0; result--) {
- final MathEntityType mathEntityType = MathEntityType.getType(ch);
+ final MathEntityType mathEntityType = MathEntityType.getType(s, result);
- if ( mathEntityType != null ) {
- if ( CollectionsUtils.contains(mathEntityType, MathEntityType.digit, MathEntityType.dot) ) {
+ if (mathEntityType != null) {
+ if (CollectionsUtils.contains(mathEntityType, MathEntityType.digit, MathEntityType.dot)) {
// continue
- } else if (MathEntityType.closeGroupSymbols.contains(ch)) {
+ } else if (MathEntityType.closeGroupSymbols.contains(s.charAt(result))) {
numberOfOpenGroups++;
- } else if (MathEntityType.openGroupSymbols.contains(ch)) {
+ } else if (MathEntityType.openGroupSymbols.contains(s.charAt(result))) {
numberOfOpenGroups--;
} else {
if (stop(s, numberOfOpenGroups, result)) break;
@@ -90,12 +131,12 @@ public class ToJsclPreprocessor implements Preprocessor {
}
private boolean stop(String s, int numberOfOpenGroups, int i) {
- if ( numberOfOpenGroups == 0 ) {
+ if (numberOfOpenGroups == 0) {
if (i > 0) {
final EndsWithFinder endsWithFinder = new EndsWithFinder(s);
- endsWithFinder.setI(i+1);
- if ( !CollectionsUtils.contains(MathEntityType.prefixFunctions, FilterType.included, endsWithFinder) ) {
- MathEntityType type = MathEntityType.getType(s.charAt(i));
+ endsWithFinder.setI(i + 1);
+ if (!CollectionsUtils.contains(MathEntityType.prefixFunctions, FilterType.included, endsWithFinder)) {
+ MathEntityType type = MathEntityType.getType(s, i);
if (type != null && type != MathEntityType.constant) {
return true;
}
@@ -123,27 +164,6 @@ public class ToJsclPreprocessor implements Preprocessor {
return result;
}
- private static class StartsWithFinder implements Finder {
-
- private int i;
-
- @NotNull
- private final String targetString;
-
- private StartsWithFinder(@NotNull String targetString) {
- this.targetString = targetString;
- }
-
- @Override
- public boolean isFound(@Nullable String s) {
- return targetString.startsWith(s, i);
- }
-
- public void setI(int i) {
- this.i = i;
- }
- }
-
private static class EndsWithFinder implements Finder {
private int i;
@@ -165,25 +185,25 @@ public class ToJsclPreprocessor implements Preprocessor {
}
}
- private static void checkMultiplicationSignBeforeFunction(@NotNull StringBuilder sb, @NotNull String s, int i) {
+ private static void checkMultiplicationSignBeforeFunction(@NotNull StringBuilder sb, @NotNull String s, int i, boolean constantBefore) {
if (i > 0) {
// get character before function
char chBefore = s.charAt(i - 1);
char ch = s.charAt(i);
final MathEntityType mathTypeBefore = MathEntityType.getType(String.valueOf(chBefore));
- final MathEntityType mathType = MathEntityType.getType(String.valueOf(ch));
+ final MathEntityType mathType = MathEntityType.getType(s, i);
- if (mathTypeBefore != MathEntityType.binary_operation &&
+ if (constantBefore || (mathTypeBefore != MathEntityType.binary_operation &&
mathTypeBefore != MathEntityType.unary_operation &&
- mathTypeBefore != MathEntityType.function &&
- !MathEntityType.openGroupSymbols.contains(chBefore)) {
+ mathTypeBefore != MathEntityType.function &&
+ !MathEntityType.openGroupSymbols.contains(chBefore))) {
if (mathType == MathEntityType.constant) {
sb.append("*");
} else if (MathEntityType.openGroupSymbols.contains(ch) && mathTypeBefore != null) {
sb.append("*");
- } else if (mathType == MathEntityType.digit && mathTypeBefore != MathEntityType.digit && mathTypeBefore != MathEntityType.dot) {
+ } else if (mathType == MathEntityType.digit && ((mathTypeBefore != MathEntityType.digit && mathTypeBefore != MathEntityType.dot) || constantBefore) ) {
sb.append("*");
} else {
for (String function : MathEntityType.prefixFunctions) {
diff --git a/src/main/java/org/solovyev/android/calculator/VarsRegister.java b/src/main/java/org/solovyev/android/calculator/VarsRegister.java
index 9441d79e..1962aab2 100644
--- a/src/main/java/org/solovyev/android/calculator/VarsRegister.java
+++ b/src/main/java/org/solovyev/android/calculator/VarsRegister.java
@@ -13,6 +13,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
+import org.solovyev.android.calculator.math.MathEntityComparator;
import org.solovyev.android.calculator.math.MathEntityType;
import org.solovyev.common.utils.CollectionsUtils;
import org.solovyev.common.utils.Finder;
@@ -46,20 +47,34 @@ public class VarsRegister {
public Var addVar(@Nullable String name, @NotNull Var.Builder builder) {
final Var var = builder.create();
- final Var varFromRegister = getVar(name == null ? var.getName() : name);
+ Var varFromRegister = getVar(name == null ? var.getName() : name);
if (varFromRegister == null) {
+ varFromRegister = var;
vars.add(var);
} else {
varFromRegister.copy(var);
}
- return var;
+ return varFromRegister;
}
public void remove (@NotNull Var var) {
this.vars.remove(var);
}
+ @NotNull
+ public List getVarNames () {
+ final List result = new ArrayList();
+
+ for (Var var : vars) {
+ result.add(var.getName());
+ }
+
+ Collections.sort(result, new MathEntityComparator());
+
+ return result;
+ }
+
@Nullable
public Var getVar(@NotNull final String name) {
return CollectionsUtils.get(vars, new Finder() {
@@ -121,7 +136,7 @@ public class VarsRegister {
} else if (systemVarName.equals("π")) {
systemVar = new Var.Builder(systemVarName, Math.PI).setSystem(true).create();
} else if (systemVarName.equals("i")) {
- systemVar = new Var.Builder(systemVarName, "√(-1)").setSystem(true).create();
+ systemVar = new Var.Builder(systemVarName, "sqrt(-1)").setSystem(true).create();
} else {
throw new IllegalArgumentException(systemVarName + " is not supported yet!");
}
@@ -157,7 +172,7 @@ public class VarsRegister {
throw new RuntimeException(e);
}
- editor.putString(context.getString(R.string.p_calc_vars),sw.toString());
+ editor.putString(context.getString(R.string.p_calc_vars), sw.toString());
editor.commit();
}
diff --git a/src/main/java/org/solovyev/android/calculator/math/Functions.java b/src/main/java/org/solovyev/android/calculator/math/Functions.java
index 4907efe6..98d0ace0 100644
--- a/src/main/java/org/solovyev/android/calculator/math/Functions.java
+++ b/src/main/java/org/solovyev/android/calculator/math/Functions.java
@@ -5,41 +5,48 @@
package org.solovyev.android.calculator.math;
-import org.jetbrains.annotations.NonNls;
-
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
/**
* User: serso
* Date: 9/17/11
* Time: 10:01 PM
*/
-public interface Functions {
+public class Functions {
- String SIN = "sin";
- String SINH = "sinh";
- String ASIN = "asin";
- String ASINH = "asinh";
- String COS = "cos";
- String COSH = "cosh";
- String ACOS = "acos";
- String ACOSH = "acosh";
- String TAN = "tan";
- String TANH = "tanh";
- String ATAN = "atan";
- String ATANH = "atanh";
- String LOG = "log";
- String LN = "ln";
- String MOD = "mod";
- String EXP = "exp";
- String SQRT_SIGN = "√";
- String SQRT = "sqrt";
+ public final static String SIN = "sin";
+ public final static String SINH = "sinh";
+ public final static String ASIN = "asin";
+ public final static String ASINH = "asinh";
+ public final static String COS = "cos";
+ public final static String COSH = "cosh";
+ public final static String ACOS = "acos";
+ public final static String ACOSH = "acosh";
+ public final static String TAN = "tan";
+ 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 MOD = "mod";
+ public final static String EXP = "exp";
+ public final static String SQRT_SIGN = "√";
+ public final static String SQRT = "sqrt";
- public static final List allPrefix = Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP);
+ public static final List allPrefix;
- Character FACT = '!';
- Character DEGREE = '°';
+ static {
+ final List functions = new ArrayList(Arrays.asList(SIN, SINH, ASIN, ASINH, COS, COSH, ACOS, ACOSH, TAN, TANH, ATAN, ATANH, LOG, LN, MOD, SQRT, SQRT_SIGN, EXP));
+ Collections.sort(functions, new MathEntityComparator());
+ allPrefix = functions;
+ }
+
+ public final static Character FACT = '!';
+ public final static Character DEGREE = '°';
public static final List allPostfix = Arrays.asList(FACT, DEGREE);
+
+ private Functions() {
+ throw new AssertionError("Not allowed!");
+ }
}
diff --git a/src/main/java/org/solovyev/android/calculator/math/MathEntityComparator.java b/src/main/java/org/solovyev/android/calculator/math/MathEntityComparator.java
new file mode 100644
index 00000000..49aac482
--- /dev/null
+++ b/src/main/java/org/solovyev/android/calculator/math/MathEntityComparator.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2009-2011. Created by serso aka se.solovyev.
+ * For more information, please, contact se.solovyev@gmail.com
+ * or visit http://se.solovyev.org
+ */
+
+package org.solovyev.android.calculator.math;
+
+import java.util.Comparator;
+
+/**
+ * User: serso
+ * Date: 10/3/11
+ * Time: 12:30 AM
+ */
+public class MathEntityComparator implements Comparator {
+
+ @Override
+ public int compare(String s, String s1) {
+ return s1.length() - s.length();
+ }
+}
diff --git a/src/main/java/org/solovyev/android/calculator/math/MathEntityType.java b/src/main/java/org/solovyev/android/calculator/math/MathEntityType.java
index 50c00dc0..a18d216b 100644
--- a/src/main/java/org/solovyev/android/calculator/math/MathEntityType.java
+++ b/src/main/java/org/solovyev/android/calculator/math/MathEntityType.java
@@ -8,6 +8,8 @@ package org.solovyev.android.calculator.math;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.CalculatorModel;
+import org.solovyev.android.calculator.CharacterAtPositionFinder;
+import org.solovyev.android.calculator.StartsWithFinder;
import org.solovyev.android.calculator.Var;
import org.solovyev.common.utils.CollectionsUtils;
import org.solovyev.common.utils.Finder;
@@ -22,20 +24,21 @@ public enum MathEntityType {
digit,
constant,
dot,
- function,
+ function,
postfix_function,
unary_operation,
binary_operation,
group_symbols,
group_symbol;
-
+
public static final List constants = Arrays.asList("e", "π", "i");
+ public static final List digits = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9");
public static final List dots = Arrays.asList('.');
public static final List unaryOperations = Arrays.asList('-', '=', '!');
- public static final List binaryOperations = Arrays.asList('-', '+', '*', '×', '∙', '/', '^' );
+ public static final List binaryOperations = Arrays.asList('-', '+', '*', '×', '∙', '/', '^');
public static final List prefixFunctions = Functions.allPrefix;
@@ -48,6 +51,7 @@ public enum MathEntityType {
public static final List closeGroupSymbols = Arrays.asList(']', ')', '}');
public static final List singleGroupSymbols;
+
static {
final List list = new ArrayList();
list.addAll(openGroupSymbols);
@@ -56,24 +60,24 @@ public enum MathEntityType {
}
@Nullable
- public static MathEntityType getType( @NotNull String s ) {
+ public static MathEntityType getType(@NotNull String s) {
MathEntityType result = null;
-
- if ( s.length() == 1 ) {
+
+ if (s.length() == 1) {
result = getType(s.charAt(0));
}
-
- if ( result == null ) {
- if ( isConstant(s) ) {
- result = MathEntityType.constant;
- } else if ( prefixFunctions.contains(s) ) {
+
+ if (result == null) {
+ if (prefixFunctions.contains(s)) {
result = MathEntityType.function;
- } else if ( groupSymbols.contains(s) ) {
+ } else if (isConstant(s)) {
+ result = MathEntityType.constant;
+ } else if (groupSymbols.contains(s)) {
result = MathEntityType.group_symbols;
}
}
-
-
+
+
return result;
}
@@ -81,19 +85,19 @@ public enum MathEntityType {
public static MathEntityType getType(final char ch) {
MathEntityType result = null;
- if ( Character.isDigit(ch) ) {
+ if (Character.isDigit(ch)) {
result = MathEntityType.digit;
- } else if ( postfixFunctions.contains(ch) ) {
+ } else if (postfixFunctions.contains(ch)) {
result = MathEntityType.postfix_function;
- } else if ( unaryOperations.contains(ch) ) {
+ } else if (unaryOperations.contains(ch)) {
result = MathEntityType.unary_operation;
- } else if ( binaryOperations.contains(ch) ) {
+ } else if (binaryOperations.contains(ch)) {
result = MathEntityType.binary_operation;
- } else if ( singleGroupSymbols.contains(ch) ) {
+ } else if (singleGroupSymbols.contains(ch)) {
result = MathEntityType.group_symbol;
} else if (isConstant(ch)) {
result = MathEntityType.constant;
- } else if ( dots.contains(ch) ) {
+ } else if (dots.contains(ch)) {
result = MathEntityType.dot;
}
return result;
@@ -113,4 +117,46 @@ public enum MathEntityType {
}
}) != null;
}
+
+ public static MathEntityType getType(String s, int i) {
+ final StartsWithFinder startsWithFinder = new StartsWithFinder(s, i);
+ final CharacterAtPositionFinder characterStartWithFinder = new CharacterAtPositionFinder(s, i);
+
+ return getType(startsWithFinder, characterStartWithFinder);
+ }
+
+ @Nullable
+ private static MathEntityType getType(@NotNull Finder finder, @NotNull CharacterAtPositionFinder characterStartWithFinder) {
+ MathEntityType result = null;
+
+ if (contains(digits, finder)) {
+ result = MathEntityType.digit;
+ } else if (contains(postfixFunctions, characterStartWithFinder)) {
+ result = MathEntityType.postfix_function;
+ } else if (contains(unaryOperations, characterStartWithFinder)) {
+ result = MathEntityType.unary_operation;
+ } else if (contains(binaryOperations, characterStartWithFinder)) {
+ result = MathEntityType.binary_operation;
+ } else if (contains(groupSymbols, finder)) {
+ result = MathEntityType.group_symbols;
+ } else if (contains(singleGroupSymbols, characterStartWithFinder)) {
+ result = MathEntityType.group_symbol;
+ } else if (contains(prefixFunctions, finder)) {
+ result = MathEntityType.function;
+ } else if (contains(CalculatorModel.getInstance().getVarsRegister().getVarNames(), finder)) {
+ result = MathEntityType.constant;
+ } else if (contains(dots, characterStartWithFinder)) {
+ result = MathEntityType.dot;
+ }
+
+ return result;
+ }
+
+ private static boolean contains(@NotNull List list, @NotNull final Finder startsWithFinder) {
+ return CollectionsUtils.get(list, startsWithFinder) != null;
+ }
+
+ private static boolean contains(@NotNull List list, @NotNull final CharacterAtPositionFinder atPositionFinder) {
+ return CollectionsUtils.get(list, atPositionFinder) != null;
+ }
}
diff --git a/src/test/java/org/solovyev/android/calculator/CalculatorModelTest.java b/src/test/java/org/solovyev/android/calculator/CalculatorModelTest.java
index ff2930bb..d11cb326 100644
--- a/src/test/java/org/solovyev/android/calculator/CalculatorModelTest.java
+++ b/src/test/java/org/solovyev/android/calculator/CalculatorModelTest.java
@@ -5,8 +5,8 @@
package org.solovyev.android.calculator;
+import bsh.EvalError;
import org.junit.Assert;
-import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -47,6 +47,25 @@ public class CalculatorModelTest {
Assert.assertEquals("-3.41007+3.41007i", cm.evaluate(JsclOperation.numeric, "(5tan(2i)+2i)/(1-i)"));
Assert.assertEquals("-0.1-0.2i", cm.evaluate(JsclOperation.numeric, "(1-i)/(2+6i)"));
+ CalculatorModel.getInstance().getVarsRegister().addVar(null, new Var.Builder("si", 5d));
+ Assert.assertEquals("5.0", cm.evaluate(JsclOperation.numeric, "si"));
+ try {
+ cm.evaluate(JsclOperation.numeric, "sin");
+ Assert.fail();
+ } catch (EvalError e) {
+ }
+ Assert.assertEquals("-0.95892", cm.evaluate(JsclOperation.numeric, "sin(5)"));
+ Assert.assertEquals("-4.79462", cm.evaluate(JsclOperation.numeric, "sin(5)si"));
+ Assert.assertEquals("-23.97311", cm.evaluate(JsclOperation.numeric, "sisin(5)si"));
+ Assert.assertEquals("-23.97311", cm.evaluate(JsclOperation.numeric, "si*sin(5)si"));
+ Assert.assertEquals("-3.30879", cm.evaluate(JsclOperation.numeric, "sisin(5si)si"));
+
+ CalculatorModel.getInstance().getVarsRegister().addVar(null, new Var.Builder("s", 1d));
+ Assert.assertEquals("5.0", cm.evaluate(JsclOperation.numeric, "si"));
+
+ CalculatorModel.getInstance().getVarsRegister().addVar(null, new Var.Builder("k", 3.5d));
+ CalculatorModel.getInstance().getVarsRegister().addVar(null, new Var.Builder("k1", 4d));
+ Assert.assertEquals("4.0", cm.evaluate(JsclOperation.numeric, "k11"));
}
@Test