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 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
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();
|
||||||
}
|
}
|
||||||
|
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();
|
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;
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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