package bjc.dicelang.ast; import java.util.function.BinaryOperator; import bjc.dicelang.ast.nodes.IDiceASTNode; import bjc.dicelang.ast.nodes.OperatorDiceNode; import bjc.utils.data.IPair; import bjc.utils.data.Pair; import bjc.utils.funcdata.IFunctionalList; import bjc.utils.funcdata.ITree; import bjc.utils.funcdata.Tree; /** * Responsible for collapsing arithmetic operators * * @author ben * */ final class ArithmeticCollapser implements IOperatorCollapser { private OperatorDiceNode type; private BinaryOperator valueOp; public ArithmeticCollapser(OperatorDiceNode type, BinaryOperator valueOp) { this.type = type; this.valueOp = valueOp; } @Override public IPair> apply( IFunctionalList>> nodes) { IPair> initState = new Pair<>(0, new Tree<>(type)); BinaryOperator>> reducer = (currentState, accumulatedState) -> { // Force evaluation of accumulated state to prevent // certain bugs from occuring accumulatedState.merge((l, r) -> null); return reduceStates(accumulatedState, currentState); }; IPair> reducedState = nodes.reduceAux(initState, reducer, (state) -> state); return reducedState; } private IPair> reduceStates( IPair> accumulatedState, IPair> currentState) { return accumulatedState .bind((accumulatedValue, accumulatedTree) -> { return currentState .bind((currentValue, currentTree) -> { accumulatedTree.addChild(currentTree); Integer combinedValue = valueOp.apply( accumulatedValue, currentValue); return new Pair<>(combinedValue, accumulatedTree); }); }); } }