Click here to Skip to main content
15,896,606 members
Articles / Desktop Programming / MFC

Another Enum Viewer

Rate me:
Please Sign up or sign in to vote.
4.50/5 (2 votes)
22 Oct 20015 min read 83.1K   1.3K   19  
An article on the usage and design of another Enum Viewer
// CPPExpr.h:  Expression support classes

#ifndef INCL_CPPEXPR_H
#define INCL_CPPEXPR_H

#ifdef _MSC_VER
   #pragma warning (disable:4786)    // long debug names
   #pragma warning (disable:4146)    // unary minus operator applied to unsigned type
   #pragma warning (disable:4018)    // '>' : signed/unsigned mismatch
#endif

#include "CPPExprIncomplete.h"
#include "CPPDeclIncomplete.h"
#include "CPPTypeIncomplete.h"
#include "CPPScopeIncomplete.h"
#include "tokens.h"
#include "JLStr.h"
#include "assert.h"

////////////////////////////////////////////////////////////////
// Base expression class.
////////////////////////////////////////////////////////////////
class CPPExpr : public VRefCount {
public:
   enum Flavor { 
      Binary,        // all binary ops except [], ()
      Unary,         // all prefix unary ops
      Conditional,   // conditional
      Literal,       // literal constant
      SizeofExpr,    // sizeof(expr)
      SizeofType,    // sizeof(type)
      Id,            // Id for which name lookup was unique
      IdLazy,        // Id with deferred name lookup
      IdUndefined,   // Id that could not be found (for templates)
      Cast,          // Cast expression
      TemplatePlaceholder,   // Template placeholder value
      New,           // new
      Delete,        // delete
      FunctionCall,  // f(args)
      Postop,        // postfix ++, --
      This,          // "this"
      ArraySubscript // array[subscript]
   };

   CPPExpr(Flavor flavor_) : flavor(flavor_) {}
   virtual ~CPPExpr() {}

   Flavor GetFlavor() const { return flavor; }

   // Evaluate the expression as a constant-expression
   // Returns false if the expression is not constant
   virtual bool EvaluateConstant(
      double& result,
      bool& resultIsInteger
   ) const { return false; }

   virtual JLStr Format() const { return JLStr(); }

   // Is this expression a template placeholder?
   virtual bool IsPlaceholder() const { return false; }

   // Get the type of the expression, or a nil ref if the type is invalid
   // or cannot be determined.
   virtual CPPTypeRefI GetType() { 
      // Type of expressions is undefined (nil) unless subclass overrides
      return CPPTypeRefI(); 
   }

protected:
   // Data
   Flavor flavor;

private:
   // Do not allow copy/assignment.  
   CPPExpr(const CPPExpr& rhs);
   CPPExpr& operator=(const CPPExpr& rhs);
};

////////////////////////////////////////////////////////////////
// Binary-operation expression class
////////////////////////////////////////////////////////////////
class CPPExprBinary : public CPPExpr {
public:
   CPPExprBinary(
      CPPExprRefI lhs_,
      CPPExprRefI rhs_,
      ANTLRTokenType opToken_
   ) :
      CPPExpr(Binary),
      lhs(lhs_),
      rhs(rhs_),
      opToken(opToken_)
   {}
   virtual ~CPPExprBinary() {}
   virtual bool EvaluateConstant(double& result, bool& resultIsInteger) const;
   virtual CPPTypeRefI GetType();
   virtual JLStr Format() const;

   CPPExprRefI GetLhs() const { assertValid(); return lhs; }
   CPPExprRefI GetRhs() const { assertValid(); return rhs; }
   ANTLRTokenType GetOpToken() const { assertValid(); return opToken; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == Binary); }

   CPPExprRef lhs;
   CPPExprRef rhs;
   ANTLRTokenType opToken;
};

