jscl without bsh

This commit is contained in:
Sergey Solovyev 2011-10-27 18:38:45 +04:00
parent 6a84dab9c7
commit 7c4f6b153f
6 changed files with 51 additions and 60 deletions

14
pom.xml
View File

@ -39,24 +39,18 @@
<version>0.2</version>
</dependency>
<dependency>
<groupId>org.beanshell</groupId>
<artifactId>bsh</artifactId>
<version>2.0b4</version>
</dependency>
<dependency>
<groupId>org.solovyev</groupId>
<artifactId>jscl</artifactId>
<version>0.0.1</version>
<!--<exclusions>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>-->
<scope>system</scope>
<systemPath>${additionalLibs}/jscl.jar</systemPath>
</exclusions>
<!-- <scope>system</scope>
<systemPath>${additionalLibs}/jscl.jar</systemPath>-->
</dependency>
<dependency>

View File

@ -22,7 +22,6 @@ import android.view.*;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import bsh.EvalError;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType;
@ -257,11 +256,7 @@ public class CalculatorActivity extends Activity implements FontSizeAdjuster, Sh
}
}
try {
CalculatorEngine.instance.init(this, preferences);
} catch (EvalError evalError) {
throw new RuntimeException("Could not initialize interpreter!");
}
CalculatorEngine.instance.init(this, preferences);
initialized = true;
}
}

View File

@ -15,7 +15,6 @@ import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import bsh.EvalError;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.jscl.JsclOperation;
@ -208,8 +207,6 @@ public enum CalculatorModel implements CursorControl, HistoryControl<CalculatorH
display.setText("");
}
display.setJsclOperation(result.getUserOperation());
} catch (EvalError e) {
handleEvaluationException(expression, display, operation, e);
} catch (ParseException e) {
handleEvaluationException(expression, display, operation, e);
}

View File

