2017-07-26 13:31:05 -07:00
|
|
|
package org.nwapw.abacus.tree;
|
|
|
|
|
2017-07-28 21:25:02 -07:00
|
|
|
import org.nwapw.abacus.Abacus;
|
2017-07-26 18:44:30 -07:00
|
|
|
import org.nwapw.abacus.function.Function;
|
2017-07-26 13:31:05 -07:00
|
|
|
import org.nwapw.abacus.number.NumberInterface;
|
|
|
|
|
2017-07-26 19:16:10 -07:00
|
|
|
/**
|
|
|
|
* A reducer implementation that turns a tree into a single number.
|
|
|
|
* This is not always guaranteed to work.
|
|
|
|
*/
|
2017-07-26 13:31:05 -07:00
|
|
|
public class NumberReducer implements Reducer<NumberInterface> {
|
|
|
|
|
2017-07-26 19:16:10 -07:00
|
|
|
/**
|
|
|
|
* The plugin manager from which to draw the functions.
|
|
|
|
*/
|
2017-07-28 21:25:02 -07:00
|
|
|
private Abacus abacus;
|
2017-07-26 13:31:05 -07:00
|
|
|
|
2017-07-26 19:16:10 -07:00
|
|
|
/**
|
2017-07-28 21:25:02 -07:00
|
|
|
* Creates a new number reducer.
|
2017-07-30 21:11:32 -07:00
|
|
|
*
|
2017-07-28 21:25:02 -07:00
|
|
|
* @param abacus the calculator instance.
|
2017-07-26 19:16:10 -07:00
|
|
|
*/
|
2017-07-30 21:11:32 -07:00
|
|
|
public NumberReducer(Abacus abacus) {
|
2017-07-28 21:25:02 -07:00
|
|
|
this.abacus = abacus;
|
2017-07-26 13:31:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public NumberInterface reduceNode(TreeNode node, Object... children) {
|
2017-07-30 21:11:32 -07:00
|
|
|
if (node instanceof NumberNode) {
|
2017-07-26 13:31:05 -07:00
|
|
|
return ((NumberNode) node).getNumber();
|
2017-07-30 21:11:32 -07:00
|
|
|
} else if (node instanceof BinaryInfixNode) {
|
2017-07-26 13:31:05 -07:00
|
|
|
NumberInterface left = (NumberInterface) children[0];
|
|
|
|
NumberInterface right = (NumberInterface) children[1];
|
2017-07-28 21:25:02 -07:00
|
|
|
Function function = abacus.getPluginManager().operatorFor(((BinaryInfixNode) node).getOperation()).getFunction();
|
2017-07-30 21:11:32 -07:00
|
|
|
if (function == null) return null;
|
2017-07-26 18:44:30 -07:00
|
|
|
return function.apply(left, right);
|
2017-07-30 21:11:32 -07:00
|
|
|
} else if (node instanceof UnaryPrefixNode) {
|
2017-07-28 11:14:45 -07:00
|
|
|
NumberInterface child = (NumberInterface) children[0];
|
2017-07-28 21:25:02 -07:00
|
|
|
Function functionn = abacus.getPluginManager().operatorFor(((UnaryPrefixNode) node).getOperation()).getFunction();
|
2017-07-30 21:11:32 -07:00
|
|
|
if (functionn == null) return null;
|
2017-07-28 11:14:45 -07:00
|
|
|
return functionn.apply(child);
|
2017-07-30 21:11:32 -07:00
|
|
|
} else if (node instanceof FunctionNode) {
|
2017-07-26 18:44:30 -07:00
|
|
|
NumberInterface[] convertedChildren = new NumberInterface[children.length];
|
2017-07-30 21:11:32 -07:00
|
|
|
for (int i = 0; i < convertedChildren.length; i++) {
|
2017-07-26 18:44:30 -07:00
|
|
|
convertedChildren[i] = (NumberInterface) children[i];
|
|
|
|
}
|
2017-07-28 21:25:02 -07:00
|
|
|
Function function = abacus.getPluginManager().functionFor(((FunctionNode) node).getFunction());
|
2017-07-30 21:11:32 -07:00
|
|
|
if (function == null) return null;
|
2017-07-26 18:44:30 -07:00
|
|
|
return function.apply(convertedChildren);
|
2017-07-26 13:31:05 -07:00
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|