1 /*
2 * Copyright 2006-2014 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Stephan Aßmus <superstippi@gmx.de>
7 * Rene Gollent <rene@gollent.com>
8 * John Scipione <jscipione@gmail.com>
9 * Ingo Weinhold <bonefish@cs.tu-berlin.de>
10 */
11
12 #include "CLanguageExpressionEvaluator.h"
13
14 #include <algorithm>
15
16 #include "AutoLocker.h"
17
18 #include "CLanguageTokenizer.h"
19 #include "ExpressionInfo.h"
20 #include "FloatValue.h"
21 #include "IntegerFormatter.h"
22 #include "IntegerValue.h"
23 #include "ObjectID.h"
24 #include "StackFrame.h"
25 #include "SyntheticPrimitiveType.h"
26 #include "TeamTypeInformation.h"
27 #include "Thread.h"
28 #include "Type.h"
29 #include "TypeHandlerRoster.h"
30 #include "TypeLookupConstraints.h"
31 #include "Value.h"
32 #include "ValueLocation.h"
33 #include "ValueNode.h"
34 #include "ValueNodeManager.h"
35 #include "Variable.h"
36 #include "VariableValueNodeChild.h"
37
38
39 using namespace CLanguage;
40
41
42 enum operand_kind {
43 OPERAND_KIND_UNKNOWN = 0,
44 OPERAND_KIND_PRIMITIVE,
45 OPERAND_KIND_TYPE,
46 OPERAND_KIND_VALUE_NODE
47 };
48
49
TokenTypeToString(int32 type)50 static BString TokenTypeToString(int32 type)
51 {
52 BString token;
53
54 switch (type) {
55 case TOKEN_PLUS:
56 token = "+";
57 break;
58
59 case TOKEN_MINUS:
60 token = "-";
61 break;
62
63 case TOKEN_STAR:
64 token = "*";
65 break;
66
67 case TOKEN_SLASH:
68 token = "/";
69 break;
70
71 case TOKEN_MODULO:
72 token = "%";
73 break;
74
75 case TOKEN_OPENING_PAREN:
76 token = "(";
77 break;
78
79 case TOKEN_CLOSING_PAREN:
80 token = ")";
81 break;
82
83 case TOKEN_LOGICAL_AND:
84 token = "&&";
85 break;
86
87 case TOKEN_LOGICAL_OR:
88 token = "||";
89 break;
90
91 case TOKEN_LOGICAL_NOT:
92 token = "!";
93 break;
94
95 case TOKEN_BITWISE_AND:
96 token = "&";
97 break;
98
99 case TOKEN_BITWISE_OR:
100 token = "|";
101 break;
102
103 case TOKEN_BITWISE_NOT:
104 token = "~";
105 break;
106
107 case TOKEN_BITWISE_XOR:
108 token = "^";
109 break;
110
111 case TOKEN_EQ:
112 token = "==";
113 break;
114
115 case TOKEN_NE:
116 token = "!=";
117 break;
118
119 case TOKEN_GT:
120 token = ">";
121 break;
122
123 case TOKEN_GE:
124 token = ">=";
125 break;
126
127 case TOKEN_LT:
128 token = "<";
129 break;
130
131 case TOKEN_LE:
132 token = "<=";
133 break;
134
135 case TOKEN_MEMBER_PTR:
136 token = "->";
137 break;
138
139 default:
140 token.SetToFormat("Unknown token type %" B_PRId32, type);
141 break;
142 }
143
144 return token;
145 }
146
147
148 // #pragma mark - CLanguageExpressionEvaluator::InternalVariableID
149
150
151 class CLanguageExpressionEvaluator::InternalVariableID : public ObjectID {
152 public:
InternalVariableID(const BVariant & value)153 InternalVariableID(const BVariant& value)
154 :
155 fValue(value)
156 {
157 }
158
~InternalVariableID()159 virtual ~InternalVariableID()
160 {
161 }
162
operator ==(const ObjectID & other) const163 virtual bool operator==(const ObjectID& other) const
164 {
165 const InternalVariableID* otherID
166 = dynamic_cast<const InternalVariableID*>(&other);
167 if (otherID == NULL)
168 return false;
169
170 return fValue == otherID->fValue;
171 }
172
173 protected:
ComputeHashValue() const174 virtual uint32 ComputeHashValue() const
175 {
176 return *(uint32*)(&fValue);
177 }
178
179 private:
180 BVariant fValue;
181 };
182
183
184 // #pragma mark - CLanguageExpressionEvaluator::Operand
185
186
187 class CLanguageExpressionEvaluator::Operand {
188 public:
Operand()189 Operand()
190 :
191 fPrimitive(),
192 fValueNode(NULL),
193 fType(NULL),
194 fKind(OPERAND_KIND_UNKNOWN)
195 {
196 }
197
Operand(int64 value)198 Operand(int64 value)
199 :
200 fPrimitive(value),
201 fValueNode(NULL),
202 fType(NULL),
203 fKind(OPERAND_KIND_PRIMITIVE)
204 {
205 }
206
Operand(double value)207 Operand(double value)
208 :
209 fPrimitive(value),
210 fValueNode(NULL),
211 fType(NULL),
212 fKind(OPERAND_KIND_PRIMITIVE)
213 {
214 }
215
Operand(ValueNode * node)216 Operand(ValueNode* node)
217 :
218 fPrimitive(),
219 fValueNode(NULL),
220 fType(NULL),
221 fKind(OPERAND_KIND_UNKNOWN)
222 {
223 SetTo(node);
224 }
225
Operand(Type * type)226 Operand(Type* type)
227 :
228 fPrimitive(),
229 fValueNode(NULL),
230 fType(NULL),
231 fKind(OPERAND_KIND_UNKNOWN)
232 {
233 SetTo(type);
234 }
235
Operand(const Operand & X)236 Operand(const Operand& X)
237 :
238 fPrimitive(),
239 fValueNode(NULL),
240 fType(NULL),
241 fKind(OPERAND_KIND_UNKNOWN)
242 {
243 *this = X;
244 }
245
246
~Operand()247 virtual ~Operand()
248 {
249 Unset();
250 }
251
operator =(const Operand & X)252 Operand& operator=(const Operand& X)
253 {
254 switch (X.fKind) {
255 case OPERAND_KIND_UNKNOWN:
256 Unset();
257 break;
258
259 case OPERAND_KIND_PRIMITIVE:
260 SetTo(X.fPrimitive);
261 break;
262
263 case OPERAND_KIND_VALUE_NODE:
264 SetTo(X.fValueNode);
265 break;
266
267 case OPERAND_KIND_TYPE:
268 SetTo(X.fType);
269 break;
270 }
271
272 return *this;
273 }
274
SetTo(const BVariant & value)275 void SetTo(const BVariant& value)
276 {
277 Unset();
278 fPrimitive = value;
279 fKind = OPERAND_KIND_PRIMITIVE;
280 }
281
SetTo(ValueNode * node)282 void SetTo(ValueNode* node)
283 {
284 Unset();
285 fValueNode = node;
286 fValueNode->AcquireReference();
287
288 Value* value = node->GetValue();
289 if (value != NULL)
290 value->ToVariant(fPrimitive);
291
292 fKind = OPERAND_KIND_VALUE_NODE;
293 }
294
SetTo(Type * type)295 void SetTo(Type* type)
296 {
297 Unset();
298 fType = type;
299 fType->AcquireReference();
300
301 fKind = OPERAND_KIND_TYPE;
302 }
303
Unset()304 void Unset()
305 {
306 if (fValueNode != NULL)
307 fValueNode->ReleaseReference();
308
309 if (fType != NULL)
310 fType->ReleaseReference();
311
312 fValueNode = NULL;
313 fType = NULL;
314 fKind = OPERAND_KIND_UNKNOWN;
315 }
316
Kind() const317 inline operand_kind Kind() const
318 {
319 return fKind;
320 }
321
PrimitiveValue() const322 inline const BVariant& PrimitiveValue() const
323 {
324 return fPrimitive;
325 }
326
GetValueNode() const327 inline ValueNode* GetValueNode() const
328 {
329 return fValueNode;
330
331 }
332
GetType() const333 inline Type* GetType() const
334 {
335 return fType;
336 }
337
operator +=(const Operand & rhs)338 Operand& operator+=(const Operand& rhs)
339 {
340 Operand temp = rhs;
341 _ResolveTypesIfNeeded(temp);
342
343 switch (fPrimitive.Type()) {
344 case B_INT8_TYPE:
345 {
346 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
347 + temp.fPrimitive.ToInt8()));
348 break;
349 }
350
351 case B_UINT8_TYPE:
352 {
353 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
354 + temp.fPrimitive.ToUInt8()));
355 break;
356 }
357
358 case B_INT16_TYPE:
359 {
360 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
361 + temp.fPrimitive.ToInt16()));
362 break;
363 }
364
365 case B_UINT16_TYPE:
366 {
367 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
368 + temp.fPrimitive.ToUInt16()));
369 break;
370 }
371
372 case B_INT32_TYPE:
373 {
374 fPrimitive.SetTo(fPrimitive.ToInt32()
375 + temp.fPrimitive.ToInt32());
376 break;
377 }
378
379 case B_UINT32_TYPE:
380 {
381 fPrimitive.SetTo(fPrimitive.ToUInt32()
382 + temp.fPrimitive.ToUInt32());
383 break;
384 }
385
386 case B_INT64_TYPE:
387 {
388 fPrimitive.SetTo(fPrimitive.ToInt64()
389 + temp.fPrimitive.ToInt64());
390 break;
391 }
392
393 case B_UINT64_TYPE:
394 {
395 fPrimitive.SetTo(fPrimitive.ToUInt64()
396 + temp.fPrimitive.ToUInt64());
397 break;
398 }
399
400 case B_FLOAT_TYPE:
401 {
402 fPrimitive.SetTo(fPrimitive.ToFloat()
403 + temp.fPrimitive.ToFloat());
404 break;
405 }
406
407 case B_DOUBLE_TYPE:
408 {
409 fPrimitive.SetTo(fPrimitive.ToDouble()
410 + temp.fPrimitive.ToDouble());
411 break;
412 }
413 }
414
415 return *this;
416 }
417
operator -=(const Operand & rhs)418 Operand& operator-=(const Operand& rhs)
419 {
420 Operand temp = rhs;
421 _ResolveTypesIfNeeded(temp);
422
423 switch (fPrimitive.Type()) {
424 case B_INT8_TYPE:
425 {
426 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
427 - temp.fPrimitive.ToInt8()));
428 break;
429 }
430
431 case B_UINT8_TYPE:
432 {
433 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
434 - temp.fPrimitive.ToUInt8()));
435 break;
436 }
437
438 case B_INT16_TYPE:
439 {
440 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
441 - temp.fPrimitive.ToInt16()));
442 break;
443 }
444
445 case B_UINT16_TYPE:
446 {
447 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
448 - temp.fPrimitive.ToUInt16()));
449 break;
450 }
451
452 case B_INT32_TYPE:
453 {
454 fPrimitive.SetTo(fPrimitive.ToInt32()
455 - temp.fPrimitive.ToInt32());
456 break;
457 }
458
459 case B_UINT32_TYPE:
460 {
461 fPrimitive.SetTo(fPrimitive.ToUInt32()
462 - temp.fPrimitive.ToUInt32());
463 break;
464 }
465
466 case B_INT64_TYPE:
467 {
468 fPrimitive.SetTo(fPrimitive.ToInt64()
469 - temp.fPrimitive.ToInt64());
470 break;
471 }
472
473 case B_UINT64_TYPE:
474 {
475 fPrimitive.SetTo(fPrimitive.ToUInt64()
476 - temp.fPrimitive.ToUInt64());
477 break;
478 }
479
480 case B_FLOAT_TYPE:
481 {
482 fPrimitive.SetTo(fPrimitive.ToFloat()
483 - temp.fPrimitive.ToFloat());
484 break;
485 }
486
487 case B_DOUBLE_TYPE:
488 {
489 fPrimitive.SetTo(fPrimitive.ToDouble()
490 - temp.fPrimitive.ToDouble());
491 break;
492 }
493 }
494
495 return *this;
496 }
497
operator /=(const Operand & rhs)498 Operand& operator/=(const Operand& rhs)
499 {
500 Operand temp = rhs;
501 _ResolveTypesIfNeeded(temp);
502
503 switch (fPrimitive.Type()) {
504 case B_INT8_TYPE:
505 {
506 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
507 / temp.fPrimitive.ToInt8()));
508 break;
509 }
510
511 case B_UINT8_TYPE:
512 {
513 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
514 / temp.fPrimitive.ToUInt8()));
515 break;
516 }
517
518 case B_INT16_TYPE:
519 {
520 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
521 / temp.fPrimitive.ToInt16()));
522 break;
523 }
524
525 case B_UINT16_TYPE:
526 {
527 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
528 / temp.fPrimitive.ToUInt16()));
529 break;
530 }
531
532 case B_INT32_TYPE:
533 {
534 fPrimitive.SetTo(fPrimitive.ToInt32()
535 / temp.fPrimitive.ToInt32());
536 break;
537 }
538
539 case B_UINT32_TYPE:
540 {
541 fPrimitive.SetTo(fPrimitive.ToUInt32()
542 / temp.fPrimitive.ToUInt32());
543 break;
544 }
545
546 case B_INT64_TYPE:
547 {
548 fPrimitive.SetTo(fPrimitive.ToInt64()
549 / temp.fPrimitive.ToInt64());
550 break;
551 }
552
553 case B_UINT64_TYPE:
554 {
555 fPrimitive.SetTo(fPrimitive.ToUInt64()
556 / temp.fPrimitive.ToUInt64());
557 break;
558 }
559
560 case B_FLOAT_TYPE:
561 {
562 fPrimitive.SetTo(fPrimitive.ToFloat()
563 / temp.fPrimitive.ToFloat());
564 break;
565 }
566
567 case B_DOUBLE_TYPE:
568 {
569 fPrimitive.SetTo(fPrimitive.ToDouble()
570 / temp.fPrimitive.ToDouble());
571 break;
572 }
573 }
574
575 return *this;
576 }
577
operator *=(const Operand & rhs)578 Operand& operator*=(const Operand& rhs)
579 {
580 Operand temp = rhs;
581 _ResolveTypesIfNeeded(temp);
582
583 switch (fPrimitive.Type()) {
584 case B_INT8_TYPE:
585 {
586 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
587 * temp.fPrimitive.ToInt8()));
588 break;
589 }
590
591 case B_UINT8_TYPE:
592 {
593 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
594 * temp.fPrimitive.ToUInt8()));
595 break;
596 }
597
598 case B_INT16_TYPE:
599 {
600 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
601 * temp.fPrimitive.ToInt16()));
602 break;
603 }
604
605 case B_UINT16_TYPE:
606 {
607 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
608 * temp.fPrimitive.ToUInt16()));
609 break;
610 }
611
612 case B_INT32_TYPE:
613 {
614 fPrimitive.SetTo(fPrimitive.ToInt32()
615 * temp.fPrimitive.ToInt32());
616 break;
617 }
618
619 case B_UINT32_TYPE:
620 {
621 fPrimitive.SetTo(fPrimitive.ToUInt32()
622 * temp.fPrimitive.ToUInt32());
623 break;
624 }
625
626 case B_INT64_TYPE:
627 {
628 fPrimitive.SetTo(fPrimitive.ToInt64()
629 * temp.fPrimitive.ToInt64());
630 break;
631 }
632
633 case B_UINT64_TYPE:
634 {
635 fPrimitive.SetTo(fPrimitive.ToUInt64()
636 * temp.fPrimitive.ToUInt64());
637 break;
638 }
639
640 case B_FLOAT_TYPE:
641 {
642 fPrimitive.SetTo(fPrimitive.ToFloat()
643 * temp.fPrimitive.ToFloat());
644 break;
645 }
646
647 case B_DOUBLE_TYPE:
648 {
649 fPrimitive.SetTo(fPrimitive.ToDouble()
650 * temp.fPrimitive.ToDouble());
651 break;
652 }
653 }
654
655 return *this;
656 }
657
operator %=(const Operand & rhs)658 Operand& operator%=(const Operand& rhs)
659 {
660 Operand temp = rhs;
661 _ResolveTypesIfNeeded(temp);
662
663 switch (fPrimitive.Type()) {
664 case B_INT8_TYPE:
665 {
666 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
667 % temp.fPrimitive.ToInt8()));
668 break;
669 }
670
671 case B_UINT8_TYPE:
672 {
673 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
674 % temp.fPrimitive.ToUInt8()));
675 break;
676 }
677
678 case B_INT16_TYPE:
679 {
680 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
681 % temp.fPrimitive.ToInt16()));
682 break;
683 }
684
685 case B_UINT16_TYPE:
686 {
687 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
688 % temp.fPrimitive.ToUInt16()));
689 break;
690 }
691
692 case B_INT32_TYPE:
693 {
694 fPrimitive.SetTo(fPrimitive.ToInt32()
695 % temp.fPrimitive.ToInt32());
696 break;
697 }
698
699 case B_UINT32_TYPE:
700 {
701 fPrimitive.SetTo(fPrimitive.ToUInt32()
702 % temp.fPrimitive.ToUInt32());
703 break;
704 }
705
706 case B_INT64_TYPE:
707 {
708 fPrimitive.SetTo(fPrimitive.ToInt64()
709 % temp.fPrimitive.ToInt64());
710 break;
711 }
712
713 case B_UINT64_TYPE:
714 {
715 fPrimitive.SetTo(fPrimitive.ToUInt64()
716 % temp.fPrimitive.ToUInt64());
717 break;
718 }
719 }
720
721 return *this;
722 }
723
operator &=(const Operand & rhs)724 Operand& operator&=(const Operand& rhs)
725 {
726 Operand temp = rhs;
727 _ResolveTypesIfNeeded(temp);
728
729 switch (fPrimitive.Type()) {
730 case B_INT8_TYPE:
731 {
732 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
733 & temp.fPrimitive.ToInt8()));
734 break;
735 }
736
737 case B_UINT8_TYPE:
738 {
739 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
740 & temp.fPrimitive.ToUInt8()));
741 break;
742 }
743
744 case B_INT16_TYPE:
745 {
746 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
747 & temp.fPrimitive.ToInt16()));
748 break;
749 }
750
751 case B_UINT16_TYPE:
752 {
753 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
754 & temp.fPrimitive.ToUInt16()));
755 break;
756 }
757
758 case B_INT32_TYPE:
759 {
760 fPrimitive.SetTo(fPrimitive.ToInt32()
761 & temp.fPrimitive.ToInt32());
762 break;
763 }
764
765 case B_UINT32_TYPE:
766 {
767 fPrimitive.SetTo(fPrimitive.ToUInt32()
768 & temp.fPrimitive.ToUInt32());
769 break;
770 }
771
772 case B_INT64_TYPE:
773 {
774 fPrimitive.SetTo(fPrimitive.ToInt64()
775 & temp.fPrimitive.ToInt64());
776 break;
777 }
778
779 case B_UINT64_TYPE:
780 {
781 fPrimitive.SetTo(fPrimitive.ToUInt64()
782 & temp.fPrimitive.ToUInt64());
783 break;
784 }
785 }
786
787 return *this;
788 }
789
operator |=(const Operand & rhs)790 Operand& operator|=(const Operand& rhs)
791 {
792 Operand temp = rhs;
793 _ResolveTypesIfNeeded(temp);
794
795 switch (fPrimitive.Type()) {
796 case B_INT8_TYPE:
797 {
798 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
799 | temp.fPrimitive.ToInt8()));
800 break;
801 }
802
803 case B_UINT8_TYPE:
804 {
805 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
806 | temp.fPrimitive.ToUInt8()));
807 break;
808 }
809
810 case B_INT16_TYPE:
811 {
812 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
813 | temp.fPrimitive.ToInt16()));
814 break;
815 }
816
817 case B_UINT16_TYPE:
818 {
819 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
820 | temp.fPrimitive.ToUInt16()));
821 break;
822 }
823
824 case B_INT32_TYPE:
825 {
826 fPrimitive.SetTo(fPrimitive.ToInt32()
827 | temp.fPrimitive.ToInt32());
828 break;
829 }
830
831 case B_UINT32_TYPE:
832 {
833 fPrimitive.SetTo(fPrimitive.ToUInt32()
834 | temp.fPrimitive.ToUInt32());
835 break;
836 }
837
838 case B_INT64_TYPE:
839 {
840 fPrimitive.SetTo(fPrimitive.ToInt64()
841 | temp.fPrimitive.ToInt64());
842 break;
843 }
844
845 case B_UINT64_TYPE:
846 {
847 fPrimitive.SetTo(fPrimitive.ToUInt64()
848 | temp.fPrimitive.ToUInt64());
849 break;
850 }
851 }
852
853 return *this;
854 }
855
operator ^=(const Operand & rhs)856 Operand& operator^=(const Operand& rhs)
857 {
858 Operand temp = rhs;
859 _ResolveTypesIfNeeded(temp);
860
861 switch (fPrimitive.Type()) {
862 case B_INT8_TYPE:
863 {
864 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
865 ^ temp.fPrimitive.ToInt8()));
866 break;
867 }
868
869 case B_UINT8_TYPE:
870 {
871 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
872 ^ temp.fPrimitive.ToUInt8()));
873 break;
874 }
875
876 case B_INT16_TYPE:
877 {
878 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
879 ^ temp.fPrimitive.ToInt16()));
880 break;
881 }
882
883 case B_UINT16_TYPE:
884 {
885 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
886 ^ temp.fPrimitive.ToUInt16()));
887 break;
888 }
889
890 case B_INT32_TYPE:
891 {
892 fPrimitive.SetTo(fPrimitive.ToInt32()
893 ^ temp.fPrimitive.ToInt32());
894 break;
895 }
896
897 case B_UINT32_TYPE:
898 {
899 fPrimitive.SetTo(fPrimitive.ToUInt32()
900 ^ temp.fPrimitive.ToUInt32());
901 break;
902 }
903
904 case B_INT64_TYPE:
905 {
906 fPrimitive.SetTo(fPrimitive.ToInt64()
907 ^ temp.fPrimitive.ToInt64());
908 break;
909 }
910
911 case B_UINT64_TYPE:
912 {
913 fPrimitive.SetTo(fPrimitive.ToUInt64()
914 ^ temp.fPrimitive.ToUInt64());
915 break;
916 }
917 }
918
919 return *this;
920 }
921
operator -() const922 Operand operator-() const
923 {
924 Operand value(*this);
925 value._ResolveToPrimitive();
926
927 switch (fPrimitive.Type()) {
928 case B_INT8_TYPE:
929 {
930 value.fPrimitive.SetTo((int8)-fPrimitive.ToInt8());
931 break;
932 }
933
934 case B_UINT8_TYPE:
935 {
936 value.fPrimitive.SetTo((uint8)-fPrimitive.ToUInt8());
937 break;
938 }
939
940 case B_INT16_TYPE:
941 {
942 value.fPrimitive.SetTo((int16)-fPrimitive.ToInt16());
943 break;
944 }
945
946 case B_UINT16_TYPE:
947 {
948 value.fPrimitive.SetTo((uint16)-fPrimitive.ToUInt16());
949 break;
950 }
951
952 case B_INT32_TYPE:
953 {
954 value.fPrimitive.SetTo(-fPrimitive.ToInt32());
955 break;
956 }
957
958 case B_UINT32_TYPE:
959 {
960 value.fPrimitive.SetTo(-fPrimitive.ToUInt32());
961 break;
962 }
963
964 case B_INT64_TYPE:
965 {
966 value.fPrimitive.SetTo(-fPrimitive.ToInt64());
967 break;
968 }
969
970 case B_UINT64_TYPE:
971 {
972 value.fPrimitive.SetTo(-fPrimitive.ToUInt64());
973 break;
974 }
975
976 case B_FLOAT_TYPE:
977 {
978 value.fPrimitive.SetTo(-fPrimitive.ToFloat());
979 break;
980 }
981
982 case B_DOUBLE_TYPE:
983 {
984 value.fPrimitive.SetTo(-fPrimitive.ToDouble());
985 break;
986 }
987 }
988
989 return value;
990 }
991
operator ~() const992 Operand operator~() const
993 {
994 Operand value(*this);
995 value._ResolveToPrimitive();
996
997 switch (fPrimitive.Type()) {
998 case B_INT8_TYPE:
999 {
1000 value.fPrimitive.SetTo((int8)~fPrimitive.ToInt8());
1001 break;
1002 }
1003
1004 case B_UINT8_TYPE:
1005 {
1006 value.fPrimitive.SetTo((uint8)~fPrimitive.ToUInt8());
1007 break;
1008 }
1009
1010 case B_INT16_TYPE:
1011 {
1012 value.fPrimitive.SetTo((int16)~fPrimitive.ToInt16());
1013 break;
1014 }
1015
1016 case B_UINT16_TYPE:
1017 {
1018 value.fPrimitive.SetTo((uint16)~fPrimitive.ToUInt16());
1019 break;
1020 }
1021
1022 case B_INT32_TYPE:
1023 {
1024 value.fPrimitive.SetTo(~fPrimitive.ToInt32());
1025 break;
1026 }
1027
1028 case B_UINT32_TYPE:
1029 {
1030 value.fPrimitive.SetTo(~fPrimitive.ToUInt32());
1031 break;
1032 }
1033
1034 case B_INT64_TYPE:
1035 {
1036 value.fPrimitive.SetTo(~fPrimitive.ToInt64());
1037 break;
1038 }
1039
1040 case B_UINT64_TYPE:
1041 {
1042 value.fPrimitive.SetTo(~fPrimitive.ToUInt64());
1043 break;
1044 }
1045 }
1046
1047 return value;
1048 }
1049
operator <(const Operand & rhs) const1050 int operator<(const Operand& rhs) const
1051 {
1052 Operand lhs = *this;
1053 Operand temp = rhs;
1054
1055 lhs._ResolveTypesIfNeeded(temp);
1056
1057 int result = 0;
1058 switch (fPrimitive.Type()) {
1059 case B_INT8_TYPE:
1060 {
1061 result = lhs.fPrimitive.ToInt8() < temp.fPrimitive.ToInt8();
1062 break;
1063 }
1064
1065 case B_UINT8_TYPE:
1066 {
1067 result = lhs.fPrimitive.ToUInt8() < temp.fPrimitive.ToUInt8();
1068 break;
1069 }
1070
1071 case B_INT16_TYPE:
1072 {
1073 result = lhs.fPrimitive.ToInt16() < temp.fPrimitive.ToInt16();
1074 break;
1075 }
1076
1077 case B_UINT16_TYPE:
1078 {
1079 result = lhs.fPrimitive.ToUInt16()
1080 < temp.fPrimitive.ToUInt16();
1081 break;
1082 }
1083
1084 case B_INT32_TYPE:
1085 {
1086 result = lhs.fPrimitive.ToInt32() < temp.fPrimitive.ToInt32();
1087 break;
1088 }
1089
1090 case B_UINT32_TYPE:
1091 {
1092 result = lhs.fPrimitive.ToUInt32()
1093 < temp.fPrimitive.ToUInt32();
1094 break;
1095 }
1096
1097 case B_INT64_TYPE:
1098 {
1099 result = lhs.fPrimitive.ToInt64() < temp.fPrimitive.ToInt64();
1100 break;
1101 }
1102
1103 case B_UINT64_TYPE:
1104 {
1105 result = lhs.fPrimitive.ToUInt64()
1106 < temp.fPrimitive.ToUInt64();
1107 break;
1108 }
1109
1110 case B_FLOAT_TYPE:
1111 {
1112 result = lhs.fPrimitive.ToFloat() < temp.fPrimitive.ToFloat();
1113 break;
1114 }
1115
1116 case B_DOUBLE_TYPE:
1117 {
1118 result = lhs.fPrimitive.ToDouble()
1119 < temp.fPrimitive.ToDouble();
1120 break;
1121 }
1122 }
1123
1124 return result;
1125 }
1126
operator <=(const Operand & rhs) const1127 int operator<=(const Operand& rhs) const
1128 {
1129 return (*this < rhs) || (*this == rhs);
1130 }
1131
operator >(const Operand & rhs) const1132 int operator>(const Operand& rhs) const
1133 {
1134 Operand lhs = *this;
1135 Operand temp = rhs;
1136 lhs._ResolveTypesIfNeeded(temp);
1137
1138 int result = 0;
1139 switch (fPrimitive.Type()) {
1140 case B_INT8_TYPE:
1141 {
1142 result = lhs.fPrimitive.ToInt8() > temp.fPrimitive.ToInt8();
1143 break;
1144 }
1145
1146 case B_UINT8_TYPE:
1147 {
1148 result = lhs.fPrimitive.ToUInt8() > temp.fPrimitive.ToUInt8();
1149 break;
1150 }
1151
1152 case B_INT16_TYPE:
1153 {
1154 result = lhs.fPrimitive.ToInt16() > temp.fPrimitive.ToInt16();
1155 break;
1156 }
1157
1158 case B_UINT16_TYPE:
1159 {
1160 result = lhs.fPrimitive.ToUInt16()
1161 > temp.fPrimitive.ToUInt16();
1162 break;
1163 }
1164
1165 case B_INT32_TYPE:
1166 {
1167 result = lhs.fPrimitive.ToInt32() > temp.fPrimitive.ToInt32();
1168 break;
1169 }
1170
1171 case B_UINT32_TYPE:
1172 {
1173 result = lhs.fPrimitive.ToUInt32()
1174 > temp.fPrimitive.ToUInt32();
1175 break;
1176 }
1177
1178 case B_INT64_TYPE:
1179 {
1180 result = lhs.fPrimitive.ToInt64() > temp.fPrimitive.ToInt64();
1181 break;
1182 }
1183
1184 case B_UINT64_TYPE:
1185 {
1186 result = lhs.fPrimitive.ToUInt64()
1187 > temp.fPrimitive.ToUInt64();
1188 break;
1189 }
1190
1191 case B_FLOAT_TYPE:
1192 {
1193 result = lhs.fPrimitive.ToFloat() > temp.fPrimitive.ToFloat();
1194 break;
1195 }
1196
1197 case B_DOUBLE_TYPE:
1198 {
1199 result = lhs.fPrimitive.ToDouble()
1200 > temp.fPrimitive.ToDouble();
1201 break;
1202 }
1203 }
1204
1205 return result;
1206 }
1207
operator >=(const Operand & rhs) const1208 int operator>=(const Operand& rhs) const
1209 {
1210 return (*this > rhs) || (*this == rhs);
1211 }
1212
operator ==(const Operand & rhs) const1213 int operator==(const Operand& rhs) const
1214 {
1215 Operand lhs = *this;
1216 Operand temp = rhs;
1217 lhs._ResolveTypesIfNeeded(temp);
1218
1219 int result = 0;
1220 switch (fPrimitive.Type()) {
1221 case B_INT8_TYPE:
1222 {
1223 result = lhs.fPrimitive.ToInt8() == temp.fPrimitive.ToInt8();
1224 break;
1225 }
1226
1227 case B_UINT8_TYPE:
1228 {
1229 result = lhs.fPrimitive.ToUInt8() == temp.fPrimitive.ToUInt8();
1230 break;
1231 }
1232
1233 case B_INT16_TYPE:
1234 {
1235 result = lhs.fPrimitive.ToInt16() == temp.fPrimitive.ToInt16();
1236 break;
1237 }
1238
1239 case B_UINT16_TYPE:
1240 {
1241 result = lhs.fPrimitive.ToUInt16()
1242 == temp.fPrimitive.ToUInt16();
1243 break;
1244 }
1245
1246 case B_INT32_TYPE:
1247 {
1248 result = lhs.fPrimitive.ToInt32() == temp.fPrimitive.ToInt32();
1249 break;
1250 }
1251
1252 case B_UINT32_TYPE:
1253 {
1254 result = lhs.fPrimitive.ToUInt32()
1255 == temp.fPrimitive.ToUInt32();
1256 break;
1257 }
1258
1259 case B_INT64_TYPE:
1260 {
1261 result = lhs.fPrimitive.ToInt64() == temp.fPrimitive.ToInt64();
1262 break;
1263 }
1264
1265 case B_UINT64_TYPE:
1266 {
1267 result = lhs.fPrimitive.ToUInt64()
1268 == temp.fPrimitive.ToUInt64();
1269 break;
1270 }
1271
1272 case B_FLOAT_TYPE:
1273 {
1274 result = lhs.fPrimitive.ToFloat() == temp.fPrimitive.ToFloat();
1275 break;
1276 }
1277
1278 case B_DOUBLE_TYPE:
1279 {
1280 result = lhs.fPrimitive.ToDouble()
1281 == temp.fPrimitive.ToDouble();
1282 break;
1283 }
1284 }
1285
1286 return result;
1287 }
1288
operator !=(const Operand & rhs) const1289 int operator!=(const Operand& rhs) const
1290 {
1291 return !(*this == rhs);
1292 }
1293
1294 private:
_GetAsType(type_code type)1295 void _GetAsType(type_code type)
1296 {
1297 switch (type) {
1298 case B_INT8_TYPE:
1299 fPrimitive.SetTo(fPrimitive.ToInt8());
1300 break;
1301 case B_UINT8_TYPE:
1302 fPrimitive.SetTo(fPrimitive.ToUInt8());
1303 break;
1304 case B_INT16_TYPE:
1305 fPrimitive.SetTo(fPrimitive.ToInt16());
1306 break;
1307 case B_UINT16_TYPE:
1308 fPrimitive.SetTo(fPrimitive.ToUInt16());
1309 break;
1310 case B_INT32_TYPE:
1311 fPrimitive.SetTo(fPrimitive.ToInt32());
1312 break;
1313 case B_UINT32_TYPE:
1314 fPrimitive.SetTo(fPrimitive.ToUInt32());
1315 break;
1316 case B_INT64_TYPE:
1317 fPrimitive.SetTo(fPrimitive.ToInt64());
1318 break;
1319 case B_UINT64_TYPE:
1320 fPrimitive.SetTo(fPrimitive.ToUInt64());
1321 break;
1322 case B_FLOAT_TYPE:
1323 fPrimitive.SetTo(fPrimitive.ToFloat());
1324 break;
1325 case B_DOUBLE_TYPE:
1326 fPrimitive.SetTo(fPrimitive.ToDouble());
1327 break;
1328 }
1329 }
1330
_ResolveTypesIfNeeded(Operand & other)1331 void _ResolveTypesIfNeeded(Operand& other)
1332 {
1333 _ResolveToPrimitive();
1334 other._ResolveToPrimitive();
1335
1336 if (!fPrimitive.IsNumber() || !other.fPrimitive.IsNumber()) {
1337 throw ParseException("Cannot perform mathematical operations "
1338 "between non-numerical objects.", 0);
1339 }
1340
1341 type_code thisType = fPrimitive.Type();
1342 type_code otherType = other.fPrimitive.Type();
1343
1344 if (thisType == otherType)
1345 return;
1346
1347 type_code resolvedType = _ResolvePriorityType(thisType, otherType);
1348 if (thisType != resolvedType)
1349 _GetAsType(resolvedType);
1350
1351 if (otherType != resolvedType)
1352 other._GetAsType(resolvedType);
1353 }
1354
_ResolveToPrimitive()1355 void _ResolveToPrimitive()
1356 {
1357 if (Kind() == OPERAND_KIND_PRIMITIVE)
1358 return;
1359 else if (Kind() == OPERAND_KIND_TYPE) {
1360 throw ParseException("Cannot perform mathematical operations "
1361 "between type objects.", 0);
1362 }
1363
1364 status_t error = fValueNode->LocationAndValueResolutionState();
1365 if (error != B_OK) {
1366 BString errorMessage;
1367 errorMessage.SetToFormat("Failed to resolve value of %s: %"
1368 B_PRId32 ".", fValueNode->Name().String(), error);
1369 throw ParseException(errorMessage.String(), 0);
1370 }
1371
1372 Value* value = fValueNode->GetValue();
1373 BVariant tempValue;
1374 if (value->ToVariant(tempValue))
1375 SetTo(tempValue);
1376 else {
1377 BString error;
1378 error.SetToFormat("Failed to retrieve value of %s.",
1379 fValueNode->Name().String());
1380 throw ParseException(error.String(), 0);
1381 }
1382 }
1383
_ResolvePriorityType(type_code lhs,type_code rhs) const1384 type_code _ResolvePriorityType(type_code lhs, type_code rhs) const
1385 {
1386 size_t byteSize = std::max(BVariant::SizeOfType(lhs),
1387 BVariant::SizeOfType(rhs));
1388 bool isFloat = BVariant::TypeIsFloat(lhs)
1389 || BVariant::TypeIsFloat(rhs);
1390 bool isSigned = isFloat;
1391 if (!isFloat) {
1392 BVariant::TypeIsInteger(lhs, &isSigned);
1393 if (!isSigned)
1394 BVariant::TypeIsInteger(rhs, &isSigned);
1395 }
1396
1397 if (isFloat) {
1398 if (byteSize == sizeof(float))
1399 return B_FLOAT_TYPE;
1400 return B_DOUBLE_TYPE;
1401 }
1402
1403 switch (byteSize) {
1404 case 1:
1405 return isSigned ? B_INT8_TYPE : B_UINT8_TYPE;
1406 case 2:
1407 return isSigned ? B_INT16_TYPE : B_UINT16_TYPE;
1408 case 4:
1409 return isSigned ? B_INT32_TYPE : B_UINT32_TYPE;
1410 case 8:
1411 return isSigned ? B_INT64_TYPE : B_UINT64_TYPE;
1412 default:
1413 break;
1414 }
1415
1416 BString error;
1417 error.SetToFormat("Unable to reconcile types %#" B_PRIx32
1418 " and %#" B_PRIx32, lhs, rhs);
1419 throw ParseException(error.String(), 0);
1420 }
1421
1422 private:
1423 BVariant fPrimitive;
1424 ValueNode* fValueNode;
1425 Type* fType;
1426 operand_kind fKind;
1427 };
1428
1429
1430 // #pragma mark - CLanguageExpressionEvaluator
1431
1432
CLanguageExpressionEvaluator()1433 CLanguageExpressionEvaluator::CLanguageExpressionEvaluator()
1434 :
1435 fTokenizer(new Tokenizer()),
1436 fTypeInfo(NULL),
1437 fNodeManager(NULL)
1438 {
1439 }
1440
1441
~CLanguageExpressionEvaluator()1442 CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator()
1443 {
1444 delete fTokenizer;
1445 }
1446
1447
1448 ExpressionResult*
Evaluate(const char * expressionString,ValueNodeManager * manager,TeamTypeInformation * info)1449 CLanguageExpressionEvaluator::Evaluate(const char* expressionString,
1450 ValueNodeManager* manager, TeamTypeInformation* info)
1451 {
1452 fNodeManager = manager;
1453 fTypeInfo = info;
1454 fTokenizer->SetTo(expressionString);
1455
1456 Operand value = _ParseSum();
1457 Token token = fTokenizer->NextToken();
1458 if (token.type != TOKEN_END_OF_LINE)
1459 throw ParseException("parse error", token.position);
1460
1461 ExpressionResult* result = new(std::nothrow)ExpressionResult;
1462 if (result != NULL) {
1463 BReference<ExpressionResult> resultReference(result, true);
1464 if (value.Kind() == OPERAND_KIND_PRIMITIVE) {
1465 Value* outputValue = NULL;
1466 BVariant primitive = value.PrimitiveValue();
1467 if (primitive.IsInteger())
1468 outputValue = new(std::nothrow) IntegerValue(primitive);
1469 else if (primitive.IsFloat()) {
1470 outputValue = new(std::nothrow) FloatValue(
1471 primitive.ToDouble());
1472 }
1473
1474 BReference<Value> valueReference;
1475 if (outputValue != NULL) {
1476 valueReference.SetTo(outputValue, true);
1477 result->SetToPrimitive(outputValue);
1478 } else
1479 return NULL;
1480 } else if (value.Kind() == OPERAND_KIND_VALUE_NODE)
1481 result->SetToValueNode(value.GetValueNode()->NodeChild());
1482 else if (value.Kind() == OPERAND_KIND_TYPE)
1483 result->SetToType(value.GetType());
1484
1485 resultReference.Detach();
1486 }
1487
1488 return result;
1489 }
1490
1491
1492 CLanguageExpressionEvaluator::Operand
_ParseSum()1493 CLanguageExpressionEvaluator::_ParseSum()
1494 {
1495 Operand value = _ParseProduct();
1496
1497 while (true) {
1498 Token token = fTokenizer->NextToken();
1499 switch (token.type) {
1500 case TOKEN_PLUS:
1501 value += _ParseProduct();
1502 break;
1503 case TOKEN_MINUS:
1504 value -= _ParseProduct();
1505 break;
1506
1507 default:
1508 fTokenizer->RewindToken();
1509 return value;
1510 }
1511 }
1512 }
1513
1514
1515 CLanguageExpressionEvaluator::Operand
_ParseProduct()1516 CLanguageExpressionEvaluator::_ParseProduct()
1517 {
1518 static Operand zero(int64(0LL));
1519
1520 Operand value = _ParseUnary();
1521
1522 while (true) {
1523 Token token = fTokenizer->NextToken();
1524 switch (token.type) {
1525 case TOKEN_STAR:
1526 value *= _ParseUnary();
1527 break;
1528 case TOKEN_SLASH:
1529 {
1530 Operand rhs = _ParseUnary();
1531 if (rhs == zero)
1532 throw ParseException("division by zero", token.position);
1533 value /= rhs;
1534 break;
1535 }
1536
1537 case TOKEN_MODULO:
1538 {
1539 Operand rhs = _ParseUnary();
1540 if (rhs == zero)
1541 throw ParseException("modulo by zero", token.position);
1542 value %= rhs;
1543 break;
1544 }
1545
1546 case TOKEN_LOGICAL_AND:
1547 {
1548 value.SetTo((value != zero)
1549 && (_ParseUnary() != zero));
1550
1551 break;
1552 }
1553
1554 case TOKEN_LOGICAL_OR:
1555 {
1556 value.SetTo((value != zero)
1557 || (_ParseUnary() != zero));
1558 break;
1559 }
1560
1561 case TOKEN_BITWISE_AND:
1562 value &= _ParseUnary();
1563 break;
1564
1565 case TOKEN_BITWISE_OR:
1566 value |= _ParseUnary();
1567 break;
1568
1569 case TOKEN_BITWISE_XOR:
1570 value ^= _ParseUnary();
1571 break;
1572
1573 case TOKEN_EQ:
1574 value.SetTo((int64)(value == _ParseUnary()));
1575 break;
1576
1577 case TOKEN_NE:
1578 value.SetTo((int64)(value != _ParseUnary()));
1579 break;
1580
1581 case TOKEN_GT:
1582 value.SetTo((int64)(value > _ParseUnary()));
1583 break;
1584
1585 case TOKEN_GE:
1586 value.SetTo((int64)(value >= _ParseUnary()));
1587 break;
1588
1589 case TOKEN_LT:
1590 value.SetTo((int64)(value < _ParseUnary()));
1591 break;
1592
1593 case TOKEN_LE:
1594 value.SetTo((int64)(value <= _ParseUnary()));
1595 break;
1596
1597 default:
1598 fTokenizer->RewindToken();
1599 return value;
1600 }
1601 }
1602 }
1603
1604
1605 CLanguageExpressionEvaluator::Operand
_ParseUnary()1606 CLanguageExpressionEvaluator::_ParseUnary()
1607 {
1608 Token token = fTokenizer->NextToken();
1609 if (token.type == TOKEN_END_OF_LINE)
1610 throw ParseException("unexpected end of expression", token.position);
1611
1612 switch (token.type) {
1613 case TOKEN_PLUS:
1614 return _ParseUnary();
1615
1616 case TOKEN_MINUS:
1617 return -_ParseUnary();
1618
1619 case TOKEN_BITWISE_NOT:
1620 return ~_ParseUnary();
1621
1622 case TOKEN_LOGICAL_NOT:
1623 {
1624 Operand zero((int64)0);
1625 return Operand((int64)(_ParseUnary() == zero));
1626 }
1627
1628 case TOKEN_IDENTIFIER:
1629 fTokenizer->RewindToken();
1630 return _ParseIdentifier();
1631
1632 default:
1633 fTokenizer->RewindToken();
1634 return _ParseAtom();
1635 }
1636
1637 return Operand();
1638 }
1639
1640
1641 CLanguageExpressionEvaluator::Operand
_ParseIdentifier(ValueNode * parentNode)1642 CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode)
1643 {
1644 Token token = fTokenizer->NextToken();
1645 const BString& identifierName = token.string;
1646
1647 ValueNodeChild* child = NULL;
1648 if (fNodeManager != NULL) {
1649 ValueNodeContainer* container = fNodeManager->GetContainer();
1650 AutoLocker<ValueNodeContainer> containerLocker(container);
1651
1652 if (parentNode == NULL) {
1653 ValueNodeChild* thisChild = NULL;
1654 for (int32 i = 0; i < container->CountChildren(); i++) {
1655 ValueNodeChild* current = container->ChildAt(i);
1656 const BString& nodeName = current->Name();
1657 if (nodeName == identifierName) {
1658 child = current;
1659 break;
1660 } else if (nodeName == "this")
1661 thisChild = current;
1662 }
1663
1664 if (child == NULL && thisChild != NULL) {
1665 // the name was not found in the variables or parameters,
1666 // but we have a class pointer. Try to find the name in the
1667 // list of members.
1668 _RequestValueIfNeeded(token, thisChild);
1669 ValueNode* thisNode = thisChild->Node();
1670 fTokenizer->RewindToken();
1671 return _ParseIdentifier(thisNode);
1672 }
1673 } else {
1674 // skip intermediate address nodes
1675 if (parentNode->GetType()->Kind() == TYPE_ADDRESS
1676 && parentNode->CountChildren() == 1) {
1677 child = parentNode->ChildAt(0);
1678
1679 _RequestValueIfNeeded(token, child);
1680 parentNode = child->Node();
1681 fTokenizer->RewindToken();
1682 return _ParseIdentifier(parentNode);
1683 }
1684
1685 for (int32 i = 0; i < parentNode->CountChildren(); i++) {
1686 ValueNodeChild* current = parentNode->ChildAt(i);
1687 const BString& nodeName = current->Name();
1688 if (nodeName == identifierName) {
1689 child = current;
1690 break;
1691 }
1692 }
1693 }
1694 }
1695
1696 if (child == NULL && fTypeInfo != NULL) {
1697 Type* resultType = NULL;
1698 status_t error = fTypeInfo->LookupTypeByName(identifierName,
1699 TypeLookupConstraints(), resultType);
1700 if (error == B_OK) {
1701 BReference<Type> typeReference(resultType, true);
1702 return _ParseType(resultType);
1703 } else if (error != B_ENTRY_NOT_FOUND) {
1704 BString errorMessage;
1705 errorMessage.SetToFormat("Failed to look up type name '%s': %"
1706 B_PRId32 ".", identifierName.String(), error);
1707 throw ParseException(errorMessage.String(), token.position);
1708 }
1709 }
1710
1711 BString errorMessage;
1712 if (child == NULL) {
1713 errorMessage.SetToFormat("Unable to resolve variable name: '%s'",
1714 identifierName.String());
1715 throw ParseException(errorMessage, token.position);
1716 }
1717
1718 _RequestValueIfNeeded(token, child);
1719 ValueNode* node = child->Node();
1720
1721 token = fTokenizer->NextToken();
1722 if (token.type == TOKEN_MEMBER_PTR) {
1723 token = fTokenizer->NextToken();
1724 if (token.type == TOKEN_IDENTIFIER) {
1725 fTokenizer->RewindToken();
1726 return _ParseIdentifier(node);
1727 } else {
1728 throw ParseException("Expected identifier after member "
1729 "dereference.", token.position);
1730 }
1731 } else
1732 fTokenizer->RewindToken();
1733
1734 return Operand(node);
1735 }
1736
1737
1738 CLanguageExpressionEvaluator::Operand
_ParseAtom()1739 CLanguageExpressionEvaluator::_ParseAtom()
1740 {
1741 Token token = fTokenizer->NextToken();
1742 if (token.type == TOKEN_END_OF_LINE)
1743 throw ParseException("Unexpected end of expression", token.position);
1744
1745 Operand value;
1746
1747 if (token.type == TOKEN_CONSTANT)
1748 value.SetTo(token.value);
1749 else {
1750 fTokenizer->RewindToken();
1751
1752 _EatToken(TOKEN_OPENING_PAREN);
1753
1754 value = _ParseSum();
1755
1756 _EatToken(TOKEN_CLOSING_PAREN);
1757 }
1758
1759 if (value.Kind() == OPERAND_KIND_TYPE) {
1760 token = fTokenizer->NextToken();
1761 if (token.type == TOKEN_END_OF_LINE)
1762 return value;
1763
1764 Type* castType = value.GetType();
1765 // if our evaluated result was a type, and there still remain
1766 // further tokens to evaluate, then this is a typecast for
1767 // a subsequent expression. Attempt to evaluate it, and then
1768 // apply the cast to the result.
1769 fTokenizer->RewindToken();
1770 value = _ParseSum();
1771 ValueNodeChild* child = NULL;
1772 if (value.Kind() != OPERAND_KIND_PRIMITIVE
1773 && value.Kind() != OPERAND_KIND_VALUE_NODE) {
1774 throw ParseException("Expected value or variable expression after"
1775 " typecast.", token.position);
1776 }
1777
1778 if (value.Kind() == OPERAND_KIND_VALUE_NODE)
1779 child = value.GetValueNode()->NodeChild();
1780 else if (value.Kind() == OPERAND_KIND_PRIMITIVE)
1781 _GetNodeChildForPrimitive(token, value.PrimitiveValue(), child);
1782
1783 ValueNode* newNode = NULL;
1784 status_t error = TypeHandlerRoster::Default()->CreateValueNode(child,
1785 castType, NULL, newNode);
1786 if (error != B_OK) {
1787 throw ParseException("Unable to create value node for typecast"
1788 " operation.", token.position);
1789 }
1790 child->SetNode(newNode);
1791 value.SetTo(newNode);
1792 }
1793
1794 return value;
1795 }
1796
1797
1798 void
_EatToken(int32 type)1799 CLanguageExpressionEvaluator::_EatToken(int32 type)
1800 {
1801 Token token = fTokenizer->NextToken();
1802 if (token.type != type) {
1803 BString expected;
1804 switch (type) {
1805 case TOKEN_IDENTIFIER:
1806 expected = "an identifier";
1807 break;
1808
1809 case TOKEN_CONSTANT:
1810 expected = "a constant";
1811 break;
1812
1813 case TOKEN_SLASH:
1814 expected = "'/', '\\', or ':'";
1815 break;
1816
1817 case TOKEN_END_OF_LINE:
1818 expected = "'\\n'";
1819 break;
1820
1821 default:
1822 expected << "'" << TokenTypeToString(type) << "'";
1823 break;
1824 }
1825
1826 BString temp;
1827 temp << "Expected " << expected.String() << " got '" << token.string
1828 << "'";
1829 throw ParseException(temp.String(), token.position);
1830 }
1831 }
1832
1833
1834 CLanguageExpressionEvaluator::Operand
_ParseType(Type * baseType)1835 CLanguageExpressionEvaluator::_ParseType(Type* baseType)
1836 {
1837 BReference<Type> typeReference;
1838 Type* finalType = baseType;
1839
1840 bool arraySpecifierEncountered = false;
1841 status_t error;
1842 for (;;) {
1843 Token token = fTokenizer->NextToken();
1844 if (token.type == TOKEN_STAR || token.type == TOKEN_BITWISE_AND) {
1845 if (arraySpecifierEncountered)
1846 break;
1847
1848 address_type_kind addressKind = (token.type == TOKEN_STAR)
1849 ? DERIVED_TYPE_POINTER : DERIVED_TYPE_REFERENCE;
1850 AddressType* derivedType = NULL;
1851 error = finalType->CreateDerivedAddressType(addressKind,
1852 derivedType);
1853 if (error != B_OK) {
1854 BString errorMessage;
1855 errorMessage.SetToFormat("Failed to create derived address"
1856 " type %d for base type %s: %s (%" B_PRId32 ")",
1857 addressKind, finalType->Name().String(), strerror(error),
1858 error);
1859 throw ParseException(errorMessage, token.position);
1860 }
1861
1862 finalType = derivedType;
1863 typeReference.SetTo(finalType, true);
1864 } else if (token.type == TOKEN_OPENING_SQUARE_BRACKET) {
1865 Operand indexSize = _ParseSum();
1866 if (indexSize.Kind() == OPERAND_KIND_TYPE) {
1867 throw ParseException("Cannot specify type name as array"
1868 " subscript.", token.position);
1869 }
1870
1871 _EatToken(TOKEN_CLOSING_SQUARE_BRACKET);
1872
1873 uint32 resolvedSize = indexSize.PrimitiveValue().ToUInt32();
1874 if (resolvedSize == 0) {
1875 throw ParseException("Non-zero array size required in type"
1876 " specifier.", token.position);
1877 }
1878
1879 ArrayType* derivedType = NULL;
1880 error = finalType->CreateDerivedArrayType(0, resolvedSize, true,
1881 derivedType);
1882 if (error != B_OK) {
1883 BString errorMessage;
1884 errorMessage.SetToFormat("Failed to create derived array type"
1885 " of size %" B_PRIu32 " for base type %s: %s (%"
1886 B_PRId32 ")", resolvedSize, finalType->Name().String(),
1887 strerror(error), error);
1888 throw ParseException(errorMessage, token.position);
1889 }
1890
1891 arraySpecifierEncountered = true;
1892 finalType = derivedType;
1893 typeReference.SetTo(finalType, true);
1894 } else
1895 break;
1896 }
1897
1898 typeReference.Detach();
1899 fTokenizer->RewindToken();
1900 return Operand(finalType);
1901 }
1902
1903
1904 void
_RequestValueIfNeeded(const Token & token,ValueNodeChild * child)1905 CLanguageExpressionEvaluator::_RequestValueIfNeeded(
1906 const Token& token, ValueNodeChild* child)
1907 {
1908 status_t state;
1909 BString errorMessage;
1910 if (child->Node() == NULL) {
1911 state = fNodeManager->AddChildNodes(child);
1912 if (state != B_OK) {
1913 errorMessage.SetToFormat("Unable to add children for node '%s': "
1914 "%s", child->Name().String(), strerror(state));
1915 throw ParseException(errorMessage, token.position);
1916 }
1917 }
1918
1919 state = child->LocationResolutionState();
1920 if (state == VALUE_NODE_UNRESOLVED)
1921 throw ValueNeededException(child->Node());
1922 else if (state != B_OK) {
1923 errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
1924 "%s", child->Name().String(), strerror(state));
1925 throw ParseException(errorMessage, token.position);
1926 }
1927
1928 ValueNode* node = child->Node();
1929 state = node->LocationAndValueResolutionState();
1930 if (state == VALUE_NODE_UNRESOLVED)
1931 throw ValueNeededException(child->Node());
1932 else if (state != B_OK) {
1933 errorMessage.SetToFormat("Unable to resolve variable value for '%s': "
1934 "%s", child->Name().String(), strerror(state));
1935 throw ParseException(errorMessage, token.position);
1936 }
1937 }
1938
1939
1940 void
_GetNodeChildForPrimitive(const Token & token,const BVariant & value,ValueNodeChild * & _output) const1941 CLanguageExpressionEvaluator::_GetNodeChildForPrimitive(const Token& token,
1942 const BVariant& value, ValueNodeChild*& _output) const
1943 {
1944 Type* type = new(std::nothrow) SyntheticPrimitiveType(value.Type());
1945 if (type == NULL) {
1946 throw ParseException("Out of memory while creating type object.",
1947 token.position);
1948 }
1949
1950 BReference<Type> typeReference(type, true);
1951 ValueLocation* location = new(std::nothrow) ValueLocation();
1952 if (location == NULL) {
1953 throw ParseException("Out of memory while creating location object.",
1954 token.position);
1955 }
1956
1957 BReference<ValueLocation> locationReference(location, true);
1958 ValuePieceLocation piece;
1959 if (!piece.SetToValue(value.Bytes(), value.Size())
1960 || !location->AddPiece(piece)) {
1961 throw ParseException("Out of memory populating location"
1962 " object.", token.position);
1963 }
1964
1965 char variableName[32];
1966 if (!IntegerFormatter::FormatValue(value, INTEGER_FORMAT_HEX_DEFAULT,
1967 variableName, sizeof(variableName))) {
1968 throw ParseException("Failed to generate internal variable name.",
1969 token.position);
1970 }
1971
1972 InternalVariableID* id = new(std::nothrow) InternalVariableID(value);
1973 if (id == NULL) {
1974 throw ParseException("Out of memory while creating ID object.",
1975 token.position);
1976 }
1977
1978 BReference<ObjectID> idReference(id, true);
1979 Variable* variable = new(std::nothrow) Variable(id, variableName, type,
1980 location);
1981 if (variable == NULL) {
1982 throw ParseException("Out of memory while creating variable object.",
1983 token.position);
1984 }
1985
1986 BReference<Variable> variableReference(variable, true);
1987 _output = new(std::nothrow) VariableValueNodeChild(
1988 variable);
1989 if (_output == NULL) {
1990 throw ParseException("Out of memory while creating node child object.",
1991 token.position);
1992 }
1993 }
1994