////////////////////////////////////////////////////////////////
// Unary-operation expression class
////////////////////////////////////////////////////////////////
class CPPExprUnary  : public CPPExpr {
public:
   CPPExprUnary(
      CPPExprRefI rhs_,
      ANTLRTokenType opToken_
   ) :
      CPPExpr(Unary),
      rhs(rhs_),
      opToken(opToken_)
   {}
   virtual ~CPPExprUnary() {}
   virtual bool EvaluateConstant(double& result, bool& resultIsInteger) const;
   virtual JLStr Format() const;

   CPPExprRefI GetRhs() const { assertValid(); return rhs; }
   ANTLRTokenType GetOpToken() const { assertValid(); return opToken; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == Unary); }

   CPPExprRef rhs;
   ANTLRTokenType opToken;
};


////////////////////////////////////////////////////////////////
// Conditional expression class
////////////////////////////////////////////////////////////////
class CPPExprConditional : public CPPExpr {
public:
   CPPExprConditional(
      CPPExprRefI condition_,
      CPPExprRefI lhs_,
      CPPExprRefI rhs_
   ) :
      CPPExpr(Conditional),
      condition(condition_),
      lhs(lhs_),
      rhs(rhs_)
   {}
   virtual ~CPPExprConditional() {}
   virtual bool EvaluateConstant(double& result, bool& resultIsInteger) const;
   virtual JLStr Format() const;

   CPPExprRefI GetCondition() const { assertValid(); return condition; }
   CPPExprRefI GetLhs() const { assertValid(); return lhs; }
   CPPExprRefI GetRhs() const { assertValid(); return rhs; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == Conditional); }

   CPPExprRef condition;
   CPPExprRef lhs;
   CPPExprRef rhs;
};

////////////////////////////////////////////////////////////////
// Literal expression class
////////////////////////////////////////////////////////////////
class CPPExprLiteral : public CPPExpr {
public:
   CPPExprLiteral(
      ANTLRTokenType tokType_,
      const JLStr& tokText_
   );
   virtual ~CPPExprLiteral() {}
   virtual bool EvaluateConstant(double& result, bool& resultIsInteger) const;
   virtual JLStr Format() const { return tokText; }

   ANTLRTokenType GetTokenType() const { assertValid(); return tokType; }
   const JLStr& GetTokenText() const { assertValid(); return tokText; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == Literal); }

   ANTLRTokenType tokType;
   JLStr tokText;
};


////////////////////////////////////////////////////////////////
// sizeof expression classes
////////////////////////////////////////////////////////////////
class CPPExprSizeofExpr : public CPPExpr {
public:
   CPPExprSizeofExpr(
      CPPExprRefI expr_
   ) :
      CPPExpr(SizeofExpr),
      expr(expr_)
   {}
   virtual ~CPPExprSizeofExpr() {}
   virtual bool EvaluateConstant(double& result, bool& resultIsInteger) const;
   virtual JLStr Format() const;

   CPPExprRefI GetExpr() const { return expr; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == SizeofExpr); }

   CPPExprRef expr;
};


class CPPExprSizeofType : public CPPExpr {
public:
   CPPExprSizeofType(
      CPPTypeRefI type_
   ) :
      CPPExpr(SizeofType),
      type(type_)
   {}
   virtual ~CPPExprSizeofType() {}
   virtual bool EvaluateConstant(double& result, bool& resultIsInteger) const;
   virtual JLStr Format() const;

   CPPTypeRefI GetType() const { assertValid(); return type; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == SizeofType); }

   CPPTypeRefI type;
};


////////////////////////////////////////////////////////////////
// id expression class
////////////////////////////////////////////////////////////////
class CPPExprId : public CPPExpr {
public:
   CPPExprId(
      CPPDeclRefI decl_
   ) :
      CPPExpr(Id),
      decl(decl_)
   {}
   virtual ~CPPExprId() {}
   virtual bool EvaluateConstant(double& result, bool& resultIsInteger) const;
   virtual JLStr Format() const;
   virtual CPPTypeRefI GetType();

   CPPDeclRefI GetDecl() const { assertValid(); return decl; }
private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == Id); }

   CPPDeclRefI decl;
};

