headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / debugger / source_language / c_family / CLanguageExpressionEvaluator.cpp
blob11e73012d35b4b1ba653e7be1e9fa40bbc553f16
1 /*
2 * Copyright 2006-2014 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
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>
12 #include "CLanguageExpressionEvaluator.h"
14 #include <algorithm>
16 #include "AutoLocker.h"
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"
39 using namespace CLanguage;
42 enum operand_kind {
43 OPERAND_KIND_UNKNOWN = 0,
44 OPERAND_KIND_PRIMITIVE,
45 OPERAND_KIND_TYPE,
46 OPERAND_KIND_VALUE_NODE
50 static BString TokenTypeToString(int32 type)
52 BString token;
54 switch (type) {
55 case TOKEN_PLUS:
56 token = "+";
57 break;
59 case TOKEN_MINUS:
60 token = "-";
61 break;
63 case TOKEN_STAR:
64 token = "*";
65 break;
67 case TOKEN_SLASH:
68 token = "/";
69 break;
71 case TOKEN_MODULO:
72 token = "%";
73 break;
75 case TOKEN_OPENING_PAREN:
76 token = "(";
77 break;
79 case TOKEN_CLOSING_PAREN:
80 token = ")";
81 break;
83 case TOKEN_LOGICAL_AND:
84 token = "&&";
85 break;
87 case TOKEN_LOGICAL_OR:
88 token = "||";
89 break;
91 case TOKEN_LOGICAL_NOT:
92 token = "!";
93 break;
95 case TOKEN_BITWISE_AND:
96 token = "&";
97 break;
99 case TOKEN_BITWISE_OR:
100 token = "|";
101 break;
103 case TOKEN_BITWISE_NOT:
104 token = "~";
105 break;
107 case TOKEN_BITWISE_XOR:
108 token = "^";
109 break;
111 case TOKEN_EQ:
112 token = "==";
113 break;
115 case TOKEN_NE:
116 token = "!=";
117 break;
119 case TOKEN_GT:
120 token = ">";
121 break;
123 case TOKEN_GE:
124 token = ">=";
125 break;
127 case TOKEN_LT:
128 token = "<";
129 break;
131 case TOKEN_LE:
132 token = "<=";
133 break;
135 case TOKEN_MEMBER_PTR:
136 token = "->";
137 break;
139 default:
140 token.SetToFormat("Unknown token type %" B_PRId32, type);
141 break;
144 return token;
148 // #pragma mark - CLanguageExpressionEvaluator::InternalVariableID
151 class CLanguageExpressionEvaluator::InternalVariableID : public ObjectID {
152 public:
153 InternalVariableID(const BVariant& value)
155 fValue(value)
159 virtual ~InternalVariableID()
163 virtual bool operator==(const ObjectID& other) const
165 const InternalVariableID* otherID
166 = dynamic_cast<const InternalVariableID*>(&other);
167 if (otherID == NULL)
168 return false;
170 return fValue == otherID->fValue;
173 protected:
174 virtual uint32 ComputeHashValue() const
176 return *(uint32*)(&fValue);
179 private:
180 BVariant fValue;
184 // #pragma mark - CLanguageExpressionEvaluator::Operand
187 class CLanguageExpressionEvaluator::Operand {
188 public:
189 Operand()
191 fPrimitive(),
192 fValueNode(NULL),
193 fType(NULL),
194 fKind(OPERAND_KIND_UNKNOWN)
198 Operand(int64 value)
200 fPrimitive(value),
201 fValueNode(NULL),
202 fType(NULL),
203 fKind(OPERAND_KIND_PRIMITIVE)
207 Operand(double value)
209 fPrimitive(value),
210 fValueNode(NULL),
211 fType(NULL),
212 fKind(OPERAND_KIND_PRIMITIVE)
216 Operand(ValueNode* node)
218 fPrimitive(),
219 fValueNode(NULL),
220 fType(NULL),
221 fKind(OPERAND_KIND_UNKNOWN)
223 SetTo(node);
226 Operand(Type* type)
228 fPrimitive(),
229 fValueNode(NULL),
230 fType(NULL),
231 fKind(OPERAND_KIND_UNKNOWN)
233 SetTo(type);
236 Operand(const Operand& X)
238 fPrimitive(),
239 fValueNode(NULL),
240 fType(NULL),
241 fKind(OPERAND_KIND_UNKNOWN)
243 *this = X;
247 virtual ~Operand()
249 Unset();
252 Operand& operator=(const Operand& X)
254 switch (X.fKind) {
255 case OPERAND_KIND_UNKNOWN:
256 Unset();
257 break;
259 case OPERAND_KIND_PRIMITIVE:
260 SetTo(X.fPrimitive);
261 break;
263 case OPERAND_KIND_VALUE_NODE:
264 SetTo(X.fValueNode);
265 break;
267 case OPERAND_KIND_TYPE:
268 SetTo(X.fType);
269 break;
272 return *this;
275 void SetTo(const BVariant& value)
277 Unset();
278 fPrimitive = value;
279 fKind = OPERAND_KIND_PRIMITIVE;
282 void SetTo(ValueNode* node)
284 Unset();
285 fValueNode = node;
286 fValueNode->AcquireReference();
288 Value* value = node->GetValue();
289 if (value != NULL)
290 value->ToVariant(fPrimitive);
292 fKind = OPERAND_KIND_VALUE_NODE;
295 void SetTo(Type* type)
297 Unset();
298 fType = type;
299 fType->AcquireReference();
301 fKind = OPERAND_KIND_TYPE;
304 void Unset()
306 if (fValueNode != NULL)
307 fValueNode->ReleaseReference();
309 if (fType != NULL)
310 fType->ReleaseReference();
312 fValueNode = NULL;
313 fType = NULL;
314 fKind = OPERAND_KIND_UNKNOWN;
317 inline operand_kind Kind() const
319 return fKind;
322 inline const BVariant& PrimitiveValue() const
324 return fPrimitive;
327 inline ValueNode* GetValueNode() const
329 return fValueNode;
333 inline Type* GetType() const
335 return fType;
338 Operand& operator+=(const Operand& rhs)
340 Operand temp = rhs;
341 _ResolveTypesIfNeeded(temp);
343 switch (fPrimitive.Type()) {
344 case B_INT8_TYPE:
346 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
347 + temp.fPrimitive.ToInt8()));
348 break;
351 case B_UINT8_TYPE:
353 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
354 + temp.fPrimitive.ToUInt8()));
355 break;
358 case B_INT16_TYPE:
360 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
361 + temp.fPrimitive.ToInt16()));
362 break;
365 case B_UINT16_TYPE:
367 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
368 + temp.fPrimitive.ToUInt16()));
369 break;
372 case B_INT32_TYPE:
374 fPrimitive.SetTo(fPrimitive.ToInt32()
375 + temp.fPrimitive.ToInt32());
376 break;
379 case B_UINT32_TYPE:
381 fPrimitive.SetTo(fPrimitive.ToUInt32()
382 + temp.fPrimitive.ToUInt32());
383 break;
386 case B_INT64_TYPE:
388 fPrimitive.SetTo(fPrimitive.ToInt64()
389 + temp.fPrimitive.ToInt64());
390 break;
393 case B_UINT64_TYPE:
395 fPrimitive.SetTo(fPrimitive.ToUInt64()
396 + temp.fPrimitive.ToUInt64());
397 break;
400 case B_FLOAT_TYPE:
402 fPrimitive.SetTo(fPrimitive.ToFloat()
403 + temp.fPrimitive.ToFloat());
404 break;
407 case B_DOUBLE_TYPE:
409 fPrimitive.SetTo(fPrimitive.ToDouble()
410 + temp.fPrimitive.ToDouble());
411 break;
415 return *this;
418 Operand& operator-=(const Operand& rhs)
420 Operand temp = rhs;
421 _ResolveTypesIfNeeded(temp);
423 switch (fPrimitive.Type()) {
424 case B_INT8_TYPE:
426 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
427 - temp.fPrimitive.ToInt8()));
428 break;
431 case B_UINT8_TYPE:
433 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
434 - temp.fPrimitive.ToUInt8()));
435 break;
438 case B_INT16_TYPE:
440 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
441 - temp.fPrimitive.ToInt16()));
442 break;
445 case B_UINT16_TYPE:
447 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
448 - temp.fPrimitive.ToUInt16()));
449 break;
452 case B_INT32_TYPE:
454 fPrimitive.SetTo(fPrimitive.ToInt32()
455 - temp.fPrimitive.ToInt32());
456 break;
459 case B_UINT32_TYPE:
461 fPrimitive.SetTo(fPrimitive.ToUInt32()
462 - temp.fPrimitive.ToUInt32());
463 break;
466 case B_INT64_TYPE:
468 fPrimitive.SetTo(fPrimitive.ToInt64()
469 - temp.fPrimitive.ToInt64());
470 break;
473 case B_UINT64_TYPE:
475 fPrimitive.SetTo(fPrimitive.ToUInt64()
476 - temp.fPrimitive.ToUInt64());
477 break;
480 case B_FLOAT_TYPE:
482 fPrimitive.SetTo(fPrimitive.ToFloat()
483 - temp.fPrimitive.ToFloat());
484 break;
487 case B_DOUBLE_TYPE:
489 fPrimitive.SetTo(fPrimitive.ToDouble()
490 - temp.fPrimitive.ToDouble());
491 break;
495 return *this;
498 Operand& operator/=(const Operand& rhs)
500 Operand temp = rhs;
501 _ResolveTypesIfNeeded(temp);
503 switch (fPrimitive.Type()) {
504 case B_INT8_TYPE:
506 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
507 / temp.fPrimitive.ToInt8()));
508 break;
511 case B_UINT8_TYPE:
513 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
514 / temp.fPrimitive.ToUInt8()));
515 break;
518 case B_INT16_TYPE:
520 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
521 / temp.fPrimitive.ToInt16()));
522 break;
525 case B_UINT16_TYPE:
527 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
528 / temp.fPrimitive.ToUInt16()));
529 break;
532 case B_INT32_TYPE:
534 fPrimitive.SetTo(fPrimitive.ToInt32()
535 / temp.fPrimitive.ToInt32());
536 break;
539 case B_UINT32_TYPE:
541 fPrimitive.SetTo(fPrimitive.ToUInt32()
542 / temp.fPrimitive.ToUInt32());
543 break;
546 case B_INT64_TYPE:
548 fPrimitive.SetTo(fPrimitive.ToInt64()
549 / temp.fPrimitive.ToInt64());
550 break;
553 case B_UINT64_TYPE:
555 fPrimitive.SetTo(fPrimitive.ToUInt64()
556 / temp.fPrimitive.ToUInt64());
557 break;
560 case B_FLOAT_TYPE:
562 fPrimitive.SetTo(fPrimitive.ToFloat()
563 / temp.fPrimitive.ToFloat());
564 break;
567 case B_DOUBLE_TYPE:
569 fPrimitive.SetTo(fPrimitive.ToDouble()
570 / temp.fPrimitive.ToDouble());
571 break;
575 return *this;
578 Operand& operator*=(const Operand& rhs)
580 Operand temp = rhs;
581 _ResolveTypesIfNeeded(temp);
583 switch (fPrimitive.Type()) {
584 case B_INT8_TYPE:
586 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
587 * temp.fPrimitive.ToInt8()));
588 break;
591 case B_UINT8_TYPE:
593 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
594 * temp.fPrimitive.ToUInt8()));
595 break;
598 case B_INT16_TYPE:
600 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
601 * temp.fPrimitive.ToInt16()));
602 break;
605 case B_UINT16_TYPE:
607 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
608 * temp.fPrimitive.ToUInt16()));
609 break;
612 case B_INT32_TYPE:
614 fPrimitive.SetTo(fPrimitive.ToInt32()
615 * temp.fPrimitive.ToInt32());
616 break;
619 case B_UINT32_TYPE:
621 fPrimitive.SetTo(fPrimitive.ToUInt32()
622 * temp.fPrimitive.ToUInt32());
623 break;
626 case B_INT64_TYPE:
628 fPrimitive.SetTo(fPrimitive.ToInt64()
629 * temp.fPrimitive.ToInt64());
630 break;
633 case B_UINT64_TYPE:
635 fPrimitive.SetTo(fPrimitive.ToUInt64()
636 * temp.fPrimitive.ToUInt64());
637 break;
640 case B_FLOAT_TYPE:
642 fPrimitive.SetTo(fPrimitive.ToFloat()
643 * temp.fPrimitive.ToFloat());
644 break;
647 case B_DOUBLE_TYPE:
649 fPrimitive.SetTo(fPrimitive.ToDouble()
650 * temp.fPrimitive.ToDouble());
651 break;
655 return *this;
658 Operand& operator%=(const Operand& rhs)
660 Operand temp = rhs;
661 _ResolveTypesIfNeeded(temp);
663 switch (fPrimitive.Type()) {
664 case B_INT8_TYPE:
666 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
667 % temp.fPrimitive.ToInt8()));
668 break;
671 case B_UINT8_TYPE:
673 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
674 % temp.fPrimitive.ToUInt8()));
675 break;
678 case B_INT16_TYPE:
680 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
681 % temp.fPrimitive.ToInt16()));
682 break;
685 case B_UINT16_TYPE:
687 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
688 % temp.fPrimitive.ToUInt16()));
689 break;
692 case B_INT32_TYPE:
694 fPrimitive.SetTo(fPrimitive.ToInt32()
695 % temp.fPrimitive.ToInt32());
696 break;
699 case B_UINT32_TYPE:
701 fPrimitive.SetTo(fPrimitive.ToUInt32()
702 % temp.fPrimitive.ToUInt32());
703 break;
706 case B_INT64_TYPE:
708 fPrimitive.SetTo(fPrimitive.ToInt64()
709 % temp.fPrimitive.ToInt64());
710 break;
713 case B_UINT64_TYPE:
715 fPrimitive.SetTo(fPrimitive.ToUInt64()
716 % temp.fPrimitive.ToUInt64());
717 break;
721 return *this;
724 Operand& operator&=(const Operand& rhs)
726 Operand temp = rhs;
727 _ResolveTypesIfNeeded(temp);
729 switch (fPrimitive.Type()) {
730 case B_INT8_TYPE:
732 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
733 & temp.fPrimitive.ToInt8()));
734 break;
737 case B_UINT8_TYPE:
739 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
740 & temp.fPrimitive.ToUInt8()));
741 break;
744 case B_INT16_TYPE:
746 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
747 & temp.fPrimitive.ToInt16()));
748 break;
751 case B_UINT16_TYPE:
753 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
754 & temp.fPrimitive.ToUInt16()));
755 break;
758 case B_INT32_TYPE:
760 fPrimitive.SetTo(fPrimitive.ToInt32()
761 & temp.fPrimitive.ToInt32());
762 break;
765 case B_UINT32_TYPE:
767 fPrimitive.SetTo(fPrimitive.ToUInt32()
768 & temp.fPrimitive.ToUInt32());
769 break;
772 case B_INT64_TYPE:
774 fPrimitive.SetTo(fPrimitive.ToInt64()
775 & temp.fPrimitive.ToInt64());
776 break;
779 case B_UINT64_TYPE:
781 fPrimitive.SetTo(fPrimitive.ToUInt64()
782 & temp.fPrimitive.ToUInt64());
783 break;
787 return *this;
790 Operand& operator|=(const Operand& rhs)
792 Operand temp = rhs;
793 _ResolveTypesIfNeeded(temp);
795 switch (fPrimitive.Type()) {
796 case B_INT8_TYPE:
798 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
799 | temp.fPrimitive.ToInt8()));
800 break;
803 case B_UINT8_TYPE:
805 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
806 | temp.fPrimitive.ToUInt8()));
807 break;
810 case B_INT16_TYPE:
812 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
813 | temp.fPrimitive.ToInt16()));
814 break;
817 case B_UINT16_TYPE:
819 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
820 | temp.fPrimitive.ToUInt16()));
821 break;
824 case B_INT32_TYPE:
826 fPrimitive.SetTo(fPrimitive.ToInt32()
827 | temp.fPrimitive.ToInt32());
828 break;
831 case B_UINT32_TYPE:
833 fPrimitive.SetTo(fPrimitive.ToUInt32()
834 | temp.fPrimitive.ToUInt32());
835 break;
838 case B_INT64_TYPE:
840 fPrimitive.SetTo(fPrimitive.ToInt64()
841 | temp.fPrimitive.ToInt64());
842 break;
845 case B_UINT64_TYPE:
847 fPrimitive.SetTo(fPrimitive.ToUInt64()
848 | temp.fPrimitive.ToUInt64());
849 break;
853 return *this;
856 Operand& operator^=(const Operand& rhs)
858 Operand temp = rhs;
859 _ResolveTypesIfNeeded(temp);
861 switch (fPrimitive.Type()) {
862 case B_INT8_TYPE:
864 fPrimitive.SetTo((int8)(fPrimitive.ToInt8()
865 ^ temp.fPrimitive.ToInt8()));
866 break;
869 case B_UINT8_TYPE:
871 fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8()
872 ^ temp.fPrimitive.ToUInt8()));
873 break;
876 case B_INT16_TYPE:
878 fPrimitive.SetTo((int16)(fPrimitive.ToInt16()
879 ^ temp.fPrimitive.ToInt16()));
880 break;
883 case B_UINT16_TYPE:
885 fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16()
886 ^ temp.fPrimitive.ToUInt16()));
887 break;
890 case B_INT32_TYPE:
892 fPrimitive.SetTo(fPrimitive.ToInt32()
893 ^ temp.fPrimitive.ToInt32());
894 break;
897 case B_UINT32_TYPE:
899 fPrimitive.SetTo(fPrimitive.ToUInt32()
900 ^ temp.fPrimitive.ToUInt32());
901 break;
904 case B_INT64_TYPE:
906 fPrimitive.SetTo(fPrimitive.ToInt64()
907 ^ temp.fPrimitive.ToInt64());
908 break;
911 case B_UINT64_TYPE:
913 fPrimitive.SetTo(fPrimitive.ToUInt64()
914 ^ temp.fPrimitive.ToUInt64());
915 break;
919 return *this;
922 Operand operator-() const
924 Operand value(*this);
925 value._ResolveToPrimitive();
927 switch (fPrimitive.Type()) {
928 case B_INT8_TYPE:
930 value.fPrimitive.SetTo((int8)-fPrimitive.ToInt8());
931 break;
934 case B_UINT8_TYPE:
936 value.fPrimitive.SetTo((uint8)-fPrimitive.ToUInt8());
937 break;
940 case B_INT16_TYPE:
942 value.fPrimitive.SetTo((int16)-fPrimitive.ToInt16());
943 break;
946 case B_UINT16_TYPE:
948 value.fPrimitive.SetTo((uint16)-fPrimitive.ToUInt16());
949 break;
952 case B_INT32_TYPE:
954 value.fPrimitive.SetTo(-fPrimitive.ToInt32());
955 break;
958 case B_UINT32_TYPE:
960 value.fPrimitive.SetTo(-fPrimitive.ToUInt32());
961 break;
964 case B_INT64_TYPE:
966 value.fPrimitive.SetTo(-fPrimitive.ToInt64());
967 break;
970 case B_UINT64_TYPE:
972 value.fPrimitive.SetTo(-fPrimitive.ToUInt64());
973 break;
976 case B_FLOAT_TYPE:
978 value.fPrimitive.SetTo(-fPrimitive.ToFloat());
979 break;
982 case B_DOUBLE_TYPE:
984 value.fPrimitive.SetTo(-fPrimitive.ToDouble());
985 break;
989 return value;
992 Operand operator~() const
994 Operand value(*this);
995 value._ResolveToPrimitive();
997 switch (fPrimitive.Type()) {
998 case B_INT8_TYPE:
1000 value.fPrimitive.SetTo((int8)~fPrimitive.ToInt8());
1001 break;
1004 case B_UINT8_TYPE:
1006 value.fPrimitive.SetTo((uint8)~fPrimitive.ToUInt8());
1007 break;
1010 case B_INT16_TYPE:
1012 value.fPrimitive.SetTo((int16)~fPrimitive.ToInt16());
1013 break;
1016 case B_UINT16_TYPE:
1018 value.fPrimitive.SetTo((uint16)~fPrimitive.ToUInt16());
1019 break;
1022 case B_INT32_TYPE:
1024 value.fPrimitive.SetTo(~fPrimitive.ToInt32());
1025 break;
1028 case B_UINT32_TYPE:
1030 value.fPrimitive.SetTo(~fPrimitive.ToUInt32());
1031 break;
1034 case B_INT64_TYPE:
1036 value.fPrimitive.SetTo(~fPrimitive.ToInt64());
1037 break;
1040 case B_UINT64_TYPE:
1042 value.fPrimitive.SetTo(~fPrimitive.ToUInt64());
1043 break;
1047 return value;
1050 int operator<(const Operand& rhs) const
1052 Operand lhs = *this;
1053 Operand temp = rhs;
1055 lhs._ResolveTypesIfNeeded(temp);
1057 int result = 0;
1058 switch (fPrimitive.Type()) {
1059 case B_INT8_TYPE:
1061 result = lhs.fPrimitive.ToInt8() < temp.fPrimitive.ToInt8();
1062 break;
1065 case B_UINT8_TYPE:
1067 result = lhs.fPrimitive.ToUInt8() < temp.fPrimitive.ToUInt8();
1068 break;
1071 case B_INT16_TYPE:
1073 result = lhs.fPrimitive.ToInt16() < temp.fPrimitive.ToInt16();
1074 break;
1077 case B_UINT16_TYPE:
1079 result = lhs.fPrimitive.ToUInt16()
1080 < temp.fPrimitive.ToUInt16();
1081 break;
1084 case B_INT32_TYPE:
1086 result = lhs.fPrimitive.ToInt32() < temp.fPrimitive.ToInt32();
1087 break;
1090 case B_UINT32_TYPE:
1092 result = lhs.fPrimitive.ToUInt32()
1093 < temp.fPrimitive.ToUInt32();
1094 break;
1097 case B_INT64_TYPE:
1099 result = lhs.fPrimitive.ToInt64() < temp.fPrimitive.ToInt64();
1100 break;
1103 case B_UINT64_TYPE:
1105 result = lhs.fPrimitive.ToUInt64()
1106 < temp.fPrimitive.ToUInt64();
1107 break;
1110 case B_FLOAT_TYPE:
1112 result = lhs.fPrimitive.ToFloat() < temp.fPrimitive.ToFloat();
1113 break;
1116 case B_DOUBLE_TYPE:
1118 result = lhs.fPrimitive.ToDouble()
1119 < temp.fPrimitive.ToDouble();
1120 break;
1124 return result;
1127 int operator<=(const Operand& rhs) const
1129 return (*this < rhs) || (*this == rhs);
1132 int operator>(const Operand& rhs) const
1134 Operand lhs = *this;
1135 Operand temp = rhs;
1136 lhs._ResolveTypesIfNeeded(temp);
1138 int result = 0;
1139 switch (fPrimitive.Type()) {
1140 case B_INT8_TYPE:
1142 result = lhs.fPrimitive.ToInt8() > temp.fPrimitive.ToInt8();
1143 break;
1146 case B_UINT8_TYPE:
1148 result = lhs.fPrimitive.ToUInt8() > temp.fPrimitive.ToUInt8();
1149 break;
1152 case B_INT16_TYPE:
1154 result = lhs.fPrimitive.ToInt16() > temp.fPrimitive.ToInt16();
1155 break;
1158 case B_UINT16_TYPE:
1160 result = lhs.fPrimitive.ToUInt16()
1161 > temp.fPrimitive.ToUInt16();
1162 break;
1165 case B_INT32_TYPE:
1167 result = lhs.fPrimitive.ToInt32() > temp.fPrimitive.ToInt32();
1168 break;
1171 case B_UINT32_TYPE:
1173 result = lhs.fPrimitive.ToUInt32()
1174 > temp.fPrimitive.ToUInt32();
1175 break;
1178 case B_INT64_TYPE:
1180 result = lhs.fPrimitive.ToInt64() > temp.fPrimitive.ToInt64();
1181 break;
1184 case B_UINT64_TYPE:
1186 result = lhs.fPrimitive.ToUInt64()
1187 > temp.fPrimitive.ToUInt64();
1188 break;
1191 case B_FLOAT_TYPE:
1193 result = lhs.fPrimitive.ToFloat() > temp.fPrimitive.ToFloat();
1194 break;
1197 case B_DOUBLE_TYPE:
1199 result = lhs.fPrimitive.ToDouble()
1200 > temp.fPrimitive.ToDouble();
1201 break;
1205 return result;
1208 int operator>=(const Operand& rhs) const
1210 return (*this > rhs) || (*this == rhs);
1213 int operator==(const Operand& rhs) const
1215 Operand lhs = *this;
1216 Operand temp = rhs;
1217 lhs._ResolveTypesIfNeeded(temp);
1219 int result = 0;
1220 switch (fPrimitive.Type()) {
1221 case B_INT8_TYPE:
1223 result = lhs.fPrimitive.ToInt8() == temp.fPrimitive.ToInt8();
1224 break;
1227 case B_UINT8_TYPE:
1229 result = lhs.fPrimitive.ToUInt8() == temp.fPrimitive.ToUInt8();
1230 break;
1233 case B_INT16_TYPE:
1235 result = lhs.fPrimitive.ToInt16() == temp.fPrimitive.ToInt16();
1236 break;
1239 case B_UINT16_TYPE:
1241 result = lhs.fPrimitive.ToUInt16()
1242 == temp.fPrimitive.ToUInt16();
1243 break;
1246 case B_INT32_TYPE:
1248 result = lhs.fPrimitive.ToInt32() == temp.fPrimitive.ToInt32();
1249 break;
1252 case B_UINT32_TYPE:
1254 result = lhs.fPrimitive.ToUInt32()
1255 == temp.fPrimitive.ToUInt32();
1256 break;
1259 case B_INT64_TYPE:
1261 result = lhs.fPrimitive.ToInt64() == temp.fPrimitive.ToInt64();
1262 break;
1265 case B_UINT64_TYPE:
1267 result = lhs.fPrimitive.ToUInt64()
1268 == temp.fPrimitive.ToUInt64();
1269 break;
1272 case B_FLOAT_TYPE:
1274 result = lhs.fPrimitive.ToFloat() == temp.fPrimitive.ToFloat();
1275 break;
1278 case B_DOUBLE_TYPE:
1280 result = lhs.fPrimitive.ToDouble()
1281 == temp.fPrimitive.ToDouble();
1282 break;
1286 return result;
1289 int operator!=(const Operand& rhs) const
1291 return !(*this == rhs);
1294 private:
1295 void _GetAsType(type_code type)
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;
1331 void _ResolveTypesIfNeeded(Operand& other)
1333 _ResolveToPrimitive();
1334 other._ResolveToPrimitive();
1336 if (!fPrimitive.IsNumber() || !other.fPrimitive.IsNumber()) {
1337 throw ParseException("Cannot perform mathematical operations "
1338 "between non-numerical objects.", 0);
1341 type_code thisType = fPrimitive.Type();
1342 type_code otherType = other.fPrimitive.Type();
1344 if (thisType == otherType)
1345 return;
1347 type_code resolvedType = _ResolvePriorityType(thisType, otherType);
1348 if (thisType != resolvedType)
1349 _GetAsType(resolvedType);
1351 if (otherType != resolvedType)
1352 other._GetAsType(resolvedType);
1355 void _ResolveToPrimitive()
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);
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);
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);
1384 type_code _ResolvePriorityType(type_code lhs, type_code rhs) const
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);
1397 if (isFloat) {
1398 if (byteSize == sizeof(float))
1399 return B_FLOAT_TYPE;
1400 return B_DOUBLE_TYPE;
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;
1416 BString error;
1417 error.SetToFormat("Unable to reconcile types %#" B_PRIx32
1418 " and %#" B_PRIx32, lhs, rhs);
1419 throw ParseException(error.String(), 0);
1422 private:
1423 BVariant fPrimitive;
1424 ValueNode* fValueNode;
1425 Type* fType;
1426 operand_kind fKind;
1430 // #pragma mark - CLanguageExpressionEvaluator
1433 CLanguageExpressionEvaluator::CLanguageExpressionEvaluator()
1435 fTokenizer(new Tokenizer()),
1436 fTypeInfo(NULL),
1437 fNodeManager(NULL)
1442 CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator()
1444 delete fTokenizer;
1448 ExpressionResult*
1449 CLanguageExpressionEvaluator::Evaluate(const char* expressionString,
1450 ValueNodeManager* manager, TeamTypeInformation* info)
1452 fNodeManager = manager;
1453 fTypeInfo = info;
1454 fTokenizer->SetTo(expressionString);
1456 Operand value = _ParseSum();
1457 Token token = fTokenizer->NextToken();
1458 if (token.type != TOKEN_END_OF_LINE)
1459 throw ParseException("parse error", token.position);
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());
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());
1485 resultReference.Detach();
1488 return result;
1492 CLanguageExpressionEvaluator::Operand
1493 CLanguageExpressionEvaluator::_ParseSum()
1495 Operand value = _ParseProduct();
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;
1507 default:
1508 fTokenizer->RewindToken();
1509 return value;
1515 CLanguageExpressionEvaluator::Operand
1516 CLanguageExpressionEvaluator::_ParseProduct()
1518 static Operand zero(int64(0LL));
1520 Operand value = _ParseUnary();
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:
1530 Operand rhs = _ParseUnary();
1531 if (rhs == zero)
1532 throw ParseException("division by zero", token.position);
1533 value /= rhs;
1534 break;
1537 case TOKEN_MODULO:
1539 Operand rhs = _ParseUnary();
1540 if (rhs == zero)
1541 throw ParseException("modulo by zero", token.position);
1542 value %= rhs;
1543 break;
1546 case TOKEN_LOGICAL_AND:
1548 value.SetTo((value != zero)
1549 && (_ParseUnary() != zero));
1551 break;
1554 case TOKEN_LOGICAL_OR:
1556 value.SetTo((value != zero)
1557 || (_ParseUnary() != zero));
1558 break;
1561 case TOKEN_BITWISE_AND:
1562 value &= _ParseUnary();
1563 break;
1565 case TOKEN_BITWISE_OR:
1566 value |= _ParseUnary();
1567 break;
1569 case TOKEN_BITWISE_XOR:
1570 value ^= _ParseUnary();
1571 break;
1573 case TOKEN_EQ:
1574 value.SetTo((int64)(value == _ParseUnary()));
1575 break;
1577 case TOKEN_NE:
1578 value.SetTo((int64)(value != _ParseUnary()));
1579 break;
1581 case TOKEN_GT:
1582 value.SetTo((int64)(value > _ParseUnary()));
1583 break;
1585 case TOKEN_GE:
1586 value.SetTo((int64)(value >= _ParseUnary()));
1587 break;
1589 case TOKEN_LT:
1590 value.SetTo((int64)(value < _ParseUnary()));
1591 break;
1593 case TOKEN_LE:
1594 value.SetTo((int64)(value <= _ParseUnary()));
1595 break;
1597 default:
1598 fTokenizer->RewindToken();
1599 return value;
1605 CLanguageExpressionEvaluator::Operand
1606 CLanguageExpressionEvaluator::_ParseUnary()
1608 Token token = fTokenizer->NextToken();
1609 if (token.type == TOKEN_END_OF_LINE)
1610 throw ParseException("unexpected end of expression", token.position);
1612 switch (token.type) {
1613 case TOKEN_PLUS:
1614 return _ParseUnary();
1616 case TOKEN_MINUS:
1617 return -_ParseUnary();
1619 case TOKEN_BITWISE_NOT:
1620 return ~_ParseUnary();
1622 case TOKEN_LOGICAL_NOT:
1624 Operand zero((int64)0);
1625 return Operand((int64)(_ParseUnary() == zero));
1628 case TOKEN_IDENTIFIER:
1629 fTokenizer->RewindToken();
1630 return _ParseIdentifier();
1632 default:
1633 fTokenizer->RewindToken();
1634 return _ParseAtom();
1637 return Operand();
1641 CLanguageExpressionEvaluator::Operand
1642 CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode)
1644 Token token = fTokenizer->NextToken();
1645 const BString& identifierName = token.string;
1647 ValueNodeChild* child = NULL;
1648 if (fNodeManager != NULL) {
1649 ValueNodeContainer* container = fNodeManager->GetContainer();
1650 AutoLocker<ValueNodeContainer> containerLocker(container);
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;
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);
1673 } else {
1674 // skip intermediate address nodes
1675 if (parentNode->GetType()->Kind() == TYPE_ADDRESS
1676 && parentNode->CountChildren() == 1) {
1677 child = parentNode->ChildAt(0);
1679 _RequestValueIfNeeded(token, child);
1680 parentNode = child->Node();
1681 fTokenizer->RewindToken();
1682 return _ParseIdentifier(parentNode);
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;
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);
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);
1718 _RequestValueIfNeeded(token, child);
1719 ValueNode* node = child->Node();
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);
1731 } else
1732 fTokenizer->RewindToken();
1734 return Operand(node);
1738 CLanguageExpressionEvaluator::Operand
1739 CLanguageExpressionEvaluator::_ParseAtom()
1741 Token token = fTokenizer->NextToken();
1742 if (token.type == TOKEN_END_OF_LINE)
1743 throw ParseException("Unexpected end of expression", token.position);
1745 Operand value;
1747 if (token.type == TOKEN_CONSTANT)
1748 value.SetTo(token.value);
1749 else {
1750 fTokenizer->RewindToken();
1752 _EatToken(TOKEN_OPENING_PAREN);
1754 value = _ParseSum();
1756 _EatToken(TOKEN_CLOSING_PAREN);
1759 if (value.Kind() == OPERAND_KIND_TYPE) {
1760 token = fTokenizer->NextToken();
1761 if (token.type == TOKEN_END_OF_LINE)
1762 return value;
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);
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);
1783 ValueNode* newNode = NULL;
1784 status_t error = TypeHandlerRoster::Default()->CreateValueNode(child,
1785 castType, newNode);
1786 if (error != B_OK) {
1787 throw ParseException("Unable to create value node for typecast"
1788 " operation.", token.position);
1790 child->SetNode(newNode);
1791 value.SetTo(newNode);
1794 return value;
1798 void
1799 CLanguageExpressionEvaluator::_EatToken(int32 type)
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;
1809 case TOKEN_CONSTANT:
1810 expected = "a constant";
1811 break;
1813 case TOKEN_SLASH:
1814 expected = "'/', '\\', or ':'";
1815 break;
1817 case TOKEN_END_OF_LINE:
1818 expected = "'\\n'";
1819 break;
1821 default:
1822 expected << "'" << TokenTypeToString(type) << "'";
1823 break;
1826 BString temp;
1827 temp << "Expected " << expected.String() << " got '" << token.string
1828 << "'";
1829 throw ParseException(temp.String(), token.position);
1834 CLanguageExpressionEvaluator::Operand
1835 CLanguageExpressionEvaluator::_ParseType(Type* baseType)
1837 BReference<Type> typeReference;
1838 Type* finalType = baseType;
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;
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);
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);
1871 _EatToken(TOKEN_CLOSING_SQUARE_BRACKET);
1873 uint32 resolvedSize = indexSize.PrimitiveValue().ToUInt32();
1874 if (resolvedSize == 0) {
1875 throw ParseException("Non-zero array size required in type"
1876 " specifier.", token.position);
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);
1891 arraySpecifierEncountered = true;
1892 finalType = derivedType;
1893 typeReference.SetTo(finalType, true);
1894 } else
1895 break;
1898 typeReference.Detach();
1899 fTokenizer->RewindToken();
1900 return Operand(finalType);
1904 void
1905 CLanguageExpressionEvaluator::_RequestValueIfNeeded(
1906 const Token& token, ValueNodeChild* child)
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);
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);
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);
1940 void
1941 CLanguageExpressionEvaluator::_GetNodeChildForPrimitive(const Token& token,
1942 const BVariant& value, ValueNodeChild*& _output) const
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);
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);
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);
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);
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);
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);
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);