[haiku-commits] haiku: hrev48361 - in src/apps/debugger: source_language/expression_evaluators user_interface/gui/team_window types . model

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 22 Nov 2014 23:19:51 +0100 (CET)

hrev48361 adds 2 changesets to branch 'master'
old head: 8d48eb9311edaabd52ef4f6ba9ff22fd89de413f
new head: b4a861136b9249eefc78a47528e5f4e515c633c6
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=b4a8611+%5E8d48eb9

----------------------------------------------------------------------------

81c848a: Debugger: Rework expression parsing API.
  
  ExpressionInfo:
  - No longer stores an explicit result type (this is inferred from
    evaluation of the expression itself now).
  - Introduce class ExpressionResult for returning the result of an
    expression computation. This can currently take the form of either
    a primitive value, or a value node object.
  - Adjust UserInterfaceListener and ExpressionInfo::Listener to take
    the above changes into account, and correspondingly adjust all
    callers/listeners.
  
  CLanguageExpressionEvaluator:
  - Introduce child class Operand. This subsumes the functionality that
    was previously in the separate Number class, and can represent a
    primitive value, a value node or  a type. Also has functionality to
    implicity handle type promotion/inferring when performing calculations
    between operands.
  - Adjust expression parser to operate in terms of Operands rather than
    Numbers. This allows a number of improvements, most notably that an
    expression can now return a value node as a result rather than only
    a primitive number. This capability isn't yet fully used, but paves
    the way for future uses such as an expression that evaluates to a data
    member, a global variable, or an arbitrary pointer of a particular type.
  - Various cleanups/simplifications that were possible as a result of the above
    changes.
  
  ExpressionEvaluationWindow/ExpressionPromptWindow:
  - Remove type menu field, since the expression API no longer uses it.
  
  Adding/removing expressions in the VariablesView is temporarily disabled,
  pending some further rework there to properly handle the new result object.

b4a8611: Debugger: Adjust VariablesView for new expression API.
  
  - Simplify handling of expression nodes. For primitive results, we now
    construct a Variable object that represents the expression result, and
    then add that as we would any other local variable. This simplifies 
