package org.nwapw.abacus.tree;

import org.nwapw.abacus.Abacus;
import org.nwapw.abacus.function.Function;
import org.nwapw.abacus.number.NumberInterface;

/**
 * A reducer implementation that turns a tree into a single number.
 * This is not always guaranteed to work.
 */
public class NumberReducer implements Reducer<NumberInterface> {

    /**
     * The plugin manager from which to draw the functions.
     */
    private Abacus abacus;

    /**
     * Creates a new number reducer.
     *
     * @param abacus the calculator instance.
     */
    public NumberReducer(Abacus abacus) {
        this.abacus = abacus;
    }

    @Override
    public NumberInterface reduceNode(TreeNode node, Object... children) {
        if (node instanceof NumberNode) {
            return abacus.numberFromString(((NumberNode) node).getNumber());
        } else if(node instanceof VariableNode) {
            return abacus.numberFromString("0");
        } else if (node instanceof BinaryNode) {
            NumberInterface left = (NumberInterface) children[0];
            NumberInterface right = (NumberInterface) children[1];
            Function function = abacus.getPluginManager().operatorFor(((BinaryNode) node).getOperation()).getFunction();
            if (function == null) return null;
            return function.apply(left, right);
        } else if (node instanceof UnaryNode) {
            NumberInterface child = (NumberInterface) children[0];
            Function functionn = abacus.getPluginManager().operatorFor(((UnaryNode) node).getOperation()).getFunction();
            if (functionn == null) return null;
            return functionn.apply(child);
        } else if (node instanceof FunctionNode) {
            NumberInterface[] convertedChildren = new NumberInterface[children.length];
            for (int i = 0; i < convertedChildren.length; i++) {
                convertedChildren[i] = (NumberInterface) children[i];
            }
            Function function = abacus.getPluginManager().functionFor(((FunctionNode) node).getCallTo());
            if (function == null) return null;
            return function.apply(convertedChildren);
        }
        return null;
    }

}

@@ -100,16 +100,68 @@
 nction;%0A
+import org.nwapw.abacus.function.TreeValueFunction;%0A
 import o
@@ -2201,16 +2201,587 @@
 ldren);%0A
+        %7D else if (node instanceof TreeValueFunctionNode)%7B%0A            CallNode callNode = (CallNode) node;%0A            TreeNode%5B%5D realChildren = new TreeNode%5BcallNode.getChildren().size()%5D;%0A            for(int i = 0; i %3C realChildren.length; i++)%7B%0A                realChildren%5Bi%5D = callNode.getChildren().get(i);%0A            %7D%0A            TreeValueFunction function =%0A                    abacus.getPluginManager().treeValueFunctionFor(callNode.getCallTo());%0A            if(function == null) return null;%0A            return function.applyWithReducer(this, realChildren);%0A
         

Add Tree Value Functions to NumberReducer.