summaryrefslogtreecommitdiff
path: root/dice-lang/src/bjc/dicelang/v1/ast/optimization/ArithmeticCollapser.java
blob: acc1afa4fca8f72fed654aa82404f1377860a0d6 (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
package bjc.dicelang.v1.ast.optimization;

import bjc.dicelang.v1.ast.DiceASTUtils;
import bjc.dicelang.v1.ast.nodes.DiceASTType;
import bjc.dicelang.v1.ast.nodes.IDiceASTNode;
import bjc.dicelang.v1.ast.nodes.ILiteralDiceNode;
import bjc.dicelang.v1.ast.nodes.IntegerLiteralNode;
import bjc.dicelang.v1.ast.nodes.OperatorDiceNode;
import bjc.utils.data.ITree;
import bjc.utils.data.Tree;
import bjc.utils.funcdata.IList;

import java.util.function.BinaryOperator;

class ArithmeticCollapser {
	private BinaryOperator<Integer>	reducer;
	private OperatorDiceNode	type;

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

	public ITree<IDiceASTNode> collapse(IList<ITree<IDiceASTNode>> children) {
		boolean allConstant = children.allMatch((subtree) -> {
			return subtree.transformHead((node) -> {
				if(node.getType() == DiceASTType.LITERAL)
					return ((ILiteralDiceNode) node).canOptimize();

				return false;
			});
		});

		if(!allConstant) return new Tree<>(type, children);

		int initState = DiceASTUtils.literalToInteger(children.first());

		return children.tail().reduceAux(initState, (currentNode, state) -> {
			return reducer.apply(state, DiceASTUtils.literalToInteger(currentNode));
		}, (state) -> new Tree<>(new IntegerLiteralNode(state)));
	}
}