Added new expression blocks, like parentheses and power of x

This commit is contained in:
XDrake99 2017-04-11 22:04:44 +02:00
parent c2df21d682
commit 57fc8cfa44
12 changed files with 424 additions and 76 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

View File

@ -11,29 +11,34 @@ public class BlockContainer implements GraphicalElement {
private static boolean initialized = false; private static boolean initialized = false;
private final int minWidth; private int minWidth;
private final int minHeight; private int minHeight;
private final ObjectArrayList<Block> content; private final ObjectArrayList<Block> content;
private boolean small; private boolean small;
private int width; private int width;
private int height; private int height;
private int line; private int line;
public final boolean withBorder; public final boolean withBorder;
private boolean autoMinimums;
public BlockContainer() { public BlockContainer() {
this(false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true); this(false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
autoMinimums = true;
} }
public BlockContainer(boolean small) { public BlockContainer(boolean small) {
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true); this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true);
autoMinimums = true;
} }
public BlockContainer(boolean small, boolean withBorder) { public BlockContainer(boolean small, boolean withBorder) {
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder); this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
autoMinimums = true;
} }
public BlockContainer(boolean small, int minWidth, int minHeight, boolean withBorder) { public BlockContainer(boolean small, int minWidth, int minHeight, boolean withBorder) {
this(small, minWidth, minHeight, new ObjectArrayList<>(), withBorder); this(small, minWidth, minHeight, new ObjectArrayList<>(), withBorder);
autoMinimums = false;
} }
public BlockContainer(boolean small, int minWidth, int minHeight, ObjectArrayList<Block> content, boolean withBorder) { public BlockContainer(boolean small, int minWidth, int minHeight, ObjectArrayList<Block> content, boolean withBorder) {
@ -111,9 +116,9 @@ public class BlockContainer implements GraphicalElement {
if (caret.getRemaining() == 0) { if (caret.getRemaining() == 0) {
if (content.size() > 0) { if (content.size() > 0) {
BlockContainer.drawCaret(ge, r, caret, x, y + line - content.get(0).line, content.get(0).height); BlockContainer.drawCaret(ge, r, caret, small, x, y + line - content.get(0).line, content.get(0).height);
} else { } else {
BlockContainer.drawCaret(ge, r, caret, x, y, height); BlockContainer.drawCaret(ge, r, caret, small, x, y, height);
} }
} }
@ -128,7 +133,7 @@ public class BlockContainer implements GraphicalElement {
b.draw(ge, r, x + paddingX, y + line - b.line, caret); b.draw(ge, r, x + paddingX, y + line - b.line, caret);
paddingX += b.getWidth(); paddingX += b.getWidth();
if (caret.getRemaining() == 0) { if (caret.getRemaining() == 0) {
BlockContainer.drawCaret(ge, r, caret, x + paddingX, y + line - b.line, b.height); BlockContainer.drawCaret(ge, r, caret, small, x + paddingX, y + line - b.line, b.height);
} }
paddingX += 1; paddingX += 1;
} }
@ -271,17 +276,22 @@ public class BlockContainer implements GraphicalElement {
return defFontSizes[b ? 3 : 1]; return defFontSizes[b ? 3 : 1];
} }
public static void drawCaret(GraphicEngine ge, Renderer r, Caret caret, int x, int y, int height) { public static void drawCaret(GraphicEngine ge, Renderer r, Caret caret, boolean small, int x, int y, int height) {
if (caret.getState() == CaretState.VISIBLE_ON) { if (caret.getState() == CaretState.VISIBLE_ON) {
r.glColor(getDefaultColor()); r.glColor(getDefaultColor());
r.glDrawLine(x, y, x, y - 1 + height); r.glFillColor(x, y, small?2:3, height);
r.glDrawLine(x + 1, y, x + 1, y - 1 + height);
r.glDrawLine(x + 2, y, x + 2, y - 1 + height);
} }
} }
public void setSmall(boolean small) { public void setSmall(boolean small) {
this.small = small; this.small = small;
if (this.autoMinimums) {
this.minWidth = BlockContainer.getDefaultCharWidth(small);
this.minHeight = BlockContainer.getDefaultCharHeight(small);
}
for (Block b : this.content) {
b.setSmall(small);
}
recomputeDimensions(); recomputeDimensions();
} }

View File

@ -0,0 +1,8 @@
package org.warp.picalculator.gui.expression;
public class BlockExponentialNotation extends BlockPower {
@Override
protected int getSpacing() {
return -3;
}
}

View File

@ -1,5 +1,6 @@
package org.warp.picalculator.gui.expression; package org.warp.picalculator.gui.expression;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
@ -9,6 +10,9 @@ public class BlockParenthesis extends Block {
private final BlockContainer containerNumber; private final BlockContainer containerNumber;
private int chw;
private int chh;
public BlockParenthesis() { public BlockParenthesis() {
containerNumber = new BlockContainer(false); containerNumber = new BlockContainer(false);
recomputeDimensions(); recomputeDimensions();
@ -18,7 +22,13 @@ public class BlockParenthesis extends Block {
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) { public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge); BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor()); r.glColor(BlockContainer.getDefaultColor());
containerNumber.draw(ge, r, x + 7, y + 3, caret); r.glDrawCharLeft(x, y, '╭');
r.glDrawCharLeft(x, y+height-chh, '╰');
r.glFillColor(x+3, y+6, 2, height-6*2);
r.glFillColor(x+width-5, y+6, 2, height-6*2);
r.glDrawCharLeft(x+width-chw, y, '╮');
r.glDrawCharLeft(x+width-chw, y+height-chh, '╯');
containerNumber.draw(ge, r, x+chw, y, caret);
} }
@Override @Override
@ -43,7 +53,9 @@ public class BlockParenthesis extends Block {
@Override @Override
public void recomputeDimensions() { public void recomputeDimensions() {
width = containerNumber.getWidth() + BlockContainer.getDefaultCharWidth(small) * 2; chw = BlockContainer.getDefaultCharWidth(small);
chh = BlockContainer.getDefaultCharHeight(small);
width = containerNumber.getWidth() + chw * 2 + 3;
height = containerNumber.getHeight(); height = containerNumber.getHeight();
line = containerNumber.getLine(); line = containerNumber.getLine();
} }

View File

@ -0,0 +1,97 @@
package org.warp.picalculator.gui.expression;
import org.warp.picalculator.gui.expression.Block;
import org.warp.picalculator.gui.expression.BlockContainer;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public class BlockPower extends Block {
public static final int CLASS_ID = 0x00000005;
private final BlockContainer containerNumber;
private final BlockContainer containerExponent;
private int h1;
private int w1;
public BlockPower() {
containerNumber = new BlockContainer(false);
containerExponent = new BlockContainer(true);
recomputeDimensions();
}
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
containerNumber.draw(ge, r, x, y+height-h1, caret);
BlockContainer.getDefaultFont(true).use(ge);
containerExponent.draw(ge, r, x+w1+getSpacing(), y, caret);
}
@Override
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
added = added | containerNumber.putBlock(caret, newBlock);
added = added | containerExponent.putBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(Caret caret) {
boolean removed = false;
removed = removed | containerNumber.delBlock(caret);
removed = removed | containerExponent.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public void recomputeDimensions() {
w1 = containerNumber.getWidth();
final int w2 = containerExponent.getWidth();
h1 = containerNumber.getHeight();
final int h2 = containerExponent.getHeight();
final int l1 = containerNumber.getLine();
width = w1+getSpacing()+1+w2;
height = h1 + h2 - 3;
line = height-h1+l1;
}
@Override
public void setSmall(boolean small) {
this.small = small;
containerNumber.setSmall(small);
containerExponent.setSmall(true);
recomputeDimensions();
}
public BlockContainer getNumberContainer() {
return containerNumber;
}
public BlockContainer getExponentContainer() {
return containerExponent;
}
@Override
public int getClassID() {
return CLASS_ID;
}
@Override
public int computeCaretMaxBound() {
return containerNumber.computeCaretMaxBound() + containerExponent.computeCaretMaxBound();
}
protected int getSpacing() {
return 1;
}
}

View File

@ -74,6 +74,8 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
final int curPos = caret.getPosition(); final int curPos = caret.getPosition();
if (curPos > 0) { if (curPos > 0) {
caret.setPosition(curPos - 1); caret.setPosition(curPos - 1);
} else {
caret.setPosition(maxPosition-1);
} }
caret.turnOn(); caret.turnOn();
caretTime = 0; caretTime = 0;
@ -83,6 +85,8 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
final int curPos = caret.getPosition(); final int curPos = caret.getPosition();
if (curPos + 1 < maxPosition) { if (curPos + 1 < maxPosition) {
caret.setPosition(curPos + 1); caret.setPosition(curPos + 1);
} else {
caret.setPosition(0);
} }
caret.turnOn(); caret.turnOn();
caretTime = 0; caretTime = 0;

View File

@ -4,6 +4,7 @@ import org.warp.picalculator.gui.expression.Block;
import org.warp.picalculator.gui.expression.BlockChar; import org.warp.picalculator.gui.expression.BlockChar;
import org.warp.picalculator.gui.expression.BlockDivision; import org.warp.picalculator.gui.expression.BlockDivision;
import org.warp.picalculator.gui.expression.BlockParenthesis; import org.warp.picalculator.gui.expression.BlockParenthesis;
import org.warp.picalculator.gui.expression.BlockPower;
import org.warp.picalculator.gui.expression.BlockSquareRoot; import org.warp.picalculator.gui.expression.BlockSquareRoot;
import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.MathematicalSymbols;
@ -29,8 +30,12 @@ public class NormalInputContainer extends InputContainer {
case MathematicalSymbols.SQUARE_ROOT: case MathematicalSymbols.SQUARE_ROOT:
return new BlockSquareRoot(); return new BlockSquareRoot();
case MathematicalSymbols.PARENTHESIS_OPEN: case MathematicalSymbols.PARENTHESIS_OPEN:
case MathematicalSymbols.PARENTHESIS_CLOSE:
return new BlockParenthesis(); return new BlockParenthesis();
case MathematicalSymbols.PARENTHESIS_CLOSE:
return null;
case MathematicalSymbols.POWER:
case MathematicalSymbols.POWER_OF_TWO:
return new BlockPower();
case MathematicalSymbols.MULTIPLICATION: case MathematicalSymbols.MULTIPLICATION:
case MathematicalSymbols.SUM: case MathematicalSymbols.SUM:
case MathematicalSymbols.SUM_SUBTRACTION: case MathematicalSymbols.SUM_SUBTRACTION:
@ -50,4 +55,12 @@ public class NormalInputContainer extends InputContainer {
return new BlockChar(c); return new BlockChar(c);
} }
} }
@Override
public void typeChar(char c) {
super.typeChar(c);
if (c == MathematicalSymbols.PARENTHESIS_CLOSE) {
this.moveRight();
}
}
} }