////////////////////////////////////////////////////////////////
// id expression class for identifiers that were multiply-defined
// at the time of name lookup.  This allows deferral of the
// overload resolution
////////////////////////////////////////////////////////////////
class CPPExprIdLazy : public CPPExpr {
public:
   CPPExprIdLazy(
      const JLStr& name_,
      CPPDeclListRefI& declList_
   ) :
      name(name_),
      CPPExpr(IdLazy),
      declList(declList_)
   {}
   virtual ~CPPExprIdLazy() {}
   virtual JLStr Format() const { return name; }

   const JLStr& GetName() const { return name; }
   const CPPDeclListRefI GetDecls() const { assertValid(); return declList; }
private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == IdLazy); }

   // Name of the declaration
   JLStr name;
   // List of all decls under that name
   CPPDeclListRefI declList;
};

////////////////////////////////////////////////////////////////
// id expression class for identifiers that were not found
// in the scope context.  Only applies to identifiers found
// in template declarations.
////////////////////////////////////////////////////////////////
class CPPExprIdUndefined : public CPPExpr {
public:
   CPPExprIdUndefined(
      const JLStr& name_
   ) :
      CPPExpr(IdUndefined),
      name(name_)
   {}
   virtual ~CPPExprIdUndefined() {}
   virtual JLStr Format() const { return name; }

   const JLStr& GetName() const { assertValid(); return name; }
private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == IdUndefined); }

   JLStr name;
};

////////////////////////////////////////////////////////////////
// id expression class
////////////////////////////////////////////////////////////////
class CPPExprCast : public CPPExpr {
public:
   enum CastFlavor { Const, Static, Dynamic, Reinterpret, Traditional, FunctionLike };
   CPPExprCast(
      CastFlavor castFlavor_,
      CPPTypeRefI type_,
      CPPExprRefI rhs_
   ) :
      CPPExpr(Cast),
      castFlavor(castFlavor_),
      type(type_),
      rhs(rhs_)
   {}
   virtual ~CPPExprCast() {}
   virtual bool EvaluateConstant(double& result, bool& resultIsInteger) const;
   virtual JLStr Format() const;
   virtual CPPTypeRefI GetType() { return type; }

   CastFlavor GetCastFlavor() const { assertValid(); return castFlavor; }
   CPPExprRefI GetRhs() const { assertValid(); return rhs; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == Cast); }

   CastFlavor castFlavor;
   CPPTypeRefI type;
   CPPExprRefI rhs;
};

////////////////////////////////////////////////////////////////
// template placeholder value class
////////////////////////////////////////////////////////////////
class CPPExprTemplatePlaceholder : public CPPExpr {
public:
   CPPExprTemplatePlaceholder(
      short parameterIdx_,
      short templateLevel_
   ) : 
      CPPExpr(TemplatePlaceholder),
      parameterIdx(parameterIdx_),
      templateLevel(templateLevel_)
   {}
   virtual JLStr Format() const;
   virtual bool IsPlaceholder() const { return true; }

   short GetParameterIdx() const { assertValid(); return parameterIdx; }
   short GetTemplateLevel() const { assertValid(); return templateLevel; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == TemplatePlaceholder); }

   // The index of the parameter in its list (zero-based)
   short parameterIdx;
   // The level of template nesting of the parameter (zero-based)
   short templateLevel;
};

////////////////////////////////////////////////////////////////
// new expression class
////////////////////////////////////////////////////////////////
class CPPExprNew : public CPPExpr {
public:
   CPPExprNew(
      CPPExprRefI placementExpr_,
      CPPTypeRefI rawType_,
      CPPTypeRefI arrayType_,
      CPPExprRefI arraySizeExpr_,
      CPPExprRefI initExpr_
   ) :
      CPPExpr(New),
      placementExpr(placementExpr_),
      rawType(rawType_),
      arrayType(arrayType_),
      arraySizeExpr(arraySizeExpr_),
      initExpr(initExpr_)
   {
   }

   virtual JLStr Format() const;
   virtual CPPTypeRefI GetType() { return arrayType; }

