jscl without bsh

This commit is contained in:
serso 2011-10-27 18:38:45 +04:00
parent 17cd3902b9
commit 005123229e
6 changed files with 51 additions and 60 deletions

14
pom.xml
View File

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

View File

@ -22,7 +22,6 @@ import android.view.*;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import bsh.EvalError;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.math.MathType; 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); CalculatorEngine.instance.init(this, preferences);
} catch (EvalError evalError) {
throw new RuntimeException("Could not initialize interpreter!");
}
initialized = true; initialized = true;
} }
} }

View File

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

View File

@ -6,6 +6,7 @@
package org.solovyev.android.calculator.jscl; package org.solovyev.android.calculator.jscl;
import jscl.math.Expression;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.solovyev.android.calculator.model.DummyTextProcessor; import org.solovyev.android.calculator.model.DummyTextProcessor;
import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor; import org.solovyev.android.calculator.model.FromJsclSimplifyTextProcessor;
@ -13,10 +14,30 @@ import org.solovyev.android.calculator.model.TextProcessor;
public enum JsclOperation { public enum JsclOperation {
simplify(new FromJsclSimplifyTextProcessor()), simplify(new FromJsclSimplifyTextProcessor()) {
elementary(DummyTextProcessor.instance), @NotNull
importCommands(DummyTextProcessor.instance), @Override
numeric(new FromJsclNumericTextProcessor()); 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 @NotNull
private final TextProcessor<String> fromProcessor; private final TextProcessor<String> fromProcessor;
@ -29,4 +50,7 @@ public enum JsclOperation {
public TextProcessor<String> getFromProcessor() { public TextProcessor<String> getFromProcessor() {
return fromProcessor; 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.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import bsh.EvalError; import jscl.math.Expression;
import bsh.Interpreter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.solovyev.android.calculator.R; 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_P_KEY = "org.solovyev.android.calculator.CalculatorModel_result_precision";
public static final String RESULT_PRECISION_DEFAULT = "5"; public static final String RESULT_PRECISION_DEFAULT = "5";
@NotNull
private Interpreter interpreter;
@NotNull @NotNull
private final Object lock = new Object(); private final Object lock = new Object();
@ -131,13 +127,13 @@ public enum CalculatorEngine {
} }
public Result evaluate(@NotNull JsclOperation operation, public Result evaluate(@NotNull JsclOperation operation,
@NotNull String expression) throws EvalError, ParseException { @NotNull String expression) throws ParseException {
return evaluate(operation, expression, null); return evaluate(operation, expression, null);
} }
public Result evaluate(@NotNull JsclOperation operation, public Result evaluate(@NotNull JsclOperation operation,
@NotNull String expression, @NotNull String expression,
@Nullable MessageRegistry<AndroidMessage> mr) throws EvalError, ParseException { @Nullable MessageRegistry<AndroidMessage> mr) throws ParseException {
synchronized (lock) { synchronized (lock) {
final StringBuilder sb = new StringBuilder(); 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; final String result;
if (!tooLongExecutionCache.contains(jsclExpression)) { if (!tooLongExecutionCache.contains(jsclExpression)) {
final MutableObject<Object> calculationResult = new MutableObject<Object>(null); 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 MutableObject<Thread> calculationThread = new MutableObject<Thread>(null);
final CountDownLatch latch = new CountDownLatch(1); final CountDownLatch latch = new CountDownLatch(1);
@ -177,9 +174,9 @@ public enum CalculatorEngine {
try { try {
//Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName()); //Log.d(CalculatorEngine.class.getName(), "Calculation thread started work: " + thread.getName());
calculationThread.setObject(thread); calculationThread.setObject(thread);
calculationResult.setObject(interpreter.eval(jsclExpression)); calculationResult.setObject(finalOperation.evaluate(Expression.valueOf(jsclExpression)));
} catch (EvalError evalError) { } catch (jscl.text.ParseException e) {
exception.setObject(evalError); exception.setObject(new ParseException(e));
} finally { } finally {
//Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName()); //Log.d(CalculatorEngine.class.getName(), "Calculation thread ended work: " + thread.getName());
calculationThread.setObject(null); calculationThread.setObject(null);
@ -190,10 +187,10 @@ public enum CalculatorEngine {
try { try {
//Log.d(CalculatorEngine.class.getName(), "Main thread is waiting: " + Thread.currentThread().getName()); //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()); //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 Object calculationResultLocal = calculationResult.getObject();
final Thread calculationThreadLocal = calculationThread.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 // todo serso: interrupt doesn't stop the thread but it MUST be killed
threadKiller.killThread(calculationThreadLocal); threadKiller.killThread(calculationThreadLocal);
//calculationThreadLocal.stop(); //calculationThreadLocal.stop();
resetInterpreter();
} }
if ( evalErrorLocal != null ) { if ( evalErrorLocal != null ) {
@ -242,10 +238,9 @@ public enum CalculatorEngine {
this.roundResult = roundResult; 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) { synchronized (lock) {
reset(context, preferences); 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 //for tests only
void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) { void setDecimalGroupSymbols(@NotNull DecimalFormatSymbols decimalGroupSymbols) {
synchronized (lock) { synchronized (lock) {

View File

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