View File

@ -10,6 +10,10 @@ import org.warp.picalculator.gui.expression.Block;
import org.warp.picalculator.gui.expression.BlockChar; import org.warp.picalculator.gui.expression.BlockChar;
import org.warp.picalculator.gui.expression.BlockContainer; import org.warp.picalculator.gui.expression.BlockContainer;
import org.warp.picalculator.gui.expression.BlockDivision; import org.warp.picalculator.gui.expression.BlockDivision;
import org.warp.picalculator.gui.expression.BlockExponentialNotation;
import org.warp.picalculator.gui.expression.BlockParenthesis;
import org.warp.picalculator.gui.expression.BlockPower;
import org.warp.picalculator.gui.expression.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.FunctionOperator;
@ -17,6 +21,8 @@ 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.Number; 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.Subtraction;
import org.warp.picalculator.math.functions.Sum; import org.warp.picalculator.math.functions.Sum;
import org.warp.picalculator.math.functions.SumSubtraction; import org.warp.picalculator.math.functions.SumSubtraction;
@ -29,12 +35,17 @@ import org.warp.picalculator.math.parser.features.FeatureChar;
import org.warp.picalculator.math.parser.features.FeatureDivision; 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.FeaturePower;
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.features.interfaces.FeatureDouble;
import org.warp.picalculator.math.parser.features.interfaces.FeatureSingle;
import com.sun.org.apache.xpath.internal.functions.Function2Args; import com.sun.org.apache.xpath.internal.functions.Function2Args;
import com.sun.org.apache.xpath.internal.operations.Mult;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectListIterator; import it.unimi.dsi.fastutil.objects.ObjectListIterator;
@ -50,7 +61,7 @@ public class MathParser {
return result; return result;
} }
public static ObjectArrayList<Block> parseOutput(MathContext context, ObjectArrayList<Function> expr) { public static ObjectArrayList<Block> parseOutput(MathContext context, ObjectArrayList<Function> expr) throws Error {
final ObjectArrayList<Block> resultBlocks = new ObjectArrayList<>(); final ObjectArrayList<Block> resultBlocks = new ObjectArrayList<>();
for (Function f : expr) { for (Function f : expr) {
@ -60,7 +71,7 @@ public class MathParser {
return resultBlocks; return resultBlocks;
} }
private static ObjectArrayList<Block> parseFunction(MathContext context, Function func) { private static ObjectArrayList<Block> parseFunction(MathContext context, Function func) throws Error {
ObjectArrayList<Block> result = new ObjectArrayList<>(); ObjectArrayList<Block> result = new ObjectArrayList<>();
if (func instanceof FunctionOperator) { if (func instanceof FunctionOperator) {
ObjectArrayList<Block> sub1 = parseFunction(context, func.getParameter(0)); ObjectArrayList<Block> sub1 = parseFunction(context, func.getParameter(0));
@ -71,23 +82,124 @@ public class MathParser {
result.addAll(sub2); result.addAll(sub2);
return result; return result;
} }
if (func instanceof Subtraction) {
result.addAll(sub1);
result.add(new BlockChar(MathematicalSymbols.SUBTRACTION));
result.addAll(sub2);
return result;
}
if (func instanceof SumSubtraction) {
result.addAll(sub1);
result.add(new BlockChar(MathematicalSymbols.SUM_SUBTRACTION));
result.addAll(sub2);
return result;
}
if (func instanceof Multiplication) {
Block nearLeft = sub1.get(sub1.size()-1);
Block nearRight = sub2.get(0);
result.addAll(sub1);
if (nearLeft instanceof BlockChar && nearRight instanceof BlockChar) {
} else {
result.add(new BlockChar(MathematicalSymbols.MULTIPLICATION));
}
result.addAll(sub2);
return result;
}
if (func instanceof Division) {
BlockDivision bd = new BlockDivision();
BlockContainer uc = bd.getUpperContainer();
BlockContainer lc = bd.getLowerContainer();
for (Block b : sub1) {
uc.appendBlockUnsafe(b);
}
for (Block b : sub2) {
lc.appendBlockUnsafe(b);
}
uc.recomputeDimensions();
lc.recomputeDimensions();
bd.recomputeDimensions();
result.add(bd);
return result;
}
if (func instanceof Power) {
BlockPower bp = new BlockPower();
BlockContainer nc = bp.getNumberContainer();
BlockContainer ec = bp.getExponentContainer();
for (Block b : sub1) {
nc.appendBlockUnsafe(b);
}
for (Block b : sub2) {
ec.appendBlockUnsafe(b);
}
nc.recomputeDimensions();
ec.recomputeDimensions();
bp.recomputeDimensions();
result.add(bp);
return result;
}
}
if (func instanceof FunctionSingle) {
ObjectArrayList<Block> sub = parseFunction(context, func.getParameter(0));
if (func instanceof RootSquare) {
BlockSquareRoot bsqr = new BlockSquareRoot();
BlockContainer bsqrc = bsqr.getNumberContainer();
for (Block b : sub) {
bsqrc.appendBlockUnsafe(b);
}
bsqrc.recomputeDimensions();
bsqr.recomputeDimensions();
result.add((bsqr));
return result;
}
}
if (func instanceof Expression) {
ObjectArrayList<Block> sub = parseFunction(context, ((Expression) func).getParameter(0));
BlockParenthesis bp = new BlockParenthesis();
BlockContainer bpc = bp.getNumberContainer();
for (Block b : sub) {
bpc.appendBlockUnsafe(b);
}
bpc.recomputeDimensions();
bp.recomputeDimensions();
result.add(bp);
return result;
} }
if (func instanceof Number) { if (func instanceof Number) {
Number numb = (Number) func; Number numb = (Number) func;
BigDecimal decimal = numb.getTerm(); String numberString = numb.toString();
String numberString; if (numberString.contains("")) {
if (numb.isInteger()) { String[] numberParts = numberString.split("", 2);
BigInteger integ = decimal.toBigInteger(); numberParts[0]+="";
numberString = integ.toString(); BlockPower bp = new BlockExponentialNotation();
BlockContainer bpnc = bp.getNumberContainer();
BlockContainer bpec = bp.getExponentContainer();
for (char c : numberParts[0].toCharArray()) {
bpnc.appendBlockUnsafe(new BlockChar(c));
}
for (char c : numberParts[1].toCharArray()) {
bpec.appendBlockUnsafe(new BlockChar(c));
}
bpnc.recomputeDimensions();
bpec.recomputeDimensions();
bp.recomputeDimensions();
result.add(bp);
return result;
} else { } else {
numberString = decimal.toPlainString(); for (char c : numberString.toCharArray()) {
} result.add(new BlockChar(c));
for (char c : numberString.toCharArray()) { }
result.add(new BlockChar(c));
} }
return result; return result;
} }
throw new UnsupportedOperationException("Unknown function " + func.getClass().getSimpleName()); if (func instanceof Variable) {
//TODO: Temporary solution. In near future Variables will be distint objects and they will have a color. So they will be no longer a BlockChar/FeatureChar
result.add(new BlockChar(((Variable) func).getChar()));
return result;
}
throw new Error(Errors.NOT_IMPLEMENTED, "Unknown function " + func.getClass().getSimpleName());
} }
private static Function parseContainer(final MathContext context, final Iterable<Block> blocks) throws Error { private static Function parseContainer(final MathContext context, final Iterable<Block> blocks) throws Error {
@ -117,8 +229,24 @@ public class MathParser {
final Function lower = parseContainer(context, bd.getLowerContainer().getContent()); final Function lower = parseContainer(context, bd.getLowerContainer().getContent());
result = new FeatureDivision(upper, lower); result = new FeatureDivision(upper, lower);
break; break;
case BlockSquareRoot.CLASS_ID:
final BlockSquareRoot bsqr = (BlockSquareRoot) block;
final Function contnt = parseContainer(context, bsqr.getNumberContainer().getContent());
result = new FeatureSquareRoot(contnt);
break;
case BlockParenthesis.CLASS_ID:
final BlockParenthesis bp = (BlockParenthesis) block;
final Function cont = parseContainer(context, bp.getNumberContainer().getContent());
result = new FeatureParenthesis(cont);
break;
case BlockPower.CLASS_ID:
final BlockPower blp = (BlockPower) block;
final Function nmb = parseContainer(context, blp.getNumberContainer().getContent());
final Function exp = parseContainer(context, blp.getExponentContainer().getContent());
result = new FeaturePower(nmb, exp);
break;
default: default:
throw new Error(Errors.SYNTAX_ERROR); throw new Error(Errors.NOT_IMPLEMENTED, "The block " + block.getClass().getSimpleName() + " isn't a known BLock");
} }
return result; return result;
@ -141,76 +269,117 @@ public class MathParser {
private static void fixStack(MathContext context, ObjectArrayList<Function> process) throws Error { private static void fixStack(MathContext context, ObjectArrayList<Function> process) throws Error {
//Phase 1 boolean lastLoopDidSomething;
ObjectListIterator<Function> stackIterator = process.listIterator(process.size());
Function lastElement = null; ObjectListIterator<Function> stackIterator;
while (stackIterator.hasPrevious()) {
final Function f = stackIterator.previous(); //Phase 0: join number and variables ([2][x] => [[2]*[x]])
do {
if (f instanceof FunctionSingle) { lastLoopDidSomething = false;
if (((FunctionSingle) f).getParameter() == null) { stackIterator = process.listIterator(process.size());
if (lastElement == null) { Function lastElement = null;
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified."); while (stackIterator.hasPrevious()) {
} else { final Function f = stackIterator.previous();
((FunctionSingle) f).setParameter(lastElement); final int curIndex = stackIterator.nextIndex();
process.remove(stackIterator.nextIndex());
if (f instanceof Number | f instanceof Variable) {
if (lastElement instanceof Variable) {
lastLoopDidSomething = true;
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;
} }
lastElement = f; } while (lastLoopDidSomething);
}
//Phase 1
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 //Phase 2
stackIterator = process.listIterator(); do {
while (stackIterator.hasNext()) { lastLoopDidSomething = false;
final Function f = stackIterator.next(); stackIterator = process.listIterator();
final int curIndex = stackIterator.previousIndex(); while (stackIterator.hasNext()) {
final Function f = stackIterator.next();
final int curIndex = stackIterator.previousIndex();
if (f instanceof Multiplication || f instanceof Division) { if (f instanceof Multiplication || f instanceof Division) {
if (curIndex - 1 >= 0 && stackIterator.hasNext()) { if (curIndex - 1 >= 0 && stackIterator.hasNext()) {
final Function next = process.get(curIndex + 1); lastLoopDidSomething = true;
final Function prev = process.get(curIndex - 1); final Function next = process.get(curIndex + 1);
stackIterator.set(f.setParameter(0, prev).setParameter(1, next)); final Function prev = process.get(curIndex - 1);
process.remove(curIndex + 1); stackIterator.set(f.setParameter(0, prev).setParameter(1, next));
process.remove(curIndex - 1); process.remove(curIndex + 1);
} else { process.remove(curIndex - 1);
if (f.getParameter(0) == null || f.getParameter(1) == null) { } else {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified."); 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 //Phase 3
stackIterator = process.listIterator(); do {
while (stackIterator.hasNext()) { lastLoopDidSomething = false;
final Function f = stackIterator.next(); stackIterator = process.listIterator();
final int curIndex = stackIterator.previousIndex(); while (stackIterator.hasNext()) {
final Function f = stackIterator.next();
final int curIndex = stackIterator.previousIndex();
if (f instanceof Sum || f instanceof Subtraction || f instanceof SumSubtraction) { if (f instanceof Sum || f instanceof Subtraction || f instanceof SumSubtraction) {
if (curIndex - 1 >= 0 && stackIterator.hasNext()) { if (curIndex - 1 >= 0 && stackIterator.hasNext()) {
final Function next = process.get(curIndex + 1); lastLoopDidSomething = true;
final Function prev = process.get(curIndex - 1); final Function next = process.get(curIndex + 1);
stackIterator.set(f.setParameter(0, prev).setParameter(1, next)); final Function prev = process.get(curIndex - 1);
process.remove(curIndex + 1); stackIterator.set(f.setParameter(0, prev).setParameter(1, next));
process.remove(curIndex - 1); process.remove(curIndex + 1);
} else { process.remove(curIndex - 1);
if (f.getParameter(0) == null || f.getParameter(1) == null) { } else {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified."); 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 //Phase 4
stackIterator = process.iterator(); do {
while (stackIterator.hasNext()) { lastLoopDidSomething = false;
final Function f = stackIterator.next(); stackIterator = process.iterator();
while (stackIterator.hasNext()) {
final Function f = stackIterator.next();
if (f instanceof Function2Args) { if (f instanceof Function2Args) {
}
} }
} } while (lastLoopDidSomething);
} }
private static ObjectArrayList<Function> makeFunctions(MathContext context, ObjectArrayList<Feature> features) private static ObjectArrayList<Function> makeFunctions(MathContext context, ObjectArrayList<Feature> features)
@ -226,6 +395,12 @@ public class MathParser {
process.add(new Variable(context, ((FeatureVariable) f).ch, ((FeatureVariable) f).varType)); process.add(new Variable(context, ((FeatureVariable) f).ch, ((FeatureVariable) f).varType));
} else if (f instanceof FeatureSum) { } else if (f instanceof FeatureSum) {
process.add(new Sum(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2())); process.add(new Sum(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
} else if (f instanceof FeaturePower) {
process.add(new Power(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
} else if (f instanceof FeatureSquareRoot) {
process.add(new RootSquare(context, (Function) ((FeatureSingle) f).getChild()));
} else if (f instanceof FeatureParenthesis) {
process.add(new Expression(context, (Function) ((FeatureSingle) f).getChild()));
// } else if (f instanceof FeatureSubtraction) { // } else if (f instanceof FeatureSubtraction) {
// process.add(new Subtraction(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2())); // process.add(new Subtraction(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
// } else if (f instanceof FeatureSumSubtraction) { // } else if (f instanceof FeatureSumSubtraction) {
@ -321,7 +496,7 @@ public class MathParser {
break; break;
} }
} }
if (bcf.ch == '-') { if (bcf.ch == '-' || bcf.ch == '.') {
isNumber = true; isNumber = true;
} }
if (isNumber) { if (isNumber) {

View File

@ -0,0 +1,9 @@
package org.warp.picalculator.math.parser.features;
public class FeatureParenthesis extends FeatureSingleImpl {
public FeatureParenthesis(Object child) {
super(child);
}
}

View File

@ -0,0 +1,11 @@
package org.warp.picalculator.math.parser.features;
import org.warp.picalculator.math.parser.features.interfaces.Feature;
public class FeaturePower extends FeatureDoubleImpl {
public FeaturePower(Object child1, Object child2) {
super(child1, child2);
}
}

View File

@ -0,0 +1,9 @@
package org.warp.picalculator.math.parser.features;
public class FeatureSquareRoot extends FeatureSingleImpl {
public FeatureSquareRoot(Object child) {
super(child);
}
}