diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index cb3317a0e4..15787aea26 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -222,7 +222,6 @@ Application Debugger : # types ArrayIndexPath.cpp - Number.cpp TargetAddressRangeList.cpp ValueLocation.cpp diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp b/src/apps/debugger/controllers/ThreadHandler.cpp index 18c5eccdbf..f513d71a89 100644 --- a/src/apps/debugger/controllers/ThreadHandler.cpp +++ b/src/apps/debugger/controllers/ThreadHandler.cpp @@ -35,6 +35,7 @@ #include "Team.h" #include "Tracing.h" #include "Value.h" +#include "ValueLocation.h" #include "Worker.h" @@ -63,7 +64,7 @@ public: } virtual void ExpressionEvaluated(ExpressionInfo* info, status_t result, - Value* value) + ExpressionResult* value) { fHandler->_HandleBreakpointConditionEvaluated(value); } @@ -888,14 +889,8 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState) if (listener == NULL) return false; - Type* type = new(std::nothrow) SyntheticPrimitiveType(B_UINT64_TYPE); - if (type == NULL) - return false; - - BReference typeReference(type, true); - ExpressionInfo* expressionInfo = new(std::nothrow) ExpressionInfo( - userBreakpoint->Condition(), type); + userBreakpoint->Condition()); if (expressionInfo == NULL) return false; @@ -921,23 +916,13 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState) teamLocker.Lock(); - bool stop = false; - if (fConditionResult == NULL) - stop = true; - else { - BVariant value; - if (!fConditionResult->ToVariant(value)) - stop = true; - if (!value.TypeIsInteger(value.Type())) - stop = true; - stop = value.ToBool(); - fConditionResult->ReleaseReference(); - fConditionResult = NULL; - } - - if (stop) + if (_CheckStopCondition()) { + if (fConditionResult != NULL) { + fConditionResult->ReleaseReference(); + fConditionResult = NULL; + } return false; - else { + } else { _SetThreadState(THREAD_STATE_RUNNING, NULL, THREAD_STOPPED_UNKNOWN, BString()); fDebuggerInterface->ContinueThread(fThread->ID()); @@ -951,7 +936,7 @@ ThreadHandler::_HandleBreakpointConditionIfNeeded(CpuState* cpuState) void -ThreadHandler::_HandleBreakpointConditionEvaluated(Value* value) +ThreadHandler::_HandleBreakpointConditionEvaluated(ExpressionResult* value) { fConditionResult = value; if (fConditionResult != NULL) @@ -960,6 +945,25 @@ ThreadHandler::_HandleBreakpointConditionEvaluated(Value* value) } +bool +ThreadHandler::_CheckStopCondition() +{ + // if we we're unable to properly assess the expression result + // in any way, fall back to behaving like an unconditional breakpoint. + if (fConditionResult == NULL) + return true; + + if (fConditionResult->Kind() != EXPRESSION_RESULT_KIND_PRIMITIVE) + return true; + + BVariant value; + if (!fConditionResult->PrimitiveValue()->ToVariant(value)) + return true; + + return value.ToBool(); +} + + bool ThreadHandler::_HasExitedFrame(target_addr_t framePointer) const { diff --git a/src/apps/debugger/controllers/ThreadHandler.h b/src/apps/debugger/controllers/ThreadHandler.h index 86b530721c..eb34741d02 100644 --- a/src/apps/debugger/controllers/ThreadHandler.h +++ b/src/apps/debugger/controllers/ThreadHandler.h @@ -18,10 +18,10 @@ class BreakpointManager; class DebuggerInterface; +class ExpressionResult; class ImageDebugInfoJobListener; class StackFrame; class Statement; -class Value; class Worker; @@ -102,7 +102,8 @@ private: bool _HandleBreakpointConditionIfNeeded( CpuState* cpuState); void _HandleBreakpointConditionEvaluated( - Value* value); + ExpressionResult* value); + bool _CheckStopCondition(); bool _HandleBreakpointHitStep(CpuState* cpuState); bool _HandleSingleStepStep(CpuState* cpuState); @@ -124,7 +125,7 @@ private: target_addr_t fPreviousFrameAddress; bool fSingleStepping; sem_id fConditionWaitSem; - Value* fConditionResult; + ExpressionResult* fConditionResult; public: ThreadHandler* fNext; diff --git a/src/apps/debugger/jobs/ExpressionEvaluationJob.cpp b/src/apps/debugger/jobs/ExpressionEvaluationJob.cpp index a65879d156..52b5cc1391 100644 --- a/src/apps/debugger/jobs/ExpressionEvaluationJob.cpp +++ b/src/apps/debugger/jobs/ExpressionEvaluationJob.cpp @@ -19,6 +19,7 @@ #include "Value.h" #include "ValueNode.h" #include "ValueNodeManager.h" +#include "Variable.h" ExpressionEvaluationJob::ExpressionEvaluationJob(Team* team, @@ -89,10 +90,8 @@ ExpressionEvaluationJob::Do() } ValueNode* neededNode = NULL; - PrimitiveType* type = dynamic_cast( - fExpressionInfo->ResultType()); result = fLanguage->EvaluateExpression(fExpressionInfo->Expression(), - type->TypeConstant(), fManager, fResultValue, neededNode); + fManager, fResultValue, neededNode); if (neededNode != NULL) { result = ResolveNodeValue(neededNode); if (State() == JOB_STATE_WAITING) diff --git a/src/apps/debugger/jobs/Jobs.h b/src/apps/debugger/jobs/Jobs.h index 2c8db45c99..65a0ab0ef8 100644 --- a/src/apps/debugger/jobs/Jobs.h +++ b/src/apps/debugger/jobs/Jobs.h @@ -19,6 +19,7 @@ class BVariant; class CpuState; class DebuggerInterface; class ExpressionInfo; +class ExpressionResult; class Function; class FunctionInstance; class Image; @@ -245,7 +246,7 @@ public: virtual const JobKey& Key() const; virtual status_t Do(); - Value* GetResultValue() const { return fResultValue; } + ExpressionResult* GetResult() const { return fResultValue; } private: status_t ResolveNodeValue(ValueNode* node); @@ -261,7 +262,7 @@ private: StackFrame* fFrame; Thread* fThread; ValueNodeManager* fManager; - Value* fResultValue; + ExpressionResult* fResultValue; }; diff --git a/src/apps/debugger/model/ExpressionInfo.cpp b/src/apps/debugger/model/ExpressionInfo.cpp index bdbfab7f9b..9aaf0d61e5 100644 --- a/src/apps/debugger/model/ExpressionInfo.cpp +++ b/src/apps/debugger/model/ExpressionInfo.cpp @@ -6,70 +6,123 @@ #include "ExpressionInfo.h" -#include "Type.h" +#include "Value.h" +#include "ValueNode.h" + + +// #pragma mark - ExpressionResult + + +ExpressionResult::ExpressionResult() + : + fResultKind(EXPRESSION_RESULT_KIND_UNKNOWN), + fPrimitiveValue(NULL), + fValueNodeValue(NULL) +{ +} + + +ExpressionResult::~ExpressionResult() +{ + if (fPrimitiveValue != NULL) + fPrimitiveValue->ReleaseReference(); + + if (fValueNodeValue != NULL) + fValueNodeValue->ReleaseReference(); +} + + +void +ExpressionResult::SetToPrimitive(Value* value) +{ + _Unset(); + + fPrimitiveValue = value; + if (fPrimitiveValue != NULL) { + fPrimitiveValue->AcquireReference(); + fResultKind = EXPRESSION_RESULT_KIND_PRIMITIVE; + } +} + + +void +ExpressionResult::SetToValueNode(ValueNodeChild* child) +{ + _Unset(); + + fValueNodeValue = child; + if (fValueNodeValue != NULL) { + fValueNodeValue->AcquireReference(); + fResultKind = EXPRESSION_RESULT_KIND_VALUE_NODE; + } + + // if the child has a node with a resolved value, store + // it as a primitive, so the consumer of the expression + // can use it as-is if desired. + + ValueNode* node = child->Node(); + if (node == NULL) + return; + + fPrimitiveValue = node->GetValue(); + if (fPrimitiveValue != NULL) + fPrimitiveValue->AcquireReference(); +} + + +void +ExpressionResult::_Unset() +{ + if (fPrimitiveValue != NULL) { + fPrimitiveValue->ReleaseReference(); + fPrimitiveValue = NULL; + } + + if (fValueNodeValue != NULL) { + fValueNodeValue->ReleaseReference(); + fValueNodeValue = NULL; + } + + fResultKind = EXPRESSION_RESULT_KIND_UNKNOWN; +} + + +// #pragma mark - ExpressionInfo ExpressionInfo::ExpressionInfo() : - fExpression(), - fResultType(NULL) + fExpression() { } ExpressionInfo::ExpressionInfo(const ExpressionInfo& other) : - fExpression(other.fExpression), - fResultType(other.fResultType) + fExpression(other.fExpression) { - if (fResultType != NULL) - fResultType->AcquireReference(); } ExpressionInfo::~ExpressionInfo() { - SetResultType(NULL); } -ExpressionInfo::ExpressionInfo(const BString& expression, Type* resultType) +ExpressionInfo::ExpressionInfo(const BString& expression) : - fExpression(expression), - fResultType(resultType) + fExpression(expression) { - if (resultType != NULL) - resultType->AcquireReference(); } void -ExpressionInfo::SetTo(const BString& expression, Type* resultType) -{ - SetExpression(expression); - SetResultType(resultType); -} - - -void -ExpressionInfo::SetExpression(const BString& expression) +ExpressionInfo::SetTo(const BString& expression) { fExpression = expression; } -void -ExpressionInfo::SetResultType(Type* resultType) -{ - if (fResultType != NULL) - fResultType->ReleaseReference(); - - fResultType = resultType; - if (fResultType != NULL) - fResultType->AcquireReference(); -} - - void ExpressionInfo::AddListener(Listener* listener) { @@ -85,7 +138,8 @@ ExpressionInfo::RemoveListener(Listener* listener) void -ExpressionInfo::NotifyExpressionEvaluated(status_t result, Value* value) +ExpressionInfo::NotifyExpressionEvaluated(status_t result, + ExpressionResult* value) { for (ListenerList::Iterator it = fListeners.GetIterator(); Listener* listener = it.Next();) { diff --git a/src/apps/debugger/model/ExpressionInfo.h b/src/apps/debugger/model/ExpressionInfo.h index 33c5e8bea1..feab5c40f2 100644 --- a/src/apps/debugger/model/ExpressionInfo.h +++ b/src/apps/debugger/model/ExpressionInfo.h @@ -10,9 +10,44 @@ #include #include +#include + -class Type; class Value; +class ValueNodeChild; + + +enum expression_result_kind { + EXPRESSION_RESULT_KIND_UNKNOWN = 0, + EXPRESSION_RESULT_KIND_PRIMITIVE, + EXPRESSION_RESULT_KIND_VALUE_NODE +}; + + +class ExpressionResult : public BReferenceable { +public: + ExpressionResult(); + virtual ~ExpressionResult(); + + + expression_result_kind Kind() const { return fResultKind; } + + Value* PrimitiveValue() const + { return fPrimitiveValue; } + ValueNodeChild* ValueNodeValue() const + { return fValueNodeValue; } + + void SetToPrimitive(Value* value); + void SetToValueNode(ValueNodeChild* child); + +private: + void _Unset(); + +private: + expression_result_kind fResultKind; + Value* fPrimitiveValue; + ValueNodeChild* fValueNodeValue; +}; class ExpressionInfo : public BReferenceable { @@ -22,31 +57,24 @@ public: public: ExpressionInfo(); ExpressionInfo(const ExpressionInfo& other); - ExpressionInfo(const BString& expression, - Type* resultType); + ExpressionInfo(const BString& expression); virtual ~ExpressionInfo(); - void SetTo(const BString& expression, - Type* resultType); + void SetTo(const BString& expression); const BString& Expression() const { return fExpression; } - void SetExpression(const BString& expression); - - Type* ResultType() const { return fResultType; } - void SetResultType(Type* resultType); void AddListener(Listener* listener); void RemoveListener(Listener* listener); void NotifyExpressionEvaluated(status_t result, - Value* value); + ExpressionResult* value); private: typedef DoublyLinkedList ListenerList; private: BString fExpression; - Type* fResultType; ListenerList fListeners; }; @@ -56,7 +84,8 @@ public: virtual ~Listener(); virtual void ExpressionEvaluated(ExpressionInfo* info, - status_t result, Value* value) = 0; + status_t result, + ExpressionResult* value) = 0; }; diff --git a/src/apps/debugger/source_language/CLanguageFamily.cpp b/src/apps/debugger/source_language/CLanguageFamily.cpp index 88c6be77c3..96f793751a 100644 --- a/src/apps/debugger/source_language/CLanguageFamily.cpp +++ b/src/apps/debugger/source_language/CLanguageFamily.cpp @@ -11,11 +11,9 @@ #include #include "CLanguageExpressionEvaluator.h" -#include "FloatValue.h" -#include "IntegerValue.h" -#include "Number.h" -#include "StringValue.h" +#include "ExpressionInfo.h" #include "TeamTypeInformation.h" +#include "StringValue.h" #include "Type.h" #include "TypeLookupConstraints.h" @@ -167,46 +165,28 @@ CLanguageFamily::ParseTypeExpression(const BString& expression, status_t -CLanguageFamily::EvaluateExpression(const BString& expression, type_code type, - ValueNodeManager* manager, Value*& _output, ValueNode*& _neededNode) +CLanguageFamily::EvaluateExpression(const BString& expression, + ValueNodeManager* manager, ExpressionResult*& _output, + ValueNode*& _neededNode) { _output = NULL; _neededNode = NULL; CLanguageExpressionEvaluator evaluator; - Number result; try { - result = evaluator.Evaluate(expression, type, manager); - BVariant resultValue = result.GetValue(); - switch (type) { - case B_INT8_TYPE: - case B_UINT8_TYPE: - case B_INT16_TYPE: - case B_UINT16_TYPE: - case B_INT32_TYPE: - case B_UINT32_TYPE: - case B_INT64_TYPE: - case B_UINT64_TYPE: - _output = new(std::nothrow) IntegerValue(resultValue); - break; - - case B_FLOAT_TYPE: - _output = new(std::nothrow) FloatValue(resultValue.ToFloat()); - break; - - case B_DOUBLE_TYPE: - _output = new(std::nothrow) FloatValue(resultValue.ToDouble()); - break; - } - - if (_output == NULL) - return B_NO_MEMORY; - + _output = evaluator.Evaluate(expression, manager); return B_OK; } catch (ParseException ex) { - BString stringValue; - stringValue.SetToFormat("Parse error at position %" B_PRId32 ": %s", + BString error; + error.SetToFormat("Parse error at position %" B_PRId32 ": %s", ex.position, ex.message.String()); - _output = new(std::nothrow) StringValue(stringValue); + StringValue* value = new(std::nothrow) StringValue(error.String()); + if (value == NULL) + return B_NO_MEMORY; + BReference valueReference(value, true); + _output = new(std::nothrow) ExpressionResult(); + if (_output == NULL) + return B_NO_MEMORY; + _output->SetToPrimitive(value); return B_BAD_DATA; } catch (ValueNeededException ex) { _neededNode = ex.value; diff --git a/src/apps/debugger/source_language/CLanguageFamily.h b/src/apps/debugger/source_language/CLanguageFamily.h index 7159df0d07..62fa17ca5a 100644 --- a/src/apps/debugger/source_language/CLanguageFamily.h +++ b/src/apps/debugger/source_language/CLanguageFamily.h @@ -22,8 +22,9 @@ public: Type*& _resultType) const; virtual status_t EvaluateExpression(const BString& expression, - type_code type, ValueNodeManager* manager, - Value*& _output, ValueNode*& _neededNode); + ValueNodeManager* manager, + ExpressionResult*& _output, + ValueNode*& _neededNode); protected: virtual bool IsModifierValid(char modifier) const = 0; diff --git a/src/apps/debugger/source_language/SourceLanguage.cpp b/src/apps/debugger/source_language/SourceLanguage.cpp index 7f16327765..5d7e6ecde1 100644 --- a/src/apps/debugger/source_language/SourceLanguage.cpp +++ b/src/apps/debugger/source_language/SourceLanguage.cpp @@ -30,7 +30,7 @@ SourceLanguage::ParseTypeExpression(const BString& expression, status_t SourceLanguage::EvaluateExpression(const BString& expression, - type_code type, ValueNodeManager* manager, Value*& _resultValue, + ValueNodeManager* manager, ExpressionResult*& _resultValue, ValueNode*& _neededNode) { return B_NOT_SUPPORTED; diff --git a/src/apps/debugger/source_language/SourceLanguage.h b/src/apps/debugger/source_language/SourceLanguage.h index c732b3b66f..2133100300 100644 --- a/src/apps/debugger/source_language/SourceLanguage.h +++ b/src/apps/debugger/source_language/SourceLanguage.h @@ -11,10 +11,10 @@ class BString; +class ExpressionResult; class SyntaxHighlighter; class TeamTypeInformation; class Type; -class Value; class ValueNode; class ValueNodeManager; @@ -34,8 +34,9 @@ public: Type*& _resultType) const; virtual status_t EvaluateExpression(const BString& expression, - type_code type, ValueNodeManager* manager, - Value*& _output, ValueNode*& _neededNode); + ValueNodeManager* manager, + ExpressionResult*& _output, + ValueNode*& _neededNode); }; diff --git a/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.cpp b/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.cpp index 4d6574e722..f4d506768c 100644 --- a/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.cpp +++ b/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.cpp @@ -11,6 +11,8 @@ #include "CLanguageExpressionEvaluator.h" +#include + #include #include #include @@ -18,7 +20,9 @@ #include "AutoLocker.h" -#include "Number.h" +#include "ExpressionInfo.h" +#include "FloatValue.h" +#include "IntegerValue.h" #include "StackFrame.h" #include "Thread.h" #include "Type.h" @@ -26,6 +30,7 @@ #include "ValueNode.h" #include "ValueNodeManager.h" #include "Variable.h" +#include "VariableValueNodeChild.h" enum { @@ -63,6 +68,15 @@ enum { TOKEN_MEMBER_PTR }; + +enum operand_kind { + OPERAND_KIND_UNKNOWN = 0, + OPERAND_KIND_PRIMITIVE, + OPERAND_KIND_TYPE, + OPERAND_KIND_VALUE_NODE +}; + + static BString TokenTypeToString(int32 type) { BString token; @@ -165,6 +179,1255 @@ static BString TokenTypeToString(int32 type) } +// #pragma mark - CLanguageExpressionEvaluator::Operand + + +class CLanguageExpressionEvaluator::Operand { +public: + Operand() + : + fPrimitive(), + fValueNode(NULL), + fType(NULL), + fKind(OPERAND_KIND_UNKNOWN) + { + } + + Operand(int64 value) + : + fPrimitive(value), + fValueNode(NULL), + fType(NULL), + fKind(OPERAND_KIND_PRIMITIVE) + { + } + + Operand(double value) + : + fPrimitive(value), + fValueNode(NULL), + fType(NULL), + fKind(OPERAND_KIND_PRIMITIVE) + { + } + + Operand(ValueNode* node) + : + fPrimitive(), + fValueNode(NULL), + fType(NULL), + fKind(OPERAND_KIND_UNKNOWN) + { + SetTo(node); + } + + Operand(Type* type) + : + fPrimitive(), + fValueNode(NULL), + fType(NULL), + fKind(OPERAND_KIND_UNKNOWN) + { + SetTo(type); + } + + Operand(const Operand& X) + : + fPrimitive(), + fValueNode(NULL), + fType(NULL), + fKind(OPERAND_KIND_UNKNOWN) + { + *this = X; + } + + + virtual ~Operand() + { + Unset(); + } + + Operand& operator=(const Operand& X) + { + switch (X.fKind) { + case OPERAND_KIND_UNKNOWN: + Unset(); + break; + + case OPERAND_KIND_PRIMITIVE: + SetTo(X.fPrimitive); + break; + + case OPERAND_KIND_VALUE_NODE: + SetTo(X.fValueNode); + break; + + case OPERAND_KIND_TYPE: + SetTo(X.fType); + break; + } + + return *this; + } + + void SetTo(const BVariant& value) + { + Unset(); + fPrimitive = value; + fKind = OPERAND_KIND_PRIMITIVE; + } + + void SetTo(ValueNode* node) + { + Unset(); + fValueNode = node; + fValueNode->AcquireReference(); + + Value* value = node->GetValue(); + if (value != NULL) + value->ToVariant(fPrimitive); + + fKind = OPERAND_KIND_VALUE_NODE; + } + + void SetTo(Type* type) + { + Unset(); + fType = type; + fType->AcquireReference(); + + fKind = OPERAND_KIND_TYPE; + } + + void Unset() + { + if (fValueNode != NULL) + fValueNode->ReleaseReference(); + + if (fType != NULL) + fType->ReleaseReference(); + + fValueNode = NULL; + fType = NULL; + fKind = OPERAND_KIND_UNKNOWN; + } + + inline operand_kind Kind() const + { + return fKind; + } + + inline const BVariant& PrimitiveValue() const + { + return fPrimitive; + } + + inline ValueNode* GetValueNode() const + { + return fValueNode; + + } + + inline Type* GetType() const + { + return fType; + } + + Operand& operator+=(const Operand& rhs) + { + Operand temp = rhs; + _ResolveTypesIfNeeded(temp); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + fPrimitive.SetTo((int8)(fPrimitive.ToInt8() + + temp.fPrimitive.ToInt8())); + break; + } + + case B_UINT8_TYPE: + { + fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8() + + temp.fPrimitive.ToUInt8())); + break; + } + + case B_INT16_TYPE: + { + fPrimitive.SetTo((int16)(fPrimitive.ToInt16() + + temp.fPrimitive.ToInt16())); + break; + } + + case B_UINT16_TYPE: + { + fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16() + + temp.fPrimitive.ToUInt16())); + break; + } + + case B_INT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt32() + + temp.fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt32() + + temp.fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt64() + + temp.fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt64() + + temp.fPrimitive.ToUInt64()); + break; + } + + case B_FLOAT_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToFloat() + + temp.fPrimitive.ToFloat()); + break; + } + + case B_DOUBLE_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToDouble() + + temp.fPrimitive.ToDouble()); + break; + } + } + + return *this; + } + + Operand& operator-=(const Operand& rhs) + { + Operand temp = rhs; + _ResolveTypesIfNeeded(temp); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + fPrimitive.SetTo((int8)(fPrimitive.ToInt8() + - temp.fPrimitive.ToInt8())); + break; + } + + case B_UINT8_TYPE: + { + fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8() + - temp.fPrimitive.ToUInt8())); + break; + } + + case B_INT16_TYPE: + { + fPrimitive.SetTo((int16)(fPrimitive.ToInt16() + - temp.fPrimitive.ToInt16())); + break; + } + + case B_UINT16_TYPE: + { + fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16() + - temp.fPrimitive.ToUInt16())); + break; + } + + case B_INT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt32() + - temp.fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt32() + - temp.fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt64() + - temp.fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt64() + - temp.fPrimitive.ToUInt64()); + break; + } + + case B_FLOAT_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToFloat() + - temp.fPrimitive.ToFloat()); + break; + } + + case B_DOUBLE_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToDouble() + - temp.fPrimitive.ToDouble()); + break; + } + } + + return *this; + } + + Operand& operator/=(const Operand& rhs) + { + Operand temp = rhs; + _ResolveTypesIfNeeded(temp); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + fPrimitive.SetTo((int8)(fPrimitive.ToInt8() + / temp.fPrimitive.ToInt8())); + break; + } + + case B_UINT8_TYPE: + { + fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8() + / temp.fPrimitive.ToUInt8())); + break; + } + + case B_INT16_TYPE: + { + fPrimitive.SetTo((int16)(fPrimitive.ToInt16() + / temp.fPrimitive.ToInt16())); + break; + } + + case B_UINT16_TYPE: + { + fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16() + / temp.fPrimitive.ToUInt16())); + break; + } + + case B_INT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt32() + / temp.fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt32() + / temp.fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt64() + / temp.fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt64() + / temp.fPrimitive.ToUInt64()); + break; + } + + case B_FLOAT_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToFloat() + / temp.fPrimitive.ToFloat()); + break; + } + + case B_DOUBLE_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToDouble() + / temp.fPrimitive.ToDouble()); + break; + } + } + + return *this; + } + + Operand& operator*=(const Operand& rhs) + { + Operand temp = rhs; + _ResolveTypesIfNeeded(temp); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + fPrimitive.SetTo((int8)(fPrimitive.ToInt8() + * temp.fPrimitive.ToInt8())); + break; + } + + case B_UINT8_TYPE: + { + fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8() + * temp.fPrimitive.ToUInt8())); + break; + } + + case B_INT16_TYPE: + { + fPrimitive.SetTo((int16)(fPrimitive.ToInt16() + * temp.fPrimitive.ToInt16())); + break; + } + + case B_UINT16_TYPE: + { + fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16() + * temp.fPrimitive.ToUInt16())); + break; + } + + case B_INT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt32() + * temp.fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt32() + * temp.fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt64() + * temp.fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt64() + * temp.fPrimitive.ToUInt64()); + break; + } + + case B_FLOAT_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToFloat() + * temp.fPrimitive.ToFloat()); + break; + } + + case B_DOUBLE_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToDouble() + * temp.fPrimitive.ToDouble()); + break; + } + } + + return *this; + } + + Operand& operator%=(const Operand& rhs) + { + Operand temp = rhs; + _ResolveTypesIfNeeded(temp); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + fPrimitive.SetTo((int8)(fPrimitive.ToInt8() + % temp.fPrimitive.ToInt8())); + break; + } + + case B_UINT8_TYPE: + { + fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8() + % temp.fPrimitive.ToUInt8())); + break; + } + + case B_INT16_TYPE: + { + fPrimitive.SetTo((int16)(fPrimitive.ToInt16() + % temp.fPrimitive.ToInt16())); + break; + } + + case B_UINT16_TYPE: + { + fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16() + % temp.fPrimitive.ToUInt16())); + break; + } + + case B_INT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt32() + % temp.fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt32() + % temp.fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt64() + % temp.fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt64() + % temp.fPrimitive.ToUInt64()); + break; + } + } + + return *this; + } + + Operand& operator&=(const Operand& rhs) + { + Operand temp = rhs; + _ResolveTypesIfNeeded(temp); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + fPrimitive.SetTo((int8)(fPrimitive.ToInt8() + & temp.fPrimitive.ToInt8())); + break; + } + + case B_UINT8_TYPE: + { + fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8() + & temp.fPrimitive.ToUInt8())); + break; + } + + case B_INT16_TYPE: + { + fPrimitive.SetTo((int16)(fPrimitive.ToInt16() + & temp.fPrimitive.ToInt16())); + break; + } + + case B_UINT16_TYPE: + { + fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16() + & temp.fPrimitive.ToUInt16())); + break; + } + + case B_INT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt32() + & temp.fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt32() + & temp.fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt64() + & temp.fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt64() + & temp.fPrimitive.ToUInt64()); + break; + } + } + + return *this; + } + + Operand& operator|=(const Operand& rhs) + { + Operand temp = rhs; + _ResolveTypesIfNeeded(temp); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + fPrimitive.SetTo((int8)(fPrimitive.ToInt8() + | temp.fPrimitive.ToInt8())); + break; + } + + case B_UINT8_TYPE: + { + fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8() + | temp.fPrimitive.ToUInt8())); + break; + } + + case B_INT16_TYPE: + { + fPrimitive.SetTo((int16)(fPrimitive.ToInt16() + | temp.fPrimitive.ToInt16())); + break; + } + + case B_UINT16_TYPE: + { + fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16() + | temp.fPrimitive.ToUInt16())); + break; + } + + case B_INT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt32() + | temp.fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt32() + | temp.fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt64() + | temp.fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt64() + | temp.fPrimitive.ToUInt64()); + break; + } + } + + return *this; + } + + Operand& operator^=(const Operand& rhs) + { + Operand temp = rhs; + _ResolveTypesIfNeeded(temp); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + fPrimitive.SetTo((int8)(fPrimitive.ToInt8() + ^ temp.fPrimitive.ToInt8())); + break; + } + + case B_UINT8_TYPE: + { + fPrimitive.SetTo((uint8)(fPrimitive.ToUInt8() + ^ temp.fPrimitive.ToUInt8())); + break; + } + + case B_INT16_TYPE: + { + fPrimitive.SetTo((int16)(fPrimitive.ToInt16() + ^ temp.fPrimitive.ToInt16())); + break; + } + + case B_UINT16_TYPE: + { + fPrimitive.SetTo((uint16)(fPrimitive.ToUInt16() + ^ temp.fPrimitive.ToUInt16())); + break; + } + + case B_INT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt32() + ^ temp.fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt32() + ^ temp.fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToInt64() + ^ temp.fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + fPrimitive.SetTo(fPrimitive.ToUInt64() + ^ temp.fPrimitive.ToUInt64()); + break; + } + } + + return *this; + } + + Operand operator-() const + { + Operand value(*this); + value._ResolveToPrimitive(); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + value.fPrimitive.SetTo((int8)-fPrimitive.ToInt8()); + break; + } + + case B_UINT8_TYPE: + { + value.fPrimitive.SetTo((uint8)-fPrimitive.ToUInt8()); + break; + } + + case B_INT16_TYPE: + { + value.fPrimitive.SetTo((int16)-fPrimitive.ToInt16()); + break; + } + + case B_UINT16_TYPE: + { + value.fPrimitive.SetTo((uint16)-fPrimitive.ToUInt16()); + break; + } + + case B_INT32_TYPE: + { + value.fPrimitive.SetTo(-fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + value.fPrimitive.SetTo(-fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + value.fPrimitive.SetTo(-fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + value.fPrimitive.SetTo(-fPrimitive.ToUInt64()); + break; + } + + case B_FLOAT_TYPE: + { + value.fPrimitive.SetTo(-fPrimitive.ToFloat()); + break; + } + + case B_DOUBLE_TYPE: + { + value.fPrimitive.SetTo(-fPrimitive.ToDouble()); + break; + } + } + + return value; + } + + Operand operator~() const + { + Operand value(*this); + value._ResolveToPrimitive(); + + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + value.fPrimitive.SetTo((int8)~fPrimitive.ToInt8()); + break; + } + + case B_UINT8_TYPE: + { + value.fPrimitive.SetTo((uint8)~fPrimitive.ToUInt8()); + break; + } + + case B_INT16_TYPE: + { + value.fPrimitive.SetTo((int16)~fPrimitive.ToInt16()); + break; + } + + case B_UINT16_TYPE: + { + value.fPrimitive.SetTo((uint16)~fPrimitive.ToUInt16()); + break; + } + + case B_INT32_TYPE: + { + value.fPrimitive.SetTo(~fPrimitive.ToInt32()); + break; + } + + case B_UINT32_TYPE: + { + value.fPrimitive.SetTo(~fPrimitive.ToUInt32()); + break; + } + + case B_INT64_TYPE: + { + value.fPrimitive.SetTo(~fPrimitive.ToInt64()); + break; + } + + case B_UINT64_TYPE: + { + value.fPrimitive.SetTo(~fPrimitive.ToUInt64()); + break; + } + } + + return value; + } + + int operator<(const Operand& rhs) const + { + Operand lhs = *this; + Operand temp = rhs; + + lhs._ResolveTypesIfNeeded(temp); + + int result = 0; + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + result = lhs.fPrimitive.ToInt8() < temp.fPrimitive.ToInt8(); + break; + } + + case B_UINT8_TYPE: + { + result = lhs.fPrimitive.ToUInt8() < temp.fPrimitive.ToUInt8(); + break; + } + + case B_INT16_TYPE: + { + result = lhs.fPrimitive.ToInt16() < temp.fPrimitive.ToInt16(); + break; + } + + case B_UINT16_TYPE: + { + result = lhs.fPrimitive.ToUInt16() + < temp.fPrimitive.ToUInt16(); + break; + } + + case B_INT32_TYPE: + { + result = lhs.fPrimitive.ToInt32() < temp.fPrimitive.ToInt32(); + break; + } + + case B_UINT32_TYPE: + { + result = lhs.fPrimitive.ToUInt32() + < temp.fPrimitive.ToUInt32(); + break; + } + + case B_INT64_TYPE: + { + result = lhs.fPrimitive.ToInt64() < temp.fPrimitive.ToInt64(); + break; + } + + case B_UINT64_TYPE: + { + result = lhs.fPrimitive.ToUInt64() + < temp.fPrimitive.ToUInt64(); + break; + } + + case B_FLOAT_TYPE: + { + result = lhs.fPrimitive.ToFloat() < temp.fPrimitive.ToFloat(); + break; + } + + case B_DOUBLE_TYPE: + { + result = lhs.fPrimitive.ToDouble() + < temp.fPrimitive.ToDouble(); + break; + } + } + + return result; + } + + int operator<=(const Operand& rhs) const + { + return (*this < rhs) || (*this == rhs); + } + + int operator>(const Operand& rhs) const + { + Operand lhs = *this; + Operand temp = rhs; + lhs._ResolveTypesIfNeeded(temp); + + int result = 0; + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + result = lhs.fPrimitive.ToInt8() > temp.fPrimitive.ToInt8(); + break; + } + + case B_UINT8_TYPE: + { + result = lhs.fPrimitive.ToUInt8() > temp.fPrimitive.ToUInt8(); + break; + } + + case B_INT16_TYPE: + { + result = lhs.fPrimitive.ToInt16() > temp.fPrimitive.ToInt16(); + break; + } + + case B_UINT16_TYPE: + { + result = lhs.fPrimitive.ToUInt16() + > temp.fPrimitive.ToUInt16(); + break; + } + + case B_INT32_TYPE: + { + result = lhs.fPrimitive.ToInt32() > temp.fPrimitive.ToInt32(); + break; + } + + case B_UINT32_TYPE: + { + result = lhs.fPrimitive.ToUInt32() + > temp.fPrimitive.ToUInt32(); + break; + } + + case B_INT64_TYPE: + { + result = lhs.fPrimitive.ToInt64() > temp.fPrimitive.ToInt64(); + break; + } + + case B_UINT64_TYPE: + { + result = lhs.fPrimitive.ToUInt64() + > temp.fPrimitive.ToUInt64(); + break; + } + + case B_FLOAT_TYPE: + { + result = lhs.fPrimitive.ToFloat() > temp.fPrimitive.ToFloat(); + break; + } + + case B_DOUBLE_TYPE: + { + result = lhs.fPrimitive.ToDouble() + > temp.fPrimitive.ToDouble(); + break; + } + } + + return result; + } + + int operator>=(const Operand& rhs) const + { + return (*this > rhs) || (*this == rhs); + } + + int operator==(const Operand& rhs) const + { + Operand lhs = *this; + Operand temp = rhs; + lhs._ResolveTypesIfNeeded(temp); + + int result = 0; + switch (fPrimitive.Type()) { + case B_INT8_TYPE: + { + result = lhs.fPrimitive.ToInt8() == temp.fPrimitive.ToInt8(); + break; + } + + case B_UINT8_TYPE: + { + result = lhs.fPrimitive.ToUInt8() == temp.fPrimitive.ToUInt8(); + break; + } + + case B_INT16_TYPE: + { + result = lhs.fPrimitive.ToInt16() == temp.fPrimitive.ToInt16(); + break; + } + + case B_UINT16_TYPE: + { + result = lhs.fPrimitive.ToUInt16() + == temp.fPrimitive.ToUInt16(); + break; + } + + case B_INT32_TYPE: + { + result = lhs.fPrimitive.ToInt32() == temp.fPrimitive.ToInt32(); + break; + } + + case B_UINT32_TYPE: + { + result = lhs.fPrimitive.ToUInt32() + == temp.fPrimitive.ToUInt32(); + break; + } + + case B_INT64_TYPE: + { + result = lhs.fPrimitive.ToInt64() == temp.fPrimitive.ToInt64(); + break; + } + + case B_UINT64_TYPE: + { + result = lhs.fPrimitive.ToUInt64() + == temp.fPrimitive.ToUInt64(); + break; + } + + case B_FLOAT_TYPE: + { + result = lhs.fPrimitive.ToFloat() == temp.fPrimitive.ToFloat(); + break; + } + + case B_DOUBLE_TYPE: + { + result = lhs.fPrimitive.ToDouble() + == temp.fPrimitive.ToDouble(); + break; + } + } + + return result; + } + + int operator!=(const Operand& rhs) const + { + return !(*this == rhs); + } + +private: + void _GetAsType(type_code type) + { + switch (type) { + case B_INT8_TYPE: + fPrimitive.SetTo(fPrimitive.ToInt8()); + break; + case B_UINT8_TYPE: + fPrimitive.SetTo(fPrimitive.ToUInt8()); + break; + case B_INT16_TYPE: + fPrimitive.SetTo(fPrimitive.ToInt16()); + break; + case B_UINT16_TYPE: + fPrimitive.SetTo(fPrimitive.ToUInt16()); + break; + case B_INT32_TYPE: + fPrimitive.SetTo(fPrimitive.ToInt32()); + break; + case B_UINT32_TYPE: + fPrimitive.SetTo(fPrimitive.ToUInt32()); + break; + case B_INT64_TYPE: + fPrimitive.SetTo(fPrimitive.ToInt64()); + break; + case B_UINT64_TYPE: + fPrimitive.SetTo(fPrimitive.ToUInt64()); + break; + case B_FLOAT_TYPE: + fPrimitive.SetTo(fPrimitive.ToFloat()); + break; + case B_DOUBLE_TYPE: + fPrimitive.SetTo(fPrimitive.ToDouble()); + break; + } + } + + void _ResolveTypesIfNeeded(Operand& other) + { + _ResolveToPrimitive(); + other._ResolveToPrimitive(); + + if (!fPrimitive.IsNumber() || !other.fPrimitive.IsNumber()) { + throw ParseException("Cannot perform mathematical operations " + "between non-numerical objects.", 0); + } + + type_code thisType = fPrimitive.Type(); + type_code otherType = other.fPrimitive.Type(); + + if (thisType == otherType) + return; + + type_code resolvedType = _ResolvePriorityType(thisType, otherType); + if (thisType != resolvedType) + _GetAsType(resolvedType); + + if (otherType != resolvedType) + other._GetAsType(resolvedType); + } + + void _ResolveToPrimitive() + { + if (Kind() == OPERAND_KIND_PRIMITIVE) + return; + else if (Kind() == OPERAND_KIND_TYPE) { + throw ParseException("Cannot perform mathematical operations " + "between type objects.", 0); + } + + status_t error = fValueNode->LocationAndValueResolutionState(); + if (error != B_OK) { + BString errorMessage; + errorMessage.SetToFormat("Failed to resolve value of %s: %" + B_PRId32 ".", fValueNode->Name().String(), error); + throw ParseException(errorMessage.String(), 0); + } + + Value* value = fValueNode->GetValue(); + BVariant tempValue; + if (value->ToVariant(tempValue)) + SetTo(tempValue); + else { + BString error; + error.SetToFormat("Failed to retrieve value of %s.", + fValueNode->Name().String()); + throw ParseException(error.String(), 0); + } + } + + type_code _ResolvePriorityType(type_code lhs, type_code rhs) const + { + size_t byteSize = std::max(BVariant::SizeOfType(lhs), + BVariant::SizeOfType(rhs)); + bool isFloat = BVariant::TypeIsFloat(lhs) + || BVariant::TypeIsFloat(rhs); + bool isSigned = isFloat; + if (!isFloat) { + BVariant::TypeIsInteger(lhs, &isSigned); + if (!isSigned) + BVariant::TypeIsInteger(rhs, &isSigned); + } + + if (isFloat) { + if (byteSize == sizeof(float)) + return B_FLOAT_TYPE; + return B_DOUBLE_TYPE; + } + + switch (byteSize) { + case 1: + return isSigned ? B_INT8_TYPE : B_UINT8_TYPE; + case 2: + return isSigned ? B_INT16_TYPE : B_UINT16_TYPE; + case 4: + return isSigned ? B_INT32_TYPE : B_UINT32_TYPE; + case 8: + return isSigned ? B_INT64_TYPE : B_UINT64_TYPE; + default: + break; + } + + BString error; + error.SetToFormat("Unable to reconcile types %#" B_PRIx32 + " and %#" B_PRIx32, lhs, rhs); + throw ParseException(error.String(), 0); + } + +private: + BVariant fPrimitive; + ValueNode* fValueNode; + Type* fType; + operand_kind fKind; +}; + + +// #pragma mark - CLanguageExpressionEvaluator::Token + + struct CLanguageExpressionEvaluator::Token { Token() : string(""), @@ -201,20 +1464,22 @@ struct CLanguageExpressionEvaluator::Token { BString string; int32 type; - Number value; + BVariant value; int32 position; }; +// #pragma mark - CLanguageExpressionEvaluator::Tokenizer + + class CLanguageExpressionEvaluator::Tokenizer { - public: +public: Tokenizer() : fString(""), fCurrentChar(NULL), fCurrentToken(), - fReuseToken(false), - fType(B_INT32_TYPE) + fReuseToken(false) { } @@ -226,11 +1491,6 @@ class CLanguageExpressionEvaluator::Tokenizer { fReuseToken = false; } - void SetType(type_code type) - { - fType = type; - } - const Token& NextToken() { if (fCurrentToken.type == TOKEN_END_OF_LINE) @@ -252,7 +1512,7 @@ class CLanguageExpressionEvaluator::Tokenizer { if (decimal || isdigit(*fCurrentChar)) { if (*fCurrentChar == '0' && fCurrentChar[1] == 'x') - return _ParseHexNumber(); + return _ParseHexOperand(); BString temp; @@ -267,6 +1527,7 @@ class CLanguageExpressionEvaluator::Tokenizer { // optional post comma part // (required if there are no digits before the comma) if (*fCurrentChar == '.' || *fCurrentChar == ',') { + decimal = true; temp << '.'; fCurrentChar++; @@ -277,29 +1538,6 @@ class CLanguageExpressionEvaluator::Tokenizer { } } - // optional exponent part - if (*fCurrentChar == 'E') { - temp << *fCurrentChar; - fCurrentChar++; - - // optional exponent sign - if (*fCurrentChar == '+' || *fCurrentChar == '-') { - temp << *fCurrentChar; - fCurrentChar++; - } - - // required exponent digits - if (!isdigit(*fCurrentChar)) { - throw ParseException("missing exponent in constant", - fCurrentChar - begin); - } - - while (isdigit(*fCurrentChar)) { - temp << *fCurrentChar; - fCurrentChar++; - } - } - int32 length = fCurrentChar - begin; if (length == 1 && decimal) { // check for . operator @@ -324,7 +1562,13 @@ class CLanguageExpressionEvaluator::Tokenizer { fCurrentToken = Token(begin, length, _CurrentPos() - length, TOKEN_CONSTANT); - fCurrentToken.value.SetTo(fType, temp.String()); + if (decimal) + fCurrentToken.value.SetTo(value); + else { + fCurrentToken.value.SetTo((int64)strtoll(temp.String(), NULL, + 10)); + } + } else if (isalpha(*fCurrentChar)) { const char* begin = fCurrentChar; while (*fCurrentChar != 0 && (isalpha(*fCurrentChar) @@ -510,7 +1754,7 @@ class CLanguageExpressionEvaluator::Tokenizer { return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } - Token& _ParseHexNumber() + Token& _ParseHexOperand() { const char* begin = fCurrentChar; fCurrentChar += 2; @@ -527,7 +1771,8 @@ class CLanguageExpressionEvaluator::Tokenizer { fCurrentToken = Token(begin, length, _CurrentPos() - length, TOKEN_CONSTANT); - fCurrentToken.value.SetTo(fType, fCurrentToken.string.String(), 16); + fCurrentToken.value.SetTo((int64)strtoull( + fCurrentToken.string.String(), NULL, 16)); return fCurrentToken; } @@ -540,14 +1785,15 @@ class CLanguageExpressionEvaluator::Tokenizer { const char* fCurrentChar; Token fCurrentToken; bool fReuseToken; - type_code fType; }; +// #pragma mark - CLanguageExpressionEvaluator + + CLanguageExpressionEvaluator::CLanguageExpressionEvaluator() : fTokenizer(new Tokenizer()), - fCurrentType(B_INT64_TYPE), fNodeManager(NULL) { } @@ -559,28 +1805,53 @@ CLanguageExpressionEvaluator::~CLanguageExpressionEvaluator() } -Number +ExpressionResult* CLanguageExpressionEvaluator::Evaluate(const char* expressionString, - type_code type, ValueNodeManager* manager) + ValueNodeManager* manager) { - fCurrentType = type; fNodeManager = manager; - fTokenizer->SetType(type); fTokenizer->SetTo(expressionString); - Number value = _ParseSum(); + Operand value = _ParseSum(); Token token = fTokenizer->NextToken(); if (token.type != TOKEN_END_OF_LINE) throw ParseException("parse error", token.position); - return value; + ExpressionResult* result = new(std::nothrow)ExpressionResult; + if (result != NULL) { + BReference resultReference(result, true); + Value* outputValue = NULL; + BVariant primitive = value.PrimitiveValue(); + if (primitive.IsInteger()) + outputValue = new(std::nothrow) IntegerValue(primitive); + else if (primitive.IsFloat()) { + outputValue = new(std::nothrow) FloatValue( + primitive.ToDouble()); + } + + BReference valueReference; + if (outputValue != NULL) + valueReference.SetTo(outputValue, true); + + if (value.Kind() == OPERAND_KIND_PRIMITIVE) { + if (outputValue == NULL) + return NULL; + + result->SetToPrimitive(outputValue); + } else if (value.Kind() == OPERAND_KIND_VALUE_NODE) + result->SetToValueNode(value.GetValueNode()->NodeChild()); + + resultReference.Detach(); + } + + return result; } -Number +CLanguageExpressionEvaluator::Operand CLanguageExpressionEvaluator::_ParseSum() { - Number value = _ParseProduct(); + Operand value = _ParseProduct(); while (true) { Token token = fTokenizer->NextToken(); @@ -600,10 +1871,12 @@ CLanguageExpressionEvaluator::_ParseSum() } -Number +CLanguageExpressionEvaluator::Operand CLanguageExpressionEvaluator::_ParseProduct() { - Number value = _ParsePower(); + static Operand zero(int64(0LL)); + + Operand value = _ParsePower(); while (true) { Token token = fTokenizer->NextToken(); @@ -613,8 +1886,8 @@ CLanguageExpressionEvaluator::_ParseProduct() break; case TOKEN_SLASH: { - Number rhs = _ParsePower(); - if (rhs == Number(fCurrentType, 0)) + Operand rhs = _ParsePower(); + if (rhs == zero) throw ParseException("division by zero", token.position); value /= rhs; break; @@ -622,8 +1895,8 @@ CLanguageExpressionEvaluator::_ParseProduct() case TOKEN_MODULO: { - Number rhs = _ParsePower(); - if (rhs == Number()) + Operand rhs = _ParsePower(); + if (rhs == zero) throw ParseException("modulo by zero", token.position); value %= rhs; break; @@ -631,18 +1904,16 @@ CLanguageExpressionEvaluator::_ParseProduct() case TOKEN_LOGICAL_AND: { - Number zero(BVariant(0L)); - value.SetTo(BVariant((int32)((value != zero) - && (_ParsePower() != zero)))); + value.SetTo((value != zero) + && (_ParsePower() != zero)); break; } case TOKEN_LOGICAL_OR: { - Number zero(BVariant(0L)); - value.SetTo(BVariant((int32)((value != zero) - || (_ParsePower() != zero)))); + value.SetTo((value != zero) + || (_ParsePower() != zero)); break; } @@ -659,27 +1930,27 @@ CLanguageExpressionEvaluator::_ParseProduct() break; case TOKEN_EQ: - value.SetTo(BVariant((int32)(value == _ParsePower()))); + value.SetTo((int64)(value == _ParsePower())); break; case TOKEN_NE: - value.SetTo(BVariant((int32)(value != _ParsePower()))); + value.SetTo((int64)(value != _ParsePower())); break; case TOKEN_GT: - value.SetTo(BVariant((int32)(value > _ParsePower()))); + value.SetTo((int64)(value > _ParsePower())); break; case TOKEN_GE: - value.SetTo(BVariant((int32)(value >= _ParsePower()))); + value.SetTo((int64)(value >= _ParsePower())); break; case TOKEN_LT: - value.SetTo(BVariant((int32)(value < _ParsePower()))); + value.SetTo((int64)(value < _ParsePower())); break; case TOKEN_LE: - value.SetTo(BVariant((int32)(value <= _ParsePower()))); + value.SetTo((int64)(value <= _ParsePower())); break; default: @@ -690,10 +1961,10 @@ CLanguageExpressionEvaluator::_ParseProduct() } -Number +CLanguageExpressionEvaluator::Operand CLanguageExpressionEvaluator::_ParsePower() { - Number value = _ParseUnary(); + Operand value = _ParseUnary(); while (true) { Token token = fTokenizer->NextToken(); @@ -702,9 +1973,9 @@ CLanguageExpressionEvaluator::_ParsePower() return value; } - Number power = _ParseUnary(); - Number temp = value; - int32 powerValue = power.GetValue().ToInt32(); + Operand power = _ParseUnary(); + Operand temp = value; + int64 powerValue = power.PrimitiveValue().ToInt64(); bool handleNegativePower = false; if (powerValue < 0) { powerValue = abs(powerValue); @@ -712,14 +1983,14 @@ CLanguageExpressionEvaluator::_ParsePower() } if (powerValue == 0) - value.SetTo(fCurrentType, "1"); + value.SetTo((int64)1); else { for (; powerValue > 1; powerValue--) value *= temp; } if (handleNegativePower) { - temp.SetTo(fCurrentType, "1"); + temp.SetTo((int64)1); temp /= value; value = temp; } @@ -727,7 +1998,7 @@ CLanguageExpressionEvaluator::_ParsePower() } -Number +CLanguageExpressionEvaluator::Operand CLanguageExpressionEvaluator::_ParseUnary() { Token token = fTokenizer->NextToken(); @@ -745,7 +2016,10 @@ CLanguageExpressionEvaluator::_ParseUnary() return ~_ParseUnary(); case TOKEN_LOGICAL_NOT: - return Number((int32)(_ParseUnary() == Number(BVariant(0L)))); + { + Operand zero((int64)0); + return Operand((int64)(_ParseUnary() == zero)); + } case TOKEN_IDENTIFIER: fTokenizer->RewindToken(); @@ -756,15 +2030,14 @@ CLanguageExpressionEvaluator::_ParseUnary() return _ParseAtom(); } - return Number(); + return Operand(); } -Number +CLanguageExpressionEvaluator::Operand CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode) { Token token = fTokenizer->NextToken(); - Number value; if (fNodeManager == NULL) { throw ParseException("Identifiers not resolvable without manager.", @@ -843,33 +2116,30 @@ CLanguageExpressionEvaluator::_ParseIdentifier(ValueNode* parentNode) } else fTokenizer->RewindToken(); - BVariant variant; - Value* nodeValue = node->GetValue(); - nodeValue->ToVariant(variant); - value.SetTo(variant); - _CoerceTypeIfNeeded(token, value); - - return value; + return Operand(node); } -Number +CLanguageExpressionEvaluator::Operand CLanguageExpressionEvaluator::_ParseAtom() { Token token = fTokenizer->NextToken(); if (token.type == TOKEN_END_OF_LINE) throw ParseException("unexpected end of expression", token.position); + Operand value; + if (token.type == TOKEN_CONSTANT) - return token.value; + value.SetTo(token.value); + else { + fTokenizer->RewindToken(); - fTokenizer->RewindToken(); + _EatToken(TOKEN_OPENING_BRACKET); - _EatToken(TOKEN_OPENING_BRACKET); + value = _ParseSum(); - Number value = _ParseSum(); - - _EatToken(TOKEN_CLOSING_BRACKET); + _EatToken(TOKEN_CLOSING_BRACKET); + } return value; } @@ -961,82 +2231,3 @@ CLanguageExpressionEvaluator::_RequestValueIfNeeded(const Token& token, throw ParseException(errorMessage, token.position); } } - - -void -CLanguageExpressionEvaluator::_CoerceTypeIfNeeded(const Token& token, - Number& _number) -{ - if (_number.Type() == 0) { - throw ParseException("Unable to resolve value type.", - token.position); - } - - BVariant value = _number.GetValue(); - type_code valueType = value.Type(); - - if (valueType == fCurrentType) { - // nothing to do. - return; - } - - if (BVariant::TypeIsInteger(fCurrentType)) { - if (BVariant::TypeIsFloat(valueType)) { - value.SetTo((int64)value.ToDouble()); - valueType = value.Type(); - } - - if (BVariant::TypeIsInteger(valueType)) { - switch (fCurrentType) { - case B_INT8_TYPE: - value.SetTo(value.ToInt8()); - break; - - case B_UINT8_TYPE: - value.SetTo(value.ToUInt8()); - break; - - case B_INT16_TYPE: - value.SetTo(value.ToInt16()); - break; - - case B_UINT16_TYPE: - value.SetTo(value.ToUInt16()); - break; - - case B_INT32_TYPE: - value.SetTo(value.ToInt32()); - break; - - case B_UINT32_TYPE: - value.SetTo(value.ToUInt32()); - break; - - case B_INT64_TYPE: - value.SetTo(value.ToInt64()); - break; - - case B_UINT64_TYPE: - value.SetTo(value.ToUInt64()); - break; - } - } - } else if (BVariant::TypeIsFloat(fCurrentType)) { - if (BVariant::TypeIsInteger(valueType)) { - value.SetTo((double)value.ToInt64()); - valueType = value.Type(); - } - - switch (fCurrentType) { - case B_FLOAT_TYPE: - value.SetTo(value.ToFloat()); - break; - - case B_DOUBLE_TYPE: - value.SetTo(value.ToDouble()); - break; - } - } - - _number.SetTo(value); -} diff --git a/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.h b/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.h index bd5f414a17..ef92daa34f 100644 --- a/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.h +++ b/src/apps/debugger/source_language/expression_evaluators/CLanguageExpressionEvaluator.h @@ -18,6 +18,7 @@ class ValueNode; class ValueNodeChild; class ValueNodeManager; +class Variable; class ParseException { @@ -38,6 +39,7 @@ class ParseException { int32 position; }; + class ValueNeededException { public: ValueNeededException(ValueNode* node) @@ -50,6 +52,7 @@ public: }; +class ExpressionResult; class Number; @@ -59,31 +62,28 @@ class CLanguageExpressionEvaluator { CLanguageExpressionEvaluator(); ~CLanguageExpressionEvaluator(); - Number Evaluate(const char* expressionString, - type_code type, ValueNodeManager* manager); + ExpressionResult* Evaluate(const char* expressionString, + ValueNodeManager* manager); private: + class Operand; struct Token; class Tokenizer; private: - Number _ParseSum(); - Number _ParseProduct(); - Number _ParsePower(); - Number _ParseUnary(); - Number _ParseIdentifier(ValueNode* parentNode = NULL); - Number _ParseAtom(); + Operand _ParseSum(); + Operand _ParseProduct(); + Operand _ParsePower(); + Operand _ParseUnary(); + Operand _ParseIdentifier(ValueNode* parentNode = NULL); + Operand _ParseAtom(); void _EatToken(int32 type); void _RequestValueIfNeeded(const Token& token, ValueNodeChild* child); - void _CoerceTypeIfNeeded(const Token& token, - Number& _number); - Tokenizer* fTokenizer; - type_code fCurrentType; ValueNodeManager* fNodeManager; }; diff --git a/src/apps/debugger/types/Number.cpp b/src/apps/debugger/types/Number.cpp deleted file mode 100644 index b8e007a03d..0000000000 --- a/src/apps/debugger/types/Number.cpp +++ /dev/null @@ -1,1008 +0,0 @@ -/* - * Copyright 2014, Rene Gollent, rene@gollent.com. - * Distributed under the terms of the MIT License. - */ - - -#include "Number.h" - -#include - -#include - - -Number::Number() - : - fValue() -{ -} - - -Number::~Number() -{ -} - - -Number::Number(type_code type, const BString& value) -{ - SetTo(type, value); -} - - -Number::Number(const BVariant& value) - : - fValue(value) -{ -} - - -Number::Number(const Number& other) - : - fValue(other.fValue) -{ -} - - -void -Number::SetTo(type_code type, const BString& value, int32 base) -{ - switch (type) { - case B_INT8_TYPE: - { - int8 tempValue = (int8)strtol(value.String(), NULL, base); - fValue.SetTo(tempValue); - break; - } - - case B_UINT8_TYPE: - { - uint8 tempValue = (uint8)strtoul(value.String(), NULL, base); - fValue.SetTo(tempValue); - break; - } - - case B_INT16_TYPE: - { - int16 tempValue = (int16)strtol(value.String(), NULL, base); - fValue.SetTo(tempValue); - break; - } - - case B_UINT16_TYPE: - { - uint16 tempValue = (uint16)strtoul(value.String(), NULL, base); - fValue.SetTo(tempValue); - break; - } - - case B_INT32_TYPE: - { - int32 tempValue = (int32)strtol(value.String(), NULL, base); - fValue.SetTo(tempValue); - break; - } - - case B_UINT32_TYPE: - { - uint32 tempValue = (int32)strtoul(value.String(), NULL, base); - fValue.SetTo(tempValue); - break; - } - - case B_INT64_TYPE: - { - int64 tempValue = (int64)strtoll(value.String(), NULL, base); - fValue.SetTo(tempValue); - break; - } - - case B_UINT64_TYPE: - { - uint64 tempValue = (uint64)strtol(value.String(), NULL, base); - fValue.SetTo(tempValue); - break; - } - - case B_FLOAT_TYPE: - { - float tempValue = strtof(value.String(), NULL); - fValue.SetTo(tempValue); - break; - } - - case B_DOUBLE_TYPE: - { - double tempValue = strtod(value.String(), NULL); - fValue.SetTo(tempValue); - break; - } - } -} - - -void -Number::SetTo(const BVariant& value) -{ - fValue = value; -} - - -Number& -Number::operator=(const Number& rhs) -{ - fValue = rhs.fValue; - return *this; -} - - -Number& -Number::operator+=(const Number& rhs) -{ - switch (fValue.Type()) { - case B_INT8_TYPE: - { - fValue.SetTo((int8)(fValue.ToInt8() + rhs.fValue.ToInt8())); - break; - } - - case B_UINT8_TYPE: - { - fValue.SetTo((uint8)(fValue.ToUInt8() + rhs.fValue.ToUInt8())); - break; - } - - case B_INT16_TYPE: - { - fValue.SetTo((int16)(fValue.ToInt16() + rhs.fValue.ToInt16())); - break; - } - - case B_UINT16_TYPE: - { - fValue.SetTo((uint16)(fValue.ToUInt16() + rhs.fValue.ToUInt16())); - break; - } - - case B_INT32_TYPE: - { - fValue.SetTo(fValue.ToInt32() + rhs.fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - fValue.SetTo(fValue.ToUInt32() + rhs.fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - fValue.SetTo(fValue.ToInt64() + rhs.fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - fValue.SetTo(fValue.ToUInt64() + rhs.fValue.ToUInt64()); - break; - } - - case B_FLOAT_TYPE: - { - fValue.SetTo(fValue.ToFloat() + rhs.fValue.ToFloat()); - break; - } - - case B_DOUBLE_TYPE: - { - fValue.SetTo(fValue.ToDouble() + rhs.fValue.ToDouble()); - break; - } - } - - return *this; -} - - -Number& -Number::operator-=(const Number& rhs) -{ - switch (fValue.Type()) { - case B_INT8_TYPE: - { - fValue.SetTo((int8)(fValue.ToInt8() - rhs.fValue.ToInt8())); - break; - } - - case B_UINT8_TYPE: - { - fValue.SetTo((uint8)(fValue.ToUInt8() - rhs.fValue.ToUInt8())); - break; - } - - case B_INT16_TYPE: - { - fValue.SetTo((int16)(fValue.ToInt16() - rhs.fValue.ToInt16())); - break; - } - - case B_UINT16_TYPE: - { - fValue.SetTo((uint16)(fValue.ToUInt16() - rhs.fValue.ToUInt16())); - break; - } - - case B_INT32_TYPE: - { - fValue.SetTo(fValue.ToInt32() - rhs.fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - fValue.SetTo(fValue.ToUInt32() - rhs.fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - fValue.SetTo(fValue.ToInt64() - rhs.fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - fValue.SetTo(fValue.ToUInt64() - rhs.fValue.ToUInt64()); - break; - } - - case B_FLOAT_TYPE: - { - fValue.SetTo(fValue.ToFloat() - rhs.fValue.ToFloat()); - break; - } - - case B_DOUBLE_TYPE: - { - fValue.SetTo(fValue.ToDouble() - rhs.fValue.ToDouble()); - break; - } - } - - return *this; -} - - -Number& -Number::operator/=(const Number& rhs) -{ - switch (fValue.Type()) { - case B_INT8_TYPE: - { - fValue.SetTo((int8)(fValue.ToInt8() / rhs.fValue.ToInt8())); - break; - } - - case B_UINT8_TYPE: - { - fValue.SetTo((uint8)(fValue.ToUInt8() / rhs.fValue.ToUInt8())); - break; - } - - case B_INT16_TYPE: - { - fValue.SetTo((int16)(fValue.ToInt16() / rhs.fValue.ToInt16())); - break; - } - - case B_UINT16_TYPE: - { - fValue.SetTo((uint16)(fValue.ToUInt16() / rhs.fValue.ToUInt16())); - break; - } - - case B_INT32_TYPE: - { - fValue.SetTo(fValue.ToInt32() / rhs.fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - fValue.SetTo(fValue.ToUInt32() / rhs.fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - fValue.SetTo(fValue.ToInt64() / rhs.fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - fValue.SetTo(fValue.ToUInt64() / rhs.fValue.ToUInt64()); - break; - } - - case B_FLOAT_TYPE: - { - fValue.SetTo(fValue.ToFloat() / rhs.fValue.ToFloat()); - break; - } - - case B_DOUBLE_TYPE: - { - fValue.SetTo(fValue.ToDouble() / rhs.fValue.ToDouble()); - break; - } - } - - return *this; -} - - -Number& -Number::operator%=(const Number& rhs) -{ - switch (fValue.Type()) { - case B_INT8_TYPE: - { - fValue.SetTo((int8)(fValue.ToInt8() % rhs.fValue.ToInt8())); - break; - } - - case B_UINT8_TYPE: - { - fValue.SetTo((uint8)(fValue.ToUInt8() % rhs.fValue.ToUInt8())); - break; - } - - case B_INT16_TYPE: - { - fValue.SetTo((int16)(fValue.ToInt16() % rhs.fValue.ToInt16())); - break; - } - - case B_UINT16_TYPE: - { - fValue.SetTo((uint16)(fValue.ToUInt16() % rhs.fValue.ToUInt16())); - break; - } - - case B_INT32_TYPE: - { - fValue.SetTo(fValue.ToInt32() % rhs.fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - fValue.SetTo(fValue.ToUInt32() % rhs.fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - fValue.SetTo(fValue.ToInt64() % rhs.fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - fValue.SetTo(fValue.ToUInt64() % rhs.fValue.ToUInt64()); - break; - } - } - - return *this; -} - - -Number& -Number::operator*=(const Number& rhs) -{ - switch (fValue.Type()) { - case B_INT8_TYPE: - { - fValue.SetTo((int8)(fValue.ToInt8() * rhs.fValue.ToInt8())); - break; - } - - case B_UINT8_TYPE: - { - fValue.SetTo((uint8)(fValue.ToUInt8() * rhs.fValue.ToUInt8())); - break; - } - - case B_INT16_TYPE: - { - fValue.SetTo((int16)(fValue.ToInt16() * rhs.fValue.ToInt16())); - break; - } - - case B_UINT16_TYPE: - { - fValue.SetTo((uint16)(fValue.ToUInt16() * rhs.fValue.ToUInt16())); - break; - } - - case B_INT32_TYPE: - { - fValue.SetTo(fValue.ToInt32() * rhs.fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - fValue.SetTo(fValue.ToUInt32() * rhs.fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - fValue.SetTo(fValue.ToInt64() * rhs.fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - fValue.SetTo(fValue.ToUInt64() * rhs.fValue.ToUInt64()); - break; - } - - case B_FLOAT_TYPE: - { - fValue.SetTo(fValue.ToFloat() * rhs.fValue.ToFloat()); - break; - } - - case B_DOUBLE_TYPE: - { - fValue.SetTo(fValue.ToDouble() * rhs.fValue.ToDouble()); - break; - } - } - - return *this; -} - - -Number& -Number::operator&=(const Number& rhs) -{ - switch (fValue.Type()) { - case B_INT8_TYPE: - { - fValue.SetTo((int8)(fValue.ToInt8() & rhs.fValue.ToInt8())); - break; - } - - case B_UINT8_TYPE: - { - fValue.SetTo((uint8)(fValue.ToUInt8() & rhs.fValue.ToUInt8())); - break; - } - - case B_INT16_TYPE: - { - fValue.SetTo((int16)(fValue.ToInt16() & rhs.fValue.ToInt16())); - break; - } - - case B_UINT16_TYPE: - { - fValue.SetTo((uint16)(fValue.ToUInt16() & rhs.fValue.ToUInt16())); - break; - } - - case B_INT32_TYPE: - { - fValue.SetTo(fValue.ToInt32() & rhs.fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - fValue.SetTo(fValue.ToUInt32() & rhs.fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - fValue.SetTo(fValue.ToInt64() & rhs.fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - fValue.SetTo(fValue.ToUInt64() & rhs.fValue.ToUInt64()); - break; - } - } - - return *this; -} - - -Number& -Number::operator|=(const Number& rhs) -{ - switch (fValue.Type()) { - case B_INT8_TYPE: - { - fValue.SetTo((int8)(fValue.ToInt8() | rhs.fValue.ToInt8())); - break; - } - - case B_UINT8_TYPE: - { - fValue.SetTo((uint8)(fValue.ToUInt8() | rhs.fValue.ToUInt8())); - break; - } - - case B_INT16_TYPE: - { - fValue.SetTo((int16)(fValue.ToInt16() | rhs.fValue.ToInt16())); - break; - } - - case B_UINT16_TYPE: - { - fValue.SetTo((uint16)(fValue.ToUInt16() | rhs.fValue.ToUInt16())); - break; - } - - case B_INT32_TYPE: - { - fValue.SetTo(fValue.ToInt32() | rhs.fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - fValue.SetTo(fValue.ToUInt32() | rhs.fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - fValue.SetTo(fValue.ToInt64() | rhs.fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - fValue.SetTo(fValue.ToUInt64() | rhs.fValue.ToUInt64()); - break; - } - } - - return *this; -} - - -Number& -Number::operator^=(const Number& rhs) -{ - switch (fValue.Type()) { - case B_INT8_TYPE: - { - fValue.SetTo((int8)(fValue.ToInt8() ^ rhs.fValue.ToInt8())); - break; - } - - case B_UINT8_TYPE: - { - fValue.SetTo((uint8)(fValue.ToUInt8() ^ rhs.fValue.ToUInt8())); - break; - } - - case B_INT16_TYPE: - { - fValue.SetTo((int16)(fValue.ToInt16() ^ rhs.fValue.ToInt16())); - break; - } - - case B_UINT16_TYPE: - { - fValue.SetTo((uint16)(fValue.ToUInt16() ^ rhs.fValue.ToUInt16())); - break; - } - - case B_INT32_TYPE: - { - fValue.SetTo(fValue.ToInt32() ^ rhs.fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - fValue.SetTo(fValue.ToUInt32() ^ rhs.fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - fValue.SetTo(fValue.ToInt64() ^ rhs.fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - fValue.SetTo(fValue.ToUInt64() ^ rhs.fValue.ToUInt64()); - break; - } - } - - return *this; -} - - -Number -Number::operator-() const -{ - Number value(*this); - - switch (fValue.Type()) { - case B_INT8_TYPE: - { - value.fValue.SetTo((int8)-fValue.ToInt8()); - break; - } - - case B_UINT8_TYPE: - { - value.fValue.SetTo((uint8)-fValue.ToUInt8()); - break; - } - - case B_INT16_TYPE: - { - value.fValue.SetTo((int16)-fValue.ToInt16()); - break; - } - - case B_UINT16_TYPE: - { - value.fValue.SetTo((uint16)-fValue.ToUInt16()); - break; - } - - case B_INT32_TYPE: - { - value.fValue.SetTo(-fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - value.fValue.SetTo(-fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - value.fValue.SetTo(-fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - value.fValue.SetTo(-fValue.ToUInt64()); - break; - } - - case B_FLOAT_TYPE: - { - value.fValue.SetTo(-fValue.ToFloat()); - break; - } - - case B_DOUBLE_TYPE: - { - value.fValue.SetTo(-fValue.ToDouble()); - break; - } - } - - return value; -} - - -Number -Number::operator~() const -{ - Number value(*this); - - switch (fValue.Type()) { - case B_INT8_TYPE: - { - value.fValue.SetTo((int8)~fValue.ToInt8()); - break; - } - - case B_UINT8_TYPE: - { - value.fValue.SetTo((uint8)~fValue.ToUInt8()); - break; - } - - case B_INT16_TYPE: - { - value.fValue.SetTo((int16)~fValue.ToInt16()); - break; - } - - case B_UINT16_TYPE: - { - value.fValue.SetTo((uint16)~fValue.ToUInt16()); - break; - } - - case B_INT32_TYPE: - { - value.fValue.SetTo(~fValue.ToInt32()); - break; - } - - case B_UINT32_TYPE: - { - value.fValue.SetTo(~fValue.ToUInt32()); - break; - } - - case B_INT64_TYPE: - { - value.fValue.SetTo(~fValue.ToInt64()); - break; - } - - case B_UINT64_TYPE: - { - value.fValue.SetTo(~fValue.ToUInt64()); - break; - } - } - - return value; -} - - -int -Number::operator<(const Number& rhs) const -{ - int result = 0; - switch (fValue.Type()) { - case B_INT8_TYPE: - { - result = fValue.ToInt8() < rhs.fValue.ToInt8(); - break; - } - - case B_UINT8_TYPE: - { - result = fValue.ToUInt8() < rhs.fValue.ToUInt8(); - break; - } - - case B_INT16_TYPE: - { - result = fValue.ToInt16() < rhs.fValue.ToInt16(); - break; - } - - case B_UINT16_TYPE: - { - result = fValue.ToUInt16() < rhs.fValue.ToUInt16(); - break; - } - - case B_INT32_TYPE: - { - result = fValue.ToInt32() < rhs.fValue.ToInt32(); - break; - } - - case B_UINT32_TYPE: - { - result = fValue.ToUInt32() < rhs.fValue.ToUInt32(); - break; - } - - case B_INT64_TYPE: - { - result = fValue.ToInt64() < rhs.fValue.ToInt64(); - break; - } - - case B_UINT64_TYPE: - { - result = fValue.ToUInt64() < rhs.fValue.ToUInt64(); - break; - } - - case B_FLOAT_TYPE: - { - result = fValue.ToFloat() < rhs.fValue.ToFloat(); - break; - } - - case B_DOUBLE_TYPE: - { - result = fValue.ToDouble() < rhs.fValue.ToDouble(); - break; - } - } - - return result; -} - - -int -Number::operator<=(const Number& rhs) const -{ - return (*this < rhs) || (*this == rhs); -} - - -int -Number::operator>(const Number& rhs) const -{ - int result = 0; - switch (fValue.Type()) { - case B_INT8_TYPE: - { - result = fValue.ToInt8() > rhs.fValue.ToInt8(); - break; - } - - case B_UINT8_TYPE: - { - result = fValue.ToUInt8() > rhs.fValue.ToUInt8(); - break; - } - - case B_INT16_TYPE: - { - result = fValue.ToInt16() > rhs.fValue.ToInt16(); - break; - } - - case B_UINT16_TYPE: - { - result = fValue.ToUInt16() > rhs.fValue.ToUInt16(); - break; - } - - case B_INT32_TYPE: - { - result = fValue.ToInt32() > rhs.fValue.ToInt32(); - break; - } - - case B_UINT32_TYPE: - { - result = fValue.ToUInt32() > rhs.fValue.ToUInt32(); - break; - } - - case B_INT64_TYPE: - { - result = fValue.ToInt64() > rhs.fValue.ToInt64(); - break; - } - - case B_UINT64_TYPE: - { - result = fValue.ToUInt64() > rhs.fValue.ToUInt64(); - break; - } - - case B_FLOAT_TYPE: - { - result = fValue.ToFloat() > rhs.fValue.ToFloat(); - break; - } - - case B_DOUBLE_TYPE: - { - result = fValue.ToDouble() > rhs.fValue.ToDouble(); - break; - } - } - - return result; -} - - -int -Number::operator>=(const Number& rhs) const -{ - return (*this > rhs) || (*this == rhs); -} - - -int -Number::operator==(const Number& rhs) const -{ - int result = 0; - switch (fValue.Type()) { - case B_INT8_TYPE: - { - result = fValue.ToInt8() == rhs.fValue.ToInt8(); - break; - } - - case B_UINT8_TYPE: - { - result = fValue.ToUInt8() == rhs.fValue.ToUInt8(); - break; - } - - case B_INT16_TYPE: - { - result = fValue.ToInt16() == rhs.fValue.ToInt16(); - break; - } - - case B_UINT16_TYPE: - { - result = fValue.ToUInt16() == rhs.fValue.ToUInt16(); - break; - } - - case B_INT32_TYPE: - { - result = fValue.ToInt32() == rhs.fValue.ToInt32(); - break; - } - - case B_UINT32_TYPE: - { - result = fValue.ToUInt32() == rhs.fValue.ToUInt32(); - break; - } - - case B_INT64_TYPE: - { - result = fValue.ToInt64() == rhs.fValue.ToInt64(); - break; - } - - case B_UINT64_TYPE: - { - result = fValue.ToUInt64() == rhs.fValue.ToUInt64(); - break; - } - - case B_FLOAT_TYPE: - { - result = fValue.ToFloat() == rhs.fValue.ToFloat(); - break; - } - - case B_DOUBLE_TYPE: - { - result = fValue.ToDouble() == rhs.fValue.ToDouble(); - break; - } - } - - return result; -} - - -int -Number::operator!=(const Number& rhs) const -{ - return !(*this == rhs); -} - - -BVariant -Number::GetValue() const -{ - return fValue; -} - diff --git a/src/apps/debugger/types/Number.h b/src/apps/debugger/types/Number.h deleted file mode 100644 index 564cb44f69..0000000000 --- a/src/apps/debugger/types/Number.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014, Rene Gollent, rene@gollent.com. - * Distributed under the terms of the MIT License. - */ -#ifndef NUMBER_H -#define NUMBER_H - -#include - -#include "Variant.h" - - -class BString; - - -class Number { -public: - Number(); - virtual ~Number(); - Number(type_code type, const BString& value); - Number(const BVariant& value); - Number(const Number& other); - - void SetTo(type_code type, const BString& value, - int32 base = 10); - void SetTo(const BVariant& value); - - type_code Type() const { return fValue.Type(); } - - Number& operator=(const Number& rhs); - Number& operator+=(const Number& rhs); - Number& operator-=(const Number& rhs); - Number& operator/=(const Number& rhs); - Number& operator*=(const Number& rhs); - Number& operator%=(const Number& rhs); - - Number& operator&=(const Number& rhs); - Number& operator|=(const Number& rhs); - Number& operator^=(const Number& rhs); - - Number operator-() const; - Number operator~() const; - - int operator<(const Number& rhs) const; - int operator<=(const Number& rhs) const; - int operator>(const Number& rhs) const; - int operator>=(const Number& rhs) const; - int operator==(const Number& rhs) const; - int operator!=(const Number& rhs) const; - - BVariant GetValue() const; - -private: - BVariant fValue; -}; - - -#endif // NUMBER_H diff --git a/src/apps/debugger/user_interface/cli/CliContext.cpp b/src/apps/debugger/user_interface/cli/CliContext.cpp index 12dafaed73..7c97d2d674 100644 --- a/src/apps/debugger/user_interface/cli/CliContext.cpp +++ b/src/apps/debugger/user_interface/cli/CliContext.cpp @@ -12,8 +12,9 @@ #include "StackTrace.h" #include "UserInterface.h" -#include "Value.h" #include "ValueNodeManager.h" +#include "Variable.h" + // NOTE: This is a simple work-around for EditLine not having any kind of user // data field. Hence in _GetPrompt() we don't have access to the context object. @@ -29,7 +30,7 @@ static CliContext* sCurrentContext; struct CliContext::Event : DoublyLinkedListLinkImpl { Event(int type, Thread* thread = NULL, TeamMemoryBlock* block = NULL, ExpressionInfo* info = NULL, status_t expressionResult = B_OK, - Value* expressionValue = NULL) + ExpressionResult* expressionValue = NULL) : fType(type), fThreadReference(thread), @@ -65,7 +66,7 @@ struct CliContext::Event : DoublyLinkedListLinkImpl { return fExpressionResult; } - Value* GetExpressionValue() const + ExpressionResult* GetExpressionValue() const { return fExpressionValue.Get(); } @@ -77,7 +78,7 @@ private: BReference fMemoryBlockReference; BReference fExpressionInfo; status_t fExpressionResult; - BReference fExpressionValue; + BReference fExpressionValue; }; @@ -509,7 +510,7 @@ CliContext::ThreadStackTraceChanged(const Team::ThreadEvent& threadEvent) void CliContext::ExpressionEvaluated(ExpressionInfo* info, status_t result, - Value* value) + ExpressionResult* value) { _QueueEvent( new(std::nothrow) Event(EVENT_EXPRESSION_EVALUATED, diff --git a/src/apps/debugger/user_interface/cli/CliContext.h b/src/apps/debugger/user_interface/cli/CliContext.h index ae2ac4fe62..8232c783c0 100644 --- a/src/apps/debugger/user_interface/cli/CliContext.h +++ b/src/apps/debugger/user_interface/cli/CliContext.h @@ -85,7 +85,7 @@ public: { return fExpressionInfo; } status_t GetExpressionResult() const { return fExpressionResult; } - Value* GetExpressionValue() const + ExpressionResult* GetExpressionValue() const { return fExpressionValue; } const char* PromptUser(const char* prompt); @@ -120,7 +120,7 @@ private: // ExpressionInfo::Listener virtual void ExpressionEvaluated(ExpressionInfo* info, - status_t result, Value* value); + status_t result, ExpressionResult* value); // ValueNodeContainer::Listener virtual void ValueNodeChanged(ValueNodeChild* nodeChild, @@ -160,7 +160,7 @@ private: ExpressionInfo* fExpressionInfo; status_t fExpressionResult; - Value* fExpressionValue; + ExpressionResult* fExpressionValue; EventList fPendingEvents; }; diff --git a/src/apps/debugger/user_interface/cli/commands/CliDumpMemoryCommand.cpp b/src/apps/debugger/user_interface/cli/commands/CliDumpMemoryCommand.cpp index 86a78caa79..9f988f4704 100644 --- a/src/apps/debugger/user_interface/cli/commands/CliDumpMemoryCommand.cpp +++ b/src/apps/debugger/user_interface/cli/commands/CliDumpMemoryCommand.cpp @@ -18,12 +18,12 @@ #include "CliContext.h" #include "CppLanguage.h" -#include "SyntheticPrimitiveType.h" #include "Team.h" #include "TeamMemoryBlock.h" #include "UiUtils.h" #include "UserInterface.h" #include "Value.h" +#include "Variable.h" CliDumpMemoryCommand::CliDumpMemoryCommand() @@ -60,22 +60,7 @@ CliDumpMemoryCommand::Execute(int argc, const char* const* argv, ExpressionInfo* info = context.GetExpressionInfo(); target_addr_t address = 0; - - PrimitiveType* type = dynamic_cast(info->ResultType()); - if (type == NULL || type->TypeConstant() != B_UINT64_TYPE) { - type = new(std::nothrow) SyntheticPrimitiveType( - B_UINT64_TYPE); - if (type == NULL) { - printf("Unable to evaluate expression: %s\n", strerror(B_NO_MEMORY)); - return; - } - - BReference typeReference(type, true); - - info->SetResultType(type); - } - - info->SetExpression(argv[1]); + info->SetTo(argv[1]); context.GetUserInterfaceListener()->ExpressionEvaluationRequested( fLanguage, info); @@ -84,14 +69,17 @@ CliDumpMemoryCommand::Execute(int argc, const char* const* argv, return; BString errorMessage; - Value* value = context.GetExpressionValue(); - if (value != NULL) { - BVariant variantValue; - value->ToVariant(variantValue); - if (variantValue.Type() == B_UINT64_TYPE) - address = variantValue.ToUInt64(); - else - value->ToString(errorMessage); + ExpressionResult* result = context.GetExpressionValue(); + if (result != NULL) { + if (result->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { + Value* value = result->PrimitiveValue(); + BVariant variantValue; + value->ToVariant(variantValue); + if (variantValue.Type() == B_STRING_TYPE) + errorMessage.SetTo(variantValue.ToString()); + else + address = variantValue.ToUInt64(); + } } else errorMessage = strerror(context.GetExpressionResult()); diff --git a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp index 0fd48f0ded..0b9569b34d 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp +++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.cpp @@ -19,12 +19,11 @@ #include "Architecture.h" #include "CppLanguage.h" #include "GuiTeamUiSettings.h" +#include "IntegerValue.h" #include "MemoryView.h" #include "MessageCodes.h" -#include "SyntheticPrimitiveType.h" #include "Team.h" #include "UserInterface.h" -#include "Value.h" enum { @@ -94,9 +93,7 @@ void InspectorWindow::_Init() { fLanguage = new CppLanguage(); - ::Type* type = new SyntheticPrimitiveType(B_UINT64_TYPE); - BReference< ::Type> typeReference(type); - fExpressionInfo = new ExpressionInfo(NULL, type); + fExpressionInfo = new ExpressionInfo(); fExpressionInfo->AddListener(this); BScrollView* scrollView; @@ -236,7 +233,7 @@ InspectorWindow::MessageReceived(BMessage* message) if (fAddressInput->TextView()->TextLength() == 0) break; - fExpressionInfo->SetExpression(fAddressInput->Text()); + fExpressionInfo->SetTo(fAddressInput->Text()); fListener->ExpressionEvaluationRequested(fLanguage, fExpressionInfo); @@ -247,18 +244,22 @@ InspectorWindow::MessageReceived(BMessage* message) case MSG_EXPRESSION_EVALUATED: { BString errorMessage; - BReference reference; - Value* value = NULL; + BReference reference; + ExpressionResult* value = NULL; if (message->FindPointer("value", reinterpret_cast(&value)) == B_OK) { reference.SetTo(value, true); - BVariant variant; - value->ToVariant(variant); - if (variant.Type() == B_UINT64_TYPE) { - _SetToAddress(variant.ToUInt64()); - break; - } else - value->ToString(errorMessage); + if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { + Value* primitive = value->PrimitiveValue(); + BVariant variantValue; + primitive->ToVariant(variantValue); + if (variantValue.Type() == B_STRING_TYPE) { + errorMessage.SetTo(variantValue.ToString()); + } else { + _SetToAddress(variantValue.ToUInt64()); + break; + } + } } else { status_t result = message->FindInt32("result"); errorMessage.SetToFormat("Failed to evaluate expression: %s", @@ -385,11 +386,11 @@ InspectorWindow::TargetAddressChanged(target_addr_t address) void InspectorWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result, - Value* value) + ExpressionResult* value) { BMessage message(MSG_EXPRESSION_EVALUATED); message.AddInt32("result", result); - BReference reference; + BReference reference; if (value != NULL) { reference.SetTo(value); message.AddPointer("value", value); diff --git a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h index 29c951f078..039e087b58 100644 --- a/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h +++ b/src/apps/debugger/user_interface/gui/inspector_window/InspectorWindow.h @@ -55,7 +55,7 @@ public: // ExpressionInfo::Listener virtual void ExpressionEvaluated(ExpressionInfo* info, - status_t result, Value* value); + status_t result, ExpressionResult* value); status_t LoadSettings( const GuiTeamUiSettings& settings); diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp index 402ee448f7..51a8b7b988 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp @@ -14,6 +14,7 @@ #include "AutoLocker.h" +#include "IntegerValue.h" #include "MessageCodes.h" #include "SourceLanguage.h" #include "StackFrame.h" @@ -21,12 +22,6 @@ #include "Thread.h" #include "UiUtils.h" #include "UserInterface.h" -#include "Value.h" - - -enum { - MSG_CHANGE_EVALUATION_TYPE = 'chet' -}; ExpressionEvaluationWindow::ExpressionEvaluationWindow( @@ -91,9 +86,8 @@ ExpressionEvaluationWindow::Create(SourceLanguage* language, StackFrame* frame, void ExpressionEvaluationWindow::_Init() { - ::Type* type = new SyntheticPrimitiveType(B_INT64_TYPE); - BReference< ::Type> typeReference(type, true); - fExpressionInfo = new ExpressionInfo(NULL, type); + fExpressionInfo = new ExpressionInfo; + fExpressionInfo->AddListener(this); fExpressionInput = new BTextControl("Expression:", NULL, new BMessage(MSG_EVALUATE_EXPRESSION)); @@ -107,16 +101,11 @@ ExpressionEvaluationWindow::_Init() fExpressionOutput->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); - BMenuField* typeField = new BMenuField("Type:", _BuildTypesMenu()); - typeField->Menu()->SetTargetForItems(this); - BLayoutBuilder::Group<>(this, B_VERTICAL) .SetInsets(B_USE_DEFAULT_SPACING) .AddGroup(B_HORIZONTAL, 4.0f) .Add(labelItem) .Add(inputItem) - .Add(typeField->CreateLabelLayoutItem()) - .Add(typeField->CreateMenuBarLayoutItem()) .End() .AddGroup(B_HORIZONTAL, 4.0f) .Add(new BStringView("OutputLabelView", "Result:")) @@ -130,54 +119,18 @@ ExpressionEvaluationWindow::_Init() fExpressionInput->SetTarget(this); fEvaluateButton->SetTarget(this); + fEvaluateButton->MakeDefault(true); fExpressionInput->TextView()->MakeFocus(true); } -BMenu* -ExpressionEvaluationWindow::_BuildTypesMenu() -{ - BMenu* menu = new BMenu("Types"); - menu->SetLabelFromMarked(true); - - _AddMenuItemForType(menu, B_INT8_TYPE); - _AddMenuItemForType(menu, B_UINT8_TYPE); - _AddMenuItemForType(menu, B_INT16_TYPE); - _AddMenuItemForType(menu, B_UINT16_TYPE); - _AddMenuItemForType(menu, B_INT32_TYPE); - _AddMenuItemForType(menu, B_UINT32_TYPE); - BMenuItem* item = _AddMenuItemForType(menu, B_INT64_TYPE); - if (item != NULL) - item->SetMarked(true); - - _AddMenuItemForType(menu, B_UINT64_TYPE); - _AddMenuItemForType(menu, B_FLOAT_TYPE); - _AddMenuItemForType(menu, B_DOUBLE_TYPE); - - return menu; -} - - -BMenuItem* -ExpressionEvaluationWindow::_AddMenuItemForType(BMenu* menu, type_code type) -{ - BMessage *message = new BMessage(MSG_CHANGE_EVALUATION_TYPE); - message->AddInt32("type", type); - - BMenuItem* item = new BMenuItem(UiUtils::TypeCodeToString(type), message); - menu->AddItem(item); - - return item; -} - - void ExpressionEvaluationWindow::ExpressionEvaluated(ExpressionInfo* info, - status_t result, Value* value) + status_t result, ExpressionResult* value) { BMessage message(MSG_EXPRESSION_EVALUATED); message.AddInt32("result", result); - BReference reference; + BReference reference; if (value != NULL) { message.AddPointer("value", value); reference.SetTo(value); @@ -215,35 +168,16 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message) if (fExpressionInput->TextView()->TextLength() == 0) break; - fExpressionInfo->SetExpression(fExpressionInput->Text()); + fExpressionInfo->SetTo(fExpressionInput->Text()); fListener->ExpressionEvaluationRequested(fLanguage, fExpressionInfo, fStackFrame, fThread); break; } - - case MSG_CHANGE_EVALUATION_TYPE: - { - uint32 typeConstant = message->FindInt32("type"); - PrimitiveType* type = dynamic_cast( - fExpressionInfo->ResultType()); - if (type->TypeConstant() == typeConstant) - break; - - type = new(std::nothrow) SyntheticPrimitiveType( - typeConstant); - if (type == NULL) - break; - - BReference< ::Type> typeReference(type, true); - fExpressionInfo->SetResultType(type); - break; - } - case MSG_EXPRESSION_EVALUATED: { - Value* value = NULL; - BReference reference; + ExpressionResult* value = NULL; + BReference reference; if (message->FindPointer("value", reinterpret_cast(&value)) == B_OK) { reference.SetTo(value, true); @@ -251,14 +185,20 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message) BString outputText; if (value != NULL) { - BVariant variantValue; - value->ToVariant(variantValue); - if (variantValue.TypeIsInteger(variantValue.Type())) { - value->ToString(outputText); - outputText.SetToFormat("%#" B_PRIx64 " (%s)", - variantValue.ToUInt64(), outputText.String()); - } else - value->ToString(outputText); + if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { + Value* primitive = value->PrimitiveValue(); + if (dynamic_cast(primitive) != NULL) { + BVariant variantValue; + primitive->ToVariant(variantValue); + primitive->ToString(outputText); + outputText.SetToFormat("%#" B_PRIx64 " (%s)", + variantValue.ToUInt64(), outputText.String()); + } else + primitive->ToString(outputText); + } else { + outputText.SetToFormat("Unsupported result type: %d", + value->Kind()); + } } else { status_t result; if (message->FindInt32("result", &result) != B_OK) @@ -271,8 +211,6 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message) fExpressionOutput->SetText(outputText); break; } - - default: BWindow::MessageReceived(message); break; diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h index 3a7da82fa7..e985667b96 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h @@ -9,16 +9,12 @@ #include #include "ExpressionInfo.h" -#include "types/Types.h" -class BMenu; -class BMenuItem; class BButton; class BStringView; class BTextControl; class Thread; -class PrimitiveType; class SourceLanguage; class StackFrame; class UserInterfaceListener; @@ -53,13 +49,10 @@ public: private: void _Init(); - BMenu* _BuildTypesMenu(); - BMenuItem* _AddMenuItemForType(BMenu* menu, - type_code type); // ExpressionInfo::Listener virtual void ExpressionEvaluated(ExpressionInfo* info, - status_t result, Value* value); + status_t result, ExpressionResult* value); private: SourceLanguage* fLanguage; diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp index add0137241..7e59844ee4 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp @@ -6,17 +6,10 @@ #include #include -#include #include #include #include "MessageCodes.h" -#include "UiUtils.h" - - -enum { - MSG_CHANGE_EVALUATION_TYPE = 'chet', -}; ExpressionPromptWindow::ExpressionPromptWindow(BHandler* addTarget, @@ -28,8 +21,7 @@ ExpressionPromptWindow::ExpressionPromptWindow(BHandler* addTarget, fCancelButton(NULL), fAddButton(NULL), fAddTarget(addTarget), - fCloseTarget(closeTarget), - fCurrentType(B_INT64_TYPE) + fCloseTarget(closeTarget) { } @@ -68,16 +60,11 @@ ExpressionPromptWindow::_Init() inputItem->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); labelItem->View()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - BMenuField* typeField = new BMenuField("Type:", _BuildTypesMenu()); - typeField->Menu()->SetTargetForItems(this); - BLayoutBuilder::Group<>(this, B_VERTICAL) .SetInsets(B_USE_DEFAULT_SPACING) .AddGroup(B_HORIZONTAL, 4.0f) .Add(labelItem) .Add(inputItem) - .Add(typeField->CreateLabelLayoutItem()) - .Add(typeField->CreateMenuBarLayoutItem()) .End() .AddGroup(B_HORIZONTAL, 4.0f) .AddGlue() @@ -95,43 +82,6 @@ ExpressionPromptWindow::_Init() } -BMenu* -ExpressionPromptWindow::_BuildTypesMenu() -{ - BMenu* menu = new BMenu("Types"); - menu->SetLabelFromMarked(true); - - _AddMenuItemForType(menu, B_INT8_TYPE); - _AddMenuItemForType(menu, B_UINT8_TYPE); - _AddMenuItemForType(menu, B_INT16_TYPE); - _AddMenuItemForType(menu, B_UINT16_TYPE); - _AddMenuItemForType(menu, B_INT32_TYPE); - _AddMenuItemForType(menu, B_UINT32_TYPE); - BMenuItem* item = _AddMenuItemForType(menu, B_INT64_TYPE); - if (item != NULL) - item->SetMarked(true); - - _AddMenuItemForType(menu, B_UINT64_TYPE); - _AddMenuItemForType(menu, B_FLOAT_TYPE); - _AddMenuItemForType(menu, B_DOUBLE_TYPE); - - return menu; -} - - -BMenuItem* -ExpressionPromptWindow::_AddMenuItemForType(BMenu* menu, type_code type) -{ - BMessage *message = new BMessage(MSG_CHANGE_EVALUATION_TYPE); - message->AddInt32("type", type); - - BMenuItem* item = new BMenuItem(UiUtils::TypeCodeToString(type), message); - menu->AddItem(item); - - return item; -} - - void ExpressionPromptWindow::Show() { @@ -154,17 +104,10 @@ void ExpressionPromptWindow::MessageReceived(BMessage* message) { switch (message->what) { - case MSG_CHANGE_EVALUATION_TYPE: - { - fCurrentType = message->FindInt32("type"); - break; - } - case MSG_ADD_NEW_EXPRESSION: { BMessage addMessage(MSG_EXPRESSION_PROMPT_WINDOW_CLOSED); addMessage.AddString("expression", fExpressionInput->Text()); - addMessage.AddInt32("type", fCurrentType); addMessage.AddMessenger("target", BMessenger(fAddTarget)); BMessenger(fCloseTarget).SendMessage(&addMessage); diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h index 024577d1d4..ce18792f55 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h @@ -10,8 +10,6 @@ class BButton; -class BMenu; -class BMenuItem; class BTextControl; @@ -35,9 +33,6 @@ public: private: void _Init(); - BMenu* _BuildTypesMenu(); - BMenuItem* _AddMenuItemForType(BMenu* menu, - type_code type); private: BTextControl* fExpressionInput; @@ -45,7 +40,6 @@ private: BButton* fAddButton; BHandler* fAddTarget; BHandler* fCloseTarget; - type_code fCurrentType; }; #endif // EXPRESSION_PROMPT_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index f4c783ce0e..0f8f101fda 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -406,15 +406,12 @@ TeamWindow::MessageReceived(BMessage* message) fExpressionPromptWindow = NULL; const char* expression; - int32 type; BMessenger targetMessenger; if (message->FindString("expression", &expression) == B_OK - && message->FindInt32("type", &type) == B_OK && message->FindMessenger("target", &targetMessenger) == B_OK) { BMessage addMessage(MSG_ADD_NEW_EXPRESSION); addMessage.AddString("expression", expression); - addMessage.AddInt32("type", type); targetMessenger.SendMessage(&addMessage); } diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 5787aea853..1ed17992e1 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -1944,18 +1944,11 @@ VariablesView::MessageReceived(BMessage* message) case MSG_ADD_NEW_EXPRESSION: { const char* expression; - int32 type; - Type* resultType; - if (message->FindString("expression", &expression) != B_OK - || message->FindInt32("type", &type) != B_OK - || _GetTypeForTypeCode(type, resultType) != B_OK) { + if (message->FindString("expression", &expression) != B_OK) break; - } - - BReference typeReference(resultType, true); ExpressionInfo* info; - status_t error = _AddExpression(expression, resultType, info); + status_t error = _AddExpression(expression, info); if (error != B_OK) { // TODO: notify user of failure break; @@ -1969,14 +1962,14 @@ VariablesView::MessageReceived(BMessage* message) { ExpressionInfo* info; status_t result; - Value* value = NULL; + ExpressionResult* value = NULL; if (message->FindPointer("info", reinterpret_cast(&info)) != B_OK || message->FindInt32("result", &result) != B_OK) { break; } - BReference valueReference; + BReference valueReference; if (message->FindPointer("value", reinterpret_cast(&value)) == B_OK) { valueReference.SetTo(value, true); @@ -2231,12 +2224,12 @@ VariablesView::TreeTableCellMouseDown(TreeTable* table, void VariablesView::ExpressionEvaluated(ExpressionInfo* info, status_t result, - Value* value) + ExpressionResult* value) { BMessage message(MSG_EXPRESSION_EVALUATED); message.AddPointer("info", info); message.AddInt32("result", result); - BReference valueReference; + BReference valueReference; if (value != NULL) { valueReference.SetTo(value); @@ -2417,6 +2410,7 @@ VariablesView::_GetContextActionsForNode(ModelNode* node, BPrivate::ObjectDeleter postActionListDeleter( _postActions); +#if 0 result = _AddContextAction("Add watch expression" B_UTF8_ELLIPSIS, MSG_ADD_WATCH_EXPRESSION, _postActions, message); if (result != B_OK) @@ -2429,6 +2423,7 @@ VariablesView::_GetContextActionsForNode(ModelNode* node, return result; message->AddPointer("node", node); } +#endif preActionListDeleter.Detach(); postActionListDeleter.Detach(); @@ -2748,8 +2743,7 @@ VariablesView::_CopyVariableValueToClipboard() status_t -VariablesView::_AddExpression(const char* expression, Type* resultType, - ExpressionInfo*& _info) +VariablesView::_AddExpression(const char* expression, ExpressionInfo*& _info) { // if our stack frame doesn't have an associated function, // we can't add an expression @@ -2775,8 +2769,7 @@ VariablesView::_AddExpression(const char* expression, Type* resultType, } } - ExpressionInfo* info = new(std::nothrow) ExpressionInfo(expression, - resultType); + ExpressionInfo* info = new(std::nothrow) ExpressionInfo(expression); if (info == NULL) return B_NO_MEMORY; @@ -2829,7 +2822,7 @@ VariablesView::_RemoveExpression(ModelNode* node) status_t VariablesView::_AddExpressionNode(ExpressionInfo* info) { - Type* type = info->ResultType(); +#if 0 ExpressionValueNodeChild* child = new(std::nothrow) ExpressionValueNodeChild(info->Expression(), type); if (child == NULL) @@ -2859,7 +2852,10 @@ VariablesView::_AddExpressionNode(ExpressionInfo* info) expressionNodeReference.Detach(); modelNodeReference.Detach(); + return B_OK; +#endif + return B_NOT_SUPPORTED; } @@ -2890,7 +2886,7 @@ VariablesView::_RestoreExpressionNodes() void VariablesView::_SetExpressionNodeValue(ExpressionInfo* info, status_t result, - Value* value) + ExpressionResult* value) { FunctionInstance* instance = fStackFrame->Function(); if (instance == NULL) @@ -2918,7 +2914,8 @@ VariablesView::_SetExpressionNodeValue(ExpressionInfo* info, status_t result, if (child->GetExpression() != info->Expression()) continue; - child->Node()->SetLocationAndValue(NULL, value, result); + child->Node()->SetLocationAndValue(NULL, value->PrimitiveValue(), + result); return; } } diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h index 8abb333647..0ce8062e40 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -66,7 +66,7 @@ private: // ExpressionInfo::Listener virtual void ExpressionEvaluated(ExpressionInfo* info, - status_t result, Value* value); + status_t result, ExpressionResult* value); private: class ContainerListener; @@ -110,7 +110,6 @@ private: void _CopyVariableValueToClipboard(); status_t _AddExpression(const char* expression, - Type* resultType, ExpressionInfo*& _info); void _RemoveExpression(ModelNode* node); @@ -118,7 +117,7 @@ private: void _RestoreExpressionNodes(); void _SetExpressionNodeValue(ExpressionInfo* info, - status_t result, Value* value); + status_t result, ExpressionResult* value); status_t _GetTypeForTypeCode(int32 typeCode, Type*& _resultType) const; diff --git a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp index b45bbca516..218599ee62 100644 --- a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.cpp @@ -17,10 +17,10 @@ #include "Architecture.h" #include "CppLanguage.h" +#include "IntegerValue.h" #include "MessageCodes.h" #include "SyntheticPrimitiveType.h" #include "UserInterface.h" -#include "Value.h" #include "Watchpoint.h" @@ -91,21 +91,15 @@ WatchPromptWindow::_Init() { fLanguage = new CppLanguage(); - PrimitiveType* type = new SyntheticPrimitiveType(B_UINT64_TYPE); - BReference typeReference(type, true); - BString text; text.SetToFormat("0x%" B_PRIx64, fInitialAddress); fAddressInput = new BTextControl("Address:", text, NULL); - fAddressExpressionInfo = new ExpressionInfo(text, type); + fAddressExpressionInfo = new ExpressionInfo(text); fAddressExpressionInfo->AddListener(this); - type = new SyntheticPrimitiveType(B_INT32_TYPE); - typeReference.SetTo(type, true); - text.SetToFormat("%" B_PRId32, fInitialLength); fLengthInput = new BTextControl("Length:", text, NULL); - fLengthExpressionInfo = new ExpressionInfo(text, type); + fLengthExpressionInfo = new ExpressionInfo(text); fLengthExpressionInfo->AddListener(this); int32 maxDebugRegisters = 0; @@ -170,11 +164,12 @@ WatchPromptWindow::Show() void WatchPromptWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result, - Value* value) + ExpressionResult* value) { BMessage message(MSG_EXPRESSION_EVALUATED); message.AddInt32("result", result); - BReference reference; + message.AddPointer("info", info); + BReference reference; if (value != NULL) { reference.SetTo(value); message.AddPointer("value", value); @@ -192,20 +187,32 @@ WatchPromptWindow::MessageReceived(BMessage* message) case MSG_EXPRESSION_EVALUATED: { BString errorMessage; - BReference reference; - Value* value = NULL; + BReference reference; + ExpressionResult* value = NULL; + ExpressionInfo* info = NULL; + if (message->FindPointer("info", + reinterpret_cast(&info)) != B_OK) { + break; + } + if (message->FindPointer("value", reinterpret_cast(&value)) == B_OK) { reference.SetTo(value, true); - BVariant variant; - value->ToVariant(variant); - if (variant.Type() == B_UINT64_TYPE) { - fRequestedAddress = variant.ToUInt64(); - break; - } else if (variant.Type() == B_INT32_TYPE) - fRequestedLength = variant.ToInt32(); - else - value->ToString(errorMessage); + if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { + Value* primitive = value->PrimitiveValue(); + if (dynamic_cast(primitive) != NULL) { + BVariant resultVariant; + primitive->ToVariant(resultVariant); + if (info == fAddressExpressionInfo) { + fRequestedAddress = resultVariant.ToUInt64(); + break; + } else + fRequestedLength = resultVariant.ToInt32(); + } + else + primitive->ToString(errorMessage); + } else + errorMessage.SetTo("Unsupported expression result."); } else { status_t result = message->FindInt32("result"); errorMessage.SetToFormat("Failed to evaluate expression: %s", @@ -237,11 +244,11 @@ WatchPromptWindow::MessageReceived(BMessage* message) fRequestedAddress = 0; fRequestedLength = 0; - fAddressExpressionInfo->SetExpression(fAddressInput->Text()); + fAddressExpressionInfo->SetTo(fAddressInput->Text()); fListener->ExpressionEvaluationRequested(fLanguage, fAddressExpressionInfo); - fLengthExpressionInfo->SetExpression(fLengthInput->Text()); + fLengthExpressionInfo->SetTo(fLengthInput->Text()); fListener->ExpressionEvaluationRequested(fLanguage, fLengthExpressionInfo); break; diff --git a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.h b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.h index 2c46597ec6..eb45ea6faa 100644 --- a/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/WatchPromptWindow.h @@ -43,7 +43,7 @@ public: // ExpressionInfo::Listener virtual void ExpressionEvaluated(ExpressionInfo* info, - status_t result, Value* value); + status_t result, ExpressionResult* value); private: void _Init();