compstmt.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 551 行 · 第 1/2 页

C
551
字号

static  void    GetStmtType(void) {
//=============================

    char        *curr_opnd;
    OPR         opr;

    curr_opnd = CITNode->opnd;
    if( CITNode->opn.ds != DSOPN_NAM ) {
        Error( ST_WANT_NAME );
        StmtProc = PR_NULL;
    } else if( ( *curr_opnd == 'D' ) && ( *(curr_opnd+1) == 'O' ) &&
               ( StmtSw & ( SS_EQ_THEN_COMMA | SS_COMMA_THEN_EQ ) ) ) {
        StmtProc = PR_DO;
        RemKeyword( CITNode, 2 );
    } else if( ( *curr_opnd == 'I' ) && ( *(curr_opnd+1) == 'F' ) &&
               ( CITNode->link->opr == OPR_LBR ) && ( SPtr1 != NULL ) &&
               ( ( SPtr1->opn.ds == DSOPN_NAM ) || ( SPtr1->opn.ds == DSOPN_INT ) ) ) {
        if( SPtr1->opn.ds == DSOPN_INT ) {
            StmtProc = PR_ARIF;
        } else {
            StmtProc = PR_IF;
        }
        RemKeyword( CITNode, 2 );
    } else if( ( ( StmtSw & SS_COMMA_THEN_EQ ) == 0 ) &&
               ( ( StmtSw & SS_EQUALS_FOUND ) != 0 ) ) {
        StmtProc = PR_ASNMNT;
        if( RecName() && RecNextOpr( OPR_LBR ) ) {
            if( SPtr1->opn.ds != DSOPN_PHI ) {
                DefStmtType();
            } else {
                opr = SPtr1->link->opr;
                if( opr != OPR_LBR && opr != OPR_DPT && opr != OPR_FLD ) {
                    if( opr != OPR_EQU ) {
                        DefStmtType();
                    } else {
                        LkSym();
                        if( !BitOn( SY_USAGE | SY_SUB_PARM ) &&
                            !CharSubStrung() ) {
                            StmtProc = PR_STMTFUNC;
                        }
                    }
                }
            }
        }
    } else {
        DefStmtType();
    }
}


static  void    SetCtrlFlgs(void) {
//=============================

    CtrlFlgs = CFTable[ StmtProc ];
}


static  void    DefStmtType(void) {
//=============================

    StmtProc = RecStmtKW();      // look up keyword, strip off if found
    if( StmtProc != 0 ) {
        RemKeyword( CITNode, strlen( StmtKeywords[ StmtProc ] ) );
    }
}


static  void    RemCheck(void) {
//==========================

// Check for errors or warnings concerning the dependencies
// of this statement on the last one. eg. READ before ATEND.

    if( StmtProc == PR_ATEND) {
        if( Remember.read ) {
            if( Remember.end_equals ) {
                Error( SP_ATEND_AND_ENDEQUALS );
            }
        } else {
            Error( SP_READ_NO_ATEND );
        }
    }
    if( Remember.transfer && ( StmtNo == 0 ) &&
        !CtrlFlgOn( CF_BAD_BRANCH_OBJECT | CF_IMPLICIT_LABEL ) &&
        ( !Remember.stop_or_return || ( StmtProc != PR_END ) ) ) {
        Warning( ST_NO_EXEC );
    }
    if( Remember.slct && ( StmtProc != PR_CASE ) ) {
        Error( SP_SELECT_THEN_CASE );
    }
}


void    ClearRem(void) {
//==================

// Clear the Remember flags for a new statement.

    Remember.read           = FALSE;
    Remember.end_equals     = FALSE;
    Remember.transfer       = FALSE;
    Remember.slct           = FALSE;
    Remember.endstmt        = FALSE;
    Remember.stop_or_return = FALSE;
}


static  void    CheckOrder(void) {
//============================

    AError = FALSE;
    if( (StmtProc == PR_IMP) && (SgmtSw & SG_NO_MORE_IMPLICIT) ) {
        Error( ST_IMPLICIT_LATE );
    } else if( CtrlFlgOn( CF_SPECIFICATION ) && (SgmtSw & SG_NO_MORE_SPECS) ) {
        // ENTRY and DATA statements are special specification statements
        if( (StmtProc != PR_ENTRY) && (StmtProc != PR_DATA) ) {
            Error( ST_SPEC_LATE );
        }
    } else if( CtrlFlgOn( CF_SPECIFICATION ) && (SgmtSw & SG_SEEN_DATA) ) {
        if( ( StmtProc != PR_DATA ) && !(ExtnSw & XS_DATA_STMT_ORDER) ) {
            Extension( ST_DATA_TOO_EARLY );
            ExtnSw |= XS_DATA_STMT_ORDER;
        }
    } else if( (StmtProc == PR_STMTFUNC) && (SgmtSw & SG_NO_MORE_SF) ) {
        Error( ST_ASF_LATE );
        AError = FALSE; // so we still process statement function
    }
    if( !CtrlFlgOn( CF_SUBPROGRAM ) && (StmtProc != PR_FMT) &&
        (StmtProc != PR_INCLUDE) && (StmtProc != PR_ENTRY) &&
        (StmtProc != PR_PARM) && (StmtProc != PR_DATA) &&
        (StmtProc != PR_IMP) ) {
        SgmtSw |= SG_NO_MORE_IMPLICIT;
        if( !CtrlFlgOn( CF_SPECIFICATION ) ) {
            SgmtSw |= SG_NO_MORE_SPECS;
            if( SgmtSw & SG_DEFINING_STRUCTURE ) {
                Error( SP_UNFINISHED, StmtKeywords[ PR_STRUCTURE ] );
                SgmtSw &= ~SG_DEFINING_STRUCTURE;
                AError = FALSE; // so we still process the statement
            }
            if( StmtProc != PR_STMTFUNC ) {
                SgmtSw |= SG_NO_MORE_SF;
            }
        }
    }
}