handling,
    and also allows saving/restoration of their view state to be handled the
    same as other nodes. Complex expression results aren't yet handled properly,
    pending some further work in progress on the evaluator.

                                         [ Rene Gollent <rene@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

30 files changed, 1982 insertions(+), 1890 deletions(-)
src/apps/debugger/Jamfile                        |    1 -
src/apps/debugger/controllers/ThreadHandler.cpp  |   54 +-
src/apps/debugger/controllers/ThreadHandler.h    |    7 +-
.../debugger/jobs/ExpressionEvaluationJob.cpp    |    5 +-
src/apps/debugger/jobs/Jobs.h                    |    5 +-
src/apps/debugger/model/ExpressionInfo.cpp       |  118 +-
src/apps/debugger/model/ExpressionInfo.h         |   53 +-
.../debugger/source_language/CLanguageFamily.cpp |   52 +-
.../debugger/source_language/CLanguageFamily.h   |    5 +-
.../debugger/source_language/SourceLanguage.cpp  |    2 +-
.../debugger/source_language/SourceLanguage.h    |    7 +-
.../CLanguageExpressionEvaluator.cpp             | 1739 +++++++++++++++---
.../CLanguageExpressionEvaluator.h               |   24 +-
src/apps/debugger/types/Number.cpp               | 1008 ----------
src/apps/debugger/types/Number.h                 |   58 -
.../debugger/user_interface/cli/CliContext.cpp   |   11 +-
.../debugger/user_interface/cli/CliContext.h     |    6 +-
.../cli/commands/CliDumpMemoryCommand.cpp        |   38 +-
.../gui/inspector_window/InspectorWindow.cpp     |   35 +-
.../gui/inspector_window/InspectorWindow.h       |    2 +-
.../team_window/ExpressionEvaluationWindow.cpp   |  108 +-
.../gui/team_window/ExpressionEvaluationWindow.h |    9 +-
.../gui/team_window/ExpressionPromptWindow.cpp   |   59 +-
.../gui/team_window/ExpressionPromptWindow.h     |    6 -
.../gui/team_window/TeamWindow.cpp               |    3 -
.../gui/team_window/VariablesView.cpp            |  386 ++--
.../gui/team_window/VariablesView.h              |   12 +-
.../gui/team_window/WatchPromptWindow.cpp        |   55 +-
.../gui/team_window/WatchPromptWindow.h          |    2 +-
.../debugger/user_interface/util/UiUtils.cpp     |    2 +

############################################################################

Commit:      81c848a14a380679a439cccb9e10b60d05bd6fbc
URL:         http://cgit.haiku-os.org/haiku/commit/?id=81c848a
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Sat Nov 15 05:31:17 2014 UTC

Debugger: Rework expression parsing API.

ExpressionInfo:
- No longer stores an explicit result type (this is inferred from
  evaluation of the expression itself now).
- Introduce class ExpressionResult for returning the result of an
  expression computation. This can currently take the form of either
  a primitive value, or a value node object.
- Adjust UserInterfaceListener and ExpressionInfo::Listener to take
  the above changes into account, and correspondingly adjust all
  callers/listeners.

CLanguageExpressionEvaluator:
- Introduce child class Operand. This subsumes the functionality that
  was previously in the separate Number class, and can represent a
  primitive value, a value node or  a type. Also has functionality to
  implicity handle type promotion/inferring when performing calculations
  between operands.
- Adjust expression parser to operate in terms of Operands rather than
  Numbers. This allows a number of improvements, most notably that an
  expression can now return a value node as a result rather than only
  a primitive number. This capability isn't yet fully used, but paves
  the way for future uses such as an expression that evaluates to a data
  member, a global variable, or an arbitrary pointer of a particular type.
- Various cleanups/simplifications that were possible as a result of the above
  changes.

ExpressionEvaluationWindow/ExpressionPromptWindow:
- Remove type menu field, since the expression API no longer uses it.

Adding/removing expressions in the VariablesView is temporarily disabled,
pending some further rework there to properly handle the new result object.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index cb3317a..15787ae 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 18c5ecc..f513d71 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<Type> 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)
@@ -961,6 +946,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
 {
        return fDebuggerInterface->GetArchitecture()->StackGrowthDirection()
diff --git a/src/apps/debugger/controllers/ThreadHandler.h 
b/src/apps/debugger/controllers/ThreadHandler.h
index 86b5307..eb34741 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 a65879d..52b5cc1 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<PrimitiveType*>(
-               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 2c8db45..65a0ab0 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 bdbfab7..9aaf0d6 100644
--- a/src/apps/debugger/model/ExpressionInfo.cpp
+++ b/src/apps/debugger/model/ExpressionInfo.cpp
@@ -6,67 +6,120 @@
 
 #include "ExpressionInfo.h"
 
-#include "Type.h"
+#include "Value.h"
+#include "ValueNode.h"
 
 
-ExpressionInfo::ExpressionInfo()
+// #pragma mark - ExpressionResult
+
+
+ExpressionResult::ExpressionResult()
        :
-       fExpression(),
-       fResultType(NULL)
+       fResultKind(EXPRESSION_RESULT_KIND_UNKNOWN),
+       fPrimitiveValue(NULL),
+       fValueNodeValue(NULL)
 {
 }
 
 
-ExpressionInfo::ExpressionInfo(const ExpressionInfo& other)
-       :
-       fExpression(other.fExpression),
-       fResultType(other.fResultType)
+ExpressionResult::~ExpressionResult()
 {
-       if (fResultType != NULL)
-               fResultType->AcquireReference();
+       if (fPrimitiveValue != NULL)
+               fPrimitiveValue->ReleaseReference();
+
+       if (fValueNodeValue != NULL)
+               fValueNodeValue->ReleaseReference();
 }
 
 
-ExpressionInfo::~ExpressionInfo()
+void
+ExpressionResult::SetToPrimitive(Value* value)
 {
-       SetResultType(NULL);
+       _Unset();
+
+       fPrimitiveValue = value;
+       if (fPrimitiveValue != NULL) {
+               fPrimitiveValue->AcquireReference();
+               fResultKind = EXPRESSION_RESULT_KIND_PRIMITIVE;
+       }
 }
 
 
-ExpressionInfo::ExpressionInfo(const BString& expression, Type* resultType)
-       :
-       fExpression(expression),
-       fResultType(resultType)
+void
+ExpressionResult::SetToValueNode(ValueNodeChild* child)
 {
-       if (resultType != NULL)
-               resultType->AcquireReference();
+       _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
-ExpressionInfo::SetTo(const BString& expression, Type* resultType)
+ExpressionResult::_Unset()
 {
-       SetExpression(expression);
-       SetResultType(resultType);
+       if (fPrimitiveValue != NULL) {
+               fPrimitiveValue->ReleaseReference();
+               fPrimitiveValue = NULL;
+       }
+
+       if (fValueNodeValue != NULL) {
+               fValueNodeValue->ReleaseReference();
+               fValueNodeValue = NULL;
+       }
+
+       fResultKind = EXPRESSION_RESULT_KIND_UNKNOWN;
 }
 
 
-void
-ExpressionInfo::SetExpression(const BString& expression)
+// #pragma mark - ExpressionInfo
+
+
+ExpressionInfo::ExpressionInfo()
+       :
+       fExpression()
 {
-       fExpression = expression;
 }
 
 
-void
-ExpressionInfo::SetResultType(Type* resultType)
+ExpressionInfo::ExpressionInfo(const ExpressionInfo& other)
+       :
+       fExpression(other.fExpression)
+{
+}
+
+
+ExpressionInfo::~ExpressionInfo()
 {
-       if (fResultType != NULL)
-               fResultType->ReleaseReference();
+}
+
 
-       fResultType = resultType;
-       if (fResultType != NULL)
-               fResultType->AcquireReference();
+ExpressionInfo::ExpressionInfo(const BString& expression)
+       :
+       fExpression(expression)
+{
+}
+
+
+void
+ExpressionInfo::SetTo(const BString& expression)
+{
+       fExpression = expression;
 }
 
 
@@ -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 33c5e8b..feab5c4 100644
--- a/src/apps/debugger/model/ExpressionInfo.h
+++ b/src/apps/debugger/model/ExpressionInfo.h
@@ -10,9 +10,44 @@
 
 #include <Referenceable.h>
 #include <util/DoublyLinkedList.h>
+#include <Variant.h>
+
 
-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<Listener> 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 88c6be7..96f7937 100644
--- a/src/apps/debugger/source_language/CLanguageFamily.cpp
+++ b/src/apps/debugger/source_language/CLanguageFamily.cpp
@@ -11,11 +11,9 @@
 #include <stdlib.h>
 
 #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<Value> 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 7159df0..62fa17c 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 7f16327..5d7e6ec 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 c732b3b..2133100 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 4d6574e..f4d5067 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 <algorithm>
+
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -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,143 +30,1402 @@
 #include "ValueNode.h"
 #include "ValueNodeManager.h"
 #include "Variable.h"
+#include "VariableValueNodeChild.h"
+
+
+enum {
+       TOKEN_NONE                                      = 0,
+       TOKEN_IDENTIFIER,
+       TOKEN_CONSTANT,
+       TOKEN_END_OF_LINE,
+
+       TOKEN_PLUS,
+       TOKEN_MINUS,
+
+       TOKEN_STAR,
+       TOKEN_SLASH,
+       TOKEN_MODULO,
+
+       TOKEN_POWER,
+
+       TOKEN_OPENING_BRACKET,
+       TOKEN_CLOSING_BRACKET,
+
+       TOKEN_LOGICAL_AND,
+       TOKEN_LOGICAL_OR,
+       TOKEN_LOGICAL_NOT,
+       TOKEN_BITWISE_AND,
+       TOKEN_BITWISE_OR,
+       TOKEN_BITWISE_NOT,
+       TOKEN_BITWISE_XOR,
+       TOKEN_EQ,
+       TOKEN_NE,
+       TOKEN_GT,
+       TOKEN_GE,
+       TOKEN_LT,
+       TOKEN_LE,
+
+       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;
+
+       switch (type) {
+               case TOKEN_PLUS:
+                       token = "+";
+                       break;
+
+               case TOKEN_MINUS:
+                       token = "-";
+                       break;
+
+               case TOKEN_STAR:
+                       token = "*";
+                       break;
+
+               case TOKEN_SLASH:
+                       token = "/";
+                       break;
+
+               case TOKEN_MODULO:
+                       token = "%";
+                       break;
+
+               case TOKEN_POWER:
+                       token = "**";
+                       break;
+
+               case TOKEN_OPENING_BRACKET:
+                       token = "(";
+                       break;
+
+               case TOKEN_CLOSING_BRACKET:
+                       token = ")";
+                       break;
+
+               case TOKEN_LOGICAL_AND:
+                       token = "&&";
+                       break;
+
+               case TOKEN_LOGICAL_OR:
+                       token = "||";
+                       break;
+
+               case TOKEN_LOGICAL_NOT:
+                       token = "!";
+                       break;
+
+               case TOKEN_BITWISE_AND:
+                       token = "&";
+                       break;
+
+               case TOKEN_BITWISE_OR:
+                       token = "|";
+                       break;
+
+               case TOKEN_BITWISE_NOT:
+                       token = "~";
+                       break;
+
+               case TOKEN_BITWISE_XOR:
+                       token = "^";
+                       break;
+
+               case TOKEN_EQ:
+                       token = "==";
+                       break;
+
+               case TOKEN_NE:
+                       token = "!=";
+                       break;
+
+               case TOKEN_GT:
+                       token = ">";
+                       break;
+
+               case TOKEN_GE:
+                       token = ">=";
+                       break;
+
+               case TOKEN_LT:
+                       token = "<";
+                       break;
+
+               case TOKEN_LE:
+                       token = "<=";
+                       break;
+
+               case TOKEN_MEMBER_PTR:
+                       token = "->";
+                       break;
+
+               default:
+                       token.SetToFormat("Unknown token type %" B_PRId32, 
type);
+                       break;
+       }
+
+       return token;
+}
+
+
+// #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;
+                       }
+               }
 
-enum {
-       TOKEN_NONE                                      = 0,
-       TOKEN_IDENTIFIER,
-       TOKEN_CONSTANT,
-       TOKEN_END_OF_LINE,
+               return result;
+       }
 
-       TOKEN_PLUS,
-       TOKEN_MINUS,
+       int operator>=(const Operand& rhs) const
+       {
+               return (*this > rhs) || (*this == rhs);
+       }
 
-       TOKEN_STAR,
-       TOKEN_SLASH,
-       TOKEN_MODULO,
+       int     operator==(const Operand& rhs) const
+       {
+               Operand lhs = *this;
+               Operand temp = rhs;
+               lhs._ResolveTypesIfNeeded(temp);
 
-       TOKEN_POWER,
+               int result = 0;
+               switch (fPrimitive.Type()) {
+                       case B_INT8_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToInt8() == 
temp.fPrimitive.ToInt8();
+                               break;
+                       }
 
-       TOKEN_OPENING_BRACKET,
-       TOKEN_CLOSING_BRACKET,
+                       case B_UINT8_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToUInt8() == 
temp.fPrimitive.ToUInt8();
+                               break;
+                       }
 
-       TOKEN_LOGICAL_AND,
-       TOKEN_LOGICAL_OR,
-       TOKEN_LOGICAL_NOT,
-       TOKEN_BITWISE_AND,
-       TOKEN_BITWISE_OR,
-       TOKEN_BITWISE_NOT,
-       TOKEN_BITWISE_XOR,
-       TOKEN_EQ,
-       TOKEN_NE,
-       TOKEN_GT,
-       TOKEN_GE,
-       TOKEN_LT,
-       TOKEN_LE,
+                       case B_INT16_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToInt16() == 
temp.fPrimitive.ToInt16();
+                               break;
+                       }
 
