View Javadoc
1   package calculator.operations;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   
6   import calculator.Expression;
7   import calculator.IllegalConstruction;
8   import calculator.Notation;
9   import calculator.atoms.Atom;
10  import calculator.atoms.Complex;
11  import calculator.atoms.IntegerAtom;
12  import calculator.atoms.Rationnal;
13  import calculator.atoms.Real;
14  import visitor.Printer;
15  import visitor.Visitor;
16  
17  /**
18   * Operation is an abstract class that represents arithmetic operations,
19   * which are a special kind of Expressions, just like numbers are.
20   *
21   * @see Expression
22   * @see Atom
23   */
24  public abstract class Operation implements Expression {
25  	/**
26  	 * The list of expressions passed as an argument to the arithmetic operation
27  	 */
28  	public List<Expression> args;
29  
30  	/**
31  	 * The character used to represent the arithmetic operation (e.g. "+", "*")
32  	 */
33  	protected String symbol;
34  
35  	/**
36  	 * The neutral element of the operation (e.g. 1 for *, 0 for +)
37  	 */
38  	protected int neutral;
39  
40  	/**
41  	 * To construct an operation with a list of expressions as arguments,
42  	 * as well as the Notation used to represent the operation.
43  	 *
44  	 * @param elist The list of expressions passed as argument to the arithmetic
45  	 *              operation
46  	 * @throws IllegalConstruction Exception thrown if a null list of expressions is
47  	 *                             passed as argument
48  	 */
49  	protected /* constructor */ Operation(List<Expression> elist)
50  			throws IllegalConstruction {
51  		if (elist == null) {
52  			throw new IllegalConstruction();
53  		} else {
54  			args = new ArrayList<>(elist);
55  		}
56  	}
57  
58  	/**
59  	 * getter method to return the number of arguments of an arithmetic operation.
60  	 *
61  	 * @return The number of arguments of the arithmetic operation.
62  	 */
63  	public List<Expression> getArgs() {
64  		return args;
65  	}
66  
67  	/**
68  	 * getter method to return the symbol of the arithmetic operation.
69  	 *
70  	 * @return The symbol of the arithmetic operation (e.g. "+", "-", "*", "/").
71  	 */
72  	public String getSymbol() {
73  		return symbol;
74  	}
75  
76  	/**
77  	 * Abstract method representing the actual binary arithmetic operation to
78  	 * compute on Reals
79  	 * 
80  	 * @param r1 first Real of the binary operation
81  	 * @param r2 second Real of the binary operation
82  	 * @return result of computing the binary operation
83  	 */
84  	public abstract Real op(Real r1, Real r2);
85  
86  	/**
87  	 * Abstract method representing the actual binary arithmetic operation to
88  	 * compute on Complexes
89  	 * 
90  	 * @param c1 first Complex of the binary operation
91  	 * @param c2 second Complex of the binary operation
92  	 * @return result of computing the binary operation
93  	 */
94  	public abstract Complex op(Complex c1, Complex c2);
95  
96  	/**
97  	 * Abstract method representing the actual binary arithmetic operation to
98  	 * compute on Integer
99  	 * 
100 	 * @param i1 first Integer of the binary operation
101 	 * @param i2 second Integer of the binary operation
102 	 * @return result of computing the binary operation
103 	 */
104 	public abstract Atom op(IntegerAtom i1, IntegerAtom i2);
105 
106 	/**
107 	 * Abstract method representing the actual binary arithmetic operation to
108 	 * compute on Rationnals
109 	 * 
110 	 * @param q1 first Rationnal of the binary operation
111 	 * @param q2 second Rationnal of the binary operation
112 	 * @return result of computing the binary operation
113 	 */
114 	public abstract Atom op(Rationnal q1, Rationnal q2);
115 
116 	/**
117 	 * Add more parameters to the existing list of parameters
118 	 *
119 	 * @param params The list of parameters to be added
120 	 */
121 	public void addMoreParams(List<Expression> params) {
122 		args.addAll(params);
123 	}
124 
125 	/**
126 	 * Accept method to implement the visitor design pattern to traverse arithmetic
127 	 * expressions.
128 	 * Each operation will delegate the visitor to each of its arguments
129 	 * expressions,
130 	 * and will then pass itself to the visitor object to get processed by the
131 	 * visitor object.
132 	 *
133 	 * @param v The visitor object
134 	 */
135 	public void accept(Visitor v) {
136 		v.visit(this);
137 	}
138 
139 	/**
140 	 * Convert the arithmetic operation into a String to allow it to be printed,
141 	 * using the default printer
142 	 *
143 	 * @return The String that is the result of the conversion.
144 	 */
145 	@Override
146 	public final String toString() {
147 		Printer p = new Printer();
148 		this.accept(p);
149 		return p.getResult();
150 	}
151 
152 	/**
153 	 * Appeal to the visitor to convert the arithmetic operation into a String to
154 	 * allow it to be printed,
155 	 * using the notation n (prefix, infix or postfix) that is specified as a
156 	 * parameter.
157 	 *
158 	 * @param n The notation to be used for representing the operation (prefix,
159 	 *          infix or postfix)
160 	 * @return The String that is the result of the conversion.
161 	 */
162 	public final String toString(Notation n) {
163 		Printer p = new Printer(n);
164 		this.accept(p);
165 		return p.getResult();
166 	}
167 
168 	/**
169 	 * Two operation objects are equal if their list of arguments is equal and they
170 	 * correspond to the same operation.
171 	 *
172 	 * @param o The object to compare with
173 	 * @return The result of the equality comparison
174 	 */
175 	@Override
176 	public boolean equals(Object o) {
177 		if (o == null)
178 			return false; // No object should be equal to null
179 
180 		if (this == o)
181 			return true; // If it's the same object, they're obviously equal
182 
183 		if (getClass() != o.getClass())
184 			return false; // getClass() instead of instanceof() because an addition is not the same as a
185 										// multiplication
186 
187 		Operation other = (Operation) o;
188 		return this.args.equals(other.getArgs());
189 	}
190 
191 	/**
192 	 * The method hashCode needs to be overridden it the equals method is
193 	 * overridden;
194 	 * otherwise there may be problems when you use your object in hashed
195 	 * collections
196 	 * such as HashMap, HashSet, LinkedHashSet.
197 	 *
198 	 * @return The result of computing the hash.
199 	 */
200 	@Override
201 	public int hashCode() {
202 		int result = 5;
203 		int prime = 31;
204 		result = prime * result + neutral;
205 		result = prime * result + symbol.hashCode();
206 		result = prime * result + args.hashCode();
207 		return result;
208 	}
209 
210 }