AtomCaster.java
package calculator.atoms.visitor;
import java.math.BigDecimal;
import calculator.atoms.*;
/**
* AtomCaster is an AtomVisitor whose goal is to cast
* the visited atom to the specified type
* and throws errors if this cast is impossible e.g a complex to an Integer
*
* @see AtomVisitor
*/
public class AtomCaster extends AtomVisitor {
/* The type to Cast the visited Atom to */
private AtomType type;
/* The Result of the casting after the visit */
private Atom result;
/**
* returns the result of the cast of the visited to the specified type
*
* @return the Result of the cast from the visited Atom to the specified type
*/
public Atom getResult() {
return result;
}
/**
* Constructs an AtomCaster to cast to the specified type
*
* @param type The type to Cast the visited Atom to
*/
public AtomCaster(AtomType type) {
this.type = type;
}
/**
* Visiting a Real Atom to cast it to the specified type of the visitor
*
* @param r The visited Real to be cast
* @throws IllegalAtomCast in case of an impossible cast
*/
@Override
public void visit(Real r) {
switch (type) {
case REAL:
result = r;
break;
case INTEGER:
throw new IllegalAtomCast("Impossible to cast Real to Integer");
case RATIONNAL:
if (r.isNan() || r.isPlusInf() || r.isMinusInf()) {
throw new IllegalAtomCast("Impossible to cast NaN or Infinity Real to Rationnal");
}
result = new Rationnal(org.apache.commons.numbers.fraction.Fraction.from(r.getValue().doubleValue()));
break;
case COMPLEX:
if (r.isNan()) {
result = Complex.nan();
break;
}
result = new Complex(r.getValue().doubleValue(), 0);
break;
default:
result = null;
throw new UnsupportedOperationException("Cast Not implemented");
}
}
/**
* Visiting a Complex Atom to cast it to the specified type of the visitor
*
* @param c The visited Complex to be cast
* @throws IllegalAtomCast in case of an impossible cast
*/
@Override
public void visit(Complex c) {
switch (type) {
case COMPLEX:
result = c;
break;
case REAL:
case INTEGER:
case RATIONNAL:
throw new IllegalAtomCast("Impossible to cast Complex to " + type);
default:
result = null;
throw new UnsupportedOperationException("Cast Not implemented");
}
}
/**
* Visiting a Rationnal Atom to cast it to the specified type of the visitor
*
* @param q The visited Rationnal to be cast
* @throws IllegalAtomCast in case of an impossible cast
*/
@Override
public void visit(Rationnal q) {
switch (type) {
case RATIONNAL:
result = q;
break;
case REAL:
BigDecimal num = new BigDecimal(q.getNumerator());
BigDecimal denom = new BigDecimal(q.getDenominator());
result = new Real(num.divide(denom, Real.context));
break;
case COMPLEX:
result = new Complex(q.getValue().doubleValue(), 0);
break;
case INTEGER:
throw new IllegalAtomCast("Impossible to cast Rationnal to Integer");
default:
result = null;
throw new UnsupportedOperationException("Cast Not implemented");
}
}
/**
* Visiting a Integer Atom to cast it to the specified type of the visitor
*
* @param i The visited IntegerAtom to be cast
* @throws IllegalAtomCast in case of an impossible cast
*/
@Override
public void visit(IntegerAtom i) {
switch (type) {
case INTEGER:
result = i;
break;
case REAL:
result = new Real(i.getValue());
break;
case RATIONNAL:
result = new Rationnal(i.getValue(), 1);
break;
case COMPLEX:
result = new Complex(i.getValue(), 0);
break;
default:
result = null;
throw new UnsupportedOperationException("Cast Not implemented");
}
}
}