-       TOKEN_MEMBER_PTR
-};
+                       case B_UINT16_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToUInt16()
+                                       == temp.fPrimitive.ToUInt16();
+                               break;
+                       }
 
-static BString TokenTypeToString(int32 type)
-{
-       BString token;
+                       case B_INT32_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToInt32() == 
temp.fPrimitive.ToInt32();
+                               break;
+                       }
 
-       switch (type) {
-               case TOKEN_PLUS:
-                       token = "+";
-                       break;
+                       case B_UINT32_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToUInt32()
+                                       == temp.fPrimitive.ToUInt32();
+                               break;
+                       }
 
-               case TOKEN_MINUS:
-                       token = "-";
-                       break;
+                       case B_INT64_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToInt64() == 
temp.fPrimitive.ToInt64();
+                               break;
+                       }
 
-               case TOKEN_STAR:
-                       token = "*";
-                       break;
+                       case B_UINT64_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToUInt64()
+                                       == temp.fPrimitive.ToUInt64();
+                               break;
+                       }
 
-               case TOKEN_SLASH:
-                       token = "/";
-                       break;
+                       case B_FLOAT_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToFloat() == 
temp.fPrimitive.ToFloat();
+                               break;
+                       }
 
-               case TOKEN_MODULO:
-                       token = "%";
-                       break;
+                       case B_DOUBLE_TYPE:
+                       {
+                               result = lhs.fPrimitive.ToDouble()
+                                       == temp.fPrimitive.ToDouble();
+                               break;
+                       }
+               }
 
