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 + -
显示快捷键?