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