ppact.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 2,617 行 · 第 1/5 页
CPP
2,617 行
enum NodeState // node states
{ NS_RIGHT_BEFORE // - processing for right before
, NS_RIGHT_ACTUAL // - processing for right actual
, NS_ACTUAL // - processing for actual
, NS_LEFT_ACTUAL // - processing for left actual
, NS_LEFT_AFTER // - processing for left afters
, NS_DONE // - completed processing
};
protected:
struct PrintStack { // PRINT STACK
ExpOp* _node; // - node to be printed
NodeState _state; // - processing state
EdgeType _edge; // - current edge
unsigned inlined : 1; // - TRUE ==> will be inlined
};
static Stk<PrintStack> _pstk; // print stack
static int pstackEmpty(); // test if stack empty
static PrintStack& pstackPop(); // pop stack
static PrintStack& pstackPush // push stack
( ExpOp* node // - node
, NodeState state // - state
, int inlined ); // - TRUE ==> is inline node
static PrintStack& pstackTop(); // access top of stack
#ifndef NDEBUG
static pstackDump()
{
static char* state[] =
{ "NS_RIGHT_BEFORE"
, "NS_RIGHT_ACTUAL"
, "NS_ACTUAL "
, "NS_LEFT_ACTUAL "
, "NS_LEFT_AFTER "
, "NS_DONE "
};
static char* edge[] =
{ "edge_none "
, "edge_right_prt "
, "edge_right_blank"
, "edge_left_prt "
, "edge_left_blank "
, "edge_arg "
, "edge_call "
};
if( ! pstackEmpty() ) {
printf( "PSTACK:\n" );
unsigned index;
for( index = 0; index < _pstk._sp; ++ index ) {
printf( "%d %p %s %s %d "
, index
, _pstk._stack._array[index]._node
, state[ _pstk._stack._array[index]._state ]
, edge[ _pstk._stack._array[index]._edge ]
, _pstk._stack._array[index].inlined
);
_pstk._stack._array[index]._node->printActual( stdout );
printf( "\n" );
}
}
}
#endif
};
ExpOp::ExpOp( Str const & type // CONSTRUCTOR
, CgId id )
: _type( type )
, _id( id )
{
}
static Set<ExpOp> ExpOp::_live; // live list
static Stk<ExpOp::PrintStack> ExpOp::_pstk; // print stack
static ExpOp* ExpOp::find( CgId id ) // FIND LIVE EXPRESSION
{
SetIter<ExpOp> iter( _live );
ExpOp* expr;
for( ; ; ++iter ) {
expr = *iter;
if( expr == 0 ) break;
if( id == expr->_id ) break;
}
return expr;
}
ExpOp* ExpOp::nodeLeft // GET LEFT NODE
( void )
const
{
return 0;
}
ExpOp* ExpOp::nodeRight // GET RIGHT NODE
( void )
const
{
return 0;
}
static ExpOp* ExpOp::popLive( CgId id ) // FIND AND REMOVE LIVE EXPRESSION
{
ExpOp* expr = find( id );
if( expr != 0 ) {
removeLive( expr );
}
return expr;
}
static
ExpOp::PrintStack& ExpOp::pstackPop // POP PRINT STACK
( void )
{
return _pstk.pop();
}
static
ExpOp::PrintStack& ExpOp::pstackTop // ACCESS TOP OF PRINT STACK
( void )
{
return _pstk.top();
}
static
ExpOp::PrintStack& ExpOp::pstackPush // PUSH ON PRINT STACK
( ExpOp* node // - node
, NodeState state // - state
, int inlined ) // - TRUE ==> is inline node
{
PrintStack& stk = _pstk.push();
stk._node = node;
stk._state = state;
stk._edge = edge_none;
stk.inlined = inlined;
return stk;
}
static int ExpOp::pstackEmpty // TEST IF EMPTY
( void )
{
return _pstk.empty();
}
void ExpOp::print // PRINT A TREE
( FILE* out )
{
pstackPush( this, NS_RIGHT_BEFORE, 0 );
for( ; ; ) {
#ifndef NDEBUG
if( options.pstack ) {
pstackDump();
}
#endif
PrintStack & top = pstackTop();
PrtType type = top._node->printType();
switch( top._state ) {
case NS_RIGHT_BEFORE :
if( type & PRT_BEFORE_RIGHT ) {
pstackPush( top._node->nodeRight(), NS_RIGHT_BEFORE, 0 );
top._edge = edge_right_blank;
top._state = NS_RIGHT_ACTUAL;
continue;
}
case NS_RIGHT_ACTUAL :
if( type & PRT_ACTUAL_RIGHT ) {
pstackPush( top._node->nodeRight(), NS_RIGHT_BEFORE, 1 );
if( top.inlined ) {
top._state = NS_DONE;
} else {
top._state = NS_ACTUAL;
}
continue;
} else if( type & PRT_ACTUAL_LEFT ) {
pstackPush( top._node->nodeLeft(), NS_RIGHT_BEFORE, 1 );
if( top.inlined ) {
top._state = NS_DONE;
} else {
top._state = NS_ACTUAL;
}
continue;
}
case NS_ACTUAL :
if( top.inlined ) {
_pstk.pop();
continue;
} else {
printIndentation( out );
ExpOp* node;
PrtType ntype;
for( node = top._node, ntype = type; ; ) {
node->printActual( out );
if( ntype & PRT_ACTUAL_RIGHT ) {
node = node->nodeRight();
} else if( ntype & PRT_ACTUAL_LEFT ) {
node = node->nodeLeft();
} else {
break;
}
ntype = node->printType();
}
fputc( '\n', out );
}
case NS_LEFT_ACTUAL :
if( type & PRT_ACTUAL_RIGHT ) {
pstackPush( top._node->nodeRight(), NS_LEFT_ACTUAL, 1 );
if( type & PRT_AFTER_LEFT ) {
if( type & PRT_CALL ) {
top._edge = edge_call;
} else if( type & PRT_ARG ) {
top._edge = edge_none;
if( ! type & PRT_AFTER_LEFT ) {
((&top)-1)->_edge = edge_left_prt;
}
} else {
top._edge = edge_left_prt;
}
top._state = NS_LEFT_AFTER;
} else {
top._state = NS_DONE;
}
continue;
} else if( type & PRT_ACTUAL_LEFT ) {
pstackPush( top._node->nodeLeft(), NS_LEFT_ACTUAL, 1 );
top._state = NS_DONE;
continue;
}
case NS_LEFT_AFTER :
if( type & PRT_AFTER_LEFT ) {
if( type & PRT_ARG ) {
top._node = top._node->nodeLeft();
top._edge = edge_none;
top._state = NS_RIGHT_BEFORE;
top.inlined = 0;
if( ! ( top._node->printType() & PRT_AFTER_LEFT ) ) {
((&top)-1)->_edge = edge_left_prt;
}
} else {
ExpOp* left = top._node->nodeLeft();
if( type & PRT_CALL ) {
if( left->printType() & PRT_AFTER_LEFT ) {
top._edge = edge_call;
} else {
top._edge = edge_left_prt;
}
} else {
top._edge = edge_left_prt;
}
pstackPush( left, NS_RIGHT_BEFORE, 0 );
top._state = NS_DONE;
}
continue;
}
case NS_DONE :
_pstk.pop();
if( _pstk.empty() ) break;
continue;
}
break;
}
}
void ExpOp::printActual // DEFAULT PRINT (ACTUAL
( FILE* out )
{
#if 0
if( options.verbose ) {
fprintf( out
, " %s id=%d"
, (const char*)_type
, _id );
}
#else
char buffer[128];
fputs( nodeName( buffer ), out );
#endif
}
char* ExpOp::nodeName // DEFAULT NODE NAME FOR ExpOp
( char * buffer ) // - default buffer
const
{
buffer[0] = '\0';
if( options.verbose ) {
char* p = buffer;
char buf[32];
if( 0 != _type ) {
p = stpcpy( p, " " );
p = stpcpy( p, (char const *)_type );
}
if( 0 != _id ) {
p = stpcpy( p, " id=" );
p = stpcpy( p, utoa( _id, buf, 16 ) );
}
}
return buffer;
}
void ExpOp::printAfter // DEFAULT PRINT (AFTER)
( FILE* )
{
}
static void ExpOp::printAfter // PRINT INDENTED ENTRY (AFTER)
( FILE* out
, ExpOp* operand )
{
print( out, operand );
}
void ExpOp::printBefore // DEFAULT PRINT (BEFORE)
( FILE* )
{
}
static void ExpOp::printIndentation // PRINT INDENTATION
( FILE* out )
{
unsigned bound = _pstk._sp - 1;
unsigned curr = bound - 1;
int index;
int skipped_args = 0;
char seg[5] = " ";
char last;
for( index = 0; index < bound; ++ index ) {
PrintStack & ps = _pstk[ index ];
EdgeType& edge = ps._edge;
if( index == curr ) {
if( edge == edge_right_blank ) {
last = BOX_CORNER_UP;
edge = edge_right_prt;
} else if( edge == edge_call ) {
last = BOX_TEE_RIGHT;
} else {
if( skipped_args == 0 ) {
last = BOX_CORNER_DN;
edge = edge_left_blank;
} else {
last = BOX_TEE_RIGHT;
}
}
} else {
#if 0
if( edge == edge_arg ) {
++ skipped_args;
continue;
} else if( edge == edge_call ) {
++ skipped_args;
} else {
skipped_args = 0;
}
#endif
if( edge == edge_left_prt
#if 1
|| edge == edge_call
#endif
|| edge == edge_right_prt ) {
last = BOX_LINE_VERT;
} else {
last = ' ';
}
}
seg[3] = last;
fputs( seg, out );
}
}
ExpOp::PrtType ExpOp::printType // DEFAULT PRINT-TYPE (ONLY SELF)
( void )
const
{
return PRT_ACTUAL_SELF;
}
static void ExpOp::print // PRINT INDENTED ENTRY
( FILE* out
, ExpOp* operand )
{
if( 0 != operand ) {
operand->print( out );
}
}
#ifdef TRPRTDLL
////////////////////////////////////////////////////////////////////////////
//
// Use tree-printing DLL
//
////////////////////////////////////////////////////////////////////////////
TreePtr treeSuppLeft // GET LEFT OPERAND
( TreePtr node ) // - node
{
return TreePtr( ((ExpOp*)node)->nodeLeft() );
}
TreePtr treeSuppRight // GET RIGHT OPERAND
( TreePtr node ) // - node
{
return TreePtr( ((ExpOp*)node)->nodeRight() );
}
char const * treeSuppName // GET NAME
( TreePtr node ) // - node
{
static char name_buffer[120];
return ((ExpOp*)node)->nodeName( name_buffer );
}
unsigned treeSuppWidth // GET WIDTH
( TreePtr node ) // - node
{
return strlen( treeSuppName( node ) );
}
static FILE* output_file;
void treeSuppPrint // PRINT A LINE
( char const *line ) // - the line
{
fputs( line, output_file );
fputc( '\n', output_file );
}
static TreeSupport support // TREE-PRINTING SUPPORT STRUCTURE
( &treeSuppLeft
, &treeSuppRight
, &treeSuppWidth
, &treeSuppName
, &treeSuppPrint
, 0
, 0
);
#endif
static void ExpOp::verifyEmpty // VERIFY LIVE SET IS EMPTY
( FILE* out )
{
SetIter<ExpOp> iter( _live );
for( ; ; ) {
ExpOp* expr = *iter;
if( expr == 0 ) break;
fputs( "\nFollowing expression was not connected\n", out );
#ifdef TRPRTDLL
support.print( TreePtr( expr ) );
#else
expr->print( out );
#endif
iter.erase();
delete expr;
}
}
////////////////////////////////////////////////////////////////////////////
//
// ExpBitMask -- expression bit mask
//
////////////////////////////////////////////////////////////////////////////
struct ExpBitMask
: public ExpOp
{
Str _start;
Str _size;
ExpOp* _operand;
ExpBitMask( Str const & type // CONSTRUCTOR
, CgId id
, CgId operand
, Str const & start
, Str const & size )
: ExpOp( type, id )
, _start( start )
, _size( size )
, _operand( ExpOp::popLive( operand ) )
{
}
ExpOp* nodeLeft() const; // GET 0 OR LEFT NODE
char* nodeName( char * ) const; // GET NODE NAME
// void printActual( FILE* ); // PRINT AN ENTRY (ACTUAL)
PrtType printType() const; // DETERMINE PRINTING TYPE
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?