   CPPExprRefI GetPlacementExpr() const { assertValid(); return placementExpr; }
   CPPTypeRefI GetArrayType() const { assertValid(); return arrayType; }
   CPPExprRefI GetArraySizeExpr() const { assertValid(); return arraySizeExpr; }
   CPPExprRefI GetInitExpr() const { assertValid(); return initExpr; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == New); }

   CPPExprRefI placementExpr; // placement expression if non-nul
   CPPTypeRefI rawType;       // type to allocate
   CPPTypeRefI arrayType;     // type of any resulting array
   CPPExprRefI arraySizeExpr; // array size expression if non-nil
   CPPExprRefI initExpr;      // initializer if non-nil
};

////////////////////////////////////////////////////////////////
// delete expression class
////////////////////////////////////////////////////////////////
class CPPExprDelete : public CPPExpr {
public:
   CPPExprDelete(
      CPPExprRefI exprToDelete_,
      bool deleteArray_
   ) :
      CPPExpr(Delete),
      exprToDelete(exprToDelete_),
      deleteArray(deleteArray_)
   {
   }

   virtual JLStr Format() const;

   CPPExprRefI GetExprToDelete() const { assertValid(); return exprToDelete; }
   bool GetDeleteArray() const { assertValid(); return deleteArray; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == Delete); }

   CPPExprRefI exprToDelete;
   bool deleteArray;
};


////////////////////////////////////////////////////////////////
// function call expression class
////////////////////////////////////////////////////////////////
class CPPExprFunctionCall : public CPPExpr {
public:
   CPPExprFunctionCall(
      CPPExprRefI exprFunction_,
      CPPExprRefI exprArgList_
   ) :
      CPPExpr(FunctionCall),
      exprFunction(exprFunction_),
      exprArgList(exprArgList_)
   {
   }

   virtual JLStr Format() const;
   virtual CPPTypeRefI GetType();

   CPPExprRefI GetExprFunction() const { assertValid(); return exprFunction; }
   CPPExprRefI GetExprArgList() const { assertValid(); return exprArgList; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == FunctionCall); }

   CPPExprRefI exprFunction;
   CPPExprRefI exprArgList;
};


////////////////////////////////////////////////////////////////
// post-op expression
////////////////////////////////////////////////////////////////
class CPPExprPostop : public CPPExpr {
public:
   CPPExprPostop(
      CPPExprRefI lhs_,
      ANTLRTokenType opToken_
   ) :
      CPPExpr(Postop),
      lhs(lhs_),
      opToken(opToken_)
   {
   }

   virtual JLStr Format() const;

   CPPExprRefI GetLhs() const { assertValid(); return lhs; }
   ANTLRTokenType GetOpToken() const { assertValid(); return opToken; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == Postop); }

   CPPExprRefI lhs;
   ANTLRTokenType opToken;
};

////////////////////////////////////////////////////////////////
// "this" expression
////////////////////////////////////////////////////////////////
class CPPExprThis : public CPPExpr {
public:
   CPPExprThis() : CPPExpr(This) {}

   virtual JLStr Format() const { return "this"; }

private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == This); }
};

////////////////////////////////////////////////////////////////
// array-subscript expression
////////////////////////////////////////////////////////////////
class CPPExprArraySubscript : public CPPExpr {
public:
   CPPExprArraySubscript(
      CPPExprRefI lhs_,
      CPPExprRefI exprSubscript_
   ) : 
      CPPExpr(ArraySubscript),
      lhs(lhs_),
      exprSubscript(exprSubscript_)
   {}

   virtual JLStr Format() const;
   virtual CPPTypeRefI GetType();

   CPPExprRefI GetLhs() const { assertValid(); return lhs; }
   CPPExprRefI GetExprSubscript() const { assertValid(); return exprSubscript; }
private:
   // Catch bad downcast
   void assertValid() const { assert(flavor == ArraySubscript); }

   CPPExprRefI lhs;
   CPPExprRefI exprSubscript;
};

#endif

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions