compstmt.c

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

C
551
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


//
// COMPSTMT  : compile a FORTRAN statement
//

#include "ftnstd.h"
#include "progsw.h"
#include "stmtsw.h"
#include "errcod.h"
#include "opr.h"
#include "opn.h"
#include "cpopt.h"
#include "segsw.h"
#include "extnsw.h"
#include "ctrlflgs.h"
#include "global.h"
#include "recog.h"
#include "ferror.h"
#include "insert.h"
#include "frl.h"
#include "inout.h"
#include "utility.h"

#include <string.h>
#include <ctype.h>

extern  sym_id          LkSym(void);
extern  void            MakeITList(void);
extern  STMT            RecStmtKW(void);
extern  void            TermDo(void);
extern  void            TermDoWhile(void);
extern  void            DefStmtNo(unsigned_32);
extern  void            Update(unsigned_32);
extern  void            STResolve(void);
extern  void            GSetDbugLine(void);
extern  void            Prologue(void);
extern  void            DefProg(void);
extern  bool            SubStrung(void);
extern  void            GSetSrcLine(void);
extern  void            TDStmtInit(void);
extern  void            TDStmtFini(void);

extern  char                    *StmtKeywords[];
extern  void                    (* const __FAR ProcTable[])();
extern  const unsigned_16       __FAR CFTable[];


static  void    ChkStatementSequence(void) {
//======================================

    SetCtrlFlgs();
    if( ( StmtSw & SS_HOLLERITH ) && ( StmtProc != PR_FMT ) ) {
        Extension( HO_CONST );
    }
    if( SgmtSw & SG_DEFINING_MAP ) {
        if( CtrlFlgOn( CF_NOT_IN_MAP ) ) {
            StmtPtrErr( SP_NOT_IN_STRUCTURE, StmtKeywords[PR_MAP] );
        }
    } else if( SgmtSw & SG_DEFINING_UNION ) {
        if( CtrlFlgOn( CF_NOT_IN_UNION ) ) {
            StmtPtrErr( SP_NOT_IN_STRUCTURE, StmtKeywords[PR_UNION] );
        }
    } else if( SgmtSw & SG_DEFINING_STRUCTURE ) {
        if( CtrlFlgOn( CF_NOT_IN_STRUCTURE ) ) {
            StmtPtrErr( SP_NOT_IN_STRUCTURE, StmtKeywords[PR_STRUCTURE] );
        }
    } else {
        if( StmtProc == PR_MAP ) {
            StmtPtrErr( SP_STATEMENT_REQUIRED, StmtKeywords[PR_UNION] );
        } else if( StmtProc == PR_UNION ) {
            StmtPtrErr( SP_STATEMENT_REQUIRED, StmtKeywords[PR_STRUCTURE] );
        }
    }
    if( ( ( SgmtSw & SG_PROLOG_DONE ) == 0 ) &&
        ( ProgSw & PS_IN_SUBPROGRAM ) &&
        ( !CtrlFlgOn( CF_SPECIFICATION ) ) &&
        ( StmtProc != PR_FMT ) && ( StmtProc != PR_INCLUDE ) ) {
        Prologue();
    }
    if( ( ( SgmtSw & SG_SYMTAB_RESOLVED ) == 0 ) &&
        ( !CtrlFlgOn( CF_SPECIFICATION | CF_SUBPROGRAM ) ) &&
        ( StmtProc != PR_FMT ) && ( StmtProc != PR_INCLUDE ) ) {
        STResolve();
        SgmtSw |= SG_SYMTAB_RESOLVED;
    }
    if( Remember.endstmt || ( ( SgmtSw & SG_STMT_PROCESSED ) == 0 ) ) {
        if( !CtrlFlgOn( CF_SUBPROGRAM ) && ( StmtProc != PR_INCLUDE ) ) {
            DefProg();
        }
    }
    // Must be done after prologue so that a label can be dumped
    if( !CtrlFlgOn( CF_SUBPROGRAM ) ) {
        CkDefStmtNo();
    }
}


static  void    ProcStmt( void ) {
//================================

    if( AError )
        return;
    if( CpError && (StmtProc == PR_NULL) )
        return;
    ProcTable[ StmtProc ]();
}


