Added new expression blocks, like parentheses and power of x
This commit is contained in:
parent
c2df21d682
commit
57fc8cfa44
BIN
res/draft unknown variable choice.png
Normal file
BIN
res/draft unknown variable choice.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.9 KiB |
BIN
res/font_ex.rft
BIN
res/font_ex.rft
Binary file not shown.
@ -11,29 +11,34 @@ public class BlockContainer implements GraphicalElement {
|
||||
|
||||
private static boolean initialized = false;
|
||||
|
||||
private final int minWidth;
|
||||
private final int minHeight;
|
||||
private int minWidth;
|
||||
private int minHeight;
|
||||
private final ObjectArrayList<Block> content;
|
||||
private boolean small;
|
||||
private int width;
|
||||
private int height;
|
||||
private int line;
|
||||
public final boolean withBorder;
|
||||
private boolean autoMinimums;
|
||||
|
||||
public BlockContainer() {
|
||||
this(false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
|
||||
autoMinimums = true;
|
||||
}
|
||||
|
||||
public BlockContainer(boolean small) {
|
||||
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true);
|
||||
autoMinimums = true;
|
||||
}
|
||||
|
||||
public BlockContainer(boolean small, boolean withBorder) {
|
||||
this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
|
||||
autoMinimums = true;
|
||||
}
|
||||
|
||||
public BlockContainer(boolean small, int minWidth, int minHeight, boolean withBorder) {
|
||||
this(small, minWidth, minHeight, new ObjectArrayList<>(), withBorder);
|
||||
autoMinimums = false;
|
||||
}
|
||||
|
||||
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 (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 {
|
||||
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);
|
||||
paddingX += b.getWidth();
|
||||
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;
|
||||
}
|
||||
@ -271,17 +276,22 @@ public class BlockContainer implements GraphicalElement {
|
||||
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) {
|
||||
r.glColor(getDefaultColor());
|
||||
r.glDrawLine(x, y, x, y - 1 + height);
|
||||
r.glDrawLine(x + 1, y, x + 1, y - 1 + height);
|
||||
r.glDrawLine(x + 2, y, x + 2, y - 1 + height);
|
||||
r.glFillColor(x, y, small?2:3, height);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSmall(boolean 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();
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,8 @@
|
||||
package org.warp.picalculator.gui.expression;
|
||||
|
||||
public class BlockExponentialNotation extends BlockPower {
|
||||
@Override
|
||||
protected int getSpacing() {
|
||||
return -3;
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
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.Renderer;
|
||||
|
||||
@ -9,6 +10,9 @@ public class BlockParenthesis extends Block {
|
||||
|
||||
private final BlockContainer containerNumber;
|
||||
|
||||
private int chw;
|
||||
private int chh;
|
||||
|
||||
public BlockParenthesis() {
|
||||
containerNumber = new BlockContainer(false);
|
||||
recomputeDimensions();
|
||||
@ -18,7 +22,13 @@ public class BlockParenthesis extends Block {
|
||||
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 + 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
|
||||
@ -43,7 +53,9 @@ public class BlockParenthesis extends Block {
|
||||
|
||||
@Override
|
||||
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();
|
||||
line = containerNumber.getLine();
|
||||
}
|
||||
|
97
src/org/warp/picalculator/gui/expression/BlockPower.java
Normal file
97
src/org/warp/picalculator/gui/expression/BlockPower.java
Normal 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;
|
||||
}
|
||||
}
|
@ -74,6 +74,8 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
|
||||
final int curPos = caret.getPosition();
|
||||
if (curPos > 0) {
|
||||
caret.setPosition(curPos - 1);
|
||||
} else {
|
||||
caret.setPosition(maxPosition-1);
|
||||
}
|
||||
caret.turnOn();
|
||||
caretTime = 0;
|
||||
@ -83,6 +85,8 @@ public abstract class InputContainer implements GraphicalElement, InputLayout, S
|
||||
final int curPos = caret.getPosition();
|
||||
if (curPos + 1 < maxPosition) {
|
||||
caret.setPosition(curPos + 1);
|
||||
} else {
|
||||
caret.setPosition(0);
|
||||
}
|
||||
caret.turnOn();
|
||||
caretTime = 0;
|
||||
|
@ -4,6 +4,7 @@ import org.warp.picalculator.gui.expression.Block;
|
||||
import org.warp.picalculator.gui.expression.BlockChar;
|
||||
import org.warp.picalculator.gui.expression.BlockDivision;
|
||||
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.math.MathematicalSymbols;
|
||||
|
||||
@ -29,8 +30,12 @@ public class NormalInputContainer extends InputContainer {
|
||||
case MathematicalSymbols.SQUARE_ROOT:
|
||||
return new BlockSquareRoot();
|
||||
case MathematicalSymbols.PARENTHESIS_OPEN:
|
||||
case MathematicalSymbols.PARENTHESIS_CLOSE:
|
||||
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.SUM:
|
||||
case MathematicalSymbols.SUM_SUBTRACTION:
|
||||
@ -50,4 +55,12 @@ public class NormalInputContainer extends InputContainer {
|
||||
return new BlockChar(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void typeChar(char c) {
|
||||
super.typeChar(c);
|
||||
if (c == MathematicalSymbols.PARENTHESIS_CLOSE) {
|
||||
this.moveRight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,10 @@ import org.warp.picalculator.gui.expression.Block;
|
||||
import org.warp.picalculator.gui.expression.BlockChar;
|
||||
import org.warp.picalculator.gui.expression.BlockContainer;
|
||||
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.math.Function;
|
||||
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.MathematicalSymbols;
|
||||
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;
|
||||
@ -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.FeatureMultiplication;
|
||||
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.FeatureVariable;
|
||||
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.FeatureSingle;
|
||||
|
||||
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.ObjectListIterator;
|
||||
@ -50,7 +61,7 @@ public class MathParser {
|
||||
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<>();
|
||||
|
||||
for (Function f : expr) {
|
||||
@ -60,7 +71,7 @@ public class MathParser {
|
||||
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<>();
|
||||
if (func instanceof FunctionOperator) {
|
||||
ObjectArrayList<Block> sub1 = parseFunction(context, func.getParameter(0));
|
||||
@ -71,23 +82,124 @@ public class MathParser {
|
||||
result.addAll(sub2);
|
||||
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) {
|
||||
Number numb = (Number) func;
|
||||
BigDecimal decimal = numb.getTerm();
|
||||
String numberString;
|
||||
if (numb.isInteger()) {
|
||||
BigInteger integ = decimal.toBigInteger();
|
||||
numberString = integ.toString();
|
||||
String numberString = numb.toString();
|
||||
if (numberString.contains("ℯ℮")) {
|
||||
String[] numberParts = numberString.split("ℯ℮", 2);
|
||||
numberParts[0]+="ℯ℮";
|
||||
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 {
|
||||
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;
|
||||
}
|
||||
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 {
|
||||
@ -117,8 +229,24 @@ public class MathParser {
|
||||
final Function lower = parseContainer(context, bd.getLowerContainer().getContent());
|
||||
result = new FeatureDivision(upper, lower);
|
||||
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:
|
||||
throw new Error(Errors.SYNTAX_ERROR);
|
||||
throw new Error(Errors.NOT_IMPLEMENTED, "The block " + block.getClass().getSimpleName() + " isn't a known BLock");
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -141,76 +269,117 @@ public class MathParser {
|
||||
|
||||
private static void fixStack(MathContext context, ObjectArrayList<Function> process) throws Error {
|
||||
|
||||
//Phase 1
|
||||
ObjectListIterator<Function> stackIterator = process.listIterator(process.size());
|
||||
Function lastElement = null;
|
||||
while (stackIterator.hasPrevious()) {
|
||||
final Function f = stackIterator.previous();
|
||||
boolean lastLoopDidSomething;
|
||||
|
||||
if (f instanceof FunctionSingle) {
|
||||
if (((FunctionSingle) f).getParameter() == null) {
|
||||
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());
|
||||
ObjectListIterator<Function> stackIterator;
|
||||
|
||||
//Phase 0: join number and variables ([2][x] => [[2]*[x]])
|
||||
do {
|
||||
lastLoopDidSomething = false;
|
||||
stackIterator = process.listIterator(process.size());
|
||||
Function lastElement = null;
|
||||
while (stackIterator.hasPrevious()) {
|
||||
final Function f = stackIterator.previous();
|
||||
final int curIndex = 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
|
||||
stackIterator = process.listIterator();
|
||||
while (stackIterator.hasNext()) {
|
||||
final Function f = stackIterator.next();
|
||||
final int curIndex = stackIterator.previousIndex();
|
||||
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()) {
|
||||
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.");
|
||||
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
|
||||
stackIterator = process.listIterator();
|
||||
while (stackIterator.hasNext()) {
|
||||
final Function f = stackIterator.next();
|
||||
final int curIndex = stackIterator.previousIndex();
|
||||
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()) {
|
||||
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.");
|
||||
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
|
||||
stackIterator = process.iterator();
|
||||
while (stackIterator.hasNext()) {
|
||||
final Function f = stackIterator.next();
|
||||
do {
|
||||
lastLoopDidSomething = false;
|
||||
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)
|
||||
@ -226,6 +395,12 @@ public class MathParser {
|
||||
process.add(new Variable(context, ((FeatureVariable) f).ch, ((FeatureVariable) f).varType));
|
||||
} else if (f instanceof FeatureSum) {
|
||||
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) {
|
||||
// process.add(new Subtraction(context, (Function) ((FeatureDouble) f).getChild1(), (Function) ((FeatureDouble) f).getChild2()));
|
||||
// } else if (f instanceof FeatureSumSubtraction) {
|
||||
@ -321,7 +496,7 @@ public class MathParser {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bcf.ch == '-') {
|
||||
if (bcf.ch == '-' || bcf.ch == '.') {
|
||||
isNumber = true;
|
||||
}
|
||||
if (isNumber) {
|
||||
|
@ -0,0 +1,9 @@
|
||||
package org.warp.picalculator.math.parser.features;
|
||||
|
||||
public class FeatureParenthesis extends FeatureSingleImpl {
|
||||
|
||||
public FeatureParenthesis(Object child) {
|
||||
super(child);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package org.warp.picalculator.math.parser.features;
|
||||
|
||||
public class FeatureSquareRoot extends FeatureSingleImpl {
|
||||
|
||||
public FeatureSquareRoot(Object child) {
|
||||
super(child);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user