2 * Copyright 2006-2014 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
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"
16 #include "AutoLocker.h"
18 #include "CLanguageTokenizer.h"
19 #include "ExpressionInfo.h"
20 #include "FloatValue.h"
21 #include "IntegerFormatter.h"
22 #include "IntegerValue.h"
24 #include "StackFrame.h"
25 #include "SyntheticPrimitiveType.h"
26 #include "TeamTypeInformation.h"
29 #include "TypeHandlerRoster.h"
30 #include "TypeLookupConstraints.h"
32 #include "ValueLocation.h"
33 #include "ValueNode.h"
34 #include "ValueNodeManager.h"
36 #include "VariableValueNodeChild.h"
39 using namespace CLanguage
;
43 OPERAND_KIND_UNKNOWN
= 0,
44 OPERAND_KIND_PRIMITIVE
,
46 OPERAND_KIND_VALUE_NODE
50 static BString
TokenTypeToString(int32 type
)
75 case TOKEN_OPENING_PAREN
:
79 case TOKEN_CLOSING_PAREN
:
83 case TOKEN_LOGICAL_AND
:
87 case TOKEN_LOGICAL_OR
:
91 case TOKEN_LOGICAL_NOT
:
95 case TOKEN_BITWISE_AND
:
99 case TOKEN_BITWISE_OR
:
103 case TOKEN_BITWISE_NOT
:
107 case TOKEN_BITWISE_XOR
:
135 case TOKEN_MEMBER_PTR
:
140 token
.SetToFormat("Unknown token type %" B_PRId32
, type
);
148 // #pragma mark - CLanguageExpressionEvaluator::InternalVariableID
151 class CLanguageExpressionEvaluator::InternalVariableID
: public ObjectID
{
153 InternalVariableID(const BVariant
& value
)
159 virtual ~InternalVariableID()
163 virtual bool operator==(const ObjectID
& other
) const
165 const InternalVariableID
* otherID
166 = dynamic_cast<const InternalVariableID
*>(&other
);
170 return fValue
== otherID
->fValue
;
174 virtual uint32
ComputeHashValue() const
176 return *(uint32
*)(&fValue
);
184 // #pragma mark - CLanguageExpressionEvaluator::Operand
187 class CLanguageExpressionEvaluator::Operand
{
194 fKind(OPERAND_KIND_UNKNOWN
)
203 fKind(OPERAND_KIND_PRIMITIVE
)
207 Operand(double value
)
212 fKind(OPERAND_KIND_PRIMITIVE
)
216 Operand(ValueNode
* node
)
221 fKind(OPERAND_KIND_UNKNOWN
)
231 fKind(OPERAND_KIND_UNKNOWN
)
236 Operand(const Operand
& X
)
241 fKind(OPERAND_KIND_UNKNOWN
)
252 Operand
& operator=(const Operand
& X
)
255 case OPERAND_KIND_UNKNOWN
:
259 case OPERAND_KIND_PRIMITIVE
:
263 case OPERAND_KIND_VALUE_NODE
:
267 case OPERAND_KIND_TYPE
:
275 void SetTo(const BVariant
& value
)
279 fKind
= OPERAND_KIND_PRIMITIVE
;
282 void SetTo(ValueNode
* node
)
286 fValueNode
->AcquireReference();
288 Value
* value
= node
->GetValue();
290 value
->ToVariant(fPrimitive
);
292 fKind
= OPERAND_KIND_VALUE_NODE
;
295 void SetTo(Type
* type
)
299 fType
->AcquireReference();
301 fKind
= OPERAND_KIND_TYPE
;
306 if (fValueNode
!= NULL
)
307 fValueNode
->ReleaseReference();
310 fType
->ReleaseReference();
314 fKind
= OPERAND_KIND_UNKNOWN
;
317 inline operand_kind
Kind() const
322 inline const BVariant
& PrimitiveValue() const
327 inline ValueNode
* GetValueNode() const
333 inline Type
* GetType() const
338 Operand
& operator+=(const Operand
& rhs
)
341 _ResolveTypesIfNeeded(temp
);
343 switch (fPrimitive
.Type()) {
346 fPrimitive
.SetTo((int8
)(fPrimitive
.ToInt8()
347 + temp
.fPrimitive
.ToInt8()));
353 fPrimitive
.SetTo((uint8
)(fPrimitive
.ToUInt8()
354 + temp
.fPrimitive
.ToUInt8()));
360 fPrimitive
.SetTo((int16
)(fPrimitive
.ToInt16()
361 + temp
.fPrimitive
.ToInt16()));
367 fPrimitive
.SetTo((uint16
)(fPrimitive
.ToUInt16()
368 + temp
.fPrimitive
.ToUInt16()));
374 fPrimitive
.SetTo(fPrimitive
.ToInt32()
375 + temp
.fPrimitive
.ToInt32());
381 fPrimitive
.SetTo(fPrimitive
.ToUInt32()
382 + temp
.fPrimitive
.ToUInt32());
388 fPrimitive
.SetTo(fPrimitive
.ToInt64()
389 + temp
.fPrimitive
.ToInt64());
395 fPrimitive
.SetTo(fPrimitive
.ToUInt64()
396 + temp
.fPrimitive
.ToUInt64());
402 fPrimitive
.SetTo(fPrimitive
.ToFloat()
403 + temp
.fPrimitive
.ToFloat());
409 fPrimitive
.SetTo(fPrimitive
.ToDouble()
410 + temp
.fPrimitive
.ToDouble());
418 Operand
& operator-=(const Operand
& rhs
)
421 _ResolveTypesIfNeeded(temp
);
423 switch (fPrimitive
.Type()) {
426 fPrimitive
.SetTo((int8
)(fPrimitive
.ToInt8()
427 - temp
.fPrimitive
.ToInt8()));
433 fPrimitive
.SetTo((uint8
)(fPrimitive
.ToUInt8()
434 - temp
.fPrimitive
.ToUInt8()));
440 fPrimitive
.SetTo((int16
)(fPrimitive
.ToInt16()
441 - temp
.fPrimitive
.ToInt16()));
447 fPrimitive
.SetTo((uint16
)(fPrimitive
.ToUInt16()
448 - temp
.fPrimitive
.ToUInt16()));
454 fPrimitive
.SetTo(fPrimitive
.ToInt32()
455 - temp
.fPrimitive
.ToInt32());
461 fPrimitive
.SetTo(fPrimitive
.ToUInt32()
462 - temp
.fPrimitive
.ToUInt32());
468 fPrimitive
.SetTo(fPrimitive
.ToInt64()
469 - temp
.fPrimitive
.ToInt64());
475 fPrimitive
.SetTo(fPrimitive
.ToUInt64()
476 - temp
.fPrimitive
.ToUInt64());
482 fPrimitive
.SetTo(fPrimitive
.ToFloat()
483 - temp
.fPrimitive
.ToFloat());
489 fPrimitive
.SetTo(fPrimitive
.ToDouble()
490 - temp
.fPrimitive
.ToDouble());
498 Operand
& operator/=(const Operand
& rhs
)
501 _ResolveTypesIfNeeded(temp
);
503 switch (fPrimitive
.Type()) {
506 fPrimitive
.SetTo((int8
)(fPrimitive
.ToInt8()
507 / temp
.fPrimitive
.ToInt8()));
513 fPrimitive
.SetTo((uint8
)(fPrimitive
.ToUInt8()
514 / temp
.fPrimitive
.ToUInt8()));
520 fPrimitive
.SetTo((int16
)(fPrimitive
.ToInt16()
521 / temp
.fPrimitive
.ToInt16()));
527 fPrimitive
.SetTo((uint16
)(fPrimitive
.ToUInt16()
528 / temp
.fPrimitive
.ToUInt16()));
534 fPrimitive
.SetTo(fPrimitive
.ToInt32()
535 / temp
.fPrimitive
.ToInt32());
541 fPrimitive
.SetTo(fPrimitive
.ToUInt32()
542 / temp
.fPrimitive
.ToUInt32());
548 fPrimitive
.SetTo(fPrimitive
.ToInt64()
549 / temp
.fPrimitive
.ToInt64());
555 fPrimitive
.SetTo(fPrimitive
.ToUInt64()
556 / temp
.fPrimitive
.ToUInt64());
562 fPrimitive
.SetTo(fPrimitive
.ToFloat()
563 / temp
.fPrimitive
.ToFloat());
569 fPrimitive
.SetTo(fPrimitive
.ToDouble()
570 / temp
.fPrimitive
.ToDouble());
578 Operand
& operator*=(const Operand
& rhs
)
581 _ResolveTypesIfNeeded(temp
);
583 switch (fPrimitive
.Type()) {
586 fPrimitive
.SetTo((int8
)(fPrimitive
.ToInt8()
587 * temp
.fPrimitive
.ToInt8()));
593 fPrimitive
.SetTo((uint8
)(fPrimitive
.ToUInt8()
594 * temp
.fPrimitive
.ToUInt8()));
600 fPrimitive
.SetTo((int16
)(fPrimitive
.ToInt16()
601 * temp
.fPrimitive
.ToInt16()));
607 fPrimitive
.SetTo((uint16
)(fPrimitive
.ToUInt16()
608 * temp
.fPrimitive
.ToUInt16()));
614 fPrimitive
.SetTo(fPrimitive
.ToInt32()
615 * temp
.fPrimitive
.ToInt32());
621 fPrimitive
.SetTo(fPrimitive
.ToUInt32()
622 * temp
.fPrimitive
.ToUInt32());
628 fPrimitive
.SetTo(fPrimitive
.ToInt64()
629 * temp
.fPrimitive
.ToInt64());
635 fPrimitive
.SetTo(fPrimitive
.ToUInt64()
636 * temp
.fPrimitive
.ToUInt64());
642 fPrimitive
.SetTo(fPrimitive
.ToFloat()
643 * temp
.fPrimitive
.ToFloat());
649 fPrimitive
.SetTo(fPrimitive
.ToDouble()
650 * temp
.fPrimitive
.ToDouble());
658 Operand
& operator%=(const Operand
& rhs
)
661 _ResolveTypesIfNeeded(temp
);
663 switch (fPrimitive
.Type()) {
666 fPrimitive
.SetTo((int8
)(fPrimitive
.ToInt8()
667 % temp
.fPrimitive
.ToInt8()));
673 fPrimitive
.SetTo((uint8
)(fPrimitive
.ToUInt8()
674 % temp
.fPrimitive
.ToUInt8()));
680 fPrimitive
.SetTo((int16
)(fPrimitive
.ToInt16()
681 % temp
.fPrimitive
.ToInt16()));
687 fPrimitive
.SetTo((uint16
)(fPrimitive
.ToUInt16()
688 % temp
.fPrimitive
.ToUInt16()));
694 fPrimitive
.SetTo(fPrimitive
.ToInt32()
695 % temp
.fPrimitive
.ToInt32());
701 fPrimitive
.SetTo(fPrimitive
.ToUInt32()
702 % temp
.fPrimitive
.ToUInt32());
708 fPrimitive
.SetTo(fPrimitive
.ToInt64()
709 % temp
.fPrimitive
.ToInt64());
715 fPrimitive
.SetTo(fPrimitive
.ToUInt64()
716 % temp
.fPrimitive
.ToUInt64());
724 Operand
& operator&=(const Operand
& rhs
)
727 _ResolveTypesIfNeeded(temp
);
729 switch (fPrimitive
.Type()) {
732 fPrimitive
.SetTo((int8
)(fPrimitive
.ToInt8()
733 & temp
.fPrimitive
.ToInt8()));
739 fPrimitive
.SetTo((uint8
)(fPrimitive
.ToUInt8()
740 & temp
.fPrimitive
.ToUInt8()));
746 fPrimitive
.SetTo((int16
)(fPrimitive
.ToInt16()
747 & temp
.fPrimitive
.ToInt16()));
753 fPrimitive
.SetTo((uint16
)(fPrimitive
.ToUInt16()
754 & temp
.fPrimitive
.ToUInt16()));
760 fPrimitive
.SetTo(fPrimitive
.ToInt32()
761 & temp
.fPrimitive
.ToInt32());
767 fPrimitive
.SetTo(fPrimitive
.ToUInt32()
768 & temp
.fPrimitive
.ToUInt32());
774 fPrimitive
.SetTo(fPrimitive
.ToInt64()
775 & temp
.fPrimitive
.ToInt64());
781 fPrimitive
.SetTo(fPrimitive
.ToUInt64()
782 & temp
.fPrimitive
.ToUInt64());
790 Operand
& operator|=(const Operand
& rhs
)
793 _ResolveTypesIfNeeded(temp
);
795 switch (fPrimitive
.Type()) {
798 fPrimitive
.SetTo((int8
)(fPrimitive
.ToInt8()
799 | temp
.fPrimitive
.ToInt8()));
805 fPrimitive
.SetTo((uint8
)(fPrimitive
.ToUInt8()
806 | temp
.fPrimitive
.ToUInt8()));
812 fPrimitive
.SetTo((int16
)(fPrimitive
.ToInt16()
813 | temp
.fPrimitive
.ToInt16()));
819 fPrimitive
.SetTo((uint16
)(fPrimitive
.ToUInt16()
820 | temp
.fPrimitive
.ToUInt16()));
826 fPrimitive
.SetTo(fPrimitive
.ToInt32()
827 | temp
.fPrimitive
.ToInt32());
833 fPrimitive
.SetTo(fPrimitive
.ToUInt32()
834 | temp
.fPrimitive
.ToUInt32());
840 fPrimitive
.SetTo(fPrimitive
.ToInt64()
841 | temp
.fPrimitive
.ToInt64());
847 fPrimitive
.SetTo(fPrimitive
.ToUInt64()
848 | temp
.fPrimitive
.ToUInt64());
856 Operand
& operator^=(const Operand
& rhs
)
859 _ResolveTypesIfNeeded(temp
);
861 switch (fPrimitive
.Type()) {
864 fPrimitive
.SetTo((int8
)(fPrimitive
.ToInt8()
865 ^ temp
.fPrimitive
.ToInt8()));
871 fPrimitive
.SetTo((uint8
)(fPrimitive
.ToUInt8()
872 ^ temp
.fPrimitive
.ToUInt8()));
878 fPrimitive
.SetTo((int16
)(fPrimitive
.ToInt16()
879 ^ temp
.fPrimitive
.ToInt16()));
885 fPrimitive
.SetTo((uint16
)(fPrimitive
.ToUInt16()
886 ^ temp
.fPrimitive
.ToUInt16()));
892 fPrimitive
.SetTo(fPrimitive
.ToInt32()
893 ^ temp
.fPrimitive
.ToInt32());
899 fPrimitive
.SetTo(fPrimitive
.ToUInt32()
900 ^ temp
.fPrimitive
.ToUInt32());
906 fPrimitive
.SetTo(fPrimitive
.ToInt64()
907 ^ temp
.fPrimitive
.ToInt64());
913 fPrimitive
.SetTo(fPrimitive
.ToUInt64()
914 ^ temp
.fPrimitive
.ToUInt64());
922 Operand
operator-() const
924 Operand
value(*this);
925 value
._ResolveToPrimitive();
927 switch (fPrimitive
.Type()) {
930 value
.fPrimitive
.SetTo((int8
)-fPrimitive
.ToInt8());
936 value
.fPrimitive
.SetTo((uint8
)-fPrimitive
.ToUInt8());
942 value
.fPrimitive
.SetTo((int16
)-fPrimitive
.ToInt16());
948 value
.fPrimitive
.SetTo((uint16
)-fPrimitive
.ToUInt16());
954 value
.fPrimitive
.SetTo(-fPrimitive
.ToInt32());
960 value
.fPrimitive
.SetTo(-fPrimitive
.ToUInt32());
966 value
.fPrimitive
.SetTo(-fPrimitive
.ToInt64());
972 value
.fPrimitive
.SetTo(-fPrimitive
.ToUInt64());
978 value
.fPrimitive
.SetTo(-fPrimitive
.ToFloat());
984 value
.fPrimitive
.SetTo(-fPrimitive
.ToDouble());
992 Operand
operator~() const
994 Operand
value(*this);
995 value
._ResolveToPrimitive();
997 switch (fPrimitive
.Type()) {
1000 value
.fPrimitive
.SetTo((int8
)~fPrimitive
.ToInt8());
1006 value
.fPrimitive
.SetTo((uint8
)~fPrimitive
.ToUInt8());
1012 value
.fPrimitive
.SetTo((int16
)~fPrimitive
.ToInt16());
1018 value
.fPrimitive
.SetTo((uint16
)~fPrimitive
.ToUInt16());
1024 value
.fPrimitive
.SetTo(~fPrimitive
.ToInt32());
1030 value
.fPrimitive
.SetTo(~fPrimitive
.ToUInt32());
1036 value
.fPrimitive
.SetTo(~fPrimitive
.ToInt64());
1042 value
.fPrimitive
.SetTo(~fPrimitive
.ToUInt64());
1050 int operator<(const Operand
& rhs
) const
1052 Operand lhs
= *this;
1055 lhs
._ResolveTypesIfNeeded(temp
);
1058 switch (fPrimitive
.Type()) {
1061 result
= lhs
.fPrimitive
.ToInt8() < temp
.fPrimitive
.ToInt8();
1067 result
= lhs
.fPrimitive
.ToUInt8() < temp
.fPrimitive
.ToUInt8();
1073 result
= lhs
.fPrimitive
.ToInt16() < temp
.fPrimitive
.ToInt16();
1079 result
= lhs
.fPrimitive
.ToUInt16()
1080 < temp
.fPrimitive
.ToUInt16();
1086 result
= lhs
.fPrimitive
.ToInt32() < temp
.fPrimitive
.ToInt32();
1092 result
= lhs
.fPrimitive
.ToUInt32()
1093 < temp
.fPrimitive
.ToUInt32();
1099 result
= lhs
.fPrimitive
.ToInt64() < temp
.fPrimitive
.ToInt64();
1105 result
= lhs
.fPrimitive
.ToUInt64()
1106 < temp
.fPrimitive
.ToUInt64();
1112 result
= lhs
.fPrimitive
.ToFloat() < temp
.fPrimitive
.ToFloat();
1118 result
= lhs
.fPrimitive
.ToDouble()
1119 < temp
.fPrimitive
.ToDouble();
1127 int operator<=(const Operand
& rhs
) const
1129 return (*this < rhs
) || (*this == rhs
);
1132 int operator>(const Operand
& rhs
) const
1134 Operand lhs
= *this;
1136 lhs
._ResolveTypesIfNeeded(temp
);
1139 switch (fPrimitive
.Type()) {
1142 result
= lhs
.fPrimitive
.ToInt8() > temp
.fPrimitive
.ToInt8();
1148 result
= lhs
.fPrimitive
.ToUInt8() > temp
.fPrimitive
.ToUInt8();
1154 result
= lhs
.fPrimitive
.ToInt16() > temp
.fPrimitive
.ToInt16();
1160 result
= lhs
.fPrimitive
.ToUInt16()
1161 > temp
.fPrimitive
.ToUInt16();
1167 result
= lhs
.fPrimitive
.ToInt32() > temp
.fPrimitive
.ToInt32();
1173 result
= lhs
.fPrimitive
.ToUInt32()
1174 > temp
.fPrimitive
.ToUInt32();
1180 result
= lhs
.fPrimitive
.ToInt64() > temp
.fPrimitive
.ToInt64();
1186 result
= lhs
.fPrimitive
.ToUInt64()
1187 > temp
.fPrimitive
.ToUInt64();
1193 result
= lhs
.fPrimitive
.ToFloat() > temp
.fPrimitive
.ToFloat();
1199 result
= lhs
.fPrimitive
.ToDouble()
1200 > temp
.fPrimitive
.ToDouble();
1208 int operator>=(const Operand
& rhs
) const
1210 return (*this > rhs
) || (*this == rhs
);
1213 int operator==(const Operand
& rhs
) const
1215 Operand lhs
= *this;
1217 lhs
._ResolveTypesIfNeeded(temp
);
1220 switch (fPrimitive
.Type()) {
1223 result
= lhs
.fPrimitive
.ToInt8() == temp
.fPrimitive
.ToInt8();
1229 result
= lhs
.fPrimitive
.ToUInt8() == temp
.fPrimitive
.ToUInt8();
1235 result
= lhs
.fPrimitive
.ToInt16() == temp
.fPrimitive
.ToInt16();
1241 result
= lhs
.fPrimitive
.ToUInt16()
1242 == temp
.fPrimitive
.ToUInt16();
1248 result
= lhs
.fPrimitive
.ToInt32() == temp
.fPrimitive
.ToInt32();
1254 result
= lhs
.fPrimitive
.ToUInt32()
1255 == temp
.fPrimitive
.ToUInt32();
1261 result
= lhs
.fPrimitive
.ToInt64() == temp
.fPrimitive
.ToInt64();
1267 result
= lhs
.fPrimitive
.ToUInt64()
1268 == temp
.fPrimitive
.ToUInt64();
1274 result
= lhs
.fPrimitive
.ToFloat() == temp
.fPrimitive
.ToFloat();
1280 result
= lhs
.fPrimitive
.ToDouble()
1281 == temp
.fPrimitive
.ToDouble();
1289 int operator!=(const Operand
& rhs
) const
1291 return !(*this == rhs
);
1295 void _GetAsType(type_code type
)
1299 fPrimitive
.SetTo(fPrimitive
.ToInt8());
1302 fPrimitive
.SetTo(fPrimitive
.ToUInt8());
1305 fPrimitive
.SetTo(fPrimitive
.ToInt16());
1308 fPrimitive
.SetTo(fPrimitive
.ToUInt16());
1311 fPrimitive
.SetTo(fPrimitive
.ToInt32());
1314 fPrimitive
.SetTo(fPrimitive
.ToUInt32());
1317 fPrimitive
.SetTo(fPrimitive
.ToInt64());
1320 fPrimitive
.SetTo(fPrimitive
.ToUInt64());
1323 fPrimitive
.SetTo(fPrimitive
.ToFloat());
1326 fPrimitive
.SetTo(fPrimitive
.ToDouble());
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
)
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
)
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();
1374 if (value
->ToVariant(tempValue
))
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
;
1392 BVariant::TypeIsInteger(lhs
, &isSigned
);
1394 BVariant::TypeIsInteger(rhs
, &isSigned
);
1398 if (byteSize
== sizeof(float))
1399 return B_FLOAT_TYPE
;
1400 return B_DOUBLE_TYPE
;
1405 return isSigned
? B_INT8_TYPE
: B_UINT8_TYPE
;
1407 return isSigned
? B_INT16_TYPE
: B_UINT16_TYPE
;
1409 return isSigned
? B_INT32_TYPE
: B_UINT32_TYPE
;
1411 return isSigned
? B_INT64_TYPE
: B_UINT64_TYPE
;
1417 error
.SetToFormat("Unable to reconcile types %#" B_PRIx32
1418 " and %#" B_PRIx32
, lhs
, rhs
);
1419 throw ParseException(error
.String(), 0);
1423 BVariant fPrimitive
;
1424 ValueNode
* fValueNode
;
1430 // #pragma mark - CLanguageExpressionEvaluator
1433 CLanguageExpressionEvaluator::CLanguageExpressionEvaluator()
1435 fTokenizer(new Tokenizer()),
1442 CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator()
1449 CLanguageExpressionEvaluator::Evaluate(const char* expressionString
,
1450 ValueNodeManager
* manager
, TeamTypeInformation
* info
)
1452 fNodeManager
= manager
;
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
);
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();
1492 CLanguageExpressionEvaluator::Operand
1493 CLanguageExpressionEvaluator::_ParseSum()
1495 Operand value
= _ParseProduct();
1498 Token token
= fTokenizer
->NextToken();
1499 switch (token
.type
) {
1501 value
+= _ParseProduct();
1504 value
-= _ParseProduct();
1508 fTokenizer
->RewindToken();
1515 CLanguageExpressionEvaluator::Operand
1516 CLanguageExpressionEvaluator::_ParseProduct()
1518 static Operand
zero(int64(0LL));
1520 Operand value
= _ParseUnary();
1523 Token token
= fTokenizer
->NextToken();
1524 switch (token
.type
) {
1526 value
*= _ParseUnary();
1530 Operand rhs
= _ParseUnary();
1532 throw ParseException("division by zero", token
.position
);
1539 Operand rhs
= _ParseUnary();
1541 throw ParseException("modulo by zero", token
.position
);
1546 case TOKEN_LOGICAL_AND
:
1548 value
.SetTo((value
!= zero
)
1549 && (_ParseUnary() != zero
));
1554 case TOKEN_LOGICAL_OR
:
1556 value
.SetTo((value
!= zero
)
1557 || (_ParseUnary() != zero
));
1561 case TOKEN_BITWISE_AND
:
1562 value
&= _ParseUnary();
1565 case TOKEN_BITWISE_OR
:
1566 value
|= _ParseUnary();
1569 case TOKEN_BITWISE_XOR
:
1570 value
^= _ParseUnary();
1574 value
.SetTo((int64
)(value
== _ParseUnary()));
1578 value
.SetTo((int64
)(value
!= _ParseUnary()));
1582 value
.SetTo((int64
)(value
> _ParseUnary()));
1586 value
.SetTo((int64
)(value
>= _ParseUnary()));
1590 value
.SetTo((int64
)(value
< _ParseUnary()));
1594 value
.SetTo((int64
)(value
<= _ParseUnary()));
1598 fTokenizer
->RewindToken();
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
) {
1614 return _ParseUnary();
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();
1633 fTokenizer
->RewindToken();
1634 return _ParseAtom();
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
) {
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
1668 _RequestValueIfNeeded(token
, thisChild
);
1669 ValueNode
* thisNode
= thisChild
->Node();
1670 fTokenizer
->RewindToken();
1671 return _ParseIdentifier(thisNode
);
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
) {
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
);
1728 throw ParseException("Expected identifier after member "
1729 "dereference.", token
.position
);
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
);
1747 if (token
.type
== TOKEN_CONSTANT
)
1748 value
.SetTo(token
.value
);
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
)
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
,
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
);
1799 CLanguageExpressionEvaluator::_EatToken(int32 type
)
1801 Token token
= fTokenizer
->NextToken();
1802 if (token
.type
!= type
) {
1805 case TOKEN_IDENTIFIER
:
1806 expected
= "an identifier";
1809 case TOKEN_CONSTANT
:
1810 expected
= "a constant";
1814 expected
= "'/', '\\', or ':'";
1817 case TOKEN_END_OF_LINE
:
1822 expected
<< "'" << TokenTypeToString(type
) << "'";
1827 temp
<< "Expected " << expected
.String() << " got '" << token
.string
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;
1843 Token token
= fTokenizer
->NextToken();
1844 if (token
.type
== TOKEN_STAR
|| token
.type
== TOKEN_BITWISE_AND
) {
1845 if (arraySpecifierEncountered
)
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
,
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
),
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,
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);
1898 typeReference
.Detach();
1899 fTokenizer
->RewindToken();
1900 return Operand(finalType
);
1905 CLanguageExpressionEvaluator::_RequestValueIfNeeded(
1906 const Token
& token
, ValueNodeChild
* child
)
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
);
1941 CLanguageExpressionEvaluator::_GetNodeChildForPrimitive(const Token
& token
,
1942 const BVariant
& value
, ValueNodeChild
*& _output
) const
1944 Type
* type
= new(std::nothrow
) SyntheticPrimitiveType(value
.Type());
1946 throw ParseException("Out of memory while creating type object.",
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.",
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.",
1972 InternalVariableID
* id
= new(std::nothrow
) InternalVariableID(value
);
1974 throw ParseException("Out of memory while creating ID object.",
1978 BReference
<ObjectID
> idReference(id
, true);
1979 Variable
* variable
= new(std::nothrow
) Variable(id
, variableName
, type
,
1981 if (variable
== NULL
) {
1982 throw ParseException("Out of memory while creating variable object.",
1986 BReference
<Variable
> variableReference(variable
, true);
1987 _output
= new(std::nothrow
) VariableValueNodeChild(
1989 if (_output
== NULL
) {
1990 throw ParseException("Out of memory while creating node child object.",