@ -6,6 +6,7 @@
package org.solovyev.android.calculator.jscl;
import jscl.math.Expression;
import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.model.DummyTextProcessor;
import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor;
@ -13,10 +14,30 @@ import org.solovyev.android.calculator.model.TextProcessor;
public enum JsclOperation {
simplify(new FromJsclSimplifyTextProcessor()),
elementary(DummyTextProcessor.instance),
importCommands(DummyTextProcessor.instance),
numeric(new FromJsclNumericTextProcessor());
simplify(new FromJsclSimplifyTextProcessor()) {
@NotNull
@Override
public String evaluate(@NotNull Expression expression) {
return expression.simplify().toString();
}
},
elementary(DummyTextProcessor.instance) {
@NotNull
@Override
public String evaluate(@NotNull Expression expression) {
return expression.elementary().toString();
}
},
numeric(new FromJsclNumericTextProcessor()) {
@NotNull
@Override
public String evaluate(@NotNull Expression expression) {
return expression.numeric().toString();
}
};
@NotNull
private final TextProcessor<String> fromProcessor;
@ -29,4 +50,7 @@ public enum JsclOperation {
public TextProcessor<String> getFromProcessor() {
return fromProcessor;
}
@NotNull
public abstract String evaluate(@NotNull Expression expression);
}

View File

@ -7,8 +7,7 @@ package org.solovyev.android.calculator.model;
import android.content.Context;
import android.content.SharedPreferences;
import bsh.EvalError;
import bsh.Interpreter;
import jscl.math.Expression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.R;
@ -50,9 +49,6 @@ public enum CalculatorEngine {
public static final String RESULT_PRECISION_P_KEY = "org.solovyev.android.calculator.CalculatorModel_result_precision";
public static final String RESULT_PRECISION_DEFAULT = "5";
@NotNull
private Interpreter interpreter;
@NotNull
private final Object lock = new Object();
@ -131,13 +127,13 @@ public enum CalculatorEngine {
}
public Result evaluate(@NotNull JsclOperation operation,
@NotNull String expression) throws EvalError, ParseException {
@NotNull String expression) throws ParseException {
return evaluate(operation, expression, null);
}
public Result evaluate(@NotNull JsclOperation operation,
@NotNull String expression,
@Nullable MessageRegistry<AndroidMessage> mr) throws EvalError, ParseException {
@Nullable MessageRegistry<AndroidMessage> mr) throws ParseException {
synchronized (lock) {
final StringBuilder sb = new StringBuilder();
@ -160,12 +156,13 @@ public enum CalculatorEngine {
}
}
final String jsclExpression = ToJsclTextProcessor.wrap(operation, sb.toString());
final String jsclExpression = sb.toString();
final JsclOperation finalOperation = operation;
final String result;
if (!tooLongExecutionCache.contains(jsclExpression)) {
final MutableObject<Object> calculationResult = new MutableObject<Object>(null);
final MutableObject<EvalError> exception = new MutableObject<EvalError>(null);
final MutableObject<ParseException> exception = new MutableObject<ParseException>(null);
final MutableObject<Thread> calculationThread = new MutableObject<Thread>(null);
final CountDownLatch latch = new CountDownLatch(1);
@ -177,9 +174,9 @@ public enum CalculatorEngine {
try {
//Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName());
calculationThread.setObject(thread);
calculationResult.setObject(interpreter.eval(jsclExpression));
} catch (EvalError evalError) {
exception.setObject(evalError);
calculationResult.setObject(finalOperation.evaluate(Expression.valueOf(jsclExpression)));
} catch (jscl.text.ParseException e) {
exception.setObject(new ParseException(e));
} finally {
//Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName());
calculationThread.setObject(null);
@ -190,10 +187,10 @@ public enum CalculatorEngine {
try {
//Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName());
latch.await(3, TimeUnit.SECONDS);
latch.await(3000, TimeUnit.SECONDS);
//Log.d(CalculatorEngine.class.getName(), "Main thread got up: " + Thread.currentThread().getName());
final EvalError evalErrorLocal = exception.getObject();
final ParseException evalErrorLocal = exception.getObject();
final Object calculationResultLocal = calculationResult.getObject();
final Thread calculationThreadLocal = calculationThread.getObject();
@ -201,7 +198,6 @@ public enum CalculatorEngine {
// todo serso: interrupt doesn't stop the thread but it MUST be killed
threadKiller.killThread(calculationThreadLocal);
//calculationThreadLocal.stop();
resetInterpreter();
}
if ( evalErrorLocal != null ) {
@ -242,10 +238,9 @@ public enum CalculatorEngine {
this.roundResult = roundResult;
}
public void init(@Nullable Context context, @Nullable SharedPreferences preferences) throws EvalError {
public void init(@Nullable Context context, @Nullable SharedPreferences preferences) {
synchronized (lock) {
reset(context, preferences);
resetInterpreter();
}
}
@ -270,17 +265,6 @@ public enum CalculatorEngine {
}
}
public void resetInterpreter() {
synchronized (lock) {
try {
interpreter = new Interpreter();
interpreter.eval(ToJsclTextProcessor.wrap(JsclOperation.importCommands, "/jscl/editorengine/commands"));
} catch (EvalError evalError) {
throw new RuntimeException(evalError);
}
}
}
//for tests only
void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) {
synchronized (lock) {

View File

@ -5,7 +5,6 @@
package org.solovyev.android.calculator.model;
import bsh.EvalError;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
@ -35,22 +34,19 @@ public class CalculatorEngineTest {
try {
cm.evaluate(JsclOperation.numeric, "3^10^10^10");
Assert.fail();
} catch (EvalError evalError) {
Assert.fail();
} catch (ParseException e) {
if (e.getMessage().startsWith("Too long calculation")) {
if (e.getCause().getMessage().startsWith("Too big")) {
} else {
System.out.print(e.getCause().getMessage());
Assert.fail();
}
}
final long start = System.currentTimeMillis();
/*final long start = System.currentTimeMillis();
try {
cm.evaluate(JsclOperation.numeric, "3^10^10^10");
Assert.fail();
} catch (EvalError evalError) {
Assert.fail();
} catch (ParseException e) {
if (e.getMessage().startsWith("Too long calculation")) {
final long end = System.currentTimeMillis();
@ -58,7 +54,7 @@ public class CalculatorEngineTest {
} else {
Assert.fail();
}
}
}*/
}
@ -140,10 +136,11 @@ public class CalculatorEngineTest {
CalculatorEngine.instance.getVarsRegister().addVar(null, new Var.Builder("si", 5d));
Assert.assertEquals("5", cm.evaluate(JsclOperation.numeric, "si").getResult());
try {
cm.evaluate(JsclOperation.numeric, "sin");
Assert.fail();
} catch (EvalError e) {
} catch (ParseException e) {
}
}