Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
LogicalExpr.cs
Go to the documentation of this file.
3
5
6internal sealed class LogicalExpr : ValueQuery
7{
8 private delegate bool cmpXslt(Operator.Op op, object val1, object val2);
9
10 private struct NodeSet
11 {
12 private readonly Query _opnd;
13
15
16 public string Value => _current.Value;
17
18 public NodeSet(object opnd)
19 {
20 _opnd = (Query)opnd;
21 _current = null;
22 }
23
24 public bool MoveNext()
25 {
27 return _current != null;
28 }
29
30 public void Reset()
31 {
32 _opnd.Reset();
33 }
34 }
35
36 private readonly Operator.Op _op;
37
38 private readonly Query _opnd1;
39
40 private readonly Query _opnd2;
41
42 private static readonly cmpXslt[][] s_CompXsltE = new cmpXslt[5][]
43 {
44 new cmpXslt[5] { cmpNumberNumber, null, null, null, null },
45 new cmpXslt[5] { cmpStringNumber, cmpStringStringE, null, null, null },
46 new cmpXslt[5] { cmpBoolNumberE, cmpBoolStringE, cmpBoolBoolE, null, null },
49 };
50
51 private static readonly cmpXslt[][] s_CompXsltO = new cmpXslt[5][]
52 {
53 new cmpXslt[5] { cmpNumberNumber, null, null, null, null },
54 new cmpXslt[5] { cmpStringNumber, cmpStringStringO, null, null, null },
55 new cmpXslt[5] { cmpBoolNumberO, cmpBoolStringO, cmpBoolBoolO, null, null },
58 };
59
60 public override XPathResultType StaticType => XPathResultType.Boolean;
61
62 public LogicalExpr(Operator.Op op, Query opnd1, Query opnd2)
63 {
64 _op = op;
65 _opnd1 = opnd1;
66 _opnd2 = opnd2;
67 }
68
69 private LogicalExpr(LogicalExpr other)
70 : base(other)
71 {
72 _op = other._op;
73 _opnd1 = Query.Clone(other._opnd1);
74 _opnd2 = Query.Clone(other._opnd2);
75 }
76
77 public override void SetXsltContext(XsltContext context)
78 {
79 _opnd1.SetXsltContext(context);
80 _opnd2.SetXsltContext(context);
81 }
82
83 public override object Evaluate(XPathNodeIterator nodeIterator)
84 {
85 Operator.Op op = _op;
86 object obj = _opnd1.Evaluate(nodeIterator);
87 object obj2 = _opnd2.Evaluate(nodeIterator);
88 int num = (int)GetXPathType(obj);
89 int num2 = (int)GetXPathType(obj2);
90 if (num < num2)
91 {
92 op = Operator.InvertOperator(op);
93 object obj3 = obj;
94 obj = obj2;
95 obj2 = obj3;
96 int num3 = num;
97 num = num2;
98 num2 = num3;
99 }
100 cmpXslt cmpXslt = ((op != Operator.Op.EQ && op != Operator.Op.NE) ? s_CompXsltO[num][num2] : s_CompXsltE[num][num2]);
101 return cmpXslt(op, obj, obj2);
102 }
103
104 private static bool cmpQueryQueryE(Operator.Op op, object val1, object val2)
105 {
106 bool flag = op == Operator.Op.EQ;
107 NodeSet nodeSet = new NodeSet(val1);
108 NodeSet nodeSet2 = new NodeSet(val2);
109 while (true)
110 {
111 if (!nodeSet.MoveNext())
112 {
113 return false;
114 }
115 if (!nodeSet2.MoveNext())
116 {
117 break;
118 }
119 string value = nodeSet.Value;
120 do
121 {
122 if (value == nodeSet2.Value == flag)
123 {
124 return true;
125 }
126 }
127 while (nodeSet2.MoveNext());
128 nodeSet2.Reset();
129 }
130 return false;
131 }
132
133 private static bool cmpQueryQueryO(Operator.Op op, object val1, object val2)
134 {
135 NodeSet nodeSet = new NodeSet(val1);
136 NodeSet nodeSet2 = new NodeSet(val2);
137 while (true)
138 {
139 if (!nodeSet.MoveNext())
140 {
141 return false;
142 }
143 if (!nodeSet2.MoveNext())
144 {
145 break;
146 }
147 double n = NumberFunctions.Number(nodeSet.Value);
148 do
149 {
150 if (cmpNumberNumber(op, n, NumberFunctions.Number(nodeSet2.Value)))
151 {
152 return true;
153 }
154 }
155 while (nodeSet2.MoveNext());
156 nodeSet2.Reset();
157 }
158 return false;
159 }
160
161 private static bool cmpQueryNumber(Operator.Op op, object val1, object val2)
162 {
163 NodeSet nodeSet = new NodeSet(val1);
164 double n = (double)val2;
165 while (nodeSet.MoveNext())
166 {
167 if (cmpNumberNumber(op, NumberFunctions.Number(nodeSet.Value), n))
168 {
169 return true;
170 }
171 }
172 return false;
173 }
174
175 private static bool cmpQueryStringE(Operator.Op op, object val1, object val2)
176 {
177 NodeSet nodeSet = new NodeSet(val1);
178 string n = (string)val2;
179 while (nodeSet.MoveNext())
180 {
181 if (cmpStringStringE(op, nodeSet.Value, n))
182 {
183 return true;
184 }
185 }
186 return false;
187 }
188
189 private static bool cmpQueryStringO(Operator.Op op, object val1, object val2)
190 {
191 NodeSet nodeSet = new NodeSet(val1);
192 double n = NumberFunctions.Number((string)val2);
193 while (nodeSet.MoveNext())
194 {
195 if (cmpNumberNumberO(op, NumberFunctions.Number(nodeSet.Value), n))
196 {
197 return true;
198 }
199 }
200 return false;
201 }
202
203 private static bool cmpRtfQueryE(Operator.Op op, object val1, object val2)
204 {
205 string n = Rtf(val1);
206 NodeSet nodeSet = new NodeSet(val2);
207 while (nodeSet.MoveNext())
208 {
209 if (cmpStringStringE(op, n, nodeSet.Value))
210 {
211 return true;
212 }
213 }
214 return false;
215 }
216
217 private static bool cmpRtfQueryO(Operator.Op op, object val1, object val2)
218 {
219 double n = NumberFunctions.Number(Rtf(val1));
220 NodeSet nodeSet = new NodeSet(val2);
221 while (nodeSet.MoveNext())
222 {
223 if (cmpNumberNumberO(op, n, NumberFunctions.Number(nodeSet.Value)))
224 {
225 return true;
226 }
227 }
228 return false;
229 }
230
231 private static bool cmpQueryBoolE(Operator.Op op, object val1, object val2)
232 {
233 bool n = new NodeSet(val1).MoveNext();
234 bool n2 = (bool)val2;
235 return cmpBoolBoolE(op, n, n2);
236 }
237
238 private static bool cmpQueryBoolO(Operator.Op op, object val1, object val2)
239 {
240 double n = (new NodeSet(val1).MoveNext() ? 1.0 : 0.0);
241 double n2 = NumberFunctions.Number((bool)val2);
242 return cmpNumberNumberO(op, n, n2);
243 }
244
245 private static bool cmpBoolBoolE(Operator.Op op, bool n1, bool n2)
246 {
247 return op == Operator.Op.EQ == (n1 == n2);
248 }
249
250 private static bool cmpBoolBoolE(Operator.Op op, object val1, object val2)
251 {
252 bool n = (bool)val1;
253 bool n2 = (bool)val2;
254 return cmpBoolBoolE(op, n, n2);
255 }
256
257 private static bool cmpBoolBoolO(Operator.Op op, object val1, object val2)
258 {
259 double n = NumberFunctions.Number((bool)val1);
260 double n2 = NumberFunctions.Number((bool)val2);
261 return cmpNumberNumberO(op, n, n2);
262 }
263
264 private static bool cmpBoolNumberE(Operator.Op op, object val1, object val2)
265 {
266 bool n = (bool)val1;
267 bool n2 = BooleanFunctions.toBoolean((double)val2);
268 return cmpBoolBoolE(op, n, n2);
269 }
270
271 private static bool cmpBoolNumberO(Operator.Op op, object val1, object val2)
272 {
273 double n = NumberFunctions.Number((bool)val1);
274 double n2 = (double)val2;
275 return cmpNumberNumberO(op, n, n2);
276 }
277
278 private static bool cmpBoolStringE(Operator.Op op, object val1, object val2)
279 {
280 bool n = (bool)val1;
281 bool n2 = BooleanFunctions.toBoolean((string)val2);
282 return cmpBoolBoolE(op, n, n2);
283 }
284
285 private static bool cmpRtfBoolE(Operator.Op op, object val1, object val2)
286 {
287 bool n = BooleanFunctions.toBoolean(Rtf(val1));
288 bool n2 = (bool)val2;
289 return cmpBoolBoolE(op, n, n2);
290 }
291
292 private static bool cmpBoolStringO(Operator.Op op, object val1, object val2)
293 {
294 return cmpNumberNumberO(op, NumberFunctions.Number((bool)val1), NumberFunctions.Number((string)val2));
295 }
296
297 private static bool cmpRtfBoolO(Operator.Op op, object val1, object val2)
298 {
299 return cmpNumberNumberO(op, NumberFunctions.Number(Rtf(val1)), NumberFunctions.Number((bool)val2));
300 }
301
302 private static bool cmpNumberNumber(Operator.Op op, double n1, double n2)
303 {
304 return op switch
305 {
306 Operator.Op.LT => n1 < n2,
307 Operator.Op.GT => n1 > n2,
308 Operator.Op.LE => n1 <= n2,
309 Operator.Op.GE => n1 >= n2,
310 Operator.Op.EQ => n1 == n2,
311 Operator.Op.NE => n1 != n2,
312 _ => false,
313 };
314 }
315
316 private static bool cmpNumberNumberO(Operator.Op op, double n1, double n2)
317 {
318 return op switch
319 {
320 Operator.Op.LT => n1 < n2,
321 Operator.Op.GT => n1 > n2,
322 Operator.Op.LE => n1 <= n2,
323 Operator.Op.GE => n1 >= n2,
324 _ => false,
325 };
326 }
327
328 private static bool cmpNumberNumber(Operator.Op op, object val1, object val2)
329 {
330 double n = (double)val1;
331 double n2 = (double)val2;
332 return cmpNumberNumber(op, n, n2);
333 }
334
335 private static bool cmpStringNumber(Operator.Op op, object val1, object val2)
336 {
337 double n = (double)val2;
338 double n2 = NumberFunctions.Number((string)val1);
339 return cmpNumberNumber(op, n2, n);
340 }
341
342 private static bool cmpRtfNumber(Operator.Op op, object val1, object val2)
343 {
344 double n = (double)val2;
345 double n2 = NumberFunctions.Number(Rtf(val1));
346 return cmpNumberNumber(op, n2, n);
347 }
348
349 private static bool cmpStringStringE(Operator.Op op, string n1, string n2)
350 {
351 return op == Operator.Op.EQ == (n1 == n2);
352 }
353
354 private static bool cmpStringStringE(Operator.Op op, object val1, object val2)
355 {
356 string n = (string)val1;
357 string n2 = (string)val2;
358 return cmpStringStringE(op, n, n2);
359 }
360
361 private static bool cmpRtfStringE(Operator.Op op, object val1, object val2)
362 {
363 string n = Rtf(val1);
364 string n2 = (string)val2;
365 return cmpStringStringE(op, n, n2);
366 }
367
368 private static bool cmpRtfRtfE(Operator.Op op, object val1, object val2)
369 {
370 string n = Rtf(val1);
371 string n2 = Rtf(val2);
372 return cmpStringStringE(op, n, n2);
373 }
374
375 private static bool cmpStringStringO(Operator.Op op, object val1, object val2)
376 {
377 double n = NumberFunctions.Number((string)val1);
378 double n2 = NumberFunctions.Number((string)val2);
379 return cmpNumberNumberO(op, n, n2);
380 }
381
382 private static bool cmpRtfStringO(Operator.Op op, object val1, object val2)
383 {
384 double n = NumberFunctions.Number(Rtf(val1));
385 double n2 = NumberFunctions.Number((string)val2);
386 return cmpNumberNumberO(op, n, n2);
387 }
388
389 private static bool cmpRtfRtfO(Operator.Op op, object val1, object val2)
390 {
391 double n = NumberFunctions.Number(Rtf(val1));
392 double n2 = NumberFunctions.Number(Rtf(val2));
393 return cmpNumberNumberO(op, n, n2);
394 }
395
396 public override XPathNodeIterator Clone()
397 {
398 return new LogicalExpr(this);
399 }
400
401 private static string Rtf(object o)
402 {
403 return ((XPathNavigator)o).Value;
404 }
405}
static bool toBoolean(double number)
static bool cmpRtfQueryE(Operator.Op op, object val1, object val2)
static bool cmpStringStringO(Operator.Op op, object val1, object val2)
static bool cmpRtfStringO(Operator.Op op, object val1, object val2)
override XPathResultType StaticType
static bool cmpRtfQueryO(Operator.Op op, object val1, object val2)
static bool cmpBoolBoolE(Operator.Op op, bool n1, bool n2)
static bool cmpStringStringE(Operator.Op op, string n1, string n2)
static bool cmpRtfBoolE(Operator.Op op, object val1, object val2)
override void SetXsltContext(XsltContext context)
static bool cmpRtfBoolO(Operator.Op op, object val1, object val2)
static bool cmpRtfStringE(Operator.Op op, object val1, object val2)
static bool cmpStringStringE(Operator.Op op, object val1, object val2)
static bool cmpStringNumber(Operator.Op op, object val1, object val2)
static bool cmpQueryNumber(Operator.Op op, object val1, object val2)
static readonly cmpXslt[][] s_CompXsltE
static bool cmpBoolNumberO(Operator.Op op, object val1, object val2)
static bool cmpQueryQueryO(Operator.Op op, object val1, object val2)
override object Evaluate(XPathNodeIterator nodeIterator)
static bool cmpRtfNumber(Operator.Op op, object val1, object val2)
static bool cmpRtfRtfO(Operator.Op op, object val1, object val2)
LogicalExpr(Operator.Op op, Query opnd1, Query opnd2)
static bool cmpQueryBoolO(Operator.Op op, object val1, object val2)
static readonly cmpXslt[][] s_CompXsltO
static bool cmpBoolNumberE(Operator.Op op, object val1, object val2)
delegate bool cmpXslt(Operator.Op op, object val1, object val2)
static bool cmpQueryStringO(Operator.Op op, object val1, object val2)
static bool cmpNumberNumberO(Operator.Op op, double n1, double n2)
static bool cmpBoolBoolO(Operator.Op op, object val1, object val2)
static bool cmpBoolStringO(Operator.Op op, object val1, object val2)
override XPathNodeIterator Clone()
static bool cmpBoolBoolE(Operator.Op op, object val1, object val2)
static bool cmpQueryQueryE(Operator.Op op, object val1, object val2)
static bool cmpBoolStringE(Operator.Op op, object val1, object val2)
static bool cmpNumberNumber(Operator.Op op, double n1, double n2)
static string Rtf(object o)
static bool cmpQueryBoolE(Operator.Op op, object val1, object val2)
static bool cmpQueryStringE(Operator.Op op, object val1, object val2)
static bool cmpNumberNumber(Operator.Op op, object val1, object val2)
static bool cmpRtfRtfE(Operator.Op op, object val1, object val2)
static Op InvertOperator(Op op)
Definition Operator.cs:69
object Evaluate(XPathNodeIterator nodeIterator)
XPathResultType GetXPathType(object value)
Definition Query.cs:147
virtual void SetXsltContext(XsltContext context)
Definition Query.cs:52
XPathNavigator Advance()
static Query Clone(Query input)
Definition Query.cs:66