I have started to learn Java and I need your critique for my first program. It is an interpreter that can calculate any expression including abs(), sqrt(), min(), max(), round() and pow().
What can you say about this? Are there any code defects or pointless comments?
Main class
import java.io.*;
public class Main {
static boolean Error=false;
public static void main(String args[]) throws Exception{
System.out.println("Type an expression to calculate \n" +
"abs(x) function returns absolute value of x\n" +
"sqrt(x) function returns square root of value x\n" +
"min(x,y,…) function returns a minimum value between x,y,...\n" +
"max(x,y,…) function returns a maximum value between x,y,...\n" +
"round(x) function returns a round value of x\n" +
"pow(x,y) function returns an exponentiation of x,y\n" +
"Type \"exit\" to exit");
while (true){
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
String stringForProcessing =read.readLine(); //Input a string to work with it
String output= Calculating.calculating(stringForProcessing); //Calculating
System.out.println(output);//Output
Error=false;
}
}
}
Calculating class
import java.lang.Math;
import java.util.ArrayList;
public class Calculating {
static String calculating(String workingString){
ArrayList<String> separatedString = new ArrayList<>();
int Position=0;
boolean Negative=false;
if(Main.Error){ //return error report
return(workingString);
}
while(Position<workingString.length()){ //reducing spaces
if(workingString.charAt(Position)==' '){
while (((Position)<workingString.length())
&&(workingString.charAt(Position)==' ')){
Position++;
}
}
else if (workingString.charAt(Position)=='-'&&(Position==0 //checking value for negativity
|| workingString.charAt(Position-1)=='-'
|| workingString.charAt(Position-1)=='+'
|| workingString.charAt(Position-1)=='*'
|| workingString.charAt(Position-1)=='/')){
Negative=true;
Position++;
}
else if ((workingString.charAt(Position)=='-' //checking for repeating operators
|| workingString.charAt(Position)=='+'
|| workingString.charAt(Position)=='*'
|| workingString.charAt(Position)=='/')
&&(Position==0
|| workingString.charAt(Position-1)=='-'
|| workingString.charAt(Position-1)=='+'
|| workingString.charAt(Position-1)=='*'
|| workingString.charAt(Position-1)=='/')){
Main.Error=true;return("Error: two or more operators in a row");
}
separatedString.add(Character.toString(workingString.charAt(Position)));
if (workingString.charAt(Position)=='('){ //Creating bracer stack to parse
int BrcrStack=1;
String Temp="";
while (((Position+1)<workingString.length())){
switch (workingString.charAt(Position+1)){
case '(':BrcrStack++;break;
case ')':BrcrStack--;break;
}
Position++;
if(BrcrStack!=0){
Temp+=workingString.charAt(Position);
}
else {break;}
}
if(BrcrStack!=0){
Main.Error=true;return("Error: missing \")\"");
}
separatedString.set(separatedString.size()-1, calculating(Temp));
}
else if (Character.isDigit(workingString.charAt(Position))){ //Bolting numbers
while (((Position+1)<workingString.length())&&(Character.isDigit(workingString.charAt(Position+1))
|| workingString.charAt(Position+1)=='.') ){
separatedString.set(separatedString.size()-1,
separatedString.get(separatedString.size()-1)+workingString.charAt(Position+1));
Position++;
}
try {
Float.valueOf(separatedString.get(separatedString.size()-1));}
catch(Exception e){
Main.Error=true;return("Error: multiple points");
}
if(Negative){ //Negate parameter
separatedString.set(separatedString.size()-1,Float.toString(-(Float.valueOf(separatedString.get(separatedString.size()-1)))));
Negative=false;
}
}
else if (Character.isAlphabetic(workingString.charAt(Position))){ //Bolting functions
while (((Position+1)<workingString.length())
&&(Character.isAlphabetic(workingString.charAt(Position+1))) ){
separatedString.set(separatedString.size()-1,
separatedString.get(separatedString.size()-1)+workingString.charAt(Position+1));
Position++;
}
switch (separatedString.get(separatedString.size()-1)){ //Checking functions
case "abs":break;
case "sqrt":break;
case "min":break;
case "max":break;
case "round":break;
case "pow":break;
case "exit":System.exit(0);
default: {
Main.Error=true;return("Error: unknown function \""+separatedString.get(separatedString.size()-1)+"\"");
}
}
if ((Position+1)==workingString.length()||workingString.charAt(Position+1)!='(') //Parsing function parameters
{
Main.Error=true;return("Error: missing \"(\" after "+"\""+separatedString.get(separatedString.size()-1)+"\" "+ "function");
}
ArrayList<String> Temp = new ArrayList<>();
int BrcrStack=1;
Temp.add("");
while (((Position+2)<workingString.length())){
switch (workingString.charAt(Position+2)){
case '(':BrcrStack++;break;
case ')':BrcrStack--;break;
case ',': if (BrcrStack==1){Temp.add("");Position++;continue;}break;
}
Position++;
if(BrcrStack!=0){Temp.set(Temp.size()-1,Temp.get(Temp.size()-1)+Character.toString(workingString.charAt(Position+1)));}
else {break;}
}
if(BrcrStack!=0){
Main.Error=true;return("Error: missing \")\"");}
Position++;
float FuncArr[]=new float[Temp.size()];
for (int i=0;i<Temp.size();i++){
Temp.set(i, Calculating.calculating(Temp.get(i)));
if (Temp.get(i).length()==0){
Main.Error=true;return("Error: missing expression");}
FuncArr[i]=Float.valueOf(Temp.get(i));
}
switch (separatedString.get(separatedString.size()-1)){ //Calculating functions
case "abs":if (FuncArr.length==1) {
separatedString.set(separatedString.size()-1,Float.toString(Math.abs(FuncArr[0])));}
else {
Main.Error=true;return("Error: \"abs\" function needs only one argument");}break;
case "sqrt":if (FuncArr.length==1) {
double a=FuncArr[0];
separatedString.set(separatedString.size()-1,Double.toString(Math.sqrt(a)));}
else {
Main.Error=true;return("Error: \"sqrt\" function needs only one argument");}break;
case "min":separatedString.set(separatedString.size()-1,Float.toString(Min(FuncArr))) ;break;
case "max":separatedString.set(separatedString.size()-1,Float.toString(Max(FuncArr))) ;break;
case "round":if (FuncArr.length==1) {
separatedString.set(separatedString.size()-1,Float.toString(Math.round((FuncArr[0]))));}
else {
Main.Error=true;return("Error: \"round\" function needs only one argument");}break;
case "pow":if (FuncArr.length==2) {
separatedString.set(separatedString.size()-1,Double.toString(Math.pow(FuncArr[0],FuncArr[1])));}
else {
Main.Error=true;return("Error: \"pow\" function needs only two arguments");}break;
}
}
Position++;
}
ArrayList<String> ResultArr = new ArrayList<>();
if(Negative){ //Negate parameter
separatedString.set(separatedString.size()-1,Float.toString(-(Float.valueOf(separatedString.get(separatedString.size()-1)))));
}
ArrayList<String> Stack = new ArrayList<>();
int i=0;
while (i<separatedString.size()){ //Converting expression to postfix notation
if (separatedString.get(i).length()==1&&(separatedString.get(i).charAt(0)=='+'||separatedString.get(i).charAt(0)=='-'||separatedString.get(i).charAt(0)=='/'||separatedString.get(i).charAt(0)=='*')){
if(Stack.size()==0){
Stack.add(separatedString.get(i));
}else {
if ((separatedString.get(i).charAt(0) == '+' || separatedString.get(i).charAt(0) == '-') && (Stack.get(Stack.size() - 1).charAt(0) == '*' || Stack.get(Stack.size() - 1).charAt(0) == '/')) {
Stack.add(separatedString.get(i));
} else {
Stack.add(separatedString.get(i));
Stack.add(separatedString.get(i+1));
i++;
while (Stack.size() > 0) {
ResultArr.add(Stack.get(Stack.size()-1));
Stack.remove(Stack.size() - 1);
}
}
}
}
else{
ResultArr.add(separatedString.get(i));
}
i++;
}
while (Stack.size() > 0) {
ResultArr.add(Stack.get(Stack.size()-1));
Stack.remove(Stack.size() - 1);
}
i=0;
while (ResultArr.size()>1){ //Calculating postfix expression
if (ResultArr.get(i).length()==1&&(ResultArr.get(i).charAt(0)=='+'||ResultArr.get(i).charAt(0)=='-'||ResultArr.get(i).charAt(0)=='/'||ResultArr.get(i).charAt(0)=='*')){
switch (ResultArr.get(i).charAt(0)){
case '+':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))+Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;
case '-':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))-Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;
case '*':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))*Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;
case '/':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))/Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;
}
i=0;
}
i++;
}
String Result="";
for (String aResultArr : ResultArr) {
Result += aResultArr;
}
if (Float.valueOf(Result)==Math.floor(Float.valueOf(Result))){
Result=Integer.toString(Math.round(Float.valueOf(Result)));
}
return Result;
}
static float Min(float Arr[]){
float Min=Arr[0];
for (int i=1;i<Arr.length;i++){
if (Arr[i]<Min){Min=Arr[i];
}
}
return Min;
}
static float Max(float Arr[]){
float Max=Arr[0];
for (int i=1;i<Arr.length;i++){
if (Arr[i]>Max){Max=Arr[i];
}
}
return Max;
}
}