package uk.ac.nesc.rph.myCalc3;
/* *************************** PREAMBLE *********************
* A modified version of MyCalculator2 in which
* the error checking has been inproved.
* For a commmand line argument which is not a positive integer,
* it outputs message 'MyCalculator3: Argument error'
* It outputs error messages for incorrect input -
* 'Try Again - "" input error: Input out of range'
* for being the 3 character user input and being "1", "2" or "3"
* The changed parts of the program have comments //!!!
* ********************** END *******************************
* ********************** PREAMBLE ****************************************8
*/
class SelectiveInput{
private char [][] syn;
private char quit;
SelectiveInput (char [][] syn, char quit)
{this.syn=syn;
this.quit=quit;}
private boolean isNoticed (char c){
int i=0 ;
for ( ; i=syn[i][0])&&(c<=syn[i][1])) return true;}
return false;}
char getInput() throws java.io.IOException, userQuit {
char c;
while (!isNoticed(c= (char) System.in.read()))
if (c==quit) throw new userQuit();
return c;
}
}
/** Provides Exception for IntegerVariable Interface*/
class uninitialized extends Exception
{static final long serialVersionUID = 2; }
/** This is for any class whose instances maintain an integer value
* which can be manipulated through its set and get methods*/
interface IntegerVariable {
int get()throws uninitialized;
int set(int value);}
/** Maintains a running integer value, initially 0, which can be incremented and reSet
* and accessed using methods incr, reSet and get respectively.
* This is a modified version with improved error checking.
* @author Richard Hopkins
* */
class Accumulator {
int total;
static int uses=0; //to keep count of number of accumulator operations
public Accumulator(){total=0;} //constructor
public int incr(int i){++uses; total= total+i ; return total;}//increment
public int reSet(int r){uses++; return total=r;}
public int get(){return total;}
}
/** Maintains a running integer value which can be incremented, decremented, set
* and accessed using methods incr, decr, set and get respectively.
* @author Richard Hopkins
* */
class AccMKII extends Accumulator implements IntegerVariable {
public AccMKII(int initialTotal) //new constructor
{total=initialTotal;}
public AccMKII() //re-implemented constructor
{this(0);}
public int decr(int i) // new operation
{uses++;total=total-i;return total;}
public int incr(int i) //re-implemented operation
{return this.decr(-i) ;}
public int set(int r) //new operation
{uses+=1;return total=r;}
}
class userQuit extends Exception //exception for MyCalculator
{static final long serialVersionUID = 2; };
class UIError extends Exception //!!! exception for MyCalculator
{static final long serialVersionUID = 2;
String anErrorMess = "No Comment";
UIError(String s){anErrorMess=s;}
public String getMessage() {return anErrorMess;}
}
/** This application provides a number of accumulator objects (class AccMKII),
* and implements an input language for operating on them.
* @author Richard Hopkins
* */
public class MyCalculator3 {
static final char QUIT='q'; // the character for quitting
public static void main(String[] args) {
// ****** Initialisation
char [][] syn ={{'A','Z'},{'0','9'},{'+','+'},{'-','-'},{'=','='},{'?','?'}};
// syntax array for use in getInput(syn) - each pair of characters
// is an inclusive range of recoginsed input characters
SelectiveInput reader = new SelectiveInput(syn,QUIT);
int size; //!!!
try{size= Integer.parseInt(args[0]);}//size of accumulator array
catch (java.lang.NumberFormatException e1)
{System.out.println("MyCalculator3: Argument error"); return;}
if (size>26) size=26;
else if (size < 1) //!!!
{System.out.println("MyCalculator3: Argument error"); return;}
Accumulator [] accs = new Accumulator [size];
for ( int i=0 ; i=size)throw new UIError("Input 1 out of range"); //!!!
if (('A' <= c3) && (c3 <= 'Z'))
{p2= c3-'A';
isLiteral=false;
if (p2>=size)throw new UIError("Input 3 out of range"); //!!!
}
else if (('0' <= c3) && (c3 <= '9')) {p2= c3-'0' ; isLiteral=true;}
else throw new UIError("Input 3 out of range"); //!!!
if (!(c2=='+' || c2=='-' || c2== '?' || c2=='=')) //!!!
throw new UIError("Input 2 out of range");
// *** Doing the requested action
int v2, v3=0; //values of second operand and result
boolean show=false; // whether there is a result to show
AccMKII target = (AccMKII) accs[p1];
v2=(isLiteral ? p2 : accs[p2].get());
switch (c2){
case '+' : v3=target.incr(v2); show=true; break;
case '-' : v3=target.decr(v2); show=true; break;
case '=' : v3=target.set(v2); show=true; break;
case '?' :
String s = "";
do {
s=s+"["+c1+"]="+accs[p1].get()+" ";
p1++; c1++;
}while (p1 <= p2);
System.out.println(s);
show = false; break;
}
if (show) System.out.println(Accumulator.uses+")----------> ["+c1+"]= "+v3);
}catch (UIError e1) //!!
{System.out.println("Try Again - \"" +c1+c2+c3+
"\" input error: "+e1.getMessage());}
}while(true);
}
// ****** Exception Handling
catch (userQuit e1){System.out.println("You have quit - Goodbye");}
catch (java.io.IOException e1) {System.out.println("IOException");}
}
} // end of Class MyCalculator3