void    CompStatement( void ) {
//=============================

    bool        scan_error;

    InitStatement();
    scan_error = CpError;
    if( ITHead != NULL ) {
        GetStmtType();
        // if it's a bad statement:
        //    - don't set control flags so that we don't get cascading
        //      errors in the following case
        //          INTEGER X
        //          ITNEGER Y
        //          REAL Z
        //    - don't let STResolve() get done so that we have incomplete
        //      data structures as in the following case
        //          A : 2
        //          CHARACTER A, B(79)
        //          EQUIVALENCE (A,B(1))
        //          END
        if( !scan_error && (StmtProc != PR_NULL) ) {
            ChkStatementSequence();
        }
    }
    if( !scan_error ) {
        if( CurrFile->link == NULL ) {  // no line numbering information for
            GSetDbugLine();             // include files
        }
        if( CtrlFlgOn( CF_NEED_SET_LINE ) && ( Options & OPT_TRACE ) ) {
            GSetSrcLine();
        }
        CheckOrder();
        if( ( ProgSw & PS_BLOCK_DATA ) && !CtrlFlgOn( CF_BLOCK_DATA ) ) {
            // if statement wasn't decodeable, don't issue an error
            if( StmtProc != PR_NULL ) {
                StmtErr( BD_IN_BLOCK_DATA );
            }
        } else if( CtrlFlgOn( CF_NOT_EXECUTABLE ) ) {
            ProcStmt();
        } else {
            RemCheck();
            ClearRem();
            ProcStmt();
        }
    }
    // Must come before CheckDoEnd(). Consider:
    //           DO I=1,10
    //   10      M = M + 1
    // We must terminate the statement containing the DO label before we
    // terminate the DO-loop.
    TDStmtFini();
    if( StmtNo != 0 ) {
        Update( StmtNo );
        CheckDoEnd();
    }
    // The following must include a check for scanning errors since it is
    // possible to get a scanning error and "StmtProc != PR_NULL" as in the
    // following example:       integer*2 fwinmain( hInstance
    // If the check for a scanning error is not performed, then SubProgId
    // will not be properly set when we compile the RETURN statement in the
    // following example:       integer*2 fwinmain( hInstance
    //                          return
    if( !scan_error && (StmtProc != PR_NULL) && (StmtProc != PR_INCLUDE) ) {
        SgmtSw |= SG_STMT_PROCESSED;
    }
    FiniStatement();
}


void    CkDefStmtNo(void) {
//=====================

    if( StmtNo != 0 ) {
        DefStmtNo( StmtNo );
    }
}


void    Recurse(void) {
//=================

// Compile a statement after a logical IF or AT END.
// Do not be alarmed by the name of this routine. The recursion is
// controlled so that it may only happen once due to the fact that
// another IF or AT END cannot follow the first one.

    unsigned_16 ctrlflgs;
    STMT        proc;

    CITNode->opr = OPR_TRM;
    ctrlflgs = CtrlFlgs;
    proc = StmtProc;
    SPtr1 = SPtr2;
    GetStmtType();
    SetCtrlFlgs();
    if( CtrlFlgOn( CF_NOT_SIMPLE_STMT ) ) { // controls recursion
        StmtPtrErr( ST_NOT_ALLOWED, StmtKeywords[ proc ] );
    } else {
        ProcStmt();
        ClearRem();
        TDStmtFini();
        if( CtrlFlgOn( CF_NOT_SIMPLE_STMT | CF_NOT_EXECUTABLE ) ) {
            StmtPtrErr( ST_NOT_ALLOWED, StmtKeywords[ proc ] );
        }
    }
    StmtProc = proc;
    CtrlFlgs = ctrlflgs;
}


static  void    InitStatement(void) {
//===============================

    TDStmtInit();
    ChkPntLst();
    StmtSw = SS_SCANNING;
    CpError = FALSE;
    MakeITList();
    StmtSw &= ~SS_SCANNING;
    StmtProc = 0;
}


static  bool    CharSubStrung(void) {
//================================

    bool        substrung;
    itnode      *cit;

    cit = CITNode;
    AdvanceITPtr();                     // step up to the OPR_LBR
    substrung = SubStrung();
    CITNode = cit;
    return( substrung );
}

⌨️ 快捷键说明

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