Fixed bugs and enhanched math parser.
This commit is contained in:
parent
f31985764d
commit
8bc727e823
9
src/main/java/org/warp/picalculator/IntegerObj.java
Normal file
9
src/main/java/org/warp/picalculator/IntegerObj.java
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.warp.picalculator;
|
||||||
|
|
||||||
|
public class IntegerObj {
|
||||||
|
public int i;
|
||||||
|
|
||||||
|
public IntegerObj(int i) {
|
||||||
|
this.i = i;
|
||||||
|
}
|
||||||
|
}
|
@ -30,10 +30,10 @@ public class Main {
|
|||||||
Main.args = args;
|
Main.args = args;
|
||||||
beforeStart();
|
beforeStart();
|
||||||
new DisplayManager(screen);
|
new DisplayManager(screen);
|
||||||
Utils.debug.println("Shutdown...");
|
Utils.out.println(1, "Shutdown...");
|
||||||
beforeShutdown();
|
beforeShutdown();
|
||||||
Utils.debug.println("");
|
Utils.out.println(1, "");
|
||||||
Utils.debug.println("Closed.");
|
Utils.out.println(1, "Closed.");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,17 +46,49 @@ public class Utils {
|
|||||||
public static final int scaleMode = BigDecimal.ROUND_HALF_UP;
|
public static final int scaleMode = BigDecimal.ROUND_HALF_UP;
|
||||||
public static final RoundingMode scaleMode2 = RoundingMode.HALF_UP;
|
public static final RoundingMode scaleMode2 = RoundingMode.HALF_UP;
|
||||||
|
|
||||||
public static DebugStream debug = new DebugStream();
|
public static AdvancedOutputStream out = new AdvancedOutputStream();
|
||||||
|
|
||||||
public static boolean debugOn;
|
public static boolean debugOn;
|
||||||
|
public static int outputLevel = 5;
|
||||||
|
public static final int OUTPUTLEVEL_NODEBUG = 0;
|
||||||
|
public static final int OUTPUTLEVEL_DEBUG_MIN = 1;
|
||||||
|
public static final int OUTPUTLEVEL_DEBUG_MAX = 4;
|
||||||
public static boolean debugThirdScreen;
|
public static boolean debugThirdScreen;
|
||||||
public static final boolean debugWindow2x = true;
|
public static final boolean debugWindow2x = true;
|
||||||
|
|
||||||
public static final class DebugStream extends StringWriter {
|
public static final class AdvancedOutputStream extends StringWriter {
|
||||||
|
|
||||||
public void println(String str) {
|
public void println(String str) {
|
||||||
if (debugOn) {
|
println(0, str);
|
||||||
System.err.println(str);
|
}
|
||||||
|
|
||||||
|
public void println(int level) {
|
||||||
|
if (outputLevel >= level) {
|
||||||
|
if (outputLevel == 0) {
|
||||||
|
System.out.println();
|
||||||
|
} else {
|
||||||
|
System.err.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void println(int level, String str) {
|
||||||
|
if (outputLevel >= level) {
|
||||||
|
if (outputLevel == 0) {
|
||||||
|
System.out.println(str);
|
||||||
|
} else {
|
||||||
|
System.err.println(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void print(int level, String str) {
|
||||||
|
if (outputLevel >= level) {
|
||||||
|
if (outputLevel == 0) {
|
||||||
|
System.out.print(str);
|
||||||
|
} else {
|
||||||
|
System.err.print(str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,7 +832,7 @@ public class Keyboard {
|
|||||||
refreshRequest = true;
|
refreshRequest = true;
|
||||||
}
|
}
|
||||||
} else if (!done) {
|
} else if (!done) {
|
||||||
Utils.debug.println("Key " + k.toString() + " ignored.");
|
Utils.out.println(1, "Key " + k.toString() + " ignored.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -862,7 +862,7 @@ public class Keyboard {
|
|||||||
refreshRequest = true;
|
refreshRequest = true;
|
||||||
}
|
}
|
||||||
} else if (!done) {
|
} else if (!done) {
|
||||||
Utils.debug.println("Key " + k.toString() + " ignored.");
|
Utils.out.println(1, "Key " + k.toString() + " ignored.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,12 +77,12 @@ public final class DisplayManager implements RenderingLoop {
|
|||||||
GraphicEngine d;
|
GraphicEngine d;
|
||||||
d = new GPUEngine();
|
d = new GPUEngine();
|
||||||
if (d.isSupported()) {
|
if (d.isSupported()) {
|
||||||
Utils.debug.println("Using GPU Graphic Engine");
|
Utils.out.println(1, "Using GPU Graphic Engine");
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
d = new CPUEngine();
|
d = new CPUEngine();
|
||||||
if (d.isSupported()) {
|
if (d.isSupported()) {
|
||||||
Utils.debug.println("Using CPU Graphic Engine");
|
Utils.out.println(1, "Using CPU Graphic Engine");
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
d = new Headless256Engine();
|
d = new Headless256Engine();
|
||||||
@ -273,7 +273,7 @@ public final class DisplayManager implements RenderingLoop {
|
|||||||
if (brightness <= 10) {
|
if (brightness <= 10) {
|
||||||
renderer.glFillRect(Main.screenSize[0] - (padding + 16), 2, 16, 16, 16 * brightness, 16 * 1, 16, 16);
|
renderer.glFillRect(Main.screenSize[0] - (padding + 16), 2, 16, 16, 16 * brightness, 16 * 1, 16, 16);
|
||||||
} else {
|
} else {
|
||||||
Utils.debug.println("Brightness error");
|
Utils.out.println(1, "Brightness error");
|
||||||
}
|
}
|
||||||
|
|
||||||
padding += 18 + 6;
|
padding += 18 + 6;
|
||||||
@ -478,7 +478,7 @@ public final class DisplayManager implements RenderingLoop {
|
|||||||
Gpio.pwmWrite(12, (int) Math.ceil(brightness * 1024f));
|
Gpio.pwmWrite(12, (int) Math.ceil(brightness * 1024f));
|
||||||
// SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10)));
|
// SoftPwm.softPwmWrite(12, (int)(Math.ceil(brightness*10)));
|
||||||
} else {
|
} else {
|
||||||
Utils.debug.println("Brightness: " + newval);
|
Utils.out.println(1, "Brightness: " + newval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,5 +359,5 @@ public class BlockContainer implements GraphicalElement {
|
|||||||
final Function result = MathParser.joinFeatures(context, blockFeatures);
|
final Function result = MathParser.joinFeatures(context, blockFeatures);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -132,7 +132,7 @@ public class MathInputScreen extends Screen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean keyPressed(Key k) {
|
public boolean keyPressed(Key k) {
|
||||||
Utils.debug.println(k.toString());
|
Utils.out.println(1, k.toString());
|
||||||
switch (k) {
|
switch (k) {
|
||||||
case OK:
|
case OK:
|
||||||
userInput.toggleExtra();
|
userInput.toggleExtra();
|
||||||
@ -184,7 +184,7 @@ public class MathInputScreen extends Screen {
|
|||||||
case SIMPLIFY:
|
case SIMPLIFY:
|
||||||
if (DisplayManager.error != null) {
|
if (DisplayManager.error != null) {
|
||||||
//TODO: make the error management a global API rather than being relegated to this screen.
|
//TODO: make the error management a global API rather than being relegated to this screen.
|
||||||
Utils.debug.println("Resetting after error...");
|
Utils.out.println(1, "Resetting after error...");
|
||||||
DisplayManager.error = null;
|
DisplayManager.error = null;
|
||||||
calc.f = null;
|
calc.f = null;
|
||||||
calc.f2 = null;
|
calc.f2 = null;
|
||||||
@ -205,38 +205,40 @@ public class MathInputScreen extends Screen {
|
|||||||
calc.f.add(expr);
|
calc.f.add(expr);
|
||||||
int stop = 0;
|
int stop = 0;
|
||||||
boolean done = false;
|
boolean done = false;
|
||||||
ObjectArrayList<ObjectArrayList<Function>> resultExpressions = new ObjectArrayList<>();
|
ObjectArrayList<Function> resultExpressions = new ObjectArrayList<>();
|
||||||
resultExpressions.add(new ObjectArrayList<Function>(expr.getParameters()));
|
resultExpressions.add(expr.getParameter());
|
||||||
while (!done && stop < 3000) {
|
while (!done && stop < 3000) {
|
||||||
ObjectArrayList<ObjectArrayList<Function>> newResultExpressions = new ObjectArrayList<>();
|
ObjectArrayList<Function> newResultExpressions = new ObjectArrayList<>();
|
||||||
done = true;
|
done = true;
|
||||||
for (ObjectArrayList<Function> resultExpr : resultExpressions) {
|
for (Function f : resultExpressions) {
|
||||||
ObjectArrayList<Function> newResults = new ObjectArrayList<>();
|
Function newResult = null;
|
||||||
for (Function f : resultExpr) {
|
if (f.isSimplified() == false) {
|
||||||
if (f.isSimplified() == false) {
|
done = false;
|
||||||
done = false;
|
if (f instanceof Expression) {
|
||||||
if (f instanceof Expression) {
|
ObjectArrayList<Function> fncResult = ((Expression)f).solve();
|
||||||
ObjectArrayList<Function> fncResult = ((Expression)f).solve();
|
for (Function resultItem : fncResult) {
|
||||||
for (Function resultItem : fncResult) {
|
newResultExpressions.add(resultItem);
|
||||||
newResultExpressions.add(new ObjectArrayList<Function>(new Function[] {resultItem}));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
List<Function> fncResult = f.simplify();
|
|
||||||
for (Function resultItem : fncResult) {
|
|
||||||
newResultExpressions.add(new ObjectArrayList<Function>(new Function[] {resultItem}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newResults.add(f);
|
List<Function> fncResult = f.simplify();
|
||||||
|
for (Function resultItem : fncResult) {
|
||||||
|
newResultExpressions.add(resultItem);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
newResult = f;
|
||||||
}
|
}
|
||||||
if (newResults.isEmpty() == false) {
|
if (newResult != null) {
|
||||||
newResultExpressions.add(newResults);
|
newResultExpressions.add(newResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resultExpressions = newResultExpressions;
|
resultExpressions = newResultExpressions;
|
||||||
stop++;
|
stop++;
|
||||||
}
|
}
|
||||||
|
Utils.out.println(2, "INPUT: "+expr);
|
||||||
|
for (Function rr : resultExpressions) {
|
||||||
|
Utils.out.println(1, "RESULT: " + rr.toString());
|
||||||
|
}
|
||||||
ObjectArrayList<ObjectArrayList<Block>> resultBlocks = MathParser.parseOutput(calc, resultExpressions);
|
ObjectArrayList<ObjectArrayList<Block>> resultBlocks = MathParser.parseOutput(calc, resultExpressions);
|
||||||
result.setContentAsMultipleGroups(resultBlocks);
|
result.setContentAsMultipleGroups(resultBlocks);
|
||||||
// showVariablesDialog(() -> {
|
// showVariablesDialog(() -> {
|
||||||
@ -372,18 +374,14 @@ public class MathInputScreen extends Screen {
|
|||||||
userInput.clear();
|
userInput.clear();
|
||||||
result.clear();
|
result.clear();
|
||||||
if (DisplayManager.error != null) {
|
if (DisplayManager.error != null) {
|
||||||
Utils.debug.println("Resetting after error...");
|
Utils.out.println(1, "Resetting after error...");
|
||||||
DisplayManager.error = null;
|
DisplayManager.error = null;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
case SURD_MODE:
|
case SURD_MODE:
|
||||||
calc.exactMode = !calc.exactMode;
|
calc.exactMode = !calc.exactMode;
|
||||||
if (calc.exactMode == false) {
|
result.clear();
|
||||||
calc.f2 = solveExpression(calc.f2);
|
Keyboard.keyPressed(Key.SIMPLIFY);
|
||||||
} else {
|
|
||||||
result.clear();
|
|
||||||
Keyboard.keyPressed(Key.SIMPLIFY);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
case debug1:
|
case debug1:
|
||||||
DisplayManager.INSTANCE.setScreen(new EmptyScreen());
|
DisplayManager.INSTANCE.setScreen(new EmptyScreen());
|
||||||
@ -442,7 +440,11 @@ public class MathInputScreen extends Screen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@Deprecated
|
||||||
private ObjectArrayList<Function> solveExpression(ObjectArrayList<Function> f22) {
|
private ObjectArrayList<Function> solveExpression(ObjectArrayList<Function> f22) {
|
||||||
|
return null;
|
||||||
|
/*
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
return calc.solveExpression(f22);
|
return calc.solveExpression(f22);
|
||||||
@ -461,9 +463,12 @@ public class MathInputScreen extends Screen {
|
|||||||
System.err.println(e.id);
|
System.err.println(e.id);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
protected void step() {
|
protected void step() {
|
||||||
|
/*
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
showVariablesDialog();
|
showVariablesDialog();
|
||||||
@ -499,7 +504,7 @@ public class MathInputScreen extends Screen {
|
|||||||
results.addAll(hs);
|
results.addAll(hs);
|
||||||
calc.f2 = results;
|
calc.f2 = results;
|
||||||
}
|
}
|
||||||
Utils.debug.println(calc.f2.toString());
|
Utils.out.println(1, calc.f2.toString());
|
||||||
} catch (final Exception ex) {
|
} catch (final Exception ex) {
|
||||||
if (Utils.debugOn) {
|
if (Utils.debugOn) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
@ -514,9 +519,12 @@ public class MathInputScreen extends Screen {
|
|||||||
DisplayManager.error = e.id.toString();
|
DisplayManager.error = e.id.toString();
|
||||||
System.err.println(e.id);
|
System.err.println(e.id);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
protected void simplify() {
|
protected void simplify() {
|
||||||
|
/*
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
for (final Function f : calc.f) {
|
for (final Function f : calc.f) {
|
||||||
@ -553,6 +561,7 @@ public class MathInputScreen extends Screen {
|
|||||||
DisplayManager.error = e.id.toString();
|
DisplayManager.error = e.id.toString();
|
||||||
System.err.println(e.id);
|
System.err.println(e.id);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@ -610,7 +619,7 @@ public class MathInputScreen extends Screen {
|
|||||||
DisplayManager.INSTANCE.setScreen(cvs);
|
DisplayManager.INSTANCE.setScreen(cvs);
|
||||||
try {
|
try {
|
||||||
while (DisplayManager.screen == cvs) {
|
while (DisplayManager.screen == cvs) {
|
||||||
Utils.debug.println(Thread.currentThread().getName());
|
Utils.out.println(1, Thread.currentThread().getName());
|
||||||
Thread.sleep(200);
|
Thread.sleep(200);
|
||||||
}
|
}
|
||||||
} catch (final InterruptedException e) {}
|
} catch (final InterruptedException e) {}
|
||||||
|
@ -177,4 +177,9 @@ public abstract class FunctionOperator implements Function {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract boolean equals(Object o);
|
public abstract boolean equals(Object o);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName()+"("+this.getParameter1()+","+this.getParameter2()+")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,17 @@ public abstract class FunctionSingle implements Function {
|
|||||||
parameter = value;
|
parameter = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of FunctionSingle.
|
||||||
|
*
|
||||||
|
* @param mathContext
|
||||||
|
* Math Context
|
||||||
|
*/
|
||||||
|
public FunctionSingle(MathContext mathContext) {
|
||||||
|
this.mathContext = mathContext;
|
||||||
|
parameter = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of FunctionSingle.
|
* Create a new instance of FunctionSingle.
|
||||||
*
|
*
|
||||||
|
@ -30,7 +30,10 @@ public class MathContext {
|
|||||||
resultsCount = 0;
|
resultsCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public Function parseString(String string) throws Error {
|
public Function parseString(String string) throws Error {
|
||||||
|
return null;
|
||||||
|
/*
|
||||||
if (string.contains("{")) {
|
if (string.contains("{")) {
|
||||||
if (!string.startsWith("{")) {
|
if (!string.startsWith("{")) {
|
||||||
throw new Error(Errors.SYNTAX_ERROR);
|
throw new Error(Errors.SYNTAX_ERROR);
|
||||||
@ -46,9 +49,13 @@ public class MathContext {
|
|||||||
} else {
|
} else {
|
||||||
return new Expression(this, string);
|
return new Expression(this, string);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public Function parseEquationString(String string) throws Error {
|
public Function parseEquationString(String string) throws Error {
|
||||||
|
return null;
|
||||||
|
/*
|
||||||
final String[] parts = string.split("=");
|
final String[] parts = string.split("=");
|
||||||
if (parts.length == 1) {
|
if (parts.length == 1) {
|
||||||
return new Equation(this, new Expression(this, parts[0]), new Number(this, BigInteger.ZERO));
|
return new Equation(this, new Expression(this, parts[0]), new Number(this, BigInteger.ZERO));
|
||||||
@ -56,10 +63,13 @@ public class MathContext {
|
|||||||
return new Equation(this, new Expression(this, parts[0]), new Expression(this, parts[1]));
|
return new Equation(this, new Expression(this, parts[0]), new Expression(this, parts[1]));
|
||||||
} else {
|
} else {
|
||||||
throw new Error(Errors.SYNTAX_ERROR);
|
throw new Error(Errors.SYNTAX_ERROR);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public ObjectArrayList<Function> solveExpression(ObjectArrayList<Function> input) throws Error {
|
public ObjectArrayList<Function> solveExpression(ObjectArrayList<Function> input) throws Error {
|
||||||
|
return null;
|
||||||
|
/*
|
||||||
ObjectArrayList<Function> results = new ObjectArrayList<>();
|
ObjectArrayList<Function> results = new ObjectArrayList<>();
|
||||||
final ObjectArrayList<Function> partialResults = new ObjectArrayList<>();
|
final ObjectArrayList<Function> partialResults = new ObjectArrayList<>();
|
||||||
for (final Function f : input) {
|
for (final Function f : input) {
|
||||||
@ -87,6 +97,7 @@ public class MathContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public Function getChild() {
|
public Function getChild() {
|
||||||
|
@ -29,28 +29,29 @@ import org.warp.picalculator.math.functions.trigonometry.Tangent;
|
|||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
|
||||||
public class Expression extends FunctionDynamic {
|
public class Expression extends FunctionSingle {
|
||||||
|
|
||||||
public Expression(MathContext root) {
|
public Expression(MathContext root) {
|
||||||
super(root);
|
super(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Expression(MathContext root, Function[] values) {
|
|
||||||
super(root, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Expression(MathContext root, Function value) {
|
public Expression(MathContext root, Function value) {
|
||||||
super(root, new Function[] { value });
|
super(root, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean initialParenthesis = false;
|
private boolean initialParenthesis = false;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public Expression(MathContext root, String string) throws Error {
|
public Expression(MathContext root, String string) throws Error {
|
||||||
this(root, string, "", true);
|
this(root, string, "", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public Expression(MathContext root, String string, String debugSpaces, boolean initialParenthesis) throws Error {
|
public Expression(MathContext root, String string, String debugSpaces, boolean initialParenthesis) throws Error {
|
||||||
super(root);
|
super(root);
|
||||||
|
|
||||||
|
/*
|
||||||
|
super(root);
|
||||||
this.initialParenthesis = initialParenthesis;
|
this.initialParenthesis = initialParenthesis;
|
||||||
boolean isNumber = false;
|
boolean isNumber = false;
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ public class Expression extends FunctionDynamic {
|
|||||||
// If the expression is already a number:
|
// If the expression is already a number:
|
||||||
// Se l'espressione è già un numero:
|
// Se l'espressione è già un numero:
|
||||||
final Number t = new Number(root, string);
|
final Number t = new Number(root, string);
|
||||||
functions = new Function[] { t };
|
parameter = t;
|
||||||
Utils.debug.println(debugSpaces + "•Result:" + t.toString());
|
Utils.debug.println(debugSpaces + "•Result:" + t.toString());
|
||||||
} else {
|
} else {
|
||||||
// Else prepare the expression:
|
// Else prepare the expression:
|
||||||
@ -223,7 +224,7 @@ public class Expression extends FunctionDynamic {
|
|||||||
|
|
||||||
// Convert the expression to a list of objects
|
// Convert the expression to a list of objects
|
||||||
Expression imputRawParenthesis = new Expression(root);
|
Expression imputRawParenthesis = new Expression(root);
|
||||||
imputRawParenthesis = (Expression) imputRawParenthesis.setParameters(new Function[] {});
|
imputRawParenthesis = (Expression) imputRawParenthesis.setParameter(null);
|
||||||
String tmp = "";
|
String tmp = "";
|
||||||
final char[] functions = concat(concat(concat(concat(MathematicalSymbols.functions, MathematicalSymbols.parentheses), MathematicalSymbols.signums(true)), MathematicalSymbols.variables), MathematicalSymbols.genericSyntax);
|
final char[] functions = concat(concat(concat(concat(MathematicalSymbols.functions, MathematicalSymbols.parentheses), MathematicalSymbols.signums(true)), MathematicalSymbols.variables), MathematicalSymbols.genericSyntax);
|
||||||
for (int i = 0; i < processExpression.length(); i++) {
|
for (int i = 0; i < processExpression.length(); i++) {
|
||||||
@ -555,48 +556,32 @@ public class Expression extends FunctionDynamic {
|
|||||||
final String result = toString();
|
final String result = toString();
|
||||||
Utils.debug.println(debugSpaces + "•Result:" + result);
|
Utils.debug.println(debugSpaces + "•Result:" + result);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isSolvable() {
|
protected boolean isSolvable() {
|
||||||
if (getParametersLength() > 1) {
|
final Function f = getParameter();
|
||||||
|
if (f.isSimplified() == false) {
|
||||||
return true;
|
return true;
|
||||||
} else if (getParametersLength() == 1) {
|
} else {
|
||||||
final Function f = getParameter(0);
|
return !parenthesisNeeded();
|
||||||
if (f.isSimplified() == false) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return !parenthesisNeeded();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectArrayList<Function> solve() throws Error {
|
public ObjectArrayList<Function> solve() throws Error {
|
||||||
final ObjectArrayList<Function> ret = new ObjectArrayList<>();
|
final ObjectArrayList<Function> ret = new ObjectArrayList<>();
|
||||||
if (getParametersLength() == 1) {
|
if (getParameter().isSimplified() || !parenthesisNeeded()) {
|
||||||
if (getParameter(0).isSimplified() || !parenthesisNeeded()) {
|
ret.add(getParameter());
|
||||||
ret.add(getParameter(0));
|
return ret;
|
||||||
return ret;
|
|
||||||
} else {
|
|
||||||
final List<Function> l = getParameter(0).simplify();
|
|
||||||
for (final Function f : l) {
|
|
||||||
if (f instanceof Number || f instanceof Variable) {
|
|
||||||
ret.add(f);
|
|
||||||
} else {
|
|
||||||
ret.add(new Expression(root, new Function[] { f }));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (final Function f : getParameters()) {
|
final List<Function> l = getParameter().simplify();
|
||||||
if (f.isSimplified() == false) {
|
for (final Function f : l) {
|
||||||
final List<Function> partial = f.simplify();
|
if (f instanceof Number || f instanceof Variable) {
|
||||||
for (final Function fnc : partial) {
|
ret.add(f);
|
||||||
ret.add(new Expression(root, new Function[] { fnc }));
|
} else {
|
||||||
}
|
ret.add(new Expression(mathContext, f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -608,20 +593,18 @@ public class Expression extends FunctionDynamic {
|
|||||||
if (initialParenthesis) {
|
if (initialParenthesis) {
|
||||||
parenthesisneeded = false;
|
parenthesisneeded = false;
|
||||||
} else {
|
} else {
|
||||||
if (getParametersLength() == 1) {
|
final Function f = getParameter(0);
|
||||||
final Function f = getParameter(0);
|
if (f instanceof Number || f instanceof Variable || f instanceof Expression || f instanceof Division || f instanceof Joke || f instanceof Undefined || f instanceof Power || f instanceof Sine || f instanceof Cosine || f instanceof Tangent || f instanceof ArcSine || f instanceof ArcCosine || f instanceof ArcTangent || f instanceof RootSquare) {
|
||||||
if (f instanceof Number || f instanceof Variable || f instanceof Expression || f instanceof Division || f instanceof Joke || f instanceof Undefined || f instanceof Power || f instanceof Sine || f instanceof Cosine || f instanceof Tangent || f instanceof ArcSine || f instanceof ArcCosine || f instanceof ArcTangent || f instanceof RootSquare) {
|
parenthesisneeded = false;
|
||||||
|
}
|
||||||
|
if (f instanceof Multiplication) {
|
||||||
|
if (((Multiplication) f).getParameter1() instanceof Number) {
|
||||||
|
parenthesisneeded = !(((Multiplication) f).getParameter2() instanceof Variable);
|
||||||
|
} else if (((Multiplication) f).getParameter2() instanceof Number) {
|
||||||
|
parenthesisneeded = !(((Multiplication) f).getParameter1() instanceof Variable);
|
||||||
|
} else if (((Multiplication) f).getParameter1() instanceof Variable || ((Multiplication) f).getParameter2() instanceof Variable) {
|
||||||
parenthesisneeded = false;
|
parenthesisneeded = false;
|
||||||
}
|
}
|
||||||
if (f instanceof Multiplication) {
|
|
||||||
if (((Multiplication) f).getParameter1() instanceof Number) {
|
|
||||||
parenthesisneeded = !(((Multiplication) f).getParameter2() instanceof Variable);
|
|
||||||
} else if (((Multiplication) f).getParameter2() instanceof Number) {
|
|
||||||
parenthesisneeded = !(((Multiplication) f).getParameter1() instanceof Variable);
|
|
||||||
} else if (((Multiplication) f).getParameter1() instanceof Variable || ((Multiplication) f).getParameter2() instanceof Variable) {
|
|
||||||
parenthesisneeded = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return parenthesisneeded;
|
return parenthesisneeded;
|
||||||
@ -645,46 +628,29 @@ public class Expression extends FunctionDynamic {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String s = "(";
|
String s = "(";
|
||||||
if (functions.length > 0) {
|
if (parameter == null) {
|
||||||
for (final Function f : functions) {
|
s += "null";
|
||||||
if (f == null) {
|
} else {
|
||||||
s += "[null],";
|
s += parameter.toString();
|
||||||
} else {
|
|
||||||
s += f.toString() + ",";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s = s.substring(0, s.length() - 1);
|
|
||||||
}
|
}
|
||||||
|
s = s.substring(0, s.length() - 1);
|
||||||
s += ")";
|
s += ")";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o instanceof Expression) {
|
if (parameter == null | o == null) {
|
||||||
final Expression f = (Expression) o;
|
return parameter == o;
|
||||||
final Function[] exprFuncs1 = getParameters();
|
} else {
|
||||||
final Function[] exprFuncs2 = f.getParameters();
|
|
||||||
if (exprFuncs1.length == exprFuncs2.length) {
|
|
||||||
for (int i = 0; i < exprFuncs1.length; i++) {
|
|
||||||
if (exprFuncs1[i].equals(exprFuncs2[i]) == false) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else if (o != null & getParametersLength() == 1) {
|
|
||||||
final Function f = (Function) o;
|
final Function f = (Function) o;
|
||||||
return (getParameter(0).equals(f));
|
return (getParameter(0).equals(f));
|
||||||
} else if (o == null & getParametersLength() == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expression clone() {
|
public Expression clone() {
|
||||||
return new Expression(root, functions);
|
return new Expression(mathContext, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -105,11 +105,6 @@ public class Multiplication extends FunctionOperator {
|
|||||||
return new Multiplication(mathContext, parameter1, parameter2);
|
return new Multiplication(mathContext, parameter1, parameter2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "(" + parameter1.toString() + ")*(" + parameter2.toString() + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectArrayList<Block> toBlock(MathContext context) throws Error {
|
public ObjectArrayList<Block> toBlock(MathContext context) throws Error {
|
||||||
ObjectArrayList<Block> result = new ObjectArrayList<>();
|
ObjectArrayList<Block> result = new ObjectArrayList<>();
|
||||||
|
@ -48,7 +48,7 @@ public class EquationsSystem extends FunctionDynamic {
|
|||||||
if (f instanceof Number) {
|
if (f instanceof Number) {
|
||||||
ret.add(f);
|
ret.add(f);
|
||||||
} else {
|
} else {
|
||||||
ret.add(new Expression(root, new Function[] { f }));
|
ret.add(new Expression(root, f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -58,7 +58,7 @@ public class EquationsSystem extends FunctionDynamic {
|
|||||||
if (f.isSimplified() == false) {
|
if (f.isSimplified() == false) {
|
||||||
final List<Function> partial = f.simplify();
|
final List<Function> partial = f.simplify();
|
||||||
for (final Function fnc : partial) {
|
for (final Function fnc : partial) {
|
||||||
ret.add(new Expression(root, new Function[] { fnc }));
|
ret.add(new Expression(root, fnc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,48 +2,27 @@ package org.warp.picalculator.math.parser;
|
|||||||
|
|
||||||
import org.warp.picalculator.Error;
|
import org.warp.picalculator.Error;
|
||||||
import org.warp.picalculator.Errors;
|
import org.warp.picalculator.Errors;
|
||||||
|
import org.warp.picalculator.IntegerObj;
|
||||||
|
import org.warp.picalculator.Utils;
|
||||||
import org.warp.picalculator.gui.expression.blocks.Block;
|
import org.warp.picalculator.gui.expression.blocks.Block;
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockChar;
|
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockContainer;
|
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockDivision;
|
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockExponentialNotation;
|
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockParenthesis;
|
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockPower;
|
|
||||||
import org.warp.picalculator.gui.expression.blocks.BlockSquareRoot;
|
|
||||||
import org.warp.picalculator.gui.expression.containers.InputContainer;
|
import org.warp.picalculator.gui.expression.containers.InputContainer;
|
||||||
import org.warp.picalculator.math.Function;
|
import org.warp.picalculator.math.Function;
|
||||||
import org.warp.picalculator.math.FunctionOperator;
|
|
||||||
import org.warp.picalculator.math.FunctionSingle;
|
|
||||||
import org.warp.picalculator.math.MathContext;
|
import org.warp.picalculator.math.MathContext;
|
||||||
import org.warp.picalculator.math.MathematicalSymbols;
|
import org.warp.picalculator.math.MathematicalSymbols;
|
||||||
import org.warp.picalculator.math.functions.Division;
|
|
||||||
import org.warp.picalculator.math.functions.Expression;
|
import org.warp.picalculator.math.functions.Expression;
|
||||||
import org.warp.picalculator.math.functions.Multiplication;
|
|
||||||
import org.warp.picalculator.math.functions.Number;
|
|
||||||
import org.warp.picalculator.math.functions.Power;
|
|
||||||
import org.warp.picalculator.math.functions.RootSquare;
|
|
||||||
import org.warp.picalculator.math.functions.Subtraction;
|
|
||||||
import org.warp.picalculator.math.functions.Sum;
|
|
||||||
import org.warp.picalculator.math.functions.SumSubtraction;
|
|
||||||
import org.warp.picalculator.math.functions.Variable;
|
|
||||||
import org.warp.picalculator.math.functions.Variable.V_TYPE;
|
import org.warp.picalculator.math.functions.Variable.V_TYPE;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureChar;
|
import org.warp.picalculator.math.parser.features.FeatureChar;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureDivision;
|
|
||||||
import org.warp.picalculator.math.parser.features.FeatureMultiplication;
|
import org.warp.picalculator.math.parser.features.FeatureMultiplication;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureNumber;
|
import org.warp.picalculator.math.parser.features.FeatureNumber;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureParenthesis;
|
|
||||||
import org.warp.picalculator.math.parser.features.FeaturePowerChar;
|
|
||||||
import org.warp.picalculator.math.parser.features.FeatureSquareRoot;
|
|
||||||
import org.warp.picalculator.math.parser.features.FeatureSum;
|
import org.warp.picalculator.math.parser.features.FeatureSum;
|
||||||
import org.warp.picalculator.math.parser.features.FeatureVariable;
|
import org.warp.picalculator.math.parser.features.FeatureVariable;
|
||||||
import org.warp.picalculator.math.parser.features.interfaces.Feature;
|
import org.warp.picalculator.math.parser.features.interfaces.Feature;
|
||||||
import org.warp.picalculator.math.parser.features.interfaces.FeatureDouble;
|
import org.warp.picalculator.math.parser.steps.JoinNumberAndVariables;
|
||||||
import org.warp.picalculator.math.parser.features.interfaces.FeatureSingle;
|
import org.warp.picalculator.math.parser.steps.FixMultiplicationsAndDivisions;
|
||||||
|
import org.warp.picalculator.math.parser.steps.FixSingleFunctionArgs;
|
||||||
import com.sun.org.apache.xpath.internal.functions.Function2Args;
|
import org.warp.picalculator.math.parser.steps.FixSumsAndSubtractions;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
|
|
||||||
|
|
||||||
public class MathParser {
|
public class MathParser {
|
||||||
public static Expression parseInput(MathContext context, InputContainer c) throws Error {
|
public static Expression parseInput(MathContext context, InputContainer c) throws Error {
|
||||||
@ -55,15 +34,11 @@ public class MathParser {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ObjectArrayList<ObjectArrayList<Block>> parseOutput(MathContext context, ObjectArrayList<ObjectArrayList<Function>> resultExpressions) throws Error {
|
public static ObjectArrayList<ObjectArrayList<Block>> parseOutput(MathContext context, ObjectArrayList<Function> resultExpressions) throws Error {
|
||||||
final ObjectArrayList<ObjectArrayList<Block>> result = new ObjectArrayList<>();
|
final ObjectArrayList<ObjectArrayList<Block>> result = new ObjectArrayList<>();
|
||||||
for (ObjectArrayList<Function> resultExpression : resultExpressions) {
|
for (Function resultExpression : resultExpressions) {
|
||||||
final ObjectArrayList<Block> resultBlocks = new ObjectArrayList<>();
|
ObjectArrayList<Block> resultBlocks = resultExpression.toBlock(context);
|
||||||
for (Function f : resultExpression) {
|
if (resultBlocks == null) throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + resultExpression.getClass().getSimpleName());
|
||||||
ObjectArrayList<Block> resultPart = f.toBlock(context);
|
|
||||||
if (resultPart == null) throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + f.getClass().getSimpleName());
|
|
||||||
resultBlocks.addAll(resultPart);
|
|
||||||
}
|
|
||||||
result.add(resultBlocks);
|
result.add(resultBlocks);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -73,7 +48,7 @@ public class MathParser {
|
|||||||
|
|
||||||
features = fixFeatures(context, features);
|
features = fixFeatures(context, features);
|
||||||
|
|
||||||
final ObjectArrayList<Function> process = new ObjectArrayList<>();
|
ObjectArrayList<Function> process = new ObjectArrayList<>();
|
||||||
|
|
||||||
for (final Feature f : features) {
|
for (final Feature f : features) {
|
||||||
Function fnc = f.toFunction(context);
|
Function fnc = f.toFunction(context);
|
||||||
@ -81,7 +56,7 @@ public class MathParser {
|
|||||||
process.add(fnc);
|
process.add(fnc);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixStack(context, process);
|
process = fixStack(context, process);
|
||||||
|
|
||||||
if (process.size() > 1) {
|
if (process.size() > 1) {
|
||||||
throw new Error(Errors.UNBALANCED_STACK, "The stack is unbalanced. Not all the functions are nested correctly");
|
throw new Error(Errors.UNBALANCED_STACK, "The stack is unbalanced. Not all the functions are nested correctly");
|
||||||
@ -90,119 +65,55 @@ public class MathParser {
|
|||||||
return process.get(0);
|
return process.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void fixStack(MathContext context, ObjectArrayList<Function> process) throws Error {
|
private static ObjectArrayList<Function> fixStack(MathContext context, ObjectArrayList<Function> functionsList) throws Error {
|
||||||
|
final MathParserStep[] steps = new MathParserStep[] {
|
||||||
|
new JoinNumberAndVariables(context),
|
||||||
|
new FixSingleFunctionArgs(),
|
||||||
|
new FixMultiplicationsAndDivisions(),
|
||||||
|
new FixSumsAndSubtractions(),
|
||||||
|
};
|
||||||
boolean lastLoopDidSomething;
|
boolean lastLoopDidSomething;
|
||||||
|
Function lastElement;
|
||||||
|
|
||||||
ObjectListIterator<Function> stackIterator;
|
for (MathParserStep step : steps) {
|
||||||
|
Utils.out.println(2, "Stack fixing step \""+step.getStepName()+"\"");
|
||||||
|
int stepQty = step.requiresReversedIteration()?-1:1, initialIndex = step.requiresReversedIteration()?functionsList.size()-1:0;
|
||||||
|
do {
|
||||||
|
lastLoopDidSomething = false;
|
||||||
|
lastElement = null;
|
||||||
|
IntegerObj curIndex = new IntegerObj(initialIndex);
|
||||||
|
while(curIndex.i >= 0 && curIndex.i < functionsList.size()) {
|
||||||
|
final Function f = functionsList.get(curIndex.i);
|
||||||
|
|
||||||
|
if (step.eval(curIndex, lastElement, f, functionsList)) {
|
||||||
|
lastLoopDidSomething = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastElement=f;
|
||||||
|
curIndex.i+=stepQty;
|
||||||
|
}
|
||||||
|
} while (lastLoopDidSomething);
|
||||||
|
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, "\tStatus: ");
|
||||||
|
for (Function f : functionsList) {
|
||||||
|
Utils.out.print(Utils.OUTPUTLEVEL_DEBUG_MAX, f.toString());
|
||||||
|
}
|
||||||
|
Utils.out.println(Utils.OUTPUTLEVEL_DEBUG_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
//Phase 0: join number and variables ([2][x] => [[2]*[x]])
|
// //Phase 4
|
||||||
do {
|
// do {
|
||||||
lastLoopDidSomething = false;
|
// lastLoopDidSomething = false;
|
||||||
stackIterator = process.listIterator(process.size());
|
// functionListIterator = functionsList.iterator();
|
||||||
Function lastElement = null;
|
// while (functionListIterator.hasNext()) {
|
||||||
while (stackIterator.hasPrevious()) {
|
// final Function f = functionListIterator.next();
|
||||||
final Function f = stackIterator.previous();
|
//
|
||||||
final int curIndex = stackIterator.nextIndex();
|
// if (f instanceof Function2Args) {
|
||||||
|
//
|
||||||
if (f instanceof Number | f instanceof Variable) {
|
// }
|
||||||
if (lastElement instanceof Variable) {
|
// }
|
||||||
lastLoopDidSomething = true;
|
// } while (lastLoopDidSomething);
|
||||||
final Function var = process.get(curIndex + 1);
|
|
||||||
final Function numb = process.get(curIndex);
|
|
||||||
stackIterator.set(new Multiplication(context, numb, var));
|
|
||||||
process.remove(curIndex + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastElement = f;
|
|
||||||
}
|
|
||||||
} while (lastLoopDidSomething);
|
|
||||||
|
|
||||||
//Phase 1
|
return functionsList;
|
||||||
do {
|
|
||||||
lastLoopDidSomething = false;
|
|
||||||
stackIterator = process.listIterator(process.size());
|
|
||||||
Function lastElement = null;
|
|
||||||
while (stackIterator.hasPrevious()) {
|
|
||||||
final Function f = stackIterator.previous();
|
|
||||||
|
|
||||||
if (f instanceof FunctionSingle) {
|
|
||||||
if (((FunctionSingle) f).getParameter() == null) {
|
|
||||||
lastLoopDidSomething = true;
|
|
||||||
if (lastElement == null) {
|
|
||||||
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
|
|
||||||
} else {
|
|
||||||
((FunctionSingle) f).setParameter(lastElement);
|
|
||||||
process.remove(stackIterator.nextIndex());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastElement = f;
|
|
||||||
}
|
|
||||||
} while (lastLoopDidSomething);
|
|
||||||
|
|
||||||
//Phase 2
|
|
||||||
do {
|
|
||||||
lastLoopDidSomething = false;
|
|
||||||
stackIterator = process.listIterator();
|
|
||||||
while (stackIterator.hasNext()) {
|
|
||||||
final Function f = stackIterator.next();
|
|
||||||
final int curIndex = stackIterator.previousIndex();
|
|
||||||
|
|
||||||
if (f instanceof Multiplication || f instanceof Division) {
|
|
||||||
if (curIndex - 1 >= 0 && stackIterator.hasNext()) {
|
|
||||||
lastLoopDidSomething = true;
|
|
||||||
final Function next = process.get(curIndex + 1);
|
|
||||||
final Function prev = process.get(curIndex - 1);
|
|
||||||
stackIterator.set(f.setParameter(0, prev).setParameter(1, next));
|
|
||||||
process.remove(curIndex + 1);
|
|
||||||
process.remove(curIndex - 1);
|
|
||||||
} else {
|
|
||||||
if (f.getParameter(0) == null || f.getParameter(1) == null) {
|
|
||||||
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (lastLoopDidSomething);
|
|
||||||
|
|
||||||
//Phase 3
|
|
||||||
do {
|
|
||||||
lastLoopDidSomething = false;
|
|
||||||
stackIterator = process.listIterator();
|
|
||||||
while (stackIterator.hasNext()) {
|
|
||||||
final Function f = stackIterator.next();
|
|
||||||
final int curIndex = stackIterator.previousIndex();
|
|
||||||
|
|
||||||
if (f instanceof Sum || f instanceof Subtraction || f instanceof SumSubtraction) {
|
|
||||||
if (curIndex - 1 >= 0 && stackIterator.hasNext()) {
|
|
||||||
lastLoopDidSomething = true;
|
|
||||||
final Function next = process.get(curIndex + 1);
|
|
||||||
final Function prev = process.get(curIndex - 1);
|
|
||||||
stackIterator.set(f.setParameter(0, prev).setParameter(1, next));
|
|
||||||
process.remove(curIndex + 1);
|
|
||||||
process.remove(curIndex - 1);
|
|
||||||
} else {
|
|
||||||
if (f.getParameter(0) == null || f.getParameter(1) == null) {
|
|
||||||
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (lastLoopDidSomething);
|
|
||||||
|
|
||||||
//Phase 4
|
|
||||||
do {
|
|
||||||
lastLoopDidSomething = false;
|
|
||||||
stackIterator = process.iterator();
|
|
||||||
while (stackIterator.hasNext()) {
|
|
||||||
final Function f = stackIterator.next();
|
|
||||||
|
|
||||||
if (f instanceof Function2Args) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (lastLoopDidSomething);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ObjectArrayList<Feature> fixFeatures(final MathContext context, ObjectArrayList<Feature> features)
|
private static ObjectArrayList<Feature> fixFeatures(final MathContext context, ObjectArrayList<Feature> features)
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package org.warp.picalculator.math.parser;
|
||||||
|
|
||||||
|
import org.warp.picalculator.Error;
|
||||||
|
import org.warp.picalculator.IntegerObj;
|
||||||
|
import org.warp.picalculator.math.Function;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Join number and variables together ([2][4][x] => [[24]*[x]])
|
||||||
|
* @author Andrea Cavalli
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface MathParserStep {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param f
|
||||||
|
* @param curIndex
|
||||||
|
* @param process
|
||||||
|
* @return true if something changed
|
||||||
|
*/
|
||||||
|
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList<Function> functionsfunctionsList) throws Error;
|
||||||
|
|
||||||
|
public boolean requiresReversedIteration();
|
||||||
|
|
||||||
|
public String getStepName();
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package org.warp.picalculator.math.parser.steps;
|
||||||
|
|
||||||
|
import org.warp.picalculator.Error;
|
||||||
|
import org.warp.picalculator.Errors;
|
||||||
|
import org.warp.picalculator.IntegerObj;
|
||||||
|
import org.warp.picalculator.math.Function;
|
||||||
|
import org.warp.picalculator.math.functions.Division;
|
||||||
|
import org.warp.picalculator.math.functions.Multiplication;
|
||||||
|
import org.warp.picalculator.math.parser.MathParserStep;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
|
||||||
|
public class FixMultiplicationsAndDivisions implements MathParserStep {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction,
|
||||||
|
ObjectArrayList<Function> functionsList) throws Error {
|
||||||
|
if (currentFunction instanceof Multiplication || currentFunction instanceof Division) {
|
||||||
|
if (currentFunction.getParameter(0) == null && currentFunction.getParameter(1) == null) {
|
||||||
|
if (curIndex.i - 1 >= 0 && curIndex.i + 1 < functionsList.size()) {
|
||||||
|
final Function next = functionsList.get(curIndex.i + 1);
|
||||||
|
final Function prev = functionsList.get(curIndex.i - 1);
|
||||||
|
functionsList.set(curIndex.i, currentFunction.setParameter(0, prev).setParameter(1, next));
|
||||||
|
functionsList.remove(curIndex.i + 1);
|
||||||
|
functionsList.remove(curIndex.i - 1);
|
||||||
|
curIndex.i--;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (currentFunction.getParameter(0) == null || currentFunction.getParameter(1) == null) {
|
||||||
|
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresReversedIteration() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStepName() {
|
||||||
|
return "Fix Multiplications and Divisions";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package org.warp.picalculator.math.parser.steps;
|
||||||
|
|
||||||
|
import org.warp.picalculator.Error;
|
||||||
|
import org.warp.picalculator.Errors;
|
||||||
|
import org.warp.picalculator.IntegerObj;
|
||||||
|
import org.warp.picalculator.math.Function;
|
||||||
|
import org.warp.picalculator.math.FunctionSingle;
|
||||||
|
import org.warp.picalculator.math.parser.MathParserStep;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts the argument of Single Functions inside them
|
||||||
|
* @author Andrea Cavalli
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FixSingleFunctionArgs implements MathParserStep {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction,
|
||||||
|
ObjectArrayList<Function> functionsList) throws Error {
|
||||||
|
if (currentFunction instanceof FunctionSingle) {
|
||||||
|
if (((FunctionSingle) currentFunction).getParameter() == null) {
|
||||||
|
if (lastFunction == null) {
|
||||||
|
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
|
||||||
|
} else {
|
||||||
|
((FunctionSingle) currentFunction).setParameter(lastFunction);
|
||||||
|
functionsList.remove(curIndex.i+1);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresReversedIteration() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStepName() {
|
||||||
|
return "Fix Single Function Arguments";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package org.warp.picalculator.math.parser.steps;
|
||||||
|
|
||||||
|
import org.warp.picalculator.Error;
|
||||||
|
import org.warp.picalculator.Errors;
|
||||||
|
import org.warp.picalculator.IntegerObj;
|
||||||
|
import org.warp.picalculator.math.Function;
|
||||||
|
import org.warp.picalculator.math.functions.Multiplication;
|
||||||
|
import org.warp.picalculator.math.functions.Subtraction;
|
||||||
|
import org.warp.picalculator.math.functions.Sum;
|
||||||
|
import org.warp.picalculator.math.functions.SumSubtraction;
|
||||||
|
import org.warp.picalculator.math.parser.MathParserStep;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
|
||||||
|
public class FixSumsAndSubtractions implements MathParserStep {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction,
|
||||||
|
ObjectArrayList<Function> functionsList) throws Error {
|
||||||
|
if (currentFunction instanceof Sum || currentFunction instanceof Subtraction || currentFunction instanceof SumSubtraction) {
|
||||||
|
if (currentFunction.getParameter(0) == null && currentFunction.getParameter(1) == null) {
|
||||||
|
if (curIndex.i - 1 >= 0 && curIndex.i + 1 < functionsList.size()) {
|
||||||
|
final Function next = functionsList.get(curIndex.i + 1);
|
||||||
|
final Function prev = functionsList.get(curIndex.i - 1);
|
||||||
|
functionsList.set(curIndex.i, currentFunction.setParameter(0, prev).setParameter(1, next));
|
||||||
|
functionsList.remove(curIndex.i + 1);
|
||||||
|
functionsList.remove(curIndex.i - 1);
|
||||||
|
curIndex.i--;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if (currentFunction.getParameter(0) == null || currentFunction.getParameter(1) == null) {
|
||||||
|
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresReversedIteration() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStepName() {
|
||||||
|
return "Fix Sums and Subtractions";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package org.warp.picalculator.math.parser.steps;
|
||||||
|
|
||||||
|
import org.warp.picalculator.IntegerObj;
|
||||||
|
import org.warp.picalculator.math.Function;
|
||||||
|
import org.warp.picalculator.math.MathContext;
|
||||||
|
import org.warp.picalculator.math.functions.Multiplication;
|
||||||
|
import org.warp.picalculator.math.functions.Number;
|
||||||
|
import org.warp.picalculator.math.functions.Variable;
|
||||||
|
import org.warp.picalculator.math.parser.MathParserStep;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
|
||||||
|
public class JoinNumberAndVariables implements MathParserStep {
|
||||||
|
|
||||||
|
private MathContext context;
|
||||||
|
|
||||||
|
public JoinNumberAndVariables(MathContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean eval(IntegerObj curIndex, Function lastFunction, Function currentFunction, ObjectArrayList<Function> functionsList) {
|
||||||
|
if (currentFunction instanceof Number | currentFunction instanceof Variable) {
|
||||||
|
if (lastFunction instanceof Variable) {
|
||||||
|
final Function var = lastFunction;
|
||||||
|
final Function numb = currentFunction;
|
||||||
|
functionsList.set(curIndex.i, new Multiplication(context, numb, var));
|
||||||
|
functionsList.remove(curIndex.i + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresReversedIteration() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStepName() {
|
||||||
|
return "Join number and variables together";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -27,28 +27,24 @@ public class ExpandRule1 {
|
|||||||
final Negative fnc = (Negative) f;
|
final Negative fnc = (Negative) f;
|
||||||
if (fnc.getParameter() instanceof Expression) {
|
if (fnc.getParameter() instanceof Expression) {
|
||||||
final Expression expr = (Expression) fnc.getParameter();
|
final Expression expr = (Expression) fnc.getParameter();
|
||||||
if (expr.getParametersLength() == 1) {
|
if (expr.getParameter() instanceof Sum) {
|
||||||
if (expr.getParameter(0) instanceof Sum) {
|
return true;
|
||||||
return true;
|
} else if (expr.getParameter() instanceof Subtraction) {
|
||||||
} else if (expr.getParameter(0) instanceof Subtraction) {
|
return true;
|
||||||
return true;
|
} else if (expr.getParameter() instanceof SumSubtraction) {
|
||||||
} else if (expr.getParameter(0) instanceof SumSubtraction) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (f instanceof Subtraction || f instanceof SumSubtraction) {
|
} else if (f instanceof Subtraction || f instanceof SumSubtraction) {
|
||||||
final FunctionOperator fnc = (FunctionOperator) f;
|
final FunctionOperator fnc = (FunctionOperator) f;
|
||||||
if (fnc.getParameter2() instanceof Expression) {
|
if (fnc.getParameter2() instanceof Expression) {
|
||||||
final Expression expr = (Expression) fnc.getParameter2();
|
final Expression expr = (Expression) fnc.getParameter2();
|
||||||
if (expr.getParametersLength() == 1) {
|
if (expr.getParameter() instanceof Sum) {
|
||||||
if (expr.getParameter(0) instanceof Sum) {
|
return true;
|
||||||
return true;
|
} else if (expr.getParameter() instanceof Subtraction) {
|
||||||
} else if (expr.getParameter(0) instanceof Subtraction) {
|
return true;
|
||||||
return true;
|
} else if (expr.getParameter() instanceof SumSubtraction) {
|
||||||
} else if (expr.getParameter(0) instanceof SumSubtraction) {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +73,7 @@ public class ExpandRule1 {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final Function fnc = expr.getParameter(0);
|
final Function fnc = expr.getParameter();
|
||||||
if (fnc instanceof Sum) {
|
if (fnc instanceof Sum) {
|
||||||
final Function a = ((Sum) fnc).getParameter1();
|
final Function a = ((Sum) fnc).getParameter1();
|
||||||
final Function b = ((Sum) fnc).getParameter2();
|
final Function b = ((Sum) fnc).getParameter2();
|
||||||
|
@ -22,13 +22,13 @@ public class ExpandRule5 {
|
|||||||
final Negative fnc = (Negative) f;
|
final Negative fnc = (Negative) f;
|
||||||
if (fnc.getParameter() instanceof Expression) {
|
if (fnc.getParameter() instanceof Expression) {
|
||||||
final Expression e = (Expression) fnc.getParameter();
|
final Expression e = (Expression) fnc.getParameter();
|
||||||
return e.getParametersLength() == 1 && e.getParameter(0) instanceof Negative;
|
return e.getParameter() instanceof Negative;
|
||||||
}
|
}
|
||||||
} else if (f instanceof Subtraction) {
|
} else if (f instanceof Subtraction) {
|
||||||
final Subtraction fnc = (Subtraction) f;
|
final Subtraction fnc = (Subtraction) f;
|
||||||
if (fnc.getParameter2() instanceof Expression) {
|
if (fnc.getParameter2() instanceof Expression) {
|
||||||
final Expression e = (Expression) fnc.getParameter2();
|
final Expression e = (Expression) fnc.getParameter2();
|
||||||
return e.getParametersLength() == 1 && e.getParameter(0) instanceof Negative;
|
return e.getParameter() instanceof Negative;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -39,10 +39,10 @@ public class ExpandRule5 {
|
|||||||
|
|
||||||
if (f instanceof Negative) {
|
if (f instanceof Negative) {
|
||||||
final Negative fnc = (Negative) f;
|
final Negative fnc = (Negative) f;
|
||||||
result.add(((Negative) ((Expression) fnc.getParameter()).getParameter(0)).getParameter());
|
result.add(((Negative) ((Expression) fnc.getParameter()).getParameter()).getParameter());
|
||||||
} else if (f instanceof Subtraction) {
|
} else if (f instanceof Subtraction) {
|
||||||
final Subtraction fnc = (Subtraction) f;
|
final Subtraction fnc = (Subtraction) f;
|
||||||
result.add(((Negative) ((Expression) fnc.getParameter2()).getParameter(0)).getParameter());
|
result.add(((Negative) ((Expression) fnc.getParameter2()).getParameter()).getParameter());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ public class ExponentRule4 {
|
|||||||
|
|
||||||
public static boolean compare(Function f) {
|
public static boolean compare(Function f) {
|
||||||
final Power fnc = (Power) f;
|
final Power fnc = (Power) f;
|
||||||
if (fnc.getParameter1() instanceof Expression && ((Expression) fnc.getParameter1()).getParametersLength() == 1 && ((Expression) fnc.getParameter1()).getParameter(0) instanceof Multiplication && fnc.getParameter2() instanceof Number) {
|
if (fnc.getParameter1() instanceof Expression && ((Expression) fnc.getParameter1()).getParameter() instanceof Multiplication && fnc.getParameter2() instanceof Number) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -32,7 +32,7 @@ public class ExponentRule4 {
|
|||||||
final ObjectArrayList<Function> result = new ObjectArrayList<>();
|
final ObjectArrayList<Function> result = new ObjectArrayList<>();
|
||||||
final Power fnc = (Power) f;
|
final Power fnc = (Power) f;
|
||||||
final Expression expr = (Expression) fnc.getParameter1();
|
final Expression expr = (Expression) fnc.getParameter1();
|
||||||
final Multiplication mult = (Multiplication) expr.getParameter(0);
|
final Multiplication mult = (Multiplication) expr.getParameter();
|
||||||
final Function a = mult.getParameter1();
|
final Function a = mult.getParameter1();
|
||||||
final Function b = mult.getParameter2();
|
final Function b = mult.getParameter2();
|
||||||
final Number n = (Number) fnc.getParameter2();
|
final Number n = (Number) fnc.getParameter2();
|
||||||
|
@ -23,7 +23,7 @@ public class SyntaxRule2 {
|
|||||||
}
|
}
|
||||||
if (f.getParameter2() instanceof Expression) {
|
if (f.getParameter2() instanceof Expression) {
|
||||||
final Expression e = (Expression) f.getParameter2();
|
final Expression e = (Expression) f.getParameter2();
|
||||||
if (e.getParametersLength() == 1 && e.getParameter(0) instanceof Sum) {
|
if (e.getParameter() instanceof Sum) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,8 +39,8 @@ public class SyntaxRule2 {
|
|||||||
b = ((Sum) f.getParameter2()).getParameter1();
|
b = ((Sum) f.getParameter2()).getParameter1();
|
||||||
c = ((Sum) f.getParameter2()).getParameter2();
|
c = ((Sum) f.getParameter2()).getParameter2();
|
||||||
} else {
|
} else {
|
||||||
b = ((Sum) ((Expression) f.getParameter2()).getParameter(0)).getParameter1();
|
b = ((Sum) ((Expression) f.getParameter2()).getParameter()).getParameter1();
|
||||||
c = ((Sum) ((Expression) f.getParameter2()).getParameter(0)).getParameter2();
|
c = ((Sum) ((Expression) f.getParameter2()).getParameter()).getParameter2();
|
||||||
}
|
}
|
||||||
final Sum mIn = new Sum(root, a, b);
|
final Sum mIn = new Sum(root, a, b);
|
||||||
f.setParameter1(mIn);
|
f.setParameter1(mIn);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user