-               case TOKEN_POWER:
-                       token = "**";
-                       break;
+               return result;
+       }
 
-               case TOKEN_OPENING_BRACKET:
-                       token = "(";
-                       break;
+       int operator!=(const Operand& rhs) const
+       {
+               return !(*this == rhs);
+       }
 
-               case TOKEN_CLOSING_BRACKET:
-                       token = ")";
-                       break;
+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;
+               }
+       }
 
-               case TOKEN_LOGICAL_AND:
-                       token = "&&";
-                       break;
+       void _ResolveTypesIfNeeded(Operand& other)
+       {
+               _ResolveToPrimitive();
+               other._ResolveToPrimitive();
 
-               case TOKEN_LOGICAL_OR:
-                       token = "||";
-                       break;
+               if (!fPrimitive.IsNumber() || !other.fPrimitive.IsNumber()) {
+                               throw ParseException("Cannot perform 
mathematical operations "
+                                       "between non-numerical objects.", 0);
+               }
 
-               case TOKEN_LOGICAL_NOT:
-                       token = "!";
-                       break;
+               type_code thisType = fPrimitive.Type();
+               type_code otherType = other.fPrimitive.Type();
 
-               case TOKEN_BITWISE_AND:
-                       token = "&";
-                       break;
+               if (thisType == otherType)
+                       return;
 
-               case TOKEN_BITWISE_OR:
-                       token = "|";
-                       break;
+               type_code resolvedType = _ResolvePriorityType(thisType, 
otherType);
+               if (thisType != resolvedType)
+                       _GetAsType(resolvedType);
 
-               case TOKEN_BITWISE_NOT:
-                       token = "~";
-                       break;
+               if (otherType != resolvedType)
+                       other._GetAsType(resolvedType);
+       }
 
