/* stc.c -- Implementation File (module.c template V1.0) Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Contributed by James Craig Burley. This file is part of GNU Fortran. GNU Fortran is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU Fortran is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Fortran; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Related Modules: st.c Description: Verifies the proper semantics for statements, checking expressions already semantically analyzed individually, collectively, checking label defs and refs, and so on. Uses ffebad to indicate errors in semantics. In many cases, both a token and a keyword (ffestrFirst, ffestrSecond, or ffestrOther) is provided. ONLY USE THE TOKEN as a pointer to the source-code location for an error message or similar; use the keyword as the semantic matching for the token, since the token's text might not match the keyword's code. For example, INTENT(IN OUT) A in free source form passes to ffestc_R519_start the token "IN" but the keyword FFESTR_otherINOUT, and the latter is correct. Generally, either a single ffestc function handles an entire statement, in which case its name is ffestc_xyz_, or more than one function is needed, in which case its names are ffestc_xyz_start_, ffestc_xyz_item_ or ffestc_xyz_item_abc_, and ffestc_xyz_finish_. The caller must call _start_ before calling any _item_ functions, and must call _finish_ afterwards. If it is clearly a syntactic matter as to restrictions on the number and variety of _item_ calls, then the caller should report any errors and ffestc_ should presume it has been taken care of and handle any semantic problems with grace and no error messages. If the permitted number and variety of _item_ calls has some basis in semantics, then the caller should not generate any messages and ffestc should do all the checking. A few ffestc functions have names rather than grammar numbers, like ffestc_elsewhere and ffestc_end. These are cases where the actual statement depends on its context rather than just its form; ELSE WHERE may be the obvious (WHERE...ELSE WHERE...END WHERE) or something a little more subtle (WHERE: IF THEN...ELSE WHERE...END IF WHERE). The actual ffestc functions do exist and do work, but may or may not be invoked by ffestb depending on whether some form of resolution is possible. For example, ffestc_R1103 end-program-stmt is reachable directly when END PROGRAM [name] is specified, or via ffestc_end when END is specified and the context is a main program. So ffestc_xyz_ should make a quick determination of the context and pick the appropriate ffestc_Nxyz_ function to invoke, without a lot of ceremony. Modifications: */ /* Include files. */ #include "proj.h" #include "stc.h" #include "bad.h" #include "bld.h" #include "data.h" #include "expr.h" #include "global.h" #include "implic.h" #include "lex.h" #include "malloc.h" #include "src.h" #include "sta.h" #include "std.h" #include "stp.h" #include "str.h" #include "stt.h" #include "stw.h" /* Externals defined here. */ ffeexprContext ffestc_iolist_context_ = FFEEXPR_contextIOLIST; /* Valid only from READ/WRITE start to finish. */ /* Simple definitions and enumerations. */ typedef enum { FFESTC_orderOK_, /* Statement ok in this context, process. */ FFESTC_orderBAD_, /* Statement not ok in this context, don't process. */ FFESTC_orderBADOK_, /* Don't process but push block if applicable. */ FFESTC } ffestcOrder_; typedef enum { FFESTC_stateletSIMPLE_, /* Expecting simple/start. */ FFESTC_stateletATTRIB_, /* Expecting attrib/item/itemstart. */ FFESTC_stateletITEM_, /* Expecting item/itemstart/finish. */ FFESTC_stateletITEMVALS_, /* Expecting itemvalue/itemendvals. */ FFESTC_ } ffestcStatelet_; /* Internal typedefs. */ /* Private include files. */ /* Internal structure definitions. */ union ffestc_local_u_ { struct { ffebld initlist; /* For list of one sym in INTEGER I/3/ case. */ ffetargetCharacterSize stmt_size; ffetargetCharacterSize size; ffeinfoBasictype basic_type; ffeinfoKindtype stmt_kind_type; ffeinfoKindtype kind_type; bool per_var_kind_ok; char is_R426; /* 1=R426, 2=R501. */ } decl; struct { ffebld objlist; /* For list of target objects. */ ffebldListBottom list_bottom; /* For building lists. */ } data; struct { ffebldListBottom list_bottom; /* For building lists. */ int entry_num; } dummy; struct { ffesymbol symbol; /* NML symbol. */ } namelist; struct { ffelexToken t; /* First token in list. */ ffeequiv eq; /* Current equivalence being built up. */ ffebld list; /* List of expressions in equivalence. */ ffebldListBottom bottom; bool ok; /* TRUE while current list still being processed. */ bool save; /* TRUE if any var in list is SAVEd. */ } equiv; struct { ffesymbol symbol; /* BCB/NCB symbol. */ } common; struct { ffesymbol symbol; /* SFN symbol. */ } sfunc; #if FFESTR_VXT struct { char list_state; /* 0=>no field names allowed, 1=>error reported already, 2=>field names req'd, 3=>have a field name. */ } V003; #endif }; /* Merge with the one in ffestc later. */ /* Static objects accessed by functions in this module. */ static bool ffestc_ok_; /* _start_ fn's send this to _xyz_ fn's. */ static bool ffestc_parent_ok_; /* Parent sym for baby sym fn's ok. */ static char ffestc_namelist_; /* 0=>not namelist, 1=>namelist, 2=>error. */ static union ffestc_local_u_ ffestc_local_; static ffestcStatelet_ ffestc_statelet_ = FFESTC_stateletSIMPLE_; static ffestwShriek ffestc_shriek_after1_ = NULL; static unsigned long ffestc_blocknum_ = 0; /* Next block# to assign. */ static int ffestc_entry_num_; static int ffestc_sfdummy_argno_; static int ffestc_saved_entry_num_; static ffelab ffestc_label_; /* Static functions (internal). */ static void ffestc_R544_equiv_ (ffebld expr, ffelexToken t); static void ffestc_establish_declinfo_ (ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent); static void ffestc_establish_declstmt_ (ffestpType type, ffelexToken typet, ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent); static void ffestc_establish_impletter_ (ffelexToken first, ffelexToken last); static ffeinfoKindtype ffestc_kindtype_kind_ (ffeinfoBasictype bt, ffetargetCharacterSize val); static ffeinfoKindtype ffestc_kindtype_star_ (ffeinfoBasictype bt, ffetargetCharacterSize val); static void ffestc_labeldef_any_ (void); static bool ffestc_labeldef_begin_ (void); static void ffestc_labeldef_branch_begin_ (void); static void ffestc_labeldef_branch_end_ (void); static void ffestc_labeldef_endif_ (void); static void ffestc_labeldef_format_ (void); static void ffestc_labeldef_invalid_ (void); static void ffestc_labeldef_notloop_ (void); static void ffestc_labeldef_notloop_begin_ (void); static void ffestc_labeldef_useless_ (void); static bool ffestc_labelref_is_assignable_ (ffelexToken label_token, ffelab *label); static bool ffestc_labelref_is_branch_ (ffelexToken label_token, ffelab *label); static bool ffestc_labelref_is_format_ (ffelexToken label_token, ffelab *label); static bool ffestc_labelref_is_loopend_ (ffelexToken label_token, ffelab *label); #if FFESTR_F90 static ffestcOrder_ ffestc_order_access_ (void); #endif static ffestcOrder_ ffestc_order_actiondo_ (void); static ffestcOrder_ ffestc_order_actionif_ (void); static ffestcOrder_ ffestc_order_actionwhere_ (void); static void ffestc_order_any_ (void); static void ffestc_order_bad_ (void); static ffestcOrder_ ffestc_order_blockdata_ (void); static ffestcOrder_ ffestc_order_blockspec_ (void); #if FFESTR_F90 static ffestcOrder_ ffestc_order_component_ (void); #endif #if FFESTR_F90 static ffestcOrder_ ffestc_order_contains_ (void); #endif static ffestcOrder_ ffestc_order_data_ (void); static ffestcOrder_ ffestc_order_data77_ (void); #if FFESTR_F90 static ffestcOrder_ ffestc_order_derivedtype_ (void); #endif static ffestcOrder_ ffestc_order_do_ (void); static ffestcOrder_ ffestc_order_entry_ (void); static ffestcOrder_ ffestc_order_exec_ (void); static ffestcOrder_ ffestc_order_format_ (void); static ffestcOrder_ ffestc_order_function_ (void); static ffestcOrder_ ffestc_order_iface_ (void); static ffestcOrder_ ffestc_order_ifthen_ (void); static ffestcOrder_ ffestc_order_implicit_ (void); static ffestcOrder_ ffestc_order_implicitnone_ (void); #if FFESTR_F90 static ffestcOrder_ ffestc_order_interface_ (void); #endif #if FFESTR_F90 static ffestcOrder_ ffestc_order_map_ (void); #endif #if FFESTR_F90 static ffestcOrder_ ffestc_order_module_ (void); #endif static ffestcOrder_ ffestc_order_parameter_ (void); static ffestcOrder_ ffestc_order_program_ (void); static ffestcOrder_ ffestc_order_progspec_ (void); #if FFESTR_F90 static ffestcOrder_ ffestc_order_record_ (void); #endif static ffestcOrder_ ffestc_order_selectcase_ (void); static ffestcOrder_ ffestc_order_sfunc_ (void); #if FFESTR_F90 static ffestcOrder_ ffestc_order_spec_ (void); #endif #if FFESTR_VXT static ffestcOrder_ ffestc_order_structure_ (void); #endif static ffestcOrder_ ffestc_order_subroutine_ (void); #if FFESTR_F90 static ffestcOrder_ ffestc_order_type_ (void); #endif static ffestcOrder_ ffestc_order_typedecl_ (void); #if FFESTR_VXT static ffestcOrder_ ffestc_order_union_ (void); #endif static ffestcOrder_ ffestc_order_unit_ (void); #if FFESTR_F90 static ffestcOrder_ ffestc_order_use_ (void); #endif #if FFESTR_VXT static ffestcOrder_ ffestc_order_vxtstructure_ (void); #endif #if FFESTR_F90 static ffestcOrder_ ffestc_order_where_ (void); #endif static void ffestc_promote_dummy_ (ffelexToken t); static void ffestc_promote_execdummy_ (ffelexToken t); static void ffestc_promote_sfdummy_ (ffelexToken t); static void ffestc_shriek_begin_program_ (void); #if FFESTR_F90 static void ffestc_shriek_begin_uses_ (void); #endif static void ffestc_shriek_blockdata_ (bool ok); static void ffestc_shriek_do_ (bool ok); static void ffestc_shriek_end_program_ (bool ok); #if FFESTR_F90 static void ffestc_shriek_end_uses_ (bool ok); #endif static void ffestc_shriek_function_ (bool ok); static void ffestc_shriek_if_ (bool ok); static void ffestc_shriek_ifthen_ (bool ok); #if FFESTR_F90 static void ffestc_shriek_interface_ (bool ok); #endif #if FFESTR_F90 static void ffestc_shriek_map_ (bool ok); #endif #if FFESTR_F90 static void ffestc_shriek_module_ (bool ok); #endif static void ffestc_shriek_select_ (bool ok); #if FFESTR_VXT static void ffestc_shriek_structure_ (bool ok); #endif static void ffestc_shriek_subroutine_ (bool ok); #if FFESTR_F90 static void ffestc_shriek_type_ (bool ok); #endif #if FFESTR_VXT static void ffestc_shriek_union_ (bool ok); #endif #if FFESTR_F90 static void ffestc_shriek_where_ (bool ok); #endif #if FFESTR_F90 static void ffestc_shriek_wherethen_ (bool ok); #endif static int ffestc_subr_binsrch_ (const char **list, int size, ffestpFile *spec, const char *whine); static ffestvFormat ffestc_subr_format_ (ffestpFile *spec); static bool ffestc_subr_is_branch_ (ffestpFile *spec); static bool ffestc_subr_is_format_ (ffestpFile *spec); static bool ffestc_subr_is_present_ (const char *name, ffestpFile *spec); static int ffestc_subr_speccmp_ (const char *string, ffestpFile *spec, const char **target, int *length); static ffestvUnit ffestc_subr_unit_ (ffestpFile *spec); static void ffestc_try_shriek_do_ (void); /* Internal macros. */ #define ffestc_check_simple_() \ assert(ffestc_statelet_ == FFESTC_stateletSIMPLE_) #define ffestc_check_start_() \ assert(ffestc_statelet_ == FFESTC_stateletSIMPLE_); \ ffestc_statelet_ = FFESTC_stateletATTRIB_ #define ffestc_check_attrib_() \ assert(ffestc_statelet_ == FFESTC_stateletATTRIB_) #define ffestc_check_item_() \ assert(ffestc_statelet_ == FFESTC_stateletATTRIB_ \ || ffestc_statelet_ == FFESTC_stateletITEM_); \ ffestc_statelet_ = FFESTC_stateletITEM_ #define ffestc_check_item_startvals_() \ assert(ffestc_statelet_ == FFESTC_stateletATTRIB_ \ || ffestc_statelet_ == FFESTC_stateletITEM_); \ ffestc_statelet_ = FFESTC_stateletITEMVALS_ #define ffestc_check_item_value_() \ assert(ffestc_statelet_ == FFESTC_stateletITEMVALS_) #define ffestc_check_item_endvals_() \ assert(ffestc_statelet_ == FFESTC_stateletITEMVALS_); \ ffestc_statelet_ = FFESTC_stateletITEM_ #define ffestc_check_finish_() \ assert(ffestc_statelet_ == FFESTC_stateletATTRIB_ \ || ffestc_statelet_ == FFESTC_stateletITEM_); \ ffestc_statelet_ = FFESTC_stateletSIMPLE_ #define ffestc_order_action_() ffestc_order_exec_() #if FFESTR_F90 #define ffestc_order_interfacespec_() ffestc_order_derivedtype_() #endif #define ffestc_shriek_if_lost_ ffestc_shriek_if_ #if FFESTR_F90 #define ffestc_shriek_where_lost_ ffestc_shriek_where_ #endif /* ffestc_establish_declinfo_ -- Determine specific type/params info for entity ffestc_establish_declinfo_(kind,kind_token,len,len_token); Must be called after _declstmt_ called to establish base type. */ static void ffestc_establish_declinfo_ (ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent) { ffeinfoBasictype bt = ffestc_local_.decl.basic_type; ffeinfoKindtype kt; ffetargetCharacterSize val; if (kindt == NULL) kt = ffestc_local_.decl.stmt_kind_type; else if (!ffestc_local_.decl.per_var_kind_ok) { ffebad_start (FFEBAD_KINDTYPE); ffebad_here (0, ffelex_token_where_line (kindt), ffelex_token_where_column (kindt)); ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); kt = ffestc_local_.decl.stmt_kind_type; } else { if (kind == NULL) { assert (ffelex_token_type (kindt) == FFELEX_typeNUMBER); val = atol (ffelex_token_text (kindt)); kt = ffestc_kindtype_star_ (bt, val); } else if (ffebld_op (kind) == FFEBLD_opANY) kt = ffestc_local_.decl.stmt_kind_type; else { assert (ffebld_op (kind) == FFEBLD_opCONTER); assert (ffeinfo_basictype (ffebld_info (kind)) == FFEINFO_basictypeINTEGER); assert (ffeinfo_kindtype (ffebld_info (kind)) == FFEINFO_kindtypeINTEGERDEFAULT); val = ffebld_constant_integerdefault (ffebld_conter (kind)); kt = ffestc_kindtype_kind_ (bt, val); } if (kt == FFEINFO_kindtypeNONE) { /* Not valid kind type. */ ffebad_start (FFEBAD_KINDTYPE); ffebad_here (0, ffelex_token_where_line (kindt), ffelex_token_where_column (kindt)); ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); kt = ffestc_local_.decl.stmt_kind_type; } } ffestc_local_.decl.kind_type = kt; /* Now check length specification for CHARACTER data type. */ if (((len == NULL) && (lent == NULL)) || (bt != FFEINFO_basictypeCHARACTER)) val = ffestc_local_.decl.stmt_size; else { if (len == NULL) { assert (ffelex_token_type (lent) == FFELEX_typeNUMBER); val = atol (ffelex_token_text (lent)); } else if (ffebld_op (len) == FFEBLD_opSTAR) val = FFETARGET_charactersizeNONE; else if (ffebld_op (len) == FFEBLD_opANY) val = FFETARGET_charactersizeNONE; else { assert (ffebld_op (len) == FFEBLD_opCONTER); assert (ffeinfo_basictype (ffebld_info (len)) == FFEINFO_basictypeINTEGER); assert (ffeinfo_kindtype (ffebld_info (len)) == FFEINFO_kindtypeINTEGERDEFAULT); val = ffebld_constant_integerdefault (ffebld_conter (len)); } } if ((val == 0) && !(0 && ffe_is_90 ())) { val = 1; ffebad_start (FFEBAD_ZERO_SIZE); ffebad_here (0, ffelex_token_where_line (lent), ffelex_token_where_column (lent)); ffebad_finish (); } ffestc_local_.decl.size = val; } /* ffestc_establish_declstmt_ -- Establish host-specific type/params info ffestc_establish_declstmt_(type,type_token,kind,kind_token,len, len_token); */ static void ffestc_establish_declstmt_ (ffestpType type, ffelexToken typet, ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent) { ffeinfoBasictype bt; ffeinfoKindtype ktd; /* Default kindtype. */ ffeinfoKindtype kt; ffetargetCharacterSize val; bool per_var_kind_ok = TRUE; /* Determine basictype and default kindtype. */ switch (type) { case FFESTP_typeINTEGER: bt = FFEINFO_basictypeINTEGER; ktd = FFEINFO_kindtypeINTEGERDEFAULT; break; case FFESTP_typeBYTE: bt = FFEINFO_basictypeINTEGER; ktd = FFEINFO_kindtypeINTEGER2; break; case FFESTP_typeWORD: bt = FFEINFO_basictypeINTEGER; ktd = FFEINFO_kindtypeINTEGER3; break; case FFESTP_typeREAL: bt = FFEINFO_basictypeREAL; ktd = FFEINFO_kindtypeREALDEFAULT; break; case FFESTP_typeCOMPLEX: bt = FFEINFO_basictypeCOMPLEX; ktd = FFEINFO_kindtypeREALDEFAULT; break; case FFESTP_typeLOGICAL: bt = FFEINFO_basictypeLOGICAL; ktd = FFEINFO_kindtypeLOGICALDEFAULT; break; case FFESTP_typeCHARACTER: bt = FFEINFO_basictypeCHARACTER; ktd = FFEINFO_kindtypeCHARACTERDEFAULT; break; case FFESTP_typeDBLPRCSN: bt = FFEINFO_basictypeREAL; ktd = FFEINFO_kindtypeREALDOUBLE; per_var_kind_ok = FALSE; break; case FFESTP_typeDBLCMPLX: bt = FFEINFO_basictypeCOMPLEX; #if FFETARGET_okCOMPLEX2 ktd = FFEINFO_kindtypeREALDOUBLE; #else ktd = FFEINFO_kindtypeREALDEFAULT; ffebad_start (FFEBAD_BAD_DBLCMPLX); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); #endif per_var_kind_ok = FALSE; break; default: assert ("Unexpected type (F90 TYPE?)!" == NULL); bt = FFEINFO_basictypeNONE; ktd = FFEINFO_kindtypeNONE; break; } if (kindt == NULL) kt = ktd; else { /* Not necessarily default kind type. */ if (kind == NULL) { /* Shouldn't happen for CHARACTER. */ assert (ffelex_token_type (kindt) == FFELEX_typeNUMBER); val = atol (ffelex_token_text (kindt)); kt = ffestc_kindtype_star_ (bt, val); } else if (ffebld_op (kind) == FFEBLD_opANY) kt = ktd; else { assert (ffebld_op (kind) == FFEBLD_opCONTER); assert (ffeinfo_basictype (ffebld_info (kind)) == FFEINFO_basictypeINTEGER); assert (ffeinfo_kindtype (ffebld_info (kind)) == FFEINFO_kindtypeINTEGERDEFAULT); val = ffebld_constant_integerdefault (ffebld_conter (kind)); kt = ffestc_kindtype_kind_ (bt, val); } if (kt == FFEINFO_kindtypeNONE) { /* Not valid kind type. */ ffebad_start (FFEBAD_KINDTYPE); ffebad_here (0, ffelex_token_where_line (kindt), ffelex_token_where_column (kindt)); ffebad_here (1, ffelex_token_where_line (typet), ffelex_token_where_column (typet)); ffebad_finish (); kt = ktd; } } ffestc_local_.decl.basic_type = bt; ffestc_local_.decl.stmt_kind_type = kt; ffestc_local_.decl.per_var_kind_ok = per_var_kind_ok; /* Now check length specification for CHARACTER data type. */ if (((len == NULL) && (lent == NULL)) || (type != FFESTP_typeCHARACTER)) val = (type == FFESTP_typeCHARACTER) ? 1 : FFETARGET_charactersizeNONE; else { if (len == NULL) { assert (ffelex_token_type (lent) == FFELEX_typeNUMBER); val = atol (ffelex_token_text (lent)); } else if (ffebld_op (len) == FFEBLD_opSTAR) val = FFETARGET_charactersizeNONE; else if (ffebld_op (len) == FFEBLD_opANY) val = FFETARGET_charactersizeNONE; else { assert (ffebld_op (len) == FFEBLD_opCONTER); assert (ffeinfo_basictype (ffebld_info (len)) == FFEINFO_basictypeINTEGER); assert (ffeinfo_kindtype (ffebld_info (len)) == FFEINFO_kindtypeINTEGERDEFAULT); val = ffebld_constant_integerdefault (ffebld_conter (len)); } } if ((val == 0) && !(0 && ffe_is_90 ())) { val = 1; ffebad_start (FFEBAD_ZERO_SIZE); ffebad_here (0, ffelex_token_where_line (lent), ffelex_token_where_column (lent)); ffebad_finish (); } ffestc_local_.decl.stmt_size = val; } /* ffestc_establish_impletter_ -- Establish type/params for IMPLICIT letter(s) ffestc_establish_impletter_(first_letter_token,last_letter_token); */ static void ffestc_establish_impletter_ (ffelexToken first, ffelexToken last) { bool ok = FALSE; /* Stays FALSE if first letter > last. */ char c; if (last == NULL) ok = ffeimplic_establish_initial (c = *(ffelex_token_text (first)), ffestc_local_.decl.basic_type, ffestc_local_.decl.kind_type, ffestc_local_.decl.size); else { for (c = *(ffelex_token_text (first)); c <= *(ffelex_token_text (last)); c++) { ok = ffeimplic_establish_initial (c, ffestc_local_.decl.basic_type, ffestc_local_.decl.kind_type, ffestc_local_.decl.size); if (!ok) break; } } if (!ok) { char cs[2]; cs[0] = c; cs[1] = '\0'; ffebad_start (FFEBAD_BAD_IMPLICIT); ffebad_here (0, ffelex_token_where_line (first), ffelex_token_where_column (first)); ffebad_string (cs); ffebad_finish (); } } /* ffestc_init_3 -- Initialize ffestc for new program unit ffestc_init_3(); */ void ffestc_init_3 () { ffestv_save_state_ = FFESTV_savestateNONE; ffestc_entry_num_ = 0; ffestv_num_label_defines_ = 0; } /* ffestc_init_4 -- Initialize ffestc for new scoping unit ffestc_init_4(); For SUBROUTINEs/FUNCTIONs within INTERFACE/END INTERFACE, derived-TYPE- defs, and statement function defs. */ void ffestc_init_4 () { ffestc_saved_entry_num_ = ffestc_entry_num_; ffestc_entry_num_ = 0; } /* ffestc_kindtype_kind_ -- Determine kindtype from basictype and KIND= value ffeinfoKindtype kt; ffeinfoBasictype bt; ffetargetCharacterSize val; kt = ffestc_kindtype_kind_(bt,val); if (kt == FFEINFO_kindtypeNONE) // unsupported/invalid KIND= value for type */ static ffeinfoKindtype ffestc_kindtype_kind_ (ffeinfoBasictype bt, ffetargetCharacterSize val) { ffetype type; ffetype base_type; ffeinfoKindtype kt; base_type = ffeinfo_type (bt, 1); /* ~~ */ assert (base_type != NULL); type = ffetype_lookup_kind (base_type, (int) val); if (type == NULL) return FFEINFO_kindtypeNONE; for (kt = 1; kt < FFEINFO_kindtype; ++kt) if (ffeinfo_type (bt, kt) == type) return kt; return FFEINFO_kindtypeNONE; } /* ffestc_kindtype_star_ -- Determine kindtype from basictype and * value ffeinfoKindtype kt; ffeinfoBasictype bt; ffetargetCharacterSize val; kt = ffestc_kindtype_star_(bt,val); if (kt == FFEINFO_kindtypeNONE) // unsupported/invalid * value for type */ static ffeinfoKindtype ffestc_kindtype_star_ (ffeinfoBasictype bt, ffetargetCharacterSize val) { ffetype type; ffetype base_type; ffeinfoKindtype kt; base_type = ffeinfo_type (bt, 1); /* ~~ */ assert (base_type != NULL); type = ffetype_lookup_star (base_type, (int) val); if (type == NULL) return FFEINFO_kindtypeNONE; for (kt = 1; kt < FFEINFO_kindtype; ++kt) if (ffeinfo_type (bt, kt) == type) return kt; return FFEINFO_kindtypeNONE; } /* Define label as usable for anything without complaint. */ static void ffestc_labeldef_any_ () { if ((ffesta_label_token == NULL) || !ffestc_labeldef_begin_ ()) return; ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffestc_labeldef_branch_end_ (); } /* ffestc_labeldef_begin_ -- Define label as unknown, initially ffestc_labeldef_begin_(); */ static bool ffestc_labeldef_begin_ () { ffelabValue label_value; ffelab label; label_value = (ffelabValue) atol (ffelex_token_text (ffesta_label_token)); if ((label_value == 0) || (label_value > FFELAB_valueMAX)) { ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_finish (); } label = ffelab_find (label_value); if (label == NULL) { label = ffestc_label_ = ffelab_new (label_value); ffestv_num_label_defines_++; ffelab_set_definition_line (label, ffewhere_line_use (ffelex_token_where_line (ffesta_label_token))); ffelab_set_definition_column (label, ffewhere_column_use (ffelex_token_where_column (ffesta_label_token))); return TRUE; } if (ffewhere_line_is_unknown (ffelab_definition_line (label))) { ffestv_num_label_defines_++; ffestc_label_ = label; ffelab_set_definition_line (label, ffewhere_line_use (ffelex_token_where_line (ffesta_label_token))); ffelab_set_definition_column (label, ffewhere_column_use (ffelex_token_where_column (ffesta_label_token))); return TRUE; } ffebad_start (FFEBAD_LABEL_ALREADY_DEFINED); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_definition_line (label), ffelab_definition_column (label)); ffebad_string (ffelex_token_text (ffesta_label_token)); ffebad_finish (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; return FALSE; } /* ffestc_labeldef_branch_begin_ -- Define label as a branch target one ffestc_labeldef_branch_begin_(); */ static void ffestc_labeldef_branch_begin_ () { if ((ffesta_label_token == NULL) || (ffestc_shriek_after1_ != NULL) || !ffestc_labeldef_begin_ ()) return; switch (ffelab_type (ffestc_label_)) { case FFELAB_typeUNKNOWN: case FFELAB_typeASSIGNABLE: ffelab_set_type (ffestc_label_, FFELAB_typeNOTLOOP); ffelab_set_blocknum (ffestc_label_, ffestw_blocknum (ffestw_stack_top ())); ffestd_labeldef_branch (ffestc_label_); break; case FFELAB_typeNOTLOOP: if (ffelab_blocknum (ffestc_label_) < ffestw_blocknum (ffestw_stack_top ())) { ffebad_start (FFEBAD_LABEL_BLOCK); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); } ffelab_set_blocknum (ffestc_label_, ffestw_blocknum (ffestw_stack_top ())); ffestd_labeldef_branch (ffestc_label_); break; case FFELAB_typeLOOPEND: if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) { /* Unterminated block. */ ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); ffebad_here (0, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_here (2, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_finish (); break; } ffestd_labeldef_branch (ffestc_label_); /* Leave something around for _branch_end_() to handle. */ return; case FFELAB_typeFORMAT: ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); break; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } ffestc_try_shriek_do_ (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; } /* Define possible end of labeled-DO-loop. Call only after calling ffestc_labeldef_branch_begin_, or when other branch_* functions recognize that a label might also be serving as a branch end (in which case they must issue a diagnostic). */ static void ffestc_labeldef_branch_end_ () { if (ffesta_label_token == NULL) return; assert (ffestc_label_ != NULL); assert ((ffelab_type (ffestc_label_) == FFELAB_typeLOOPEND) || (ffelab_type (ffestc_label_) == FFELAB_typeANY)); while ((ffestw_state (ffestw_stack_top ()) == FFESTV_stateDO) && (ffestw_label (ffestw_stack_top ()) == ffestc_label_)) ffestc_shriek_do_ (TRUE); ffestc_try_shriek_do_ (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; } /* ffestc_labeldef_endif_ -- Define label as an END IF one ffestc_labeldef_endif_(); */ static void ffestc_labeldef_endif_ () { if ((ffesta_label_token == NULL) || (ffestc_shriek_after1_ != NULL) || !ffestc_labeldef_begin_ ()) return; switch (ffelab_type (ffestc_label_)) { case FFELAB_typeUNKNOWN: case FFELAB_typeASSIGNABLE: ffelab_set_type (ffestc_label_, FFELAB_typeENDIF); ffelab_set_blocknum (ffestc_label_, ffestw_blocknum (ffestw_previous (ffestw_stack_top ()))); ffestd_labeldef_endif (ffestc_label_); break; case FFELAB_typeNOTLOOP: if (ffelab_blocknum (ffestc_label_) < ffestw_blocknum (ffestw_previous (ffestw_stack_top ()))) { ffebad_start (FFEBAD_LABEL_BLOCK); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); } ffelab_set_blocknum (ffestc_label_, ffestw_blocknum (ffestw_previous (ffestw_stack_top ()))); ffestd_labeldef_endif (ffestc_label_); break; case FFELAB_typeLOOPEND: if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) { /* Unterminated block. */ ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); ffebad_here (0, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_here (2, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_finish (); break; } ffestd_labeldef_endif (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_finish (); ffestc_labeldef_branch_end_ (); return; case FFELAB_typeFORMAT: ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); break; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } ffestc_try_shriek_do_ (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; } /* ffestc_labeldef_format_ -- Define label as a FORMAT one ffestc_labeldef_format_(); */ static void ffestc_labeldef_format_ () { if ((ffesta_label_token == NULL) || (ffestc_shriek_after1_ != NULL)) { ffebad_start (FFEBAD_FORMAT_NO_LABEL_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); return; } if (!ffestc_labeldef_begin_ ()) return; switch (ffelab_type (ffestc_label_)) { case FFELAB_typeUNKNOWN: case FFELAB_typeASSIGNABLE: ffelab_set_type (ffestc_label_, FFELAB_typeFORMAT); ffestd_labeldef_format (ffestc_label_); break; case FFELAB_typeFORMAT: ffestd_labeldef_format (ffestc_label_); break; case FFELAB_typeLOOPEND: if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) { /* Unterminated block. */ ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); ffebad_here (0, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_here (2, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_finish (); break; } ffestd_labeldef_format (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_finish (); ffestc_labeldef_branch_end_ (); return; case FFELAB_typeNOTLOOP: ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); break; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } ffestc_try_shriek_do_ (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; } /* ffestc_labeldef_invalid_ -- Label definition invalid, complain if present ffestc_labeldef_invalid_(); */ static void ffestc_labeldef_invalid_ () { if ((ffesta_label_token == NULL) || (ffestc_shriek_after1_ != NULL) || !ffestc_labeldef_begin_ ()) return; ffebad_start (FFEBAD_INVALID_LABEL_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_finish (); ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffestc_try_shriek_do_ (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; } /* Define label as a non-loop-ending one on a statement that can't be in the "then" part of a logical IF, such as a block-IF statement. */ static void ffestc_labeldef_notloop_ () { if (ffesta_label_token == NULL) return; assert (ffestc_shriek_after1_ == NULL); if (!ffestc_labeldef_begin_ ()) return; switch (ffelab_type (ffestc_label_)) { case FFELAB_typeUNKNOWN: case FFELAB_typeASSIGNABLE: ffelab_set_type (ffestc_label_, FFELAB_typeNOTLOOP); ffelab_set_blocknum (ffestc_label_, ffestw_blocknum (ffestw_stack_top ())); ffestd_labeldef_notloop (ffestc_label_); break; case FFELAB_typeNOTLOOP: if (ffelab_blocknum (ffestc_label_) < ffestw_blocknum (ffestw_stack_top ())) { ffebad_start (FFEBAD_LABEL_BLOCK); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); } ffelab_set_blocknum (ffestc_label_, ffestw_blocknum (ffestw_stack_top ())); ffestd_labeldef_notloop (ffestc_label_); break; case FFELAB_typeLOOPEND: if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) { /* Unterminated block. */ ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); ffebad_here (0, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_here (2, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_finish (); break; } ffestd_labeldef_notloop (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_finish (); ffestc_labeldef_branch_end_ (); return; case FFELAB_typeFORMAT: ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); break; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } ffestc_try_shriek_do_ (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; } /* Define label as a non-loop-ending one. Use this when it is possible that the pending label is inhibited because we're in the midst of a logical-IF, and thus _branch_end_ is going to be called after the current statement to resolve a potential loop-ending label. */ static void ffestc_labeldef_notloop_begin_ () { if ((ffesta_label_token == NULL) || (ffestc_shriek_after1_ != NULL) || !ffestc_labeldef_begin_ ()) return; switch (ffelab_type (ffestc_label_)) { case FFELAB_typeUNKNOWN: case FFELAB_typeASSIGNABLE: ffelab_set_type (ffestc_label_, FFELAB_typeNOTLOOP); ffelab_set_blocknum (ffestc_label_, ffestw_blocknum (ffestw_stack_top ())); ffestd_labeldef_notloop (ffestc_label_); break; case FFELAB_typeNOTLOOP: if (ffelab_blocknum (ffestc_label_) < ffestw_blocknum (ffestw_stack_top ())) { ffebad_start (FFEBAD_LABEL_BLOCK); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); } ffelab_set_blocknum (ffestc_label_, ffestw_blocknum (ffestw_stack_top ())); ffestd_labeldef_notloop (ffestc_label_); break; case FFELAB_typeLOOPEND: if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) { /* Unterminated block. */ ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); ffebad_here (0, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_here (2, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_finish (); break; } ffestd_labeldef_branch (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_finish (); return; case FFELAB_typeFORMAT: ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); break; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } ffestc_try_shriek_do_ (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; } /* ffestc_labeldef_useless_ -- Define label as a useless one ffestc_labeldef_useless_(); */ static void ffestc_labeldef_useless_ () { if ((ffesta_label_token == NULL) || (ffestc_shriek_after1_ != NULL) || !ffestc_labeldef_begin_ ()) return; switch (ffelab_type (ffestc_label_)) { case FFELAB_typeUNKNOWN: ffelab_set_type (ffestc_label_, FFELAB_typeUSELESS); ffestd_labeldef_useless (ffestc_label_); break; case FFELAB_typeLOOPEND: ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) { /* Unterminated block. */ ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); ffebad_here (0, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_here (2, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_finish (); break; } ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_doref_line (ffestc_label_), ffelab_doref_column (ffestc_label_)); ffebad_finish (); ffestc_labeldef_branch_end_ (); return; case FFELAB_typeASSIGNABLE: case FFELAB_typeFORMAT: case FFELAB_typeNOTLOOP: ffelab_set_type (ffestc_label_, FFELAB_typeANY); ffestd_labeldef_any (ffestc_label_); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelex_token_where_line (ffesta_label_token), ffelex_token_where_column (ffesta_label_token)); ffebad_here (1, ffelab_firstref_line (ffestc_label_), ffelab_firstref_column (ffestc_label_)); ffebad_finish (); break; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } ffestc_try_shriek_do_ (); ffelex_token_kill (ffesta_label_token); ffesta_label_token = NULL; } /* ffestc_labelref_is_assignable_ -- Reference to label in ASSIGN stmt if (ffestc_labelref_is_assignable_(label_token,&label)) // label ref is ok, label is filled in with ffelab object */ static bool ffestc_labelref_is_assignable_ (ffelexToken label_token, ffelab *x_label) { ffelab label; ffelabValue label_value; label_value = (ffelabValue) atol (ffelex_token_text (label_token)); if ((label_value == 0) || (label_value > FFELAB_valueMAX)) { ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); ffebad_here (0, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); return FALSE; } label = ffelab_find (label_value); if (label == NULL) { label = ffelab_new (label_value); ffelab_set_firstref_line (label, ffewhere_line_use (ffelex_token_where_line (label_token))); ffelab_set_firstref_column (label, ffewhere_column_use (ffelex_token_where_column (label_token))); } switch (ffelab_type (label)) { case FFELAB_typeUNKNOWN: ffelab_set_type (label, FFELAB_typeASSIGNABLE); break; case FFELAB_typeASSIGNABLE: case FFELAB_typeLOOPEND: case FFELAB_typeFORMAT: case FFELAB_typeNOTLOOP: case FFELAB_typeENDIF: break; case FFELAB_typeUSELESS: ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } *x_label = label; return TRUE; } /* ffestc_labelref_is_branch_ -- Reference to label in branch stmt if (ffestc_labelref_is_branch_(label_token,&label)) // label ref is ok, label is filled in with ffelab object */ static bool ffestc_labelref_is_branch_ (ffelexToken label_token, ffelab *x_label) { ffelab label; ffelabValue label_value; ffestw block; unsigned long blocknum; label_value = (ffelabValue) atol (ffelex_token_text (label_token)); if ((label_value == 0) || (label_value > FFELAB_valueMAX)) { ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); ffebad_here (0, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); return FALSE; } label = ffelab_find (label_value); if (label == NULL) { label = ffelab_new (label_value); ffelab_set_firstref_line (label, ffewhere_line_use (ffelex_token_where_line (label_token))); ffelab_set_firstref_column (label, ffewhere_column_use (ffelex_token_where_column (label_token))); } switch (ffelab_type (label)) { case FFELAB_typeUNKNOWN: case FFELAB_typeASSIGNABLE: ffelab_set_type (label, FFELAB_typeNOTLOOP); ffelab_set_blocknum (label, ffestw_blocknum (ffestw_stack_top ())); break; case FFELAB_typeLOOPEND: if (ffelab_blocknum (label) != 0) break; /* Already taken care of. */ for (block = ffestw_top_do (ffestw_stack_top ()); (block != NULL) && (ffestw_label (block) != label); block = ffestw_top_do (ffestw_previous (block))) ; /* Find most recent DO <label> ancestor. */ if (block == NULL) { /* Reference to within a (dead) block. */ ffebad_start (FFEBAD_LABEL_BLOCK); ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); break; } ffelab_set_blocknum (label, ffestw_blocknum (block)); ffelab_set_firstref_line (label, ffewhere_line_use (ffelex_token_where_line (label_token))); ffelab_set_firstref_column (label, ffewhere_column_use (ffelex_token_where_column (label_token))); break; case FFELAB_typeNOTLOOP: case FFELAB_typeENDIF: if (ffelab_blocknum (label) == ffestw_blocknum (ffestw_stack_top ())) break; blocknum = ffelab_blocknum (label); for (block = ffestw_stack_top (); ffestw_blocknum (block) > blocknum; block = ffestw_previous (block)) ; /* Find most recent common ancestor. */ if (ffelab_blocknum (label) == ffestw_blocknum (block)) break; /* Check again. */ if (!ffewhere_line_is_unknown (ffelab_definition_line (label))) { /* Reference to within a (dead) block. */ ffebad_start (FFEBAD_LABEL_BLOCK); ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); break; } ffelab_set_blocknum (label, ffestw_blocknum (block)); break; case FFELAB_typeFORMAT: if (ffewhere_line_is_unknown (ffelab_definition_line (label))) { ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_USE_USE); ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; } /* Fall through. */ case FFELAB_typeUSELESS: ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } *x_label = label; return TRUE; } /* ffestc_labelref_is_format_ -- Reference to label in [FMT=] specification if (ffestc_labelref_is_format_(label_token,&label)) // label ref is ok, label is filled in with ffelab object */ static bool ffestc_labelref_is_format_ (ffelexToken label_token, ffelab *x_label) { ffelab label; ffelabValue label_value; label_value = (ffelabValue) atol (ffelex_token_text (label_token)); if ((label_value == 0) || (label_value > FFELAB_valueMAX)) { ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); ffebad_here (0, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); return FALSE; } label = ffelab_find (label_value); if (label == NULL) { label = ffelab_new (label_value); ffelab_set_firstref_line (label, ffewhere_line_use (ffelex_token_where_line (label_token))); ffelab_set_firstref_column (label, ffewhere_column_use (ffelex_token_where_column (label_token))); } switch (ffelab_type (label)) { case FFELAB_typeUNKNOWN: case FFELAB_typeASSIGNABLE: ffelab_set_type (label, FFELAB_typeFORMAT); break; case FFELAB_typeFORMAT: break; case FFELAB_typeLOOPEND: case FFELAB_typeNOTLOOP: if (ffewhere_line_is_unknown (ffelab_definition_line (label))) { ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_USE_USE); ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; } /* Fall through. */ case FFELAB_typeUSELESS: case FFELAB_typeENDIF: ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } ffestc_try_shriek_do_ (); *x_label = label; return TRUE; } /* ffestc_labelref_is_loopend_ -- Reference to label in DO stmt if (ffestc_labelref_is_loopend_(label_token,&label)) // label ref is ok, label is filled in with ffelab object */ static bool ffestc_labelref_is_loopend_ (ffelexToken label_token, ffelab *x_label) { ffelab label; ffelabValue label_value; label_value = (ffelabValue) atol (ffelex_token_text (label_token)); if ((label_value == 0) || (label_value > FFELAB_valueMAX)) { ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); ffebad_here (0, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); return FALSE; } label = ffelab_find (label_value); if (label == NULL) { label = ffelab_new (label_value); ffelab_set_doref_line (label, ffewhere_line_use (ffelex_token_where_line (label_token))); ffelab_set_doref_column (label, ffewhere_column_use (ffelex_token_where_column (label_token))); } switch (ffelab_type (label)) { case FFELAB_typeASSIGNABLE: ffelab_set_doref_line (label, ffewhere_line_use (ffelex_token_where_line (label_token))); ffelab_set_doref_column (label, ffewhere_column_use (ffelex_token_where_column (label_token))); ffewhere_line_kill (ffelab_firstref_line (label)); ffelab_set_firstref_line (label, ffewhere_line_unknown ()); ffewhere_column_kill (ffelab_firstref_column (label)); ffelab_set_firstref_column (label, ffewhere_column_unknown ()); /* Fall through. */ case FFELAB_typeUNKNOWN: ffelab_set_type (label, FFELAB_typeLOOPEND); ffelab_set_blocknum (label, 0); break; case FFELAB_typeLOOPEND: if (!ffewhere_line_is_unknown (ffelab_definition_line (label))) { /* Def must follow all refs. */ ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_DEF_DO); ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; } if (ffelab_blocknum (label) != 0) { /* Had a branch ref earlier, can't go inside this new block! */ ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_USE_USE); ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; } if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) || (ffestw_label (ffestw_stack_top ()) != label)) { /* Top of stack interrupts flow between two DOs specifying label. */ ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_DO_BLOCK_DO); ffebad_here (0, ffelab_doref_line (label), ffelab_doref_column (label)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_here (2, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; } break; case FFELAB_typeNOTLOOP: case FFELAB_typeFORMAT: if (ffewhere_line_is_unknown (ffelab_definition_line (label))) { ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_USE_USE); ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; } /* Fall through. */ case FFELAB_typeUSELESS: case FFELAB_typeENDIF: ffelab_set_type (label, FFELAB_typeANY); ffestd_labeldef_any (label); ffebad_start (FFEBAD_LABEL_USE_DEF); ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); ffebad_here (1, ffelex_token_where_line (label_token), ffelex_token_where_column (label_token)); ffebad_finish (); ffestc_try_shriek_do_ (); return FALSE; default: assert ("bad label" == NULL); /* Fall through. */ case FFELAB_typeANY: break; } *x_label = label; return TRUE; } /* ffestc_order_access_ -- Check ordering on <access> statement if (ffestc_order_access_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_access_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_stateMODULE3: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_actiondo_ -- Check ordering on <actiondo> statement if (ffestc_order_actiondo_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_actiondo_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateDO: return FFESTC_orderOK_; case FFESTV_stateIFTHEN: case FFESTV_stateSELECT1: if (ffestw_top_do (ffestw_stack_top ()) == NULL) break; return FFESTC_orderOK_; case FFESTV_stateIF: if (ffestw_top_do (ffestw_stack_top ()) == NULL) break; ffestc_shriek_after1_ = ffestc_shriek_if_; return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; default: break; } ffestc_order_bad_ (); return FFESTC_orderBAD_; } /* ffestc_order_actionif_ -- Check ordering on <actionif> statement if (ffestc_order_actionif_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_actionif_ () { bool update; recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: case FFESTV_statePROGRAM3: ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); update = TRUE; break; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); update = TRUE; break; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); update = TRUE; break; case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: update = FALSE; break; case FFESTV_stateIFTHEN: case FFESTV_stateDO: case FFESTV_stateSELECT1: return FFESTC_orderOK_; case FFESTV_stateIF: ffestc_shriek_after1_ = ffestc_shriek_if_; return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) { case FFESTV_stateINTERFACE0: ffestc_order_bad_ (); if (update) ffestw_update (NULL); return FFESTC_orderBAD_; default: if (update) ffestw_update (NULL); return FFESTC_orderOK_; } } /* ffestc_order_actionwhere_ -- Check ordering on <actionwhere> statement if (ffestc_order_actionwhere_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_actionwhere_ () { bool update; recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: case FFESTV_statePROGRAM3: ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); update = TRUE; break; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); update = TRUE; break; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); update = TRUE; break; case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: update = FALSE; break; case FFESTV_stateWHERETHEN: case FFESTV_stateIFTHEN: case FFESTV_stateDO: case FFESTV_stateSELECT1: return FFESTC_orderOK_; case FFESTV_stateWHERE: #if FFESTR_F90 ffestc_shriek_after1_ = ffestc_shriek_where_; #endif return FFESTC_orderOK_; case FFESTV_stateIF: ffestc_shriek_after1_ = ffestc_shriek_if_; return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) { case FFESTV_stateINTERFACE0: ffestc_order_bad_ (); if (update) ffestw_update (NULL); return FFESTC_orderBAD_; default: if (update) ffestw_update (NULL); return FFESTC_orderOK_; } } /* Check ordering on "any" statement. Like _actionwhere_, but doesn't produce any diagnostics. */ static void ffestc_order_any_ () { bool update; recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: case FFESTV_statePROGRAM3: ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); update = TRUE; break; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); update = TRUE; break; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); update = TRUE; break; case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: update = FALSE; break; case FFESTV_stateWHERETHEN: case FFESTV_stateIFTHEN: case FFESTV_stateDO: case FFESTV_stateSELECT1: return; case FFESTV_stateWHERE: #if FFESTR_F90 ffestc_shriek_after1_ = ffestc_shriek_where_; #endif return; case FFESTV_stateIF: ffestc_shriek_after1_ = ffestc_shriek_if_; return; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ default: return; } switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) { case FFESTV_stateINTERFACE0: if (update) ffestw_update (NULL); return; default: if (update) ffestw_update (NULL); return; } } /* ffestc_order_bad_ -- Whine about statement ordering violation ffestc_order_bad_(); Uses current ffesta_tokens[0] and, if available, info on where current state started to produce generic message. Someday we should do fancier things than this, but this just gets things creaking along for now. */ static void ffestc_order_bad_ () { if (ffewhere_line_is_unknown (ffestw_line (ffestw_stack_top ()))) { ffebad_start (FFEBAD_ORDER_1); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); } else { ffebad_start (FFEBAD_ORDER_2); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } ffestc_labeldef_useless_ (); /* Any label definition is useless. */ } /* ffestc_order_blockdata_ -- Check ordering on <blockdata> statement if (ffestc_order_blockdata_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_blockdata_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: case FFESTV_stateBLOCKDATA2: case FFESTV_stateBLOCKDATA3: case FFESTV_stateBLOCKDATA4: case FFESTV_stateBLOCKDATA5: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_blockspec_ -- Check ordering on <blockspec> statement if (ffestc_order_blockspec_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_blockspec_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: case FFESTV_stateBLOCKDATA2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); return FFESTC_orderOK_; case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: case FFESTV_stateBLOCKDATA3: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_component_ -- Check ordering on <component-decl> statement if (ffestc_order_component_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_component_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateTYPE: case FFESTV_stateSTRUCTURE: case FFESTV_stateMAP: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_contains_ -- Check ordering on CONTAINS statement if (ffestc_order_contains_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_contains_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: case FFESTV_statePROGRAM3: case FFESTV_statePROGRAM4: ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM5); break; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: case FFESTV_stateSUBROUTINE4: ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE5); break; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: case FFESTV_stateFUNCTION4: ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION5); break; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: case FFESTV_stateMODULE3: case FFESTV_stateMODULE4: ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE5); break; case FFESTV_stateUSE: ffestc_shriek_end_uses_ (TRUE); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) { case FFESTV_stateNIL: ffestw_update (NULL); return FFESTC_orderOK_; default: ffestc_order_bad_ (); ffestw_update (NULL); return FFESTC_orderBAD_; } } #endif /* ffestc_order_data_ -- Check ordering on DATA statement if (ffestc_order_data_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_data_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM2); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE2); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION2); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA2); return FFESTC_orderOK_; case FFESTV_statePROGRAM2: case FFESTV_stateSUBROUTINE2: case FFESTV_stateFUNCTION2: case FFESTV_stateBLOCKDATA2: case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateBLOCKDATA3: case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: case FFESTV_stateBLOCKDATA4: case FFESTV_stateWHERETHEN: case FFESTV_stateIFTHEN: case FFESTV_stateDO: case FFESTV_stateSELECT0: case FFESTV_stateSELECT1: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_data77_ -- Check ordering on pedantic-F77 DATA statement if (ffestc_order_data77_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_data77_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: case FFESTV_statePROGRAM3: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: case FFESTV_stateBLOCKDATA2: case FFESTV_stateBLOCKDATA3: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA4); return FFESTC_orderOK_; case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: case FFESTV_stateBLOCKDATA4: return FFESTC_orderOK_; case FFESTV_stateWHERETHEN: case FFESTV_stateIFTHEN: case FFESTV_stateDO: case FFESTV_stateSELECT0: case FFESTV_stateSELECT1: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_derivedtype_ -- Check ordering on derived TYPE statement if (ffestc_order_derivedtype_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_derivedtype_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: return FFESTC_orderOK_; case FFESTV_stateUSE: ffestc_shriek_end_uses_ (TRUE); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_do_ -- Check ordering on <do> statement if (ffestc_order_do_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_do_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateDO: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_entry_ -- Check ordering on ENTRY statement if (ffestc_order_entry_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_entry_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateSUBROUTINE0: ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1); break; case FFESTV_stateFUNCTION0: ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1); break; case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: break; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) { case FFESTV_stateNIL: case FFESTV_stateMODULE5: ffestw_update (NULL); return FFESTC_orderOK_; default: ffestc_order_bad_ (); ffestw_update (NULL); return FFESTC_orderBAD_; } } /* ffestc_order_exec_ -- Check ordering on <exec> statement if (ffestc_order_exec_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_exec_ () { bool update; recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: case FFESTV_statePROGRAM3: ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); update = TRUE; break; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); update = TRUE; break; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); update = TRUE; break; case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: update = FALSE; break; case FFESTV_stateIFTHEN: case FFESTV_stateDO: case FFESTV_stateSELECT1: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) { case FFESTV_stateINTERFACE0: ffestc_order_bad_ (); if (update) ffestw_update (NULL); return FFESTC_orderBAD_; default: if (update) ffestw_update (NULL); return FFESTC_orderOK_; } } /* ffestc_order_format_ -- Check ordering on FORMAT statement if (ffestc_order_format_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_format_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM1); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1); return FFESTC_orderOK_; case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: case FFESTV_stateWHERETHEN: case FFESTV_stateIFTHEN: case FFESTV_stateDO: case FFESTV_stateSELECT0: case FFESTV_stateSELECT1: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_function_ -- Check ordering on <function> statement if (ffestc_order_function_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_function_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: case FFESTV_stateFUNCTION4: case FFESTV_stateFUNCTION5: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_iface_ -- Check ordering on <iface> statement if (ffestc_order_iface_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_iface_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: case FFESTV_statePROGRAM5: case FFESTV_stateSUBROUTINE5: case FFESTV_stateFUNCTION5: case FFESTV_stateMODULE5: case FFESTV_stateINTERFACE0: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_ifthen_ -- Check ordering on <ifthen> statement if (ffestc_order_ifthen_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_ifthen_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateIFTHEN: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_implicit_ -- Check ordering on IMPLICIT statement if (ffestc_order_implicit_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_implicit_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM2); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE2); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION2); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE2); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA2); return FFESTC_orderOK_; case FFESTV_statePROGRAM2: case FFESTV_stateSUBROUTINE2: case FFESTV_stateFUNCTION2: case FFESTV_stateMODULE2: case FFESTV_stateBLOCKDATA2: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_implicitnone_ -- Check ordering on IMPLICIT NONE statement if (ffestc_order_implicitnone_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_implicitnone_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_interface_ -- Check ordering on <interface> statement if (ffestc_order_interface_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_interface_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateINTERFACE0: case FFESTV_stateINTERFACE1: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_map_ -- Check ordering on <map> statement if (ffestc_order_map_() != FFESTC_orderOK_) return; */ #if FFESTR_VXT static ffestcOrder_ ffestc_order_map_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateMAP: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_module_ -- Check ordering on <module> statement if (ffestc_order_module_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_module_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: case FFESTV_stateMODULE3: case FFESTV_stateMODULE4: case FFESTV_stateMODULE5: return FFESTC_orderOK_; case FFESTV_stateUSE: ffestc_shriek_end_uses_ (TRUE); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_parameter_ -- Check ordering on <parameter> statement if (ffestc_order_parameter_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_parameter_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM2); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE2); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION2); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE2); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA2); return FFESTC_orderOK_; case FFESTV_statePROGRAM2: case FFESTV_stateSUBROUTINE2: case FFESTV_stateFUNCTION2: case FFESTV_stateMODULE2: case FFESTV_stateBLOCKDATA2: case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: case FFESTV_stateBLOCKDATA3: case FFESTV_stateTYPE: /* GNU extension here! */ case FFESTV_stateSTRUCTURE: case FFESTV_stateUNION: case FFESTV_stateMAP: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_program_ -- Check ordering on <program> statement if (ffestc_order_program_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_program_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: case FFESTV_statePROGRAM3: case FFESTV_statePROGRAM4: case FFESTV_statePROGRAM5: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_progspec_ -- Check ordering on <progspec> statement if (ffestc_order_progspec_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_progspec_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: case FFESTV_stateBLOCKDATA2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA2); if (ffe_is_pedantic ()) { ffebad_start (FFEBAD_BLOCKDATA_STMT); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_record_ -- Check ordering on RECORD statement if (ffestc_order_record_() != FFESTC_orderOK_) return; */ #if FFESTR_VXT static ffestcOrder_ ffestc_order_record_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: case FFESTV_stateBLOCKDATA2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); return FFESTC_orderOK_; case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: case FFESTV_stateBLOCKDATA3: case FFESTV_stateSTRUCTURE: case FFESTV_stateMAP: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_selectcase_ -- Check ordering on <selectcase> statement if (ffestc_order_selectcase_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_selectcase_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateSELECT0: case FFESTV_stateSELECT1: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_sfunc_ -- Check ordering on statement-function definition if (ffestc_order_sfunc_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_sfunc_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_spec_ -- Check ordering on <spec> statement if (ffestc_order_spec_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_spec_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_structure_ -- Check ordering on <structure> statement if (ffestc_order_structure_() != FFESTC_orderOK_) return; */ #if FFESTR_VXT static ffestcOrder_ ffestc_order_structure_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateSTRUCTURE: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_subroutine_ -- Check ordering on <subroutine> statement if (ffestc_order_subroutine_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_subroutine_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: case FFESTV_stateSUBROUTINE4: case FFESTV_stateSUBROUTINE5: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_type_ -- Check ordering on <type> statement if (ffestc_order_type_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_type_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateTYPE: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_typedecl_ -- Check ordering on <typedecl> statement if (ffestc_order_typedecl_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_typedecl_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: case FFESTV_stateBLOCKDATA2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); return FFESTC_orderOK_; case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: case FFESTV_stateBLOCKDATA3: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_union_ -- Check ordering on <union> statement if (ffestc_order_union_() != FFESTC_orderOK_) return; */ #if FFESTR_VXT static ffestcOrder_ ffestc_order_union_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateUNION: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_unit_ -- Check ordering on <unit> statement if (ffestc_order_unit_() != FFESTC_orderOK_) return; */ static ffestcOrder_ ffestc_order_unit_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } /* ffestc_order_use_ -- Check ordering on USE statement if (ffestc_order_use_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_use_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM1); ffestc_shriek_begin_uses_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateSUBROUTINE0: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1); ffestc_shriek_begin_uses_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateFUNCTION0: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1); ffestc_shriek_begin_uses_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateMODULE0: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE1); ffestc_shriek_begin_uses_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateUSE: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_vxtstructure_ -- Check ordering on STRUCTURE statement if (ffestc_order_vxtstructure_() != FFESTC_orderOK_) return; */ #if FFESTR_VXT static ffestcOrder_ ffestc_order_vxtstructure_ () { recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_statePROGRAM1: case FFESTV_statePROGRAM2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); return FFESTC_orderOK_; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); return FFESTC_orderOK_; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); return FFESTC_orderOK_; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); return FFESTC_orderOK_; case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: case FFESTV_stateBLOCKDATA2: ffestw_update (NULL); ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); return FFESTC_orderOK_; case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: case FFESTV_stateBLOCKDATA3: case FFESTV_stateSTRUCTURE: case FFESTV_stateMAP: return FFESTC_orderOK_; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ case FFESTV_stateWHERE: ffestc_order_bad_ (); #if FFESTR_F90 ffestc_shriek_where_ (FALSE); #endif return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* ffestc_order_where_ -- Check ordering on <where> statement if (ffestc_order_where_() != FFESTC_orderOK_) return; */ #if FFESTR_F90 static ffestcOrder_ ffestc_order_where_ () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateWHERETHEN: return FFESTC_orderOK_; case FFESTV_stateWHERE: ffestc_order_bad_ (); ffestc_shriek_where_ (FALSE); return FFESTC_orderBAD_; case FFESTV_stateIF: ffestc_order_bad_ (); ffestc_shriek_if_ (FALSE); return FFESTC_orderBAD_; default: ffestc_order_bad_ (); return FFESTC_orderBAD_; } } #endif /* Invoked for each token in dummy arg list of FUNCTION, SUBROUTINE, and ENTRY (prior to the first executable statement). */ static void ffestc_promote_dummy_ (ffelexToken t) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffebld e; bool sfref_ok; assert (t != NULL); if (ffelex_token_type (t) == FFELEX_typeASTERISK) { ffebld_append_item (&ffestc_local_.dummy.list_bottom, ffebld_new_star ()); return; /* Don't bother with alternate returns! */ } s = ffesymbol_declare_local (t, FALSE); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ sfref_ok = FALSE; if (sa & FFESYMBOL_attrsANY) na = sa; else if (sa & FFESYMBOL_attrsDUMMY) { if (ffestc_entry_num_ == ffesymbol_maxentrynum (s)) { /* Seen this one twice in this list! */ na = FFESYMBOL_attrsetNONE; } else na = sa; sfref_ok = TRUE; /* Ok for sym to be ref'd in sfuncdef previously, since already declared as a dummy arg. */ } else if (!(sa & ~(FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsADJUSTS | FFESYMBOL_attrsANY | FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsANYSIZE | FFESYMBOL_attrsARRAY | FFESYMBOL_attrsDUMMY | FFESYMBOL_attrsEXTERNAL | FFESYMBOL_attrsSFARG | FFESYMBOL_attrsTYPE))) na = sa | FFESYMBOL_attrsDUMMY; else na = FFESYMBOL_attrsetNONE; if (!ffesymbol_is_specable (s) && (!sfref_ok || (ffesymbol_where (s) != FFEINFO_whereDUMMY))) na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, t); else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_set_maxentrynum (s, ffestc_entry_num_); ffesymbol_set_numentries (s, ffesymbol_numentries (s) + 1); e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, FFEINTRIN_impNONE); ffebld_set_info (e, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindNONE, FFEINFO_whereNONE, FFETARGET_charactersizeNONE)); ffebld_append_item (&ffestc_local_.dummy.list_bottom, e); ffesymbol_signal_unreported (s); } } /* ffestc_promote_execdummy_ -- Declare token as dummy variable in exec context ffestc_promote_execdummy_(t); Invoked for each token in dummy arg list of ENTRY when the statement follows the first executable statement. */ static void ffestc_promote_execdummy_ (ffelexToken t) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffesymbolState ss; ffesymbolState ns; ffeinfoKind kind; ffeinfoWhere where; ffebld e; assert (t != NULL); if (ffelex_token_type (t) == FFELEX_typeASTERISK) { ffebld_append_item (&ffestc_local_.dummy.list_bottom, ffebld_new_star ()); return; /* Don't bother with alternate returns! */ } s = ffesymbol_declare_local (t, FALSE); na = sa = ffesymbol_attrs (s); ss = ffesymbol_state (s); kind = ffesymbol_kind (s); where = ffesymbol_where (s); if (ffestc_entry_num_ == ffesymbol_maxentrynum (s)) { /* Seen this one twice in this list! */ na = FFESYMBOL_attrsetNONE; } /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ ns = FFESYMBOL_stateUNDERSTOOD; /* Assume we know it all know. */ switch (kind) { case FFEINFO_kindENTITY: case FFEINFO_kindFUNCTION: case FFEINFO_kindSUBROUTINE: break; /* These are fine, as far as we know. */ case FFEINFO_kindNONE: if (sa & FFESYMBOL_attrsDUMMY) ns = FFESYMBOL_stateUNCERTAIN; /* Learned nothing new. */ else if (sa & FFESYMBOL_attrsANYLEN) { kind = FFEINFO_kindENTITY; where = FFEINFO_whereDUMMY; } else if (sa & FFESYMBOL_attrsACTUALARG) na = FFESYMBOL_attrsetNONE; else { na = sa | FFESYMBOL_attrsDUMMY; ns = FFESYMBOL_stateUNCERTAIN; } break; default: na = FFESYMBOL_attrsetNONE; /* Error. */ break; } switch (where) { case FFEINFO_whereDUMMY: break; /* This is fine. */ case FFEINFO_whereNONE: where = FFEINFO_whereDUMMY; break; default: na = FFESYMBOL_attrsetNONE; /* Error. */ break; } /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, t); else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, ns); ffesymbol_set_maxentrynum (s, ffestc_entry_num_); ffesymbol_set_numentries (s, ffesymbol_numentries (s) + 1); if ((ns == FFESYMBOL_stateUNDERSTOOD) && (kind != FFEINFO_kindSUBROUTINE) && !ffeimplic_establish_symbol (s)) { ffesymbol_error (s, t); return; } ffesymbol_set_info (s, ffeinfo_new (ffesymbol_basictype (s), ffesymbol_kindtype (s), ffesymbol_rank (s), kind, where, ffesymbol_size (s))); e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, FFEINTRIN_impNONE); ffebld_set_info (e, ffeinfo_use (ffesymbol_info (s))); ffebld_append_item (&ffestc_local_.dummy.list_bottom, e); s = ffecom_sym_learned (s); ffesymbol_signal_unreported (s); } } /* ffestc_promote_sfdummy_ -- Declare token as stmt-func dummy variable ffestc_promote_sfdummy_(t); Invoked for each token in dummy arg list of statement function. 22-Oct-91 JCB 1.1 Reject arg if CHARACTER*(*). */ static void ffestc_promote_sfdummy_ (ffelexToken t) { ffesymbol s; ffesymbol sp; /* Parent symbol. */ ffesymbolAttrs sa; ffesymbolAttrs na; ffebld e; assert (t != NULL); s = ffesymbol_declare_sfdummy (t); /* Sets maxentrynum to 0 for new obj; also sets sfa_dummy_parent to parent symbol. */ if (ffesymbol_state (s) != FFESYMBOL_stateNONE) { ffesymbol_error (s, t); /* Dummy already in list. */ return; } sp = ffesymbol_sfdummyparent (s); /* Now flag dummy's parent as used for dummy. */ sa = ffesymbol_attrs (sp); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (sp) && ((ffesymbol_kind (sp) != FFEINFO_kindENTITY) || ((ffesymbol_where (sp) != FFEINFO_whereLOCAL) && (ffesymbol_where (sp) != FFEINFO_whereCOMMON) && (ffesymbol_where (sp) != FFEINFO_whereDUMMY) && (ffesymbol_where (sp) != FFEINFO_whereNONE)))) na = FFESYMBOL_attrsetNONE; /* Can't be PARAMETER etc., must be a var. */ else if (sa & FFESYMBOL_attrsANY) na = sa; else if (!(sa & ~(FFESYMBOL_attrsADJUSTS | FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsDUMMY | FFESYMBOL_attrsEQUIV | FFESYMBOL_attrsINIT | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsRESULT | FFESYMBOL_attrsSAVE | FFESYMBOL_attrsSFARG | FFESYMBOL_attrsTYPE))) na = sa | FFESYMBOL_attrsSFARG; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) { ffesymbol_error (sp, t); ffesymbol_set_info (s, ffeinfo_new_any ()); } else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_state (sp, FFESYMBOL_stateSEEN); ffesymbol_set_attrs (sp, na); if (!ffeimplic_establish_symbol (sp) || ((ffesymbol_basictype (sp) == FFEINFO_basictypeCHARACTER) && (ffesymbol_size (sp) == FFETARGET_charactersizeNONE))) ffesymbol_error (sp, t); else ffesymbol_set_info (s, ffeinfo_new (ffesymbol_basictype (sp), ffesymbol_kindtype (sp), 0, FFEINFO_kindENTITY, FFEINFO_whereDUMMY, ffesymbol_size (sp))); ffesymbol_signal_unreported (sp); } ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_maxentrynum (s, ffestc_sfdummy_argno_++); ffesymbol_signal_unreported (s); e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, FFEINTRIN_impNONE); ffebld_set_info (e, ffeinfo_use (ffesymbol_info (s))); ffebld_append_item (&ffestc_local_.dummy.list_bottom, e); } /* ffestc_shriek_begin_program_ -- Implicit PROGRAM statement ffestc_shriek_begin_program_(); Invoked only when a PROGRAM statement is NOT present at the beginning of a main program unit. */ static void ffestc_shriek_begin_program_ () { ffestw b; ffesymbol s; ffestc_blocknum_ = 0; b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_statePROGRAM0); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_end_program_); ffestw_set_name (b, NULL); s = ffesymbol_declare_programunit (NULL, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); /* Special case: this is one symbol that won't go through ffestu_exec_transition_ when the first statement in a main program is executable, because the transition happens in ffest before ffestc is reached and triggers the implicit generation of a main program. So we do the exec transition for the implicit main program right here, just for cleanliness' sake (at the very least). */ ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindPROGRAM, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_signal_unreported (s); ffestd_R1102 (s, NULL); } /* ffestc_shriek_begin_uses_ -- Start a bunch of USE statements ffestc_shriek_begin_uses_(); Invoked before handling the first USE statement in a block of one or more USE statements. _end_uses_(bool ok) is invoked before handling the first statement after the block (there are no BEGIN USE and END USE statements, but the semantics of USE statements effectively requires handling them as a single block rather than one statement at a time). */ #if FFESTR_F90 static void ffestc_shriek_begin_uses_ () { ffestw b; b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateUSE); ffestw_set_blocknum (b, 0); ffestw_set_shriek (b, ffestc_shriek_end_uses_); ffestd_begin_uses (); } #endif /* ffestc_shriek_blockdata_ -- End a BLOCK DATA ffestc_shriek_blockdata_(TRUE); */ static void ffestc_shriek_blockdata_ (bool ok) { if (!ffesta_seen_first_exec) { ffesta_seen_first_exec = TRUE; ffestd_exec_begin (); } ffestd_R1112 (ok); ffestd_exec_end (); if (ffestw_name (ffestw_stack_top ()) != NULL) ffelex_token_kill (ffestw_name (ffestw_stack_top ())); ffestw_kill (ffestw_pop ()); ffe_terminate_2 (); ffe_init_2 (); } /* ffestc_shriek_do_ -- End of statement following DO-term-stmt etc ffestc_shriek_do_(TRUE); Also invoked by _labeldef_branch_end_ (or, in cases of errors, other _labeldef_ functions) when the label definition is for a DO-target (LOOPEND) label, once per matching/outstanding DO block on the stack. These cases invoke this function with ok==TRUE, so only forced stack popping (via ffestc_eof()) invokes it with ok==FALSE. */ static void ffestc_shriek_do_ (bool ok) { ffelab l; if (((l = ffestw_label (ffestw_stack_top ())) != NULL) && (ffewhere_line_is_unknown (ffelab_definition_line (l)))) { /* DO target is label that is still undefined. */ assert ((ffelab_type (l) == FFELAB_typeLOOPEND) || (ffelab_type (l) == FFELAB_typeANY)); if (ffelab_type (l) != FFELAB_typeANY) { ffelab_set_definition_line (l, ffewhere_line_use (ffelab_doref_line (l))); ffelab_set_definition_column (l, ffewhere_column_use (ffelab_doref_column (l))); ffestv_num_label_defines_++; } ffestd_labeldef_branch (l); } ffestd_do (ok); if (ffestw_name (ffestw_stack_top ()) != NULL) ffelex_token_kill (ffestw_name (ffestw_stack_top ())); if (ffestw_do_iter_var_t (ffestw_stack_top ()) != NULL) ffelex_token_kill (ffestw_do_iter_var_t (ffestw_stack_top ())); if (ffestw_do_iter_var (ffestw_stack_top ()) != NULL) ffesymbol_set_is_doiter (ffestw_do_iter_var (ffestw_stack_top ()), FALSE); ffestw_kill (ffestw_pop ()); } /* ffestc_shriek_end_program_ -- End a PROGRAM ffestc_shriek_end_program_(); */ static void ffestc_shriek_end_program_ (bool ok) { if (!ffesta_seen_first_exec) { ffesta_seen_first_exec = TRUE; ffestd_exec_begin (); } ffestd_R1103 (ok); ffestd_exec_end (); if (ffestw_name (ffestw_stack_top ()) != NULL) ffelex_token_kill (ffestw_name (ffestw_stack_top ())); ffestw_kill (ffestw_pop ()); ffe_terminate_2 (); ffe_init_2 (); } /* ffestc_shriek_end_uses_ -- End a bunch of USE statements ffestc_shriek_end_uses_(TRUE); ok==TRUE means simply not popping due to ffestc_eof() being called, because there is no formal END USES statement in Fortran. */ #if FFESTR_F90 static void ffestc_shriek_end_uses_ (bool ok) { ffestd_end_uses (ok); ffestw_kill (ffestw_pop ()); } #endif /* ffestc_shriek_function_ -- End a FUNCTION ffestc_shriek_function_(TRUE); */ static void ffestc_shriek_function_ (bool ok) { if (!ffesta_seen_first_exec) { ffesta_seen_first_exec = TRUE; ffestd_exec_begin (); } ffestd_R1221 (ok); ffestd_exec_end (); ffelex_token_kill (ffestw_name (ffestw_stack_top ())); ffestw_kill (ffestw_pop ()); ffesta_is_entry_valid = FALSE; switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffe_terminate_2 (); ffe_init_2 (); break; default: ffe_terminate_3 (); ffe_init_3 (); break; case FFESTV_stateINTERFACE0: ffe_terminate_4 (); ffe_init_4 (); break; } } /* ffestc_shriek_if_ -- End of statement following logical IF ffestc_shriek_if_(TRUE); Applies ONLY to logical IF, not to IF-THEN. For example, does not ffelex_token_kill the construct name for an IF-THEN block (the name field is invalid for logical IF). ok==TRUE iff statement following logical IF (substatement) is valid; else, statement is invalid or stack forcibly popped due to ffestc_eof(). */ static void ffestc_shriek_if_ (bool ok) { ffestd_end_R807 (ok); ffestw_kill (ffestw_pop ()); ffestc_shriek_after1_ = NULL; ffestc_try_shriek_do_ (); } /* ffestc_shriek_ifthen_ -- End an IF-THEN ffestc_shriek_ifthen_(TRUE); */ static void ffestc_shriek_ifthen_ (bool ok) { ffestd_R806 (ok); if (ffestw_name (ffestw_stack_top ()) != NULL) ffelex_token_kill (ffestw_name (ffestw_stack_top ())); ffestw_kill (ffestw_pop ()); ffestc_try_shriek_do_ (); } /* ffestc_shriek_interface_ -- End an INTERFACE ffestc_shriek_interface_(TRUE); */ #if FFESTR_F90 static void ffestc_shriek_interface_ (bool ok) { ffestd_R1203 (ok); ffestw_kill (ffestw_pop ()); ffestc_try_shriek_do_ (); } #endif /* ffestc_shriek_map_ -- End a MAP ffestc_shriek_map_(TRUE); */ #if FFESTR_VXT static void ffestc_shriek_map_ (bool ok) { ffestd_V013 (ok); ffestw_kill (ffestw_pop ()); ffestc_try_shriek_do_ (); } #endif /* ffestc_shriek_module_ -- End a MODULE ffestc_shriek_module_(TRUE); */ #if FFESTR_F90 static void ffestc_shriek_module_ (bool ok) { if (!ffesta_seen_first_exec) { ffesta_seen_first_exec = TRUE; ffestd_exec_begin (); } ffestd_R1106 (ok); ffestd_exec_end (); ffelex_token_kill (ffestw_name (ffestw_stack_top ())); ffestw_kill (ffestw_pop ()); ffe_terminate_2 (); ffe_init_2 (); } #endif /* ffestc_shriek_select_ -- End a SELECT ffestc_shriek_select_(TRUE); */ static void ffestc_shriek_select_ (bool ok) { ffestwSelect s; ffestwCase c; ffestd_R811 (ok); if (ffestw_name (ffestw_stack_top ()) != NULL) ffelex_token_kill (ffestw_name (ffestw_stack_top ())); s = ffestw_select (ffestw_stack_top ()); ffelex_token_kill (s->t); for (c = s->first_rel; c != (ffestwCase) &s->first_rel; c = c->next_rel) ffelex_token_kill (c->t); malloc_pool_kill (s->pool); ffestw_kill (ffestw_pop ()); ffestc_try_shriek_do_ (); } /* ffestc_shriek_structure_ -- End a STRUCTURE ffestc_shriek_structure_(TRUE); */ #if FFESTR_VXT static void ffestc_shriek_structure_ (bool ok) { ffestd_V004 (ok); ffestw_kill (ffestw_pop ()); ffestc_try_shriek_do_ (); } #endif /* ffestc_shriek_subroutine_ -- End a SUBROUTINE ffestc_shriek_subroutine_(TRUE); */ static void ffestc_shriek_subroutine_ (bool ok) { if (!ffesta_seen_first_exec) { ffesta_seen_first_exec = TRUE; ffestd_exec_begin (); } ffestd_R1225 (ok); ffestd_exec_end (); ffelex_token_kill (ffestw_name (ffestw_stack_top ())); ffestw_kill (ffestw_pop ()); ffesta_is_entry_valid = FALSE; switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffe_terminate_2 (); ffe_init_2 (); break; default: ffe_terminate_3 (); ffe_init_3 (); break; case FFESTV_stateINTERFACE0: ffe_terminate_4 (); ffe_init_4 (); break; } } /* ffestc_shriek_type_ -- End a TYPE ffestc_shriek_type_(TRUE); */ #if FFESTR_F90 static void ffestc_shriek_type_ (bool ok) { ffestd_R425 (ok); ffe_terminate_4 (); ffelex_token_kill (ffestw_name (ffestw_stack_top ())); ffestw_kill (ffestw_pop ()); ffestc_try_shriek_do_ (); } #endif /* ffestc_shriek_union_ -- End a UNION ffestc_shriek_union_(TRUE); */ #if FFESTR_VXT static void ffestc_shriek_union_ (bool ok) { ffestd_V010 (ok); ffestw_kill (ffestw_pop ()); ffestc_try_shriek_do_ (); } #endif /* ffestc_shriek_where_ -- Implicit END WHERE statement ffestc_shriek_where_(TRUE); Implement the end of the current WHERE "block". ok==TRUE iff statement following WHERE (substatement) is valid; else, statement is invalid or stack forcibly popped due to ffestc_eof(). */ #if FFESTR_F90 static void ffestc_shriek_where_ (bool ok) { ffestd_R745 (ok); ffestw_kill (ffestw_pop ()); ffestc_shriek_after1_ = NULL; if (ffestw_state (ffestw_stack_top ()) == FFESTV_stateIF) ffestc_shriek_if_ (TRUE); /* "IF (x) WHERE (y) stmt" is only valid case. */ ffestc_try_shriek_do_ (); } #endif /* ffestc_shriek_wherethen_ -- End a WHERE(-THEN) ffestc_shriek_wherethen_(TRUE); */ #if FFESTR_F90 static void ffestc_shriek_wherethen_ (bool ok) { ffestd_end_R740 (ok); ffestw_kill (ffestw_pop ()); ffestc_try_shriek_do_ (); } #endif /* ffestc_subr_binsrch_ -- Binary search of char const in list of strings i = ffestc_subr_binsrch_(search_list,search_list_size,&spec,"etc"); search_list contains search_list_size char *'s, spec is checked to see if it is a char constant and, if so, is binary-searched against the list. 0 is returned if not found, else the "classic" index (beginning with 1) is returned. Before returning 0 where the search was performed but fruitless, if "etc" is a non-NULL char *, an error message is displayed using "etc" as the pick-one-of-these string. */ static int ffestc_subr_binsrch_ (const char **list, int size, ffestpFile *spec, const char *whine) { int lowest_tested; int highest_tested; int halfway; int offset; int c; const char *str; int len; if (size == 0) return 0; /* Nobody should pass size == 0, but for elegance.... */ lowest_tested = -1; highest_tested = size; halfway = size >> 1; list += halfway; c = ffestc_subr_speccmp_ (*list, spec, &str, &len); if (c == 2) return 0; c = -c; /* Sigh. */ next: /* :::::::::::::::::::: */ switch (c) { case -1: offset = (halfway - lowest_tested) >> 1; if (offset == 0) goto nope; /* :::::::::::::::::::: */ highest_tested = halfway; list -= offset; halfway -= offset; c = ffesrc_strcmp_1ns2i (ffe_case_match (), str, len, *list); goto next; /* :::::::::::::::::::: */ case 0: return halfway + 1; case 1: offset = (highest_tested - halfway) >> 1; if (offset == 0) goto nope; /* :::::::::::::::::::: */ lowest_tested = halfway; list += offset; halfway += offset; c = ffesrc_strcmp_1ns2i (ffe_case_match (), str, len, *list); goto next; /* :::::::::::::::::::: */ default: assert ("unexpected return from ffesrc_strcmp_1ns2i" == NULL); break; } nope: /* :::::::::::::::::::: */ ffebad_start (FFEBAD_SPEC_VALUE); ffebad_here (0, ffelex_token_where_line (spec->value), ffelex_token_where_column (spec->value)); ffebad_string (whine); ffebad_finish (); return 0; } /* ffestc_subr_format_ -- Return summary of format specifier ffestc_subr_format_(&specifier); */ static ffestvFormat ffestc_subr_format_ (ffestpFile *spec) { if (!spec->kw_or_val_present) return FFESTV_formatNONE; assert (spec->value_present); if (spec->value_is_label) return FFESTV_formatLABEL; /* Ok if not a label. */ assert (spec->value != NULL); if (ffebld_op (spec->u.expr) == FFEBLD_opSTAR) return FFESTV_formatASTERISK; if (ffeinfo_kind (ffebld_info (spec->u.expr)) == FFEINFO_kindNAMELIST) return FFESTV_formatNAMELIST; if (ffeinfo_rank (ffebld_info (spec->u.expr)) != 0) return FFESTV_formatCHAREXPR; /* F77 C5. */ switch (ffeinfo_basictype (ffebld_info (spec->u.expr))) { case FFEINFO_basictypeINTEGER: return FFESTV_formatINTEXPR; case FFEINFO_basictypeCHARACTER: return FFESTV_formatCHAREXPR; case FFEINFO_basictypeANY: return FFESTV_formatASTERISK; default: assert ("bad basictype" == NULL); return FFESTV_formatINTEXPR; } } /* ffestc_subr_is_branch_ -- Handle specifier as branch target label ffestc_subr_is_branch_(&specifier); */ static bool ffestc_subr_is_branch_ (ffestpFile *spec) { if (!spec->kw_or_val_present) return TRUE; assert (spec->value_present); assert (spec->value_is_label); spec->value_is_label++; /* For checking purposes only; 1=>2. */ return ffestc_labelref_is_branch_ (spec->value, &spec->u.label); } /* ffestc_subr_is_format_ -- Handle specifier as format target label ffestc_subr_is_format_(&specifier); */ static bool ffestc_subr_is_format_ (ffestpFile *spec) { if (!spec->kw_or_val_present) return TRUE; assert (spec->value_present); if (!spec->value_is_label) return TRUE; /* Ok if not a label. */ spec->value_is_label++; /* For checking purposes only; 1=>2. */ return ffestc_labelref_is_format_ (spec->value, &spec->u.label); } /* ffestc_subr_is_present_ -- Ensure specifier is present, else error ffestc_subr_is_present_("SPECIFIER",&specifier); */ static bool ffestc_subr_is_present_ (const char *name, ffestpFile *spec) { if (spec->kw_or_val_present) { assert (spec->value_present); return TRUE; } ffebad_start (FFEBAD_MISSING_SPECIFIER); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_string (name); ffebad_finish (); return FALSE; } /* ffestc_subr_speccmp_ -- Compare string to constant expression, if present if (ffestc_subr_speccmp_("Constant",&specifier,NULL,NULL) == 0) // specifier value is present and is a char constant "CONSTANT" Like strcmp, except the return values are defined as: -1 returned in place of strcmp's generic negative value, 1 in place of it's generic positive value, and 2 when there is no character constant string to compare. Also, a case-insensitive comparison is performed, where string is assumed to already be in InitialCaps form. If a non-NULL pointer is provided as the char **target, then *target is written with NULL if 2 is returned, a pointer to the constant string value of the specifier otherwise. Similarly, length is written with 0 if 2 is returned, the length of the constant string value otherwise. */ static int ffestc_subr_speccmp_ (const char *string, ffestpFile *spec, const char **target, int *length) { ffebldConstant c; int i; if (!spec->kw_or_val_present || !spec->value_present || (spec->u.expr == NULL) || (ffebld_op (spec->u.expr) != FFEBLD_opCONTER)) { if (target != NULL) *target = NULL; if (length != NULL) *length = 0; return 2; } if (ffebld_constant_type (c = ffebld_conter (spec->u.expr)) != FFEBLD_constCHARACTERDEFAULT) { if (target != NULL) *target = NULL; if (length != NULL) *length = 0; return 2; } if (target != NULL) *target = ffebld_constant_characterdefault (c).text; if (length != NULL) *length = ffebld_constant_characterdefault (c).length; i = ffesrc_strcmp_1ns2i (ffe_case_match (), ffebld_constant_characterdefault (c).text, ffebld_constant_characterdefault (c).length, string); if (i == 0) return 0; if (i > 0) return -1; /* Yes indeed, we reverse the strings to _strcmpin_. */ return 1; } /* ffestc_subr_unit_ -- Return summary of unit specifier ffestc_subr_unit_(&specifier); */ static ffestvUnit ffestc_subr_unit_ (ffestpFile *spec) { if (!spec->kw_or_val_present) return FFESTV_unitNONE; assert (spec->value_present); assert (spec->value != NULL); if (ffebld_op (spec->u.expr) == FFEBLD_opSTAR) return FFESTV_unitASTERISK; switch (ffeinfo_basictype (ffebld_info (spec->u.expr))) { case FFEINFO_basictypeINTEGER: return FFESTV_unitINTEXPR; case FFEINFO_basictypeCHARACTER: return FFESTV_unitCHAREXPR; case FFEINFO_basictypeANY: return FFESTV_unitASTERISK; default: assert ("bad basictype" == NULL); return FFESTV_unitINTEXPR; } } /* Call this function whenever it's possible that one or more top stack items are label-targeting DO blocks that have had their labels defined, but at a time when they weren't at the top of the stack. This prevents uninformative diagnostics for programs like "DO 10", "IF (...) THEN", "10 ELSE", "END IF", "END". */ static void ffestc_try_shriek_do_ () { ffelab lab; ffelabType ty; while ((ffestw_state (ffestw_stack_top ()) == FFESTV_stateDO) && ((lab = (ffestw_label (ffestw_stack_top ()))) != NULL) && (((ty = (ffelab_type (lab))) == FFELAB_typeANY) || (ty == FFELAB_typeUSELESS) || (ty == FFELAB_typeFORMAT) || (ty == FFELAB_typeNOTLOOP) || (ty == FFELAB_typeENDIF))) ffestc_shriek_do_ (FALSE); } /* ffestc_decl_start -- R426 or R501 ffestc_decl_start(...); Verify that R426 component-def-stmt or R501 type-declaration-stmt are valid here, figure out which one, and implement. */ void ffestc_decl_start (ffestpType type, ffelexToken typet, ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent) { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: case FFESTV_statePROGRAM0: case FFESTV_stateSUBROUTINE0: case FFESTV_stateFUNCTION0: case FFESTV_stateMODULE0: case FFESTV_stateBLOCKDATA0: case FFESTV_statePROGRAM1: case FFESTV_stateSUBROUTINE1: case FFESTV_stateFUNCTION1: case FFESTV_stateMODULE1: case FFESTV_stateBLOCKDATA1: case FFESTV_statePROGRAM2: case FFESTV_stateSUBROUTINE2: case FFESTV_stateFUNCTION2: case FFESTV_stateMODULE2: case FFESTV_stateBLOCKDATA2: case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateMODULE3: case FFESTV_stateBLOCKDATA3: case FFESTV_stateUSE: ffestc_local_.decl.is_R426 = 2; break; case FFESTV_stateTYPE: case FFESTV_stateSTRUCTURE: case FFESTV_stateMAP: ffestc_local_.decl.is_R426 = 1; break; default: ffestc_order_bad_ (); ffestc_labeldef_useless_ (); ffestc_local_.decl.is_R426 = 0; return; } switch (ffestc_local_.decl.is_R426) { #if FFESTR_F90 case 1: ffestc_R426_start (type, typet, kind, kindt, len, lent); break; #endif case 2: ffestc_R501_start (type, typet, kind, kindt, len, lent); break; default: ffestc_labeldef_useless_ (); break; } } /* ffestc_decl_attrib -- R426 or R501 type attribute ffestc_decl_attrib(...); Verify that R426 component-def-stmt or R501 type-declaration-stmt attribute is valid here and implement. */ void ffestc_decl_attrib (ffestpAttrib attrib UNUSED, ffelexToken attribt UNUSED, ffestrOther intent_kw UNUSED, ffesttDimList dims UNUSED) { #if FFESTR_F90 switch (ffestc_local_.decl.is_R426) { case 1: ffestc_R426_attrib (attrib, attribt, intent_kw, dims); break; case 2: ffestc_R501_attrib (attrib, attribt, intent_kw, dims); break; default: break; } #else ffebad_start (FFEBAD_F90); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); return; #endif } /* ffestc_decl_item -- R426 or R501 ffestc_decl_item(...); Establish type for a particular object. */ void ffestc_decl_item (ffelexToken name, ffebld kind, ffelexToken kindt, ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init, ffelexToken initt, bool clist) { switch (ffestc_local_.decl.is_R426) { #if FFESTR_F90 case 1: ffestc_R426_item (name, kind, kindt, dims, len, lent, init, initt, clist); break; #endif case 2: ffestc_R501_item (name, kind, kindt, dims, len, lent, init, initt, clist); break; default: break; } } /* ffestc_decl_itemstartvals -- R426 or R501 start list of values ffestc_decl_itemstartvals(); Gonna specify values for the object now. */ void ffestc_decl_itemstartvals () { switch (ffestc_local_.decl.is_R426) { #if FFESTR_F90 case 1: ffestc_R426_itemstartvals (); break; #endif case 2: ffestc_R501_itemstartvals (); break; default: break; } } /* ffestc_decl_itemvalue -- R426 or R501 source value ffestc_decl_itemvalue(repeat,repeat_token,value,value_token); Make sure repeat and value are valid for the object being initialized. */ void ffestc_decl_itemvalue (ffebld repeat, ffelexToken repeat_token, ffebld value, ffelexToken value_token) { switch (ffestc_local_.decl.is_R426) { #if FFESTR_F90 case 1: ffestc_R426_itemvalue (repeat, repeat_token, value, value_token); break; #endif case 2: ffestc_R501_itemvalue (repeat, repeat_token, value, value_token); break; default: break; } } /* ffestc_decl_itemendvals -- R426 or R501 end list of values ffelexToken t; // the SLASH token that ends the list. ffestc_decl_itemendvals(t); No more values, might specify more objects now. */ void ffestc_decl_itemendvals (ffelexToken t) { switch (ffestc_local_.decl.is_R426) { #if FFESTR_F90 case 1: ffestc_R426_itemendvals (t); break; #endif case 2: ffestc_R501_itemendvals (t); break; default: break; } } /* ffestc_decl_finish -- R426 or R501 ffestc_decl_finish(); Just wrap up any local activities. */ void ffestc_decl_finish () { switch (ffestc_local_.decl.is_R426) { #if FFESTR_F90 case 1: ffestc_R426_finish (); break; #endif case 2: ffestc_R501_finish (); break; default: break; } } /* ffestc_elsewhere -- Generic ELSE WHERE statement ffestc_end(); Decide whether ELSEWHERE or ELSE w/if-construct-name=="WHERE" is meant. */ void ffestc_elsewhere (ffelexToken where) { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateIFTHEN: ffestc_R805 (where); break; default: #if FFESTR_F90 ffestc_R744 (); #endif break; } } /* ffestc_end -- Generic END statement ffestc_end(); Make sure a generic END is valid in the current context, and implement it. */ void ffestc_end () { ffestw b; b = ffestw_stack_top (); recurse: switch (ffestw_state (b)) { case FFESTV_stateBLOCKDATA0: case FFESTV_stateBLOCKDATA1: case FFESTV_stateBLOCKDATA2: case FFESTV_stateBLOCKDATA3: case FFESTV_stateBLOCKDATA4: case FFESTV_stateBLOCKDATA5: ffestc_R1112 (NULL); break; case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: case FFESTV_stateFUNCTION4: case FFESTV_stateFUNCTION5: if ((ffestw_state (ffestw_previous (b)) != FFESTV_stateNIL) && (ffestw_state (ffestw_previous (b)) != FFESTV_stateINTERFACE0)) { ffebad_start (FFEBAD_END_WO); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_previous (b)), ffestw_col (ffestw_previous (b))); ffebad_string ("FUNCTION"); ffebad_finish (); } ffestc_R1221 (NULL); break; case FFESTV_stateMODULE0: case FFESTV_stateMODULE1: case FFESTV_stateMODULE2: case FFESTV_stateMODULE3: case FFESTV_stateMODULE4: case FFESTV_stateMODULE5: #if FFESTR_F90 ffestc_R1106 (NULL); #endif break; case FFESTV_stateSUBROUTINE0: case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: case FFESTV_stateSUBROUTINE4: case FFESTV_stateSUBROUTINE5: if ((ffestw_state (ffestw_previous (b)) != FFESTV_stateNIL) && (ffestw_state (ffestw_previous (b)) != FFESTV_stateINTERFACE0)) { ffebad_start (FFEBAD_END_WO); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_previous (b)), ffestw_col (ffestw_previous (b))); ffebad_string ("SUBROUTINE"); ffebad_finish (); } ffestc_R1225 (NULL); break; case FFESTV_stateUSE: b = ffestw_previous (ffestw_stack_top ()); goto recurse; /* :::::::::::::::::::: */ default: ffestc_R1103 (NULL); break; } } /* ffestc_eof -- Generic EOF ffestc_eof(); Make sure we're at state NIL, or issue an error message and use each block's shriek function to clean up to state NIL. */ void ffestc_eof () { if (ffestw_state (ffestw_stack_top ()) != FFESTV_stateNIL) { ffebad_start (FFEBAD_EOF_BEFORE_BLOCK_END); ffebad_here (0, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); do (*ffestw_shriek (ffestw_stack_top ()))(FALSE); while (ffestw_state (ffestw_stack_top ()) != FFESTV_stateNIL); } } /* ffestc_exec_transition -- Check if ok and move stmt state to executable if (ffestc_exec_transition()) // Transition successful (kind of like a CONTINUE stmt was seen). If the current statement state is a non-nested specification state in which, say, a CONTINUE statement would be valid, then enter the state we'd be in after seeing CONTINUE (without, of course, generating any CONTINUE code), call ffestd_exec_begin, and return TRUE. Otherwise return FALSE. This function cannot be invoked once the first executable statement is seen. This function may choose to always return TRUE by shrieking away any interceding state stack entries to reach the base level of specification state, but right now it doesn't, and it is (or should be) purely an issue of how one wishes errors to be handled (for example, an unrecognized statement in the middle of a STRUCTURE construct: after the error message, should subsequent statements still be interpreted as being within the construct, or should the construct be terminated upon seeing the unrecognized statement? we do the former at the moment). */ bool ffestc_exec_transition () { bool update; recurse: switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: ffestc_shriek_begin_program_ (); goto recurse; /* :::::::::::::::::::: */ case FFESTV_statePROGRAM0: case FFESTV_stateSUBROUTINE0: case FFESTV_stateFUNCTION0: case FFESTV_stateBLOCKDATA0: ffestw_state (ffestw_stack_top ()) += 4; /* To state UNIT4. */ update = TRUE; break; case FFESTV_statePROGRAM1: case FFESTV_stateSUBROUTINE1: case FFESTV_stateFUNCTION1: case FFESTV_stateBLOCKDATA1: ffestw_state (ffestw_stack_top ()) += 3; /* To state UNIT4. */ update = TRUE; break; case FFESTV_statePROGRAM2: case FFESTV_stateSUBROUTINE2: case FFESTV_stateFUNCTION2: case FFESTV_stateBLOCKDATA2: ffestw_state (ffestw_stack_top ()) += 2; /* To state UNIT4. */ update = TRUE; break; case FFESTV_statePROGRAM3: case FFESTV_stateSUBROUTINE3: case FFESTV_stateFUNCTION3: case FFESTV_stateBLOCKDATA3: ffestw_state (ffestw_stack_top ()) += 1; /* To state UNIT4. */ update = TRUE; break; case FFESTV_stateUSE: #if FFESTR_F90 ffestc_shriek_end_uses_ (TRUE); #endif goto recurse; /* :::::::::::::::::::: */ default: return FALSE; } if (update) ffestw_update (NULL); /* Update state line/col info. */ ffesta_seen_first_exec = TRUE; ffestd_exec_begin (); return TRUE; } /* ffestc_ffebad_here_doiter -- Calls ffebad_here with ptr to DO iter var ffesymbol s; // call ffebad_start first, of course. ffestc_ffebad_here_doiter(0,s); // call ffebad_finish afterwards, naturally. Searches the stack of blocks backwards for a DO loop that has s as its iteration variable, then calls ffebad_here with pointers to that particular reference to the variable. Crashes if the DO loop can't be found. */ void ffestc_ffebad_here_doiter (ffebadIndex i, ffesymbol s) { ffestw block; for (block = ffestw_top_do (ffestw_stack_top ()); (block != NULL) && (ffestw_blocknum (block) != 0); block = ffestw_top_do (ffestw_previous (block))) { if (ffestw_do_iter_var (block) == s) { ffebad_here (i, ffelex_token_where_line (ffestw_do_iter_var_t (block)), ffelex_token_where_column (ffestw_do_iter_var_t (block))); return; } } assert ("no do block found" == NULL); } /* ffestc_is_decl_not_R1219 -- Context information for FFESTB if (ffestc_is_decl_not_R1219()) ... When a statement with the form "type[RECURSIVE]FUNCTIONname(name-list)" is seen, call this function. It returns TRUE if the statement's context is such that it is a declaration of an object named "[RECURSIVE]FUNCTIONname" with an array-decl spec of "name-list", FALSE if the statement's context is such that it begins the definition of a function named "name" havin the dummy argument list "name-list" (this is the R1219 function-stmt case). */ bool ffestc_is_decl_not_R1219 () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateNIL: case FFESTV_statePROGRAM5: case FFESTV_stateSUBROUTINE5: case FFESTV_stateFUNCTION5: case FFESTV_stateMODULE5: case FFESTV_stateINTERFACE0: return FALSE; default: return TRUE; } } /* ffestc_is_entry_in_subr -- Context information for FFESTB if (ffestc_is_entry_in_subr()) ... When a statement with the form "ENTRY name(name-list)" is seen, call this function. It returns TRUE if the statement's context is such that it may have "*", meaning alternate return, in place of names in the name list (i.e. if the ENTRY is in a subroutine context). It also returns TRUE if the ENTRY is not in a function context (invalid but prevents extra complaints about "*", if present). It returns FALSE if the ENTRY is in a function context. */ bool ffestc_is_entry_in_subr () { ffestvState s; s = ffestw_state (ffestw_stack_top ()); recurse: switch (s) { case FFESTV_stateFUNCTION0: case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: case FFESTV_stateFUNCTION4: return FALSE; case FFESTV_stateUSE: s = ffestw_state (ffestw_previous (ffestw_stack_top ())); goto recurse; /* :::::::::::::::::::: */ default: return TRUE; } } /* ffestc_is_let_not_V027 -- Context information for FFESTB if (ffestc_is_let_not_V027()) ... When a statement with the form "PARAMETERname=expr" is seen, call this function. It returns TRUE if the statement's context is such that it is an assignment to an object named "PARAMETERname", FALSE if the statement's context is such that it is a V-extension PARAMETER statement that is like a PARAMETER(name=expr) statement except that the type of name is determined by the type of expr, not the implicit or explicit typing of name. */ bool ffestc_is_let_not_V027 () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: case FFESTV_stateWHERETHEN: case FFESTV_stateIFTHEN: case FFESTV_stateDO: case FFESTV_stateSELECT0: case FFESTV_stateSELECT1: case FFESTV_stateWHERE: case FFESTV_stateIF: return TRUE; default: return FALSE; } } /* ffestc_module -- MODULE or MODULE PROCEDURE statement ffestc_module(module_name_token,procedure_name_token); Decide which is intended, and implement it by calling _R1105_ or _R1205_. */ #if FFESTR_F90 void ffestc_module (ffelexToken module, ffelexToken procedure) { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateINTERFACE0: case FFESTV_stateINTERFACE1: ffestc_R1205_start (); ffestc_R1205_item (procedure); ffestc_R1205_finish (); break; default: ffestc_R1105 (module); break; } } #endif /* ffestc_private -- Generic PRIVATE statement ffestc_end(); This is either a PRIVATE within R422 derived-type statement or an R521 PRIVATE statement. Figure it out based on context and implement it, or produce an error. */ #if FFESTR_F90 void ffestc_private () { switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateTYPE: ffestc_R423A (); break; default: ffestc_R521B (); break; } } #endif /* ffestc_terminate_4 -- Terminate ffestc after scoping unit ffestc_terminate_4(); For SUBROUTINEs/FUNCTIONs within INTERFACE/END INTERFACE, derived-TYPE- defs, and statement function defs. */ void ffestc_terminate_4 () { ffestc_entry_num_ = ffestc_saved_entry_num_; } /* ffestc_R423A -- PRIVATE statement (in R422 derived-type statement) ffestc_R423A(); */ #if FFESTR_F90 void ffestc_R423A () { ffestc_check_simple_ (); if (ffestc_order_type_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) != 0) { ffebad_start (FFEBAD_DERIVTYP_ACCESS_FIRST); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); return; } if (ffestw_state (ffestw_previous (ffestw_stack_top ())) != FFESTV_stateMODULE3) { ffebad_start (FFEBAD_DERIVTYP_ACCESS); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); return; } ffestw_set_substate (ffestw_stack_top (), 1); /* Seen private-sequence-stmt. */ ffestd_R423A (); } /* ffestc_R423B -- SEQUENCE statement (in R422 derived-type-stmt) ffestc_R423B(); */ void ffestc_R423B () { ffestc_check_simple_ (); if (ffestc_order_type_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) != 0) { ffebad_start (FFEBAD_DERIVTYP_ACCESS_FIRST); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); return; } ffestw_set_substate (ffestw_stack_top (), 1); /* Seen private-sequence-stmt. */ ffestd_R423B (); } /* ffestc_R424 -- derived-TYPE-def statement ffestc_R424(access_token,access_kw,name_token); Handle a derived-type definition. */ void ffestc_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name) { ffestw b; assert (name != NULL); ffestc_check_simple_ (); if (ffestc_order_derivedtype_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if ((access != NULL) && (ffestw_state (ffestw_stack_top ()) != FFESTV_stateMODULE3)) { ffebad_start (FFEBAD_DERIVTYP_ACCESS); ffebad_here (0, ffelex_token_where_line (access), ffelex_token_where_column (access)); ffebad_finish (); access = NULL; } b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateTYPE); ffestw_set_blocknum (b, 0); ffestw_set_shriek (b, ffestc_shriek_type_); ffestw_set_name (b, ffelex_token_use (name)); ffestw_set_substate (b, 0); /* Awaiting private-sequence-stmt and one component-def-stmt. */ ffestd_R424 (access, access_kw, name); ffe_init_4 (); } /* ffestc_R425 -- END TYPE statement ffestc_R425(name_token); Make sure ffestc_kind_ identifies a TYPE definition. If not NULL, make sure name_token gives the correct name. Implement the end of the type definition. */ void ffestc_R425 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_type_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) != 2) { ffebad_start (FFEBAD_DERIVTYP_NO_COMPONENTS); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } if ((name != NULL) && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0)) { ffebad_start (FFEBAD_TYPE_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } ffestc_shriek_type_ (TRUE); } /* ffestc_R426_start -- component-declaration-stmt ffestc_R426_start(...); Verify that R426 component-declaration-stmt is valid here and implement. */ void ffestc_R426_start (ffestpType type, ffelexToken typet, ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent) { ffestc_check_start_ (); if (ffestc_order_component_ () != FFESTC_orderOK_) { ffestc_local_.decl.is_R426 = 0; return; } ffestc_labeldef_useless_ (); switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateSTRUCTURE: case FFESTV_stateMAP: ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one member. */ break; case FFESTV_stateTYPE: ffestw_set_substate (ffestw_stack_top (), 2); break; default: assert ("Component parent state invalid" == NULL); break; } } /* ffestc_R426_attrib -- type attribute ffestc_R426_attrib(...); Verify that R426 component-declaration-stmt attribute is valid here and implement. */ void ffestc_R426_attrib (ffestpAttrib attrib, ffelexToken attribt, ffestrOther intent_kw, ffesttDimList dims) { ffestc_check_attrib_ (); } /* ffestc_R426_item -- declared object ffestc_R426_item(...); Establish type for a particular object. */ void ffestc_R426_item (ffelexToken name, ffebld kind, ffelexToken kindt, ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init, ffelexToken initt, bool clist) { ffestc_check_item_ (); assert (name != NULL); assert (ffelex_token_type (name) == FFELEX_typeNAME); /* Not NAMES. */ assert (kind == NULL); /* No way an expression should get here. */ if ((dims != NULL) || (init != NULL) || clist) ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); } /* ffestc_R426_itemstartvals -- Start list of values ffestc_R426_itemstartvals(); Gonna specify values for the object now. */ void ffestc_R426_itemstartvals () { ffestc_check_item_startvals_ (); } /* ffestc_R426_itemvalue -- Source value ffestc_R426_itemvalue(repeat,repeat_token,value,value_token); Make sure repeat and value are valid for the object being initialized. */ void ffestc_R426_itemvalue (ffebld repeat, ffelexToken repeat_token, ffebld value, ffelexToken value_token) { ffestc_check_item_value_ (); } /* ffestc_R426_itemendvals -- End list of values ffelexToken t; // the SLASH token that ends the list. ffestc_R426_itemendvals(t); No more values, might specify more objects now. */ void ffestc_R426_itemendvals (ffelexToken t) { ffestc_check_item_endvals_ (); } /* ffestc_R426_finish -- Done ffestc_R426_finish(); Just wrap up any local activities. */ void ffestc_R426_finish () { ffestc_check_finish_ (); } #endif /* ffestc_R501_start -- type-declaration-stmt ffestc_R501_start(...); Verify that R501 type-declaration-stmt is valid here and implement. */ void ffestc_R501_start (ffestpType type, ffelexToken typet, ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent) { ffestc_check_start_ (); if (ffestc_order_typedecl_ () != FFESTC_orderOK_) { ffestc_local_.decl.is_R426 = 0; return; } ffestc_labeldef_useless_ (); ffestc_establish_declstmt_ (type, typet, kind, kindt, len, lent); } /* ffestc_R501_attrib -- type attribute ffestc_R501_attrib(...); Verify that R501 type-declaration-stmt attribute is valid here and implement. */ void ffestc_R501_attrib (ffestpAttrib attrib, ffelexToken attribt, ffestrOther intent_kw UNUSED, ffesttDimList dims UNUSED) { ffestc_check_attrib_ (); switch (attrib) { #if FFESTR_F90 case FFESTP_attribALLOCATABLE: break; #endif case FFESTP_attribDIMENSION: ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); break; case FFESTP_attribEXTERNAL: break; #if FFESTR_F90 case FFESTP_attribINTENT: break; #endif case FFESTP_attribINTRINSIC: break; #if FFESTR_F90 case FFESTP_attribOPTIONAL: break; #endif case FFESTP_attribPARAMETER: break; #if FFESTR_F90 case FFESTP_attribPOINTER: break; #endif #if FFESTR_F90 case FFESTP_attribPRIVATE: break; case FFESTP_attribPUBLIC: break; #endif case FFESTP_attribSAVE: switch (ffestv_save_state_) { case FFESTV_savestateNONE: ffestv_save_state_ = FFESTV_savestateSPECIFIC; ffestv_save_line_ = ffewhere_line_use (ffelex_token_where_line (attribt)); ffestv_save_col_ = ffewhere_column_use (ffelex_token_where_column (attribt)); break; case FFESTV_savestateSPECIFIC: case FFESTV_savestateANY: break; case FFESTV_savestateALL: if (ffe_is_pedantic ()) { ffebad_start (FFEBAD_CONFLICTING_SAVES); ffebad_here (0, ffestv_save_line_, ffestv_save_col_); ffebad_here (1, ffelex_token_where_line (attribt), ffelex_token_where_column (attribt)); ffebad_finish (); } ffestv_save_state_ = FFESTV_savestateANY; break; default: assert ("unexpected save state" == NULL); break; } break; #if FFESTR_F90 case FFESTP_attribTARGET: break; #endif default: assert ("unexpected attribute" == NULL); break; } } /* ffestc_R501_item -- declared object ffestc_R501_item(...); Establish type for a particular object. */ void ffestc_R501_item (ffelexToken name, ffebld kind, ffelexToken kindt, ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init, ffelexToken initt, bool clist) { ffesymbol s; ffesymbol sfn; /* FUNCTION symbol. */ ffebld array_size; ffebld extents; ffesymbolAttrs sa; ffesymbolAttrs na; ffestpDimtype nd; bool is_init = (init != NULL) || clist; bool is_assumed; bool is_ugly_assumed; ffeinfoRank rank; ffestc_check_item_ (); assert (name != NULL); assert (ffelex_token_type (name) == FFELEX_typeNAME); /* Not NAMES. */ assert (kind == NULL); /* No way an expression should get here. */ ffestc_establish_declinfo_ (kind, kindt, len, lent); is_assumed = (ffestc_local_.decl.basic_type == FFEINFO_basictypeCHARACTER) && (ffestc_local_.decl.size == FFETARGET_charactersizeNONE); if ((dims != NULL) || is_init) ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); s = ffesymbol_declare_local (name, TRUE); sa = ffesymbol_attrs (s); /* First figure out what kind of object this is based solely on the current object situation (type params, dimension list, and initialization). */ na = FFESYMBOL_attrsTYPE; if (is_assumed) na |= FFESYMBOL_attrsANYLEN; is_ugly_assumed = (ffe_is_ugly_assumed () && ((sa & FFESYMBOL_attrsDUMMY) || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); nd = ffestt_dimlist_type (dims, is_ugly_assumed); switch (nd) { case FFESTP_dimtypeNONE: break; case FFESTP_dimtypeKNOWN: na |= FFESYMBOL_attrsARRAY; break; case FFESTP_dimtypeADJUSTABLE: na |= FFESYMBOL_attrsARRAY | FFESYMBOL_attrsADJUSTABLE; break; case FFESTP_dimtypeASSUMED: na |= FFESYMBOL_attrsARRAY | FFESYMBOL_attrsANYSIZE; break; case FFESTP_dimtypeADJUSTABLEASSUMED: na |= FFESYMBOL_attrsARRAY | FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYSIZE; break; default: assert ("unexpected dimtype" == NULL); na = FFESYMBOL_attrsetNONE; break; } if (!ffesta_is_entry_valid && (((na & (FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsARRAY)) == (FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsARRAY)))) na = FFESYMBOL_attrsetNONE; if (is_init) { if (na == FFESYMBOL_attrsetNONE) ; else if (na & (FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYSIZE)) na = FFESYMBOL_attrsetNONE; else na |= FFESYMBOL_attrsINIT; } /* Now figure out what kind of object we've got based on previous declarations of or references to the object. */ if (na == FFESYMBOL_attrsetNONE) ; else if (!ffesymbol_is_specable (s) && (((ffesymbol_where (s) != FFEINFO_whereCONSTANT) && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC)) || (na & (FFESYMBOL_attrsARRAY | FFESYMBOL_attrsINIT)))) na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef, and can't dimension/init UNDERSTOODs. */ else if (sa & FFESYMBOL_attrsANY) na = sa; else if ((sa & na) || ((sa & (FFESYMBOL_attrsSFARG | FFESYMBOL_attrsADJUSTS)) && (na & (FFESYMBOL_attrsARRAY | FFESYMBOL_attrsANYLEN))) || ((sa & FFESYMBOL_attrsRESULT) && (na & (FFESYMBOL_attrsARRAY | FFESYMBOL_attrsINIT))) || ((sa & (FFESYMBOL_attrsSFUNC | FFESYMBOL_attrsEXTERNAL | FFESYMBOL_attrsINTRINSIC | FFESYMBOL_attrsINIT)) && (na & (FFESYMBOL_attrsARRAY | FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsINIT))) || ((sa & FFESYMBOL_attrsARRAY) && !ffesta_is_entry_valid && (na & FFESYMBOL_attrsANYLEN)) || ((sa & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsANYSIZE | FFESYMBOL_attrsDUMMY)) && (na & FFESYMBOL_attrsINIT)) || ((sa & (FFESYMBOL_attrsSAVE | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsEQUIV)) && (na & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsANYSIZE)))) na = FFESYMBOL_attrsetNONE; else if ((ffesymbol_kind (s) == FFEINFO_kindENTITY) && (ffesymbol_where (s) == FFEINFO_whereCONSTANT) && (na & FFESYMBOL_attrsANYLEN)) { /* If CHARACTER*(*) FOO after PARAMETER FOO. */ na |= FFESYMBOL_attrsTYPE; ffestc_local_.decl.size = ffebld_size (ffesymbol_init (s)); } else na |= sa; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) { ffesymbol_error (s, name); ffestc_parent_ok_ = FALSE; } else if (na & FFESYMBOL_attrsANY) ffestc_parent_ok_ = FALSE; else { ffesymbol_set_attrs (s, na); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) ffesymbol_set_state (s, FFESYMBOL_stateSEEN); rank = ffesymbol_rank (s); if (dims != NULL) { ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, &array_size, &extents, is_ugly_assumed)); ffesymbol_set_arraysize (s, array_size); ffesymbol_set_extents (s, extents); if (!(0 && ffe_is_90 ()) && (ffebld_op (array_size) == FFEBLD_opCONTER) && (ffebld_constant_integerdefault (ffebld_conter (array_size)) == 0)) { ffebad_start (FFEBAD_ZERO_ARRAY); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_finish (); } } if (init != NULL) { ffesymbol_set_init (s, ffeexpr_convert (init, initt, name, ffestc_local_.decl.basic_type, ffestc_local_.decl.kind_type, rank, ffestc_local_.decl.size, FFEEXPR_contextDATA)); ffecom_notify_init_symbol (s); ffesymbol_update_init (s); #if FFEGLOBAL_ENABLED if (ffesymbol_common (s) != NULL) ffeglobal_init_common (ffesymbol_common (s), initt); #endif } else if (clist) { ffebld symter; symter = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, FFEINTRIN_impNONE); ffebld_set_info (symter, ffeinfo_new (ffestc_local_.decl.basic_type, ffestc_local_.decl.kind_type, rank, FFEINFO_kindNONE, FFEINFO_whereNONE, ffestc_local_.decl.size)); ffestc_local_.decl.initlist = ffebld_new_item (symter, NULL); } if (ffesymbol_basictype (s) == FFEINFO_basictypeNONE) { ffesymbol_set_info (s, ffeinfo_new (ffestc_local_.decl.basic_type, ffestc_local_.decl.kind_type, rank, ffesymbol_kind (s), ffesymbol_where (s), ffestc_local_.decl.size)); if ((na & FFESYMBOL_attrsRESULT) && ((sfn = ffesymbol_funcresult (s)) != NULL)) { ffesymbol_set_info (sfn, ffeinfo_new (ffestc_local_.decl.basic_type, ffestc_local_.decl.kind_type, rank, ffesymbol_kind (sfn), ffesymbol_where (sfn), ffestc_local_.decl.size)); ffesymbol_signal_unreported (sfn); } } else if ((ffestc_local_.decl.basic_type != ffesymbol_basictype (s)) || (ffestc_local_.decl.kind_type != ffesymbol_kindtype (s)) || ((ffestc_local_.decl.basic_type == FFEINFO_basictypeCHARACTER) && (ffestc_local_.decl.size != ffesymbol_size (s)))) { /* Explicit type disagrees with established implicit type. */ ffesymbol_error (s, name); } if ((na & FFESYMBOL_attrsADJUSTS) && ((ffestc_local_.decl.basic_type != FFEINFO_basictypeINTEGER) || (ffestc_local_.decl.kind_type != FFEINFO_kindtypeINTEGER1))) ffesymbol_error (s, name); ffesymbol_signal_unreported (s); ffestc_parent_ok_ = TRUE; } } /* ffestc_R501_itemstartvals -- Start list of values ffestc_R501_itemstartvals(); Gonna specify values for the object now. */ void ffestc_R501_itemstartvals () { ffestc_check_item_startvals_ (); if (ffestc_parent_ok_) ffedata_begin (ffestc_local_.decl.initlist); } /* ffestc_R501_itemvalue -- Source value ffestc_R501_itemvalue(repeat,repeat_token,value,value_token); Make sure repeat and value are valid for the object being initialized. */ void ffestc_R501_itemvalue (ffebld repeat, ffelexToken repeat_token, ffebld value, ffelexToken value_token) { ffetargetIntegerDefault rpt; ffestc_check_item_value_ (); if (!ffestc_parent_ok_) return; if (repeat == NULL) rpt = 1; else if (ffebld_op (repeat) == FFEBLD_opCONTER) rpt = ffebld_constant_integerdefault (ffebld_conter (repeat)); else { ffestc_parent_ok_ = FALSE; ffedata_end (TRUE, NULL); return; } if (!(ffestc_parent_ok_ = ffedata_value (rpt, value, (repeat_token == NULL) ? value_token : repeat_token))) ffedata_end (TRUE, NULL); } /* ffestc_R501_itemendvals -- End list of values ffelexToken t; // the SLASH token that ends the list. ffestc_R501_itemendvals(t); No more values, might specify more objects now. */ void ffestc_R501_itemendvals (ffelexToken t) { ffestc_check_item_endvals_ (); if (ffestc_parent_ok_) ffestc_parent_ok_ = ffedata_end (FALSE, t); if (ffestc_parent_ok_) ffesymbol_signal_unreported (ffebld_symter (ffebld_head (ffestc_local_.decl.initlist))); } /* ffestc_R501_finish -- Done ffestc_R501_finish(); Just wrap up any local activities. */ void ffestc_R501_finish () { ffestc_check_finish_ (); } /* ffestc_R519_start -- INTENT statement list begin ffestc_R519_start(); Verify that INTENT is valid here, and begin accepting items in the list. */ #if FFESTR_F90 void ffestc_R519_start (ffelexToken intent, ffestrOther intent_kw) { ffestc_check_start_ (); if (ffestc_order_spec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R519_start (intent_kw); ffestc_ok_ = TRUE; } /* ffestc_R519_item -- INTENT statement for name ffestc_R519_item(name_token); Make sure name_token identifies a valid object to be INTENTed. */ void ffestc_R519_item (ffelexToken name) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffestd_R519_item (name); } /* ffestc_R519_finish -- INTENT statement list complete ffestc_R519_finish(); Just wrap up any local activities. */ void ffestc_R519_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R519_finish (); } /* ffestc_R520_start -- OPTIONAL statement list begin ffestc_R520_start(); Verify that OPTIONAL is valid here, and begin accepting items in the list. */ void ffestc_R520_start () { ffestc_check_start_ (); if (ffestc_order_spec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R520_start (); ffestc_ok_ = TRUE; } /* ffestc_R520_item -- OPTIONAL statement for name ffestc_R520_item(name_token); Make sure name_token identifies a valid object to be OPTIONALed. */ void ffestc_R520_item (ffelexToken name) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffestd_R520_item (name); } /* ffestc_R520_finish -- OPTIONAL statement list complete ffestc_R520_finish(); Just wrap up any local activities. */ void ffestc_R520_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R520_finish (); } /* ffestc_R521A -- PUBLIC statement ffestc_R521A(); Verify that PUBLIC is valid here. */ void ffestc_R521A () { ffestc_check_simple_ (); if (ffestc_order_access_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); switch (ffestv_access_state_) { case FFESTV_accessstateNONE: ffestv_access_state_ = FFESTV_accessstatePUBLIC; ffestv_access_line_ = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); ffestv_access_col_ = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); break; case FFESTV_accessstateANY: break; case FFESTV_accessstatePUBLIC: case FFESTV_accessstatePRIVATE: ffebad_start (FFEBAD_CONFLICTING_ACCESSES); ffebad_here (0, ffestv_access_line_, ffestv_access_col_); ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); ffestv_access_state_ = FFESTV_accessstateANY; break; default: assert ("unexpected access state" == NULL); break; } ffestd_R521A (); } /* ffestc_R521Astart -- PUBLIC statement list begin ffestc_R521Astart(); Verify that PUBLIC is valid here, and begin accepting items in the list. */ void ffestc_R521Astart () { ffestc_check_start_ (); if (ffestc_order_access_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R521Astart (); ffestc_ok_ = TRUE; } /* ffestc_R521Aitem -- PUBLIC statement for name ffestc_R521Aitem(name_token); Make sure name_token identifies a valid object to be PUBLICed. */ void ffestc_R521Aitem (ffelexToken name) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffestd_R521Aitem (name); } /* ffestc_R521Afinish -- PUBLIC statement list complete ffestc_R521Afinish(); Just wrap up any local activities. */ void ffestc_R521Afinish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R521Afinish (); } /* ffestc_R521B -- PRIVATE statement ffestc_R521B(); Verify that PRIVATE is valid here (outside a derived-type statement). */ void ffestc_R521B () { ffestc_check_simple_ (); if (ffestc_order_access_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); switch (ffestv_access_state_) { case FFESTV_accessstateNONE: ffestv_access_state_ = FFESTV_accessstatePRIVATE; ffestv_access_line_ = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); ffestv_access_col_ = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); break; case FFESTV_accessstateANY: break; case FFESTV_accessstatePUBLIC: case FFESTV_accessstatePRIVATE: ffebad_start (FFEBAD_CONFLICTING_ACCESSES); ffebad_here (0, ffestv_access_line_, ffestv_access_col_); ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); ffestv_access_state_ = FFESTV_accessstateANY; break; default: assert ("unexpected access state" == NULL); break; } ffestd_R521B (); } /* ffestc_R521Bstart -- PRIVATE statement list begin ffestc_R521Bstart(); Verify that PRIVATE is valid here, and begin accepting items in the list. */ void ffestc_R521Bstart () { ffestc_check_start_ (); if (ffestc_order_access_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R521Bstart (); ffestc_ok_ = TRUE; } /* ffestc_R521Bitem -- PRIVATE statement for name ffestc_R521Bitem(name_token); Make sure name_token identifies a valid object to be PRIVATEed. */ void ffestc_R521Bitem (ffelexToken name) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffestd_R521Bitem (name); } /* ffestc_R521Bfinish -- PRIVATE statement list complete ffestc_R521Bfinish(); Just wrap up any local activities. */ void ffestc_R521Bfinish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R521Bfinish (); } #endif /* ffestc_R522 -- SAVE statement with no list ffestc_R522(); Verify that SAVE is valid here, and flag everything as SAVEd. */ void ffestc_R522 () { ffestc_check_simple_ (); if (ffestc_order_blockspec_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); switch (ffestv_save_state_) { case FFESTV_savestateNONE: ffestv_save_state_ = FFESTV_savestateALL; ffestv_save_line_ = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); ffestv_save_col_ = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); break; case FFESTV_savestateANY: break; case FFESTV_savestateSPECIFIC: case FFESTV_savestateALL: if (ffe_is_pedantic ()) { ffebad_start (FFEBAD_CONFLICTING_SAVES); ffebad_here (0, ffestv_save_line_, ffestv_save_col_); ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); } ffestv_save_state_ = FFESTV_savestateALL; break; default: assert ("unexpected save state" == NULL); break; } ffe_set_is_saveall (TRUE); ffestd_R522 (); } /* ffestc_R522start -- SAVE statement list begin ffestc_R522start(); Verify that SAVE is valid here, and begin accepting items in the list. */ void ffestc_R522start () { ffestc_check_start_ (); if (ffestc_order_blockspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); switch (ffestv_save_state_) { case FFESTV_savestateNONE: ffestv_save_state_ = FFESTV_savestateSPECIFIC; ffestv_save_line_ = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); ffestv_save_col_ = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); break; case FFESTV_savestateSPECIFIC: case FFESTV_savestateANY: break; case FFESTV_savestateALL: if (ffe_is_pedantic ()) { ffebad_start (FFEBAD_CONFLICTING_SAVES); ffebad_here (0, ffestv_save_line_, ffestv_save_col_); ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); } ffestv_save_state_ = FFESTV_savestateANY; break; default: assert ("unexpected save state" == NULL); break; } ffestd_R522start (); ffestc_ok_ = TRUE; } /* ffestc_R522item_object -- SAVE statement for object-name ffestc_R522item_object(name_token); Make sure name_token identifies a valid object to be SAVEd. */ void ffestc_R522item_object (ffelexToken name) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; s = ffesymbol_declare_local (name, FALSE); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (s) && ((ffesymbol_kind (s) != FFEINFO_kindENTITY) || (ffesymbol_where (s) != FFEINFO_whereLOCAL))) na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ else if (sa & FFESYMBOL_attrsANY) na = sa; else if (!(sa & ~(FFESYMBOL_attrsARRAY | FFESYMBOL_attrsEQUIV | FFESYMBOL_attrsINIT | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsSFARG | FFESYMBOL_attrsTYPE))) na = sa | FFESYMBOL_attrsSAVE; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, name); else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_update_save (s); ffesymbol_signal_unreported (s); } ffestd_R522item_object (name); } /* ffestc_R522item_cblock -- SAVE statement for common-block-name ffestc_R522item_cblock(name_token); Make sure name_token identifies a valid common block to be SAVEd. */ void ffestc_R522item_cblock (ffelexToken name) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; s = ffesymbol_declare_cblock (name, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (s)) na = FFESYMBOL_attrsetNONE; else if (sa & FFESYMBOL_attrsANY) na = sa; /* Already have an error here, say nothing. */ else if (!(sa & ~(FFESYMBOL_attrsCBLOCK))) na = sa | FFESYMBOL_attrsSAVECBLOCK; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, (name == NULL) ? ffesta_tokens[0] : name); else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_update_save (s); ffesymbol_signal_unreported (s); } ffestd_R522item_cblock (name); } /* ffestc_R522finish -- SAVE statement list complete ffestc_R522finish(); Just wrap up any local activities. */ void ffestc_R522finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R522finish (); } /* ffestc_R524_start -- DIMENSION statement list begin ffestc_R524_start(bool virtual); Verify that DIMENSION is valid here, and begin accepting items in the list. */ void ffestc_R524_start (bool virtual) { ffestc_check_start_ (); if (ffestc_order_blockspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R524_start (virtual); ffestc_ok_ = TRUE; } /* ffestc_R524_item -- DIMENSION statement for object-name ffestc_R524_item(name_token,dim_list); Make sure name_token identifies a valid object to be DIMENSIONd. */ void ffestc_R524_item (ffelexToken name, ffesttDimList dims) { ffesymbol s; ffebld array_size; ffebld extents; ffesymbolAttrs sa; ffesymbolAttrs na; ffestpDimtype nd; ffeinfoRank rank; bool is_ugly_assumed; ffestc_check_item_ (); assert (name != NULL); assert (dims != NULL); if (!ffestc_ok_) return; ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); s = ffesymbol_declare_local (name, FALSE); sa = ffesymbol_attrs (s); /* First figure out what kind of object this is based solely on the current object situation (dimension list). */ is_ugly_assumed = (ffe_is_ugly_assumed () && ((sa & FFESYMBOL_attrsDUMMY) || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); nd = ffestt_dimlist_type (dims, is_ugly_assumed); switch (nd) { case FFESTP_dimtypeKNOWN: na = FFESYMBOL_attrsARRAY; break; case FFESTP_dimtypeADJUSTABLE: na = FFESYMBOL_attrsARRAY | FFESYMBOL_attrsADJUSTABLE; break; case FFESTP_dimtypeASSUMED: na = FFESYMBOL_attrsARRAY | FFESYMBOL_attrsANYSIZE; break; case FFESTP_dimtypeADJUSTABLEASSUMED: na = FFESYMBOL_attrsARRAY | FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYSIZE; break; default: assert ("Unexpected dims type" == NULL); na = FFESYMBOL_attrsetNONE; break; } /* Now figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (s)) na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ else if (sa & FFESYMBOL_attrsANY) na = FFESYMBOL_attrsANY; else if (!ffesta_is_entry_valid && (sa & FFESYMBOL_attrsANYLEN)) na = FFESYMBOL_attrsetNONE; else if ((sa & FFESYMBOL_attrsARRAY) || ((sa & (FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsEQUIV | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsSAVE)) && (na & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYSIZE)))) na = FFESYMBOL_attrsetNONE; else if (!(sa & ~(FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsANYSIZE | FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsDUMMY | FFESYMBOL_attrsEQUIV | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsSAVE | FFESYMBOL_attrsTYPE))) na |= sa; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, name); else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, &array_size, &extents, is_ugly_assumed)); ffesymbol_set_arraysize (s, array_size); ffesymbol_set_extents (s, extents); if (!(0 && ffe_is_90 ()) && (ffebld_op (array_size) == FFEBLD_opCONTER) && (ffebld_constant_integerdefault (ffebld_conter (array_size)) == 0)) { ffebad_start (FFEBAD_ZERO_ARRAY); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_finish (); } ffesymbol_set_info (s, ffeinfo_new (ffesymbol_basictype (s), ffesymbol_kindtype (s), rank, ffesymbol_kind (s), ffesymbol_where (s), ffesymbol_size (s))); } ffesymbol_signal_unreported (s); ffestd_R524_item (name, dims); } /* ffestc_R524_finish -- DIMENSION statement list complete ffestc_R524_finish(); Just wrap up any local activities. */ void ffestc_R524_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R524_finish (); } /* ffestc_R525_start -- ALLOCATABLE statement list begin ffestc_R525_start(); Verify that ALLOCATABLE is valid here, and begin accepting items in the list. */ #if FFESTR_F90 void ffestc_R525_start () { ffestc_check_start_ (); if (ffestc_order_progspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R525_start (); ffestc_ok_ = TRUE; } /* ffestc_R525_item -- ALLOCATABLE statement for object-name ffestc_R525_item(name_token,dim_list); Make sure name_token identifies a valid object to be ALLOCATABLEd. */ void ffestc_R525_item (ffelexToken name, ffesttDimList dims) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); ffestd_R525_item (name, dims); } /* ffestc_R525_finish -- ALLOCATABLE statement list complete ffestc_R525_finish(); Just wrap up any local activities. */ void ffestc_R525_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R525_finish (); } /* ffestc_R526_start -- POINTER statement list begin ffestc_R526_start(); Verify that POINTER is valid here, and begin accepting items in the list. */ void ffestc_R526_start () { ffestc_check_start_ (); if (ffestc_order_progspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R526_start (); ffestc_ok_ = TRUE; } /* ffestc_R526_item -- POINTER statement for object-name ffestc_R526_item(name_token,dim_list); Make sure name_token identifies a valid object to be POINTERd. */ void ffestc_R526_item (ffelexToken name, ffesttDimList dims) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); ffestd_R526_item (name, dims); } /* ffestc_R526_finish -- POINTER statement list complete ffestc_R526_finish(); Just wrap up any local activities. */ void ffestc_R526_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R526_finish (); } /* ffestc_R527_start -- TARGET statement list begin ffestc_R527_start(); Verify that TARGET is valid here, and begin accepting items in the list. */ void ffestc_R527_start () { ffestc_check_start_ (); if (ffestc_order_progspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R527_start (); ffestc_ok_ = TRUE; } /* ffestc_R527_item -- TARGET statement for object-name ffestc_R527_item(name_token,dim_list); Make sure name_token identifies a valid object to be TARGETd. */ void ffestc_R527_item (ffelexToken name, ffesttDimList dims) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); ffestd_R527_item (name, dims); } /* ffestc_R527_finish -- TARGET statement list complete ffestc_R527_finish(); Just wrap up any local activities. */ void ffestc_R527_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R527_finish (); } #endif /* ffestc_R528_start -- DATA statement list begin ffestc_R528_start(); Verify that DATA is valid here, and begin accepting items in the list. */ void ffestc_R528_start () { ffestcOrder_ order; ffestc_check_start_ (); if (ffe_is_pedantic_not_90 ()) order = ffestc_order_data77_ (); else order = ffestc_order_data_ (); if (order != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); #if 1 ffestc_local_.data.objlist = NULL; #else ffestd_R528_start_ (); #endif ffestc_ok_ = TRUE; } /* ffestc_R528_item_object -- DATA statement target object ffestc_R528_item_object(object,object_token); Make sure object is valid to be DATAd. */ void ffestc_R528_item_object (ffebld expr, ffelexToken expr_token UNUSED) { ffestc_check_item_ (); if (!ffestc_ok_) return; #if 1 if (ffestc_local_.data.objlist == NULL) ffebld_init_list (&ffestc_local_.data.objlist, &ffestc_local_.data.list_bottom); ffebld_append_item (&ffestc_local_.data.list_bottom, expr); #else ffestd_R528_item_object_ (expr, expr_token); #endif } /* ffestc_R528_item_startvals -- DATA statement start list of values ffestc_R528_item_startvals(); No more objects, gonna specify values for the list of objects now. */ void ffestc_R528_item_startvals () { ffestc_check_item_startvals_ (); if (!ffestc_ok_) return; #if 1 assert (ffestc_local_.data.objlist != NULL); ffebld_end_list (&ffestc_local_.data.list_bottom); ffedata_begin (ffestc_local_.data.objlist); #else ffestd_R528_item_startvals_ (); #endif } /* ffestc_R528_item_value -- DATA statement source value ffestc_R528_item_value(repeat,repeat_token,value,value_token); Make sure repeat and value are valid for the objects being initialized. */ void ffestc_R528_item_value (ffebld repeat, ffelexToken repeat_token, ffebld value, ffelexToken value_token) { ffetargetIntegerDefault rpt; ffestc_check_item_value_ (); if (!ffestc_ok_) return; #if 1 if (repeat == NULL) rpt = 1; else if (ffebld_op (repeat) == FFEBLD_opCONTER) rpt = ffebld_constant_integerdefault (ffebld_conter (repeat)); else { ffestc_ok_ = FALSE; ffedata_end (TRUE, NULL); return; } if (!(ffestc_ok_ = ffedata_value (rpt, value, (repeat_token == NULL) ? value_token : repeat_token))) ffedata_end (TRUE, NULL); #else ffestd_R528_item_value_ (repeat, value); #endif } /* ffestc_R528_item_endvals -- DATA statement start list of values ffelexToken t; // the SLASH token that ends the list. ffestc_R528_item_endvals(t); No more values, might specify more objects now. */ void ffestc_R528_item_endvals (ffelexToken t) { ffestc_check_item_endvals_ (); if (!ffestc_ok_) return; #if 1 ffedata_end (!ffestc_ok_, t); ffestc_local_.data.objlist = NULL; #else ffestd_R528_item_endvals_ (t); #endif } /* ffestc_R528_finish -- DATA statement list complete ffestc_R528_finish(); Just wrap up any local activities. */ void ffestc_R528_finish () { ffestc_check_finish_ (); #if 1 #else ffestd_R528_finish_ (); #endif } /* ffestc_R537_start -- PARAMETER statement list begin ffestc_R537_start(); Verify that PARAMETER is valid here, and begin accepting items in the list. */ void ffestc_R537_start () { ffestc_check_start_ (); if (ffestc_order_parameter_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); ffestd_R537_start (); ffestc_ok_ = TRUE; } /* ffestc_R537_item -- PARAMETER statement assignment ffestc_R537_item(dest,dest_token,source,source_token); Make sure the source is a valid source for the destination; make the assignment. */ void ffestc_R537_item (ffebld dest, ffelexToken dest_token, ffebld source, ffelexToken source_token) { ffesymbol s; ffestc_check_item_ (); if (!ffestc_ok_) return; if ((ffebld_op (dest) == FFEBLD_opANY) || (ffebld_op (source) == FFEBLD_opANY)) { if (ffebld_op (dest) == FFEBLD_opSYMTER) { s = ffebld_symter (dest); ffesymbol_set_init (s, ffebld_new_any ()); ffebld_set_info (ffesymbol_init (s), ffeinfo_new_any ()); ffesymbol_signal_unreported (s); } ffestd_R537_item (dest, source); return; } assert (ffebld_op (dest) == FFEBLD_opSYMTER); assert (ffebld_op (source) == FFEBLD_opCONTER); s = ffebld_symter (dest); if ((ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER) && (ffesymbol_size (s) == FFETARGET_charactersizeNONE)) { /* Destination has explicit/implicit CHARACTER*(*) type; set length. */ ffesymbol_set_info (s, ffeinfo_new (ffesymbol_basictype (s), ffesymbol_kindtype (s), 0, ffesymbol_kind (s), ffesymbol_where (s), ffebld_size (source))); ffebld_set_info (dest, ffeinfo_use (ffesymbol_info (s))); } source = ffeexpr_convert_expr (source, source_token, dest, dest_token, FFEEXPR_contextDATA); ffesymbol_set_init (s, source); ffesymbol_signal_unreported (s); ffestd_R537_item (dest, source); } /* ffestc_R537_finish -- PARAMETER statement list complete ffestc_R537_finish(); Just wrap up any local activities. */ void ffestc_R537_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R537_finish (); } /* ffestc_R539 -- IMPLICIT NONE statement ffestc_R539(); Verify that the IMPLICIT NONE statement is ok here and implement. */ void ffestc_R539 () { ffestc_check_simple_ (); if (ffestc_order_implicitnone_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffeimplic_none (); ffestd_R539 (); } /* ffestc_R539start -- IMPLICIT statement ffestc_R539start(); Verify that the IMPLICIT statement is ok here and implement. */ void ffestc_R539start () { ffestc_check_start_ (); if (ffestc_order_implicit_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R539start (); ffestc_ok_ = TRUE; } /* ffestc_R539item -- IMPLICIT statement specification (R540) ffestc_R539item(...); Verify that the type and letter list are all ok and implement. */ void ffestc_R539item (ffestpType type, ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent, ffesttImpList letters) { ffestc_check_item_ (); if (!ffestc_ok_) return; if ((type == FFESTP_typeCHARACTER) && (len != NULL) && (ffebld_op (len) == FFEBLD_opSTAR)) { /* Complain and pretend they're CHARACTER [*1]. */ ffebad_start (FFEBAD_IMPLICIT_ADJLEN); ffebad_here (0, ffelex_token_where_line (lent), ffelex_token_where_column (lent)); ffebad_finish (); len = NULL; lent = NULL; } ffestc_establish_declstmt_ (type, ffesta_tokens[0], kind, kindt, len, lent); ffestc_establish_declinfo_ (NULL, NULL, NULL, NULL); ffestt_implist_drive (letters, ffestc_establish_impletter_); ffestd_R539item (type, kind, kindt, len, lent, letters); } /* ffestc_R539finish -- IMPLICIT statement ffestc_R539finish(); Finish up any local activities. */ void ffestc_R539finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R539finish (); } /* ffestc_R542_start -- NAMELIST statement list begin ffestc_R542_start(); Verify that NAMELIST is valid here, and begin accepting items in the list. */ void ffestc_R542_start () { ffestc_check_start_ (); if (ffestc_order_progspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); if (ffe_is_f2c_library () && (ffe_case_source () == FFE_caseNONE)) { ffebad_start (FFEBAD_NAMELIST_CASE); ffesta_ffebad_here_current_stmt (0); ffebad_finish (); } ffestd_R542_start (); ffestc_local_.namelist.symbol = NULL; ffestc_ok_ = TRUE; } /* ffestc_R542_item_nlist -- NAMELIST statement for group-name ffestc_R542_item_nlist(groupname_token); Make sure name_token identifies a valid object to be NAMELISTd. */ void ffestc_R542_item_nlist (ffelexToken name) { ffesymbol s; ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; if (ffestc_local_.namelist.symbol != NULL) ffesymbol_signal_unreported (ffestc_local_.namelist.symbol); s = ffesymbol_declare_local (name, FALSE); if ((ffesymbol_state (s) == FFESYMBOL_stateNONE) || ((ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) && (ffesymbol_kind (s) == FFEINFO_kindNAMELIST))) { ffestc_parent_ok_ = TRUE; if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffebld_init_list (ffesymbol_ptr_to_namelist (s), ffesymbol_ptr_to_listbottom (s)); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindNAMELIST, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); } } else { if (ffesymbol_kind (s) != FFEINFO_kindANY) ffesymbol_error (s, name); ffestc_parent_ok_ = FALSE; } ffestc_local_.namelist.symbol = s; ffestd_R542_item_nlist (name); } /* ffestc_R542_item_nitem -- NAMELIST statement for variable-name ffestc_R542_item_nitem(name_token); Make sure name_token identifies a valid object to be NAMELISTd. */ void ffestc_R542_item_nitem (ffelexToken name) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffebld e; ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; s = ffesymbol_declare_local (name, FALSE); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (s) && ((ffesymbol_kind (s) != FFEINFO_kindENTITY) || ((ffesymbol_where (s) != FFEINFO_whereLOCAL) && (ffesymbol_where (s) != FFEINFO_whereCOMMON)))) na = FFESYMBOL_attrsetNONE; else if (sa & FFESYMBOL_attrsANY) na = FFESYMBOL_attrsANY; else if (!(sa & ~(FFESYMBOL_attrsADJUSTS | FFESYMBOL_attrsARRAY | FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsEQUIV | FFESYMBOL_attrsINIT | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsSAVE | FFESYMBOL_attrsSFARG | FFESYMBOL_attrsTYPE))) na = sa | FFESYMBOL_attrsNAMELIST; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, name); else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_set_namelisted (s, TRUE); ffesymbol_signal_unreported (s); #if 0 /* No need to establish type yet! */ if (!ffeimplic_establish_symbol (s)) ffesymbol_error (s, name); #endif } if (ffestc_parent_ok_) { e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, FFEINTRIN_impNONE); ffebld_set_info (e, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindNONE, FFEINFO_whereNONE, FFETARGET_charactersizeNONE)); ffebld_append_item (ffesymbol_ptr_to_listbottom (ffestc_local_.namelist.symbol), e); } ffestd_R542_item_nitem (name); } /* ffestc_R542_finish -- NAMELIST statement list complete ffestc_R542_finish(); Just wrap up any local activities. */ void ffestc_R542_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffesymbol_signal_unreported (ffestc_local_.namelist.symbol); ffestd_R542_finish (); } /* ffestc_R544_start -- EQUIVALENCE statement list begin ffestc_R544_start(); Verify that EQUIVALENCE is valid here, and begin accepting items in the list. */ void ffestc_R544_start () { ffestc_check_start_ (); if (ffestc_order_blockspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); ffestc_ok_ = TRUE; } /* ffestc_R544_item -- EQUIVALENCE statement assignment ffestc_R544_item(exprlist); Make sure the equivalence is valid, then implement it. */ void ffestc_R544_item (ffesttExprList exprlist) { ffestc_check_item_ (); if (!ffestc_ok_) return; /* First we go through the list and come up with one ffeequiv object that will describe all items in the list. When an ffeequiv object is first found, it is used (else we create one as a "local equiv" for the time being). If subsequent ffeequiv objects are found, they are merged with the first so we end up with one. However, if more than one COMMON variable is involved, then an error condition occurs. */ ffestc_local_.equiv.ok = TRUE; ffestc_local_.equiv.t = NULL; /* No token yet. */ ffestc_local_.equiv.eq = NULL;/* No equiv yet. */ ffestc_local_.equiv.save = FALSE; /* No SAVEd variables yet. */ ffebld_init_list (&ffestc_local_.equiv.list, &ffestc_local_.equiv.bottom); ffestt_exprlist_drive (exprlist, ffestc_R544_equiv_); /* Get one equiv. */ ffebld_end_list (&ffestc_local_.equiv.bottom); if (!ffestc_local_.equiv.ok) return; /* Something went wrong, stop bothering with this stuff. */ if (ffestc_local_.equiv.eq == NULL) ffestc_local_.equiv.eq = ffeequiv_new (); /* Make local equivalence. */ /* Append this list of equivalences to list of such lists for this equivalence. */ ffeequiv_add (ffestc_local_.equiv.eq, ffestc_local_.equiv.list, ffestc_local_.equiv.t); if (ffestc_local_.equiv.save) ffeequiv_update_save (ffestc_local_.equiv.eq); } /* ffestc_R544_equiv_ -- EQUIVALENCE statement handler for item in list ffebld expr; ffelexToken t; ffestc_R544_equiv_(expr,t); Record information, if any, on symbol in expr; if symbol has equivalence object already, merge with outstanding object if present or make it the outstanding object. */ static void ffestc_R544_equiv_ (ffebld expr, ffelexToken t) { ffesymbol s; if (!ffestc_local_.equiv.ok) return; if (ffestc_local_.equiv.t == NULL) ffestc_local_.equiv.t = t; switch (ffebld_op (expr)) { case FFEBLD_opANY: return; /* Don't put this on the list. */ case FFEBLD_opSYMTER: case FFEBLD_opARRAYREF: case FFEBLD_opSUBSTR: break; /* All of these are ok. */ default: assert ("ffestc_R544_equiv_ bad op" == NULL); return; } ffebld_append_item (&ffestc_local_.equiv.bottom, expr); s = ffeequiv_symbol (expr); /* See if symbol has an equivalence object already. */ if (ffesymbol_equiv (s) != NULL) { if (ffestc_local_.equiv.eq == NULL) ffestc_local_.equiv.eq = ffesymbol_equiv (s); /* New equiv obj. */ else if (ffestc_local_.equiv.eq != ffesymbol_equiv (s)) { ffestc_local_.equiv.eq = ffeequiv_merge (ffesymbol_equiv (s), ffestc_local_.equiv.eq, t); if (ffestc_local_.equiv.eq == NULL) ffestc_local_.equiv.ok = FALSE; /* Couldn't merge. */ } } if (ffesymbol_is_save (s)) ffestc_local_.equiv.save = TRUE; } /* ffestc_R544_finish -- EQUIVALENCE statement list complete ffestc_R544_finish(); Just wrap up any local activities. */ void ffestc_R544_finish () { ffestc_check_finish_ (); } /* ffestc_R547_start -- COMMON statement list begin ffestc_R547_start(); Verify that COMMON is valid here, and begin accepting items in the list. */ void ffestc_R547_start () { ffestc_check_start_ (); if (ffestc_order_blockspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestc_local_.common.symbol = NULL; /* Blank common is the default. */ ffestc_parent_ok_ = TRUE; ffestd_R547_start (); ffestc_ok_ = TRUE; } /* ffestc_R547_item_object -- COMMON statement for object-name ffestc_R547_item_object(name_token,dim_list); Make sure name_token identifies a valid object to be COMMONd. */ void ffestc_R547_item_object (ffelexToken name, ffesttDimList dims) { ffesymbol s; ffebld array_size; ffebld extents; ffesymbolAttrs sa; ffesymbolAttrs na; ffestpDimtype nd; ffebld e; ffeinfoRank rank; bool is_ugly_assumed; if (ffestc_parent_ok_ && (ffestc_local_.common.symbol == NULL)) ffestc_R547_item_cblock (NULL); /* As if "COMMON [//] ...". */ ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; if (dims != NULL) ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); s = ffesymbol_declare_local (name, FALSE); sa = ffesymbol_attrs (s); /* First figure out what kind of object this is based solely on the current object situation (dimension list). */ is_ugly_assumed = (ffe_is_ugly_assumed () && ((sa & FFESYMBOL_attrsDUMMY) || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); nd = ffestt_dimlist_type (dims, is_ugly_assumed); switch (nd) { case FFESTP_dimtypeNONE: na = FFESYMBOL_attrsCOMMON; break; case FFESTP_dimtypeKNOWN: na = FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsARRAY; break; default: na = FFESYMBOL_attrsetNONE; break; } /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (na == FFESYMBOL_attrsetNONE) ; else if (!ffesymbol_is_specable (s)) na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ else if (sa & FFESYMBOL_attrsANY) na = FFESYMBOL_attrsANY; else if ((sa & (FFESYMBOL_attrsADJUSTS | FFESYMBOL_attrsARRAY | FFESYMBOL_attrsINIT | FFESYMBOL_attrsSFARG)) && (na & FFESYMBOL_attrsARRAY)) na = FFESYMBOL_attrsetNONE; else if (!(sa & ~(FFESYMBOL_attrsADJUSTS | FFESYMBOL_attrsARRAY | FFESYMBOL_attrsEQUIV | FFESYMBOL_attrsINIT | FFESYMBOL_attrsNAMELIST | FFESYMBOL_attrsSFARG | FFESYMBOL_attrsTYPE))) na |= sa; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, name); else if ((ffesymbol_equiv (s) != NULL) && (ffeequiv_common (ffesymbol_equiv (s)) != NULL) && (ffeequiv_common (ffesymbol_equiv (s)) != ffestc_local_.common.symbol)) { /* Oops, just COMMONed a symbol to a different area (via equiv). */ ffebad_start (FFEBAD_EQUIV_COMMON); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_string (ffesymbol_text (ffestc_local_.common.symbol)); ffebad_string (ffesymbol_text (ffeequiv_common (ffesymbol_equiv (s)))); ffebad_finish (); ffesymbol_set_attr (s, na | FFESYMBOL_attrANY); ffesymbol_set_info (s, ffeinfo_new_any ()); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_signal_unreported (s); } else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_set_common (s, ffestc_local_.common.symbol); #if FFEGLOBAL_ENABLED if (ffesymbol_is_init (s)) ffeglobal_init_common (ffestc_local_.common.symbol, name); #endif if (ffesymbol_is_save (ffestc_local_.common.symbol)) ffesymbol_update_save (s); if (ffesymbol_equiv (s) != NULL) { /* Is this newly COMMONed symbol involved in an equivalence? */ if (ffeequiv_common (ffesymbol_equiv (s)) == NULL) ffeequiv_set_common (ffesymbol_equiv (s), /* Yes, tell equiv obj. */ ffestc_local_.common.symbol); #if FFEGLOBAL_ENABLED if (ffeequiv_is_init (ffesymbol_equiv (s))) ffeglobal_init_common (ffestc_local_.common.symbol, name); #endif if (ffesymbol_is_save (ffestc_local_.common.symbol)) ffeequiv_update_save (ffesymbol_equiv (s)); } if (dims != NULL) { ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, &array_size, &extents, is_ugly_assumed)); ffesymbol_set_arraysize (s, array_size); ffesymbol_set_extents (s, extents); if (!(0 && ffe_is_90 ()) && (ffebld_op (array_size) == FFEBLD_opCONTER) && (ffebld_constant_integerdefault (ffebld_conter (array_size)) == 0)) { ffebad_start (FFEBAD_ZERO_ARRAY); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_finish (); } ffesymbol_set_info (s, ffeinfo_new (ffesymbol_basictype (s), ffesymbol_kindtype (s), rank, ffesymbol_kind (s), ffesymbol_where (s), ffesymbol_size (s))); } ffesymbol_signal_unreported (s); } if (ffestc_parent_ok_) { e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, FFEINTRIN_impNONE); ffebld_set_info (e, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindNONE, FFEINFO_whereNONE, FFETARGET_charactersizeNONE)); ffebld_append_item (ffesymbol_ptr_to_listbottom (ffestc_local_.common.symbol), e); } ffestd_R547_item_object (name, dims); } /* ffestc_R547_item_cblock -- COMMON statement for common-block-name ffestc_R547_item_cblock(name_token); Make sure name_token identifies a valid common block to be COMMONd. */ void ffestc_R547_item_cblock (ffelexToken name) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffestc_check_item_ (); if (!ffestc_ok_) return; if (ffestc_local_.common.symbol != NULL) ffesymbol_signal_unreported (ffestc_local_.common.symbol); s = ffesymbol_declare_cblock (name, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (s)) na = FFESYMBOL_attrsetNONE; else if (sa & FFESYMBOL_attrsANY) na = FFESYMBOL_attrsANY; /* Already have an error here, say nothing. */ else if (!(sa & ~(FFESYMBOL_attrsCBLOCK | FFESYMBOL_attrsSAVECBLOCK))) { if (!(sa & FFESYMBOL_attrsCBLOCK)) ffebld_init_list (ffesymbol_ptr_to_commonlist (s), ffesymbol_ptr_to_listbottom (s)); na = sa | FFESYMBOL_attrsCBLOCK; } else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) { ffesymbol_error (s, name == NULL ? ffesta_tokens[0] : name); ffestc_parent_ok_ = FALSE; } else if (na & FFESYMBOL_attrsANY) ffestc_parent_ok_ = FALSE; else { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateSEEN); if (name == NULL) ffesymbol_update_save (s); ffestc_parent_ok_ = TRUE; } ffestc_local_.common.symbol = s; ffestd_R547_item_cblock (name); } /* ffestc_R547_finish -- COMMON statement list complete ffestc_R547_finish(); Just wrap up any local activities. */ void ffestc_R547_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; if (ffestc_local_.common.symbol != NULL) ffesymbol_signal_unreported (ffestc_local_.common.symbol); ffestd_R547_finish (); } /* ffestc_R620 -- ALLOCATE statement ffestc_R620(exprlist,stat,stat_token); Make sure the expression list is valid, then implement it. */ #if FFESTR_F90 void ffestc_R620 (ffesttExprList exprlist, ffebld stat, ffelexToken stat_token) { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); ffestd_R620 (exprlist, stat); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R624 -- NULLIFY statement ffestc_R624(pointer_name_list); Make sure pointer_name_list identifies valid pointers for a NULLIFY. */ void ffestc_R624 (ffesttExprList pointers) { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); ffestd_R624 (pointers); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R625 -- DEALLOCATE statement ffestc_R625(exprlist,stat,stat_token); Make sure the equivalence is valid, then implement it. */ void ffestc_R625 (ffesttExprList exprlist, ffebld stat, ffelexToken stat_token) { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); ffestd_R625 (exprlist, stat); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } #endif /* ffestc_let -- R1213 or R737 ffestc_let(...); Verify that R1213 defined-assignment or R737 assignment-stmt are valid here, figure out which one, and implement. */ #if FFESTR_F90 void ffestc_let (ffebld dest, ffebld source, ffelexToken source_token) { ffestc_R737 (dest, source, source_token); } #endif /* ffestc_R737 -- Assignment statement ffestc_R737(dest_expr,source_expr,source_token); Make sure the assignment is valid. */ void ffestc_R737 (ffebld dest, ffebld source, ffelexToken source_token) { ffestc_check_simple_ (); switch (ffestw_state (ffestw_stack_top ())) { #if FFESTR_F90 case FFESTV_stateWHERE: case FFESTV_stateWHERETHEN: if (ffestc_order_actionwhere_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestd_R737B (dest, source); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); return; #endif default: break; } if (ffestc_order_actionwhere_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); source = ffeexpr_convert_expr (source, source_token, dest, ffesta_tokens[0], FFEEXPR_contextLET); ffestd_R737A (dest, source); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R738 -- Pointer assignment statement ffestc_R738(dest_expr,source_expr,source_token); Make sure the assignment is valid. */ #if FFESTR_F90 void ffestc_R738 (ffebld dest, ffebld source, ffelexToken source_token) { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); ffestd_R738 (dest, source); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R740 -- WHERE statement ffestc_R740(expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R740 (ffebld expr, ffelexToken expr_token) { ffestw b; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); ffestw_set_state (b, FFESTV_stateWHERE); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_where_lost_); ffestd_R740 (expr); /* Leave label finishing to next statement. */ } /* ffestc_R742 -- WHERE-construct statement ffestc_R742(expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R742 (ffebld expr, ffelexToken expr_token) { ffestw b; ffestc_check_simple_ (); if (ffestc_order_exec_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_probably_this_wont_work_ (); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); ffestw_set_state (b, FFESTV_stateWHERETHEN); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_wherethen_); ffestw_set_substate (b, 0); /* Haven't seen ELSEWHERE yet. */ ffestd_R742 (expr); } /* ffestc_R744 -- ELSE WHERE statement ffestc_R744(); Make sure ffestc_kind_ identifies a WHERE block. Implement the ELSE of the current WHERE block. */ void ffestc_R744 () { ffestc_check_simple_ (); if (ffestc_order_where_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) != 0) { ffebad_start (FFEBAD_SECOND_ELSE_WHERE); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } ffestw_set_substate (ffestw_stack_top (), 1); /* Saw ELSEWHERE. */ ffestd_R744 (); } /* ffestc_R745 -- END WHERE statement ffestc_R745(); Make sure ffestc_kind_ identifies a WHERE block. Implement the end of the current WHERE block. */ void ffestc_R745 () { ffestc_check_simple_ (); if (ffestc_order_where_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestc_shriek_wherethen_ (TRUE); } #endif /* ffestc_R803 -- Block IF (IF-THEN) statement ffestc_R803(construct_name,expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R803 (ffelexToken construct_name, ffebld expr, ffelexToken expr_token UNUSED) { ffestw b; ffesymbol s; ffestc_check_simple_ (); if (ffestc_order_exec_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); ffestw_set_state (b, FFESTV_stateIFTHEN); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_ifthen_); ffestw_set_substate (b, 0); /* Haven't seen ELSE yet. */ if (construct_name == NULL) ffestw_set_name (b, NULL); else { ffestw_set_name (b, ffelex_token_use (construct_name)); s = ffesymbol_declare_local (construct_name, FALSE); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindCONSTRUCT, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); s = ffecom_sym_learned (s); ffesymbol_signal_unreported (s); } else ffesymbol_error (s, construct_name); } ffestd_R803 (construct_name, expr); } /* ffestc_R804 -- ELSE IF statement ffestc_R804(expr,expr_token,name_token); Make sure ffestc_kind_ identifies an IF block. If not NULL, make sure name_token gives the correct name. Implement the else of the IF block. */ void ffestc_R804 (ffebld expr, ffelexToken expr_token UNUSED, ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_ifthen_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (name != NULL) { if (ffestw_name (ffestw_stack_top ()) == NULL) { ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) { ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } } if (ffestw_substate (ffestw_stack_top ()) != 0) { ffebad_start (FFEBAD_AFTER_ELSE); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); return; /* Don't upset back end with ELSEIF after ELSE. */ } ffestd_R804 (expr, name); } /* ffestc_R805 -- ELSE statement ffestc_R805(name_token); Make sure ffestc_kind_ identifies an IF block. If not NULL, make sure name_token gives the correct name. Implement the ELSE of the IF block. */ void ffestc_R805 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_ifthen_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (name != NULL) { if (ffestw_name (ffestw_stack_top ()) == NULL) { ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) { ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } } if (ffestw_substate (ffestw_stack_top ()) != 0) { ffebad_start (FFEBAD_AFTER_ELSE); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); return; /* Tell back end about only one ELSE. */ } ffestw_set_substate (ffestw_stack_top (), 1); /* Saw ELSE. */ ffestd_R805 (name); } /* ffestc_R806 -- END IF statement ffestc_R806(name_token); Make sure ffestc_kind_ identifies an IF block. If not NULL, make sure name_token gives the correct name. Implement the end of the IF block. */ void ffestc_R806 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_ifthen_ () != FFESTC_orderOK_) return; ffestc_labeldef_endif_ (); if (name == NULL) { if (ffestw_name (ffestw_stack_top ()) != NULL) { ffebad_start (FFEBAD_CONSTRUCT_NAMED); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } } else { if (ffestw_name (ffestw_stack_top ()) == NULL) { ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) { ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } } ffestc_shriek_ifthen_ (TRUE); } /* ffestc_R807 -- Logical IF statement ffestc_R807(expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R807 (ffebld expr, ffelexToken expr_token UNUSED) { ffestw b; ffestc_check_simple_ (); if (ffestc_order_action_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); ffestw_set_state (b, FFESTV_stateIF); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_if_lost_); ffestd_R807 (expr); /* Do the label finishing in the next statement. */ } /* ffestc_R809 -- SELECT CASE statement ffestc_R809(construct_name,expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R809 (ffelexToken construct_name, ffebld expr, ffelexToken expr_token) { ffestw b; mallocPool pool; ffestwSelect s; ffesymbol sym; ffestc_check_simple_ (); if (ffestc_order_exec_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); ffestw_set_state (b, FFESTV_stateSELECT0); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_select_); ffestw_set_substate (b, 0); /* Haven't seen CASE DEFAULT yet. */ /* Init block to manage CASE list. */ pool = malloc_pool_new ("Select", ffe_pool_any_unit (), 1024); s = (ffestwSelect) malloc_new_kp (pool, "Select", sizeof (*s)); s->first_rel = (ffestwCase) &s->first_rel; s->last_rel = (ffestwCase) &s->first_rel; s->first_stmt = (ffestwCase) &s->first_rel; s->last_stmt = (ffestwCase) &s->first_rel; s->pool = pool; s->cases = 1; s->t = ffelex_token_use (expr_token); s->type = ffeinfo_basictype (ffebld_info (expr)); s->kindtype = ffeinfo_kindtype (ffebld_info (expr)); ffestw_set_select (b, s); if (construct_name == NULL) ffestw_set_name (b, NULL); else { ffestw_set_name (b, ffelex_token_use (construct_name)); sym = ffesymbol_declare_local (construct_name, FALSE); if (ffesymbol_state (sym) == FFESYMBOL_stateNONE) { ffesymbol_set_state (sym, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (sym, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindCONSTRUCT, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); sym = ffecom_sym_learned (sym); ffesymbol_signal_unreported (sym); } else ffesymbol_error (sym, construct_name); } ffestd_R809 (construct_name, expr); } /* ffestc_R810 -- CASE statement ffestc_R810(case_value_range_list,name); If case_value_range_list is NULL, it's CASE DEFAULT. name is the case- construct-name. Make sure no more than one CASE DEFAULT is present for a given case-construct and that there aren't any overlapping ranges or duplicate case values. */ void ffestc_R810 (ffesttCaseList cases, ffelexToken name) { ffesttCaseList caseobj; ffestwSelect s; ffestwCase c, nc; ffebldConstant expr1c, expr2c; ffestc_check_simple_ (); if (ffestc_order_selectcase_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); s = ffestw_select (ffestw_stack_top ()); if (ffestw_state (ffestw_stack_top ()) == FFESTV_stateSELECT0) { #if 0 /* Not sure we want to have msgs point here instead of SELECT CASE. */ ffestw_update (NULL); /* Update state line/col info. */ #endif ffestw_set_state (ffestw_stack_top (), FFESTV_stateSELECT1); } if (name != NULL) { if (ffestw_name (ffestw_stack_top ()) == NULL) { ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) { ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } } if (cases == NULL) { if (ffestw_substate (ffestw_stack_top ()) != 0) { ffebad_start (FFEBAD_CASE_SECOND_DEFAULT); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } ffestw_set_substate (ffestw_stack_top (), 1); /* Saw ELSE. */ } else { /* For each case, try to fit into sorted list of ranges. */ for (caseobj = cases->next; caseobj != cases; caseobj = caseobj->next) { if ((caseobj->expr1 == NULL) && (!caseobj->range || (caseobj->expr2 == NULL))) { /* "CASE (:)". */ ffebad_start (FFEBAD_CASE_BAD_RANGE); ffebad_here (0, ffelex_token_where_line (caseobj->t), ffelex_token_where_column (caseobj->t)); ffebad_finish (); continue; } if (((caseobj->expr1 != NULL) && ((ffeinfo_basictype (ffebld_info (caseobj->expr1)) != s->type) || (ffeinfo_kindtype (ffebld_info (caseobj->expr1)) != s->kindtype))) || ((caseobj->range) && (caseobj->expr2 != NULL) && ((ffeinfo_basictype (ffebld_info (caseobj->expr2)) != s->type) || (ffeinfo_kindtype (ffebld_info (caseobj->expr2)) != s->kindtype)))) { ffebad_start (FFEBAD_CASE_TYPE_DISAGREE); ffebad_here (0, ffelex_token_where_line (caseobj->t), ffelex_token_where_column (caseobj->t)); ffebad_here (1, ffelex_token_where_line (s->t), ffelex_token_where_column (s->t)); ffebad_finish (); continue; } if ((s->type == FFEINFO_basictypeLOGICAL) && (caseobj->range)) { ffebad_start (FFEBAD_CASE_LOGICAL_RANGE); ffebad_here (0, ffelex_token_where_line (caseobj->t), ffelex_token_where_column (caseobj->t)); ffebad_finish (); continue; } if (caseobj->expr1 == NULL) expr1c = NULL; else if (ffebld_op (caseobj->expr1) != FFEBLD_opCONTER) continue; /* opANY. */ else expr1c = ffebld_conter (caseobj->expr1); if (!caseobj->range) expr2c = expr1c; /* expr1c and expr2c are NOT NULL in this case. */ else if (caseobj->expr2 == NULL) expr2c = NULL; else if (ffebld_op (caseobj->expr2) != FFEBLD_opCONTER) continue; /* opANY. */ else expr2c = ffebld_conter (caseobj->expr2); if (expr1c == NULL) { /* "CASE (:high)", must be first in list. */ c = s->first_rel; if ((c != (ffestwCase) &s->first_rel) && ((c->low == NULL) || (ffebld_constant_cmp (expr2c, c->low) >= 0))) { /* Other "CASE (:high)" or lowest "CASE (low[:high])" low. */ ffebad_start (FFEBAD_CASE_DUPLICATE); ffebad_here (0, ffelex_token_where_line (caseobj->t), ffelex_token_where_column (caseobj->t)); ffebad_here (1, ffelex_token_where_line (c->t), ffelex_token_where_column (c->t)); ffebad_finish (); continue; } } else if (expr2c == NULL) { /* "CASE (low:)", must be last in list. */ c = s->last_rel; if ((c != (ffestwCase) &s->first_rel) && ((c->high == NULL) || (ffebld_constant_cmp (expr1c, c->high) <= 0))) { /* Other "CASE (low:)" or lowest "CASE ([low:]high)" high. */ ffebad_start (FFEBAD_CASE_DUPLICATE); ffebad_here (0, ffelex_token_where_line (caseobj->t), ffelex_token_where_column (caseobj->t)); ffebad_here (1, ffelex_token_where_line (c->t), ffelex_token_where_column (c->t)); ffebad_finish (); continue; } c = c->next_rel; /* Same as c = (ffestwCase) &s->first;. */ } else { /* (expr1c != NULL) && (expr2c != NULL). */ if (ffebld_constant_cmp (expr1c, expr2c) > 0) { /* Such as "CASE (3:1)" or "CASE ('B':'A')". */ ffebad_start (FFEBAD_CASE_RANGE_USELESS); /* Warn/inform only. */ ffebad_here (0, ffelex_token_where_line (caseobj->t), ffelex_token_where_column (caseobj->t)); ffebad_finish (); continue; } for (c = s->first_rel; (c != (ffestwCase) &s->first_rel) && ((c->low == NULL) || (ffebld_constant_cmp (expr1c, c->low) > 0)); c = c->next_rel) ; nc = c; /* Which one to report? */ if (((c != (ffestwCase) &s->first_rel) && (ffebld_constant_cmp (expr2c, c->low) >= 0)) || (((nc = c->previous_rel) != (ffestwCase) &s->first_rel) && (ffebld_constant_cmp (expr1c, nc->high) <= 0))) { /* Interference with range in case nc. */ ffebad_start (FFEBAD_CASE_DUPLICATE); ffebad_here (0, ffelex_token_where_line (caseobj->t), ffelex_token_where_column (caseobj->t)); ffebad_here (1, ffelex_token_where_line (nc->t), ffelex_token_where_column (nc->t)); ffebad_finish (); continue; } } /* If we reach here for this case range/value, it's ok (sorts into the list of ranges/values) so we give it its own case object sorted into the list of case statements. */ nc = malloc_new_kp (s->pool, "Case range", sizeof (*nc)); nc->next_rel = c; nc->previous_rel = c->previous_rel; nc->next_stmt = (ffestwCase) &s->first_rel; nc->previous_stmt = s->last_stmt; nc->low = expr1c; nc->high = expr2c; nc->casenum = s->cases; nc->t = ffelex_token_use (caseobj->t); nc->next_rel->previous_rel = nc; nc->previous_rel->next_rel = nc; nc->next_stmt->previous_stmt = nc; nc->previous_stmt->next_stmt = nc; } } ffestd_R810 ((cases == NULL) ? 0 : s->cases); s->cases++; /* Increment # of cases. */ } /* ffestc_R811 -- END SELECT statement ffestc_R811(name_token); Make sure ffestc_kind_ identifies a SELECT block. If not NULL, make sure name_token gives the correct name. Implement the end of the SELECT block. */ void ffestc_R811 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_selectcase_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); if (name == NULL) { if (ffestw_name (ffestw_stack_top ()) != NULL) { ffebad_start (FFEBAD_CONSTRUCT_NAMED); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } } else { if (ffestw_name (ffestw_stack_top ()) == NULL) { ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) { ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } } ffestc_shriek_select_ (TRUE); } /* ffestc_R819A -- Iterative labeled DO statement ffestc_R819A(construct_name,label_token,expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R819A (ffelexToken construct_name, ffelexToken label_token, ffebld var, ffelexToken var_token, ffebld start, ffelexToken start_token, ffebld end, ffelexToken end_token, ffebld incr, ffelexToken incr_token) { ffestw b; ffelab label; ffesymbol s; ffesymbol varsym; ffestc_check_simple_ (); if (ffestc_order_exec_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); if (!ffestc_labelref_is_loopend_ (label_token, &label)) return; b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, b); ffestw_set_state (b, FFESTV_stateDO); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_do_); ffestw_set_label (b, label); switch (ffebld_op (var)) { case FFEBLD_opSYMTER: if ((ffeinfo_basictype (ffebld_info (var)) == FFEINFO_basictypeREAL) && ffe_is_warn_surprising ()) { ffebad_start (FFEBAD_DO_REAL); /* See error message!!! */ ffebad_here (0, ffelex_token_where_line (var_token), ffelex_token_where_column (var_token)); ffebad_string (ffesymbol_text (ffebld_symter (var))); ffebad_finish (); } if (!ffesymbol_is_doiter (varsym = ffebld_symter (var))) { /* Presumably already complained about by ffeexpr_lhs_. */ ffesymbol_set_is_doiter (varsym, TRUE); ffestw_set_do_iter_var (b, varsym); ffestw_set_do_iter_var_t (b, ffelex_token_use (var_token)); break; } /* Fall through. */ case FFEBLD_opANY: ffestw_set_do_iter_var (b, NULL); ffestw_set_do_iter_var_t (b, NULL); break; default: assert ("bad iter var" == NULL); break; } if (construct_name == NULL) ffestw_set_name (b, NULL); else { ffestw_set_name (b, ffelex_token_use (construct_name)); s = ffesymbol_declare_local (construct_name, FALSE); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindCONSTRUCT, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); s = ffecom_sym_learned (s); ffesymbol_signal_unreported (s); } else ffesymbol_error (s, construct_name); } if (incr == NULL) { incr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1)); ffebld_set_info (incr, ffeinfo_new (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGERDEFAULT, 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); } start = ffeexpr_convert_expr (start, start_token, var, var_token, FFEEXPR_contextLET); end = ffeexpr_convert_expr (end, end_token, var, var_token, FFEEXPR_contextLET); incr = ffeexpr_convert_expr (incr, incr_token, var, var_token, FFEEXPR_contextLET); ffestd_R819A (construct_name, label, var, start, start_token, end, end_token, incr, incr_token); } /* ffestc_R819B -- Labeled DO WHILE statement ffestc_R819B(construct_name,label_token,expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R819B (ffelexToken construct_name, ffelexToken label_token, ffebld expr, ffelexToken expr_token UNUSED) { ffestw b; ffelab label; ffesymbol s; ffestc_check_simple_ (); if (ffestc_order_exec_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); if (!ffestc_labelref_is_loopend_ (label_token, &label)) return; b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, b); ffestw_set_state (b, FFESTV_stateDO); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_do_); ffestw_set_label (b, label); ffestw_set_do_iter_var (b, NULL); ffestw_set_do_iter_var_t (b, NULL); if (construct_name == NULL) ffestw_set_name (b, NULL); else { ffestw_set_name (b, ffelex_token_use (construct_name)); s = ffesymbol_declare_local (construct_name, FALSE); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindCONSTRUCT, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); s = ffecom_sym_learned (s); ffesymbol_signal_unreported (s); } else ffesymbol_error (s, construct_name); } ffestd_R819B (construct_name, label, expr); } /* ffestc_R820A -- Iterative nonlabeled DO statement ffestc_R820A(construct_name,expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R820A (ffelexToken construct_name, ffebld var, ffelexToken var_token, ffebld start, ffelexToken start_token, ffebld end, ffelexToken end_token, ffebld incr, ffelexToken incr_token) { ffestw b; ffesymbol s; ffesymbol varsym; ffestc_check_simple_ (); if (ffestc_order_exec_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, b); ffestw_set_state (b, FFESTV_stateDO); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_do_); ffestw_set_label (b, NULL); switch (ffebld_op (var)) { case FFEBLD_opSYMTER: if ((ffeinfo_basictype (ffebld_info (var)) == FFEINFO_basictypeREAL) && ffe_is_warn_surprising ()) { ffebad_start (FFEBAD_DO_REAL); /* See error message!!! */ ffebad_here (0, ffelex_token_where_line (var_token), ffelex_token_where_column (var_token)); ffebad_string (ffesymbol_text (ffebld_symter (var))); ffebad_finish (); } if (!ffesymbol_is_doiter (varsym = ffebld_symter (var))) { /* Presumably already complained about by ffeexpr_lhs_. */ ffesymbol_set_is_doiter (varsym, TRUE); ffestw_set_do_iter_var (b, varsym); ffestw_set_do_iter_var_t (b, ffelex_token_use (var_token)); break; } /* Fall through. */ case FFEBLD_opANY: ffestw_set_do_iter_var (b, NULL); ffestw_set_do_iter_var_t (b, NULL); break; default: assert ("bad iter var" == NULL); break; } if (construct_name == NULL) ffestw_set_name (b, NULL); else { ffestw_set_name (b, ffelex_token_use (construct_name)); s = ffesymbol_declare_local (construct_name, FALSE); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindCONSTRUCT, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); s = ffecom_sym_learned (s); ffesymbol_signal_unreported (s); } else ffesymbol_error (s, construct_name); } if (incr == NULL) { incr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1)); ffebld_set_info (incr, ffeinfo_new (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGERDEFAULT, 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); } start = ffeexpr_convert_expr (start, start_token, var, var_token, FFEEXPR_contextLET); end = ffeexpr_convert_expr (end, end_token, var, var_token, FFEEXPR_contextLET); incr = ffeexpr_convert_expr (incr, incr_token, var, var_token, FFEEXPR_contextLET); #if 0 if ((ffebld_op (incr) == FFEBLD_opCONTER) && (ffebld_constant_is_zero (ffebld_conter (incr)))) { ffebad_start (FFEBAD_DO_STEP_ZERO); ffebad_here (0, ffelex_token_where_line (incr_token), ffelex_token_where_column (incr_token)); ffebad_string ("Iterative DO loop"); ffebad_finish (); } #endif ffestd_R819A (construct_name, NULL, var, start, start_token, end, end_token, incr, incr_token); } /* ffestc_R820B -- Nonlabeled DO WHILE statement ffestc_R820B(construct_name,expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R820B (ffelexToken construct_name, ffebld expr, ffelexToken expr_token UNUSED) { ffestw b; ffesymbol s; ffestc_check_simple_ (); if (ffestc_order_exec_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, b); ffestw_set_state (b, FFESTV_stateDO); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_do_); ffestw_set_label (b, NULL); ffestw_set_do_iter_var (b, NULL); ffestw_set_do_iter_var_t (b, NULL); if (construct_name == NULL) ffestw_set_name (b, NULL); else { ffestw_set_name (b, ffelex_token_use (construct_name)); s = ffesymbol_declare_local (construct_name, FALSE); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindCONSTRUCT, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); s = ffecom_sym_learned (s); ffesymbol_signal_unreported (s); } else ffesymbol_error (s, construct_name); } ffestd_R819B (construct_name, NULL, expr); } /* ffestc_R825 -- END DO statement ffestc_R825(name_token); Make sure ffestc_kind_ identifies a DO block. If not NULL, make sure name_token gives the correct name. Implement the end of the DO block. */ void ffestc_R825 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_do_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (name == NULL) { if (ffestw_name (ffestw_stack_top ()) != NULL) { ffebad_start (FFEBAD_CONSTRUCT_NAMED); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } } else { if (ffestw_name (ffestw_stack_top ()) == NULL) { ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) { ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } } if (ffesta_label_token == NULL) { /* If top of stack has label, its an error! */ if (ffestw_label (ffestw_stack_top ()) != NULL) { ffebad_start (FFEBAD_DO_HAD_LABEL); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } ffestc_shriek_do_ (TRUE); ffestc_try_shriek_do_ (); return; } ffestd_R825 (name); ffestc_labeldef_branch_end_ (); } /* ffestc_R834 -- CYCLE statement ffestc_R834(name_token); Handle a CYCLE within a loop. */ void ffestc_R834 (ffelexToken name) { ffestw block; ffestc_check_simple_ (); if (ffestc_order_actiondo_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_begin_ (); if (name == NULL) block = ffestw_top_do (ffestw_stack_top ()); else { /* Search for name. */ for (block = ffestw_top_do (ffestw_stack_top ()); (block != NULL) && (ffestw_blocknum (block) != 0); block = ffestw_top_do (ffestw_previous (block))) { if ((ffestw_name (block) != NULL) && (ffelex_token_strcmp (name, ffestw_name (block)) == 0)) break; } if ((block == NULL) || (ffestw_blocknum (block) == 0)) { block = ffestw_top_do (ffestw_stack_top ()); ffebad_start (FFEBAD_CONSTRUCT_NO_DO_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_finish (); } } ffestd_R834 (block); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); /* notloop's that are actionif's can be the target of a loop-end statement if they're in the "then" part of a logical IF, as in "DO 10", "10 IF (...) CYCLE". */ ffestc_labeldef_branch_end_ (); } /* ffestc_R835 -- EXIT statement ffestc_R835(name_token); Handle a EXIT within a loop. */ void ffestc_R835 (ffelexToken name) { ffestw block; ffestc_check_simple_ (); if (ffestc_order_actiondo_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_begin_ (); if (name == NULL) block = ffestw_top_do (ffestw_stack_top ()); else { /* Search for name. */ for (block = ffestw_top_do (ffestw_stack_top ()); (block != NULL) && (ffestw_blocknum (block) != 0); block = ffestw_top_do (ffestw_previous (block))) { if ((ffestw_name (block) != NULL) && (ffelex_token_strcmp (name, ffestw_name (block)) == 0)) break; } if ((block == NULL) || (ffestw_blocknum (block) == 0)) { block = ffestw_top_do (ffestw_stack_top ()); ffebad_start (FFEBAD_CONSTRUCT_NO_DO_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_finish (); } } ffestd_R835 (block); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); /* notloop's that are actionif's can be the target of a loop-end statement if they're in the "then" part of a logical IF, as in "DO 10", "10 IF (...) EXIT". */ ffestc_labeldef_branch_end_ (); } /* ffestc_R836 -- GOTO statement ffestc_R836(label_token); Make sure label_token identifies a valid label for a GOTO. Update that label's info to indicate it is the target of a GOTO. */ void ffestc_R836 (ffelexToken label_token) { ffelab label; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_begin_ (); if (ffestc_labelref_is_branch_ (label_token, &label)) ffestd_R836 (label); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); /* notloop's that are actionif's can be the target of a loop-end statement if they're in the "then" part of a logical IF, as in "DO 10", "10 IF (...) GOTO 100". */ ffestc_labeldef_branch_end_ (); } /* ffestc_R837 -- Computed GOTO statement ffestc_R837(label_list,expr,expr_token); Make sure label_list identifies valid labels for a GOTO. Update each label's info to indicate it is the target of a GOTO. */ void ffestc_R837 (ffesttTokenList label_toks, ffebld expr, ffelexToken expr_token UNUSED) { ffesttTokenItem ti; bool ok = TRUE; int i; ffelab *labels; assert (label_toks != NULL); ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); labels = malloc_new_kp (ffesta_output_pool, "FFESTC labels", sizeof (*labels) * ffestt_tokenlist_count (label_toks)); for (ti = label_toks->first, i = 0; ti != (ffesttTokenItem) &label_toks->first; ti = ti->next, ++i) { if (!ffestc_labelref_is_branch_ (ti->t, &labels[i])) { ok = FALSE; break; } } if (ok) ffestd_R837 (labels, ffestt_tokenlist_count (label_toks), expr); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R838 -- ASSIGN statement ffestc_R838(label_token,target_variable,target_token); Make sure label_token identifies a valid label for an assignment. Update that label's info to indicate it is the source of an assignment. Update target_variable's info to indicate it is the target the assignment of that label. */ void ffestc_R838 (ffelexToken label_token, ffebld target, ffelexToken target_token UNUSED) { ffelab label; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); /* Mark target symbol as target of an ASSIGN. */ if (ffebld_op (target) == FFEBLD_opSYMTER) ffesymbol_set_assigned (ffebld_symter (target), TRUE); if (ffestc_labelref_is_assignable_ (label_token, &label)) ffestd_R838 (label, target); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R839 -- Assigned GOTO statement ffestc_R839(target,target_token,label_list); Make sure label_list identifies valid labels for a GOTO. Update each label's info to indicate it is the target of a GOTO. */ void ffestc_R839 (ffebld target, ffelexToken target_token UNUSED, ffesttTokenList label_toks) { ffesttTokenItem ti; bool ok = TRUE; int i; ffelab *labels; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_begin_ (); if (label_toks == NULL) { labels = NULL; i = 0; } else { labels = malloc_new_kp (ffesta_output_pool, "FFESTC labels", sizeof (*labels) * ffestt_tokenlist_count (label_toks)); for (ti = label_toks->first, i = 0; ti != (ffesttTokenItem) &label_toks->first; ti = ti->next, ++i) { if (!ffestc_labelref_is_branch_ (ti->t, &labels[i])) { ok = FALSE; break; } } } if (ok) ffestd_R839 (target, labels, i); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); /* notloop's that are actionif's can be the target of a loop-end statement if they're in the "then" part of a logical IF, as in "DO 10", "10 IF (...) GOTO I". */ ffestc_labeldef_branch_end_ (); } /* ffestc_R840 -- Arithmetic IF statement ffestc_R840(expr,expr_token,neg,zero,pos); Make sure the labels are valid; implement. */ void ffestc_R840 (ffebld expr, ffelexToken expr_token UNUSED, ffelexToken neg_token, ffelexToken zero_token, ffelexToken pos_token) { ffelab neg; ffelab zero; ffelab pos; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_begin_ (); if (ffestc_labelref_is_branch_ (neg_token, &neg) && ffestc_labelref_is_branch_ (zero_token, &zero) && ffestc_labelref_is_branch_ (pos_token, &pos)) ffestd_R840 (expr, neg, zero, pos); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); /* notloop's that are actionif's can be the target of a loop-end statement if they're in the "then" part of a logical IF, as in "DO 10", "10 IF (...) GOTO (100,200,300), I". */ ffestc_labeldef_branch_end_ (); } /* ffestc_R841 -- CONTINUE statement ffestc_R841(); */ void ffestc_R841 () { ffestc_check_simple_ (); if (ffestc_order_actionwhere_ () != FFESTC_orderOK_) return; switch (ffestw_state (ffestw_stack_top ())) { #if FFESTR_F90 case FFESTV_stateWHERE: case FFESTV_stateWHERETHEN: ffestc_labeldef_useless_ (); ffestd_R841 (TRUE); /* It's okay that we call ffestc_labeldef_branch_end_ () below, since that will be a no-op after calling _useless_ () above. */ break; #endif default: ffestc_labeldef_branch_begin_ (); ffestd_R841 (FALSE); break; } if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R842 -- STOP statement ffestc_R842(expr,expr_token); Make sure statement is valid here; implement. expr and expr_token are both NULL if there was no expression. */ void ffestc_R842 (ffebld expr, ffelexToken expr_token UNUSED) { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_begin_ (); ffestd_R842 (expr); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); /* notloop's that are actionif's can be the target of a loop-end statement if they're in the "then" part of a logical IF, as in "DO 10", "10 IF (...) STOP". */ ffestc_labeldef_branch_end_ (); } /* ffestc_R843 -- PAUSE statement ffestc_R843(expr,expr_token); Make sure statement is valid here; implement. expr and expr_token are both NULL if there was no expression. */ void ffestc_R843 (ffebld expr, ffelexToken expr_token UNUSED) { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); ffestd_R843 (expr); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R904 -- OPEN statement ffestc_R904(); Make sure an OPEN is valid in the current context, and implement it. */ void ffestc_R904 () { int i; int expect_file; const char *status_strs[] = { "New", "Old", "Replace", "Scratch", "Unknown" }; const char *access_strs[] = { "Append", "Direct", "Keyed", "Sequential" }; const char *blank_strs[] = { "Null", "Zero" }; const char *carriagecontrol_strs[] = { "Fortran", "List", "None" }; const char *dispose_strs[] = { "Delete", "Keep", "Print", "Print/Delete", "Save", "Submit", "Submit/Delete" }; const char *form_strs[] = { "Formatted", "Unformatted" }; const char *organization_strs[] = { "Indexed", "Relative", "Sequential" }; const char *position_strs[] = { "Append", "AsIs", "Rewind" }; const char *action_strs[] = { "Read", "ReadWrite", "Write" }; const char *delim_strs[] = { "Apostrophe", "None", "Quote" }; const char *recordtype_strs[] = { "Fixed", "Segmented", "Stream", "Stream_CR", "Stream_LF", "Variable" }; const char *pad_strs[] = { "No", "Yes" }; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.open.open_spec[FFESTP_openixERR]) && ffestc_subr_is_present_ ("UNIT", &ffestp_file.open.open_spec[FFESTP_openixUNIT])) { i = ffestc_subr_binsrch_ (status_strs, ARRAY_SIZE (status_strs), &ffestp_file.open.open_spec[FFESTP_openixSTATUS], "NEW, OLD, REPLACE, SCRATCH, or UNKNOWN"); switch (i) { case 0: /* Unknown. */ case 5: /* UNKNOWN. */ expect_file = 2; /* Unknown, don't care about FILE=. */ break; case 1: /* NEW. */ case 2: /* OLD. */ if (ffe_is_pedantic ()) expect_file = 1; /* Yes, need FILE=. */ else expect_file = 2; /* f2clib doesn't care about FILE=. */ break; case 3: /* REPLACE. */ expect_file = 1; /* Yes, need FILE=. */ break; case 4: /* SCRATCH. */ expect_file = 0; /* No, disallow FILE=. */ break; default: assert ("invalid _binsrch_ result" == NULL); expect_file = 0; break; } if ((expect_file == 0) && ffestp_file.open.open_spec[FFESTP_openixFILE].kw_or_val_present) { ffebad_start (FFEBAD_CONFLICTING_SPECS); assert (ffestp_file.open.open_spec[FFESTP_openixFILE].kw_or_val_present); if (ffestp_file.open.open_spec[FFESTP_openixFILE].kw_present) { ffebad_here (0, ffelex_token_where_line (ffestp_file.open.open_spec[FFESTP_openixFILE].kw), ffelex_token_where_column (ffestp_file.open.open_spec[FFESTP_openixFILE].kw)); } else { ffebad_here (0, ffelex_token_where_line (ffestp_file.open.open_spec[FFESTP_openixFILE].value), ffelex_token_where_column (ffestp_file.open.open_spec[FFESTP_openixFILE].value)); } assert (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw_or_val_present); if (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw_present) { ffebad_here (1, ffelex_token_where_line (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw), ffelex_token_where_column (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw)); } else { ffebad_here (1, ffelex_token_where_line (ffestp_file.open.open_spec[FFESTP_openixSTATUS].value), ffelex_token_where_column (ffestp_file.open.open_spec[FFESTP_openixSTATUS].value)); } ffebad_finish (); } else if ((expect_file == 1) && !ffestp_file.open.open_spec[FFESTP_openixFILE].kw_or_val_present) { ffebad_start (FFEBAD_MISSING_SPECIFIER); assert (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw_or_val_present); if (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw_present) { ffebad_here (0, ffelex_token_where_line (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw), ffelex_token_where_column (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw)); } else { ffebad_here (0, ffelex_token_where_line (ffestp_file.open.open_spec[FFESTP_openixSTATUS].value), ffelex_token_where_column (ffestp_file.open.open_spec[FFESTP_openixSTATUS].value)); } ffebad_string ("FILE="); ffebad_finish (); } ffestc_subr_binsrch_ (access_strs, ARRAY_SIZE (access_strs), &ffestp_file.open.open_spec[FFESTP_openixACCESS], "APPEND, DIRECT, KEYED, or SEQUENTIAL"); ffestc_subr_binsrch_ (blank_strs, ARRAY_SIZE (blank_strs), &ffestp_file.open.open_spec[FFESTP_openixBLANK], "NULL or ZERO"); ffestc_subr_binsrch_ (carriagecontrol_strs, ARRAY_SIZE (carriagecontrol_strs), &ffestp_file.open.open_spec[FFESTP_openixCARRIAGECONTROL], "FORTRAN, LIST, or NONE"); ffestc_subr_binsrch_ (dispose_strs, ARRAY_SIZE (dispose_strs), &ffestp_file.open.open_spec[FFESTP_openixDISPOSE], "DELETE, KEEP, PRINT, PRINT/DELETE, SAVE, SUBMIT, or SUBMIT/DELETE"); ffestc_subr_binsrch_ (form_strs, ARRAY_SIZE (form_strs), &ffestp_file.open.open_spec[FFESTP_openixFORM], "FORMATTED or UNFORMATTED"); ffestc_subr_binsrch_ (organization_strs, ARRAY_SIZE (organization_strs), &ffestp_file.open.open_spec[FFESTP_openixORGANIZATION], "INDEXED, RELATIVE, or SEQUENTIAL"); ffestc_subr_binsrch_ (position_strs, ARRAY_SIZE (position_strs), &ffestp_file.open.open_spec[FFESTP_openixPOSITION], "APPEND, ASIS, or REWIND"); ffestc_subr_binsrch_ (action_strs, ARRAY_SIZE (action_strs), &ffestp_file.open.open_spec[FFESTP_openixACTION], "READ, READWRITE, or WRITE"); ffestc_subr_binsrch_ (delim_strs, ARRAY_SIZE (delim_strs), &ffestp_file.open.open_spec[FFESTP_openixDELIM], "APOSTROPHE, NONE, or QUOTE"); ffestc_subr_binsrch_ (recordtype_strs, ARRAY_SIZE (recordtype_strs), &ffestp_file.open.open_spec[FFESTP_openixRECORDTYPE], "FIXED, SEGMENTED, STREAM, STREAM_CR, STREAM_LF, or VARIABLE"); ffestc_subr_binsrch_ (pad_strs, ARRAY_SIZE (pad_strs), &ffestp_file.open.open_spec[FFESTP_openixPAD], "NO or YES"); ffestd_R904 (); } if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R907 -- CLOSE statement ffestc_R907(); Make sure a CLOSE is valid in the current context, and implement it. */ void ffestc_R907 () { const char *status_strs[] = { "Delete", "Keep", "Print", "Print/Delete", "Save", "Submit", "Submit/Delete" }; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.close.close_spec[FFESTP_closeixERR]) && ffestc_subr_is_present_ ("UNIT", &ffestp_file.close.close_spec[FFESTP_closeixUNIT])) { ffestc_subr_binsrch_ (status_strs, ARRAY_SIZE (status_strs), &ffestp_file.close.close_spec[FFESTP_closeixSTATUS], "DELETE, KEEP, PRINT, PRINT/DELETE, SAVE, SUBMIT, or SUBMIT/DELETE"); ffestd_R907 (); } if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R909_start -- READ(...) statement list begin ffestc_R909_start(FALSE); Verify that READ is valid here, and begin accepting items in the list. */ void ffestc_R909_start (bool only_format) { ffestvUnit unit; ffestvFormat format; bool rec; bool key; ffestpReadIx keyn; ffestpReadIx spec1; ffestpReadIx spec2; ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); if (!ffestc_subr_is_format_ (&ffestp_file.read.read_spec[FFESTP_readixFORMAT])) { ffestc_ok_ = FALSE; return; } format = ffestc_subr_format_ (&ffestp_file.read.read_spec[FFESTP_readixFORMAT]); ffestc_namelist_ = (format == FFESTV_formatNAMELIST); if (only_format) { ffestd_R909_start (TRUE, FFESTV_unitNONE, format, FALSE, FALSE); ffestc_ok_ = TRUE; return; } if (!ffestc_subr_is_branch_ (&ffestp_file.read.read_spec[FFESTP_readixEOR]) || !ffestc_subr_is_branch_ (&ffestp_file.read.read_spec[FFESTP_readixERR]) || !ffestc_subr_is_branch_ (&ffestp_file.read.read_spec[FFESTP_readixEND])) { ffestc_ok_ = FALSE; return; } unit = ffestc_subr_unit_ (&ffestp_file.read.read_spec[FFESTP_readixUNIT]); if (unit == FFESTV_unitNONE) { ffebad_start (FFEBAD_NO_UNIT_SPEC); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); ffestc_ok_ = FALSE; return; } rec = ffestp_file.read.read_spec[FFESTP_readixREC].kw_or_val_present; if (ffestp_file.read.read_spec[FFESTP_readixKEYEQ].kw_or_val_present) { key = TRUE; keyn = spec1 = FFESTP_readixKEYEQ; } else { key = FALSE; keyn = spec1 = FFESTP_readix; } if (ffestp_file.read.read_spec[FFESTP_readixKEYGT].kw_or_val_present) { if (key) { spec2 = FFESTP_readixKEYGT; whine: /* :::::::::::::::::::: */ ffebad_start (FFEBAD_CONFLICTING_SPECS); assert (ffestp_file.read.read_spec[spec1].kw_or_val_present); if (ffestp_file.read.read_spec[spec1].kw_present) { ffebad_here (0, ffelex_token_where_line (ffestp_file.read.read_spec[spec1].kw), ffelex_token_where_column (ffestp_file.read.read_spec[spec1].kw)); } else { ffebad_here (0, ffelex_token_where_line (ffestp_file.read.read_spec[spec1].value), ffelex_token_where_column (ffestp_file.read.read_spec[spec1].value)); } assert (ffestp_file.read.read_spec[spec2].kw_or_val_present); if (ffestp_file.read.read_spec[spec2].kw_present) { ffebad_here (1, ffelex_token_where_line (ffestp_file.read.read_spec[spec2].kw), ffelex_token_where_column (ffestp_file.read.read_spec[spec2].kw)); } else { ffebad_here (1, ffelex_token_where_line (ffestp_file.read.read_spec[spec2].value), ffelex_token_where_column (ffestp_file.read.read_spec[spec2].value)); } ffebad_finish (); ffestc_ok_ = FALSE; return; } key = TRUE; keyn = spec1 = FFESTP_readixKEYGT; } if (ffestp_file.read.read_spec[FFESTP_readixKEYGE].kw_or_val_present) { if (key) { spec2 = FFESTP_readixKEYGT; goto whine; /* :::::::::::::::::::: */ } key = TRUE; keyn = FFESTP_readixKEYGT; } if (rec) { spec1 = FFESTP_readixREC; if (key) { spec2 = keyn; goto whine; /* :::::::::::::::::::: */ } if (unit == FFESTV_unitCHAREXPR) { spec2 = FFESTP_readixUNIT; goto whine; /* :::::::::::::::::::: */ } if ((format == FFESTV_formatASTERISK) || (format == FFESTV_formatNAMELIST)) { spec2 = FFESTP_readixFORMAT; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw_or_val_present) { spec2 = FFESTP_readixADVANCE; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixEND].kw_or_val_present) { spec2 = FFESTP_readixEND; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixNULLS].kw_or_val_present) { spec2 = FFESTP_readixNULLS; goto whine; /* :::::::::::::::::::: */ } } else if (key) { spec1 = keyn; if (unit == FFESTV_unitCHAREXPR) { spec2 = FFESTP_readixUNIT; goto whine; /* :::::::::::::::::::: */ } if ((format == FFESTV_formatASTERISK) || (format == FFESTV_formatNAMELIST)) { spec2 = FFESTP_readixFORMAT; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw_or_val_present) { spec2 = FFESTP_readixADVANCE; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixEND].kw_or_val_present) { spec2 = FFESTP_readixEND; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixEOR].kw_or_val_present) { spec2 = FFESTP_readixEOR; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixNULLS].kw_or_val_present) { spec2 = FFESTP_readixNULLS; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixREC].kw_or_val_present) { spec2 = FFESTP_readixREC; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixSIZE].kw_or_val_present) { spec2 = FFESTP_readixSIZE; goto whine; /* :::::::::::::::::::: */ } } else { /* Sequential/Internal. */ if (unit == FFESTV_unitCHAREXPR) { /* Internal file. */ spec1 = FFESTP_readixUNIT; if (format == FFESTV_formatNAMELIST) { spec2 = FFESTP_readixFORMAT; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw_or_val_present) { spec2 = FFESTP_readixADVANCE; goto whine; /* :::::::::::::::::::: */ } } if (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw_or_val_present) { /* ADVANCE= specified. */ spec1 = FFESTP_readixADVANCE; if (format == FFESTV_formatNONE) { ffebad_start (FFEBAD_MISSING_FORMAT_SPEC); ffebad_here (0, ffelex_token_where_line (ffestp_file.read.read_spec[spec1].kw), ffelex_token_where_column (ffestp_file.read.read_spec[spec1].kw)); ffebad_finish (); ffestc_ok_ = FALSE; return; } if (format == FFESTV_formatNAMELIST) { spec2 = FFESTP_readixFORMAT; goto whine; /* :::::::::::::::::::: */ } } if (ffestp_file.read.read_spec[FFESTP_readixEOR].kw_or_val_present) { /* EOR= specified. */ spec1 = FFESTP_readixEOR; if (ffestc_subr_speccmp_ ("No", &ffestp_file.read.read_spec[FFESTP_readixADVANCE], NULL, NULL) != 0) { goto whine_advance; /* :::::::::::::::::::: */ } } if (ffestp_file.read.read_spec[FFESTP_readixNULLS].kw_or_val_present) { /* NULLS= specified. */ spec1 = FFESTP_readixNULLS; if (format != FFESTV_formatASTERISK) { spec2 = FFESTP_readixFORMAT; goto whine; /* :::::::::::::::::::: */ } } if (ffestp_file.read.read_spec[FFESTP_readixSIZE].kw_or_val_present) { /* SIZE= specified. */ spec1 = FFESTP_readixSIZE; if (ffestc_subr_speccmp_ ("No", &ffestp_file.read.read_spec[FFESTP_readixADVANCE], NULL, NULL) != 0) { whine_advance: /* :::::::::::::::::::: */ if (ffestp_file.read.read_spec[FFESTP_readixADVANCE] .kw_or_val_present) { ffebad_start (FFEBAD_CONFLICTING_SPECS); ffebad_here (0, ffelex_token_where_line (ffestp_file.read.read_spec[spec1].kw), ffelex_token_where_column (ffestp_file.read.read_spec[spec1].kw)); ffebad_here (1, ffelex_token_where_line (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw), ffelex_token_where_column (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw)); ffebad_finish (); } else { ffebad_start (FFEBAD_MISSING_ADVANCE_SPEC); ffebad_here (0, ffelex_token_where_line (ffestp_file.read.read_spec[spec1].kw), ffelex_token_where_column (ffestp_file.read.read_spec[spec1].kw)); ffebad_finish (); } ffestc_ok_ = FALSE; return; } } } if (unit == FFESTV_unitCHAREXPR) ffestc_iolist_context_ = FFEEXPR_contextIOLISTDF; else ffestc_iolist_context_ = FFEEXPR_contextIOLIST; ffestd_R909_start (FALSE, unit, format, rec, key); ffestc_ok_ = TRUE; } /* ffestc_R909_item -- READ statement i/o item ffestc_R909_item(expr,expr_token); Implement output-list expression. */ void ffestc_R909_item (ffebld expr, ffelexToken expr_token) { ffestc_check_item_ (); if (!ffestc_ok_) return; if (ffestc_namelist_ != 0) { if (ffestc_namelist_ == 1) { ffestc_namelist_ = 2; ffebad_start (FFEBAD_NAMELIST_ITEMS); ffebad_here (0, ffelex_token_where_line (expr_token), ffelex_token_where_column (expr_token)); ffebad_finish (); } return; } ffestd_R909_item (expr, expr_token); } /* ffestc_R909_finish -- READ statement list complete ffestc_R909_finish(); Just wrap up any local activities. */ void ffestc_R909_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R909_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R910_start -- WRITE(...) statement list begin ffestc_R910_start(); Verify that WRITE is valid here, and begin accepting items in the list. */ void ffestc_R910_start () { ffestvUnit unit; ffestvFormat format; bool rec; ffestpWriteIx spec1; ffestpWriteIx spec2; ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); if (!ffestc_subr_is_branch_ (&ffestp_file.write.write_spec[FFESTP_writeixEOR]) || !ffestc_subr_is_branch_ (&ffestp_file.write.write_spec[FFESTP_writeixERR]) || !ffestc_subr_is_format_ (&ffestp_file.write.write_spec[FFESTP_writeixFORMAT])) { ffestc_ok_ = FALSE; return; } format = ffestc_subr_format_ (&ffestp_file.write.write_spec[FFESTP_writeixFORMAT]); ffestc_namelist_ = (format == FFESTV_formatNAMELIST); unit = ffestc_subr_unit_ (&ffestp_file.write.write_spec[FFESTP_writeixUNIT]); if (unit == FFESTV_unitNONE) { ffebad_start (FFEBAD_NO_UNIT_SPEC); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); ffestc_ok_ = FALSE; return; } rec = ffestp_file.write.write_spec[FFESTP_writeixREC].kw_or_val_present; if (rec) { spec1 = FFESTP_writeixREC; if (unit == FFESTV_unitCHAREXPR) { spec2 = FFESTP_writeixUNIT; whine: /* :::::::::::::::::::: */ ffebad_start (FFEBAD_CONFLICTING_SPECS); assert (ffestp_file.write.write_spec[spec1].kw_or_val_present); if (ffestp_file.write.write_spec[spec1].kw_present) { ffebad_here (0, ffelex_token_where_line (ffestp_file.write.write_spec[spec1].kw), ffelex_token_where_column (ffestp_file.write.write_spec[spec1].kw)); } else { ffebad_here (0, ffelex_token_where_line (ffestp_file.write.write_spec[spec1].value), ffelex_token_where_column (ffestp_file.write.write_spec[spec1].value)); } assert (ffestp_file.write.write_spec[spec2].kw_or_val_present); if (ffestp_file.write.write_spec[spec2].kw_present) { ffebad_here (1, ffelex_token_where_line (ffestp_file.write.write_spec[spec2].kw), ffelex_token_where_column (ffestp_file.write.write_spec[spec2].kw)); } else { ffebad_here (1, ffelex_token_where_line (ffestp_file.write.write_spec[spec2].value), ffelex_token_where_column (ffestp_file.write.write_spec[spec2].value)); } ffebad_finish (); ffestc_ok_ = FALSE; return; } if ((format == FFESTV_formatASTERISK) || (format == FFESTV_formatNAMELIST)) { spec2 = FFESTP_writeixFORMAT; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw_or_val_present) { spec2 = FFESTP_writeixADVANCE; goto whine; /* :::::::::::::::::::: */ } } else { /* Sequential/Indexed/Internal. */ if (unit == FFESTV_unitCHAREXPR) { /* Internal file. */ spec1 = FFESTP_writeixUNIT; if (format == FFESTV_formatNAMELIST) { spec2 = FFESTP_writeixFORMAT; goto whine; /* :::::::::::::::::::: */ } if (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw_or_val_present) { spec2 = FFESTP_writeixADVANCE; goto whine; /* :::::::::::::::::::: */ } } if (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw_or_val_present) { /* ADVANCE= specified. */ spec1 = FFESTP_writeixADVANCE; if (format == FFESTV_formatNONE) { ffebad_start (FFEBAD_MISSING_FORMAT_SPEC); ffebad_here (0, ffelex_token_where_line (ffestp_file.write.write_spec[spec1].kw), ffelex_token_where_column (ffestp_file.write.write_spec[spec1].kw)); ffebad_finish (); ffestc_ok_ = FALSE; return; } if (format == FFESTV_formatNAMELIST) { spec2 = FFESTP_writeixFORMAT; goto whine; /* :::::::::::::::::::: */ } } if (ffestp_file.write.write_spec[FFESTP_writeixEOR].kw_or_val_present) { /* EOR= specified. */ spec1 = FFESTP_writeixEOR; if (ffestc_subr_speccmp_ ("No", &ffestp_file.write.write_spec[FFESTP_writeixADVANCE], NULL, NULL) != 0) { if (ffestp_file.write.write_spec[FFESTP_writeixADVANCE] .kw_or_val_present) { ffebad_start (FFEBAD_CONFLICTING_SPECS); ffebad_here (0, ffelex_token_where_line (ffestp_file.write.write_spec[spec1].kw), ffelex_token_where_column (ffestp_file.write.write_spec[spec1].kw)); ffebad_here (1, ffelex_token_where_line (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw), ffelex_token_where_column (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw)); ffebad_finish (); } else { ffebad_start (FFEBAD_MISSING_ADVANCE_SPEC); ffebad_here (0, ffelex_token_where_line (ffestp_file.write.write_spec[spec1].kw), ffelex_token_where_column (ffestp_file.write.write_spec[spec1].kw)); ffebad_finish (); } ffestc_ok_ = FALSE; return; } } } if (unit == FFESTV_unitCHAREXPR) ffestc_iolist_context_ = FFEEXPR_contextIOLISTDF; else ffestc_iolist_context_ = FFEEXPR_contextIOLIST; ffestd_R910_start (unit, format, rec); ffestc_ok_ = TRUE; } /* ffestc_R910_item -- WRITE statement i/o item ffestc_R910_item(expr,expr_token); Implement output-list expression. */ void ffestc_R910_item (ffebld expr, ffelexToken expr_token) { ffestc_check_item_ (); if (!ffestc_ok_) return; if (ffestc_namelist_ != 0) { if (ffestc_namelist_ == 1) { ffestc_namelist_ = 2; ffebad_start (FFEBAD_NAMELIST_ITEMS); ffebad_here (0, ffelex_token_where_line (expr_token), ffelex_token_where_column (expr_token)); ffebad_finish (); } return; } ffestd_R910_item (expr, expr_token); } /* ffestc_R910_finish -- WRITE statement list complete ffestc_R910_finish(); Just wrap up any local activities. */ void ffestc_R910_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R910_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R911_start -- PRINT(...) statement list begin ffestc_R911_start(); Verify that PRINT is valid here, and begin accepting items in the list. */ void ffestc_R911_start () { ffestvFormat format; ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); if (!ffestc_subr_is_format_ (&ffestp_file.print.print_spec[FFESTP_printixFORMAT])) { ffestc_ok_ = FALSE; return; } format = ffestc_subr_format_ (&ffestp_file.print.print_spec[FFESTP_printixFORMAT]); ffestc_namelist_ = (format == FFESTV_formatNAMELIST); ffestd_R911_start (format); ffestc_ok_ = TRUE; } /* ffestc_R911_item -- PRINT statement i/o item ffestc_R911_item(expr,expr_token); Implement output-list expression. */ void ffestc_R911_item (ffebld expr, ffelexToken expr_token) { ffestc_check_item_ (); if (!ffestc_ok_) return; if (ffestc_namelist_ != 0) { if (ffestc_namelist_ == 1) { ffestc_namelist_ = 2; ffebad_start (FFEBAD_NAMELIST_ITEMS); ffebad_here (0, ffelex_token_where_line (expr_token), ffelex_token_where_column (expr_token)); ffebad_finish (); } return; } ffestd_R911_item (expr, expr_token); } /* ffestc_R911_finish -- PRINT statement list complete ffestc_R911_finish(); Just wrap up any local activities. */ void ffestc_R911_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R911_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R919 -- BACKSPACE statement ffestc_R919(); Make sure a BACKSPACE is valid in the current context, and implement it. */ void ffestc_R919 () { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.beru.beru_spec[FFESTP_beruixERR]) && ffestc_subr_is_present_ ("UNIT", &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT])) ffestd_R919 (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R920 -- ENDFILE statement ffestc_R920(); Make sure a ENDFILE is valid in the current context, and implement it. */ void ffestc_R920 () { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.beru.beru_spec[FFESTP_beruixERR]) && ffestc_subr_is_present_ ("UNIT", &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT])) ffestd_R920 (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R921 -- REWIND statement ffestc_R921(); Make sure a REWIND is valid in the current context, and implement it. */ void ffestc_R921 () { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.beru.beru_spec[FFESTP_beruixERR]) && ffestc_subr_is_present_ ("UNIT", &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT])) ffestd_R921 (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R923A -- INQUIRE statement (non-IOLENGTH version) ffestc_R923A(); Make sure an INQUIRE is valid in the current context, and implement it. */ void ffestc_R923A () { bool by_file; bool by_unit; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.inquire.inquire_spec[FFESTP_inquireixERR])) { by_file = ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE] .kw_or_val_present; by_unit = ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT] .kw_or_val_present; if (by_file && by_unit) { ffebad_start (FFEBAD_CONFLICTING_SPECS); assert (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw_or_val_present); if (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw_present) { ffebad_here (0, ffelex_token_where_line (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw), ffelex_token_where_column (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw)); } else { ffebad_here (0, ffelex_token_where_line (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].value), ffelex_token_where_column (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].value)); } assert (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].kw_or_val_present); if (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].kw_present) { ffebad_here (1, ffelex_token_where_line (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].kw), ffelex_token_where_column (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].kw)); } else { ffebad_here (1, ffelex_token_where_line (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].value), ffelex_token_where_column (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].value)); } ffebad_finish (); } else if (!by_file && !by_unit) { ffebad_start (FFEBAD_MISSING_SPECIFIER); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_string ("UNIT= or FILE="); ffebad_finish (); } else ffestd_R923A (by_file); } if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R923B_start -- INQUIRE(IOLENGTH=expr) statement list begin ffestc_R923B_start(); Verify that INQUIRE is valid here, and begin accepting items in the list. */ void ffestc_R923B_start () { ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); ffestd_R923B_start (); ffestc_ok_ = TRUE; } /* ffestc_R923B_item -- INQUIRE statement i/o item ffestc_R923B_item(expr,expr_token); Implement output-list expression. */ void ffestc_R923B_item (ffebld expr, ffelexToken expr_token UNUSED) { ffestc_check_item_ (); if (!ffestc_ok_) return; ffestd_R923B_item (expr); } /* ffestc_R923B_finish -- INQUIRE statement list complete ffestc_R923B_finish(); Just wrap up any local activities. */ void ffestc_R923B_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R923B_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R1001 -- FORMAT statement ffestc_R1001(format_list); Make sure format_list is valid. Update label's info to indicate it is a FORMAT label, and (perhaps) warn if there is no label! */ void ffestc_R1001 (ffesttFormatList f) { ffestc_check_simple_ (); if (ffestc_order_format_ () != FFESTC_orderOK_) return; ffestc_labeldef_format_ (); ffestd_R1001 (f); } /* ffestc_R1102 -- PROGRAM statement ffestc_R1102(name_token); Make sure ffestc_kind_ identifies an empty block. Make sure name_token gives a valid name. Implement the beginning of a main program. */ void ffestc_R1102 (ffelexToken name) { ffestw b; ffesymbol s; assert (name != NULL); ffestc_check_simple_ (); if (ffestc_order_unit_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestc_blocknum_ = 0; b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_statePROGRAM0); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_end_program_); ffestw_set_name (b, ffelex_token_use (name)); s = ffesymbol_declare_programunit (name, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindPROGRAM, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); ffesymbol_signal_unreported (s); } else ffesymbol_error (s, name); ffestd_R1102 (s, name); } /* ffestc_R1103 -- END PROGRAM statement ffestc_R1103(name_token); Make sure ffestc_kind_ identifies the current kind of program unit. If not NULL, make sure name_token gives the correct name. Implement the end of the current program unit. */ void ffestc_R1103 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_program_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); if (name != NULL) { if (ffestw_name (ffestw_stack_top ()) == NULL) { ffebad_start (FFEBAD_PROGRAM_NOT_NAMED); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) { ffebad_start (FFEBAD_UNIT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } } ffestc_shriek_end_program_ (TRUE); } /* ffestc_R1105 -- MODULE statement ffestc_R1105(name_token); Make sure ffestc_kind_ identifies an empty block. Make sure name_token gives a valid name. Implement the beginning of a module. */ #if FFESTR_F90 void ffestc_R1105 (ffelexToken name) { ffestw b; assert (name != NULL); ffestc_check_simple_ (); if (ffestc_order_unit_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestc_blocknum_ = 0; b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateMODULE0); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_module_); ffestw_set_name (b, ffelex_token_use (name)); ffestd_R1105 (name); } /* ffestc_R1106 -- END MODULE statement ffestc_R1106(name_token); Make sure ffestc_kind_ identifies the current kind of program unit. If not NULL, make sure name_token gives the correct name. Implement the end of the current program unit. */ void ffestc_R1106 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_module_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if ((name != NULL) && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0)) { ffebad_start (FFEBAD_UNIT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } ffestc_shriek_module_ (TRUE); } /* ffestc_R1107_start -- USE statement list begin ffestc_R1107_start(); Verify that USE is valid here, and begin accepting items in the list. */ void ffestc_R1107_start (ffelexToken name, bool only) { ffestc_check_start_ (); if (ffestc_order_use_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R1107_start (name, only); ffestc_ok_ = TRUE; } /* ffestc_R1107_item -- USE statement for name ffestc_R1107_item(local_token,use_token); Make sure name_token identifies a valid object to be USEed. local_token may be NULL if _start_ was called with only==TRUE. */ void ffestc_R1107_item (ffelexToken local, ffelexToken use) { ffestc_check_item_ (); assert (use != NULL); if (!ffestc_ok_) return; ffestd_R1107_item (local, use); } /* ffestc_R1107_finish -- USE statement list complete ffestc_R1107_finish(); Just wrap up any local activities. */ void ffestc_R1107_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R1107_finish (); } #endif /* ffestc_R1111 -- BLOCK DATA statement ffestc_R1111(name_token); Make sure ffestc_kind_ identifies no current program unit. If not NULL, make sure name_token gives a valid name. Implement the beginning of a block data program unit. */ void ffestc_R1111 (ffelexToken name) { ffestw b; ffesymbol s; ffestc_check_simple_ (); if (ffestc_order_unit_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestc_blocknum_ = 0; b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateBLOCKDATA0); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_blockdata_); if (name == NULL) ffestw_set_name (b, NULL); else ffestw_set_name (b, ffelex_token_use (name)); s = ffesymbol_declare_blockdataunit (name, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindBLOCKDATA, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); ffesymbol_signal_unreported (s); } else ffesymbol_error (s, name); ffestd_R1111 (s, name); } /* ffestc_R1112 -- END BLOCK DATA statement ffestc_R1112(name_token); Make sure ffestc_kind_ identifies the current kind of program unit. If not NULL, make sure name_token gives the correct name. Implement the end of the current program unit. */ void ffestc_R1112 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_blockdata_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (name != NULL) { if (ffestw_name (ffestw_stack_top ()) == NULL) { ffebad_start (FFEBAD_BLOCKDATA_NOT_NAMED); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) { ffebad_start (FFEBAD_UNIT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } } ffestc_shriek_blockdata_ (TRUE); } /* ffestc_R1202 -- INTERFACE statement ffestc_R1202(operator,defined_name); Make sure ffestc_kind_ identifies an INTERFACE block. Implement the end of the current interface. 15-May-90 JCB 1.1 Allow no operator or name to mean INTERFACE by itself; missed this valid form when originally doing syntactic analysis code. */ #if FFESTR_F90 void ffestc_R1202 (ffestpDefinedOperator operator, ffelexToken name) { ffestw b; ffestc_check_simple_ (); if (ffestc_order_interfacespec_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateINTERFACE0); ffestw_set_blocknum (b, 0); ffestw_set_shriek (b, ffestc_shriek_interface_); if ((operator == FFESTP_definedoperatorNone) && (name == NULL)) ffestw_set_substate (b, 0); /* No generic-spec, so disallow MODULE PROCEDURE. */ else ffestw_set_substate (b, 1); /* MODULE PROCEDURE ok. */ ffestd_R1202 (operator, name); ffe_init_4 (); } /* ffestc_R1203 -- END INTERFACE statement ffestc_R1203(); Make sure ffestc_kind_ identifies an INTERFACE block. Implement the end of the current interface. */ void ffestc_R1203 () { ffestc_check_simple_ (); if (ffestc_order_interface_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestc_shriek_interface_ (TRUE); ffe_terminate_4 (); } /* ffestc_R1205_start -- MODULE PROCEDURE statement list begin ffestc_R1205_start(); Verify that MODULE PROCEDURE is valid here, and begin accepting items in the list. */ void ffestc_R1205_start () { ffestc_check_start_ (); if (ffestc_order_interface_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) == 0) { ffebad_start (FFEBAD_INVALID_MODULE_PROCEDURE); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); ffestc_ok_ = FALSE; return; } if (ffestw_state (ffestw_stack_top ()) == FFESTV_stateINTERFACE0) { ffestw_update (NULL); /* Update state line/col info. */ ffestw_set_state (ffestw_stack_top (), FFESTV_stateINTERFACE1); } ffestd_R1205_start (); ffestc_ok_ = TRUE; } /* ffestc_R1205_item -- MODULE PROCEDURE statement for name ffestc_R1205_item(name_token); Make sure name_token identifies a valid object to be MODULE PROCEDUREed. */ void ffestc_R1205_item (ffelexToken name) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffestd_R1205_item (name); } /* ffestc_R1205_finish -- MODULE PROCEDURE statement list complete ffestc_R1205_finish(); Just wrap up any local activities. */ void ffestc_R1205_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R1205_finish (); } #endif /* ffestc_R1207_start -- EXTERNAL statement list begin ffestc_R1207_start(); Verify that EXTERNAL is valid here, and begin accepting items in the list. */ void ffestc_R1207_start () { ffestc_check_start_ (); if (ffestc_order_progspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R1207_start (); ffestc_ok_ = TRUE; } /* ffestc_R1207_item -- EXTERNAL statement for name ffestc_R1207_item(name_token); Make sure name_token identifies a valid object to be EXTERNALd. */ void ffestc_R1207_item (ffelexToken name) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; s = ffesymbol_declare_local (name, FALSE); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (s)) na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ else if (sa & FFESYMBOL_attrsANY) na = FFESYMBOL_attrsANY; else if (!(sa & ~(FFESYMBOL_attrsDUMMY | FFESYMBOL_attrsTYPE))) na = sa | FFESYMBOL_attrsEXTERNAL; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, name); else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_set_explicitwhere (s, TRUE); ffesymbol_reference (s, name, FALSE); ffesymbol_signal_unreported (s); } ffestd_R1207_item (name); } /* ffestc_R1207_finish -- EXTERNAL statement list complete ffestc_R1207_finish(); Just wrap up any local activities. */ void ffestc_R1207_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R1207_finish (); } /* ffestc_R1208_start -- INTRINSIC statement list begin ffestc_R1208_start(); Verify that INTRINSIC is valid here, and begin accepting items in the list. */ void ffestc_R1208_start () { ffestc_check_start_ (); if (ffestc_order_progspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_R1208_start (); ffestc_ok_ = TRUE; } /* ffestc_R1208_item -- INTRINSIC statement for name ffestc_R1208_item(name_token); Make sure name_token identifies a valid object to be INTRINSICd. */ void ffestc_R1208_item (ffelexToken name) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffeintrinGen gen; ffeintrinSpec spec; ffeintrinImp imp; ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; s = ffesymbol_declare_local (name, TRUE); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (s)) na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ else if (sa & FFESYMBOL_attrsANY) na = sa; else if (!(sa & ~FFESYMBOL_attrsTYPE)) { if (ffeintrin_is_intrinsic (ffelex_token_text (name), name, TRUE, &gen, &spec, &imp) && ((imp == FFEINTRIN_impNONE) #if 0 /* Don't bother with this for now. */ || ((ffeintrin_basictype (spec) == ffesymbol_basictype (s)) && (ffeintrin_kindtype (spec) == ffesymbol_kindtype (s))) #else || 1 #endif || !(sa & FFESYMBOL_attrsTYPE))) na = sa | FFESYMBOL_attrsINTRINSIC; else na = FFESYMBOL_attrsetNONE; } else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) ffesymbol_error (s, name); else if (!(na & FFESYMBOL_attrsANY)) { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_generic (s, gen); ffesymbol_set_specific (s, spec); ffesymbol_set_implementation (s, imp); ffesymbol_set_info (s, ffeinfo_new (ffesymbol_basictype (s), ffesymbol_kindtype (s), 0, FFEINFO_kindNONE, FFEINFO_whereINTRINSIC, ffesymbol_size (s))); ffesymbol_set_explicitwhere (s, TRUE); ffesymbol_reference (s, name, TRUE); } ffesymbol_signal_unreported (s); ffestd_R1208_item (name); } /* ffestc_R1208_finish -- INTRINSIC statement list complete ffestc_R1208_finish(); Just wrap up any local activities. */ void ffestc_R1208_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_R1208_finish (); } /* ffestc_R1212 -- CALL statement ffestc_R1212(expr,expr_token); Make sure statement is valid here; implement. */ void ffestc_R1212 (ffebld expr, ffelexToken expr_token UNUSED) { ffebld item; /* ITEM. */ ffebld labexpr; /* LABTOK=>LABTER. */ ffelab label; bool ok; /* TRUE if all LABTOKs were ok. */ bool ok1; /* TRUE if a particular LABTOK is ok. */ ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffebld_op (expr) != FFEBLD_opSUBRREF) ffestd_R841 (FALSE); /* CONTINUE. */ else { ok = TRUE; for (item = ffebld_right (expr); item != NULL; item = ffebld_trail (item)) { if (((labexpr = ffebld_head (item)) != NULL) && (ffebld_op (labexpr) == FFEBLD_opLABTOK)) { ok1 = ffestc_labelref_is_branch_ (ffebld_labtok (labexpr), &label); ffelex_token_kill (ffebld_labtok (labexpr)); if (!ok1) { label = NULL; ok = FALSE; } ffebld_set_op (labexpr, FFEBLD_opLABTER); ffebld_set_labter (labexpr, label); } } if (ok) ffestd_R1212 (expr); } if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_R1213 -- Defined assignment statement ffestc_R1213(dest_expr,source_expr,source_token); Make sure the assignment is valid. */ #if FFESTR_F90 void ffestc_R1213 (ffebld dest, ffebld source, ffelexToken source_token) { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); ffestd_R1213 (dest, source); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } #endif /* ffestc_R1219 -- FUNCTION statement ffestc_R1219(funcname,arglist,ending_token,kind,kindt,len,lent, recursive); Make sure statement is valid here, register arguments for the function name, and so on. 06-Apr-90 JCB 2.0 Added the kind, len, and recursive arguments. */ void ffestc_R1219 (ffelexToken funcname, ffesttTokenList args, ffelexToken final UNUSED, ffestpType type, ffebld kind, ffelexToken kindt, ffebld len, ffelexToken lent, ffelexToken recursive, ffelexToken result) { ffestw b; ffesymbol s; ffesymbol fs; /* FUNCTION symbol when dealing with RESULT symbol. */ ffesymbolAttrs sa; ffesymbolAttrs na; ffelexToken res; bool separate_result; assert ((funcname != NULL) && (ffelex_token_type (funcname) == FFELEX_typeNAME)); ffestc_check_simple_ (); if (ffestc_order_iface_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestc_blocknum_ = 0; ffesta_is_entry_valid = (ffestw_state (ffestw_stack_top ()) == FFESTV_stateNIL); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateFUNCTION0); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_function_); ffestw_set_name (b, ffelex_token_use (funcname)); if (type == FFESTP_typeNone) { ffestc_local_.decl.basic_type = FFEINFO_basictypeNONE; ffestc_local_.decl.kind_type = FFEINFO_kindtypeNONE; ffestc_local_.decl.size = FFETARGET_charactersizeNONE; } else { ffestc_establish_declstmt_ (type, ffesta_tokens[0], kind, kindt, len, lent); ffestc_establish_declinfo_ (NULL, NULL, NULL, NULL); } separate_result = (result != NULL) && (ffelex_token_strcmp (funcname, result) != 0); if (separate_result) fs = ffesymbol_declare_funcnotresunit (funcname); /* Global/local. */ else fs = ffesymbol_declare_funcunit (funcname); /* Global only. */ if (ffesymbol_state (fs) == FFESYMBOL_stateNONE) { ffesymbol_set_state (fs, FFESYMBOL_stateUNDERSTOOD); ffesymbol_signal_unreported (fs); /* Note that .basic_type and .kind_type might be NONE here. */ ffesymbol_set_info (fs, ffeinfo_new (ffestc_local_.decl.basic_type, ffestc_local_.decl.kind_type, 0, FFEINFO_kindFUNCTION, FFEINFO_whereLOCAL, ffestc_local_.decl.size)); /* Check whether the type info fits the filewide expectations; set ok flag accordingly. */ ffesymbol_reference (fs, funcname, FALSE); if (ffesymbol_attrs (fs) & FFESYMBOL_attrsANY) ffestc_parent_ok_ = FALSE; else ffestc_parent_ok_ = TRUE; } else { if (ffesymbol_kind (fs) != FFEINFO_kindANY) ffesymbol_error (fs, funcname); ffestc_parent_ok_ = FALSE; } if (ffestc_parent_ok_) { ffebld_init_list (&fs->dummy_args, &ffestc_local_.dummy.list_bottom); ffestt_tokenlist_drive (args, ffestc_promote_dummy_); ffebld_end_list (&ffestc_local_.dummy.list_bottom); } if (result == NULL) res = funcname; else res = result; s = ffesymbol_declare_funcresult (res); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (sa & FFESYMBOL_attrsANY) na = FFESYMBOL_attrsANY; else if (ffesymbol_state (s) != FFESYMBOL_stateNONE) na = FFESYMBOL_attrsetNONE; else { na = FFESYMBOL_attrsRESULT; if (ffestc_local_.decl.basic_type != FFEINFO_basictypeNONE) { na |= FFESYMBOL_attrsTYPE; if ((ffestc_local_.decl.basic_type == FFEINFO_basictypeCHARACTER) && (ffestc_local_.decl.size == FFETARGET_charactersizeNONE)) na |= FFESYMBOL_attrsANYLEN; } } /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if ((na & ~FFESYMBOL_attrsANY) == FFESYMBOL_attrsetNONE) { if (!(na & FFESYMBOL_attrsANY)) ffesymbol_error (s, res); ffesymbol_set_funcresult (fs, NULL); ffesymbol_set_funcresult (s, NULL); ffestc_parent_ok_ = FALSE; } else { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateSEEN); ffesymbol_set_funcresult (fs, s); ffesymbol_set_funcresult (s, fs); if (ffestc_local_.decl.basic_type != FFEINFO_basictypeNONE) { ffesymbol_set_info (s, ffeinfo_new (ffestc_local_.decl.basic_type, ffestc_local_.decl.kind_type, 0, FFEINFO_kindNONE, FFEINFO_whereNONE, ffestc_local_.decl.size)); } } ffesymbol_signal_unreported (fs); ffestd_R1219 (fs, funcname, args, type, kind, kindt, len, lent, (recursive != NULL), result, separate_result); } /* ffestc_R1221 -- END FUNCTION statement ffestc_R1221(name_token); Make sure ffestc_kind_ identifies the current kind of program unit. If not NULL, make sure name_token gives the correct name. Implement the end of the current program unit. */ void ffestc_R1221 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_function_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); if ((name != NULL) && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0)) { ffebad_start (FFEBAD_UNIT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } ffestc_shriek_function_ (TRUE); } /* ffestc_R1223 -- SUBROUTINE statement ffestc_R1223(subrname,arglist,ending_token,recursive_token); Make sure statement is valid here, register arguments for the subroutine name, and so on. 06-Apr-90 JCB 2.0 Added the recursive argument. */ void ffestc_R1223 (ffelexToken subrname, ffesttTokenList args, ffelexToken final, ffelexToken recursive) { ffestw b; ffesymbol s; assert ((subrname != NULL) && (ffelex_token_type (subrname) == FFELEX_typeNAME)); ffestc_check_simple_ (); if (ffestc_order_iface_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestc_blocknum_ = 0; ffesta_is_entry_valid = (ffestw_state (ffestw_stack_top ()) == FFESTV_stateNIL); b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateSUBROUTINE0); ffestw_set_blocknum (b, ffestc_blocknum_++); ffestw_set_shriek (b, ffestc_shriek_subroutine_); ffestw_set_name (b, ffelex_token_use (subrname)); s = ffesymbol_declare_subrunit (subrname); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindSUBROUTINE, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); ffestc_parent_ok_ = TRUE; } else { if (ffesymbol_kind (s) != FFEINFO_kindANY) ffesymbol_error (s, subrname); ffestc_parent_ok_ = FALSE; } if (ffestc_parent_ok_) { ffebld_init_list (&s->dummy_args, &ffestc_local_.dummy.list_bottom); ffestt_tokenlist_drive (args, ffestc_promote_dummy_); ffebld_end_list (&ffestc_local_.dummy.list_bottom); } ffesymbol_signal_unreported (s); ffestd_R1223 (s, subrname, args, final, (recursive != NULL)); } /* ffestc_R1225 -- END SUBROUTINE statement ffestc_R1225(name_token); Make sure ffestc_kind_ identifies the current kind of program unit. If not NULL, make sure name_token gives the correct name. Implement the end of the current program unit. */ void ffestc_R1225 (ffelexToken name) { ffestc_check_simple_ (); if (ffestc_order_subroutine_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_ (); if ((name != NULL) && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0)) { ffebad_start (FFEBAD_UNIT_WRONG_NAME); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); ffebad_finish (); } ffestc_shriek_subroutine_ (TRUE); } /* ffestc_R1226 -- ENTRY statement ffestc_R1226(entryname,arglist,ending_token); Make sure we're in a SUBROUTINE or FUNCTION, register arguments for the entry point name, and so on. */ void ffestc_R1226 (ffelexToken entryname, ffesttTokenList args, ffelexToken final UNUSED) { ffesymbol s; ffesymbol fs; ffesymbolAttrs sa; ffesymbolAttrs na; bool in_spec; /* TRUE if further specification statements may follow, FALSE if executable stmts. */ bool in_func; /* TRUE if ENTRY is a FUNCTION, not SUBROUTINE. */ assert ((entryname != NULL) && (ffelex_token_type (entryname) == FFELEX_typeNAME)); ffestc_check_simple_ (); if (ffestc_order_entry_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateFUNCTION1: case FFESTV_stateFUNCTION2: case FFESTV_stateFUNCTION3: in_func = TRUE; in_spec = TRUE; break; case FFESTV_stateFUNCTION4: in_func = TRUE; in_spec = FALSE; break; case FFESTV_stateSUBROUTINE1: case FFESTV_stateSUBROUTINE2: case FFESTV_stateSUBROUTINE3: in_func = FALSE; in_spec = TRUE; break; case FFESTV_stateSUBROUTINE4: in_func = FALSE; in_spec = FALSE; break; default: assert ("ENTRY not in FUNCTION or SUBROUTINE?" == NULL); in_func = FALSE; in_spec = FALSE; break; } if (in_func) fs = ffesymbol_declare_funcunit (entryname); else fs = ffesymbol_declare_subrunit (entryname); if (ffesymbol_state (fs) == FFESYMBOL_stateNONE) ffesymbol_set_state (fs, FFESYMBOL_stateUNDERSTOOD); else { if (ffesymbol_kind (fs) != FFEINFO_kindANY) ffesymbol_error (fs, entryname); } ++ffestc_entry_num_; ffebld_init_list (&fs->dummy_args, &ffestc_local_.dummy.list_bottom); if (in_spec) ffestt_tokenlist_drive (args, ffestc_promote_dummy_); else ffestt_tokenlist_drive (args, ffestc_promote_execdummy_); ffebld_end_list (&ffestc_local_.dummy.list_bottom); if (in_func) { s = ffesymbol_declare_funcresult (entryname); ffesymbol_set_funcresult (fs, s); ffesymbol_set_funcresult (s, fs); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) na = FFESYMBOL_attrsetNONE; else if (sa & FFESYMBOL_attrsANY) na = FFESYMBOL_attrsANY; else if (!(sa & ~(FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsTYPE))) na = sa | FFESYMBOL_attrsRESULT; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) { ffesymbol_error (s, entryname); ffestc_parent_ok_ = FALSE; } else if (na & FFESYMBOL_attrsANY) { ffestc_parent_ok_ = FALSE; } else { ffesymbol_set_attrs (s, na); if (ffesymbol_state (s) == FFESYMBOL_stateNONE) ffesymbol_set_state (s, FFESYMBOL_stateSEEN); else if (ffesymbol_state (s) == FFESYMBOL_stateUNCERTAIN) { ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); ffesymbol_set_info (s, ffeinfo_new (ffesymbol_basictype (s), ffesymbol_kindtype (s), 0, FFEINFO_kindENTITY, FFEINFO_whereRESULT, ffesymbol_size (s))); ffesymbol_resolve_intrin (s); ffestorag_exec_layout (s); } } /* Since ENTRY might appear after executable stmts, do what would have been done if it hadn't -- give symbol implicit type and exec-transition it. */ if (!in_spec && ffesymbol_is_specable (s)) { if (!ffeimplic_establish_symbol (s)) /* Do implicit typing. */ ffesymbol_error (s, entryname); s = ffecom_sym_exec_transition (s); } /* Use whatever type info is available for ENTRY to set up type for its global-name-space function symbol relative. */ ffesymbol_set_info (fs, ffeinfo_new (ffesymbol_basictype (s), ffesymbol_kindtype (s), 0, FFEINFO_kindFUNCTION, FFEINFO_whereLOCAL, ffesymbol_size (s))); /* Check whether the type info fits the filewide expectations; set ok flag accordingly. */ ffesymbol_reference (fs, entryname, FALSE); /* ~~Question??: When ENTRY FOO() RESULT(IBAR) is supported, what will the typing be if FOO and IBAR would normally end up with different types? I think the answer is that FOO is always given whatever type would be chosen for IBAR, rather than the other way around, and I think it ends up working that way for FUNCTION FOO() RESULT(IBAR), but this should be checked out in all its different combos. Related question is, is there any way that FOO in either case ends up without type info filled in? Does anyone care? */ ffesymbol_signal_unreported (s); } else { ffesymbol_set_info (fs, ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindSUBROUTINE, FFEINFO_whereLOCAL, FFETARGET_charactersizeNONE)); } if (!in_spec) fs = ffecom_sym_exec_transition (fs); ffesymbol_signal_unreported (fs); ffestd_R1226 (fs); } /* ffestc_R1227 -- RETURN statement ffestc_R1227(expr,expr_token); Make sure statement is valid here; implement. expr and expr_token are both NULL if there was no expression. */ void ffestc_R1227 (ffebld expr, ffelexToken expr_token) { ffestw b; ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_notloop_begin_ (); for (b = ffestw_stack_top (); ; b = ffestw_previous (b)) { switch (ffestw_state (b)) { case FFESTV_statePROGRAM4: case FFESTV_stateSUBROUTINE4: case FFESTV_stateFUNCTION4: goto base; /* :::::::::::::::::::: */ case FFESTV_stateNIL: assert ("bad state" == NULL); break; default: break; } } base: switch (ffestw_state (b)) { case FFESTV_statePROGRAM4: if (ffe_is_pedantic ()) { ffebad_start (FFEBAD_RETURN_IN_MAIN); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); } if (expr != NULL) { ffebad_start (FFEBAD_ALTRETURN_IN_PROGRAM); ffebad_here (0, ffelex_token_where_line (expr_token), ffelex_token_where_column (expr_token)); ffebad_finish (); expr = NULL; } break; case FFESTV_stateSUBROUTINE4: break; case FFESTV_stateFUNCTION4: if (expr != NULL) { ffebad_start (FFEBAD_ALTRETURN_IN_FUNCTION); ffebad_here (0, ffelex_token_where_line (expr_token), ffelex_token_where_column (expr_token)); ffebad_finish (); expr = NULL; } break; default: assert ("bad state #2" == NULL); break; } ffestd_R1227 (expr); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); /* notloop's that are actionif's can be the target of a loop-end statement if they're in the "then" part of a logical IF, as in "DO 10", "10 IF (...) RETURN". */ ffestc_labeldef_branch_end_ (); } /* ffestc_R1228 -- CONTAINS statement ffestc_R1228(); */ #if FFESTR_F90 void ffestc_R1228 () { ffestc_check_simple_ (); if (ffestc_order_contains_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestd_R1228 (); ffe_terminate_3 (); ffe_init_3 (); } #endif /* ffestc_R1229_start -- STMTFUNCTION statement begin ffestc_R1229_start(func_name,func_arg_list,close_paren); Verify that STMTFUNCTION is valid here, establish func_arg_list in a new "live" scope within the current scope, and expect the actual expression (or NULL) in ffestc_R1229_finish. The reason there are two ffestc functions to handle this is so the scope can be established, allowing ffeexpr to assign proper characteristics to references to the dummy arguments. */ void ffestc_R1229_start (ffelexToken name, ffesttTokenList args, ffelexToken final UNUSED) { ffesymbol s; ffesymbolAttrs sa; ffesymbolAttrs na; ffestc_check_start_ (); if (ffestc_order_sfunc_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); assert (name != NULL); assert (args != NULL); s = ffesymbol_declare_local (name, FALSE); sa = ffesymbol_attrs (s); /* Figure out what kind of object we've got based on previous declarations of or references to the object. */ if (!ffesymbol_is_specable (s)) na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ else if (sa & FFESYMBOL_attrsANY) na = FFESYMBOL_attrsANY; else if (!(sa & ~FFESYMBOL_attrsTYPE)) na = sa | FFESYMBOL_attrsSFUNC; else na = FFESYMBOL_attrsetNONE; /* Now see what we've got for a new object: NONE means a new error cropped up; ANY means an old error to be ignored; otherwise, everything's ok, update the object (symbol) and continue on. */ if (na == FFESYMBOL_attrsetNONE) { ffesymbol_error (s, name); ffestc_parent_ok_ = FALSE; } else if (na & FFESYMBOL_attrsANY) ffestc_parent_ok_ = FALSE; else { ffesymbol_set_attrs (s, na); ffesymbol_set_state (s, FFESYMBOL_stateSEEN); if (!ffeimplic_establish_symbol (s) || ((ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER) && (ffesymbol_size (s) == FFETARGET_charactersizeNONE))) { ffesymbol_error (s, ffesta_tokens[0]); ffestc_parent_ok_ = FALSE; } else { /* Tell ffeexpr that sfunc def is in progress. */ ffesymbol_set_sfexpr (s, ffebld_new_any ()); ffebld_set_info (ffesymbol_sfexpr (s), ffeinfo_new_any ()); ffestc_parent_ok_ = TRUE; } } ffe_init_4 (); if (ffestc_parent_ok_) { ffebld_init_list (&s->dummy_args, &ffestc_local_.dummy.list_bottom); ffestc_sfdummy_argno_ = 0; ffestt_tokenlist_drive (args, ffestc_promote_sfdummy_); ffebld_end_list (&ffestc_local_.dummy.list_bottom); } ffestc_local_.sfunc.symbol = s; ffestd_R1229_start (name, args); ffestc_ok_ = TRUE; } /* ffestc_R1229_finish -- STMTFUNCTION statement list complete ffestc_R1229_finish(expr,expr_token); If expr is NULL, an error occurred parsing the expansion expression, so just cancel the effects of ffestc_R1229_start and pretend nothing happened. Otherwise, install the expression as the expansion for the statement function named in _start_, then clean up. */ void ffestc_R1229_finish (ffebld expr, ffelexToken expr_token) { ffestc_check_finish_ (); if (!ffestc_ok_) return; if (ffestc_parent_ok_ && (expr != NULL)) ffesymbol_set_sfexpr (ffestc_local_.sfunc.symbol, ffeexpr_convert_to_sym (expr, expr_token, ffestc_local_.sfunc.symbol, ffesta_tokens[0])); ffestd_R1229_finish (ffestc_local_.sfunc.symbol); ffesymbol_signal_unreported (ffestc_local_.sfunc.symbol); ffe_terminate_4 (); } /* ffestc_S3P4 -- INCLUDE line ffestc_S3P4(filename,filename_token); Make sure INCLUDE not preceded by any semicolons or a label def; implement. */ void ffestc_S3P4 (ffebld filename, ffelexToken filename_token UNUSED) { ffestc_check_simple_ (); ffestc_labeldef_invalid_ (); ffestd_S3P4 (filename); } /* ffestc_V003_start -- STRUCTURE statement list begin ffestc_V003_start(structure_name); Verify that STRUCTURE is valid here, and begin accepting items in the list. */ #if FFESTR_VXT void ffestc_V003_start (ffelexToken structure_name) { ffestw b; ffestc_check_start_ (); if (ffestc_order_vxtstructure_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateSTRUCTURE: case FFESTV_stateMAP: ffestc_local_.V003.list_state = 2; /* Require at least one field name. */ ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one member. */ break; default: ffestc_local_.V003.list_state = 0; /* No field names required. */ if (structure_name == NULL) { ffebad_start (FFEBAD_STRUCT_MISSING_NAME); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_finish (); } break; } b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateSTRUCTURE); ffestw_set_blocknum (b, 0); ffestw_set_shriek (b, ffestc_shriek_structure_); ffestw_set_substate (b, 0); /* No field-declarations seen yet. */ ffestd_V003_start (structure_name); ffestc_ok_ = TRUE; } /* ffestc_V003_item -- STRUCTURE statement for object-name ffestc_V003_item(name_token,dim_list); Make sure name_token identifies a valid object to be STRUCTUREd. */ void ffestc_V003_item (ffelexToken name, ffesttDimList dims) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; if (ffestc_local_.V003.list_state < 2) { if (ffestc_local_.V003.list_state == 0) { ffestc_local_.V003.list_state = 1; ffebad_start (FFEBAD_STRUCT_IGNORING_FIELD); ffebad_here (0, ffelex_token_where_line (name), ffelex_token_where_column (name)); ffebad_finish (); } return; } ffestc_local_.V003.list_state = 3; /* Have at least one field name. */ if (dims != NULL) ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); ffestd_V003_item (name, dims); } /* ffestc_V003_finish -- STRUCTURE statement list complete ffestc_V003_finish(); Just wrap up any local activities. */ void ffestc_V003_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; if (ffestc_local_.V003.list_state == 2) { ffebad_start (FFEBAD_STRUCT_MISSING_FIELD); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_previous (ffestw_stack_top ())), ffestw_col (ffestw_previous (ffestw_stack_top ()))); ffebad_finish (); } ffestd_V003_finish (); } /* ffestc_V004 -- END STRUCTURE statement ffestc_V004(); Make sure ffestc_kind_ identifies a STRUCTURE block. Implement the end of the current STRUCTURE block. */ void ffestc_V004 () { ffestc_check_simple_ (); if (ffestc_order_structure_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) != 1) { ffebad_start (FFEBAD_STRUCT_NO_COMPONENTS); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } ffestc_shriek_structure_ (TRUE); } /* ffestc_V009 -- UNION statement ffestc_V009(); */ void ffestc_V009 () { ffestw b; ffestc_check_simple_ (); if (ffestc_order_structure_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one member. */ b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateUNION); ffestw_set_blocknum (b, 0); ffestw_set_shriek (b, ffestc_shriek_union_); ffestw_set_substate (b, 0); /* No map decls seen yet. */ ffestd_V009 (); } /* ffestc_V010 -- END UNION statement ffestc_V010(); Make sure ffestc_kind_ identifies a UNION block. Implement the end of the current UNION block. */ void ffestc_V010 () { ffestc_check_simple_ (); if (ffestc_order_union_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) != 2) { ffebad_start (FFEBAD_UNION_NO_TWO_MAPS); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } ffestc_shriek_union_ (TRUE); } /* ffestc_V012 -- MAP statement ffestc_V012(); */ void ffestc_V012 () { ffestw b; ffestc_check_simple_ (); if (ffestc_order_union_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) != 2) ffestw_substate (ffestw_stack_top ())++; /* 0=>1, 1=>2. */ b = ffestw_update (ffestw_push (NULL)); ffestw_set_top_do (b, NULL); ffestw_set_state (b, FFESTV_stateMAP); ffestw_set_blocknum (b, 0); ffestw_set_shriek (b, ffestc_shriek_map_); ffestw_set_substate (b, 0); /* No field-declarations seen yet. */ ffestd_V012 (); } /* ffestc_V013 -- END MAP statement ffestc_V013(); Make sure ffestc_kind_ identifies a MAP block. Implement the end of the current MAP block. */ void ffestc_V013 () { ffestc_check_simple_ (); if (ffestc_order_map_ () != FFESTC_orderOK_) return; ffestc_labeldef_useless_ (); if (ffestw_substate (ffestw_stack_top ()) != 1) { ffebad_start (FFEBAD_MAP_NO_COMPONENTS); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); ffebad_finish (); } ffestc_shriek_map_ (TRUE); } #endif /* ffestc_V014_start -- VOLATILE statement list begin ffestc_V014_start(); Verify that VOLATILE is valid here, and begin accepting items in the list. */ void ffestc_V014_start () { ffestc_check_start_ (); if (ffestc_order_progspec_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_V014_start (); ffestc_ok_ = TRUE; } /* ffestc_V014_item_object -- VOLATILE statement for object-name ffestc_V014_item_object(name_token); Make sure name_token identifies a valid object to be VOLATILEd. */ void ffestc_V014_item_object (ffelexToken name) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffestd_V014_item_object (name); } /* ffestc_V014_item_cblock -- VOLATILE statement for common-block-name ffestc_V014_item_cblock(name_token); Make sure name_token identifies a valid common block to be VOLATILEd. */ void ffestc_V014_item_cblock (ffelexToken name) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffestd_V014_item_cblock (name); } /* ffestc_V014_finish -- VOLATILE statement list complete ffestc_V014_finish(); Just wrap up any local activities. */ void ffestc_V014_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V014_finish (); } /* ffestc_V016_start -- RECORD statement list begin ffestc_V016_start(); Verify that RECORD is valid here, and begin accepting items in the list. */ #if FFESTR_VXT void ffestc_V016_start () { ffestc_check_start_ (); if (ffestc_order_record_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); switch (ffestw_state (ffestw_stack_top ())) { case FFESTV_stateSTRUCTURE: case FFESTV_stateMAP: ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one member. */ break; default: break; } ffestd_V016_start (); ffestc_ok_ = TRUE; } /* ffestc_V016_item_structure -- RECORD statement for common-block-name ffestc_V016_item_structure(name_token); Make sure name_token identifies a valid structure to be RECORDed. */ void ffestc_V016_item_structure (ffelexToken name) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; ffestd_V016_item_structure (name); } /* ffestc_V016_item_object -- RECORD statement for object-name ffestc_V016_item_object(name_token,dim_list); Make sure name_token identifies a valid object to be RECORDd. */ void ffestc_V016_item_object (ffelexToken name, ffesttDimList dims) { ffestc_check_item_ (); assert (name != NULL); if (!ffestc_ok_) return; if (dims != NULL) ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); ffestd_V016_item_object (name, dims); } /* ffestc_V016_finish -- RECORD statement list complete ffestc_V016_finish(); Just wrap up any local activities. */ void ffestc_V016_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V016_finish (); } /* ffestc_V018_start -- REWRITE(...) statement list begin ffestc_V018_start(); Verify that REWRITE is valid here, and begin accepting items in the list. */ void ffestc_V018_start () { ffestvFormat format; ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); if (!ffestc_subr_is_branch_ (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixERR]) || !ffestc_subr_is_format_ (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT]) || !ffestc_subr_is_present_ ("UNIT", &ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT])) { ffestc_ok_ = FALSE; return; } format = ffestc_subr_format_ (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT]); switch (format) { case FFESTV_formatNAMELIST: case FFESTV_formatASTERISK: ffebad_start (FFEBAD_CONFLICTING_SPECS); ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), ffelex_token_where_column (ffesta_tokens[0])); assert (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_or_val_present); if (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_present) { ffebad_here (0, ffelex_token_where_line (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw), ffelex_token_where_column (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw)); } else { ffebad_here (1, ffelex_token_where_line (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value), ffelex_token_where_column (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value)); } ffebad_finish (); ffestc_ok_ = FALSE; return; default: break; } ffestd_V018_start (format); ffestc_ok_ = TRUE; } /* ffestc_V018_item -- REWRITE statement i/o item ffestc_V018_item(expr,expr_token); Implement output-list expression. */ void ffestc_V018_item (ffebld expr, ffelexToken expr_token) { ffestc_check_item_ (); if (!ffestc_ok_) return; ffestd_V018_item (expr); } /* ffestc_V018_finish -- REWRITE statement list complete ffestc_V018_finish(); Just wrap up any local activities. */ void ffestc_V018_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V018_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_V019_start -- ACCEPT statement list begin ffestc_V019_start(); Verify that ACCEPT is valid here, and begin accepting items in the list. */ void ffestc_V019_start () { ffestvFormat format; ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); if (!ffestc_subr_is_format_ (&ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT])) { ffestc_ok_ = FALSE; return; } format = ffestc_subr_format_ (&ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT]); ffestc_namelist_ = (format == FFESTV_formatNAMELIST); ffestd_V019_start (format); ffestc_ok_ = TRUE; } /* ffestc_V019_item -- ACCEPT statement i/o item ffestc_V019_item(expr,expr_token); Implement output-list expression. */ void ffestc_V019_item (ffebld expr, ffelexToken expr_token) { ffestc_check_item_ (); if (!ffestc_ok_) return; if (ffestc_namelist_ != 0) { if (ffestc_namelist_ == 1) { ffestc_namelist_ = 2; ffebad_start (FFEBAD_NAMELIST_ITEMS); ffebad_here (0, ffelex_token_where_line (expr_token), ffelex_token_where_column (expr_token)); ffebad_finish (); } return; } ffestd_V019_item (expr); } /* ffestc_V019_finish -- ACCEPT statement list complete ffestc_V019_finish(); Just wrap up any local activities. */ void ffestc_V019_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V019_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } #endif /* ffestc_V020_start -- TYPE statement list begin ffestc_V020_start(); Verify that TYPE is valid here, and begin accepting items in the list. */ void ffestc_V020_start () { ffestvFormat format; ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); if (!ffestc_subr_is_format_ (&ffestp_file.type.type_spec[FFESTP_typeixFORMAT])) { ffestc_ok_ = FALSE; return; } format = ffestc_subr_format_ (&ffestp_file.type.type_spec[FFESTP_typeixFORMAT]); ffestc_namelist_ = (format == FFESTV_formatNAMELIST); ffestd_V020_start (format); ffestc_ok_ = TRUE; } /* ffestc_V020_item -- TYPE statement i/o item ffestc_V020_item(expr,expr_token); Implement output-list expression. */ void ffestc_V020_item (ffebld expr, ffelexToken expr_token) { ffestc_check_item_ (); if (!ffestc_ok_) return; if (ffestc_namelist_ != 0) { if (ffestc_namelist_ == 1) { ffestc_namelist_ = 2; ffebad_start (FFEBAD_NAMELIST_ITEMS); ffebad_here (0, ffelex_token_where_line (expr_token), ffelex_token_where_column (expr_token)); ffebad_finish (); } return; } ffestd_V020_item (expr); } /* ffestc_V020_finish -- TYPE statement list complete ffestc_V020_finish(); Just wrap up any local activities. */ void ffestc_V020_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V020_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_V021 -- DELETE statement ffestc_V021(); Make sure a DELETE is valid in the current context, and implement it. */ #if FFESTR_VXT void ffestc_V021 () { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.delete.delete_spec[FFESTP_deleteixERR]) && ffestc_subr_is_present_ ("UNIT", &ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT])) ffestd_V021 (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_V022 -- UNLOCK statement ffestc_V022(); Make sure a UNLOCK is valid in the current context, and implement it. */ void ffestc_V022 () { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.beru.beru_spec[FFESTP_beruixERR]) && ffestc_subr_is_present_ ("UNIT", &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT])) ffestd_V022 (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_V023_start -- ENCODE(...) statement list begin ffestc_V023_start(); Verify that ENCODE is valid here, and begin accepting items in the list. */ void ffestc_V023_start () { ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); if (!ffestc_subr_is_branch_ (&ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixERR])) { ffestc_ok_ = FALSE; return; } ffestd_V023_start (); ffestc_ok_ = TRUE; } /* ffestc_V023_item -- ENCODE statement i/o item ffestc_V023_item(expr,expr_token); Implement output-list expression. */ void ffestc_V023_item (ffebld expr, ffelexToken expr_token) { ffestc_check_item_ (); if (!ffestc_ok_) return; ffestd_V023_item (expr); } /* ffestc_V023_finish -- ENCODE statement list complete ffestc_V023_finish(); Just wrap up any local activities. */ void ffestc_V023_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V023_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_V024_start -- DECODE(...) statement list begin ffestc_V024_start(); Verify that DECODE is valid here, and begin accepting items in the list. */ void ffestc_V024_start () { ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); if (!ffestc_subr_is_branch_ (&ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixERR])) { ffestc_ok_ = FALSE; return; } ffestd_V024_start (); ffestc_ok_ = TRUE; } /* ffestc_V024_item -- DECODE statement i/o item ffestc_V024_item(expr,expr_token); Implement output-list expression. */ void ffestc_V024_item (ffebld expr, ffelexToken expr_token) { ffestc_check_item_ (); if (!ffestc_ok_) return; ffestd_V024_item (expr); } /* ffestc_V024_finish -- DECODE statement list complete ffestc_V024_finish(); Just wrap up any local activities. */ void ffestc_V024_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V024_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_V025_start -- DEFINEFILE statement list begin ffestc_V025_start(); Verify that DEFINEFILE is valid here, and begin accepting items in the list. */ void ffestc_V025_start () { ffestc_check_start_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_branch_begin_ (); ffestd_V025_start (); ffestc_ok_ = TRUE; } /* ffestc_V025_item -- DEFINE FILE statement item ffestc_V025_item(u,ut,m,mt,n,nt,asv,asvt); Implement item. */ void ffestc_V025_item (ffebld u, ffelexToken ut, ffebld m, ffelexToken mt, ffebld n, ffelexToken nt, ffebld asv, ffelexToken asvt) { ffestc_check_item_ (); if (!ffestc_ok_) return; ffestd_V025_item (u, m, n, asv); } /* ffestc_V025_finish -- DEFINE FILE statement list complete ffestc_V025_finish(); Just wrap up any local activities. */ void ffestc_V025_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V025_finish (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } /* ffestc_V026 -- FIND statement ffestc_V026(); Make sure a FIND is valid in the current context, and implement it. */ void ffestc_V026 () { ffestc_check_simple_ (); if (ffestc_order_actionif_ () != FFESTC_orderOK_) return; ffestc_labeldef_branch_begin_ (); if (ffestc_subr_is_branch_ (&ffestp_file.find.find_spec[FFESTP_findixERR]) && ffestc_subr_is_present_ ("UNIT", &ffestp_file.find.find_spec[FFESTP_findixUNIT]) && ffestc_subr_is_present_ ("REC", &ffestp_file.find.find_spec[FFESTP_findixREC])) ffestd_V026 (); if (ffestc_shriek_after1_ != NULL) (*ffestc_shriek_after1_) (TRUE); ffestc_labeldef_branch_end_ (); } #endif /* ffestc_V027_start -- VXT PARAMETER statement list begin ffestc_V027_start(); Verify that PARAMETER is valid here, and begin accepting items in the list. */ void ffestc_V027_start () { ffestc_check_start_ (); if (ffestc_order_parameter_ () != FFESTC_orderOK_) { ffestc_ok_ = FALSE; return; } ffestc_labeldef_useless_ (); ffestd_V027_start (); ffestc_ok_ = TRUE; } /* ffestc_V027_item -- VXT PARAMETER statement assignment ffestc_V027_item(dest,dest_token,source,source_token); Make sure the source is a valid source for the destination; make the assignment. */ void ffestc_V027_item (ffelexToken dest_token, ffebld source, ffelexToken source_token UNUSED) { ffestc_check_item_ (); if (!ffestc_ok_) return; ffestd_V027_item (dest_token, source); } /* ffestc_V027_finish -- VXT PARAMETER statement list complete ffestc_V027_finish(); Just wrap up any local activities. */ void ffestc_V027_finish () { ffestc_check_finish_ (); if (!ffestc_ok_) return; ffestd_V027_finish (); } /* Any executable statement. Mainly make sure that one-shot things like the statement for a logical IF are reset. */ void ffestc_any () { ffestc_check_simple_ (); ffestc_order_any_ (); ffestc_labeldef_any_ (); if (ffestc_shriek_after1_ == NULL) return; ffestd_any (); (*ffestc_shriek_after1_) (TRUE); }