summaryrefslogtreecommitdiff
path: root/base/src/bjc/dicelang/Node.java
blob: 55273e8036e732af5706d569b108e7c1fc966ce8 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package bjc.dicelang;

import static bjc.dicelang.EvaluatorResult.Type.FAILURE;

import bjc.utils.data.ITree;

/*
 * @TODO 10/09/17 Ben Culkin :NodeReorg
 * 	Same thing, different class. Split into subclasses based off of the type
 * 	values.
 */
/**
 * Represents a node in the AST.
 *
 * @author Ben Culkin
 */
public class Node {
	public static enum Type {
		ROOT, TOKREF, UNARYOP, BINOP, GROUP, OGROUP, RESULT
	}

	public static enum GroupType {
		ARRAY, CODE
	}

	public final Type type;

	// These can have or not have values based of the node type
	public Token tokenVal;
	public Token.Type operatorType;
	public GroupType groupType;
	public EvaluatorResult resultVal;

	public Node(final Type typ) {
		type = typ;
	}

	public Node(final Type typ, final Token tokenVl) {
		this(typ);

		tokenVal = tokenVl;
	}

	public Node(final Type typ, final Token.Type opType) {
		this(typ);

		operatorType = opType;
	}

	public Node(final Type typ, final GroupType grupType) {
		this(typ);

		groupType = grupType;
	}

	public Node(final Type typ, final EvaluatorResult res) {
		this(typ);

		resultVal = res;
	}

	@Override
	public String toString() {
		switch (type) {
		case UNARYOP:
		case BINOP:
			return "(" + type.name() + " : " + operatorType + ")";

		case OGROUP:
		case TOKREF:
			return "(" + type.name() + " : " + tokenVal + ")";

		case GROUP:
			return "(" + type.name() + " : " + groupType + ")";

		case RESULT:
			return "(" + type.name() + " : " + resultVal + ")";

		default:
			return "Unknown node type " + type;
		}
	}

	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof Node)) {
			return false;
		}

		final Node otk = (Node) other;

		if (otk.type != type) {
			return false;
		}

		switch (type) {
		case OGROUP:
			return tokenVal.equals(otk.tokenVal);

		default:
			return true;
		}
	}

	@Override
	public int hashCode() {
		return super.hashCode();
	}

	static Node FAIL(final EvaluatorResult res) {
		EvaluatorResult eres = new EvaluatorResult(FAILURE, new Node(Type.RESULT, res));
		return new Node(Type.RESULT, eres);
	}

	static Node FAIL(final Node orig) {
		return new Node(Type.RESULT, new EvaluatorResult(FAILURE, orig));
	}

	static Node FAIL(final ITree<Node> orig) {
		return new Node(Type.RESULT, new EvaluatorResult(FAILURE, orig));
	}

	/*
	 * @TODO 10/09/17 Ben Culkin :NodeFAIL These methods should be moved to Node.
	 */
	/* Create a failing node. */
	static Node FAIL() {
		return new Node(Type.RESULT, new EvaluatorResult(FAILURE));
	}
}