|
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name: expr.hxx
Abstract:
This file contains the expression class definitions.
Notes:
Author:
VibhasC Jun-06-1993 Created
Notes:
This expression evaluator is used by the front and the code generator of the midl compiler. It therefore must support the complete gamut of c expressions.
----------------------------------------------------------------------------*/ #ifndef __EXPR_HXX__
#define __EXPR_HXX__
/****************************************************************************
* include files ***************************************************************************/
#include "nulldefs.h"
#include "common.hxx"
#include "listhndl.hxx"
#include "midlnode.hxx"
extern "C" { #include <stdio.h>
} #include "stream.hxx"
#include "ndrtypes.h"
#define _STRDUP( x, y ) ( (y) ? ((x) = new char[strlen(y)+1] ), strcpy( x, y ) : x = 0)
class node_skl; class EXPR_CTXT;
typedef char * PNAME; typedef __int64 EXPR_VALUE;
/****************************************************************************
* extern references ***************************************************************************/
/****************************************************************************
* the meat of the definitions ***************************************************************************/
#if 0
//
// the class heirarchy for the expression evaluator. The class heirarchy for
// the expression does not reflect the operator or evaluation precedence. The
// class heirarchy instead reflects the organisation based on the structure of
// an object of the expression class. It is upto the generator of the expression
// to ensure proper precedence. In case the expression is generated by a parser
// the precedence is automatically ensured. The back end which generates new
// expressions must therefore ensure that the precedence is properly set up. We
// will NOT check this.
//
expr_node expr_variable expr_resource expr_constant expr_operator expr_op_unary
expr_u_arithmetic // + -
expr_u_not // !
expr_u_complement // ~
expr_deref // *
expr_u_address // &
expr_cast // (type)
expr_sizeof // sizeof( type )
expr_alignof // __alignof( type )
expr_post_incr // foo++
expr_pre_incr // ++foo
expr_post_decr // foo--
expr_pre_decr // --foo
expr_op_binary expr_b_arith // * / + - %
expr_b_logical // || &&
expr_relational // > >= == != < <=
expr_shift // << >>
expr_bitwise // |, &, ^
expr_dot // a.b
expr_pointsto // a->b
expr_index // []
expr_comma // ,
expr_assign // =
expr_proc // ()
expr_statement // ;
expr_ternary // ?:
#endif // 0
//
// The basic expression class. This class is an abstract base class. It only
// provides the interface to a general expression node.
//
#define _expr_node expr_node
#define _expr_variable expr_variable
#define _expr_constant expr_constant
#define _expr_named_constant expr_named_constant
#define _expr_operator expr_operator
#define _expr_op_unary expr_op_unary
#define _expr_op_binary expr_op_binary
#define _expr_u_arithmetic expr_u_arithmetic
#define _expr_u_not expr_u_not
#define _expr_u_complement expr_u_complement
#define _expr_u_deref expr_u_deref
#define _expr_u_address expr_u_address
#define _expr_cast expr_cast
#define _expr_sizeof expr_sizeof
#define _expr_alignof expr_alignof
#define _expr_pre_incr expr_pre_incr
#define _expr_pre_decr expr_pre_decr
#define _expr_post_incr expr_post_incr
#define _expr_post_decr expr_post_decr
#define _expr_b_arithmetic expr_b_arithmetic
#define _expr_b_logical expr_b_logical
#define _expr_relational expr_relational
#define _expr_shift expr_shift
#define _expr_bitwise expr_bitwise
#define _expr_dot expr_dot
#define _expr_pointsto expr_pointsto
#define _expr_index expr_index
#define _expr_comma expr_comma
#define _expr_assign expr_assign
#define _expr_proc_call expr_proc_call
#define _expr_param expr_param
//
// This is the constant expression class. For now this only has simple integral
// constants. We would need to have this class to be more explicit in that it
// needs to know the exact type of the constant according to the language
// rules and know the exact format to be able to print this out. This is
// necessary so that the generated constant looks the same as the original
// for the user's convenience.
//
typedef enum _pformat { VALUE_TYPE_STRING, VALUE_TYPE_WSTRING, VALUE_TYPE_CHAR, VALUE_TYPE_WCHAR,
VALUE_TYPE_NUMERIC, VALUE_TYPE_NUMERIC_U, VALUE_TYPE_NUMERIC_LONG, VALUE_TYPE_NUMERIC_ULONG,
VALUE_TYPE_HEX, VALUE_TYPE_HEX_U, VALUE_TYPE_HEX_LONG, VALUE_TYPE_HEX_ULONG,
VALUE_TYPE_OCTAL, VALUE_TYPE_OCTAL_U, VALUE_TYPE_OCTAL_LONG, VALUE_TYPE_OCTAL_ULONG,
VALUE_TYPE_BOOL,
VALUE_TYPE_FLOAT, VALUE_TYPE_DOUBLE,
// RKK64
// value types for int64
VALUE_TYPE_UNDEFINED, } PFORMAT;
struct SExprValue { PFORMAT format; union { signed char ch; signed short sh; signed int n; signed long l;
unsigned char uch; unsigned short ush; unsigned int un; unsigned long ul;
__int64 hy; float f; double d;
BOOL b; wchar_t wch; } ; };
typedef node_skl * ETYPE;
class expr_node { protected:
//
// the type of the expression. All expression nodes need to have a type
// since a variable / constant will have a type and so will an operation
// on those variables / constants.
node_skl * pType; BOOL fConstant : 1; BOOL fFloatExpr : 1;
//
// The constructor. Each expression node is instantiated using a type
// If the type is unknown at the time of instantiation, then an error type
// is the type of the expression. Therefore we provide a overloaded
// constructor for both these situations.
//
public:
expr_node() { SetType( (node_skl *)0 ); fConstant = TRUE; fFloatExpr = FALSE; };
expr_node( node_skl * pT ) { SetType( pT ); fConstant = TRUE; fFloatExpr = FALSE; };
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_node; };
//
// set the type of the expression.
//
void SetType( node_skl * pT ) { pType = pT; }
//
// get the type of the expression.
//
virtual node_skl * GetType( void ) { return pType; } //
// get the type of the expression. Force it to be determined
// if it is unknown
//
node_skl * AlwaysGetType( void ) { node_skl * pType = GetType();
if ( !pType ) { DetermineType(); pType = GetType(); } return pType; } //
// determine the type of the expression
//
virtual void DetermineType() { }
//
// set the "constness" of the expression.
//
void SetConstant( BOOL fCon = TRUE ) { fConstant = fCon; }
void SetFloatExpr( BOOL f = TRUE ) { fFloatExpr = f; } //
// queries.
//
virtual BOOL IsAVariable() { return FALSE; } virtual BOOL IsResource() { return FALSE; } virtual BOOL IsConstant() { return fConstant; } virtual BOOL IsOperator() { return FALSE; }
virtual BOOL IsUnaryOperator() { return FALSE; } virtual BOOL IsBinaryOperator() { return FALSE; }
virtual BOOL IsArithmeticOperator() { return FALSE; } virtual BOOL IsLogicalOperator() { return FALSE; }
virtual BOOL IsBitwiseOperator() { return FALSE; } virtual BOOL IsRelationalOperator() { return FALSE; } virtual BOOL IsShiftOperator() { return FALSE; }
//
// test if the expression is a string constant
//
virtual BOOL IsStringConstant (void) { return FALSE; } BOOL IsFloatExpr( void ) { return fFloatExpr; } //
// others.
//
virtual expr_node * GetLeft() { return 0; }
virtual expr_node * GetRight() { return 0; } virtual OPERATOR GetOperator() { return OP_ILLEGAL; }
virtual EXPR_VALUE GetValue() { return 0; }
virtual BOOL GetExprValue( SExprValue& v ) { v.format = VALUE_TYPE_UNDEFINED; return TRUE; } //
// Make (or add to) a list of var nodes of an expr
//
virtual short MakeListOfVars( ITERATOR & pList );
virtual short MakeListOfDerefedVars( ITERATOR& ) { return 0; }
// gaj - this is a dummy routine
virtual EXPR_VALUE Evaluate() { return GetValue(); } // gaj - end of dummy routines
//
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * ) { }
void PrintWithPrefix( ISTREAM * pS, char * Prefix );
void DecorateWithPrefix( char * Prefix = NULL );
//
// This is an overloaded virtual only for the proc_call node.
//
virtual void PrintCall( ISTREAM * pS, short , BOOL ) { Print( pS ); }
virtual void ExprAnalyze( EXPR_CTXT * pExprCtxt );
// private allocator
void * operator new ( size_t size ) { return AllocateOnceNew( size ); } void operator delete( void * ptr ) { AllocateOnceDelete( ptr ); }
};
//
// This class represents a variable in an expression.
// This expression node is instantiated for variables specified as fields of
// a struct/union or as parameters. Contrast this to the resource class which
// is VERY similar but only corresponds to the internally generated and used
// variables in the stub routines.
//
class expr_variable : public expr_node { private:
//
// the name of the variable.
//
PNAME pIDName; char * pPrefix;
public:
//
// the constructor expects the object to be instantiated using a name.
// Sometimes one needs to instantiate a variable using the type too.
//
expr_variable( PNAME p ) { SetName( p ); SetType( (node_skl *)0 ); SetConstant( FALSE ); SetPrefix( NULL ); }
expr_variable( PNAME p, node_skl * pT );
virtual void CopyTo( expr_node* lhs ); virtual expr_node* Clone() { return new expr_variable(0); }; // get the type
virtual node_skl * GetType();
//
// set methods.
//
void SetName( PNAME p ) { pIDName = p; }
void SetPrefix( char * p ) { pPrefix = p; }
//
// get methods
//
PNAME GetName() { return pIDName; } char * GetPrefix() { return pPrefix; } //
// is this a variable expression.
//
virtual BOOL IsAVariable() { return TRUE; }
//
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
//
// Make (or add to) a list of var nodes of an expr
//
virtual short MakeListOfVars( ITERATOR & pList );
//
// determine the type of the expression
//
virtual void DetermineType();
//
// analyze the expression
//
virtual void ExprAnalyze( EXPR_CTXT * pExprCtxt );
};
//
// This class represents a variable in an expression.
// This expression node is instantiated for variables specified as fields of
// a struct/union or as parameters. Contrast this to the resource class which
// is VERY similar but only corresponds to the internally generated and used
// variables in the stub routines.
//
class expr_named_constant : public expr_variable { public:
//
// the constructor expects the object to be instantiated using a name.
// Sometimes one needs to instantiate a variable using the type too.
//
expr_named_constant( PNAME p = 0) : expr_variable( p ) { SetConstant( TRUE ); }
expr_named_constant( PNAME p, node_skl * pT ) : expr_variable( p, pT ) { SetConstant( TRUE ); }
virtual expr_node* Clone() { return new expr_named_constant; };
BOOL IsAVariable() { return FALSE; }
//
// if it is a constant id or label, we can return the value
//
virtual EXPR_VALUE GetValue();
// similarly for expression
expr_node * GetExpr();
//
// Make (or add to) a list of var nodes of an expr
//
virtual short MakeListOfVars( ITERATOR & pList );
//
// determine the type of the expression
//
virtual void DetermineType();
//
// analyze the expression
//
virtual void ExprAnalyze( EXPR_CTXT * pExprCtxt );
};
//
// value type masks indicate the value type set by the user / determined from
// the value of the constant.
//
#define VALUE_T_MASK_CLEAR (0x00)
#define VALUE_T_MASK_CHAR (0x01)
#define VALUE_T_MASK_SHORT (0x02)
#define VALUE_T_MASK_LONG (0x04)
#define VALUE_T_MASK_UCHAR (0x10)
#define VALUE_T_MASK_USHORT (0x20)
#define VALUE_T_MASK_ULONG (0x40)
class expr_constant : public expr_node { private:
//
// store the original format. If the original format is a null then
// the expression is printed out in the manner suitable for the type of
// the expression. If the original format is present, then the user
// declared this expression in this format and she wants it back in the
// header/stub file also in the same format.
PFORMAT Format;
union { char C; short S; long L; __int64 I64; float F; double D; unsigned char UC; unsigned short US; unsigned long UL; unsigned __int64 UI64; unsigned char* pC; wchar_t* pWC; } Value;
//
// get and set the format of the constant.
//
void SetFormat( PFORMAT p ) { Format = p; }
public:
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_constant(this); }
PFORMAT GetFormat() const { return Format; } //
// Different constructors are available for the different kind of constants
// that are possible.
//
expr_constant( char C, PFORMAT pF = VALUE_TYPE_CHAR ) { SetFormat( pF ); Value.I64 = C; }
expr_constant( short S, PFORMAT pF = VALUE_TYPE_NUMERIC ) { SetFormat( pF ); Value.I64 = S; }
expr_constant( long L, PFORMAT pF = VALUE_TYPE_NUMERIC ) { SetFormat( pF ); Value.I64 = L; }
expr_constant( __int64 I64, PFORMAT pF = VALUE_TYPE_NUMERIC ) { SetFormat( pF ); Value.I64 = I64; }
expr_constant( float F, PFORMAT pF = VALUE_TYPE_FLOAT ) { SetFormat( pF ); Value.F = F; }
expr_constant( double D, PFORMAT pF = VALUE_TYPE_DOUBLE ) { SetFormat( pF ); Value.D = D; }
expr_constant( unsigned char UC, PFORMAT pF = VALUE_TYPE_NUMERIC_U ) { SetFormat( pF ); Value.I64 = UC; }
expr_constant( unsigned short US, PFORMAT pF = VALUE_TYPE_NUMERIC_U ) { SetFormat( pF ); Value.I64 = US; }
expr_constant( unsigned long UL, PFORMAT pF = VALUE_TYPE_NUMERIC ) { SetFormat( pF ); Value.I64 = UL; }
expr_constant( unsigned __int64 UI64, PFORMAT pF = VALUE_TYPE_NUMERIC ) { SetFormat( pF ); Value.I64 = (__int64)UI64; }
expr_constant( char *pC, PFORMAT pF = VALUE_TYPE_STRING ) { SetFormat( pF ); Value.UI64 = (unsigned __int64)pC; }
expr_constant( wchar_t *pWC, PFORMAT pF = VALUE_TYPE_WSTRING ) { SetFormat( pF ); Value.UI64 = (unsigned __int64)pWC; }
expr_constant( const expr_constant *p) { SetFormat( p->GetFormat() ); Value = p->Value; } //
// queries.
//
// gaj - return constant value assuming it is long for now...
virtual EXPR_VALUE GetValue();
BOOL GetExprValue( SExprValue& v ) { // currently only floats and double use this code path
// fix this when expr evaluator is revamped
v.format = VALUE_TYPE_UNDEFINED; if (Format == VALUE_TYPE_FLOAT) { v.format = Format; v.f = Value.F; } else if (Format == VALUE_TYPE_DOUBLE) { v.format = Format; v.d = Value.D; } return TRUE; } //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
//
// determine the type of the expression
//
virtual void DetermineType();
//
// analyze the expression
//
virtual void ExprAnalyze( EXPR_CTXT * pExprCtxt );
//
// test if the expression is a string constant
//
virtual BOOL IsStringConstant (void) { return (Format == VALUE_TYPE_STRING || Format == VALUE_TYPE_WSTRING); } };
//
// some convenient helper functions to get vanilla constant 0 and constant 1
//
extern expr_constant * GetConstant0();
extern expr_constant * GetConstant1();
//
// the operator classes. These classes are group into unary binary and
// ternary expression classes.
//
class expr_operator : public expr_node { private: OPERATOR Operator; public:
//
// the constructor of an abstract base class does nothing.
//
expr_operator( OPERATOR Op ) { SetOperator( Op ); }
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_operator( OP_ILLEGAL ); }; //
// get and set functions.
//
void SetOperator( OPERATOR Op ) { Operator = Op; }
OPERATOR GetOperator() { return Operator; } //
// queries.
//
virtual BOOL IsOperator() { return TRUE; }
void PrintSubExpr( expr_node *, ISTREAM * pS );
};
//
// unary operator classes.
//
class expr_op_unary : public expr_operator { private: expr_node * pLeft;
public:
//
// the constructor. This class is instantiated by supplying operator and
// the left had side expression values.
//
expr_op_unary( OPERATOR Op, expr_node *pL) : expr_operator(Op) { SetLeft( pL ); if ( pL ) SetConstant( pL->IsConstant() ); }
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_op_unary( OP_ILLEGAL, 0 ); }; //
// get and set routines.
//
expr_node * SetLeft( expr_node * pL ) { return ( pLeft = pL ); }
virtual expr_node * GetLeft() { return pLeft; }
//
// queries.
//
virtual BOOL IsUnaryOperator() { return TRUE; }
//
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
//
// Make (or add to) a list of var nodes of an expr
//
virtual short MakeListOfVars( ITERATOR & pList );
//
// determine the type of the expression
//
virtual void DetermineType();
//
// analyze the expression
//
virtual void ExprAnalyze( EXPR_CTXT * pExprCtxt );
virtual short MakeListOfDerefedVars( ITERATOR& List ) { if( GetLeft() ) return GetLeft()->MakeListOfDerefedVars( List ); return 0; }
};
//
// binary operator class. Each binary operator node takes a left and right
// expression connected by the binary operator.
//
class expr_op_binary : public expr_operator { private:
expr_node * pLeft; expr_node * pRight;
public:
//
// this class is instantiated by specifying the left/right and the
// operator.
//
expr_op_binary( OPERATOR Op, expr_node * pL, expr_node * pR ) : expr_operator( Op ) { SetLeft( pL ); SetRight( pR ); SetConstant( ( (pL) ? pL->IsConstant() : TRUE ) && ( (pR) ? pR->IsConstant() : TRUE ) ); } virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_op_binary( OP_ILLEGAL, 0, 0 ); }; //
// get and set.
//
virtual expr_node * SetLeft( expr_node *p ) { return (pLeft = p); }
virtual expr_node * SetRight( expr_node *p ) { return (pRight = p); }
virtual expr_node * GetLeft() { return pLeft; }
virtual expr_node * GetRight() { return pRight; }
//
// queries.
//
virtual BOOL IsBinaryOperator() { return TRUE; } //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
virtual void PrintCall( ISTREAM * pS, short LeftMargin, BOOL fInProc ); //
// Make (or add to) a list of var nodes of an expr
//
virtual short MakeListOfVars( ITERATOR & pList );
virtual short MakeListOfDerefedVars( ITERATOR& List );
//
// determine the type of the expression
//
virtual void DetermineType();
//
// analyze the expression
//
virtual void ExprAnalyze( EXPR_CTXT * pExprCtxt );
};
//
// this is the unary arithmetic class. Corresponding to the unary arithmetic
// operators + and -.
//
class expr_u_arithmetic : public expr_op_unary { public: expr_u_arithmetic( OPERATOR Op, expr_node * pL ) : expr_op_unary(Op, pL) { } virtual expr_node* Clone() { return new expr_u_arithmetic( OP_ILLEGAL, 0 ); }; //
// queries.
//
virtual BOOL IsArithmeticOperator() { return TRUE; } //
// test if the expression is a string constant
//
virtual BOOL IsStringConstant (void) { return GetLeft()->IsStringConstant(); }
virtual EXPR_VALUE GetValue();
BOOL GetExprValue( SExprValue& v );
};
//
// this is the unary not operator class.
//
class expr_u_not : public expr_op_unary { public: expr_u_not( expr_node * pL ) : expr_op_unary(OP_UNARY_NOT, pL ) { }
virtual expr_node* Clone() { return new expr_u_not( 0 ); }; //
// queries.
//
virtual BOOL IsLogicalOperator() { return TRUE; }
virtual EXPR_VALUE GetValue();
};
//
// the unary complement class.
//
class expr_u_complement : public expr_op_unary { public: expr_u_complement( expr_node *pL ) : expr_op_unary(OP_UNARY_COMPLEMENT, pL) { } virtual expr_node* Clone() { return new expr_u_complement( 0 ); }; //
// queries.
//
virtual BOOL IsBitwiseOperator() { return TRUE; }
virtual EXPR_VALUE GetValue();
};
//
// unary derefence operator
//
class expr_u_deref : public expr_op_unary { public: expr_u_deref( expr_node *pL ) : expr_op_unary(OP_UNARY_INDIRECTION, pL) { SetConstant( FALSE ); } expr_u_deref( OPERATOR op, expr_node *pL ) : expr_op_unary(op, pL) { SetConstant( FALSE ); }
virtual expr_node* Clone() { return new expr_u_deref( 0 ); }; virtual short MakeListOfDerefedVars( ITERATOR& List );
};
//
//
class expr_u_address : public expr_op_unary { public: expr_u_address( expr_node *pL ) : expr_op_unary(OP_UNARY_AND, pL) { SetConstant( FALSE ); }
virtual expr_node* Clone() { return new expr_u_address( 0 ); }; };
//
// the unary cast operator
//
class expr_cast : public expr_op_unary { node_skl* pCastType; bool fEmitModifiers;
public: expr_cast( node_skl * pT, expr_node *pL ) : expr_op_unary(OP_UNARY_CAST, pL), fEmitModifiers( true ) { pCastType = pT; }
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_cast( 0, 0 ); }; //
// Given an output steam, output the expression.
//
virtual void SetEmitModifiers(bool fModifier = true) { fEmitModifiers = fModifier; } virtual bool GetEmitModifiers() { return fEmitModifiers; }
virtual void Print( ISTREAM * pS );
virtual node_skl * GetType() { return pCastType; } virtual EXPR_VALUE GetValue();
};
//
// the unary sizeof operator.
//
class expr_sizeof : public expr_op_unary { node_skl * pType;
public: expr_sizeof( node_skl *pT) : expr_op_unary( OP_UNARY_SIZEOF,NULL ) { pType = pT; }
expr_sizeof( expr_node *pL ) : expr_op_unary( OP_UNARY_SIZEOF,pL ) { pType = pL->GetType(); }
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_sizeof( (node_skl*)0 ); }; //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
virtual short MakeListOfVars( ITERATOR & pList );
virtual EXPR_VALUE GetValue();
};
//
// the unary __alignof operator.
//
class expr_alignof : public expr_op_unary { node_skl * pType;
public: expr_alignof( node_skl *pT) : expr_op_unary( OP_UNARY_ALIGNOF, NULL ) { pType = pT; }
expr_alignof( expr_node *pL ) : expr_op_unary( OP_UNARY_ALIGNOF, pL ) { pType = pL->GetType(); }
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_alignof( (node_skl*)0 ); }; //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
virtual short MakeListOfVars( ITERATOR & pList );
virtual EXPR_VALUE GetValue();
};
//
// unary pre-increment operator.
//
class expr_pre_incr : public expr_op_unary { public: expr_pre_incr( expr_node *pL ) : expr_op_unary(OP_PRE_INCR, pL) { SetType( pL->GetType()); } virtual expr_node* Clone() { return new expr_pre_incr(0); }; //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
};
//
// unary pre-decrement operator.
//
class expr_pre_decr : public expr_op_unary { public: expr_pre_decr( expr_node *pL ): expr_op_unary(OP_PRE_DECR, pL) { SetType( pL->GetType()); } virtual expr_node* Clone() { return new expr_pre_decr(0); }; //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
};
//
// unary post-increment operator.
//
class expr_post_incr : public expr_op_unary { public: expr_post_incr( expr_node *pL ): expr_op_unary(OP_POST_INCR, pL) { SetType( pL->GetType()); } virtual expr_node* Clone() { return new expr_post_incr(0); }; //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
};
//
// unary post-decrement operator.
//
class expr_post_decr : public expr_op_unary { public: expr_post_decr( expr_node *pL ): expr_op_unary(OP_POST_DECR, pL) { SetType( pL->GetType()); } virtual expr_node* Clone() { return new expr_post_decr(0); }; //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
};
//
// binary arithmetic operators.
//
class expr_b_arithmetic : public expr_op_binary { public:
expr_b_arithmetic( OPERATOR Op, expr_node *pL, expr_node *pR ): expr_op_binary( Op, pL, pR ) { }
virtual expr_node* Clone() { return new expr_b_arithmetic(OP_ILLEGAL,0,0); }; //
// queries.
//
virtual BOOL IsArithmeticOperator() { return TRUE; }
virtual EXPR_VALUE GetValue();
BOOL GetExprValue( SExprValue& v );
};
//
// binary logical operators.
//
class expr_b_logical : public expr_op_binary { public:
expr_b_logical( OPERATOR Op, expr_node *pL, expr_node *pR ): expr_op_binary( Op, pL, pR ) { }
virtual expr_node* Clone() { return new expr_b_logical(OP_ILLEGAL,0,0); }; //
// queries.
//
virtual BOOL IsLogicalOperator() { return TRUE; }
virtual EXPR_VALUE GetValue();
};
//
// relational operators.
//
class expr_relational : public expr_op_binary { public:
expr_relational( OPERATOR Op, expr_node *pL, expr_node *pR ): expr_op_binary( Op, pL, pR ) { }
virtual expr_node* Clone() { return new expr_relational(OP_ILLEGAL,0,0); }; //
// queries.
//
virtual BOOL IsRelationalOperator() { return TRUE; }
virtual EXPR_VALUE GetValue();
};
//
// shift operators.
//
class expr_shift : public expr_op_binary { public:
expr_shift( OPERATOR Op, expr_node *pL, expr_node *pR ): expr_op_binary( Op, pL, pR ) { }
virtual expr_node* Clone() { return new expr_shift(OP_ILLEGAL,0,0); }; //
// queries.
//
virtual BOOL IsShiftOperator() { return TRUE; }
virtual EXPR_VALUE GetValue();
};
//
// bitwise operators.
//
class expr_bitwise : public expr_op_binary { public:
expr_bitwise( OPERATOR Op, expr_node *pL, expr_node *pR ): expr_op_binary( Op, pL, pR ) { }
virtual expr_node* Clone() { return new expr_bitwise(OP_ILLEGAL,0,0); }; //
// queries.
//
virtual BOOL IsBitwiseOperator() { return TRUE; }
virtual EXPR_VALUE GetValue();
};
//
// dot operator.
//
class expr_dot : public expr_op_binary { public:
expr_dot( expr_node *pL, expr_node *pR ): expr_op_binary( OP_DOT, pL, pR ) { } virtual expr_node* Clone() { return new expr_dot(0,0); }; };
//
// pointsto operator.
//
class expr_pointsto : public expr_op_binary { public:
expr_pointsto( expr_node *pL, expr_node *pR ): expr_op_binary( OP_POINTSTO, pL, pR ) { } virtual expr_node* Clone() { return new expr_pointsto(0,0); }; };
//
// array element operator.
//
class expr_index : public expr_op_binary { public:
expr_index( expr_node *pL, expr_node *pR );
virtual expr_node* Clone() { return new expr_index(0,0); }; //
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
virtual void PrintCall( ISTREAM * pS, short LeftMargin, BOOL fInProc );
};
//
// comma operator.
//
class expr_comma : public expr_op_binary { public:
expr_comma( expr_node *pL, expr_node *pR ): expr_op_binary( OP_COMMA, pL, pR ) { } virtual expr_node* Clone() { return new expr_comma(0,0); }; };
//
// assign operator.
//
class expr_assign : public expr_op_binary { public:
expr_assign( expr_node *pL, expr_node *pR ): expr_op_binary( OP_ASSIGN, pL, pR ) { } virtual expr_node* Clone() { return new expr_assign(0,0); }; virtual void PrintCall( ISTREAM * pS, short LeftMargin, BOOL fInProc );
};
//
// proc operator.
//
class expr_proc_call : public expr_op_unary { private: PNAME pName; short NoOfParams;
//
// Set the first parameter of the function. This is a private method
// because the world should use the SetParam function which will take care
// of inserting the new param expression in the correct (last) place in the
// parameter list.
//
class expr_param * SetFirstParam( class expr_param * p ) { return (class expr_param *)SetLeft( (class expr_node *) p ); }
public:
expr_proc_call(PNAME pN, expr_node *pParamList): expr_op_unary(OP_FUNCTION,pParamList) { SetName( pN ); SetNoOfParams( 0 ); }
expr_proc_call( PNAME pN ) : expr_op_unary(OP_FUNCTION, 0) { SetName( pN ); SetNoOfParams( 0 ); }
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_proc_call(0); }; //
// get and set functions.
//
void SetName( PNAME pN ) { pName = pN; }
PNAME GetName() { return pName; }
unsigned short SetNoOfParams( unsigned short N ) { return (NoOfParams = N); }
unsigned short GetNoOfParams() { return NoOfParams; } unsigned short IncrNoOfParams() { return (++NoOfParams); } //
// This method is used to get at the first param of a function. After
// that GetNextParam calls are made on the param node itself. This will
// be our most frequent usage, eg in the printing of the expression.
//
class expr_param * GetFirstParam() { return (class expr_param *)GetLeft(); }
//
// This method will insert the parameter expression at the end of the
// parameter list. This is done so that an procedure call expression
// can be created in the natural (left to right) order.
//
class expr_param * SetParam( class expr_param * pParam );
class expr_param * SetParam( expr_node * pExpr );
//
// Given an output steam, output the expression. This does not
// generate a semi-colon.
//
virtual void Print( ISTREAM * pS );
//
// This call generates a call with a semi-colon
//
virtual void PrintCall( ISTREAM * pS, short InitMargin, BOOL fInProc );
};
class expr_param : public expr_op_binary { private: PNAME pName; public:
expr_param(expr_node *pParamExpr ): expr_op_binary(OP_PARAM,pParamExpr, 0) { pName = NULL; }
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_param(0); }; //
// queries.
//
//
// This method gets the next parameter in the parameter list. To emit the
// parameter expressions for a procedure, get the first parameter on the
// expr_proc_call node and then make GetNextParam calls on the parameter
// till the call returns a null.
//
expr_param * GetNextParam() { return (expr_param *)GetRight(); } //
// This method sets the next param expression to be the one specified. This
// method does not traverse the list of params and insert at the end !!.
//
expr_param * SetNextParam( expr_param * p ) { return (expr_param *)SetRight( p ); }
//
// This method traverses to the end of the parameter list and inserts a new
// param expression at the end .Use this method when a procedure call
// expression is being generated. The way to do this is to create a
// expr_proc_call node and make as many SetParam calls to it as there are
// parameter expressions. They will all get inserted into the parameter list
// in the left to right (natural) order, with each new param expression
// going to the end of the list.
//
expr_param * SetLastPeerParam( expr_param * pN );
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS );
virtual void PrintCall( ISTREAM * pS, short LeftMargin, BOOL fInProc );
};
//
// ternary operator class. Each ternary operator node takes a relational, left and right
// expression connected by the ternary operator.
//
class expr_ternary : public expr_operator { private:
expr_node * pLeft; expr_node * pRight; expr_node * pRelational;
public:
//
// this class is instantiated by specifying the left/right and the
// operator.
//
expr_ternary( OPERATOR Op, expr_node * pRel, expr_node * pL, expr_node * pR ) : expr_operator( Op ) { SetRelational( pRel ); SetLeft( pL ); SetRight( pR ); SetConstant( ( (pL) ? pL->IsConstant() : TRUE ) && ( (pR) ? pR->IsConstant() : TRUE ) && ( (pRel) ? pRel->IsConstant() : TRUE ) ); } virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone(); //
// get and set.
//
virtual expr_node * SetRelational( expr_node *p ) { return (pRelational = p); }
virtual expr_node * SetLeft( expr_node *p ) { return (pLeft = p); }
virtual expr_node * SetRight( expr_node *p ) { return (pRight = p); }
virtual expr_node * GetRelational() { return pRelational; } virtual expr_node * GetLeft() { return pLeft; }
virtual expr_node * GetRight() { return pRight; }
//
// queries.
//
virtual BOOL IsBinaryOperator() { return TRUE; } //
// Given an output steam, output the expression.
//
void Print( ISTREAM * pS );
virtual EXPR_VALUE GetValue();
//
// determine the type of the expression
//
virtual void DetermineType();
//
// analyze the expression
//
virtual void ExprAnalyze( EXPR_CTXT * pExprCtxt );
virtual short MakeListOfVars( ITERATOR & pList );
};
// gaj - these are added for now to satisfy the grammar
class expr_init_list: public expr_node { private: class expr_init_list * pSibling; class expr_node * pExpr;
public: expr_init_list( expr_node * pE ) { pExpr = pE; SetConstant( pE->IsConstant() ); };
virtual void CopyTo( expr_node* lhs );
virtual expr_node* Clone() { return new expr_init_list(0); };
virtual void LinkSibling( class expr_init_list * pIL ) { pSibling = pIL; }
// assume only the first value here...
virtual EXPR_VALUE GetValue() { return pExpr->GetValue(); }
//
// Given an output steam, output the expression.
//
virtual void Print( ISTREAM * pS ) { pExpr->Print( pS ); }
//
// determine the type of the expression
//
virtual void DetermineType();
//
// analyze the expression
//
virtual void ExprAnalyze( EXPR_CTXT * pExprCtxt );
};
class expr_error: public expr_node { public: virtual expr_node* Clone() { return new expr_error; }; };
#endif // __EXPR_HXX__
|