1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.Xml;
9
10 namespace System.XPath
11 {
12 public class StringValueComputerVisitor : System.Xml.Visitor
13 {
14 public StringValueComputerVisitor() : stringValue()
15 {
16 }
17 public override void Visit(System.Xml.Text& text)
18 {
19 stringValue.Append(text.Data());
20 }
21 public string GetStringValue()
22 {
23 return Rvalue(stringValue);
24 }
25 private string stringValue;
26 }
27
28 public string GetStringValue(System.Xml.ParentNode* node)
29 {
30 StringValueComputerVisitor visitor;
31 node->Accept(visitor);
32 return visitor.GetStringValue();
33 }
34
35 public inline string StringValue(System.Xml.AttributeNode* attributeNode)
36 {
37 return attributeNode->Value();
38 }
39
40 public inline string StringValue(System.Xml.Document* documentNode)
41 {
42 return GetStringValue(documentNode);
43 }
44
45 public inline string StringValue(System.Xml.Element* elementNode)
46 {
47 return GetStringValue(elementNode);
48 }
49
50 public inline string StringValue(System.Xml.ProcessingInstruction* piNode)
51 {
52 return piNode->Data();
53 }
54
55 public inline string StringValue(System.Xml.Text* textNode)
56 {
57 return textNode->Data();
58 }
59
60 public inline string StringValue(System.Xml.CDataSection* cdataSectionNode)
61 {
62 return cdataSectionNode->Data();
63 }
64
65 public inline string StringValue(System.Xml.Comment* commentNode)
66 {
67 return commentNode->Data();
68 }
69
70 public string StringValue(System.Xml.Node* node)
71 {
72 switch (node->Kind())
73 {
74 case System.Xml.NodeKind.attributeNode:
75 {
76 System.Xml.AttributeNode* attributeNode = cast<System.Xml.AttributeNode*>(node);
77 return StringValue(attributeNode);
78 }
79 case System.Xml.NodeKind.documentNode:
80 {
81 System.Xml.Document* documentNode = cast<System.Xml.Document*>(node);
82 return StringValue(documentNode);
83 }
84 case System.Xml.NodeKind.elementNode:
85 {
86 System.Xml.Element* elementNode = cast<System.Xml.Element*>(node);
87 return StringValue(elementNode);
88 }
89 case System.Xml.NodeKind.processingInstructionNode:
90 {
91 System.Xml.ProcessingInstruction* processingInstructionNode = cast<System.Xml.ProcessingInstruction*>(node);
92 return StringValue(processingInstructionNode);
93 }
94 case System.Xml.NodeKind.textNode:
95 {
96 System.Xml.Text* textNode = cast<System.Xml.Text*>(node);
97 return StringValue(textNode);
98 }
99 case System.Xml.NodeKind.cdataSectionNode:
100 {
101 System.Xml.CDataSection* cdataSectionNode = cast<System.Xml.CDataSection*>(node);
102 return StringValue(cdataSectionNode);
103 }
104 case System.Xml.NodeKind.commentNode:
105 {
106 System.Xml.Comment* commentNode = cast<System.Xml.Comment*>(node);
107 return StringValue(commentNode);
108 }
109 }
110 return string();
111 }
112
113 [nodiscard]
114 public Result<UniquePtr<Object>> ToNumber(Object* object, Context& context)
115 {
116 auto numberFunctionResult = GetFunction(FunctionKind.number);
117 if (numberFunctionResult.Error())
118 {
119 return Result<UniquePtr<Object>>(ErrorId(numberFunctionResult.GetErrorId()));
120 }
121 Function* numberFunction = numberFunctionResult.Value();
122 List<Object*> args(1, object);
123 return numberFunction->Evaluate(context, args);
124 }
125
126 [nodiscard]
127 public Result<UniquePtr<Object>> ToNumber(System.Xml.Node* node, Context& context)
128 {
129 UniquePtr<Object> stringValue(new Str(StringValue(node)));
130 return ToNumber(stringValue.Get(), context);
131 }
132
133 [nodiscard]
134 public Result<Number*> NumberCast(Object* object)
135 {
136 if (object->IsNumber())
137 {
138 return Result<Number*>(cast<Number*>(object));
139 }
140 else
141 {
142 int errorId = AllocateError("number object expected");
143 return Result<Number*>(ErrorId(errorId));
144 }
145 }
146
147 [nodiscard]
148 public Result<UniquePtr<Object>> ToBoolean(Object* object, Context& context)
149 {
150 auto booleanFunctionResult = GetFunction(FunctionKind.boolean);
151 if (booleanFunctionResult.Error())
152 {
153 return Result<UniquePtr<Object>>(ErrorId(booleanFunctionResult.GetErrorId()));
154 }
155 Function* booleanFunction = booleanFunctionResult.Value();
156 List<Object*> args(1, object);
157 return booleanFunction->Evaluate(context, args);
158 }
159
160 [nodiscard]
161 public Result<Boolean*> BooleanCast(Object* object)
162 {
163 if (object->IsBoolean())
164 {
165 return Result<Boolean*>(cast<Boolean*>(object));
166 }
167 else
168 {
169 int errorId = AllocateError("Boolean object expected");
170 return Result<Boolean*>(ErrorId(errorId));
171 }
172 }
173
174 [nodiscard]
175 public Result<NodeSet*> NodeSetCast(Object* object)
176 {
177 if (object->IsNodeSet())
178 {
179 return Result<NodeSet*>(cast<NodeSet*>(object));
180 }
181 else
182 {
183 int errorId = AllocateError("node-set object expected");
184 return Result<NodeSet*>(ErrorId(errorId));
185 }
186 }
187
188 [nodiscard]
189 public Result<UniquePtr<Object>> EvaluateUnaryMinusExpr(Expr* operand, Context& context)
190 {
191 auto operandResult = operand->Evaluate(context);
192 if (operandResult.Error())
193 {
194 return operandResult;
195 }
196 Result<UniquePtr<Object>> numberResult = ToNumber(operandResult.Value().Get(), context);
197 if (numberResult.Error())
198 {
199 return numberResult;
200 }
201 auto numberCastResult = NumberCast(numberResult.Value().Get());
202 if (numberCastResult.Error())
203 {
204 return Result<UniquePtr<Object>>(ErrorId(numberCastResult.GetErrorId()));
205 }
206 Number* number = numberCastResult.Value();
207 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(-number->Value())));
208 }
209
210 [nodiscard]
211 public Result<UniquePtr<Object>> EvaluateParenExpr(Expr* operand, Context& context)
212 {
213 return operand->Evaluate(context);
214 }
215
216 [nodiscard]
217 public Result<UniquePtr<Object>> EvaluateOrExpr(Expr* left, Expr* right, Context& context)
218 {
219 auto booleanFunctionResult = GetFunction(FunctionKind.boolean);
220 if (booleanFunctionResult.Error())
221 {
222 return Result<UniquePtr<Object>>(ErrorId(booleanFunctionResult.GetErrorId()));
223 }
224 Function* booleanFunction = booleanFunctionResult.Value();
225 Result<UniquePtr<Object>> leftResult = left->Evaluate(context);
226 if (leftResult.Error())
227 {
228 return Result<UniquePtr<Object>>(ErrorId(leftResult.GetErrorId()));
229 }
230 List<Object*> leftArgs(1, leftResult.Value().Get());
231 Result<UniquePtr<Object>> leftBooleanResult = booleanFunction->Evaluate(context, leftArgs);
232 if (leftBooleanResult.Error())
233 {
234 return Result<UniquePtr<Object>>(ErrorId(leftBooleanResult.GetErrorId()));
235 }
236 auto booleanCastResult = BooleanCast(leftBooleanResult.Value().Get());
237 if (booleanCastResult.Error())
238 {
239 return Result<UniquePtr<Object>>(ErrorId(booleanCastResult.GetErrorId()));
240 }
241 Boolean* leftAsBoolean = booleanCastResult.Value();
242 if (leftAsBoolean->Value())
243 {
244 return leftBooleanResult;
245 }
246 Result<UniquePtr<Object>> rightResult = right->Evaluate(context);
247 if (rightResult.Error())
248 {
249 return Result<UniquePtr<Object>>(ErrorId(rightResult.GetErrorId()));
250 }
251 List<Object*> rightArgs(1, rightResult.Value().Get());
252 return booleanFunction->Evaluate(context, rightArgs);
253 }
254
255 [nodiscard]
256 public Result<UniquePtr<Object>> EvaluateAndExpr(Expr* left, Expr* right, Context& context)
257 {
258 auto booleanFunctionResult = GetFunction(FunctionKind.boolean);
259 if (booleanFunctionResult.Error())
260 {
261 return Result<UniquePtr<Object>>(ErrorId(booleanFunctionResult.GetErrorId()));
262 }
263 Function* booleanFunction = booleanFunctionResult.Value();
264 Result<UniquePtr<Object>> leftResult = left->Evaluate(context);
265 if (leftResult.Error())
266 {
267 return Result<UniquePtr<Object>>(ErrorId(leftResult.GetErrorId()));
268 }
269 List<Object*> leftArgs(1, leftResult.Value().Get());
270 Result<UniquePtr<Object>> leftBooleanResult = booleanFunction->Evaluate(context, leftArgs);
271 if (leftBooleanResult.Error())
272 {
273 return Result<UniquePtr<Object>>(ErrorId(leftBooleanResult.GetErrorId()));
274 }
275 auto booleanCastResult = BooleanCast(leftBooleanResult.Value().Get());
276 if (booleanCastResult.Error())
277 {
278 return Result<UniquePtr<Object>>(ErrorId(booleanCastResult.GetErrorId()));
279 }
280 Boolean* leftAsBoolean = booleanCastResult.Value();
281 if (!leftAsBoolean->Value())
282 {
283 return leftBooleanResult;
284 }
285 Result<UniquePtr<Object>> rightResult = right->Evaluate(context);
286 if (rightResult.Error())
287 {
288 return Result<UniquePtr<Object>>(ErrorId(rightResult.GetErrorId()));
289 }
290 List<Object*> rightArgs(1, rightResult.Value().Get());
291 return booleanFunction->Evaluate(context, rightArgs);
292 }
293
294 bool CompareStrings(const string& leftStr, const string& rightStr, Operator op)
295 {
296 switch (op)
297 {
298 case Operator.equal:
299 {
300 return leftStr == rightStr;
301 }
302 case Operator.notEqual:
303 {
304 return leftStr != rightStr;
305 }
306 case Operator.less:
307 {
308 return leftStr < rightStr;
309 }
310 case Operator.greater:
311 {
312 return leftStr > rightStr;
313 }
314 case Operator.lessOrEqual:
315 {
316 return leftStr <= rightStr;
317 }
318 case Operator.greaterOrEqual:
319 {
320 return leftStr >= rightStr;
321 }
322 }
323 return false;
324 }
325
326 public bool CompareNumbers(double left, double right, Operator op)
327 {
328 switch (op)
329 {
330 case Operator.equal:
331 {
332 return left == right;
333 }
334 case Operator.notEqual:
335 {
336 return left != right;
337 }
338 case Operator.less:
339 {
340 return left < right;
341 }
342 case Operator.greater:
343 {
344 return left > right;
345 }
346 case Operator.lessOrEqual:
347 {
348 return left <= right;
349 }
350 case Operator.greaterOrEqual:
351 {
352 return left >= right;
353 }
354 }
355 return false;
356 }
357
358 public bool CompareBooleans(bool left, bool right, Operator op)
359 {
360 switch (op)
361 {
362 case Operator.equal:
363 {
364 return left == right;
365 }
366 case Operator.notEqual:
367 {
368 return left != right;
369 }
370 case Operator.less:
371 {
372 return cast<int>(left) < cast<int>(right);
373 }
374 case Operator.greater:
375 {
376 return cast<int>(left) > cast<int>(right);
377 }
378 case Operator.lessOrEqual:
379 {
380 return cast<int>(left) <= cast<int>(right);
381 }
382 case Operator.greaterOrEqual:
383 {
384 return cast<int>(left) >= cast<int>(right);
385 }
386 }
387 return false;
388 }
389
390 [nodiscard]
391 public Result<UniquePtr<Object>> Compare(NodeSet* left, NodeSet* right, Operator op)
392 {
393 int n = left->Count();
394 for (int i = 0; i < n; ++i;)
395 {
396 System.Xml.Node* leftNode = left->GetNode(i);
397 string leftStringValue = StringValue(leftNode);
398 int m = right->Count();
399 for (int j = 0; j < m; ++j;)
400 {
401 System.Xml.Node* rightNode = right->GetNode(j);
402 string rightStringValue = StringValue(rightNode);
403 if (CompareStrings(leftStringValue, rightStringValue, op))
404 {
405 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(true)));
406 }
407 }
408 }
409 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(false)));
410 }
411
412 [nodiscard]
413 public Result<UniquePtr<Object>> Compare(NodeSet* left, Boolean* right, Operator op, Context& context)
414 {
415 auto leftAsBoolean = ToBoolean(left, context);
416 if (leftAsBoolean.Error())
417 {
418 return Result<UniquePtr<Object>>(ErrorId(leftAsBoolean.GetErrorId()));
419 }
420 auto booleanCastResult = BooleanCast(leftAsBoolean.Value().Get());
421 if (booleanCastResult.Error())
422 {
423 return Result<UniquePtr<Object>>(ErrorId(booleanCastResult.GetErrorId()));
424 }
425 Boolean* leftBoolean = booleanCastResult.Value();
426 return Compare(leftBoolean, right, op);
427 }
428
429 [nodiscard]
430 public Result<UniquePtr<Object>> Compare(Boolean* left, NodeSet* right, Operator op, Context& context)
431 {
432 auto rightAsBoolean = ToBoolean(right, context);
433 if (rightAsBoolean.Error())
434 {
435 return Result<UniquePtr<Object>>(ErrorId(rightAsBoolean.GetErrorId()));
436 }
437 auto booleanCastResult = BooleanCast(rightAsBoolean.Value().Get());
438 if (booleanCastResult.Error())
439 {
440 return Result<UniquePtr<Object>>(ErrorId(booleanCastResult.GetErrorId()));
441 }
442 Boolean* rightBoolean = booleanCastResult.Value();
443 return Compare(left, rightBoolean, op);
444 }
445
446 [nodiscard]
447 public Result<UniquePtr<Object>> Compare(NodeSet* left, Number* right, Operator op, Context& context)
448 {
449 int n = left->Count();
450 for (int i = 0; i < n; ++i;)
451 {
452 System.Xml.Node* leftNode = left->GetNode(i);
453 auto leftAsNumberResult = ToNumber(leftNode, context);
454 if (leftAsNumberResult.Error())
455 {
456 return leftAsNumberResult;
457 }
458 auto numberCastResult = NumberCast(leftAsNumberResult.Value().Get());
459 if (numberCastResult.Error())
460 {
461 return Result<UniquePtr<Object>>(ErrorId(numberCastResult.GetErrorId()));
462 }
463 Number* leftNumber = numberCastResult.Value();
464 if (CompareNumbers(leftNumber->Value(), right->Value(), op))
465 {
466 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(true)));
467 }
468 }
469 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(false)));
470 }
471
472 [nodiscard]
473 public Result<UniquePtr<Object>> Compare(NodeSet* left, Str* right, Operator op, Context& context)
474 {
475 int n = left->Count();
476 for (int i = 0; i < n; ++i;)
477 {
478 System.Xml.Node* leftNode = left->GetNode(i);
479 string leftString = StringValue(leftNode);
480 if (CompareStrings(leftString, right->Value(), op))
481 {
482 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(true)));
483 }
484 }
485 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(false)));
486 }
487
488 [nodiscard]
489 public Result<UniquePtr<Object>> Compare(Str* left, NodeSet* right, Operator op, Context& context)
490 {
491 int n = right->Count();
492 for (int i = 0; i < n; ++i;)
493 {
494 System.Xml.Node* rightNode = right->GetNode(i);
495 string rightString = StringValue(rightNode);
496 if (CompareStrings(left->Value(), rightString, op))
497 {
498 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(true)));
499 }
500 }
501 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(false)));
502 }
503
504 [nodiscard]
505 public Result<UniquePtr<Object>> Compare(Number* left, NodeSet* right, Operator op, Context& context)
506 {
507 int n = right->Count();
508 for (int i = 0; i < n; ++i;)
509 {
510 System.Xml.Node* rightNode = right->GetNode(i);
511 auto rightAsNumberResult = ToNumber(rightNode, context);
512 if (rightAsNumberResult.Error())
513 {
514 return rightAsNumberResult;
515 }
516 auto numberCastResult = NumberCast(rightAsNumberResult.Value().Get());
517 if (numberCastResult.Error())
518 {
519 return Result<UniquePtr<Object>>(ErrorId(numberCastResult.GetErrorId()));
520 }
521 Number* rightNumber = numberCastResult.Value();
522 if (CompareNumbers(left->Value(), rightNumber->Value(), op))
523 {
524 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(true)));
525 }
526 }
527 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(false)));
528 }
529
530 [nodiscard]
531 public Result<UniquePtr<Object>> Compare(Boolean* left, Boolean* right, Operator op)
532 {
533 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareBooleans(left->Value(), right->Value(), op))));
534 }
535
536 [nodiscard]
537 public Result<UniquePtr<Object>> Compare(Boolean* left, Number* right, Operator op, Context& context)
538 {
539 auto rightAsBoolean = ToBoolean(right, context);
540 if (rightAsBoolean.Error())
541 {
542 return Result<UniquePtr<Object>>(ErrorId(rightAsBoolean.GetErrorId()));
543 }
544 auto booleanCastResult = BooleanCast(rightAsBoolean.Value().Get());
545 if (booleanCastResult.Error())
546 {
547 return Result<UniquePtr<Object>>(ErrorId(booleanCastResult.GetErrorId()));
548 }
549 Boolean* rightBoolean = booleanCastResult.Value();
550 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareBooleans(left->Value(), rightBoolean->Value(), op))));
551 }
552
553 [nodiscard]
554 public Result<UniquePtr<Object>> Compare(Number* left, Boolean* right, Operator op, Context& context)
555 {
556 auto leftAsBoolean = ToBoolean(left, context);
557 if (leftAsBoolean.Error())
558 {
559 return Result<UniquePtr<Object>>(ErrorId(leftAsBoolean.GetErrorId()));
560 }
561 auto booleanCastResult = BooleanCast(leftAsBoolean.Value().Get());
562 if (booleanCastResult.Error())
563 {
564 return Result<UniquePtr<Object>>(ErrorId(booleanCastResult.GetErrorId()));
565 }
566 Boolean* leftBoolean = booleanCastResult.Value();
567 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareBooleans(leftBoolean->Value(), right->Value(), op))));
568 }
569
570 [nodiscard]
571 public Result<UniquePtr<Object>> Compare(Boolean* left, Str* right, Operator op, Context& context)
572 {
573 auto rightAsBoolean = ToBoolean(right, context);
574 if (rightAsBoolean.Error())
575 {
576 return Result<UniquePtr<Object>>(ErrorId(rightAsBoolean.GetErrorId()));
577 }
578 auto booleanCastResult = BooleanCast(rightAsBoolean.Value().Get());
579 if (booleanCastResult.Error())
580 {
581 return Result<UniquePtr<Object>>(ErrorId(booleanCastResult.GetErrorId()));
582 }
583 Boolean* rightBoolean = booleanCastResult.Value();
584 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareBooleans(left->Value(), rightBoolean->Value(), op))));
585 }
586
587 [nodiscard]
588 public Result<UniquePtr<Object>> Compare(Str* left, Boolean* right, Operator op, Context& context)
589 {
590 auto leftAsBoolean = ToBoolean(left, context);
591 if (leftAsBoolean.Error())
592 {
593 return Result<UniquePtr<Object>>(ErrorId(leftAsBoolean.GetErrorId()));
594 }
595 auto booleanCastResult = BooleanCast(leftAsBoolean.Value().Get());
596 if (booleanCastResult.Error())
597 {
598 return Result<UniquePtr<Object>>(ErrorId(booleanCastResult.GetErrorId()));
599 }
600 Boolean* leftBoolean = booleanCastResult.Value();
601 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareBooleans(leftBoolean->Value(), right->Value(), op))));
602 }
603
604 [nodiscard]
605 public Result<UniquePtr<Object>> Compare(Number* left, Number* right, Operator op)
606 {
607 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareNumbers(left->Value(), right->Value(), op))));
608 }
609
610 [nodiscard]
611 public Result<UniquePtr<Object>> Compare(Number* left, Str* right, Operator op, Context& context)
612 {
613 auto rightAsNumber = ToNumber(right, context);
614 if (rightAsNumber.Error())
615 {
616 return Result<UniquePtr<Object>>(ErrorId(rightAsNumber.GetErrorId()));
617 }
618 auto numberCastResult = NumberCast(rightAsNumber.Value().Get());
619 if (numberCastResult.Error())
620 {
621 return Result<UniquePtr<Object>>(ErrorId(numberCastResult.GetErrorId()));
622 }
623 Number* rightNumber = numberCastResult.Value();
624 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareNumbers(left->Value(), rightNumber->Value(), op))));
625 }
626
627 [nodiscard]
628 public Result<UniquePtr<Object>> Compare(Str* left, Number* right, Operator op, Context& context)
629 {
630 auto leftAsNumber = ToNumber(left, context);
631 if (leftAsNumber.Error())
632 {
633 return Result<UniquePtr<Object>>(ErrorId(leftAsNumber.GetErrorId()));
634 }
635 auto numberCastResult = NumberCast(leftAsNumber.Value().Get());
636 if (numberCastResult.Error())
637 {
638 return Result<UniquePtr<Object>>(ErrorId(numberCastResult.GetErrorId()));
639 }
640 Number* leftNumber = numberCastResult.Value();
641 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareNumbers(leftNumber->Value(), right->Value(), op))));
642 }
643
644 [nodiscard]
645 public Result<UniquePtr<Object>> Compare(Str* left, Str* right, Operator op)
646 {
647 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(CompareStrings(left->Value(), right->Value(), op))));
648 }
649
650 [nodiscard]
651 public Result<UniquePtr<Object>> Compare(Expr* left, Expr* right, Operator op, Context& context)
652 {
653 Result<UniquePtr<Object>> leftOperand = left->Evaluate(context);
654 if (leftOperand.Error())
655 {
656 return leftOperand;
657 }
658 Result<UniquePtr<Object>> rightOperand = right->Evaluate(context);
659 if (rightOperand.Error())
660 {
661 return rightOperand;
662 }
663 Object* leftObject = leftOperand.Value().Get();
664 Object* rightObject = rightOperand.Value().Get();
665 switch (leftObject->Kind())
666 {
667 case ObjectKind.nodeSet:
668 {
669 NodeSet* leftNodeSet = cast<NodeSet*>(leftObject);
670 switch (rightObject->Kind())
671 {
672 case ObjectKind.nodeSet:
673 {
674 NodeSet* rightNodeSet = cast<NodeSet*>(rightObject);
675 return Compare(leftNodeSet, rightNodeSet, op);
676 }
677 case ObjectKind.boolean:
678 {
679 Boolean* rightBoolean = cast<Boolean*>(rightObject);
680 return Compare(leftNodeSet, rightBoolean, op, context);
681 }
682 case ObjectKind.number:
683 {
684 Number* rightNumber = cast<Number*>(rightObject);
685 return Compare(leftNodeSet, rightNumber, op, context);
686 }
687 case ObjectKind.string:
688 {
689 Str* rightString = cast<Str*>(rightObject);
690 return Compare(leftNodeSet, rightString, op, context);
691 }
692 }
693 break;
694 }
695 case ObjectKind.boolean:
696 {
697 Boolean* leftBoolean = cast<Boolean*>(leftObject);
698 switch (rightObject->Kind())
699 {
700 case ObjectKind.boolean:
701 {
702 Boolean* rightBoolean = cast<Boolean*>(rightObject);
703 return Compare(leftBoolean, rightBoolean, op);
704 }
705 case ObjectKind.nodeSet:
706 {
707 NodeSet* rightNodeSet = cast<NodeSet*>(rightObject);
708 return Compare(leftBoolean, rightNodeSet, op, context);
709 }
710 case ObjectKind.number:
711 {
712 Number* rightNumber = cast<Number*>(rightObject);
713 return Compare(leftBoolean, rightNumber, op, context);
714 }
715 case ObjectKind.string:
716 {
717 Str* rightString = cast<Str*>(rightObject);
718 return Compare(leftBoolean, rightString, op, context);
719 }
720 }
721 break;
722 }
723 case ObjectKind.number:
724 {
725 Number* leftNumber = cast<Number*>(leftObject);
726 switch (rightObject->Kind())
727 {
728 case ObjectKind.number:
729 {
730 Number* rightNumber = cast<Number*>(rightObject);
731 return Compare(leftNumber, rightNumber, op);
732 }
733 case ObjectKind.nodeSet:
734 {
735 NodeSet* rightNodeSet = cast<NodeSet*>(rightObject);
736 return Compare(leftNumber, rightNodeSet, op, context);
737 }
738 case ObjectKind.boolean:
739 {
740 Boolean* rightBoolean = cast<Boolean*>(rightObject);
741 return Compare(leftNumber, rightBoolean, op, context);
742 }
743 case ObjectKind.string:
744 {
745 Str* rightString = cast<Str*>(rightObject);
746 return Compare(leftNumber, rightString, op, context);
747 }
748 }
749 break;
750 }
751 case ObjectKind.string:
752 {
753 Str* leftString = cast<Str*>(leftObject);
754 switch (rightObject->Kind())
755 {
756 case ObjectKind.string:
757 {
758 Str* rightString = cast<Str*>(rightObject);
759 return Compare(leftString, rightString, op);
760 }
761 case ObjectKind.nodeSet:
762 {
763 NodeSet* rightNodeSet = cast<NodeSet*>(rightObject);
764 return Compare(leftString, rightNodeSet, op, context);
765 }
766 case ObjectKind.boolean:
767 {
768 Boolean* rightBoolean = cast<Boolean*>(rightObject);
769 return Compare(leftString, rightBoolean, op, context);
770 }
771 case ObjectKind.number:
772 {
773 Number* rightNumber = cast<Number*>(rightObject);
774 return Compare(leftString, rightNumber, op, context);
775 }
776 }
777 break;
778 }
779 }
780 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Boolean(false)));
781 }
782
783 [nodiscard]
784 public Result<UniquePtr<Object>> EvaluateArithmeticOp(Expr* left, Expr* right, Operator op, Context& context)
785 {
786 Result<UniquePtr<Object>> leftOperand = left->Evaluate(context);
787 if (leftOperand.Error())
788 {
789 return leftOperand;
790 }
791 Result<UniquePtr<Object>> rightOperand = right->Evaluate(context);
792 if (rightOperand.Error())
793 {
794 return rightOperand;
795 }
796 Object* leftObject = leftOperand.Value().Get();
797 Object* rightObject = rightOperand.Value().Get();
798 Result<UniquePtr<Object>> leftAsNumber = ToNumber(leftObject, context);
799 if (leftAsNumber.Error())
800 {
801 return leftAsNumber;
802 }
803 Result<Number*> leftNumberCastResult = NumberCast(leftAsNumber.Value().Get());
804 if (leftNumberCastResult.Error())
805 {
806 return Result<UniquePtr<Object>>(ErrorId(leftNumberCastResult.GetErrorId()));
807 }
808 Number* leftNumber = leftNumberCastResult.Value();
809 Result<UniquePtr<Object>> rightAsNumber = ToNumber(rightObject, context);
810 if (rightAsNumber.Error())
811 {
812 return rightAsNumber;
813 }
814 Result<Number*> rightNumberCastResult = NumberCast(rightAsNumber.Value().Get());
815 if (rightNumberCastResult.Error())
816 {
817 return Result<UniquePtr<Object>>(ErrorId(rightNumberCastResult.GetErrorId()));
818 }
819 Number* rightNumber = rightNumberCastResult.Value();
820 switch (op)
821 {
822 case Operator.plus:
823 {
824 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(leftNumber->Value() + rightNumber->Value())));
825 }
826 case Operator.minus:
827 {
828 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(leftNumber->Value() - rightNumber->Value())));
829 }
830 case Operator.mul:
831 {
832 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(leftNumber->Value() * rightNumber->Value())));
833 }
834 case Operator.div:
835 {
836 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(leftNumber->Value() / rightNumber->Value())));
837 }
838 case Operator.mod:
839 {
840 return Result<UniquePtr<Object>>(UniquePtr<Object>(new Number(RtmRemainder(leftNumber->Value(), rightNumber->Value()))));
841 }
842 }
843 int errorId = AllocateError("arithmetic binary operator expected");
844 return Result<UniquePtr<Object>>(ErrorId(errorId));
845 }
846
847 [nodiscard]
848 public Result<UniquePtr<Object>> EvaluateUnionExpr(Expr* left, Expr* right, Context& context)
849 {
850 Result<UniquePtr<Object>> leftOperand = left->Evaluate(context);
851 if (leftOperand.Error())
852 {
853 return leftOperand;
854 }
855 Result<UniquePtr<Object>> rightOperand = right->Evaluate(context);
856 if (rightOperand.Error())
857 {
858 return rightOperand;
859 }
860 Object* leftObject = leftOperand.Value().Get();
861 Object* rightObject = rightOperand.Value().Get();
862 Result<NodeSet*> leftNodeSetCastResult = NodeSetCast(leftObject);
863 if (leftNodeSetCastResult.Error())
864 {
865 return Result<UniquePtr<Object>>(ErrorId(leftNodeSetCastResult.GetErrorId()));
866 }
867 NodeSet* leftNodeSet = leftNodeSetCastResult.Value();
868 Result<NodeSet*> rightNodeSetCastResult = NodeSetCast(rightObject);
869 if (rightNodeSetCastResult.Error())
870 {
871 return Result<UniquePtr<Object>>(ErrorId(rightNodeSetCastResult.GetErrorId()));
872 }
873 NodeSet* rightNodeSet = rightNodeSetCastResult.Value();
874 UniquePtr<NodeSet> nodeSet(new NodeSet());
875 int n = leftNodeSet->Count();
876 for (int i = 0; i < n; ++i;)
877 {
878 nodeSet->Add(leftNodeSet->GetNode(i));
879 }
880 int m = rightNodeSet->Count();
881 for (int i = 0; i < m; ++i;)
882 {
883 nodeSet->Add(rightNodeSet->GetNode(i));
884 }
885 Result<UniquePtr<Object>> result(UniquePtr<Object>(nodeSet.Release()));
886 return result;
887 }
888
889 [nodiscard]
890 public Result<UniquePtr<Object>> EvaluateCombineStepExpr(Expr* left, Expr* right, Context& context)
891 {
892 Result<UniquePtr<Object>> leftOperand = left->Evaluate(context);
893 if (leftOperand.Error())
894 {
895 return leftOperand;
896 }
897 Result<NodeSet*> leftNodeSetCastResult = NodeSetCast(leftOperand.Value().Get());
898 if (leftNodeSetCastResult.Error())
899 {
900 return Result<UniquePtr<Object>>(ErrorId(leftNodeSetCastResult.GetErrorId()));
901 }
902 NodeSet* leftNodeSet = leftNodeSetCastResult.Value();
903 UniquePtr<NodeSet> result(new NodeSet());
904 int n = leftNodeSet->Count();
905 for (int i = 0; i < n; ++i;)
906 {
907 System.Xml.Node* leftNode = leftNodeSet->GetNode(i);
908 Context rightContext(leftNode, i + 1, n);
909 Result<UniquePtr<Object>> rightOperand = right->Evaluate(rightContext);
910 Result<NodeSet*> rightNodeSetCastResult = NodeSetCast(rightOperand.Value().Get());
911 if (rightNodeSetCastResult.Error())
912 {
913 return Result<UniquePtr<Object>>(ErrorId(rightNodeSetCastResult.GetErrorId()));
914 }
915 NodeSet* rightNodeSet = rightNodeSetCastResult.Value();
916 int m = rightNodeSet->Count();
917 for (int j = 0; j < m; ++j;)
918 {
919 System.Xml.Node* rightNode = rightNodeSet->GetNode(j);
920 result->Add(rightNode);
921 }
922 }
923 return Result<UniquePtr<Object>>(UniquePtr<Object>(result.Release()));
924 }
925