void    BadStmt(void) {
//=================

    // consider:
    //          suborutine x() ! misspelled subroutine
    //          integer z
    //          ....
    //          end
    // since the first statement is undecodable, SubProgId will never be
    // set.  This causes problems when generating browsing information and
    // in the code generation routines in the load'n go compiler.
    // If the first statement is garbage, we call DefProd() to set SubProgId
    // to the default program name.
    if( SubProgId == NULL ) {
        DefProg();
    }
    OpndErr( ST_UNKNOWN_STMT );
}


static  void    CheckDoEnd(void) {
//============================

    csnode      *cs_node;

    for(;;) {
        if( CSHead->typ == CS_DO ) {
            if( CSHead->cs_info.do_parms->do_term != StmtNo ) break;
        } else if( CSHead->typ == CS_DO_WHILE ) {
            if( CSHead->cs_info.do_term != StmtNo ) break;
        } else {
            break;
        }
        FiniDo();
    }
    cs_node = CSHead;
    while( cs_node != NULL ) {
        if( cs_node->typ == CS_DO ) {
            if( cs_node->cs_info.do_parms->do_term == StmtNo ) {
                Error( DO_NESTING_BAD );
            }
        } else if( cs_node->typ == CS_DO_WHILE ) {
            if( cs_node->cs_info.do_term == StmtNo ) {
                Error( DO_NESTING_BAD );
            }
        }
        cs_node = cs_node->link;
    }
}


static  void    FiniDo(void) {
//========================

    if( ( StmtProc != 0 ) && CtrlFlgOn( CF_BAD_DO_ENDING ) ) {
        StmtErr( DO_ENDING_BAD );
    }
    if( CSHead->typ == CS_DO ) {
        TermDo();
    } else {
        TermDoWhile();
    }
}


void    RemKeyword( itnode *itptr, int remove_len ) {
//===================================================

    char        *curr_char;
    itnode      *new_it_node;
    int         curr_size;

    itptr->oprpos += remove_len;
    itptr->opnpos = itptr->oprpos;
    if( itptr->opnd_size <= remove_len ) {
        new_it_node = itptr->link;
        if( new_it_node->opr == OPR_PHI ) {
            itptr->link = new_it_node->link;
            itptr->opn = new_it_node->opn;
            itptr->opnpos = new_it_node->opnpos;
            itptr->opnd_size = new_it_node->opnd_size;
            itptr->opnd = new_it_node->opnd;
            FreeOneNode( new_it_node );
        } else {
            itptr->opnd_size = 0;
            itptr->opn.ds = DSOPN_PHI;
        }
    } else {
        itptr->opnd += remove_len;
        itptr->opnd_size -= remove_len;
        curr_char = itptr->opnd;
        curr_size = itptr->opnd_size;
        for(;;) {
            if( curr_char == itptr->opnd + curr_size ) break;
            if( isdigit( *curr_char ) == 0 ) break;
            curr_char++;
        }
        if( curr_char != itptr->opnd ) {
            itptr->opn.ds = DSOPN_INT;
            if( curr_char - itptr->opnd != curr_size ) {
                remove_len = curr_size - ( curr_char - itptr->opnd );
                itptr->opnd_size = ( curr_char - itptr->opnd );
                new_it_node = FrlAlloc( &ITPool, sizeof( itnode ) );
                new_it_node->opnd_size = remove_len;
                new_it_node->opnd = itptr->opnd + itptr->opnd_size;
                new_it_node->opn.ds = DSOPN_NAM;
                new_it_node->opr = OPR_PHI;
                new_it_node->oprpos = itptr->opnpos + itptr->opnd_size;
                new_it_node->opnpos = new_it_node->oprpos;
                new_it_node->flags = 0;
                new_it_node->list = itptr->list;
                new_it_node->link = itptr->link;
                new_it_node->typ = TY_NO_TYPE;
                itptr->link = new_it_node;
            }
        }
    }
}


static  void    FiniStatement(void) {
//===============================

    FreeITNodes( ITHead );
    ITHead = NULL;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?