diff --git a/src/main/java/math/Maths.java b/src/main/java/math/Maths.java index 98b4104..7910f74 100644 --- a/src/main/java/math/Maths.java +++ b/src/main/java/math/Maths.java @@ -1575,6 +1575,7 @@ public static void main(String args[]) { System.out.println(" RUNTIME = " + ((t4 - t3) / 1.0E6) + " ms"); + System.out.println(" fact = " + fact("0.01")); } /*We use the principle: * pi=(magic_whole_no)*(SUM(i^-n))^(1/n) < where i goes from 1 to infinity during summation > diff --git a/src/main/java/parser/BigMathExpression.java b/src/main/java/parser/BigMathExpression.java new file mode 100644 index 0000000..7da85d6 --- /dev/null +++ b/src/main/java/parser/BigMathExpression.java @@ -0,0 +1,353 @@ +/* + * Copyright 2023 gbemirojiboye. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package parser; + +import java.util.*; +import java.math.*; +import static parser.Variable.*; +import static parser.Number.*; +import static parser.Operator.*; +import static parser.methods.Method.*; +import util.FunctionManager; + +/** + * Base class for handling calculations in BigDecimal + * @author gbemirojiboye + */ +public class BigMathExpression extends MathExpression { + + public BigMathExpression(String expression) throws InputMismatchException { + super(expression); + if (isHasInbuiltFunctions() || isHasLogicOperators() || isHasListReturningOperators() + || isHasPreNumberOperators() || isHasNumberReturningNonUserDefinedFunctions() + || isHasPermOrCombOperators() || isHasRemainderOperators() || isHasPostNumberOperators()) { + setCorrectFunction(false); + throw new InputMismatchException("Functions not supported yet!"); + } // end if + + // Check if the user defined functions do not contain any function whose bigmath + // operation is yet undefined by ParserNG + if(recursiveHasContrabandFunction(this)){ + setCorrectFunction(false); + throw new InputMismatchException("User defined function calls unsupported inbuilt function!"); + } + + } + /** + * This function scans a MathExpression for functions that ParserNG cannot + * evaluate using big math yet. + * At the moment, this includes all functions that are not simple algebraic + * functions. + * + * @return true if it finds any contraband function + */ + private boolean recursiveHasContrabandFunction(MathExpression expression) { + // Check if the user defined functions do not contain any function whose big math + // operation is yet undefined by ParserNG + if (expression.hasFunctions) { + int sz = scanner.size(); + for (int i = 0; i < sz; i++) { + String token = scanner.get(i); + if (i + 1 < sz) { + String nextToken = scanner.get(i + 1); + if (isOpeningBracket(nextToken)) { + if(isInBuiltMethod(token)){ + return true;//contraband found + } + Function f = FunctionManager.getFunction(token); + if (f != null) { + if(f.getType() != Function.ALGEBRAIC){ + return true;//contraband found + } + MathExpression me = f.getMathExpression(); + if(me.hasInbuiltFunctions){ + return true; + }else if(me.hasUserDefinedFunctions){ + return recursiveHasContrabandFunction(me); + } + } + } + } + } // end for + } + + return false;//Yay, no contraband function found + } + + + /** + * used by the main parser solve to figure out SBP portions of a + * multi-bracketed expression (MBP) + * + * @param list a list of scanner tokens of a maths expression + * @return the solution to a SBP maths expression + */ + @Override + protected List solve(List list) { + //correct the anomaly: [ (,-,number....,) ] + // turn it into: [ (,,-number........,) ] + //The double commas show that there exists an empty location in between the 2 commas + if (list.get(0).equals("(") && list.get(1).equals(Operator.MINUS) && isNumber(list.get(2))) { + list.set(1, ""); + + //if the number is negative,make it positive + if (list.get(2).substring(0, 1).equals(Operator.MINUS)) { + list.set(2, list.get(2).substring(1)); + } //if the number is positive,make it negative + else { + list.set(2, Operator.MINUS + list.get(2)); + } + } + //Create a collection to serve as a garbage collector for the empty memory + //locations and other unwanted locations created in the processing collection + ArrayList real = new ArrayList(); + //insert an empty string in it so that we can use it to remove empty spaces from the processing collection. + real.add(""); + real.add("("); + real.add(")"); + + list.removeAll(real); + + if (isHasPowerOperators()) { + + /*Deals with powers.Handles the primary power operator e.g in 3^sin3^4.This is necessary at this stage to dis-allow operations like sinA^Bfrom giving the result:(sinA)^B + instead of sin(A^B). + Also instructs the software to multiply any 2 numbers in consecutive positions in the vector. + This is important in distinguishing between functions such as sinAB and sinA*B.Note:sinAB=sin(A*B),while sinA*B=B*sinA. + */ + for (int i = 0; i < list.size(); i++) { + try { + if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { + if (list.get(i).equals("^") && isNumber(list.get(i - 1)) && isNumber(list.get(i + 1))) { + BigDecimal lhs = new BigDecimal(list.get(i - 1)); + String rhs = list.get(i + 1); + list.set(i + 1, String.valueOf(lhs.pow(Integer.valueOf(rhs), MathContext.DECIMAL128))); + list.set(i - 1, ""); + list.set(i, ""); + }//end if + }//end if + else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { + if (Double.valueOf(list.get(i + 1)) > 1) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + } else if (Double.valueOf(list.get(i + 1)) == 1) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + } else if (Double.valueOf(list.get(i + 1)) < 1 && Double.valueOf(list.get(i + 1)) > 0) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + } else if (Double.valueOf(list.get(i + 1)) < 1 && Double.valueOf(list.get(i + 1)) == 0) { + list.set(i + 1, "1.0"); + list.set(i - 1, ""); + list.set(i, ""); + } else if (Double.valueOf(list.get(i + 1)) < 1 && Double.valueOf(list.get(i + 1)) < 0) { + list.set(i + 1, "0.0"); + list.set(i - 1, ""); + list.set(i, ""); + } + } else if (!list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity")) { + if (Double.valueOf(list.get(i - 1)) > 1) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + } else if (Double.valueOf(list.get(i - 1)) == 1) { + list.set(i + 1, "1.0"); + list.set(i - 1, ""); + list.set(i, ""); + } else if (Double.valueOf(list.get(i - 1)) < 1 && Double.valueOf(list.get(i - 1)) > 0) { + list.set(i + 1, "0.0"); + list.set(i - 1, ""); + list.set(i, ""); + } else if (Double.valueOf(list.get(i - 1)) < 1 && Double.valueOf(list.get(i - 1)) == 0) { + list.set(i + 1, "0.0"); + list.set(i - 1, ""); + list.set(i, ""); + } else if (Double.valueOf(list.get(i - 1)) < 1 && Double.valueOf(list.get(i - 1)) < 0) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + }//end else if + }//end else if + else if (list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity")) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + } + + }//end try + catch (NumberFormatException numerror) { + + } catch (NullPointerException nullerror) { + + } catch (IndexOutOfBoundsException inderror) { + + } + }//end for + + list.removeAll(real); + + }//end if + + list.removeAll(real); + + boolean skip = false; + if (isHasMulOrDivOperators()) { + for (int i = 0; i < list.size(); i++) { + + try { + + if (list.get(i).equals(Operator.MULTIPLY)) { + if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { + BigDecimal lhs = new BigDecimal(list.get(i - 1)); + BigDecimal rhs = new BigDecimal(list.get(i + 1)); + list.set(i + 1, String.valueOf(lhs.multiply(rhs, MathContext.DECIMAL128))); + list.set(i - 1, ""); + list.set(i, ""); + skip = true; + } else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + skip = true; + } else if (!list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity")) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + skip = true; + } else if (list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity")) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + skip = true; + } + + }//end if + else if (list.get(i).equals(Operator.DIVIDE)) { + if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { + BigDecimal lhs = new BigDecimal(list.get(i - 1)); + BigDecimal rhs = new BigDecimal(list.get(i + 1)); + + list.set(i + 1, String.valueOf(lhs.divide(rhs, MathContext.DECIMAL128))); + list.set(i - 1, ""); + list.set(i, ""); + skip = true; + } else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + skip = true; + } else if (!list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity")) { + list.set(i + 1, "0.0"); + list.set(i - 1, ""); + list.set(i, ""); + skip = true; + } else if (list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity")) { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + skip = true; + } + + }//end else if + + }//end try + catch (NullPointerException nolan) { + + }//end catch + catch (NumberFormatException numerr) { + + }//end catch + catch (IndexOutOfBoundsException inderr) { + + }//end catch + + }//end for + list.removeAll(real); + + }//end if + if (isHasPlusOrMinusOperators()) { + //Handles the subtraction and addition operators + for (int i = 0; i < list.size(); i++) { + try { + if (list.get(i).equals(Operator.PLUS) || list.get(i).equals(Operator.MINUS)) { + if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { + if (list.get(i).equals(Operator.PLUS) && isNumber(list.get(i - 1)) && isNumber(list.get(i + 1))) { + BigDecimal lhs = new BigDecimal(list.get(i - 1)); + BigDecimal rhs = new BigDecimal(list.get(i + 1)); + + list.set(i + 1, String.valueOf(lhs.add(rhs, MathContext.DECIMAL128))); + list.set(i - 1, ""); + list.set(i, ""); + }//end else + else if (list.get(i).equals(Operator.MINUS) && isNumber(list.get(i - 1)) && isNumber(list.get(i + 1))) { + BigDecimal lhs = new BigDecimal(list.get(i - 1)); + BigDecimal rhs = new BigDecimal(list.get(i + 1)); + + list.set(i + 1, String.valueOf(lhs.subtract(rhs, MathContext.DECIMAL128))); + list.set(i - 1, ""); + list.set(i, ""); + }//end else if + }//end if + else { + list.set(i + 1, "Infinity"); + list.set(i - 1, ""); + list.set(i, ""); + } + } + + }//end try + catch (NullPointerException nolerr) { + + }//end catch + catch (NumberFormatException numerr) { + + }//end catch + catch (IndexOutOfBoundsException inderr) { + }//end catch + }//end for + }//end if + + real.add("("); + real.add(")"); + + list.removeAll(real); + if (list.size() != 1) { + this.correctFunction = false; + }//end if + //Now de-list or un-package the input.If all goes well the list should have only its first memory location occupied. + return list; + + }//end method solve + + + + + + public static void main(String[] args) { + + MathExpression me = new MathExpression("a,v,d=2/3;b=3;f=3ab;p(x)=x^3+5*x^2-4*x+1;p(9);"); + System.out.println(me.solve()); + BigMathExpression bme = new BigMathExpression("x=2;h(x)=5*x^2+x+2*x-sin(x);h(3);"); + System.out.println(bme.solve()); + + MathExpression bm = new MathExpression("x=9;f(x)=3*x^2+sin(x^2);f(6)<3"); + System.out.println(bm.solve()); + } + +} diff --git a/src/main/java/parser/Function.java b/src/main/java/parser/Function.java index 174edf3..2ac2506 100644 --- a/src/main/java/parser/Function.java +++ b/src/main/java/parser/Function.java @@ -223,7 +223,7 @@ public double calc(double... x) { return Double.NaN; } - public static boolean assignObject(String input) { + public static boolean assignObject(String input, Class mathExpClass) { /** * Check if it is a function assignment operation...e.g: @@ -273,9 +273,10 @@ public static boolean assignObject(String input) { success = true; } else { - MathExpression expr = new MathExpression(rhs); + MathExpression expr = mathExpClass == BigMathExpression.class ? new BigMathExpression(rhs) : new MathExpression(rhs); String val = expr.solve(); String referenceName = expr.getReturnObjectName(); + //System.out.println("rhs: "+rhs+", mathExpClass: "+mathExpClass+", expr.class: "+expr.getClass()+", val: "+val+", type: "+expr.getReturnType()); if (Variable.isVariableString(newFuncName) || isVarNamesList) { Function f; diff --git a/src/main/java/parser/ListReturningStatsOperator.java b/src/main/java/parser/ListReturningStatsOperator.java index 315312b..482cc33 100644 --- a/src/main/java/parser/ListReturningStatsOperator.java +++ b/src/main/java/parser/ListReturningStatsOperator.java @@ -4,6 +4,7 @@ */ package parser; + import parser.methods.Method; import java.util.ArrayList; @@ -12,29 +13,26 @@ * * @author GBEMIRO */ -public final class ListReturningStatsOperator extends Operator implements Validatable{ - - - +public final class ListReturningStatsOperator extends Operator implements Validatable { /** * The container of all ListTypeOperator objects in the scanned function. */ private boolean superParent; -/** - * The index of this Operator in its parent scanned function. - */ -private int index; + /** + * The index of this Operator in its parent scanned function. + */ + private int index; -/** - * The opening bracket operator that forms one of the bracket - * pair used by this Operator to bound its data to the left - */ + /** + * The opening bracket operator that forms one of the bracket + * pair used by this Operator to bound its data to the left + */ private Bracket openBracket; -/** - * The closing bracket operator that forms one of the bracket - * pair used by this Operator to bound its data to the right - */ + /** + * The closing bracket operator that forms one of the bracket + * pair used by this Operator to bound its data to the right + */ private Bracket closeBracket; /** @@ -42,411 +40,404 @@ public final class ListReturningStatsOperator extends Operator implements Valid */ private ListReturningStatsOperator parent; - - private static String errorMessage=""; + private static String errorMessage = ""; /** * - * @param op the name of the operator - * @param index the index of this Operator in its parent scanned function. - * @param scan the ArrayList object that contains the scanned function that has this ListReturningStatsOperator object + * @param op the name of the operator + * @param index the index of this Operator in its parent scanned function. + * @param scan the ArrayList object that contains the scanned function that has + * this ListReturningStatsOperator object */ - public ListReturningStatsOperator(String op,int index,ArrayListscan) { - super( op); - this.index=(scan.get(index).equals(op))?index:-1; - this.openBracket=new Bracket("("); - this.openBracket.setIndex(index+1); - int compIndex=Bracket.getComplementIndex(true, index+1, scan); - closeBracket=new Bracket(")"); - closeBracket.setIndex(compIndex); - openBracket.setComplement(closeBracket); - closeBracket.setComplement(openBracket); - determineSuperParentStatus(scan); - hasParent(scan); - if(this.index==-1){ - throw new ArrayIndexOutOfBoundsException("PARSER COULD NOT FIND\n \'"+op+ "\' AT INDEX "+index+ - ".\nFOUND \'"+scan.get(index)+"\' INSTEAD OF \'"+op+"\'"); - } + public ListReturningStatsOperator(String op, int index, ArrayList scan) { + super(op); + this.index = (scan.get(index).equals(op)) ? index : -1; + this.openBracket = new Bracket("("); + this.openBracket.setIndex(index + 1); + int compIndex = Bracket.getComplementIndex(true, index + 1, scan); + closeBracket = new Bracket(")"); + closeBracket.setIndex(compIndex); + openBracket.setComplement(closeBracket); + closeBracket.setComplement(openBracket); + determineSuperParentStatus(scan); + hasParent(scan); + if (this.index == -1) { + throw new ArrayIndexOutOfBoundsException("PARSER COULD NOT FIND\n \'" + op + "\' AT INDEX " + index + + ".\nFOUND \'" + scan.get(index) + "\' INSTEAD OF \'" + op + "\'"); + } } - - /** * * @return true if this object is the superParent - * i.e the container for all data in the function. + * i.e the container for all data in the function. */ - private void determineSuperParentStatus(ArrayListscan){ - boolean isSuper=true; - int scanStartIndex=getCloseBracket().getIndex(); - loopForwards:{ - for(int i=scanStartIndex+1;i scan) { + boolean isSuper = true; + int scanStartIndex = getCloseBracket().getIndex(); + loopForwards: { + for (int i = scanStartIndex + 1; i < scan.size(); i++) { + if (!isClosingBracket(scan.get(i))) { + isSuper = false; + break loopForwards; + } - }//end loop + } // end for loop - loopBackwards:{ - for(int i=index-1;i>=0;i--){ - if( !isOpeningBracket( scan.get(i) ) ){ - isSuper=false; - break loopBackwards; - } + } // end loop - }//end for loop + loopBackwards: { + for (int i = index - 1; i >= 0; i--) { + if (!isOpeningBracket(scan.get(i))) { + isSuper = false; + break loopBackwards; + } - }//end loop + } // end for loop + } // end loop -setSuperParent(isSuper); + setSuperParent(isSuper); } - - -/** - * - * @param openBracket sets the opening bracket - * for this Operator - */ + /** + * + * @param openBracket sets the opening bracket + * for this Operator + */ public void setOpenBracket(Bracket openBracket) { this.openBracket = openBracket; } -/** - * - * @return the opening bracket - * for this Operator - */ + + /** + * + * @return the opening bracket + * for this Operator + */ public Bracket getOpenBracket() { return openBracket; } -/** - * - * @param closeBracket sets the closing bracket - * for this Operator - */ + + /** + * + * @param closeBracket sets the closing bracket + * for this Operator + */ public void setCloseBracket(Bracket closeBracket) { this.closeBracket = closeBracket; } -/** - * - * @return the closing bracket - * for this Operator - */ + + /** + * + * @return the closing bracket + * for this Operator + */ public Bracket getCloseBracket() { return closeBracket; } -/** - * - * @param index sets the location of this Operator - * object in its parent scanned function. - */ + + /** + * + * @param index sets the location of this Operator + * object in its parent scanned function. + */ public void setIndex(int index) { this.index = index; } -/** - * - * @return the index of its parent scanned function. - */ + + /** + * + * @return the index of its parent scanned function. + */ public int getIndex() { return index; } -/** - * - * @param superParent sets whether or not - * this is the container ListReturningStatsOperator object - * for the data set. - */ + + /** + * + * @param superParent sets whether or not + * this is the container ListReturningStatsOperator object + * for the data set. + */ public void setSuperParent(boolean superParent) { this.superParent = superParent; } -/** - * - * @return true if this is the container ListReturningStatsOperator object - * for the data set. - */ + + /** + * + * @return true if this is the container ListReturningStatsOperator object + * for the data set. + */ public boolean isSuperParent() { return superParent; } - - -/** - * The concept of a parent here is that - * the first ListReturningStatsOperator object to - * this Operator's left is one that encloses it. - * i.e sort(2,3,mode(4,1,1,3)) - * Here sort is a parent to mode. - * - * But in sort(2,3,sort(4,1,3,4),mode(4,5,1)),mode will - * have no parent here by our definition. The outermost sort which would - * have been its parent does not immediately enclose it.The outermost sort - * however is a parent to the second sort(4,1,3,4). - * We use this special definition for parent because we wish to ensure that each - * object of this class will validate its own surroundings, not even its contents. - * It will not validate beyond the next ListReturningStatsOperator to it. - * - * @param parent sets the ListReturningStatsOperator object that immediately envelopes this one. - */ + /** + * The concept of a parent here is that + * the first ListReturningStatsOperator object to + * this Operator's left is one that encloses it. + * i.e sort(2,3,mode(4,1,1,3)) + * Here sort is a parent to mode. + * + * But in sort(2,3,sort(4,1,3,4),mode(4,5,1)),mode will + * have no parent here by our definition. The outermost sort which would + * have been its parent does not immediately enclose it.The outermost sort + * however is a parent to the second sort(4,1,3,4). + * We use this special definition for parent because we wish to ensure that each + * object of this class will validate its own surroundings, not even its + * contents. + * It will not validate beyond the next ListReturningStatsOperator to it. + * + * @param parent sets the ListReturningStatsOperator object that immediately + * envelopes this one. + */ public void setParent(ListReturningStatsOperator parent) { this.parent = parent; } -/** - * - * @return the ListReturningStatsOperator object that immediately envelopes this one. - */ + + /** + * + * @return the ListReturningStatsOperator object that immediately envelopes this + * one. + */ public ListReturningStatsOperator getParent() { return parent; } -/** - * - * @param errorMessage sets the error message generated by objects of this class. - */ + + /** + * + * @param errorMessage sets the error message generated by objects of this + * class. + */ public static void setErrorMessage(String errorMessage) { ListReturningStatsOperator.errorMessage = errorMessage; } -/** - * - * @return the error message generated by objects of this class. - */ + + /** + * + * @return the error message generated by objects of this class. + */ public static String getErrorMessage() { return errorMessage; } + /** + * + * @param scan the ArrayList containing the scanned function + * @return true if the first ListReturningStatsOperator object to its + * left is its parent. So it can have a parent and yet return false + * here. + */ -/** - * - * @param scan the ArrayList containing the scanned function - * @return true if the first ListReturningStatsOperator object to its - * left is its parent. So it can have a parent and yet return false - * here. - */ - - public boolean hasParent(ArrayListscan){ -boolean isEnveloped = false; - int i=index; + public boolean hasParent(ArrayList scan) { + boolean isEnveloped = false; + int i = index; - boolean foundLikelyEncloser=false; - //search for an enclosing ListReturningStatsOperator object to the left of this - //Operator's location.If one is found set the boolean to true and exit the search loop. - for(i=index-1;i>=0;i--){ + boolean foundLikelyEncloser = false; + // search for an enclosing ListReturningStatsOperator object to the left of this + // Operator's location.If one is found set the boolean to true and exit the + // search loop. + for (i = index - 1; i >= 0; i--) { - if( Method.isListReturningStatsMethod( scan.get(i) ) ){ - foundLikelyEncloser=true; + if (Method.isListReturningStatsMethod(scan.get(i))) { + foundLikelyEncloser = true; break; - }//end if + } // end if - }//end for + } // end for - //Try to get the index of the enclosing bracket of the enclosing operator if one exists. - if(foundLikelyEncloser){ - int compIndex=Bracket.getComplementIndex(true, i+1, scan); + // Try to get the index of the enclosing bracket of the enclosing operator if + // one exists. + if (foundLikelyEncloser) { + int compIndex = Bracket.getComplementIndex(true, i + 1, scan); - if(compIndex>closeBracket.getIndex()){ - isEnveloped=true; - ListReturningStatsOperator listType = new ListReturningStatsOperator(scan.get(i), i, scan); -setParent(listType); - }// end if + if (compIndex > closeBracket.getIndex()) { + isEnveloped = true; + ListReturningStatsOperator listType = new ListReturningStatsOperator(scan.get(i), i, scan); + setParent(listType); + } // end if - - }//end if + } // end if - -return isEnveloped; + return isEnveloped; } - - - -/** - * - * @param scan the ArrayList of the scanned function - * that contains this object - * @return true if this object scans through its surroundings to - * the left and to the right and sees - * a valid bracket structure around itself - */ + /** + * + * @param scan the ArrayList of the scanned function + * that contains this object + * @return true if this object scans through its surroundings to + * the left and to the right and sees + * a valid bracket structure around itself + */ @Override -public boolean validate(ArrayListscan){ - boolean valid=true; - - - if(!isSuperParent()){ -try{ - if(isBinaryOperator( scan.get(index-1) )|| Method.isUnaryPreOperatorORDefinedMethod(scan.get(index-1))){ - valid=false; -errorMessage+="\n Bad Syntax! Do Not Concatenate operator "+scan.get(index-1)+" With "+getName(); - }//end if - }//end try -catch(IndexOutOfBoundsException indexErr){ - -}//end catch -try{ -if( isBinaryOperator( scan.get(closeBracket.getIndex()+1) )||isUnaryPostOperator(scan.get(closeBracket.getIndex()+1))){ - valid=false; - errorMessage+="\n Bad Syntax! Do Not Append operator "+scan.get(index-1)+" To "+getName(); - }//end else if -}//end try -catch(IndexOutOfBoundsException indexErr){ - -}//end catch - //validate further - if(valid){ - loopBackwards:{ - boolean openBracsOnly=true; - for(int i=index-1;i>=0;i--){ - //this logic disallows non-listtypestatsoperators from enveloping listtypestatsoperators. - if(isOpeningBracket(scan.get(i))&& Method.isUnaryPreOperatorORDefinedMethod(scan.get(i-1))){ - int compIndex=Bracket.getComplementIndex(true, i, scan); - if(compIndex>closeBracket.getIndex()){ - valid=false; -errorMessage+="\n Bad Syntax! Do Not Embed "+getName()+" In Parentheses Belonging To "+scan.get(i-1); - break loopBackwards; - } -}//end if - - //this logic recognizes the end point of backwards bracket - //validation for a given object of this class. A close bracket - //indicates the end of data that can affect this object - if(isClosingBracket(scan.get(i))|| Method.isStatsMethod(scan.get(i))){ - errorMessage+="\n Ending Backwards Validation For "+getName(); - break loopBackwards; - }//end if - - //this logic (the next two ifs)will disallow binary operations - //on encapsulations of objects of this class - // and their operands within brackets e.g sort(3,2,4)+((sort(1,3,1,-9,3)) -if(!isOpeningBracket(scan.get(i))){ - openBracsOnly = false; -errorMessage+="\n MBracket Sequence Established. Trend Finished. Apllying Other Validation Techniques."; -} - -if(openBracsOnly&&isBinaryOperator( scan.get(i-1) )|| Method.isUnaryPreOperatorORDefinedMethod(scan.get(i-1))){ - valid=false; - errorMessage+="\n Bad Syntax For Data Set Returning Operator "+getName()+"\n" + - "REASON:::"+ - "Cannot Perform Binary Operations On Data Set."; - break loopBackwards; - } - - - }//end for - }//end loopBackwards - - loopForwards:{ - boolean closeBracsOnly=true; - -for(int i=closeBracket.getIndex()+1;i scan) { + boolean valid = true; + + if (!isSuperParent()) { + try { + if (isBinaryOperator(scan.get(index - 1)) + || Method.isUnaryPreOperatorORDefinedMethod(scan.get(index - 1))) { + valid = false; + errorMessage += "\n Bad Syntax! Do Not Concatenate operator " + scan.get(index - 1) + " With " + + getName(); + } // end if + } // end try + catch (IndexOutOfBoundsException indexErr) { + + } // end catch + try { + if (isBinaryOperator(scan.get(closeBracket.getIndex() + 1)) + || isUnaryPostOperator(scan.get(closeBracket.getIndex() + 1))) { + valid = false; + errorMessage += "\n Bad Syntax! Do Not Append operator " + scan.get(index - 1) + " To " + getName(); + } // end else if + } // end try + catch (IndexOutOfBoundsException indexErr) { + + } // end catch + // validate further + if (valid) { + loopBackwards: { + boolean openBracsOnly = true; + for (int i = index - 1; i >= 0; i--) { + // this logic disallows non-listtypestatsoperators from enveloping + // listtypestatsoperators. + if (isOpeningBracket(scan.get(i)) + && Method.isUnaryPreOperatorORDefinedMethod(scan.get(i - 1))) { + int compIndex = Bracket.getComplementIndex(true, i, scan); + if (compIndex > closeBracket.getIndex()) { + valid = false; + errorMessage += "\n Bad Syntax! Do Not Embed " + getName() + + " In Parentheses Belonging To " + scan.get(i - 1); + break loopBackwards; + } + } // end if + + // this logic recognizes the end point of backwards bracket + // validation for a given object of this class. A close bracket + // indicates the end of data that can affect this object + if (isClosingBracket(scan.get(i)) || Method.isStatsMethod(scan.get(i))) { + errorMessage += "\n Ending Backwards Validation For " + getName(); + break loopBackwards; + } // end if + + // this logic (the next two ifs)will disallow binary operations + // on encapsulations of objects of this class + // and their operands within brackets e.g sort(3,2,4)+((sort(1,3,1,-9,3)) + if (!isOpeningBracket(scan.get(i))) { + openBracsOnly = false; + errorMessage += "\n MBracket Sequence Established. Trend Finished. Apllying Other Validation Techniques."; + } + + if (openBracsOnly && isBinaryOperator(scan.get(i - 1)) + || Method.isUnaryPreOperatorORDefinedMethod(scan.get(i - 1))) { + valid = false; + errorMessage += "\n Bad Syntax For Data Set Returning Operator " + getName() + "\n" + + "REASON:::" + + "Cannot Perform Binary Operations On Data Set."; + break loopBackwards; + } + + } // end for + } // end loopBackwards + + loopForwards: { + boolean closeBracsOnly = true; + + for (int i = closeBracket.getIndex() + 1; i < scan.size(); i++) { + + // this logic recognizes the end point of backwards bracket + // validation for a given object of this class. A close bracket + // indicates the end of data that can affect this object + if (isOpeningBracket(scan.get(i)) || Method.isStatsMethod(scan.get(i))) { + break loopForwards; + } // end if + + // this logic (the next two ifs)will disallow binary operations + // on encapsulations of objects of this class + // and their operands within brackets e.g sort(3,2,4)+((sort(1,3,1,-9,3)) + if (!isClosingBracket(scan.get(i))) { + closeBracsOnly = false; + } // end if + try { + if (closeBracsOnly && isBinaryOperator(scan.get(i + 1)) + || isUnaryPostOperator(scan.get(i + 1))) { + valid = false; + break loopForwards; + } // end if + } catch (IndexOutOfBoundsException indexErr) { + + } + + } // end for loop + + } // end loopForwards + + } // end if + + } // end if + + else if (isSuperParent()) { + return true; + } + + return valid; } - - return valid; -} - -/** - * Takes an object of class Function and validates its ListReturningStatsOperators objects. - * @param scan the scanner output - * @return true if valid - */ -public static boolean validateFunction(ArrayListscan){ - -ListReturningStatsOperator list; - boolean validity=true; - - for(int i=0;i scan) { + + ListReturningStatsOperator list; + boolean validity = true; + + for (int i = 0; i < scan.size(); i++) { + if (Method.isListReturningStatsMethod(scan.get(i))) { + list = new ListReturningStatsOperator(scan.get(i), i, scan); + validity = list.validate(scan); + i = list.getCloseBracket().getIndex(); + if (!validity) { + break; + } // end if + } // end if + } // end for + return validity; + }// end method validateFunction(args) @Override public String toString() { - String objectName="ListReturningStatsOperator \""+getName()+"\" located @ index "+index+" has its opening bracket @ "+openBracket.getIndex()+ - " and its closing bracket at "+closeBracket.getIndex()+ - ((isSuperParent())?" and is the root parent of this data set ":" and is not the root parent of this data set "); + String objectName = "ListReturningStatsOperator \"" + getName() + "\" located @ index " + index + + " has its opening bracket @ " + openBracket.getIndex() + + " and its closing bracket at " + closeBracket.getIndex() + + ((isSuperParent()) ? " and is the root parent of this data set " + : " and is not the root parent of this data set "); - return objectName; + return objectName; } + /* + * public static void main(String args[]){ + * + * ArrayListscan= new ArrayList(); + * + * scan = new MathScanner("sum(sort(2,3),sum(3,2))").scanner(null); + * + * ListReturningStatsOperator list = new ListReturningStatsOperator("sum", 0, + * scan); + * + * util.Utils.logError(list.toString()); + * + * util.Utils.logError(list.validate(scan)); + * + * }//end main + * + */ -/* -public static void main(String args[]){ - - ArrayListscan= new ArrayList(); - - scan = new MathScanner("sum(sort(2,3),sum(3,2))").scanner(null); - -ListReturningStatsOperator list = new ListReturningStatsOperator("sum", 0, scan); - - util.Utils.logError(list.toString()); - - util.Utils.logError(list.validate(scan)); - -}//end main - -*/ - - - - - - - - - - - -}//end class \ No newline at end of file +}// end class \ No newline at end of file diff --git a/src/main/java/parser/MathExpression.java b/src/main/java/parser/MathExpression.java index 279a3d0..e072396 100644 --- a/src/main/java/parser/MathExpression.java +++ b/src/main/java/parser/MathExpression.java @@ -62,18 +62,39 @@ public class MathExpression implements Savable, Solvable { public Parser_Result parser_Result = Parser_Result.VALID; - //determines the mode in which trig operations will be carried out on numbers.if DRG==0,it is done in degrees -//if DRG==1, it is done in radians and if it is 2, it is done in grads. + // determines the mode in which trig operations will be carried out on + // numbers.if DRG==0,it is done in degrees + // if DRG==1, it is done in radians and if it is 2, it is done in grads. private DRG_MODE DRG = Declarations.degGradRadFromVariable(); public static String lastResult = "0.0"; - private ArrayList whitespaceremover = new ArrayList<>();//used to remove white spaces from the ArrayList + private ArrayList whitespaceremover = new ArrayList<>();// used to remove white spaces from the ArrayList /** * The expression to evaluate. */ private String expression; - protected boolean correctFunction = true;//checks if the function is valid. + protected boolean correctFunction = true;// checks if the function is valid. protected int noOfListReturningOperators; - protected ArrayList scanner = new ArrayList<>();//the ArrayList that stores the scanner input function + /** + * If true, the expression being evaluated contains any kind of function,e.g. + * sin,cos or other etc + */ + protected boolean hasFunctions; + /** + * If true, the expression being evaluated contains at least one user defined + * function,e.g. + */ + protected boolean hasUserDefinedFunctions; + /** + * If true, the expression being evaluated contains at least one inbuilt + * function,e.g. + * sin,cos or other etc + */ + protected boolean hasInbuiltFunctions; + + + private boolean hasNumberReturningNonUserDefinedFunctions; + + protected ArrayList scanner = new ArrayList<>();// the ArrayList that stores the scanner input function private boolean optimizable; private Bracket[] bracket; protected boolean hasListReturningOperators; @@ -102,6 +123,7 @@ public class MathExpression implements Savable, Solvable { */ private boolean hasFunctionOrVariableInitStatement; + /** * The VariableManager object that allows an object of this class to * remember its variables. @@ -140,12 +162,17 @@ public MathExpression() { /** * * @param input The function to be evaluated. The general format contains - * variable, constant and function declarations for variables, constants and - * functions that are not yet initialized, assignment expressions for those - * that have been initialized and then an expression to evaluate. e.g. x = - * -12; y =x+1/12; const x1,x2,x3=10; z =sin(3x-1)+2.98cos(4x);cos(3x+12); - * The last expression is a function to be evaluated and it is always - * without any equals sign and may or may not end with a semicolon. + * variable, constant and function declarations for variables, + * constants and + * functions that are not yet initialized, assignment expressions + * for those + * that have been initialized and then an expression to evaluate. + * e.g. x = + * -12; y =x+1/12; const x1,x2,x3=10; z + * =sin(3x-1)+2.98cos(4x);cos(3x+12); + * The last expression is a function to be evaluated and it is + * always + * without any equals sign and may or may not end with a semicolon. * */ public MathExpression(String input) { @@ -161,7 +188,7 @@ public MathExpression(String input) { for (String code : scanned) { if (code.contains("=")) { - boolean success = Function.assignObject(code + ";"); + boolean success = Function.assignObject(code + ";", getClass()); if (!success) { correctFunction = success; parser_Result = Parser_Result.SYNTAX_ERROR; @@ -173,15 +200,35 @@ public MathExpression(String input) { ++exprCount; } } - + /** + * The input can contain a lot of evaluate-able expressions, but the real + * expression of focus + * is the one that is a math expression which is not assigned to anything. + * This constructor will evaluate everything else and store as appropriate, but + * will focus on the expression that is not assigned to anything + * as its main expression. For example: + * a=2;b=3;v=6ab;f(x)=9*cos(x);sin(cos(a/b)); + * + * In this input, there exists a number of expressions, but the expression that + * this constructor will adopt as its own expression + * will be sin(cos(a/b)), because it is an expression not assigned to anything + * a=2 and =3 and v=6ab will be evaluated and stored as variables, + * f(x)=9*cos(x) will be used to define and create the function f(x), + * but sin(cos(a/b)) will be the real expression assigned to this + * MathExpression. + * + * If multiple expressions like sin(cos(a/b)) exist in the input, then the + * expression will default to (0.0), + * as there is no way for the parser to know which to choose from. + */ if (mathExpr != null && !mathExpr.isEmpty() && exprCount == 1) { setExpression(mathExpr); - }//end if + } // end if else { setExpression("(0.0)"); } - }//end constructor MathExpression + }// end constructor MathExpression public String getExpression() { return expression; @@ -204,16 +251,17 @@ public final void setExpression(String expression) { /** * * @return true if this object has been scanned and is found valid. In this - * state, objects of this class are optimized to run at very high speeds. + * state, objects of this class are optimized to run at very high + * speeds. */ public boolean isScannedAndOptimized() { try { return !scanner.isEmpty() && correctFunction && this != null; - }//end try + } // end try catch (NullPointerException nol) { return false; - }//end catch - }//end method + } // end catch + }// end method public static void setAutoInitOn(boolean autoInitOn) { MathExpression.autoInitOn = autoInitOn; @@ -229,7 +277,7 @@ private void initializing(String expression) { setHasListReturningOperators(false); setNoOfListReturningOperators(0); whitespaceremover.add(""); - //Scanner operation + // Scanner operation MathScanner opScanner = new MathScanner(expression); scanner = opScanner.scanner(variableManager); @@ -243,9 +291,9 @@ private void initializing(String expression) { removeCommas(); mapBrackets(); functionComponentsAssociation(); - }//end if + } // end if - }//end method initializing(args) + }// end method initializing(args) private void removeCommas() { List commaList = new ArrayList<>(); @@ -274,7 +322,7 @@ public void setDRG(DRG_MODE DRG) { /** * * @return the Brackets ArrayList containing all Bracket objects found in - * the input. + * the input. */ public Bracket[] getBracket() { return bracket; @@ -283,7 +331,7 @@ public Bracket[] getBracket() { /** * * @param bracket the Brackets ArrayList containing all Bracket objects - * found in the input. + * found in the input. */ public void setBracket(Bracket[] bracket) { this.bracket = bracket; @@ -300,7 +348,7 @@ public boolean isCorrectFunction() { /** * * @param correctFunction sets if the input is valid and can be evaluated or - * not. + * not. */ public void setCorrectFunction(boolean correctFunction) { this.correctFunction = correctFunction; @@ -317,7 +365,7 @@ public int getNoOfListReturningOperators() { /** * * @param noOfListReturningOperators sets the number of list returning - * operators found in the input. + * operators found in the input. */ public void setNoOfListReturningOperators(int noOfListReturningOperators) { this.noOfListReturningOperators = noOfListReturningOperators; @@ -366,12 +414,28 @@ public boolean isHasListReturningOperators() { /** * * @param hasListReturningOperators sets the number of list returning - * operators. + * operators. */ public void setHasListReturningOperators(boolean hasListReturningOperators) { this.hasListReturningOperators = hasListReturningOperators; } + public boolean isHasFunctions() { + return hasFunctions; + } + + public boolean isHasInbuiltFunctions() { + return hasInbuiltFunctions; + } + + public boolean isHasUserDefinedFunctions() { + return hasUserDefinedFunctions; + } + + public boolean isHasNumberReturningNonUserDefinedFunctions() { + return hasNumberReturningNonUserDefinedFunctions; + } + /** * * @param optimizable sets whether this input can be optimized. @@ -407,7 +471,7 @@ public static String getLastResult() { /** * * @param hasPreNumberOperators sets whether the input has pre-number - * operators or not + * operators or not */ public void setHasPreNumberOperators(boolean hasPreNumberOperators) { this.hasPreNumberOperators = hasPreNumberOperators; @@ -424,7 +488,7 @@ public boolean isHasPreNumberOperators() { /** * * @param hasLogicOperators sets whether the input has logic operators or - * not. + * not. */ public void setHasLogicOperators(boolean hasLogicOperators) { this.hasLogicOperators = hasLogicOperators; @@ -441,7 +505,7 @@ public boolean isHasLogicOperators() { /** * * @param hasPostNumberOperators sets whether the input has post number - * operators + * operators */ public void setHasPostNumberOperators(boolean hasPostNumberOperators) { this.hasPostNumberOperators = hasPostNumberOperators; @@ -458,7 +522,7 @@ public boolean isHasPostNumberOperators() { /** * * @param hasPowerOperators sets whether or not the input has the power - * operator + * operator */ public void setHasPowerOperators(boolean hasPowerOperators) { this.hasPowerOperators = hasPowerOperators; @@ -475,7 +539,7 @@ public boolean isHasPowerOperators() { /** * * @param hasMulOrDivOperators sets whether the input has multiplication or - * division operators + * division operators */ public void setHasMulOrDivOperators(boolean hasMulOrDivOperators) { this.hasMulOrDivOperators = hasMulOrDivOperators; @@ -504,7 +568,7 @@ public String getReturnObjectName() { /** * * @param hasPlusOrMinusOperators sets whether or not the input contains - * plus or minus operators + * plus or minus operators */ public void setHasPlusOrMinusOperators(boolean hasPlusOrMinusOperators) { this.hasPlusOrMinusOperators = hasPlusOrMinusOperators; @@ -521,7 +585,7 @@ public boolean isHasPlusOrMinusOperators() { /** * * @param hasRemainderOperators sets whether or not remainder operators are - * found in the input + * found in the input */ public void setHasRemainderOperators(boolean hasRemainderOperators) { this.hasRemainderOperators = hasRemainderOperators; @@ -538,7 +602,7 @@ public boolean isHasRemainderOperators() { /** * * @param hasPermOrCombOperators sets whether permutation and combination - * operators are found in the input + * operators are found in the input */ public void setHasPermOrCombOperators(boolean hasPermOrCombOperators) { this.hasPermOrCombOperators = hasPermOrCombOperators; @@ -547,7 +611,7 @@ public void setHasPermOrCombOperators(boolean hasPermOrCombOperators) { /** * * @return true if permutation and combination operators are found in the - * input + * input */ public boolean isHasPermOrCombOperators() { return hasPermOrCombOperators; @@ -556,7 +620,8 @@ public boolean isHasPermOrCombOperators() { /** * * @param hasNumberReturningStatsOperators sets whether or not the input - * contains a data set that will evaluate to a number + * contains a data set that will + * evaluate to a number */ public void setHasNumberReturningStatsOperators(boolean hasNumberReturningStatsOperators) { this.hasNumberReturningStatsOperators = hasNumberReturningStatsOperators; @@ -565,7 +630,7 @@ public void setHasNumberReturningStatsOperators(boolean hasNumberReturningStatsO /** * * @return true if the input contains a data set that will evaluate to a - * number + * number */ public boolean isHasNumberReturningStatsOperators() { return hasNumberReturningStatsOperators; @@ -590,8 +655,9 @@ public void setVariableManager(VariableManager variableManager) { /** * * @return an ArrayList object containing all Variable objects found in the - * current input expression. This is only a subset of all Variable objects - * used in the workspace of operation of this MathExpression object. + * current input expression. This is only a subset of all Variable + * objects + * used in the workspace of operation of this MathExpression object. */ public ArrayList getVars() { @@ -601,20 +667,21 @@ public ArrayList getVars() { if (isVariableString(scanner.get(i)) && !isOpeningBracket(scanner.get(i + 1))) { String str = scanner.get(i); Variable v = VariableManager.lookUp(str); - //Variable does not exist + // Variable does not exist if (v == null) { setCorrectFunction(false); throw new NullPointerException("Variable " + str + " Was Never Initialized!!"); - } //Variable exists + } // Variable exists else { - // if var is in workspace but not yet recognized in this expression, add to usedVars + // if var is in workspace but not yet recognized in this expression, add to + // usedVars if (!usedVars.contains(v)) { usedVars.add(v); } } - }//end if + } // end if - }//end for loop + } // end for loop return usedVars; } @@ -655,80 +722,99 @@ public void unBracketDataSetReturningStatsOperators() { exitForLoop = closeBracIndex <= scanner.size(); break; } - }//end while + } // end while - }//end if + } // end if if (exitForLoop) { break; } - }//end for + } // end for scanner.removeAll(whitespaceremover); - }//end method + }// end method public void statsVerifier() { scanner.removeAll(whitespaceremover); - //determine the presence of list returning statistical operators + // determine the presence of list returning statistical operators for (int i = 0; i < scanner.size(); i++) { - if (Method.isListReturningStatsMethod(scanner.get(i)) && isOpeningBracket(scanner.get(i + 1))) { - noOfListReturningOperators++; - }//end if - - }//end for + String token = scanner.get(i); + if (i - 1 >= 0) { + String prevToken = scanner.get(i - 1); + if (isOpeningBracket(token)) { + if (Method.isListReturningStatsMethod(prevToken)) { + noOfListReturningOperators++; + } if (Method.isDefinedMethod(prevToken)) { + hasFunctions = true; + } if (Method.isInBuiltMethod(prevToken)) { + hasInbuiltFunctions = true; + } if (Method.isUserDefinedFunction(prevToken)) { + hasUserDefinedFunctions = true; + } if (Method.isNumberReturningNonUserDefinedMethod(prevToken)) { + hasNumberReturningNonUserDefinedFunctions = true; + } + } + } + } // end for correctFunction = ListReturningStatsOperator.validateFunction(this.scanner); parser_Result = correctFunction ? Parser_Result.VALID : Parser_Result.SYNTAX_ERROR; - //processLogger.writeLog(ListReturningStatsOperator.getErrorMessage()); + // processLogger.writeLog(ListReturningStatsOperator.getErrorMessage()); if (noOfListReturningOperators > 0 && correctFunction) { setHasListReturningOperators(true); - //disable usage of multiple list operators in function here by un-commenting the statement below + // disable usage of multiple list operators in function here by un-commenting + // the statement below // correctFunction=false; if (isHasListReturningOperators()) { - scanner.remove(0);//temporarily remove the starting bracket - scanner.remove(scanner.size() - 1);//temporarily remove the ending bracket + scanner.remove(0);// temporarily remove the starting bracket + scanner.remove(scanner.size() - 1);// temporarily remove the ending bracket for (int i = 0; i < scanner.size(); i++) { try { if (Method.isListReturningStatsMethod(scanner.get(i)) && isOpeningBracket(scanner.get(i + 1))) { if (isBinaryOperator(scanner.get(i - 1))) { - //processLogger.writeLog("Invalid Association Discovered For: \""+scanner.get(i-1)+"\" And \""+scanner.get(i)+"\".\n"); + // processLogger.writeLog("Invalid Association Discovered For: + // \""+scanner.get(i-1)+"\" And \""+scanner.get(i)+"\".\n"); correctFunction = false; break; } - if (isBracket(scanner.get(i - 1)) && !Method.isNumberReturningStatsMethod(scanner.get(i - 2)) + if (isBracket(scanner.get(i - 1)) + && !Method.isNumberReturningStatsMethod(scanner.get(i - 2)) && !Method.isListReturningStatsMethod(scanner.get(i - 2))) { - //processLogger.writeLog("Invalid Association Discovered For: \"(\" And "+scanner.get(i-2)+" And \""+scanner.get(i-1)+"\" And \""+scanner.get(i)+"\"\n "); + // processLogger.writeLog("Invalid Association Discovered For: \"(\" And + // "+scanner.get(i-2)+" And \""+scanner.get(i-1)+"\" And + // \""+scanner.get(i)+"\"\n "); correctFunction = false; break; } - }//end if - }//end try + } // end if + } // end try catch (IndexOutOfBoundsException ind) { } - }//end for + } // end for scanner.add(0, "("); scanner.add(")"); if (!correctFunction) { parser_Result = Parser_Result.SYNTAX_ERROR; - //processLogger.writeLog("Verifier discovers invalid association between data set returning operators:"); + // processLogger.writeLog("Verifier discovers invalid association between data + // set returning operators:"); } - }//end if isHasListReturningOperator + } // end if isHasListReturningOperator } - }//end method statsVerifier + }// end method statsVerifier /** * e.g in structures like sort(3,sin2,2sin3,5,3,2,sin(4+5),4!...) This @@ -763,12 +849,12 @@ private void evaluateCompoundStructuresInStatisticalInput() { fun = fun.substring(1); fun = fun.substring(0, fun.length() - 1); fun = fun.trim(); - }//end while + } // end while MathExpression f = new MathExpression(fun); String val = f.solve(); scanner.add(open, val); scanner.subList(open + 1, i + 2).clear(); - }//end if + } // end if else if (Method.isDefinedMethod(entry)) { int ind = open - 2; @@ -784,35 +870,35 @@ else if (Method.isDefinedMethod(entry)) { continue; } - //This for loop checks if it is the fix's scenario. e.g. statmethodName(num_or_var operator num_or_var)...e.g. sum(2+3*2...) - // If sum(2, 3+4) WRONG scenario, prod(3*2) CORRECT etc. + // This for loop checks if it is the fix's scenario. e.g. + // statmethodName(num_or_var operator num_or_var)...e.g. sum(2+3*2...) + // If sum(2, 3+4) WRONG scenario, prod(3*2) CORRECT etc. for (int c = open; c < i; c++) { String tkn = scanner.get(c); String nextTkn = scanner.get(c + 1); - if ((isNumber(tkn) || isVariableString(tkn)) && (isNumber(nextTkn) || isVariableString(nextTkn))) { + if ((isNumber(tkn) || isVariableString(tkn)) + && (isNumber(nextTkn) || isVariableString(nextTkn))) { return; } } List domain = new ArrayList<>(opener.getBracketDomainContents(scanner)); - String fun = opener.getDomainContents(scanner); - + while (fun.startsWith("(") && fun.endsWith(")")) { fun = fun.substring(1); fun = fun.substring(0, fun.length() - 1); fun = fun.trim(); - }//end while - + } // end while if (fun.contains(OPEN_CIRC_BRAC)) { - - int op = 0, cl = 0; - - while ( (cl = LISTS.nextIndexOf(domain, cl, CLOSE_CIRC_BRAC)) != -1) { + + int op = 0, cl = 0; + + while ((cl = LISTS.nextIndexOf(domain, cl, CLOSE_CIRC_BRAC)) != -1) { op = Bracket.getComplementIndex(false, cl, domain); - Listl=domain.subList(op, cl+1); + List l = domain.subList(op, cl + 1); List val = solve(l); l.clear(); l.addAll(val); @@ -832,11 +918,12 @@ else if (Method.isDefinedMethod(entry)) { while (ind >= 0 && Operator.isOpeningBracket(scanner.get(ind))) { --ind; - }//end while + } // end while if (ind >= 0) { String v = scanner.get(ind); - if (v.equals("intg") || v.equals("quad") || v.equals("diff") || v.equals("root")) { + if (v.equals("intg") || v.equals("quad") || v.equals("diff") + || v.equals("root")) { Bracket opener = new Bracket("("); opener.setIndex(open); Bracket closer = new Bracket(")"); @@ -856,21 +943,21 @@ else if (Method.isDefinedMethod(entry)) { String val = f.solve(); scanner.add(open, val); scanner.subList(open + 1, i + 2).clear(); - }//end if + } // end if } } - }//end else if + } // end else if } - }//end if - }//end try + } // end if + } // end try catch (IndexOutOfBoundsException boundsException) { boundsException.printStackTrace(); } - }//end for - }//end if - }//end method + } // end for + } // end if + }// end method /** * The method establishes meaning to some shorthand techniques in math that @@ -907,14 +994,14 @@ public void codeModifier() { utility.append(scanner.get(i + 2)); scanner.set(i + 1, utility.toString()); scanner.set(i + 2, ""); - utility.delete(0, utility.length());//clear the builder. - }//end if + utility.delete(0, utility.length());// clear the builder. + } // end if - }//end try + } // end try catch (IndexOutOfBoundsException ind) { - }//end catch + } // end catch - }//end for + } // end for /** * The theory behind this is that any sub-expression that lies @@ -936,12 +1023,17 @@ public void codeModifier() { * (3/4)*sin2 */ try { - if ((isNumber(scanner.get(i)) || (isVariableString(scanner.get(i)) && !Method.isDefinedMethod(scanner.get(i)))) && (Method.isUnaryPreOperatorORDefinedMethod(scanner.get(i + 1)) - || Method.isNumberReturningStatsMethod(scanner.get(i + 1)) || Method.isLogOrAntiLogToAnyBase(scanner.get(i + 1)))) { + if ((isNumber(scanner.get(i)) + || (isVariableString(scanner.get(i)) && !Method.isDefinedMethod(scanner.get(i)))) + && (Method.isUnaryPreOperatorORDefinedMethod(scanner.get(i + 1)) + || Method.isNumberReturningStatsMethod(scanner.get(i + 1)) + || Method.isLogOrAntiLogToAnyBase(scanner.get(i + 1)))) { - //Determine the placement of the close bracket + // Determine the placement of the close bracket int j = i + 1; - while (Method.isUnaryPreOperatorORDefinedMethod(scanner.get(j)) || Method.isNumberReturningStatsMethod(scanner.get(j)) || Method.isLogOrAntiLogToAnyBase(scanner.get(j))) { + while (Method.isUnaryPreOperatorORDefinedMethod(scanner.get(j)) + || Method.isNumberReturningStatsMethod(scanner.get(j)) + || Method.isLogOrAntiLogToAnyBase(scanner.get(j))) { ++j; } if (isNumber(scanner.get(j)) || isVariableString(scanner.get(j))) { @@ -956,10 +1048,10 @@ public void codeModifier() { } - }//end if - }//end try. + } // end if + } // end try. catch (IndexOutOfBoundsException indErr) { - }//end catch + } // end catch try { /** @@ -967,23 +1059,25 @@ public void codeModifier() { * sin(-1*(2+3)). The generic situation is * "preNumberOperator-(expr)" */ - if (Method.isUnaryPreOperatorORDefinedMethod(scanner.get(i - 1)) && Operator.isPlusOrMinus(scanner.get(i)) && isOpeningBracket(scanner.get(i + 1))) { + if (Method.isUnaryPreOperatorORDefinedMethod(scanner.get(i - 1)) + && Operator.isPlusOrMinus(scanner.get(i)) && isOpeningBracket(scanner.get(i + 1))) { if (scanner.get(i).equals(MINUS)) { - List subList = scanner.subList(i - 1, Bracket.getComplementIndex(true, i + 1, scanner) + 1); + List subList = scanner.subList(i - 1, + Bracket.getComplementIndex(true, i + 1, scanner) + 1); subList.set(1, "("); subList.add(2, "-1"); subList.add(3, MULTIPLY); subList.add(")"); - }//end if + } // end if else if (scanner.get(i).equals(PLUS)) { scanner.set(i, ""); } - }//end if - }//end try + } // end if + } // end try catch (IndexOutOfBoundsException ind) { - }//end catch + } // end catch try { /** @@ -991,7 +1085,8 @@ else if (scanner.get(i).equals(PLUS)) { * -1*sin2+3 if this is not done, it would be evaluated as * -(sin2+3) */ - if (isOpeningBracket(scanner.get(i - 1)) && Operator.isPlusOrMinus(scanner.get(i)) && Method.isUnaryPreOperatorORDefinedMethod(scanner.get(i + 1))) { + if (isOpeningBracket(scanner.get(i - 1)) && Operator.isPlusOrMinus(scanner.get(i)) + && Method.isUnaryPreOperatorORDefinedMethod(scanner.get(i + 1))) { if (scanner.get(i).equals(MINUS)) { scanner.set(i, "-1"); scanner.add(i + 1, MULTIPLY); @@ -999,20 +1094,21 @@ else if (scanner.get(i).equals(PLUS)) { scanner.set(i, ""); } } - }//end try + } // end try catch (IndexOutOfBoundsException ind) { - }//end catch + } // end catch - }//end for + } // end for scanner.removeAll(whitespaceremover); } else if (!correctFunction) { - //processLogger.writeLog("Beginning Parser Shutdown Tasks Due To Errors In User Input."); + // processLogger.writeLog("Beginning Parser Shutdown Tasks Due To Errors In User + // Input."); } detectKeyOperators(); - }//end method codeModifier + }// end method codeModifier /** * Serves as a powerful optimizer of the evaluation section as it can govern @@ -1020,33 +1116,34 @@ else if (scanner.get(i).equals(PLUS)) { */ public void detectKeyOperators() { for (int i = 0; i < scanner.size(); i++) { - if (isPlusOrMinus(scanner.get(i))) { + String token = scanner.get(i); + if (isPlusOrMinus(token)) { setHasPlusOrMinusOperators(true); - } else if (isUnaryPreOperator(scanner.get(i))) { + } else if (isUnaryPreOperator(token)) { setHasPreNumberOperators(true); - } else if (isUnaryPostOperator(scanner.get(i))) { + } else if (isUnaryPostOperator(token)) { setHasPostNumberOperators(true); - } else if (isMulOrDiv(scanner.get(i))) { + } else if (isMulOrDiv(token)) { setHasMulOrDivOperators(true); - } else if (isPermOrComb(scanner.get(i))) { + } else if (isPermOrComb(token)) { setHasPermOrCombOperators(true); - } else if (isRemainder(scanner.get(i))) { + } else if (isRemainder(token)) { setHasRemainderOperators(true); - } else if (Method.isNumberReturningStatsMethod(scanner.get(i))) { + } else if (Method.isNumberReturningStatsMethod(token)) { setHasNumberReturningStatsOperators(true); - } else if (isPower(scanner.get(i))) { + } else if (isPower(token)) { setHasPowerOperators(true); - } else if (isLogicOperator(scanner.get(i))) { + } else if (isLogicOperator(token)) { setHasLogicOperators(true); } - }//end for + } // end for } /** * * @param scanner The ArrayList object that holds the string values in the - * scanned function. + * scanned function. * @return a Bracket array that holds related brackets pairs. */ public static Bracket[] mapBrackets(ArrayList scanner) { @@ -1058,8 +1155,8 @@ public static Bracket[] mapBrackets(ArrayList scanner) { ArrayList scan = new ArrayList<>(); scan.addAll(scanner); - int open = 0;//tracks the index of an opening bracket - int close = scan.indexOf(")");//tracks the index of a closing bracket + int open = 0;// tracks the index of an opening bracket + int close = scan.indexOf(")");// tracks the index of a closing bracket int i = 0; while (close != -1) { try { @@ -1079,13 +1176,14 @@ public static Bracket[] mapBrackets(ArrayList scanner) { close = scan.indexOf(")"); ++i; - }//end try + } // end try catch (IndexOutOfBoundsException ind) { break; } - }//end while + } // end while -//after the mapping the algorithm demands that all ( and ) should have been used up in the function + // after the mapping the algorithm demands that all ( and ) should have been + // used up in the function if (scan.indexOf("(") == -1 && scan.indexOf(")") == -1) { int size = bracs.size(); Bracket[] bracket = new Bracket[size]; @@ -1094,7 +1192,7 @@ public static Bracket[] mapBrackets(ArrayList scanner) { throw new InputMismatchException("SYNTAX ERROR!"); } - }//end method + }// end method /** * Method mapBrackets goes over an input equation and maps all positions @@ -1103,14 +1201,14 @@ public static Bracket[] mapBrackets(ArrayList scanner) { public void mapBrackets() { try { setBracket(mapBrackets(scanner)); - }//end method + } // end method catch (InputMismatchException ime) { parser_Result = Parser_Result.PARENTHESES_ERROR; setCorrectFunction(false); scanner.clear(); - }//end catch + } // end catch - }//end method + }// end method /** * @@ -1121,65 +1219,73 @@ public void mapBrackets() { public void functionComponentsAssociation() { if (correctFunction) { - scanner.removeAll(whitespaceremover);//remove white spaces that may result from past parser actions -//check for good combinations of operators and numbers and dis-allow any other. + scanner.removeAll(whitespaceremover);// remove white spaces that may result from past parser actions + // check for good combinations of operators and numbers and dis-allow any other. for (int i = 0; i < scanner.size(); i++) { -//check for the various valid arrangements for all members of the function. + // check for the various valid arrangements for all members of the function. String token = scanner.get(i); - //Variables + // Variables if (isVariableString(scanner.get(i)) && !Method.isUserDefinedFunction(token)) { try { - //specify valid tokens that can come before a variable + // specify valid tokens that can come before a variable if (!isOpeningBracket(scanner.get(i - 1)) && !isLogicOperator(scanner.get(i - 1)) && !isUnaryPreOperator(scanner.get(i - 1)) - && !isBinaryOperator(scanner.get(i - 1)) && !isAssignmentOperator(scanner.get(i - 1)) && !isNumber(scanner.get(i - 1)) + && !isBinaryOperator(scanner.get(i - 1)) && !isAssignmentOperator(scanner.get(i - 1)) + && !isNumber(scanner.get(i - 1)) && !isVariableString(scanner.get(i - 1))) { - //processLogger.writeLog("ParserNG Does Not Allow "+expression+" To Combine The MathExpression Members \""+scanner.get(i-1)+"\" And \""+scanner.get(i)+"\"\n"); + // processLogger.writeLog("ParserNG Does Not Allow "+expression+" To Combine The + // MathExpression Members \""+scanner.get(i-1)+"\" And + // \""+scanner.get(i)+"\"\n"); correctFunction = false; scanner.clear(); break; - }//end if - //specify valid tokens that can come after a variable + } // end if + // specify valid tokens that can come after a variable if (!isBracket(scanner.get(i + 1)) && !isBinaryOperator(scanner.get(i + 1)) - && !isUnaryPostOperator(scanner.get(i + 1)) && !Method.isNumberReturningStatsMethod(scanner.get(i + 1)) + && !isUnaryPostOperator(scanner.get(i + 1)) + && !Method.isNumberReturningStatsMethod(scanner.get(i + 1)) && !isLogicOperator(scanner.get(i + 1)) && !isAssignmentOperator(scanner.get(i + 1)) - && !isUnaryPreOperator(scanner.get(i + 1)) && !Method.isNumberReturningStatsMethod(scanner.get(i + 1)) - && !Method.isLogToAnyBase(scanner.get(i + 1)) && !Method.isAntiLogToAnyBase(scanner.get(i + 1)) && !isNumber(scanner.get(i + 1)) + && !isUnaryPreOperator(scanner.get(i + 1)) + && !Method.isNumberReturningStatsMethod(scanner.get(i + 1)) + && !Method.isLogToAnyBase(scanner.get(i + 1)) + && !Method.isAntiLogToAnyBase(scanner.get(i + 1)) && !isNumber(scanner.get(i + 1)) && !isVariableString(scanner.get(i + 1))) { - //processLogger.writeLog("ParserNG Does Not Allow "+expression+" To Combine The MathExpression Members \""+scanner.get(i)+"\" And \""+scanner.get(i+1)+"\"PLUS As You Have Done.\n"); + // processLogger.writeLog("ParserNG Does Not Allow "+expression+" To Combine The + // MathExpression Members \""+scanner.get(i)+"\" And + // \""+scanner.get(i+1)+"\"PLUS As You Have Done.\n"); correctFunction = false; scanner.clear(); break; - }//end if - }//end try + } // end if + } // end try catch (IndexOutOfBoundsException ind) { - }//end catch - }//end else if + } // end catch + } // end else if - }//end for + } // end for if (correctFunction) { setCorrectFunction(validateAll(scanner)); } if (correctFunction) { scanner.removeAll(whitespaceremover); - }//end if + } // end if else { scanner.clear(); bracket = null; parser_Result = Parser_Result.SYNTAX_ERROR; - }//end else + } // end else - }//end if + } // end if else { scanner.clear(); bracket = null; parser_Result = Parser_Result.SYNTAX_ERROR; } - }//end method functionComponentAssociation + }// end method functionComponentAssociation /** * An important process that must occur before the function is solved. @@ -1200,29 +1306,29 @@ public void setVariableValuesInFunction(ArrayList scan) { String varName = scan.get(i); try { - if (i + 1 < sz) {//a next token exists (at i+1) so check the next token + if (i + 1 < sz) {// a next token exists (at i+1) so check the next token if (isVariableString(scan.get(i)) && !isOpeningBracket(scan.get(i + 1))) { Variable v = VariableManager.lookUp(varName); if (v != null) { scan.set(i, v.getValue()); } - }//end if - } else {//no next token exists + } // end if + } else {// no next token exists if (isVariableString(scan.get(i))) { Variable v = VariableManager.lookUp(varName); if (v != null) { scan.set(i, v.getValue()); } - }//end if + } // end if } - }//end try + } // end try catch (IndexOutOfBoundsException ind) { - }//end catch + } // end catch - }//end for + } // end for }// end method @@ -1231,7 +1337,7 @@ public void setVariableValuesInFunction(ArrayList scan) { * @param name The name of the variable or constant. * @return the value of the named variable or constant * @throws NullPointerException if a Variable object that has that name id - * not found. + * not found. */ public String getValue(String name) throws NullPointerException { Variable var = variableManager.lookUp(name); @@ -1240,10 +1346,10 @@ public String getValue(String name) throws NullPointerException { /** * - * @param name The name of the variable or constant. + * @param name The name of the variable or constant. * @param value The value to set to the variable * @throws NullPointerException if a Variable object that has that name id - * not found. + * not found. */ public void setValue(String name, String value) throws NullPointerException, NumberFormatException { Variable v = VariableManager.lookUp(name); @@ -1282,12 +1388,12 @@ public void setValue(String name, String value) throws NullPointerException, Num * shrinking factor to it.Else we continue the scan. * * - * @param brac the Bracket store to modify + * @param brac the Bracket store to modify * @param startPosition the index in the ArrayList where the modification is - * to start - * @param increment the amount by which each bracket index is to be - * decreased - * @param run will run this method if given the sign to do so. + * to start + * @param increment the amount by which each bracket index is to be + * decreased + * @param run will run this method if given the sign to do so. */ protected void modifyBracketIndices(Bracket[] brac, int startPosition, int increment, boolean run) { if (run) { @@ -1298,29 +1404,31 @@ protected void modifyBracketIndices(Bracket[] brac, int startPosition, int incre for (int i = startPosition; i < brac.length; i++) { valAtBracIndex = brac[i].getIndex(); -//values greater than the value stored by the bracket from which looping was started the -// last time represent the indices of bracket in the function list that the compression function -// will affect.So apply the decrement to them. + // values greater than the value stored by the bracket from which looping was + // started the + // last time represent the indices of bracket in the function list that the + // compression function + // will affect.So apply the decrement to them. try { if (valAtBracIndex > valAtLastEvaluatedBracIndex) { brac[i].setIndex(brac[i].getIndex() + increment); - }//end if - }//end try + } // end if + } // end try catch (IndexOutOfBoundsException indexErr) { - }//end catch - }//end for + } // end catch + } // end for ArrayList arr = new ArrayList(); for (int i = 0; i < brac.length; i++) { arr.add(brac[i].getIndex()); } - //displayIndicesStoredInBrackets(); + // displayIndicesStoredInBrackets(); } } - }//end method reduceBracketIndices -//(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1) + }// end method reduceBracketIndices + // (1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1)(1+1+1+1+1+1+1+1+1+1) /** * Display the indices of all brackets in the function,bracket pair by @@ -1343,7 +1451,7 @@ private void displayIndicesStoredInBrackets() { * * @param scan The ArrayList object. * @return the string version of the ArrayList and removes the braces i.e. - * [] + * [] */ protected String listToString(ArrayList scan) { String str = String.valueOf(scan); @@ -1355,7 +1463,7 @@ protected String listToString(ArrayList scan) { /** * * @return an Array object containing duplicate contents of the List object - * alone + * alone */ protected Bracket[] copyArrayToArray() { int size = bracket.length; @@ -1406,30 +1514,30 @@ public String solve() { if (!correctFunction) { break; - }//end if + } // end if else { try { indexOpenInMyScan = brac[0].getIndex(); indexCloseInMyScan = brac[1].getIndex(); - boolean isMethod = false;//only list returning data sets e.g sort,rnd... + boolean isMethod = false;// only list returning data sets e.g sort,rnd... List executable = null; try { isMethod = Method.isMethodName(myScan.get(indexOpenInMyScan - 1)); - }//end try + } // end try catch (IndexOutOfBoundsException indexErr) { isMethod = false; } try { executable = myScan.subList(indexOpenInMyScan, indexCloseInMyScan + 1);// - }//end try + } // end try catch (IndexOutOfBoundsException indexErr) { } if (!isMethod) { solve(executable); - }//end if + } // end if else if (isMethod) { try { @@ -1441,10 +1549,9 @@ else if (isMethod) { */ executable = myScan.subList(indexOpenInMyScan - 1, indexCloseInMyScan + 1); if (Method.isStatsMethod(executable.get(0))) { - if (!Method.isUserDefinedFunction(executable.get(0))) { Method.run(executable, DRG); - }//end if + } // end if else if (Method.isUserDefinedFunction(executable.get(0))) { Function f = FunctionManager.lookUp(executable.get(0)); @@ -1455,11 +1562,11 @@ else if (Method.isUserDefinedFunction(executable.get(0))) { Method.run(executable, DRG); } else { Method.run(executable, DRG); - }//end else + } // end else - }//end else if + } // end else if - }//end if + } // end if else { solve(executable.subList(1, executable.size())); @@ -1476,24 +1583,24 @@ else if (Method.isUserDefinedFunction(executable.get(0))) { } catch (NullPointerException nolException) { break; } - }//end else if + } // end else if brac = mapBrackets(myScan); - }//end try + } // end try catch (IndexOutOfBoundsException indexErr) { indexErr.printStackTrace(); return "SYNTAX ERROR"; - }//end catch + } // end catch catch (NumberFormatException numErr) { numErr.printStackTrace(); return "SYNTAX ERROR"; - }//end catch + } // end catch catch (InputMismatchException exception) { exception.printStackTrace(); return "SYNTAX ERROR"; } - }//end else + } // end else - }//end while + } // end while listAppender = listToString(myScan); if (listAppender.startsWith("(")) { @@ -1526,13 +1633,13 @@ else if (Method.isUserDefinedFunction(executable.get(0))) { } - //designed to deduce if or not the evaluating loop executed normally. - //If it didn't the statements in the else will execute + // designed to deduce if or not the evaluating loop executed normally. + // If it didn't the statements in the else will execute if (correctFunction) { lastResult = listAppender; - }//end if - //give an error statement and then reset correctFunction to true; + } // end if + // give an error statement and then reset correctFunction to true; else { listAppender = "A SYNTAX ERROR OCCURRED"; correctFunction = true; @@ -1541,14 +1648,14 @@ else if (Method.isUserDefinedFunction(executable.get(0))) { returnObjectName = myScan.get(0); } return listAppender; - }//end if + } // end if else if (hasFunctionOrVariableInitStatement) { return "Variable Storage Process Finished!"; } else { return "SYNTAX ERROR"; } - }//end method solve() + }// end method solve() /** * used by the main parser solve to figure out SBP portions of a @@ -1559,30 +1666,32 @@ else if (hasFunctionOrVariableInitStatement) { */ protected List solve(List list) { -//correct the anomaly: [ (,-,number....,) ] - // turn it into: [ (,,-number........,) ] - //The double commas show that there exists an empty location in between the 2 commas + // correct the anomaly: [ (,-,number....,) ] + // turn it into: [ (,,-number........,) ] + // The double commas show that there exists an empty location in between the 2 + // commas if (list.get(0).equals("(") && list.get(1).equals(MINUS) && isNumber(list.get(2))) { list.set(1, ""); - //if the number is negative,make it positive + // if the number is negative,make it positive if (list.get(2).substring(0, 1).equals(MINUS)) { list.set(2, list.get(2).substring(1)); - } //if the number is positive,make it negative + } // if the number is positive,make it negative else { list.set(2, MINUS + list.get(2)); } } -//Create a collection to serve as a garbage collector for the empty memory -//locations and other unwanted locations created in the processing collection + // Create a collection to serve as a garbage collector for the empty memory + // locations and other unwanted locations created in the processing collection ArrayList garbage = new ArrayList<>(); -//insert an empty string in it so that we can use it to remove empty spaces from the processing collection. + // insert an empty string in it so that we can use it to remove empty spaces + // from the processing collection. garbage.add(""); garbage.add("("); garbage.add(")"); list.removeAll(garbage); -//solves the factorial component of the input|[²]|[³]|[-¹]²³-¹ + // solves the factorial component of the input|[²]|[³]|[-¹]²³-¹ if (isHasPostNumberOperators()) { for (int i = 0; i < list.size(); i++) { try { @@ -1591,30 +1700,30 @@ protected List solve(List list) { if (isNumber(list.get(i))) { list.set(i + 1, Maths.fact(list.get(i))); list.set(i, ""); - }//end if + } // end if else if (list.get(i).equals("Infinity")) { list.set(i + 1, "Infinity"); list.set(i, ""); - }//end else + } // end else } else if (isSquare(list.get(i + 1))) { if (isNumber(list.get(i))) { list.set(i + 1, String.valueOf(Math.pow(Double.parseDouble(list.get(i)), 2))); list.set(i, ""); - }//end if + } // end if else if (list.get(i).equals("Infinity")) { list.set(i + 1, "Infinity"); list.set(i, ""); - }//end else + } // end else } else if (isCube(list.get(i + 1))) { if (isNumber(list.get(i))) { list.set(i + 1, String.valueOf(Math.pow(Double.parseDouble(list.get(i)), 3))); list.set(i, ""); - }//end if + } // end if else if (list.get(i).equals("Infinity")) { list.set(i + 1, "Infinity"); list.set(i, ""); - }//end else + } // end else } else if (isInverse(list.get(i + 1))) { if (isNumber(list.get(i))) { list.set(i + 1, String.valueOf(1 / Double.parseDouble(list.get(i)))); @@ -1622,34 +1731,39 @@ else if (list.get(i).equals("Infinity")) { } else if (list.get(i).equals("Infinity")) { list.set(i + 1, "0.0"); list.set(i, ""); - }//end else + } // end else } - }//end try + } // end try catch (NumberFormatException numerror) { } catch (NullPointerException nullerror) { } catch (IndexOutOfBoundsException inderror) { } - }//end for + } // end for list.removeAll(garbage); - }//end if + } // end if if (isHasPowerOperators()) { - /*Deals with powers. - Handles the primary power operator e.g in 3^sin3^4.This is necessary at this stage to dis-allow operations like sinA^Bfrom giving the result:(sinA)^B - instead of sin(A^B). - Also instructs the software to multiply any 2 numbers in consecutive positions in the list. - This is important in distinguishing between functions such as sinAB and sinA*B.Note:sinAB=sin(A*B),while sinA*B=B*sinA. + /* + * Deals with powers. + * Handles the primary power operator e.g in 3^sin3^4.This is necessary at this + * stage to dis-allow operations like sinA^Bfrom giving the result:(sinA)^B + * instead of sin(A^B). + * Also instructs the software to multiply any 2 numbers in consecutive + * positions in the list. + * This is important in distinguishing between functions such as sinAB and + * sinA*B.Note:sinAB=sin(A*B),while sinA*B=B*sinA. */ for (int i = 0; i < list.size(); i++) { try { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { if (list.get(i).equals(POWER) && isNumber(list.get(i - 1)) && isNumber(list.get(i + 1))) { - list.set(i + 1, String.valueOf(Math.pow(Double.parseDouble(list.get(i - 1)), Double.parseDouble(list.get(i + 1))))); + list.set(i + 1, String.valueOf(Math.pow(Double.parseDouble(list.get(i - 1)), + Double.parseDouble(list.get(i + 1))))); list.set(i - 1, ""); list.set(i, ""); - }//end if - }//end if + } // end if + } // end if else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { if (Double.parseDouble(list.get(i + 1)) > 1) { list.set(i + 1, "Infinity"); @@ -1663,7 +1777,8 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity list.set(i + 1, "Infinity"); list.set(i - 1, ""); list.set(i, ""); - } else if (Double.parseDouble(list.get(i + 1)) < 1 && Double.parseDouble(list.get(i + 1)) == 0) { + } else if (Double.parseDouble(list.get(i + 1)) < 1 + && Double.parseDouble(list.get(i + 1)) == 0) { list.set(i + 1, "1.0"); list.set(i - 1, ""); list.set(i, ""); @@ -1685,7 +1800,8 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity list.set(i + 1, "0.0"); list.set(i - 1, ""); list.set(i, ""); - } else if (Double.parseDouble(list.get(i - 1)) < 1 && Double.parseDouble(list.get(i - 1)) == 0) { + } else if (Double.parseDouble(list.get(i - 1)) < 1 + && Double.parseDouble(list.get(i - 1)) == 0) { list.set(i + 1, "0.0"); list.set(i - 1, ""); list.set(i, ""); @@ -1693,25 +1809,25 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity list.set(i + 1, "Infinity"); list.set(i - 1, ""); list.set(i, ""); - }//end else if - }//end else if + } // end else if + } // end else if else if (list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity")) { list.set(i + 1, "Infinity"); list.set(i - 1, ""); list.set(i, ""); } - }//end try + } // end try catch (NumberFormatException numerror) { } catch (NullPointerException nullerror) { } catch (IndexOutOfBoundsException inderror) { } - }//end for + } // end for list.removeAll(garbage); - }//end if - //Handles the pre-number operators. + } // end if + // Handles the pre-number operators. if (isHasPreNumberOperators()) { for (int i = list.size() - 1; i >= 0; i--) { @@ -1720,44 +1836,50 @@ else if (list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity" if (list.get(i).equals(ROOT)) { list.set(i, String.valueOf(Math.sqrt(Double.parseDouble(list.get(i + 1))))); list.set(i + 1, ""); - }//end if + } // end if if (list.get(i).equals(CUBE_ROOT)) { list.set(i, String.valueOf(Math.cbrt(Double.parseDouble(list.get(i + 1))))); list.set(i + 1, ""); - }//end if -//add more pre-number functions here... - }//end if + } // end if + // add more pre-number functions here... + } // end if else if (list.get(i + 1).equals("Infinity")) { list.set(i, "Infinity"); list.set(i + 1, ""); - }//end else if - }//end try + } // end else if + } // end try catch (NumberFormatException numerror) { } catch (NullPointerException nullerror) { } catch (IndexOutOfBoundsException inderror) { } - }//end for - }//end if + } // end for + } // end if list.removeAll(garbage); if (isHasPowerOperators()) { - //do the in between operators - - /*Deals with powers.Handles the primary power operator e.g in 3^sin3^4.This is necessary at this stage to dis-allow operations like sinA^Bfrom giving the result:(sinA)^B - instead of sin(A^B). - Also instructs the software to multiply any 2 numbers in consecutive positions in the vector. - This is important in distinguishing between functions such as sinAB and sinA*B.Note:sinAB=sin(A*B),while sinA*B=B*sinA. + // do the in between operators + + /* + * Deals with powers.Handles the primary power operator e.g in 3^sin3^4.This is + * necessary at this stage to dis-allow operations like sinA^Bfrom giving the + * result:(sinA)^B + * instead of sin(A^B). + * Also instructs the software to multiply any 2 numbers in consecutive + * positions in the vector. + * This is important in distinguishing between functions such as sinAB and + * sinA*B.Note:sinAB=sin(A*B),while sinA*B=B*sinA. */ for (int i = 0; i < list.size(); i++) { try { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { if (list.get(i).equals(POWER) && isNumber(list.get(i - 1)) && isNumber(list.get(i + 1))) { - list.set(i + 1, String.valueOf(Math.pow(Double.parseDouble(list.get(i - 1)), Double.parseDouble(list.get(i + 1))))); + list.set(i + 1, String.valueOf(Math.pow(Double.parseDouble(list.get(i - 1)), + Double.parseDouble(list.get(i + 1))))); list.set(i - 1, ""); list.set(i, ""); - }//end if - }//end if + } // end if + } // end if else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { if (Double.parseDouble(list.get(i + 1)) > 1) { list.set(i + 1, "Infinity"); @@ -1771,7 +1893,8 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity list.set(i + 1, "Infinity"); list.set(i - 1, ""); list.set(i, ""); - } else if (Double.parseDouble(list.get(i + 1)) < 1 && Double.parseDouble(list.get(i + 1)) == 0) { + } else if (Double.parseDouble(list.get(i + 1)) < 1 + && Double.parseDouble(list.get(i + 1)) == 0) { list.set(i + 1, "1.0"); list.set(i - 1, ""); list.set(i, ""); @@ -1793,7 +1916,8 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity list.set(i + 1, "0.0"); list.set(i - 1, ""); list.set(i, ""); - } else if (Double.parseDouble(list.get(i - 1)) < 1 && Double.parseDouble(list.get(i - 1)) == 0) { + } else if (Double.parseDouble(list.get(i - 1)) < 1 + && Double.parseDouble(list.get(i - 1)) == 0) { list.set(i + 1, "0.0"); list.set(i - 1, ""); list.set(i, ""); @@ -1801,38 +1925,40 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity list.set(i + 1, "Infinity"); list.set(i - 1, ""); list.set(i, ""); - }//end else if - }//end else if + } // end else if + } // end else if else if (list.get(i - 1).equals("Infinity") && list.get(i + 1).equals("Infinity")) { list.set(i + 1, "Infinity"); list.set(i - 1, ""); list.set(i, ""); } - }//end try + } // end try catch (NumberFormatException numerror) { } catch (NullPointerException nullerror) { } catch (IndexOutOfBoundsException inderror) { } - }//end for + } // end for list.removeAll(garbage); - }//end if + } // end if list.removeAll(garbage); if (isHasPermOrCombOperators()) { - //do the lower precedence in between operators + // do the lower precedence in between operators for (int i = 0; i < list.size(); i++) { try { if (list.get(i).equals(Operator.PERMUTATION)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf(Double.parseDouble(Maths.fact(list.get(i - 1))) / (Double.parseDouble(Maths.fact(String.valueOf(Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1)))))))); + list.set(i + 1, String.valueOf(Double.parseDouble(Maths.fact(list.get(i - 1))) + / (Double.parseDouble(Maths.fact(String.valueOf(Double.parseDouble(list.get(i - 1)) + - Double.parseDouble(list.get(i + 1)))))))); list.set(i - 1, ""); list.set(i, ""); - }//end if + } // end if else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { list.set(i + 1, "Infinity"); list.set(i - 1, ""); @@ -1847,13 +1973,16 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity list.set(i, ""); } - }//end if + } // end if else if (list.get(i).equals(Operator.COMBINATION)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf(Double.parseDouble(Maths.fact(list.get(i - 1))) / (Double.parseDouble(Maths.fact(String.valueOf(Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1))))) * Double.parseDouble(Maths.fact(list.get(i + 1)))))); + list.set(i + 1, String.valueOf(Double.parseDouble(Maths.fact(list.get(i - 1))) / (Double + .parseDouble(Maths.fact(String.valueOf( + Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1))))) + * Double.parseDouble(Maths.fact(list.get(i + 1)))))); list.set(i - 1, ""); list.set(i, ""); - }//end if + } // end if else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { list.set(i + 1, "Infinity"); list.set(i - 1, ""); @@ -1868,19 +1997,19 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity list.set(i, ""); } - }//end else if + } // end else if - }//end try + } // end try catch (NullPointerException nolan) { - }//end catch + } // end catch catch (NumberFormatException numerr) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderr) { - }//end catch + } // end catch - }//end for + } // end for list.removeAll(garbage); - }//end if + } // end if boolean skip = false; if (isHasMulOrDivOperators() || isHasRemainderOperators() || isHasLogicOperators()) { for (int i = 0; i < list.size(); i++) { @@ -1889,7 +2018,8 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity if (list.get(i).equals(MULTIPLY)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf(Double.parseDouble(list.get(i - 1)) * Double.parseDouble(list.get(i + 1)))); + list.set(i + 1, String.valueOf( + Double.parseDouble(list.get(i - 1)) * Double.parseDouble(list.get(i + 1)))); list.set(i - 1, ""); list.set(i, ""); skip = true; @@ -1910,10 +2040,11 @@ else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity skip = true; } - }//end if + } // end if else if (list.get(i).equals(DIVIDE)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf(Double.parseDouble(list.get(i - 1)) / Double.parseDouble(list.get(i + 1)))); + list.set(i + 1, String.valueOf( + Double.parseDouble(list.get(i - 1)) / Double.parseDouble(list.get(i + 1)))); list.set(i - 1, ""); list.set(i, ""); skip = true; @@ -1934,10 +2065,11 @@ else if (list.get(i).equals(DIVIDE)) { skip = true; } - }//end else if + } // end else if else if (list.get(i).equals(REMAINDER)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf(Double.parseDouble(list.get(i - 1)) % Double.parseDouble(list.get(i + 1)))); + list.set(i + 1, String.valueOf( + Double.parseDouble(list.get(i - 1)) % Double.parseDouble(list.get(i + 1)))); list.set(i - 1, ""); list.set(i, ""); skip = true; @@ -1958,21 +2090,22 @@ else if (list.get(i).equals(REMAINDER)) { skip = true; } - }//end else if - }//end try + } // end else if + } // end try catch (NullPointerException nolan) { - }//end catch + } // end catch catch (NumberFormatException numerr) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderr) { - }//end catch + } // end catch if (!skip) { try { if (list.get(i).equals(EQUALS)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1))) == 0)); + list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) + - Double.parseDouble(list.get(i + 1))) == 0)); list.set(i - 1, ""); list.set(i, ""); } else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { @@ -1989,19 +2122,20 @@ else if (list.get(i).equals(REMAINDER)) { list.set(i, ""); } } - }//end try + } // end try catch (NullPointerException nolerr) { - }//end catch + } // end catch catch (NumberFormatException numerr) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderr) { - }//end catch + } // end catch try { if (list.get(i).equals(GREATER_THAN)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1))) > 0)); + list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) + - Double.parseDouble(list.get(i + 1))) > 0)); list.set(i - 1, ""); list.set(i, ""); } else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { @@ -2018,19 +2152,20 @@ else if (list.get(i).equals(REMAINDER)) { list.set(i, ""); } } - }//end try + } // end try catch (NullPointerException nolerr) { - }//end catch + } // end catch catch (NumberFormatException numerr) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderr) { - }//end catch + } // end catch try { if (list.get(i).equals(GREATER_OR_EQUALS)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1))) >= 0)); + list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) + - Double.parseDouble(list.get(i + 1))) >= 0)); list.set(i - 1, ""); list.set(i, ""); } else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { @@ -2047,19 +2182,20 @@ else if (list.get(i).equals(REMAINDER)) { list.set(i, ""); } } - }//end try + } // end try catch (NullPointerException nolerr) { - }//end catch + } // end catch catch (NumberFormatException numerr) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderr) { - }//end catch + } // end catch try { if (list.get(i).equals(LESS_THAN)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1))) < 0)); + list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) + - Double.parseDouble(list.get(i + 1))) < 0)); list.set(i - 1, ""); list.set(i, ""); } else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { @@ -2076,20 +2212,21 @@ else if (list.get(i).equals(REMAINDER)) { list.set(i, ""); } - }//end if - }//end try + } // end if + } // end try catch (NullPointerException nolerr) { - }//end catch + } // end catch catch (NumberFormatException numerr) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderr) { - }//end catch + } // end catch try { if (list.get(i).equals(LESS_OR_EQUALS)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { - list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1))) <= 0)); + list.set(i + 1, String.valueOf((Double.parseDouble(list.get(i - 1)) + - Double.parseDouble(list.get(i + 1))) <= 0)); list.set(i - 1, ""); list.set(i, ""); } else if (list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { @@ -2105,39 +2242,42 @@ else if (list.get(i).equals(REMAINDER)) { list.set(i - 1, ""); list.set(i, ""); } - }//end if + } // end if - }//end try + } // end try catch (NullPointerException nolerr) { - }//end catch + } // end catch catch (NumberFormatException numerr) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderr) { - }//end catch + } // end catch - }//end if (skip) - }//end for + } // end if (skip) + } // end for list.removeAll(garbage); - }//end if + } // end if if (isHasPlusOrMinusOperators()) { - //Handles the subtraction and addition operators + // Handles the subtraction and addition operators for (int i = 0; i < list.size(); i++) { try { if (list.get(i).equals(PLUS) || list.get(i).equals(MINUS)) { if (!list.get(i - 1).equals("Infinity") && !list.get(i + 1).equals("Infinity")) { if (list.get(i).equals(PLUS) && isNumber(list.get(i - 1)) && isNumber(list.get(i + 1))) { - list.set(i + 1, String.valueOf(Double.parseDouble(list.get(i - 1)) + Double.parseDouble(list.get(i + 1)))); + list.set(i + 1, String.valueOf( + Double.parseDouble(list.get(i - 1)) + Double.parseDouble(list.get(i + 1)))); list.set(i - 1, ""); list.set(i, ""); - }//end else - else if (list.get(i).equals(MINUS) && isNumber(list.get(i - 1)) && isNumber(list.get(i + 1))) { - list.set(i + 1, String.valueOf(Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1)))); + } // end else + else if (list.get(i).equals(MINUS) && isNumber(list.get(i - 1)) + && isNumber(list.get(i + 1))) { + list.set(i + 1, String.valueOf( + Double.parseDouble(list.get(i - 1)) - Double.parseDouble(list.get(i + 1)))); list.set(i - 1, ""); list.set(i, ""); - }//end else if - }//end if + } // end else if + } // end if else { list.set(i + 1, "Infinity"); list.set(i - 1, ""); @@ -2145,42 +2285,50 @@ else if (list.get(i).equals(MINUS) && isNumber(list.get(i - 1)) && isNumber(list } } - }//end try + } // end try catch (NullPointerException nolerr) { - }//end catch + } // end catch catch (NumberFormatException numerr) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderr) { - }//end catch - }//end for - }//end if + } // end catch + } // end for + } // end if garbage.add("("); garbage.add(")"); list.removeAll(garbage); if (list.size() != 1) { - this.parser_Result = this.parser_Result == Parser_Result.VALID ? Parser_Result.SYNTAX_ERROR : this.parser_Result; + this.parser_Result = this.parser_Result == Parser_Result.VALID ? Parser_Result.SYNTAX_ERROR + : this.parser_Result; this.correctFunction = false; list.clear(); list.add(parser_Result.name()); - }//end if + } // end if -//Now de-list or un-package the input.If all goes well the list should have only its first memory location occupied. + // Now de-list or un-package the input.If all goes well the list should have + // only its first memory location occupied. return list; - }//end method solve + }// end method solve /** * * @param scanner is a list of scanner functions, gotten during the - * evaluation of sets of data that contain functions that need to be - * evaluated instead of numbers.If the data set does not contain functions - * e.g avg(2,3,7,1,0,9,5), then method solve will easily solve it. But if it - * does e.g avg(2,sin,3,5,cos,(,5,) ), then we invoke this method in class - * Set's constructor before we evaluate the data set. Note this is method is - * not called directly by MathExpression objects but by objects of class Set - * invoked by a MathExpression object. + * evaluation of sets of data that contain functions that need to + * be + * evaluated instead of numbers.If the data set does not contain + * functions + * e.g avg(2,3,7,1,0,9,5), then method solve will easily solve + * it. But if it + * does e.g avg(2,sin,3,5,cos,(,5,) ), then we invoke this method + * in class + * Set's constructor before we evaluate the data set. Note this + * is method is + * not called directly by MathExpression objects but by objects + * of class Set + * invoked by a MathExpression object. * * @return the solution to the scanner function */ @@ -2188,26 +2336,26 @@ public List solveSubPortions(List scanner) { scanner.add(0, "("); scanner.add(")"); -//[3,4,2,sin,2,sin,(,3,),3,*,cos,5,(,3,+,(,6,-,78,),)] + // [3,4,2,sin,2,sin,(,3,),3,*,cos,5,(,3,+,(,6,-,78,),)] int passes = 0; int i = 0; int j = 0; while (scanner.size() > 1) { passes++; try { - i = scanner.indexOf(")");//index of first ) - j = LISTS.prevIndexOf(scanner, i, "("); //index of enclosing bracket of ) above + i = scanner.indexOf(")");// index of first ) + j = LISTS.prevIndexOf(scanner, i, "("); // index of enclosing bracket of ) above List sub = scanner.subList(j, i + 1); solve(sub); - }//end try + } // end try catch (IndexOutOfBoundsException indexerr) { break; - }//end catch - }//end while + } // end catch + } // end while return scanner; - }//end method solveSubPortions() + }// end method solveSubPortions() public static void main(String... args) { String in = Main.joinArgs(Arrays.asList(args), true); @@ -2215,7 +2363,7 @@ public static void main(String... args) { System.err.println(in); } System.out.println(new MathExpression(in).solve()); - }//end method + }// end method @Override public String serialize() { @@ -2226,4 +2374,4 @@ public MathExpression parse(String enc) { return (MathExpression) Serializer.deserialize(enc); } -}//end class MathExpression +}// end class MathExpression diff --git a/src/main/java/parser/MathScanner.java b/src/main/java/parser/MathScanner.java index b25da3d..e0343f3 100644 --- a/src/main/java/parser/MathScanner.java +++ b/src/main/java/parser/MathScanner.java @@ -1299,21 +1299,18 @@ public static void extractFunctionStringFromExpressionForMatrixMethods(List 0) { String token = list.get(open - 1); if (Method.isMatrixMethod(token)) { - List l = list.subList(open - 1, i + 1); + List l = list.subList(open - 1, i + 1); int siz = l.size(); - System.err.println("list: " + list); extractFunctionStringFromExpressionForMatrixMethods(l); - i = i - (siz - l.size()); } //Most likely you have gotten to the first parameter...ignore it and process the bracket else if (FunctionManager.contains(token)) { - List l = list.subList(open, i + 1); + List l = list.subList(open, i + 1); int siz = l.size(); MathExpression me = new MathExpression(LISTS.createStringFrom(list, open, i + 1)); diff --git a/src/main/java/parser/Number.java b/src/main/java/parser/Number.java index ef3f04f..5c5dbae 100644 --- a/src/main/java/parser/Number.java +++ b/src/main/java/parser/Number.java @@ -42,7 +42,7 @@ public Number(String num, int index, ArrayList scan) { this.num = isNumber(num) ? num : ""; this.index = index; if (this.num.equals("")) { - throw new IndexOutOfBoundsException("Invalid Name For Log or antilog to any base type Operator."); + throw new IndexOutOfBoundsException("Invalid Name For log or antilog to any base type Operator."); }//end if else { this.index = (index >= 0 && scan.get(index).equals(num)) ? index : -1; diff --git a/src/main/java/parser/Operator.java b/src/main/java/parser/Operator.java index 9acc1e2..d7d6d5a 100644 --- a/src/main/java/parser/Operator.java +++ b/src/main/java/parser/Operator.java @@ -329,7 +329,7 @@ public static boolean isCube(String op){ /** * @param op the String to check * @return true if the operator is a pre-number operator - * e.g the trig operators,exponential operators,logarithmic operators(not to any base) + * e.g √ and ³√ */ public static boolean isUnaryPreOperator(String op){ return ( op.equals(ROOT) || op.equals(CUBE_ROOT)); @@ -337,7 +337,7 @@ public static boolean isUnaryPreOperator(String op){ /** * @param op the String to check * @return true if the operator is a post number operator - * e.g the inverse operator,the factorial,the square and the cube + * e.g -¹, !, ² and ³ */ public static boolean isUnaryPostOperator(String op){ return (op.equals(INVERSE)||op.equals(FACTORIAL)||op.equals(SQUARE)||op.equals(CUBE)); diff --git a/src/main/java/parser/PolynomialExpression.java b/src/main/java/parser/PolynomialExpression.java index 6b9a960..7aab49b 100644 --- a/src/main/java/parser/PolynomialExpression.java +++ b/src/main/java/parser/PolynomialExpression.java @@ -54,7 +54,7 @@ public PolynomialExpression(String expression, int precision) { * (DOUBLE_PRECISION) or 2 (BIGDECIMAL_PRECISION), it defaults to * DOUBLE_PRECISION */ - public void setPrecision(int precision) { + public final void setPrecision(int precision) { this.precision = precision == 1 ? DOUBLE_PRECISION : (precision == 2 ? BIGDECIMAL_PRECISION : DOUBLE_PRECISION); } @@ -111,7 +111,7 @@ public List doublePrecisionSolve(List list) { if (isHasPowerOperators()) { - /*Deals with powers.Handles the primary power operator e.g in 3^sin3^4.This is necessary at this stage to dis-allow operations like sinA^Bfrom giving the result:(sinA)^B + /*Deals with powers.Handles the primary power operator e.g in 3^sin3^4.This is necessary at this stage to dis-allow operations like sinA^B from giving the result:(sinA)^B instead of sin(A^B). Also instructs the software to multiply any 2 numbers in consecutive positions in the vector. This is important in distinguishing between functions such as sinAB and sinA*B.Note:sinAB=sin(A*B),while sinA*B=B*sinA. @@ -559,7 +559,9 @@ else if (list.get(i).equals(Operator.MINUS) && isNumber(list.get(i - 1)) && isNu public static void main(String args[]) { String expr = "x=2;8x*sin(x^2)/3"; +//String expr = "x=2;f(x)=3*x^2+x+2*x;f(3);"; PolynomialExpression polyExpression = new PolynomialExpression(expr, DOUBLE_PRECISION); + System.err.println("scanner: "+polyExpression.scanner); System.out.println(polyExpression.solve()); }//end method diff --git a/src/main/java/parser/Variable.java b/src/main/java/parser/Variable.java index 2ed9755..dc24b83 100644 --- a/src/main/java/parser/Variable.java +++ b/src/main/java/parser/Variable.java @@ -22,7 +22,7 @@ */ public class Variable implements Savable{ -//a String variable that represents the String property of the varriable +//the String property of the variable private String name; private TYPE type; diff --git a/src/main/java/parser/methods/Method.java b/src/main/java/parser/methods/Method.java index 437cd42..3a5316f 100644 --- a/src/main/java/parser/methods/Method.java +++ b/src/main/java/parser/methods/Method.java @@ -13,6 +13,7 @@ import parser.Set; import java.util.ArrayList; +import java.util.Arrays; import java.util.InputMismatchException; import java.util.List; import math.Maths; @@ -43,10 +44,9 @@ public class Method { */ private int DRG = 1; - /** * - * @param name The method name + * @param name The method name * @param parameters The parameters to the method */ public Method(String name, String... parameters) { @@ -57,27 +57,32 @@ public Method(String name, String... parameters) { } } - /** * * @param methodName The name of the method. * @return true if the method name represents one that can operate on - * Function objects or anonymous Functions. + * Function objects or anonymous Functions. */ public static boolean isFunctionOperatingMethod(String methodName) { - return methodName.equals(DIFFERENTIATION) || methodName.equals(INTEGRATION) || methodName.equals(QUADRATIC) || methodName.equals(GENERAL_ROOT) + return methodName.equals(DIFFERENTIATION) || methodName.equals(INTEGRATION) || methodName.equals(QUADRATIC) + || methodName.equals(GENERAL_ROOT) || methodName.equals(TARTAGLIA_ROOTS) || methodName.equals(PLOT) || methodName.equals(MATRIX_MULTIPLY) - || methodName.equals(MATRIX_DIVIDE) || methodName.equals(MATRIX_ADD) || methodName.equals(MATRIX_SUBTRACT) - || methodName.equals(MATRIX_POWER) || methodName.equals(MATRIX_EDIT) || methodName.equals(MATRIX_TRANSPOSE) - || methodName.equals(DETERMINANT) || methodName.equals(MATRIX_ADJOINT) || methodName.equals(MATRIX_COFACTORS) - || methodName.equals(MATRIX_EIGENPOLY) || methodName.equals(MATRIX_EIGENVEC) || methodName.equals(PRINT); + || methodName.equals(MATRIX_DIVIDE) || methodName.equals(MATRIX_ADD) + || methodName.equals(MATRIX_SUBTRACT) + || methodName.equals(MATRIX_POWER) || methodName.equals(MATRIX_EDIT) + || methodName.equals(MATRIX_TRANSPOSE) + || methodName.equals(DETERMINANT) || methodName.equals(MATRIX_ADJOINT) + || methodName.equals(MATRIX_COFACTORS) + || methodName.equals(MATRIX_EIGENPOLY) || methodName.equals(MATRIX_EIGENVEC) + || methodName.equals(PRINT); } /** * * @param expression Initializes the attributes of objects of this class by - * parsing the expression parameter. The format of expression is: - * methodname(args_1,args_2,....args_N) + * parsing the expression parameter. The format of expression + * is: + * methodname(args_1,args_2,....args_N) */ public Method(String expression) { parseExpression(expression); @@ -85,21 +90,21 @@ public Method(String expression) { /** * @return An array containing the names of all functions defined by the - * user and inbuilt into the software. + * user and inbuilt into the software. */ public static String[] getAllFunctions() { int sz = FunctionManager.FUNCTIONS.size(); String[] userDefined = new String[sz + getInbuiltMethods().length]; - String[] keyset = FunctionManager.FUNCTIONS.keySet().toArray(new String[]{}); + String[] keyset = FunctionManager.FUNCTIONS.keySet().toArray(new String[] {}); System.arraycopy(keyset, 0, userDefined, 0, keyset.length); System.arraycopy(getInbuiltMethods(), 0, userDefined, keyset.length, getInbuiltMethods().length); return userDefined; - }//end method. + }// end method. /** * * @param expression The expression to parse. The format of expression is: - * methodname(args_1,args_2,....args_N) + * methodname(args_1,args_2,....args_N) */ public final void parseExpression(String expression) { @@ -111,12 +116,12 @@ public final void parseExpression(String expression) { params = l.subList(1, sz).toArray(params); setParameters(params); setName(l.get(0)); - }//end if + } // end if else { throw new InputMismatchException("Invalid Method Name!"); - }//end else + } // end else - }//end method + }// end method public void setName(String name) { this.name = name; @@ -142,26 +147,81 @@ public int getDRG() { return DRG; } + /** + * @param op the String to check + * @return true if the operator is a statistical operator...basically any + * system function that takes more than 1 argument. So by definition + * even + * the log and alog (and its log-¹ variant) + * are + * included here. e.g + * sum,prod,min,max,avg,var,rms,cov,s_d,st_err,rng,mrng,med,mode,rnd + */ + public static boolean isStatsMethod(String op) { + return (isUserDefinedFunction(op) || isLogOrAntiLogToAnyBase(op) || isBasicNumericalFunction(op) + || isMatrixMethod(op) || isHardcodedStatsMethod(op) + || op.equals(POW) || op.equals(DIFFERENTIATION) + || op.equals(INTEGRATION) || op.equals(GENERAL_ROOT) || op.equals(QUADRATIC) + || op.equals(TARTAGLIA_ROOTS) || op.equals(PERMUTATION) || op.equals(COMBINATION) + || op.equals(LOG) || op.equals(LOG_INV) || op.equals(LOG_INV_ALT) || op.equals(PRINT)); + }// end method + /** * @param op the String to check * @return true if the operator is a statistical operator that returns items - * in a list e.g sort( + * in a list e.g sort( */ public static boolean isListReturningStatsMethod(String op) { - return (op.equals(SORT) || op.equals(MODE) || op.equals(RANDOM) || op.equals(QUADRATIC) || op.equals(TARTAGLIA_ROOTS) - || op.equals(INVERSE_MATRIX) || op.equals(LINEAR_SYSTEM) || op.equals(TRIANGULAR_MATRIX) || op.equals(ECHELON_MATRIX)) - || op.equals(MATRIX_MULTIPLY) || op.equals(MATRIX_DIVIDE) || op.equals(MATRIX_ADD) || op.equals(MATRIX_SUBTRACT) || op.equals(MATRIX_POWER) - || op.equals(MATRIX_TRANSPOSE) || op.equals(MATRIX_EDIT); + return (op.equals(SORT) || op.equals(MODE) || op.equals(RANDOM) || op.equals(QUADRATIC) + || op.equals(TARTAGLIA_ROOTS) + || op.equals(INVERSE_MATRIX) || op.equals(LINEAR_SYSTEM) || op.equals(TRIANGULAR_MATRIX) + || op.equals(ECHELON_MATRIX)) + || op.equals(MATRIX_MULTIPLY) || op.equals(MATRIX_DIVIDE) || op.equals(MATRIX_ADD) + || op.equals(MATRIX_SUBTRACT) || op.equals(MATRIX_POWER) + || op.equals(MATRIX_TRANSPOSE) || op.equals(MATRIX_EDIT) || op.equals(MATRIX_COFACTORS) + || op.equals(MATRIX_COFACTORS) || op.equals(MATRIX_ADJOINT) || op.equals(MATRIX_EIGENPOLY) || op.equals(MATRIX_EIGENVEC); } /** * @param op the String to check * @return true if the operator is a statistical operator that operates on a - * data set and returns a single value: e.g sum(4,3,2,2...) + * data set and returns a single value: e.g sum(4,3,2,2...) */ public static boolean isNumberReturningStatsMethod(String op) { return isStatsMethod(op) && !isListReturningStatsMethod(op); } +/* + + */ + /** + * @param op the String to check + * @return true if the operator is a statistical operator that operates on a + * data set and returns a single value: e.g sum(4,3,2,2...) + */ + public static boolean isNumberReturningNonUserDefinedMethod(String op) { + String[] someFunctions = new String[]{ + SIN, COS, TAN, SINH, COSH, TANH, ARC_SIN, ARC_COS, ARC_TAN, ARC_SINH, ARC_COSH, ARC_TANH, SEC, COSEC, COT, SECH, COSECH, + COTH, ARC_SEC, ARC_COSEC, ARC_COT, ARC_SECH, + ARC_COSECH, ARC_COTH, EXP, LN, LG, LOG, LN_INV, LG_INV, LOG_INV, ARC_SIN_ALT, ARC_COS_ALT, + ARC_TAN_ALT, ARC_SINH_ALT, ARC_COSH_ALT, ARC_TANH_ALT, ARC_SEC_ALT, ARC_COSEC_ALT, + ARC_COT_ALT, ARC_SECH_ALT, ARC_COSECH_ALT, ARC_COTH_ALT, LN_INV_ALT, LG_INV_ALT, LOG_INV_ALT, + SQRT, CBRT, INVERSE, SQUARE, CUBE, POW, FACT, PLOT, DIFFERENTIATION, INTEGRATION, QUADRATIC, DETERMINANT + + }; + + for(String x : someFunctions){ + if(x.equals(op)){ + return true; + } + } + + return isBasicNumericalFunction(op) + || op.equals(DETERMINANT) || op.equals(PROD)|| op.equals(MEDIAN)|| op.equals(RANGE)|| op.equals(MID_RANGE)|| op.equals(ROOT_MEAN_SQUARED) + || op.equals(COEFFICIENT_OF_VARIATION)|| op.equals(MIN) + || op.equals(MAX)|| op.equals(STD_DEV)|| op.equals(VARIANCE)|| op.equals(STD_ERR) + || op.equals(POW) || op.equals(GENERAL_ROOT) || op.equals(QUADRATIC) + || op.equals(TARTAGLIA_ROOTS) || op.equals(PERMUTATION) || op.equals(COMBINATION); + } /** * @param op the String to check @@ -174,7 +234,7 @@ public static boolean isRandom(String op) { /** * @param op the String to check * @return true if the operator is the log operator the form is - * log(num,base) + * log(num,base) */ public static boolean isLogToAnyBase(String op) { return (op.equals(LOG)); @@ -183,7 +243,7 @@ public static boolean isLogToAnyBase(String op) { /** * @param op the String to check * @return true if the operator is the log operator the form is - * log-¹(num,base) + * log-¹(num,base) */ public static boolean isAntiLogToAnyBase(String op) { return (op.equals(LOG_INV) || op.equals(LOG_INV_ALT)); @@ -192,7 +252,7 @@ public static boolean isAntiLogToAnyBase(String op) { /** * @param op the String to check * @return true if the operator is the natural log operator the form is - * log-¹(num,base) + * log-¹(num,base) */ public static boolean isNaturalLog(String op) { return (op.equals(LN)); @@ -201,7 +261,7 @@ public static boolean isNaturalLog(String op) { /** * @param op the String to check * @return true if the operator is the inverse natural log operator the form - * is log-¹(num,base) + * is log-¹(num,base) */ public static boolean isInverseNaturalLog(String op) { return (op.equals(LN_INV) || op.equals(LN_INV_ALT)); @@ -210,7 +270,7 @@ public static boolean isInverseNaturalLog(String op) { /** * @param op the String to check * @return true if the operator is the inverse natural log operator the form - * is log-¹(num,base) + * is log-¹(num,base) */ public static boolean isExpMethod(String op) { return (op.equals(EXP)); @@ -265,35 +325,19 @@ public boolean isPrint(String op) { return op.equals(PRINT); } - /** - * @param op the String to check - * @return true if the operator is a statistical operator..basically any - * system function that takes more than 1 argument. So by definition even - * the log and alog (and its log-¹ variant) are - * included here. e.g - * sum,prod,min,max,avg,var,rms,cov,s_d,st_err,rng,mrng,med,mode,rnd - */ - public static boolean isStatsMethod(String op) { - return (isUserDefinedFunction(op) || isLogOrAntiLogToAnyBase(op) || isBasicNumericalFunction(op) - || isMatrixMethod(op) || isHardcodedStatsMethod(op) - || op.equals(POW) || op.equals(DIFFERENTIATION) - || op.equals(INTEGRATION) || op.equals(GENERAL_ROOT) || op.equals(QUADRATIC) - || op.equals(TARTAGLIA_ROOTS) || op.equals(PERMUTATION) || op.equals(COMBINATION) - || op.equals(LOG) || op.equals(LOG_INV) || op.equals(LOG_INV_ALT) || op.equals(PRINT)); - }//end method - /** * * @param op The method name * @return true if the method is capable of acting on one or more matrix - * functions + * functions */ public static boolean isMatrixMethod(String op) { return op.equals(LINEAR_SYSTEM) || op.equals(DETERMINANT) || op.equals(INVERSE_MATRIX) || op.equals(TRIANGULAR_MATRIX) || op.equals(ECHELON_MATRIX) || op.equals(MATRIX_MULTIPLY) || op.equals(MATRIX_DIVIDE) || op.equals(MATRIX_ADD) || op.equals(MATRIX_SUBTRACT) || op.equals(MATRIX_POWER) || op.equals(MATRIX_EDIT) || op.equals(MATRIX_TRANSPOSE) - || op.equals(MATRIX_COFACTORS) || op.equals(MATRIX_ADJOINT) || op.equals(MATRIX_EIGENPOLY) || op.equals(MATRIX_EIGENVEC); + || op.equals(MATRIX_COFACTORS) || op.equals(MATRIX_ADJOINT) || op.equals(MATRIX_EIGENPOLY) + || op.equals(MATRIX_EIGENVEC); } /** @@ -362,11 +406,11 @@ public static boolean isMatrixEdit(String op) { /** * * @return true if the Function name has been defined by the user in the - * user's workspace. + * user's workspace. */ public static boolean isUserDefinedFunction(String op) { return FunctionManager.lookUp(op) != null; - }//end method + }// end method /** * A fix for stuff like sum,(,13,+,3,)... @@ -376,7 +420,7 @@ private static void quickFixCompoundStructuresInStatsExpression(List lis String methodName = list.get(0); - if(!isStatsMethod(methodName)){ + if (!isStatsMethod(methodName)) { return; } int sz = list.size(); @@ -403,33 +447,36 @@ private static void quickFixCompoundStructuresInStatsExpression(List lis } } - } + } + /** * * @param list A list containing a portion of a scanned function that has - * information about a method and its parameters..e.g. [sin,(,3.14,)] , or - * [matrix_edit,(,M,3,4,-90,)] may be grabbed from a scanner output and sent - * to this method to evaluate. - * @param DRG The trigonometric mode in which to run the method. + * information about a method and its parameters..e.g. + * [sin,(,3.14,)] , or + * [matrix_edit,(,M,3,4,-90,)] may be grabbed from a scanner output + * and sent + * to this method to evaluate. + * @param DRG The trigonometric mode in which to run the method. * @return a {@link List} object which is the output of the method's - * operation. + * operation. */ public static List run(List list, DRG_MODE DRG) { - + quickFixCompoundStructuresInStatsExpression(list); String name = list.get(0); String result = ""; - list.subList(0, 2).clear();//remove the method name and its opening bracket. - list.remove(list.size() - 1);//remove the closing bracket. + list.subList(0, 2).clear();// remove the method name and its opening bracket. + list.remove(list.size() - 1);// remove the closing bracket. int sz = list.size(); if (isStatsMethod(name)) { - for (BasicNumericalMethod basicNumericalMethod: getBasicNumericalMethods()){ - if (name.equals(basicNumericalMethod.getName())){ + for (BasicNumericalMethod basicNumericalMethod : getBasicNumericalMethods()) { + if (name.equals(basicNumericalMethod.getName())) { Set set = new Set(list); - //TODO, make basicNumericalMethod statefull (initialize by reflection) - //basicNumericalMethod.setRadDegGrad(DRG); + // TODO, make basicNumericalMethod statefull (initialize by reflection) + // basicNumericalMethod.setRadDegGrad(DRG); result = basicNumericalMethod.solve(new ArrayList<>(set.getData())); list.clear(); list.add(result); @@ -533,18 +580,19 @@ public static List run(List list, DRG_MODE DRG) { list.clear(); list.add(result); return list; - }//end try + } // end try catch (ClassNotFoundException cnfe) { - //System.out.println( " Function Not Defined!"); - }//end catch - }//end else if + // System.out.println( " Function Not Defined!"); + } // end catch + } // end else if else if (name.equals(LOG)) { if (sz == 1) { result = String.valueOf(Maths.logToAnyBase(Double.valueOf(list.get(0)), 10)); list.clear(); list.add(result); } else if (sz == 2) { - result = String.valueOf(Maths.logToAnyBase(Double.valueOf(list.get(0)), Double.valueOf(list.get(1)))); + result = String + .valueOf(Maths.logToAnyBase(Double.valueOf(list.get(0)), Double.valueOf(list.get(1)))); list.clear(); list.add(result); } @@ -557,7 +605,8 @@ else if (name.equals(LOG)) { list.add(result); return list; } else if (sz == 2) { - result = String.valueOf(Maths.antiLogToAnyBase(Double.valueOf(list.get(0)), Double.valueOf(list.get(1)))); + result = String + .valueOf(Maths.antiLogToAnyBase(Double.valueOf(list.get(0)), Double.valueOf(list.get(1)))); list.clear(); list.add(result); return list; @@ -680,7 +729,7 @@ else if (name.equals(LOG)) { String ref = Function.storeAnonymousMatrixFunction(matrix); list.add(ref); return list; - } else if (name.equals(MATRIX_EDIT)) {//matrix_edit(M,row,col,val) + } else if (name.equals(MATRIX_EDIT)) {// matrix_edit(M,row,col,val) Set set = new Set(list); Matrix matrix = set.editMatrix(); list.clear(); @@ -719,7 +768,7 @@ else if (name.equals(LOG)) { list.add(ref); return list; } else if (name.equals(PRINT)) { - + Set set = new Set(list); set.print(); list.clear(); @@ -770,11 +819,14 @@ else if (name.equals(LOG)) { } else if (name.equals(ARC_TAN) || name.equals(ARC_TAN_ALT)) { result = String.valueOf(Maths.atanRadToDeg(Double.valueOf(list.get(0)))); } else if (name.equals(ARC_SINH) || name.equals(ARC_SINH_ALT)) { - result = String.valueOf(Math.log(Double.valueOf(list.get(0)) + Math.sqrt(Math.pow(Double.valueOf(list.get(0)), 2) + 1))); + result = String.valueOf(Math.log(Double.valueOf(list.get(0)) + + Math.sqrt(Math.pow(Double.valueOf(list.get(0)), 2) + 1))); } else if (name.equals(ARC_COSH) || name.equals(ARC_COSH_ALT)) { - result = String.valueOf(Math.log(Double.valueOf(list.get(0)) + Math.sqrt(Math.pow(Double.valueOf(list.get(0)), 2) - 1))); + result = String.valueOf(Math.log(Double.valueOf(list.get(0)) + + Math.sqrt(Math.pow(Double.valueOf(list.get(0)), 2) - 1))); } else if (name.equals(ARC_TANH) || name.equals(ARC_TANH_ALT)) { - result = String.valueOf(0.5 * Math.log((1 + Double.valueOf(list.get(0))) / (1 - Double.valueOf(list.get(0))))); + result = String.valueOf(0.5 * Math + .log((1 + Double.valueOf(list.get(0))) / (1 - Double.valueOf(list.get(0))))); } else if (name.equals(ARC_SEC) || name.equals("asec")) { result = String.valueOf(Maths.acosRadToDeg(1 / Double.valueOf(list.get(0)))); } else if (name.equals(ARC_COSEC) || name.equals("acsc")) { @@ -782,11 +834,16 @@ else if (name.equals(LOG)) { } else if (name.equals(ARC_COT) || name.equals("acot")) { result = String.valueOf(Maths.atanRadToDeg(1 / Double.valueOf(list.get(0)))); } else if (name.equals(ARC_SECH) || name.equals(ARC_SECH_ALT)) { - result = String.valueOf(Math.log((1 + Math.sqrt(1 - Math.pow(Double.valueOf(list.get(0)), 2))) / Double.valueOf(list.get(0)))); + result = String + .valueOf(Math.log((1 + Math.sqrt(1 - Math.pow(Double.valueOf(list.get(0)), 2))) + / Double.valueOf(list.get(0)))); } else if (name.equals(ARC_COSECH) || name.equals(ARC_COSECH_ALT)) { - result = String.valueOf(Math.log((1 + Math.sqrt(1 + Math.pow(Double.valueOf(list.get(0)), 2))) / Double.valueOf(list.get(0)))); + result = String + .valueOf(Math.log((1 + Math.sqrt(1 + Math.pow(Double.valueOf(list.get(0)), 2))) + / Double.valueOf(list.get(0)))); } else if (name.equals(ARC_COTH) || name.equals(ARC_COTH_ALT)) { - result = String.valueOf(0.5 * Math.log((Double.valueOf(list.get(0)) + 1) / (Double.valueOf(list.get(0)) - 1))); + result = String.valueOf(0.5 * Math + .log((Double.valueOf(list.get(0)) + 1) / (Double.valueOf(list.get(0)) - 1))); } else if (name.equals(LG_INV) || name.equals(LG_INV_ALT)) { result = String.valueOf(Math.pow(10, Double.valueOf(list.get(0)))); } else if (name.equals(SQRT)) { @@ -810,8 +867,8 @@ else if (name.equals(LOG)) { list.add(result); return list; -//add more definitions below.... - }//end if DRG == 0 + // add more definitions below.... + } // end if DRG == 0 else if (DRG == DRG_MODE.RAD) { if (name.equals(SIN)) { result = String.valueOf(Math.sin(Double.valueOf(list.get(0)))); @@ -890,8 +947,8 @@ else if (DRG == DRG_MODE.RAD) { list.add(result); return list; -//add more definitions below.... - }//end else if DRG == 1 + // add more definitions below.... + } // end else if DRG == 1 else if (DRG == DRG_MODE.GRAD) { if (name.equals(SIN)) { result = String.valueOf(Maths.sinGradToRad(Double.valueOf(list.get(0)))); @@ -968,88 +1025,89 @@ else if (DRG == DRG_MODE.GRAD) { list.clear(); list.add(result); return list; -//add more definitions below.... - }//end else if DRG == 2 - }//end if list.get(0).equals("Infinity") + // add more definitions below.... + } // end else if DRG == 2 + } // end if list.get(0).equals("Infinity") else if (list.get(0).equals("Infinity")) { list.add("Infinity"); return list; } - }//end try + } // end try catch (NumberFormatException numerror) { - }//end catch + } // end catch catch (NullPointerException nullerror) { - }//end catch + } // end catch catch (IndexOutOfBoundsException inderror) { - }//end catch + } // end catch list.add("Syntax Error!"); return list; - }//end if parameters.length==1 + } // end if parameters.length==1 - }//end else + } // end else throw new IllegalArgumentException(" Unknown function: " + name); - }//end method + }// end method /** * * @param methodName The name of the method * @return true if the method has been defined by the user or is defined by - * the parser. + * the parser. */ public static boolean isUnaryPreOperatorORDefinedMethod(String methodName) { return isDefinedMethod(methodName) || parser.Operator.isUnaryPreOperator(methodName); - }//end method + }// end method /** * * @param methodName The name of the method * @return true if the method has been defined by the user or is defined by - * the parser. + * the parser. */ public static boolean isDefinedMethod(String methodName) { return arrayContains(getInbuiltMethods(), methodName) || FunctionManager.contains(methodName); - }//end method + }// end method /** * * @param methodName The name of the method * @return true if the method is defined by the parser as a core inbuilt - * function. + * function. */ public static boolean isInBuiltMethod(String methodName) { return arrayContains(getInbuiltMethods(), methodName); - }//end method + }// end method /** * * @param array An array of strings - * @param str The string to check for. + * @param str The string to check for. * @return true if the array contains the specified string. */ public static boolean arrayContains(String array[], String str) { for (String s : array) { if (s.equals(str)) { return true; - }//end if - }//end for + } // end if + } // end for return false; - }//end method + }// end method /** * * @param name The string to check if or not it represents a valid method - * name.
- * - * The method may or may not have been defined. But once it represents a - * valid method name, this method will return true. In contrast, the - * 'isDefinedMethod' checks whether or not the method has been - * afore-defined. - * + * name.
+ * + * The method may or may not have been defined. But once it + * represents a + * valid method name, this method will return true. In contrast, the + * 'isDefinedMethod' checks whether or not the method has been + * afore-defined. + * * @return true if the string represents a valid method name. */ public static boolean isMethodName(String name) { @@ -1057,7 +1115,7 @@ public static boolean isMethodName(String name) { String end = ""; if (name.equals("-¹")) { return false; - }//end if + } // end if else if (name.endsWith("-¹") && !name.equals("-¹")) { end = "-¹"; name = name.substring(0, name.length() - 2); @@ -1067,30 +1125,30 @@ else if (name.endsWith("-¹") && !name.equals("-¹")) { for (int i = 0; i < len; i++) { if (!isMethodNameBuilder(name.substring(i, i + 1))) { return false; - }//end if - }//end for loop + } // end if + } // end for loop return true; - }//end if + } // end if return false; - }//end try + } // end try catch (IndexOutOfBoundsException | NullPointerException boundsException) { return false; } - }//end method + }// end method /** * * @param name The string to check. * @return true if the string is part of the valid characters that can be - * used to build a method name. + * used to build a method name. */ public static boolean isMethodNameBuilder(String name) { if (isMethodNameBeginner(name) || isDigit(name)) { return true; - }//end if + } // end if return false; - }//end method + }// end method /** * @@ -1099,11 +1157,12 @@ public static boolean isMethodNameBuilder(String name) { */ public static boolean isMethodNameBeginner(String name) { - if (!parser.Operator.isPermOrComb(name) && Character.isLetter(name.toCharArray()[0]) || name.equals("_") || name.equals("$")) { + if (!parser.Operator.isPermOrComb(name) && Character.isLetter(name.toCharArray()[0]) || name.equals("_") + || name.equals("$")) { return true; - }//end if + } // end if return false; - }//end method + }// end method @Override public String toString() { @@ -1111,7 +1170,7 @@ public String toString() { int sz = parameters.length; for (int i = 0; i < sz; i++) { out = out.concat(parameters[i].concat(",")); - }//end for loop. + } // end for loop. out = out.substring(0, out.length()); out = out.concat(")"); @@ -1143,18 +1202,18 @@ private static String[] join(String[] arr1, String arr2[]) { for (int i = 0; i < len; i++) { if (i < subLen1) { larger[i] = arr1[i]; - }//end if + } // end if else { larger[i] = arr2[i]; - }//end else + } // end else - }//end for + } // end for return larger; - }//end method. + }// end method. private static boolean isHardcodedStatsMethod(String op) { - for (String x: getStatsMethods()) { + for (String x : getStatsMethods()) { if (x.equals(op)) { return true; } @@ -1176,12 +1235,12 @@ public static boolean hasStatsMethod(String expr) { try { if (isStatsMethod(scan.get(i)) && scan.get(i + 1).startsWith("(")) { return true; - }//end if - }//end try + } // end if + } // end try catch (IndexOutOfBoundsException boundsException) { return false; } - }//end for + } // end for return false; } @@ -1199,4 +1258,4 @@ public static void main(String args[]) { } -}//end class +}// end class diff --git a/src/main/java/util/MathExpressionManager.java b/src/main/java/util/MathExpressionManager.java index 09c8ee7..8032711 100644 --- a/src/main/java/util/MathExpressionManager.java +++ b/src/main/java/util/MathExpressionManager.java @@ -247,9 +247,10 @@ public MathExpression createFunction( String expr ){ * it has to interpret and then evaluate it. * It then stores the expression. * @param expr The expression to evaluate. + * @param mathExpClazz The java.util.Class that the parent MathExpression belongs to.. may be MathExpression.class, BigMathExpression.class etc. * @return the result. */ - public String solve( String expr ) throws NullPointerException{ + public String solve( String expr , Class mathExpClazz) throws NullPointerException{ try { CustomScanner cs = new CustomScanner( STRING.purifier(expr), false, VariableManager.endOfLine); @@ -259,7 +260,7 @@ public String solve( String expr ) throws NullPointerException{ for(String code : scanned) { if(code.contains("=")){ - boolean success = Function.assignObject(code+";"); + boolean success = Function.assignObject(code+";", mathExpClazz); if(!success) { throw new Exception("Bad Variable or Function assignment!"); } diff --git a/src/main/java/util/Utils.java b/src/main/java/util/Utils.java index 3ebbc31..b09bde0 100644 --- a/src/main/java/util/Utils.java +++ b/src/main/java/util/Utils.java @@ -124,19 +124,22 @@ public void run() { public static void logError(String message) { if (loggingEnabled) { - Log.e("Kalculitzer", message); + Log.e("ParserNG", message); + System.out.println(); } } public static void logDebug(String message) { if (loggingEnabled) { - Log.d("Kalculitzer", message); + Log.d("ParserNG", message); + System.out.println(); } } public static void logInfo(String message) { if (loggingEnabled) { - Log.i("Kalculitzer", message); + Log.i("ParserNG", message); + System.out.println(); } } diff --git a/src/main/java/util/VariableManager.java b/src/main/java/util/VariableManager.java index 3491733..02b7f4a 100644 --- a/src/main/java/util/VariableManager.java +++ b/src/main/java/util/VariableManager.java @@ -51,7 +51,12 @@ public void setCommandParser(CommandInterpreter commandParser) { public static String getEndOfLine() { return endOfLine; } + /** + * Saves stored functions and: updates the client UIs that use this manager. + */ + public static void update() { + } /** * * @return the ArrayList object that stores the Variable data of objects of @@ -142,7 +147,6 @@ public Variable parseSingleCommand(String cmd) { String value = new MathExpression(cmd.substring(indexOfEqual + 1)).solve(); Variable vv = new Variable(var, value, false); VARIABLES.put(vv.getName(), vv); - update(); return vv; } catch (Exception e) {//handle exceptions @@ -166,15 +170,8 @@ public void parseCommand(String cmd) { } else { commandParser.setCommand(cmd); } - update(); } - /** - * Saves stored variables and updates the UI that renders the variables. - */ - public static void update() { - - } /** * Initializes the variables store and loads them from persistent storage @@ -216,11 +213,7 @@ public static Variable lookUp(String vName) { * @param varName the name of the Variable object to be deleted */ public static void delete(String varName) { - VARIABLES.remove(varName); - - update(); - }//end method /** @@ -232,7 +225,6 @@ public static void delete(String varName) { public static void add(Variable var) { if (var != null && !var.isConstant() && !VARIABLES.containsKey(var.getName())) { VARIABLES.put(var.getName(), var); - update(); } }//end method @@ -249,8 +241,6 @@ public static void add(Variable... vars) { VARIABLES.put(v.getName(), v); } } - - update(); }//end method /** @@ -265,7 +255,6 @@ public static void clearVariables() { it.remove(); } } - update(); } /** @@ -280,8 +269,6 @@ public void clearConstants() { it.remove(); } } - - update(); } /** @@ -339,7 +326,7 @@ public String toString() { * insertion of the Variable objects, if the store doe not already contain * them,or updating Variable objects in the store with the incoming ones if * they have the same name. The behavior of the parser is such that it - * interpretes and executes the code on the fly. This means that it will + * interprets and executes the code on the fly. This means that it will * stop inserting data in the VARIABLES only when it detects error in the * code. * @@ -394,6 +381,11 @@ public boolean isValid() { * @return The value of the expression. */ private String getValue(String expr) throws NullPointerException, InputMismatchException { + Variable v = VARIABLES.get(expr); + if(v != null){ + return v.getValue(); + } + MathExpression func = new MathExpression(expr); func.setVariableValuesInFunction(func.getScanner()); return func.solve(); diff --git a/src/test/java/parser/BigMathExpressionTest.java b/src/test/java/parser/BigMathExpressionTest.java new file mode 100644 index 0000000..aa336b1 --- /dev/null +++ b/src/test/java/parser/BigMathExpressionTest.java @@ -0,0 +1,62 @@ +package parser; + + +import java.util.InputMismatchException; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + + +public class BigMathExpressionTest { + + @Test + void contrabandTestShouldPassSimpleExpression() { + BigMathExpression me = null; + try{ + me = new BigMathExpression("x=2;5*x^2+x+2*x;"); + Assertions.assertEquals(true, me.isCorrectFunction()); + }catch(InputMismatchException e){ + Assertions.assertEquals(true, false); + } + + + } + + @Test + void contrabandTestShouldPassFunctionWithSimpleExpression() { + BigMathExpression me = null; + try{ + me = new BigMathExpression("x=2;h(x)=5*x^2+x+2*x;h(3);"); + Assertions.assertEquals(true, me.isCorrectFunction()); + }catch(InputMismatchException e){ + Assertions.assertEquals(true, false); + } + + + } + + @Test + void contrabandTestShouldFailInbuiltFunctionFound() { + BigMathExpression me = null; + try{ + me = new BigMathExpression("x=2;5*x^2+x+ln(x);"); + Assertions.assertEquals(true, me.isCorrectFunction()); + }catch(InputMismatchException e){ + Assertions.assertEquals(false, false); + } + + + } + + @Test + void contrabandTestShouldFailUserDefinedFunctionHasInbuiltFunction() { + BigMathExpression me = null; + try{ + me = new BigMathExpression("x=2;h(x)=5*x^2+x+2*x+cosh(x);h(4);"); + Assertions.assertEquals(false, me.isCorrectFunction()); + }catch(InputMismatchException e){ + Assertions.assertEquals(false, false); + } + } + +}