bzr branch
http://gegoxaren.bato24.eu/bzr/vqdr/trunk
|
1
by Gustav Hartvigsson
* Initial code - far from done |
1 |
using VQDR.Common; |
2 |
using GLib; |
|
3 |
||
4 |
namespace VQDR.Expression { |
|
5 |
|
|
6 |
public abstract class Token : GLib.Object { |
|
|
19
by Gustav Hartvigsson
Added Round Up and Round Down function classes. |
7 |
|
|
1
by Gustav Hartvigsson
* Initial code - far from done |
8 |
//public static int VALUES_OUTPUT_PRECISION_FACTOR = (int)Math.pow(10, VALUES_OUTPUT_PRECISION_DIGITS); |
9 |
|
|
10 |
|
|
11 |
/** Max size of a single token */ |
|
12 |
public const int MAX_TOKEN_STRING_LENGTH = 64; |
|
13 |
/** Max size of an expression */ |
|
14 |
public const int MAX_TOTAL_STRING_LENGTH = 200; |
|
15 |
||
16 |
/** Max iteration number for a token (function) */ |
|
17 |
public const int MAX_TOKEN_ITERATIONS = 500; |
|
18 |
/** Max iteration number for the expression */ |
|
19 |
public const int MAX_TOTAL_ITERATIONS = 5000; |
|
|
14
by Gustav Hartvigsson
* Use enum instead of static values for the priority of operations. |
20 |
|
21 |
|
|
22 |
/** Operator precedence and associativity |
|
23 |
*
|
|
24 |
* higher number is higher priority, and is to be done befroe those
|
|
25 |
* with lower number.
|
|
26 |
*/
|
|
27 |
enum Prio { |
|
28 |
/** Priority for assignment "=" operator */ |
|
29 |
ASSIGNMENT = 0, |
|
30 |
/** Priority for conditional OR "||" operator */ |
|
31 |
CONDITIONAL_OR, |
|
32 |
/** Priority for conditional AND "&&" operator */ |
|
33 |
CONDITIONAL_AND, |
|
34 |
/** Priority for equality "==" and "!=" operators */ |
|
35 |
EQUALITY, |
|
36 |
/** Priority for comparison ">", "<", ">=", etc operators */ |
|
37 |
COMPARISON, |
|
38 |
/** Priority for addictive "+" and "-" operators */ |
|
39 |
ADDICTIVE, |
|
40 |
/** Priority for multiplicative "*" and "/" operators */ |
|
41 |
MULTIPLICATIVE, |
|
42 |
/** Priority for unary "+" and "-" and "!" operators */ |
|
43 |
UNARY, |
|
44 |
/** Priority for label assignment ":" operator */ |
|
45 |
LABEL, |
|
46 |
/** Priority for dice "d" operator */ |
|
47 |
DICE, |
|
48 |
/** Priority for functions */ |
|
49 |
FUNCTION, |
|
50 |
/** Priority for values */ |
|
51 |
VALUE; |
|
52 |
|
|
53 |
/** get the name of the priority */ |
|
54 |
string to_string () { |
|
55 |
switch (this) { |
|
56 |
case ASSIGNMENT: |
|
57 |
return "prio: assigment"; |
|
58 |
case CONDITIONAL_OR: |
|
59 |
return "prio: conditonal or"; |
|
60 |
case CONDITIONAL_AND: |
|
61 |
return "prio: conidonal and"; |
|
62 |
case EQUALITY: |
|
63 |
return "prio: equality"; |
|
64 |
case MULTIPLICATIVE: |
|
65 |
return "prio: multiplicative"; |
|
66 |
case UNARY: |
|
67 |
return "prio: unary"; |
|
68 |
case LABEL: |
|
69 |
return "prio: label"; |
|
70 |
case DICE: |
|
71 |
return "prio: dice"; |
|
72 |
case FUNCTION: |
|
73 |
return "prio: function"; |
|
74 |
case VALUE: |
|
75 |
return "prio: value"; |
|
76 |
default: |
|
77 |
assert_not_reached (); |
|
78 |
} |
|
79 |
} |
|
80 |
} |
|
|
1
by Gustav Hartvigsson
* Initial code - far from done |
81 |
|
82 |
/** Generation to use to get the root with {@link #getParent} */ |
|
83 |
protected const int ROOT_GENERATION = int.MAX; |
|
84 |
|
|
85 |
/* ********************************************************************** */ |
|
86 |
|
|
87 |
/** |
|
88 |
* tells weather the token is right associative or not.
|
|
89 |
*/
|
|
90 |
public bool right_assosiative {get;set; default = false;} |
|
91 |
|
|
92 |
|
|
93 |
private int real_priority; |
|
94 |
|
|
95 |
/** The parent token of this token*/ |
|
96 |
protected unowned Token? parent {protected get; protected set;} |
|
97 |
|
|
98 |
public virtual int priority {public get { |
|
99 |
return __get_priority (); |
|
100 |
} protected construct set { |
|
101 |
__set_priority (value); |
|
102 |
}} |
|
103 |
|
|
104 |
/** Starting position of the token in the expression */ |
|
105 |
protected int position; |
|
106 |
|
|
107 |
/** The index of the next child */ |
|
108 |
private int next_child; |
|
109 |
|
|
110 |
/** |
|
111 |
* The optional that this child represents.
|
|
112 |
*
|
|
113 |
*
|
|
114 |
*/
|
|
115 |
public int optional_num_child {public get; protected construct set;} |
|
116 |
|
|
117 |
/** The mandatory number of child this token can have */ |
|
118 |
public int mandatory_num_child {public get; protected construct set;} |
|
119 |
|
|
120 |
/** |
|
121 |
* The maximum number of chidren
|
|
122 |
*
|
|
123 |
* This is calculated at runtime as
|
|
124 |
* ''optional_num_child + mandatory_num_child''.
|
|
125 |
*
|
|
126 |
* Can not be set.
|
|
127 |
*/
|
|
128 |
public int max_num_child {get { |
|
129 |
return optional_num_child + mandatory_num_child; |
|
130 |
}} |
|
131 |
|
|
132 |
/** all children of this token */ |
|
133 |
private (unowned Token?)[] children; |
|
134 |
|
|
|
12.1.2
by Gustav Hartvigsson
* Fastnumber is now a struct, |
135 |
/* |
136 |
* These values should have a protected setter, but I could not get it to
|
|
137 |
* work. So we will have to live with this.
|
|
138 |
*/
|
|
139 |
public FastNumber result_value; |
|
140 |
public FastNumber result_max_value; |
|
141 |
public FastNumber result_min_value; |
|
|
1
by Gustav Hartvigsson
* Initial code - far from done |
142 |
public string result_string {public get; protected set; default = "";} |
143 |
|
|
144 |
construct { |
|
145 |
children = new Token[max_num_child]; |
|
146 |
next_child = 0; |
|
|
12.1.1
by Gustav Hartvigsson
* Switch to using FastNumber instead of something else. |
147 |
|
|
12.1.2
by Gustav Hartvigsson
* Fastnumber is now a struct, |
148 |
result_value = FastNumber (); |
149 |
result_max_value = FastNumber (); |
|
150 |
result_min_value = FastNumber (); |
|
|
1
by Gustav Hartvigsson
* Initial code - far from done |
151 |
} |
152 |
|
|
153 |
|
|
154 |
protected Token (int position) { |
|
155 |
this.position = position; |
|
156 |
} |
|
157 |
|
|
158 |
/** |
|
159 |
* Reorders result_min_value and result_max_value, so that
|
|
160 |
* result_max varue is the bigger of the two, and
|
|
161 |
* result_min_value is the smaller.
|
|
162 |
*/
|
|
163 |
protected void reorder_max_min_values () { |
|
|
12.1.1
by Gustav Hartvigsson
* Switch to using FastNumber instead of something else. |
164 |
if (result_max_value.compare (result_min_value) <= 0) { |
165 |
FastNumber tmp = result_max_value; |
|
|
1
by Gustav Hartvigsson
* Initial code - far from done |
166 |
result_max_value = result_min_value; |
167 |
result_min_value = tmp; |
|
168 |
} |
|
169 |
} |
|
170 |
|
|
171 |
/** |
|
172 |
* Get a child token to this token.
|
|
173 |
*
|
|
174 |
* Child positions are between 1 and max_num_child.
|
|
175 |
*
|
|
176 |
* and index of 0 is illegal.
|
|
177 |
*/
|
|
178 |
public unowned Token? get_child (int index) requires (index > 0 && index <= max_num_child) { |
|
179 |
|
|
180 |
return children[index -1 ]; |
|
181 |
} |
|
182 |
|
|
183 |
|
|
184 |
/** |
|
185 |
* Set a child token to this this token.
|
|
186 |
*
|
|
187 |
* Child positions are between 1 and max_num_child.
|
|
188 |
*
|
|
189 |
* and index of 0 is illegal.
|
|
190 |
*/
|
|
191 |
public void set_child (int index, Token? child) requires (index > 0 && index <= max_num_child) { |
|
192 |
|
|
193 |
children[index - 1] = child; |
|
194 |
|
|
195 |
if (children[index - 1] != null) { |
|
196 |
children[index -1].parent = this; |
|
197 |
|
|
198 |
} |
|
199 |
} |
|
200 |
|
|
201 |
/** |
|
202 |
* is functionally equal to get_child (1);
|
|
203 |
*/
|
|
204 |
public Token get_left_child () { |
|
205 |
return get_child (1); |
|
206 |
} |
|
207 |
|
|
208 |
/** |
|
209 |
* is functionally equal to get_child (2);
|
|
210 |
*/
|
|
211 |
public Token get_right_child () { |
|
212 |
return get_child (2); |
|
213 |
} |
|
214 |
|
|
215 |
/** |
|
216 |
* is functionally equal to set_child (1, token);
|
|
217 |
*/
|
|
218 |
public void set_left_child (Token token) { |
|
219 |
set_child (1, token); |
|
220 |
} |
|
221 |
|
|
222 |
/** |
|
223 |
* is functionally equal to set_child (2, token);
|
|
224 |
*/
|
|
225 |
public void set_right_child (Token token) { |
|
226 |
set_child (2, token); |
|
227 |
} |
|
228 |
|
|
229 |
public void evaluate (Context instance) throws GLib.Error { |
|
230 |
evaluate_self (instance); |
|
231 |
} |
|
232 |
|
|
233 |
/** |
|
234 |
* Evalutates current token tree.
|
|
235 |
*
|
|
236 |
* This Method must evaluate the token subtree, and assign proper values to
|
|
237 |
* the following properties:
|
|
238 |
*
|
|
239 |
* * result_value
|
|
240 |
* * result_max_value
|
|
241 |
* * result_min_value
|
|
242 |
* * result_string
|
|
243 |
*
|
|
244 |
* @param instance The context to be used valfor this tree.
|
|
245 |
* @throws GLib.Error an error if an error has orrured in the evaluation of the tree.
|
|
246 |
*/
|
|
247 |
protected abstract void evaluate_self (Context instance) throws GLib.Error; |
|
248 |
|
|
|
11
by Gustav Hartvigsson
* FastNumber: |
249 |
/* *********** IGNORE THE MESS I HAVE CREATED FOR MY SELF *************** */ |
|
1
by Gustav Hartvigsson
* Initial code - far from done |
250 |
/** IGNORE ME */ |
251 |
protected void __set_priority (int prio) { |
|
252 |
real_priority = prio; |
|
253 |
} |
|
254 |
|
|
255 |
/** IGNORE ME*/ |
|
256 |
protected int __get_priority () { |
|
257 |
return real_priority; |
|
258 |
} |
|
259 |
|
|
260 |
|
|
261 |
} |
|
262 |
|
|
263 |
}
|