summaryrefslogtreecommitdiff
path: root/dice-lang/src/main/java/bjc/dicelang/ast/ArithmeticCollapser.java
blob: 5ad0a0f00d4552fb87740f117678b725eb15652c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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<Integer>	valueOp;

	public ArithmeticCollapser(OperatorDiceNode type,
			BinaryOperator<Integer> valueOp) {
		this.type = type;
		this.valueOp = valueOp;
	}

	@Override
	public IPair<Integer, ITree<IDiceASTNode>> apply(
			IFunctionalList<IPair<Integer, ITree<IDiceASTNode>>> nodes) {
		IPair<Integer, ITree<IDiceASTNode>> initState =
				new Pair<>(0, new Tree<>(type));

		BinaryOperator<IPair<Integer, ITree<IDiceASTNode>>> reducer =
				(accumulatedState, currentState) -> {
					return reduceStates(accumulatedState,
							currentState);
				};

		return nodes.reduceAux(initState, reducer, (state) -> state);
	}

	private IPair<Integer, ITree<IDiceASTNode>> reduceStates(
			IPair<Integer, ITree<IDiceASTNode>> accumulatedState,
			IPair<Integer, ITree<IDiceASTNode>> 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);
							});
				});
	}
}