|
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-1999 Microsoft Corporation
Module Name: exprpr.cxx
Abstract:
expression evaluator print routines implementation.
Notes:
History:
VibhasC Aug-05-1993 Created
----------------------------------------------------------------------------*/
#pragma warning ( disable : 4514 )
/****************************************************************************
* include files ***************************************************************************/ #include "nulldefs.h"
extern "C" { #include <stdio.h>
#include <string.h>
}
#include "expr.hxx"
#include "nodeskl.hxx"
/****************************************************************************
* extern definitions ***************************************************************************/
extern char * OperatorToString( OPERATOR Op );
/***************************************************************************/
void expr_node::PrintWithPrefix( ISTREAM * pStream, char * pPrefix ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
This routine prints an expression adding a prefix to each of the varaibles within the expression.
Arguments:
pStream - A pointer to the stream to output to. pPrefix - the prefix to be prepended to each variable Return Value: Notes:
----------------------------------------------------------------------------*/ { ITERATOR VarList; expr_variable * pVarNode = 0;
short VarCount = MakeListOfVars( VarList ); if ( VarCount ) {
VarList.Init(); while ( ITERATOR_GETNEXT( VarList, pVarNode ) ) pVarNode->SetPrefix( pPrefix ); }
Print( pStream );
if ( VarCount ) { VarList.Init(); while ( ITERATOR_GETNEXT( VarList, pVarNode ) ) pVarNode->SetPrefix( NULL ); } }
/*
// table of precedences ( lower number => lower precedence )
200 [] () . -> ()++ ()-- 190 ++() --() sizeof() & *(deref) +() -() ~() !() 180 (cast) 170 * / % 160 + - 150 << >> 140 < > <= >= 130 == != 120 & (bitwise) 110 ^ 100 | 90 && 80 || 70 ?: 60 = *= /= %= += -= <<= >>= &= |= ^= 50 , (seqential eval) 0 all other operators (should be none) */
const short Prec[] = { 0 // OP_ILLEGAL = OP_START
// OP_UNARY_START
// OP_UNARY_ARITHMETIC_START = OP_UNARY_START
,190 // OP_UNARY_PLUS = OP_UNARY_ARITHMETIC_START
,190 // OP_UNARY_MINUS
// OP_UNARY_ARITHMETIC_END
// OP_UNARY_LOGICAL_START = OP_UNARY_ARITHMETIC_END
,190 // OP_UNARY_NOT = OP_UNARY_LOGICAL_START
,190 // OP_UNARY_COMPLEMENT
// OP_UNARY_LOGICAL_END
,190 // OP_UNARY_INDIRECTION = OP_UNARY_LOGICAL_END
,180 // OP_UNARY_CAST
,190 // OP_UNARY_AND
,190 // OP_UNARY_SIZEOF
,190 // OP_UNARY_ALIGNOF
,190 // OP_PRE_INCR
,190 // OP_PRE_DECR
,200 // OP_POST_INCR
,200 // OP_POST_DECR
// OP_UNARY_END
// OP_BINARY_START = OP_UNARY_END
// OP_BINARY_ARITHMETIC_START = OP_BINARY_START
,160 // OP_PLUS = OP_BINARY_ARITHMETIC_START
,160 // OP_MINUS
,170 // OP_STAR
,170 // OP_SLASH
,170 // OP_MOD
// OP_BINARY_ARITHMETIC_END
// OP_BINARY_SHIFT_START = OP_BINARY_ARITHMETIC_END
,150 // OP_LEFT_SHIFT = OP_BINARY_SHIFT_START
,150 // OP_RIGHT_SHIFT
// OP_BINARY_SHIFT_END
// OP_BINARY_RELATIONAL_START = OP_BINARY_SHIFT_END
,140 // OP_LESS = OP_BINARY_RELATIONAL_START
,140 // OP_LESS_EQUAL
,140 // OP_GREATER_EQUAL
,140 // OP_GREATER
,130 // OP_EQUAL
,130 // OP_NOT_EQUAL
// OP_BINARY_RELATIONAL_END
// OP_BINARY_BITWISE_START = OP_BINARY_RELATIONAL_END
,120 // OP_AND = OP_BINARY_BITWISE_START
,100 // OP_OR
,110 // OP_XOR
// OP_BINARY_BITWISE_END
// OP_BINARY_LOGICAL_START = OP_BINARY_BITWISE_END
,90 // OP_LOGICAL_AND = OP_BINARY_LOGICAL_START
,80 // OP_LOGICAL_OR
// OP_BINARY_LOGICAL_END
// OP_BINARY_TERNARY_START = OP_BINARY_LOGICAL_END
,70 // OP_QM = OP_BINARY_TERNARY_START
,70 // OP_COLON
// OP_BINARY_TERNARY_END
// OP_BINARY_END = OP_BINARY_TERNARY_END
,0 // OP_INTERNAL_START = OP_BINARY_END
,200 // OP_FUNCTION
,0 // OP_PARAM
,200 // OP_POINTSTO
,200 // OP_DOT
,200 // OP_INDEX
,50 // OP_COMMA
,0 // OP_STMT
,60 // OP_ASSIGN
,0 // OP_END
};
/*
// table of associativity ( -1 => L to R, 1 => R to L )
-1 [] () . -> ()++ ()-- 1 ++() --() sizeof() & *(deref) +() -() ~() !() 1 (cast) -1 * / % -1 + - -1 << >> -1 < > <= >= -1 == != -1 & (bitwise) -1 ^ -1 | -1 && -1 || 1 ?: 1 = *= /= %= += -= <<= >>= &= |= ^= -1 , (seqential eval) 0 all other operators (should be none) */
const short AssocTbl[] = { 0 // OP_ILLEGAL = OP_START
// OP_UNARY_START
// OP_UNARY_ARITHMETIC_START = OP_UNARY_START
,-1 // OP_UNARY_PLUS = OP_UNARY_ARITHMETIC_START
,-1 // OP_UNARY_MINUS
// OP_UNARY_ARITHMETIC_END
// OP_UNARY_LOGICAL_START = OP_UNARY_ARITHMETIC_END
,1 // OP_UNARY_NOT = OP_UNARY_LOGICAL_START
,1 // OP_UNARY_COMPLEMENT
// OP_UNARY_LOGICAL_END
,1 // OP_UNARY_INDIRECTION = OP_UNARY_LOGICAL_END
,1 // OP_UNARY_CAST
,1 // OP_UNARY_AND
,1 // OP_UNARY_SIZEOF
,1 // OP_UNARY_ALIGNOF
,1 // OP_PRE_INCR
,1 // OP_PRE_DECR
,-1 // OP_POST_INCR
,-1 // OP_POST_DECR
// OP_UNARY_END
// OP_BINARY_START = OP_UNARY_END
// OP_BINARY_ARITHMETIC_START = OP_BINARY_START
,-1 // OP_PLUS = OP_BINARY_ARITHMETIC_START
,-1 // OP_MINUS
,-1 // OP_STAR
,-1 // OP_SLASH
,-1 // OP_MOD
// OP_BINARY_ARITHMETIC_END
// OP_BINARY_SHIFT_START = OP_BINARY_ARITHMETIC_END
,-1 // OP_LEFT_SHIFT = OP_BINARY_SHIFT_START
,-1 // OP_RIGHT_SHIFT
// OP_BINARY_SHIFT_END
// OP_BINARY_RELATIONAL_START = OP_BINARY_SHIFT_END
,-1 // OP_LESS = OP_BINARY_RELATIONAL_START
,-1 // OP_LESS_EQUAL
,-1 // OP_GREATER_EQUAL
,-1 // OP_GREATER
,-1 // OP_EQUAL
,-1 // OP_NOT_EQUAL
// OP_BINARY_RELATIONAL_END
// OP_BINARY_BITWISE_START = OP_BINARY_RELATIONAL_END
,-1 // OP_AND = OP_BINARY_BITWISE_START
,-1 // OP_OR
,-1 // OP_XOR
// OP_BINARY_BITWISE_END
// OP_BINARY_LOGICAL_START = OP_BINARY_BITWISE_END
,-1 // OP_LOGICAL_AND = OP_BINARY_LOGICAL_START
,-1 // OP_LOGICAL_OR
// OP_BINARY_LOGICAL_END
// OP_BINARY_TERNARY_START = OP_BINARY_LOGICAL_END
,1 // OP_QM = OP_BINARY_TERNARY_START
,1 // OP_COLON
// OP_BINARY_TERNARY_END
// OP_BINARY_END = OP_BINARY_TERNARY_END
,0 // OP_INTERNAL_START = OP_BINARY_END
,0 // OP_FUNCTION
,0 // OP_PARAM
,-1 // OP_POINTSTO
,-1 // OP_DOT
,-1 // OP_INDEX
,-1 // OP_COMMA
,0 // OP_STMT
,1 // OP_ASSIGN
,0 // OP_END
};
void expr_operator::PrintSubExpr( expr_node * pExpr, ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Print a subexpression, optionally adding parens.
Arguments:
pExpr - the expression to print pStream - A pointer to the stream to output to. Return Value: Notes:
----------------------------------------------------------------------------*/ { short PrecMe = Prec[ GetOperator() ]; short PrecChild; BOOL fAddParens = FALSE; if ( pExpr->IsOperator() ) { PrecChild = Prec[ pExpr->GetOperator() ]; // account for associativity
if ( pExpr != GetLeft() ) PrecChild = short( PrecChild + AssocTbl[ pExpr->GetOperator() ] );
fAddParens = PrecChild < PrecMe; } if ( fAddParens ) pStream->Write('(');
pExpr->Print( pStream );
if ( fAddParens ) pStream->Write(')');
}
void expr_variable::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Print a variable name expression.
Arguments:
pStream - A pointer to the stream to output to. Return Value: Notes:
----------------------------------------------------------------------------*/ { if ( GetPrefix() ) pStream->Write( GetPrefix() ); pStream->Write( GetName() ); }
char * ConstFormats[] = { "\"%s\"", // string
"L\"%Ls\"", // wstring
"0x%x", // char
"L'%Lc'", // wchar
"%d", // numeric
"%uU", // numeric unsigned
"%ldL", // numeric long
"%luUL", // numeric unsigned long
"%#x", // hex
"%#xU", // hex unsigned
"%#lxL", // hex long
"%#lxUL", // hex unsigned long
"%#o", // octal
"%#oU", // octal unsigned
"%#loL", // octal long
"%#loUL", // octal unsigned long
"%s", // BOOL ( not used )
"%g", // float
"%lg", // double
// RKK64
// value types for int64
};
void expr_constant::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a constant expression to the stream.
Arguments: pStream - A pointer to the stream.
Return Value: Notes:
----------------------------------------------------------------------------*/ { char Array[ 256 ];
Array[0] = 0; if (Format == VALUE_TYPE_BOOL) { sprintf( Array, "%s", (Value.L) ? "TRUE" : "FALSE" ); } else if ( Format == VALUE_TYPE_FLOAT ) { sprintf( Array, ConstFormats[ Format] , Value.F ); } else if ( Format == VALUE_TYPE_DOUBLE ) { sprintf( Array, ConstFormats[ Format] , Value.D ); } else if ( Format == VALUE_TYPE_CHAR ) { if ( Value.C ) { Array[0] = '0'; Array[1] = 'x'; char ch = ( char ) ( ( Value.C >> 4 ) & 0xF ); Array[2] = ( char ) ( ( ch >= 0 && ch <= 9 ) ? ch + '0' : ch + 'A' - 0xA ); ch = ( char ) ( Value.C & 0xF ); Array[3] = ( char ) ( ( ch >= 0 && ch <= 9 ) ? ch + '0' : ch + 'A' - 0xA ); Array[4] = 0; } else { Array[0] = '0'; Array[1] = 0; } } else if ( Format == VALUE_TYPE_STRING ) { if (Value.pC) { pStream->Write( "\"" ); pStream->Write( ( char* ) Value.pC ); pStream->Write( "\"" ); } else { pStream->Write( "0" ); } } else if ( Format == VALUE_TYPE_WSTRING ) { if (Value.pWC) { pStream->Write( "L\"" ); pStream->Write( ( char* ) Value.pWC ); pStream->Write( "\"" ); } else { pStream->Write( "0" ); } } else { sprintf( Array, ConstFormats[ Format] , Value.I64 ); } pStream->Write( (char *)Array ); }
void expr_op_unary::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a unary expression to the stream.
Arguments: pStream - A pointer to the stream.
Return Value: Notes:
----------------------------------------------------------------------------*/ { OPERATOR Op = GetOperator(); char ch;
switch( Op ) { case OP_UNARY_PLUS: ch = '+'; break; case OP_UNARY_MINUS: ch = '-'; break; case OP_UNARY_NOT: ch = '!'; break; case OP_UNARY_COMPLEMENT: ch = '~'; break; case OP_UNARY_INDIRECTION: ch = '*'; break; case OP_UNARY_AND: ch = '&'; break; default: ch = 'X'; break; }
pStream->Write( ch ); PrintSubExpr( GetLeft(), pStream ); }
void expr_cast::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a cast expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { if ( GetEmitModifiers() == true ) { GetType()->PrintType( (PRT_CAST), pStream, (node_skl *)0 ); } else { GetType()->PrintType( (PRT_CAST) | PRT_SUPPRESS_MODIFIERS, pStream, (node_skl *)0 ); } PrintSubExpr( GetLeft(), pStream );
}
void expr_sizeof::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a sizeof expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { pStream->Write( "sizeof" ); pType->PrintType( (PRT_CAST | PRT_ARRAY_SIZE_ONE), pStream, (node_skl *)0 ); }
void expr_alignof::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a sizeof expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { pStream->Write( "__alignof" ); pType->PrintType( (PRT_CAST | PRT_ARRAY_SIZE_ONE), pStream, (node_skl *)0 ); }
void expr_pre_incr::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a pre-incr expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { pStream->Write("++"); PrintSubExpr( GetLeft(), pStream ); }
void expr_pre_decr::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a pre-decrement expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { pStream->Write("--"); PrintSubExpr( GetLeft(), pStream ); }
void expr_post_incr::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a post-increment expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { PrintSubExpr( GetLeft(), pStream ); pStream->Write("++"); }
void expr_post_decr::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a post-decrement expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { PrintSubExpr( GetLeft(), pStream ); pStream->Write("--"); }
void expr_op_binary::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a binary arithmetic expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { PrintSubExpr( GetLeft(), pStream );
pStream->Write( OperatorToString( GetOperator() ) );
PrintSubExpr( GetRight(), pStream );
} void expr_op_binary::PrintCall( ISTREAM * pStream, short LeftMargin, BOOL fInProc ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit expression as part of a procedure call.
Arguments:
pStream - A pointer to the stream. LeftMargin - The start margin for the procedure call. fInProc - Is it in a proc context already ? Return Value: None.
Notes:
The left margin is 0 if the call is the only thing on the line. If the call is in an assignment, the start of param indent must take that into account. ----------------------------------------------------------------------------*/ { expr_node * pN; if ( ( pN = GetLeft() ) != 0 ) pN->PrintCall( pStream, LeftMargin, fInProc );
pStream->Write( OperatorToString( GetOperator() ) );
if ( ( pN = GetRight() ) != 0 ) pN->PrintCall( pStream, LeftMargin, fInProc ); } void expr_assign::PrintCall( ISTREAM * pStream, short LeftMargin, BOOL fInProc ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit expression as part of a procedure call.
Arguments:
pStream - A pointer to the stream. LeftMargin - The start margin for the procedure call. fInProc - Is it in a proc context already ? Return Value: None.
Notes:
The left margin is 0 if the call is the only thing on the line. If the call is in an assignment, the start of param indent must take that into account. ----------------------------------------------------------------------------*/ { expr_node * pN; if ( ( pN = GetLeft() ) != 0 ) pN->PrintCall( pStream, LeftMargin, fInProc );
pStream->Write( " = " );
if ( ( pN = GetRight() ) != 0 ) pN->PrintCall( pStream, LeftMargin, fInProc ); }
void expr_index::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit expression for the array index operator.
Arguments:
pStream - A pointer to the stream. Return Value: None.
Notes:
----------------------------------------------------------------------------*/ {
PrintSubExpr( GetLeft(), pStream ); pStream->Write( '[' ); GetRight()->Print( pStream ); pStream->Write( ']' ); } void expr_index::PrintCall( ISTREAM * pStream, short LeftMargin, BOOL fInProc ) { GetLeft()->PrintCall( pStream, LeftMargin, fInProc ); pStream->Write( '[' ); GetRight()->PrintCall( pStream, LeftMargin, fInProc ); pStream->Write( ']' ); }
void expr_proc_call::PrintCall( ISTREAM * pStream, short LeftMargin, BOOL fInProc ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit expression for a procedure call.
Arguments:
pStream - A pointer to the stream. LeftMargin - The start margin for the procedure call. fInProc - Is it in a proc context already ? Return Value: None.
Notes:
The left margin is 0 if the call is the only thing on the line. If the call is in an assignment, the start of param indent must take that into account. ----------------------------------------------------------------------------*/ { PNAME pName = GetName(); unsigned short CurPref = pStream->GetPreferredIndent(); unsigned short CurIndent= pStream->GetIndent();
//
// Print fancy only if more than 2 params.
//
if( GetNoOfParams() < 3 ) { Print( pStream ); if( !fInProc ) pStream->Write(';'); return; }
pStream->Write( GetName() );
pStream->Write( '(' ); pStream->SetPreferredIndent( short( LeftMargin + CurPref + strlen( pName ) - CurIndent ) ); pStream->IndentInc(); pStream->NewLine(); if( GetFirstParam()) { GetFirstParam()->PrintCall( pStream, LeftMargin, TRUE // now in proc context
); }
pStream->Write( ')' ); if( !fInProc ) pStream->Write( ';' ); pStream->IndentDec(); pStream->SetPreferredIndent( CurPref ); }
void expr_proc_call::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit expression for a procedure call.
Arguments:
pStream - A pointer to the stream. Return Value: None.
Notes:
----------------------------------------------------------------------------*/ { pStream->Write( GetName() ); pStream->Write( '(' ); if( GetFirstParam()) GetFirstParam()->Print( pStream ); pStream->Write( ')' ); }
void expr_param::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit expression for a parameter.
Arguments:
pStream - A pointer to the stream. Return Value: None.
Notes:
----------------------------------------------------------------------------*/ { expr_node * pNextParam;
GetLeft()->Print( pStream );
if ( ( pNextParam = GetNextParam() ) != 0 ) { pStream->Write( ',' ); // pStream->NewLine();
pNextParam->Print( pStream ); } }
void expr_param::PrintCall( ISTREAM * pStream, short LeftMargin, BOOL fInProc ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit expression as part of a procedure call.
Arguments:
pStream - A pointer to the stream. LeftMargin - The start margin for the procedure call. fInProc - Is it in a proc context already ? pStream - A pointer to the stream. Return Value: None.
Notes:
----------------------------------------------------------------------------*/ { expr_node * pNextParam;
GetLeft()->PrintCall( pStream, LeftMargin, fInProc );
if ( ( pNextParam = GetNextParam() ) != 0 ) { pStream->Write( ',' ); pStream->NewLine(); pNextParam->PrintCall( pStream, LeftMargin, fInProc ); } }
void expr_ternary::Print( ISTREAM * pStream ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Emit a ternary expression.
Arguments: pStream - A pointer to the stream. Return Value:
None. Notes:
Not implemented for now.
----------------------------------------------------------------------------*/ { PrintSubExpr( GetRelational(), pStream ); pStream->Write( " ? " ); PrintSubExpr( GetLeft(), pStream ); pStream->Write( " : " ); PrintSubExpr( GetRight(), pStream ); } /****************************************************************************
utilities ****************************************************************************/ char * OperatorToString( OPERATOR Op ) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Routine Description:
Translate the operator to its string.
Arguments: Op - The operator value.
Return Value: Notes:
----------------------------------------------------------------------------*/ { char *p;
switch( Op ) { case OP_PLUS: p = " + "; break; case OP_MINUS: p = " - "; break; case OP_STAR: p = " * "; break; case OP_SLASH: p = " / "; break; case OP_MOD: p = " % "; break; case OP_LEFT_SHIFT: p = " << "; break; case OP_RIGHT_SHIFT: p = " >> "; break; case OP_LESS: p = " < "; break; case OP_LESS_EQUAL: p = " <= "; break; case OP_GREATER_EQUAL: p = " >= "; break; case OP_GREATER: p = " > "; break; case OP_EQUAL: p = " == "; break; case OP_NOT_EQUAL: p = " != "; break; case OP_AND: p = " & "; break; case OP_OR: p = " | "; break; case OP_XOR: p = " ^ "; break; case OP_LOGICAL_AND: p = " && "; break; case OP_LOGICAL_OR: p = " || "; break; case OP_QM: p = " ? "; break; case OP_COLON: p = " : "; break; case OP_ASSIGN: p = " = "; break; case OP_DOT: p = " . "; break; case OP_POINTSTO: p = " -> "; break; case OP_COMMA: p = " , "; break; case OP_UNARY_NOT: p = " ! "; break; default: p = " X "; break; }
return p; }
|