summaryrefslogtreecommitdiff
path: root/dice-lang/src/bjc/dicelang/ast/DiceASTUtils.java
blob: d98c8feaee7a05ebeb5e6076157a5662ac9be548 (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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package bjc.dicelang.ast;

import bjc.utils.funcdata.ITree;

import bjc.dicelang.IDiceExpression;
import bjc.dicelang.ScalarDie;
import bjc.dicelang.ast.nodes.DiceASTType;
import bjc.dicelang.ast.nodes.DiceLiteralNode;
import bjc.dicelang.ast.nodes.IDiceASTNode;
import bjc.dicelang.ast.nodes.ILiteralDiceNode;
import bjc.dicelang.ast.nodes.IntegerLiteralNode;

/**
 * Functions that are useful when dealing with dice ASTs
 * 
 * @author ben
 *
 */
public class DiceASTUtils {
	/**
	 * Check if a dice AST contains a simple variable reference
	 * 
	 * @param nameTree
	 *            The tree to check for a reference in
	 * @return Whether or not a dice AST contains a simple variable
	 *         reference
	 */
	public static boolean containsSimpleVariable(
			ITree<IDiceASTNode> nameTree) {
		return nameTree.transformHead((nameNode) -> {
			if (nameNode.getType() != DiceASTType.VARIABLE) {
				return false;
			}

			return true;
		});
	}

	/**
	 * Convert an literal AST node to a dice expression, if possible.
	 * 
	 * @param tree
	 *            The node to convert in tree form
	 * @return The tree as a dice expression
	 * 
	 * @throws ClassCastException
	 *             if the head of the tree is not a literal (implements
	 *             {@link ILiteralDiceNode})
	 * @throws UnsupportedOperationException
	 *             if the head of the tree is not optimizable
	 */
	public static IDiceExpression literalToExpression(
			ITree<IDiceASTNode> tree) {
		ILiteralDiceNode literalNode = (ILiteralDiceNode) tree.getHead();

		switch (literalNode.getLiteralType()) {
			case DICE:
				return ((DiceLiteralNode) literalNode).getValue();
			case INTEGER:
				return new ScalarDie(
						((IntegerLiteralNode) literalNode).getValue());
			default:
				throw new UnsupportedOperationException(
						"This type of literal isn't convertable to an expression");
		}
	}

	/**
	 * Convert an literal AST node to an integer, if possible.
	 * 
	 * @param tree
	 *            The literal node to convert, as a tree
	 * @return The node as an integer
	 * 
	 * @throws ClassCastException
	 *             if the head of the tree is not a literal (implements
	 *             {@link ILiteralDiceNode})
	 * @throws UnsupportedOperationException
	 *             if the head of the tree is not optimizable
	 */
	public static int literalToInteger(ITree<IDiceASTNode> tree) {
		return tree.transformHead((node) -> {
			return ((ILiteralDiceNode) node).optimize();
		});
	}
}