-               case TOKEN_BITWISE_XOR:
-                       token = "^";
-                       break;
+       void _ResolveToPrimitive()
+       {
+               if (Kind() == OPERAND_KIND_PRIMITIVE)
+                       return;
+               else if (Kind() == OPERAND_KIND_TYPE) {
+                       throw ParseException("Cannot perform mathematical 
operations "
+                               "between type objects.", 0);
+               }
 
-               case TOKEN_EQ:
-                       token = "==";
-                       break;
+               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);
+               }
 
-               case TOKEN_NE:
-                       token = "!=";
-                       break;
+               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);
+               }
+       }
 
-               case TOKEN_GT:
-                       token = ">";
-                       break;
+       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);
+               }
 
-               case TOKEN_GE:
-                       token = ">=";
-                       break;
+               if (isFloat) {
+                       if (byteSize == sizeof(float))
+                               return B_FLOAT_TYPE;
+                       return B_DOUBLE_TYPE;
+               }
 
-               case TOKEN_LT:
-                       token = "<";
-                       break;
+               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;
+               }
 
-               case TOKEN_LE:
-                       token = "<=";
-                       break;
+               BString error;
+               error.SetToFormat("Unable to reconcile types %#" B_PRIx32
+                       " and %#" B_PRIx32, lhs, rhs);
+               throw ParseException(error.String(), 0);
+       }
 
-               case TOKEN_MEMBER_PTR:
-                       token = "->";
-                       break;
+private:
+       BVariant                fPrimitive;
+       ValueNode*              fValueNode;
+       Type*                   fType;
+       operand_kind    fKind;
+};
 
-               default:
-                       token.SetToFormat("Unknown token type %" B_PRId32, 
type);
-                       break;
-       }
 
-       return token;
-}
+// #pragma mark - CLanguageExpressionEvaluator::Token
 
 
 struct CLanguageExpressionEvaluator::Token {
@@ -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<ExpressionResult> 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<Value> 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

[ *** diff truncated: 2204 lines dropped *** ]


############################################################################

Revision:    hrev48361
Commit:      b4a861136b9249eefc78a47528e5f4e515c633c6
URL:         http://cgit.haiku-os.org/haiku/commit/?id=b4a8611
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Sat Nov 22 04:31:46 2014 UTC

Debugger: Adjust VariablesView for new expression API.

- Simplify handling of expression nodes. For primitive results, we now
  construct a Variable object that represents the expression result, and
  then add that as we would any other local variable. This simplifies handling,
  and also allows saving/restoration of their view state to be handled the
  same as other nodes. Complex expression results aren't yet handled properly,
  pending some further work in progress on the evaluator.

----------------------------------------------------------------------------


Other related posts:

  • » [haiku-commits] haiku: hrev48361 - in src/apps/debugger: source_language/expression_evaluators user_interface/gui/team_window types . model - anevilyak