sec1.runoff 03/29/79 1519.5rew 07/15/74 1152.2 11124 .m1 6 .m2 0 .m3 4 .m4 6 .tr { .sr sec 1 .fo "DRAFT: SUBJECT TO CHANGE"%sec%-%"AN83" .ce 1 SECTION I .sp 2 .ce 1 OVERVIEW .sp 4 The FORTRAN Program Logic Manual (PLM) deals solely with the parse and semantic translation phases of the Multics FORTRAN Compiler. The optimizer and code generator are shared by the FORTRAN and the PL/I compilers and are discussed in the P_L_/_I__C__o_m_p_i_l_e_r_P__r_o_g_r_a_m_L__o_g_i_c_M__a_n_u_a_l (Order No. AN54). .sp 2 The FORTRAN compiler translates a segment containing the text of a FORTRAN source subprogram into a Multics standard object segment. A listing segment is optionally produced. A terminal format source segment is optionally produced. These segments are created in the user's working directory. .sp 3 D_E_F_I_N_I_T_I_O_N__O_F__T_E_R_M_S_ .sp 2 The reader is assumed to completely understand the FORTRAN language. All terms used in this section are defined either in the 1971 version of the ANSI standard for the FORTRAN language or in the section discussing the internal representation of a FORTRAN subprogram found in the P_L_/_I__C__o_m_p_i_l_e_r_P__r_o_g_r_a_m_L__o_g_i_c_M__a_n_u_a_l (Order No. AN54).  sec2.runoff 03/29/79 1519.5rew 07/16/74 1326.8 153261 .m1 6 .m2 0 .m3 4 .m4 6 .tr { .fo "DRAFT: SUBJECT TO CHANGE"%sec%-%"AN83" .sr sec 2 .ce 1 SECTION II .sp 2 .ce 1 DESIGN .sp 4 This compiler was designed to interface with a general purpose code generator. To effect this aim, this FORTRAN compiler parses a FORTRAN source subprogram and produces an equivalent form that is called the internal representation. The code generator translates the internal representation into object code. .sp 2 The compiler was designed with several goals in mind. .sp 2 .in +5 .un 5 o{{{{Modularity -- This design decision follows from the desire to localize the decision-making process in the hopes of controlling compiler errors. Routines that require similar coding, are replaced by calls to a general subroutine. .sp 2 .un 5 o{{{{Simplicity -- Algorithms and coding style are kept as simple as possible. Whenever possible, the most direct and straight forward algorithms are used. .sp 2 .un 5 o{{{{Error Processing -- When syntactic or semantic errors are encountered, an effort is made to produce an intelligble error message for the user. However, no attempt is made to eliminate all erroneous constructs. Invalid text that happens to pass through a compilation without error cannot be expected to succeed in subsequent implementations of the compiler. .in -5 .sp 3 C_O_M_P_I_L_E_R__P_R_O_C_E_D_U_R_E_S_ .sp 2 The procedures of the FORTRAN compiler can be put in the following general categories: .sp 2 .in 5 .un 5 Command Program .sp 1 fortran .sp 1 This is the command interface with the user. This procedure evaluates the user options and sets the proper fields. If the user has typed an unrecognizable option, or fails to provide a valid source segment pathname, this procedure prevents further processing by the compiler. .sp 2 It invokes the various phases of the compiler. In a link overlay environment, this would make this procedure the overlay root. However, in the Multics environment, an overlay root is not necessary although it is useful to have a single procedure responsible for invoking the compiler phases. .sp 2 It interfaces with Multics. All calls to Multics subroutines and primitives emanate only from this procedure. This includes getting a pointer to the source segment, creating and managing the object, listing, and created source segments. Creation of the abovementioned segments entails truncating the segment if it exists already. .sp 2 It establishes a cleanup handler and an unclaimed signal handler. The cleanup handler terminates any segment initiated by the compiler and truncates the compiler's external storage. The cleanup handler does not terminate or truncate segments if one of the debug options is given. It is standard practice for a command that allocates storage to establish a cleanup handler. The unclaimed signal handler prints out the source line on which the error occurs and aborts the compilation. Signals that it does not recognize are not handled. They are passed through to the standard unclaimed handler. .sp 2 If the compilation is aborted because of a compiler error, the cleanup handler is invoked. .sp 2 .un 5 Phases .sp 1 fortran_parse [optimizer] [code_gen_] .sp 1 These procedures direct the phases of the compilation. Only fortran_parse is unique to the FORTRAN compiler. It initializes and directs the parse phase of a FORTRAN compilation. A Multics FORTRAN subprogram must have its statements in a particular order. This procedure prevents out of sequence statements from being parsed. Parsing is accomplished by calling the procedure statement_recognizer which returns the statement type of the statement encountered. A parser is called to parse the statement. Statement_recognizer is called for the statement type of the next statement until an end line is encountered. .sp 2 Before the first executable statement is parsed, a declaration processor is called to finish up any declarations made by the user. After the end line is parsed, all referenced labels must be defined and all do loops are terminated. .sp 2 .un 5 Statement Typing .sp 1 statement_recognizer .sp 1 Statement_recognizer determines the statement type by looking at the first token after the first complete reference. If the token is an assignment token, the statement is either a do statement or an assignment statement. If the first two characters of the identifier are "do" and the third character is a digit, the statement is either a do statement or an assignment statement. The statement type returned is of a do statement. The do statement parser will make the final judgement as to the statement type. If the above condition is not met, it is an assignment statement. Otherwise, if there is no assignment token, a keyword table lookup is made on the first token of the statement. If a match is found, the match indicates the statement type. Otherwise it is an unknown statement type. .sp 2 .un 5 Lexical Analyzers .sp 1 flex cardlex .sp 1 These procedures isolate each token of the source text as they are requested by the parsers. Only one of these analyzers will be active during a single compilation. The procedure flex is the lexical analyzer used for terminal format FORTRAN text segments. .sp 2 The procedure cardlex is the lexical analyzer used for card-image FORTRAN text segments. .sp 2 .un 5 Statement Parsers .sp 1 .nf fortran_assign_parse declaration_parse fortran_crse_parse fortran_do_parse fortran_format_parse fortran_if_parse fortran_io_parse fortran_subroutine_parse initial_attribute stmnt_func_parse go_to_parse .fi .sp 1 Each procedure parses a particular statement and creates the appropriate nodes in the tree. These procedures perform semantics translation while parsing. In most cases, parsing requires only one pass over the source tokens. .sp 2 The statement type parsed is evident from the name of the procedure except that fortran_crse_parse parses call statements, stop and pause statements, return statements, and end lines. .sp 2 .un 5 Declaration Processing .sp 1 dcl .sp 1 This procedure is responsible for handling symbol attributes, either as declared by the program or as acquired due to implicit rules. After all declaration statements are parsed, some user defined symbols can lack either a storage class or a mode. This procedure makes a single pass through the symbol table, assigning storage class or mode to those symbols that need them. This symbol table processing precedes data initialization, equivalencing, namelist statements, and executable statements. .sp 2 When necessary, this procedure can be called to provide implicit typing, An identifier with no symbol table entry encountered after declaration processing is given the default storage class and a mode based on the current implicit rules. .sp 2 The parser for the implicit statement was stuck in this proceduure. .sp 2 .un 5 Utilities .sp 1 .nf builtin_function fortran_expression_parse fortran_operator_semantics fortran_reference_parse fortran_reserve fortran_subscripter replace_parameters set_parameters prologue_entry make_format make_label type .fi .sp 1 These procedures perform special functions required by parse procedures. For example, expression parsing and label processing. .sp 2 Procedures that do not fit in any other grouping have been collected here. For example, replace_parameters, set_parameters, prologue_entry. .sp 2 .un 5 Code Generator Procedures .sp 1 fortran_io_op .br fortran_symbol_print .sp 1 These code generator procedures are considered part of the FORTRAN compiler because they are used only during FORTRAN compilations. The procedure fortran_io_op generates code for all FORTRAN I/O statements and for encode and decode statements. The procedure fortran_symbol_print formats and outputs symbol attributes if requested by the user. .sp 2 .un 5 Externally Referenced .sp 1 general_format_parse_ .sp 1 This procedure is used both by the FORTRAN compiler and the FORTRAN I/O runtime routines to parse a format statement. .in 0 .sp 3 C_O_M_P_I_L_E_R__U_T_I_L_I_T_Y__P_R_O_C_E_D_U_R_E_S__I_N_V_O_K_E_D_ .in 5 .sp 2 .un 5 bindec$vs -- This procedure produces a varying character string representation of the fixed binary number passed to it. This procedure is a very efficient method of converting from binary to character as it shares the stack frame of its caller. .sp 2 .un 5 binoct -- This procedure produces an octal character representation of its fixed binary argument. This procedure shares the stack frame of its caller. .sp 2 .un 5 convert -- This procedure converts the first argument to the mode specified by the second argument. It chooses the proper precision. .sp 2 .un 5 convert$to_integer -- This procedure converts the first argument to integer mode. .sp 2 .un 5 convert$to_target -- This procedure converts the first argument to the mode, precision and scale. of its second argument. If the first argument is not a token, conversion will be done at runtime. .sp 2 .un 5 copy_expression -- This procedure makes a duplicate of the expression passed to it. It is used when an expression must appear several places and be unique in each place. .sp 2 .un 5 create_array -- This procedure creates an array node. A symbol that has any number of dimensions will have a single array node. .sp 2 .un 5 create_block -- This procedure creates a block node. There are two block nodes created. The root block and the procedure block. .sp 2 .un 5 create_bound -- This procedure creates a bound node. A dimensioned symbol will have one bound node for each bound. .sp 2 .un 5 create_cross_reference -- This procedure creates a cross reference node. Cross reference nodes are used in the symbol listing. .sp 2 .un 5 create_label -- This procedure creates a label node. Labels are compiler referencable addresses. .sp 2 .un 5 create_list -- This procedure creates a list node. List nodes are used to represent argument lists, descriptor lists, multiple labels on a statement, and so on. .sp 2 .un 5 create_operator -- This procedure creates an operator node. It is passed the operator type and the number of operands. .sp 2 .un 5 create_reference -- This procedure creates a reference node. Reference nodes are created whenever an unshared reference node is needed. .sp 2 .un 5 create_statement -- This procedure creates a statement node. A statement node is created for each statement in the subprogram. Statement nodes are also created by the compiler to represent compiler actions. .sp 2 .un 5 create_statement$prologue -- This procedure creates a statement node as part of the prologue of the current block. Statements in the prologue are executed everytime a subprogram entry point is invoked. Automatic variable data initializations is an example of a prologue action. .sp 2 .un 5 create_symbol -- This procedure creates an empty symbol node. (A symbol with no attributes.) Every user defined identifier must have a symbol node specifying its attributes. Compiler temporaries and constants must also have symbol nodes. .sp 2 .un 5 create_token -- This procedure creates a token node. It is passed the token string and the token type. Tokens are generally created by the lexical analyzers, however some procedures must create tokens themselves. For example -- function return values; the first identifier or integer following a keyword; or the variable reference following the letters "to" in an assign statement. .sp 2 .un 5 declare_constant -- This procedure create a compiler constant with the specified mode, precision and value. .sp 2 .un 5 declare_constant$bit -- This procedure creates a bit constant with the specified value. .sp 2 .un 5 declare_constant$char -- This procedure creates a character constant with the specified value. .sp 2 .un 5 declare_constant$integer -- This procedure creates an integer constant with the specified value. .sp 2 .un 5 declare_descriptor -- This procedure creates a descriptor for a reference. Generally the descriptor for a symbol is constant or is formed the same way in all contexts. Therefore, it is stored in the "symbol.descriptor" field. Others, such as descriptors for a single element of anarray, are not saved. .sp 2 .un 5 declare_temporary -- This procedure creates a compiler temporary with the specified mode and precision. This procedure is generally called to build a temporary for the target operand of an operator. .sp 2 .un 5 error -- This procedure prints an error message given a pointer to the statement node, the error number, and a pointer to the offending node. If the pointer to the statement node is null, error_$no_text is called. Otherwise, error_ is called. The final argument can be a null pointer. .sp 2 .un 5 error_ -- This procedure prints an error message given the following: .in +5 .sp 1 The error number. .sp 1 The source file, line, and statement numbers of the offending statement. .sp 1 A pointer to the node that should be inserted in the error text or a null pointer. .sp 1 The source segment index. Always zero for a FORTRAN compilation. .sp 1 The character offset of the beginning of the offending statement. .sp 1 The length of the offending statement. .in -5 .sp 2 All other error routines result eventually in a call to this routine or error_$no_text. .sp 2 .un 5 error_$finish -- This procedure terminates the error report mechanism. This results in sorting the error messages by statement number for printing in the listing segment. .sp 2 .un 5 error_$initialize_error -- This procedure initializes the error reporting mechanism. The mechanism basically consists of an array that can hold up to 100 error messages. Each error is stored in the array during the course of the compilation. When error_$finish is called, the array is sorted by line number and placed in the listing segment. .sp 2 .un 5 error_$no_text -- This procedure prints an error message, however, there is no assiciated source text. The arguments are similar to those of error_. .sp 2 .un 5 free_node -- This procedure frees an allocation of a node in the tree. The node is freed and added to the free list. This procedure should be called only if it is certain that no other references to the node exist. .sp 2 .un 5 optimizer -- This is the optimizer. It is called after the parse phase if the user has specified the appropriate option. .sp 2 .un 5 parse_error -- This procedure is called by parse procedures to print an error message. It results in a call to error. .sp 2 .un 5 pl1_get -- This procedure allocates storage for nodes within the compiler's external storage. .sp 2 .un 5 pl1_print$for_lex -- This procedure is called by the lexical analyzers to print the source text if the user requests it. .sp 2 .un 5 pl1_print$non_varying -- This procedure puts a character string into the listing segment. Nothing else is put in the listing. .sp 2 .un 5 pl1_print$non_varying_nl -- This procedure puts a character string into the listing segment. A newline character is appended after it. .sp 2 .un 5 pl1_print$string_ptr_nl -- This procedure puts the character string pointed to by the argument into the listing segment. A newline character is appended after it. .sp 2 .un 5 pl1_print$unaligned_nl -- This procedure puts an unaligned character string into the listing segment. A newline character is appended after it. .sp 2 .un 5 pl1_print$varying_nl -- This procedure puts a varying character string into the listing segment. A newline character is appended after it. .sp 2 .un 5 pl1_signal_catcher -- This is the unclaimed signal handler that is active during a compilation. If a condition is raised that is probably due to a compiler error, this procedure will print the offending statement and abort the compilation. If the condition does not seem to be the fault of the compiler it is passed on to any other handler that may be active. .sp 2 .un 5 share_expression -- This procedure decides what changes must be made to an expression to allow it to appear again in the tree. Unlike copy_expression, no copy is made. Instead, reference counts on unshared reference nodes are upped by one. .sp 2 .un 5 sym_sort_alphabetic -- This procedure alphabetically sorts the array of symbol nodes passed to it. This procedure is called by fortran_symbol_print to sort the symbols for the listing. .sp 2 .un 5 token_to_binary -- This procedure takes as input a decimal integer token and returns its binary value. The use of this procedure is suggested as it shares the stack frame of its caller. .sp 2 .un 5 reserve$clear -- This procedure initializes a PL/I compiler table that may be referenced by the code generator. It has no direct affect on the FORTRAN compiler. .sp 2 .un 5 tree_manager$init -- This procedure initializes the external storage for the compiler. If they do not already exist, tree_ and xeq_tree_ are created. .sp 2 .un 5 tree_manager$truncate -- This procedure truncates the external storage for the compiler. This call is made at the end of a compilation, but not if one of the debug options is specified, to truncate all external static storage used by the compiler. .in 0  sec3.runoff 03/29/79 1519.5rew 07/16/74 1331.2 99531 .m1 6 .m2 0 .m3 4 .m4 6 .tr { .fo "DRAFT: SUBJECT TO CHANGE"%sec%-%"AN83" .sr sec 3 .ce 1 SECTION III .sp 2 .ce 1 DATA STRUCTURES .sp 4 These data structures are discussed in more detail in the P_L_/_I__C__o_m_p_i_l_e_r_P__r_o_g_r_a_m_L__o_g_i_c_M__a_n_u_a_l (Order No. AN54). They represent the major method of communication between compiler procedures and phases. .sp 3 I_N_T_E_R_N_A_L__R_E_P_R_E_S_E_N_T_A_T_I_O_N__(_T_H_E__T_R_E_E_)_ .sp 2 The tree is the internal representation of a FORTRAN subprogram produced by the FORTRAN compiler. This is the representation of the subprograms seen by the optimizer and code generator. Except for timing purposes it is unimportant to know what scheme is used to allocate storage for the tree. Utility procedures common to FORTRAN and PL/I maintain the tree and generate nodes. When adding to the tree, nodes must always be allocated by calling a utility procedure. Extreme care must be taken when deleting nodes from the tree to insure that they are not referenced elsewhere. .sp 2 The following nodes are used in the FORTRAN compiler: .in +5 .sp 2 .nf array block bound cross_reference label list operator reference sf_par_node statement symbol temporary token .fi .in -5 .sp 2 These nodes are far more precise than is necessary for a FORTRAN compilation. Therefore, only a subset of the fields in these nodes are used. A summary of the fields used follows. It is arranged by FORTRAN attributes. .sp 3 I__n_t_e_g_e_r_M__o_d_e .sp 2 The attributes fixed, real, aligned,binary are set. The c_dl_size is 35. .sp 3 FORTRAN_STAT_ .sp 2 This date structure also has the name pl1_stat_. It is an external static storage area used to hold commonly referenced values, user options, debugging information, etc. It is used by the parse and semantics translation phases of the compiler. Entries used by FORTRAN are: .in +5 .sp 2 .un 5 abort_label -- This label field is set by the procedure fortran. Transferring to this label results in unwinding the compiler, printing an error message informing the user that the compilation has been aborted, and executing the cleanup handler. .sp 2 .un 5 apostrophe_mode -- This bit(1) field indicates the interpretation of the apostrophe character to the card-image lexical analyzer. If it is "0"b, the apostrophe is a string delimiter. If it is "1"b, the apostrophe is an operator. If the card-image lexical analyzer is not being used, the value of this field is undefined. .sp 2 .un 5 brief_error_mode -- This bit(1) field is set to "1"b if the brief option is specified. This field controls the amount of text printed when an error occurs. .sp 2 .un 5 card_input -- This bit(1) field is set to "1"b if the card or convert option is specified. It indicates that the source text is in card-image format and the lexical analyzer cardlex will be used. .sp 2 .un 5 char_pos -- This field contains an approximate character count for the current listing segment. It is approximate because it is always one larger than the actual character count. If the listing file is a multi-segment file, this field only contains the character count of the active component. .sp 2 .un 5 check_bounds -- This bit(1) field is set to "1"b if the subscriptrange option is specified. It causes bound checking code to be generated for all subscripted references including computed goto statements and alternate return statements. .sp 2 .un 5 compiler_created_index -- Initialized to 0, this is a count of the compiler generated symbol names. The names are of the form "cp.n" where n is the value of compiler_created_index. .sp 2 .un 5 compiler_name -- This character field is the compiler name to be stored in the object segment by the code generator. The name of this compiler is "fortran". .sp 2 .un 5 constant_list -- The root of the chain of all constants created by the compiler. .sp 2 .un 5 convert_len -- If the convert option is specified, this field will contain the character count for the source segment created. This field is set when cardlex$write_last_line is invoked. .sp 2 .un 5 convert_ptr -- If the convert option is specified, this is a pointer to the segment that will contain the created source segment. .sp 2 .un 5 convert_switch -- This bit(1) field is set to "1"b if the convert option is specified. .sp 2 .un 5 cur_block -- A pointer to current procedure block node. .sp 2 .un 5 cur_statement -- A pointer to the statement node currently being built. It is valid only during the parse phase. .sp 2 .un 5 debug_semant -- This bit(1) field is set to "1"b if any debug option is specified. .sp 2 .un 5 dummy_block -- Initialized to a null pointer by fortran. This pointer is used by the code generator. .sp 2 .un 5 equivalence_base -- This pointer is used while processing equivalence statements and for checking do loop nesting. .sp 2 .un 5 error_memory -- The procedure error_ remembers the first 100 errors so they can be sorted by line number before being placed in the listing segment. .sp 2 .un 5 error_messages -- A pointer to the segment containing the text for all error messages. .sp 2 .un 5 error_width -- The line length for the I/O stream user_output. If user_output does not have a line length, the value 120 is used. .sp 2 .un 5 expl_continuation_count -- This field is used by the lexical analyzers to tell statement_recognizer how many newline characters were parsed that statement_recognizer does not know about. .sp 2 .un 5 format_list -- The root of the chain of format statements parsed. At the end of the compilation, this chain is added to the declarations for the subprogram. .sp 2 .un 5 generate_symtab -- This bit(1) field is set to "1"b if a namelist name is referenced within a subprogram. .sp 2 .un 5 greatest_severity -- This field is zeroed at the beginning of a compilation and will indicate the error level high water mark at the end of the compilation. In other words, the highest severity error recorded for this compilation. .sp 2 .un 5 hash_table -- The token node hash table. .sp 2 .un 5 hollerith_mode -- This bit(1) field is set to indicate to the lexical analyzers what to do with the characters "h" or "H" if they are preceded by a decimal integer. If the field has the value "1"b, the "h" denotes a hollerith constant. Otherwise, the "h" is the first character of an identifier. .sp 2 .un 5 last_source -- The number of include files used in this compilation. For FORTRAN compilations this field is always zero. .sp 2 .un 5 line_count -- At the end of a compilation this field is set to the number of newline characters in the source segment. .sp 2 .un 5 list3_node -- The root of the chain of freed 3-element list nodes. .sp 2 .un 5 list5_node -- The root of the chain of freed 5-element list nodes. .sp 2 .un 5 list_ptr -- Pointer to the current listing segment. .sp 2 .un 5 listing_on -- This bit(1) field is set to "1"b if a listing segment is to be produced. .sp 2 .un 5 max_list_size -- This field is the max_seg_size of the current listing segment. .sp 2 .un 5 modetable -- An array of 52 entries one for each letter. It specifies the implied mode for the corresponding letter. .sp 2 .un 5 node_uses -- An array of counters, one for each node length. The appropriate counter is bumped whenever a node is created. The length of the operator is based on the number of words allocated for it. This information is provided for metering purposes. .sp 2 .un 5 ok_list -- The root of the chain of OK lists. One OK list is created for each referenced namelist group. .sp 2 .un 5 options -- A character string representation of all options specified. This character string will appear in the listing segment. .sp 2 .un 5 pathname -- The absolute pathname of the source segment. .sp 2 .un 5 phase -- The current compilation phase. .sp 2 .un 5 print_cp_dcl -- If the cpdcl option is specified, this field is set to "1"b. .sp 2 .un 5 profile_length -- The number of words to be allocated to implement the profile feature of the compiler. This value will approximate the number of statements in the subprogram. .sp 2 .un 5 root -- A pointer to the root block. .sp 2 .un 5 seg_name -- The entryname of the source segment but without the final component. .sp 2 .un 5 severity_plateau -- This field is initially one but can be set by the user to any value from one to four. This field implements the severity option by specifying the minimum error level of error messages to be printed. .sp 2 .un 5 source_index -- Initialized to one by fortran. .sp 2 .un 5 source_list_ptr -- Pointer to an array of source segment pointers. For FORTRAN compilations only the first element is used. .sp 2 .un 5 source_ptr -- Pointer to the source segment. .sp 2 .un 5 st_length -- Current length of the statement being compiled. It is updated everytime another token is parsed. .sp 2 .un 5 st_start -- Character offset of the beginning of the current statement relative to the base of the source segment. .sp 2 .un 5 statement_id -- The line number, statement number, and file number of the current statement. .sp 2 .un 5 stop_id -- If one of the debug options is specified, this field is compared to fortran_stat_$statement_id. If they are equal, debug is called. .sp 2 .un 5 table -- Set to "1"b if the table option is specified. .sp 2 .un 5 temporary_list -- The root of the chain of compiler temporaries created during the compilation. .sp 2 .un 5 tree_vec_index -- This field specifies how many additional segments are being used by the compiler. Its value will be zero if only tree_ and xeq_tree_ are being used. The value is maintained dynamically and reflects only the current storage requirements. .sp 2 .un 5 user_id -- The Person.Project.instance tag for current compilation. .sp 2 .un 5 util_abort -- A label used by the utility procedures to unwind after a level 3 error. It is assigned the value fortran_parse$abort. Transferring to this label results in unwinding the compiler sufficiently to continue compilation. .sp 2 .un 5 util_error -- A label variable used by the utility procedures to unwind after an error. Is is assigned the value fortran_parse$error. Transferring to this label results in unwinding the compiler sufficiently to continue compilation. .in -5 .sp 3 CG_STATIC_ .sp 2 An external data storage area used to communicate with the code generator. Entries used by FORTRAN are: .in +5 .sp 2 .un 5 cur_block -- A pointer to the current block. Used by fortran_io_op to find the address of the PS. .sp 2 .un 5 debug -- Set to "1"b if debug_cg option is specified. .sp 2 .un 5 stop_id -- Initialized to "0"b by fortran. The field serves the same function for the code generator as fortran_stat_$stop_id does for the parse phase. .sp 2 .un 5 text_base -- A pointer to the base of the object segment. .sp 2 .un 5 text_pos -- The current offset into the object segment. .in 0 .sp 3 OPERATOR_NAMES_ .sp 2 This data base specifies the names of the operators invoked by the object program at runtime. It is used by fortran_symbol_print to print the names of the operators used.  sec4.runoff 03/29/79 1519.6rew 07/16/74 1402.5 111780 .m1 6 .m2 0 .m3 4 .m4 6 .tr { .fo "DRAFT: SUBJECT TO CHANGE"%sec%-%"AN83" .sr sec 4 .ce 1 SECTION IV .sp 2 .ce 1 STATEMENT PROCESSING .sp 4 In processing the various FORTRAN statements, there are many similar constructs. These constructs will be discussed before dealing with each individual statement type. .sp 3 C_O_N_S_T_A_N_T_S_ .sp 2 Any token that represents a valid FORTRAN constant can be converted to a compiler constant by calling fortran_operator_semantics. Except in the case of converting decimal integers for use during a compilation, this is the only valid method to convert a token. No token nodes are allowed in the final internal representation. .sp 2 To convert from token to constant: .sp 2 .in 5 .nf x = create_symbol(null, null, "0"b); x->reference.symbol->symbol.temporary = "1"b; y = create_operator((assign), 2); y->operator.operand(1) = x; y->operator.operand(2) = token_ptr; constant_ref_ptr = fortran_operator_semantics(y); .fi .in 0 .sp 3 R_E_F_E_R_E_N_C_E_S_ .sp 2 A reference is an identifier or an identifier followed by parenthesized list. References should be parsed by fortran_reference_parse. There are four reference contexts: .sp 2 C__a_l_l_C__o_n_t_e_x_t .sp 2 The reference is defined by a call statement. The identifier following the word "call", and the argument list if it exists. This is not the same as a function reference. This reference differs from a function reference in that the identifier must be undeclared or declared as a subroutine. .sp 2 L__e_f_t_H__a_n_d_S__i_d_e_C__o_n_t_e_x_t .sp 2 A reference on the left hand side of an assignment statement. This context includes any set reference, (i.e.-- read and decode statement lists, implied and explicit do loop indices, assign and assignment statements, encode target strings, etc.) This differs from other references because a check is made to insure that the reference is a reference to a variable. .sp 2 S__t_a_t_e_m_e_n_t_F__u_n_c_t_i_o_n_C__o_n_t_e_x_t .sp 2 The reference on the left hand side of a statement function definition. The identifier must be undeclared. This reference differs from the others in that the identifier must be undeclared, there must be a list, and the formal parameters must be scalar references. .sp 2 S__i_m_p_l_e_C__o_n_t_e_x_t_s .sp 2 This entry parses all other references, with or without a list. If there is a list, fortran_reference_parse determines if it is a subscript list or an argument list. .sp 3 EXPRESSIONS .sp 2 In any context where an expression can appear, fortran_expression_parse should be called. It will parse and semanticize any valid expression and return a pointer to a tree segment, an operator node, a reference node, or a token node. Expressions involving constants are evaluated during compilation and replaced by an appropriate constant. Token nodes must be removed from the final tree using the rules in the paragraph concerning constants. .sp 3 OPERATOR SEMANTICS .sp 2 Whenever an operator node is created, fortran_operator_semantics should be called to validate the operator node created. Mode checking is performed and references are converted to another arithmetic mode if necessary. Arithmetic, logical, or relational operators involving constants are evaluated and replaced by a constant node. .sp 3 STATEMENT PARSING BY STATEMENT TYPE .sp 3 Main Subprogram .sp 2 A main subprogram is recognized by the absence of a subprogram statement, (i.e.- a block data, function, or subroutine statement). Even though there is no FORTRAN language statement to signify an entry into a main subprogram, the internal representation requires one. Therefore, a procedure statement is created and inserted in the procedure immediately preceding the user supplied first statement. The actual insertion of the statement is tricky because the create_statement utility will move any labels on the user's statement onto the inserted statement. This is clearly undesirable as made evident by the possibility of a format statement as the first statement in the subprogram. To circumvent this problem, the user's first statement is removed from the tree, the procedure statement is created, and then the user's statement is threaded back into the tree. .sp 2 The procedure statement is "filled in" by calling fortran_subroutine_parse. .sp 3 Assignment Statements .sp 2 An assignment statement is recognized if the first token after the first full reference is an equal sign or if the first token of the statement is not an identifier. .sp 2 The entire statement is parsed by fortran_assign_parse. The left hand side is parsed by calling fortran_reference_parse$left. The token following must be an equal sign. The expression is parsed by calling fortran_expression_parse. .sp 3 Backspace, Endfile, and Rewind Statements .sp 2 One of these statements is recognized if the statement begins with the appropriate keyword and no equal sign is detected. .sp 2 The entire statement is parsed by fortran_io_parse. Fortran_expression_parse is called to parse the unit number expression. .sp 3 Block Data Statement .sp 2 This statement is recognized if it is the first statement of the subprogram. Only comment lines may precede it. .sp 2 A flag is set in fortran_parse is set to indicate that this is a main subprogram and therefore entry statements are invalid. .sp 2 Fortran_subroutine_parse is called to complete the procedure statement and check for text after the logical end of the statement. .sp 3 Call Statement .sp 2 This statement is recognized if there is no equals sign following the first reference and the first four characters of the first identifier are "call". This statement is not recognized if the "c" appears in column 1, because that defines a comment line. .sp 2 Fortran_crse_parse calls fortran_reference_parse$call to parse the entire call reference. Then it checks for text following th logical end of the statement. .sp 3 Abnormal, Automatic, Character, Complex, Double Precision, External, Integer, and Real Statements .sp 2 These statements are recognized if there is no equals sign following the first reference and the beginning characters match the keyword. Character and complex statements are not recognized if the "c" appears in column 1. .sp 2 Declaration_parse has one entry point for each declarative statement. Each entry point initializes two masks. The first specifies the attributes to be assigned, the other indicates those attributes that would conflict with the attributes to be assigned. If conflicting attributes are introduced by the declarative statement, the declaration is not made. .sp 2 The declaration lists are all parsed by the internal procedure list_parse. Mode statements can also specify data initializations. The initializations are parsed by initial_attribute. .sp 3 Common Statement .sp 2 This statement is not recognized if the "c" appears in column 1. .sp 2 Declaration_parse parses the entire statement. .sp 3 Continue Statement .sp 2 This statement is not parsed by any parser other than statement_recognizer. .sp 3 Data Statement .sp 2 The reference lists in this statement are parsed by declaration_parse. The initial value fields are parsed by initial_attribute. .sp 3 Decode and Encode Statements .sp 2 These statements are parsed by fortran_io_parse. Instead of unit number expression, a valid string is parsed. The format reference can not be a namelist name. The I/O list must conform to the normal sort of criteria. Encode statement list elements can only be scalar references, array references, or implied do groups. Decode statement list elements can be any valid expression, or implied do group. .sp 3 Dimension Statement .sp 2 This statement is parsed by declaration_parse. .sp 3 Do Statement .sp 2 Generally, this statement is only partially recognized by statement_recognizer when fortran_do_parse is called to parse the statement. The right hand side of the statement is parsed first. If the right hand side expression is followed by a comma, this is a do statement; a second and possibly a third expression are parsed. .sp 2 Once the statement type has been identified, the left hand side can be parsed. For an assignment statement, the left hand side includes everything. For a do statement, the reference starts after the statement label. .sp 2 The expression(s) are parsed by fortran_expression_parse and the left hand side by fortran_refernce_parse$left. .sp 3 End Line .sp 2 End lines are recognized by some special case code. An end line is recognized only if there is no statement label, and the characters "end" are followed by a newline or semicolon character. .sp 2 Fortran_crse_parse creates a standard return statement in the internal representation. .sp 3 Entry and Subroutine Statements .sp 2 These statements are parsed by fortran_subroutine_parse. .sp 3 Equivalence Statement .sp 2 This statement is parsed by declaration_parse. The compiler declares a variable that becomes the base reference. All members of the equivalence group are given offsets relative to the address of this base. .sp 2 An undesirable effect of this implementation is that the name of the compiler declared symbol will appear in the ALM listing of the subprogram. .sp 3 Format Statement .sp 2 Fortran_format_parse gets the format specifications and syntax checks the format statement. It does not know anything about format specifications. As a result, all specifications that are valid at runtime are not valid at compile time. .sp 2 For example, "(5x5h x = )" causes a compile time syntax error. The specification is parsed as the tokens "(", "5", "hx", "=", and ")". Notice that the spaces have been lost. .sp 2 General_format_parse_ actually parses the format specifications and provides an "executable" form. .sp 3 Function Statements .sp 2 There are two types of function statements, those which specify a mode and those that do not. Function statements are only recognized if they are the first statement in a subprogram. .sp 2 Fortran_subroutine_parse parses the statement and assigns a mode to the function's return value only if the statement is of the first type mentioned above. .sp 3 Goto Statements .sp 2 The three goto statements are parsed by the procedure go_to_parse. This procedure determines which of the three types the statement is and parses it accordingly. .sp 3 If Statements .sp 2 Both logical and arithmetic if statements are parsed by the procedure fortran_if_parse. .sp 2 An extension was made to arithmetic if statement processing to support omitted statement labels if the -card or -convert options is specified. .sp 2 Logical if statements require a call to statement_recognizer to determine the type of the second part of the statement. .sp 3 Namelist Statement .sp 2 Thi statement is parsed by declaration_parse. .sp 3 Parameter Statement .sp 2 This statement is parsed by fortran_assign_parse. .sp 3 Pause and Stop Statements .sp 2 These statements are parsed by fortran_crse_parse. .sp 3 Print, Punch, Read, Read(, Write( Statements .sp 2 These statements are parsed by fortran_io_parse. .sp 2 The terminal directed I/O statements, print, punch, and read, are assigned the unit numbers 6, 7, and 5 respectively. For the other I/O statements, fortran_expression_parse is called to parse a unit number expression. .sp 2 A format reference is either a decimal integer (a statement label), a character variable or a dimensioned variable (a runtime format), or a namelist group name. If none of these are present it is an unformatted I/O statement. Direct access I/O statements must be unformatted. .sp 2 For direct access I/O statements, the record number is parsed by fortran_expression_parse. .sp 2 Lists for input statements can only contain scalar references, array references, and implied do groups. .sp 2 Lists for output statements can contain any valid expression, and implied do groups. .sp 3 Statement Functions .sp 2 The first assignment statement of a subprogram is always assumed to be a statement function. Stmnt_func_parse is called to parse the statement. If the statement turns out to really be an assignment, it is compiled as such and stmnt_func_parse is not called again during the compilation of the subprogram. .sp 2 If it is a statement function definition, it is compiled as such and stmnt_func_parse will continue to be called until the above criteria is met.  sec5.runoff 03/29/79 1519.6rew 07/19/74 1114.5 1674549 .m1 6 .m2 0 .m3 4 .m4 6 .tr { .fo "DRAFT: SUBJECT TO CHANGE"%sec%-%"AN83" .sr sec 5 .ce 1 SECTION V .sp 2 .ce 1 PROCEDURES .sp 4 The following information is provided for each procedure: .sp 2 .in 5 .un 5 Functions -- What the procedure does. When to call the procedure. Algorithms and implementations are explained if they are obscure. .sp 2 Internal procedures are explained if they are necessary or relevant. .sp 2 .un 5 Usage -- Entry declarations for the procedure entry points. A description of the arguments to the entry point. A description of the return value. .sp 2 .un 5 Procedures That Invoke This Procedure -- A list of all compiler procedures that invoke entry points in this procedure. .sp 2 .un 5 Programs Called -- A list of external procedures called by the procedure. .sp 2 .un 5 External Data -- A list of external data referenced by the procedure. .sp 2 .un 5 Include Files -- A list of include files required to compile the procedure. .in 0 .sp 3 P_R_O_C_E_D_U_R_E_ -- builtin_function .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure processes all valid references to intrinsic and external builtin functions. Generally, intrinsic functions can be compiled in-line, and external ones are compiled out of line. Both intrinsic and external functions can be generic. In this case, the function name is a place holder and will be replaced by an actual builtin function of the appropriate mode. .sp 2 Argument mode, number of arguments, and mode of the result are all determined by the builtin function table entry for the function in question. .sp 2 The following contexts are recognized: .in 5 .sp 2 .un 5 1.{{{An identifier with the builtin attribute is followed by a parenthesized list in an arithmetic expression. A tree segment should be created to semantically represent the function. The procedure either generates a builtin function or standard call operator node as follows: .in +5 .sp 2 .un 5 a.{{{All intrinsic functions result in the creation of a builtin function operator node. The functions amax0, amin0, max1, and min1 create an additional assign operator because the result mode differs from the argument mode. .sp 2 .un 5 b.{{{All of the external builtin functions except cabs, ccos, cexp, clog, csin, csqrt, dmod, and tanh, are implemented by creating a builtin function operator node. .sp 2 .un 5 c.{{{The functions cabs, ccos, cexp, clog, csin, csqrt, dmod, and tanh, are implemented by creating a standard call operator. No argument descriptors are generated. .in -5 .sp 2 .un 5 2.{{{The name of an external builtin is referenced as an entry value. In FORTRAN this is implied by the appearance of just the builtin name as an argument. The external name of the builtin function is declared an an entry constant and returned to the caller. .sp 2 .un 5 3.{{{An undeclared identifier is followed by a parenthesized list. If the identifer corresponds to the name of any builtin function, set the appropriate attributes in the symbol node and return. .sp 2 .un 5 4.{{{An identifier appearing in an external statement can be the name of an external builtin. If the identifier corresponds to the name of an external builtin function, set the appropriate attributes in the symbol node and return. .sp 3 .un 5 token_to_symbol (internal procedure) .sp 2 This procedure expects a token node as its argument. The token is converted to a constant by calling fortran_operator_semantics. This procedure is used to ascertain the data mode of a token, as well as to create a token. .in 0 .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 builtin_function entry(pointer, pointer dimension(128), fixed bin(15)) returns(pointer) .sp 2 .in +5 .un 5 1.{{{A pointer to a builtin function symbol node. .sp 2 The symbol node for a builtin function name has the builtin attribute, optionally has the external attribute, and symbol.c_dcl_size is set equal to the function's index in the table of builtin functions. All of the above is performed when a builtin function name is recognized, either by lookup or lookup_external. No other attributes are valid for the symbol. .sp 2 .un 5 2.{{{An array of 128 pointers. This array is created by the caller and consists of a pointer for each argument in the builtin function reference. Each points to an expression, a reference, or a token. If an expression or reference is valid but must be converted to another data mode, an assign operator will be added to it in order to effect the conversion. Token nodes that are valid but require mode conversion are simply replaced by a constant with the proper value and mode. .sp 2 .un 5 3.{{{The actual number of arguments to the builtin function reference. This indicates to builtin_function how many arguments to process. .sp 2 .un 5 Return -- A pointer to the node(s) that represents the builtin function reference. If an error occurs while in builtin_function, the pointer returned will be useless. .in -5 .sp 3 .un 5 declare_entry entry(pointer) returns(pointer) .sp 2 The input argument must be the symbol node of an external builtin function. The symbol node for the library routine for this external function is returned. .sp 2 The entry point either creates or returns the symbol node for the library routine. .sp 3 .un 5 lookup entry(pointer) returns(bit(1) aligned) .sp 2 This entry point is called with a pointer to a symbol node. The value "1"b is returned if the name of the symbol corresponds to the name of either an intrinsic function or an external builtin function. If it corresponds to neither, "0"b is returned. .sp 3 .un 5 lookup_external entry(pointer) returns(bit(1) aligned) .sp 2 This entry point is called with a pointer to a symbol node. The value "1"b is returned if the symbol name corresponds to the name of an external builtin function. Both the external and builtin attributes are set in the symbol node. If it is not "0"b is returned. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .nf .sp 2 builtin_function .sp 1 fortran_reference_parse .sp 3 declare_entry .sp 1 fortran_reference_parse .sp 3 lookup .sp 1 fortran_reference_parse .sp 3 lookup_external .sp 1 declaration_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 convert$to_target create_operator create_symbol declare_temporary fortran_operator_semantics fortran_reference_parse$make_call fortran_reserve$declare_lib parse_error -- 41, 42, 43. .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_data$builtin_name .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 block boundary declare_type fortran language_utility list nodes op_codes operator reference source_id_descriptor statement statement_types symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- card_lex_data .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This ALM segment defines the discrete state machine that defines tokens for the card-image FORTRAN lexical analyzer. It is the table that drives the card-image lexical analyzer. Currently there are 22 states, 24 character types, and 28 actions. The character types, and the actions are defined by use in the procedure cardlex. Lists for all three are provided here to aid in conceptualizing the matrix. .sp 3 C__h_a_r_a_c_t_e_r_T__y_p_e_s .sp 2 .in 5 .un 4 0. All invalid characters. That is all characters not listed in any other type. .sp 2 .un 4 1. A-Z, a-z except the following letters: d, e, h, x, D, E, H, X. d, e, D, and E are potential exponent characters. h and H could signify the beginning of a hollerith constant. x and X are isolated for historical reasons. .sp 2 .un 4 2. Digits. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. .sp 2 .nf .in 1 3. + 8. ( 13. ^ 18. " 4. - 9. ) 14. x, X 19. $ 5. * 10. . 15. d, D 20. _ 6. / 11. , 16. e, E 21. ' 7. = 12. ; 17. h, H .fi .in 5 .sp 2 .un 5 22. End of line character. This character is created by the lexical analyzer when the last character of the last continuation card of a statement has been parsed. It will force the termination of the token being parsed. .sp 2 .un 5 23. Space or Tab. These two characters are interchangable except in character strings. One tab is the same as one space. .bp .in 0 S__t_a_t_e_s_A__n_d_A__c_t_i_o_n_s .sp 2 .nf Character Value | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |------+------+------+------+------+------+------+------| State 1| 1-13| 2-5 | 3-1 | 1-3 | 1-3 | 7-1 | 1-3 | 1-3 | |------+------+------+------+------+------+------+------| State 2| 1-2 | 2-5 | 2-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 3| 1-2 | 1-2 | 3-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 4| 1-2 | 1-2 | 4-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 5| 1-2 | 6-5 | 4-1 | 1-14| 1-14| 1-14| 1-14| 1-14| |------+------+------+------+------+------+------+------| State 6| 1-15| 6-5 | 1-15| 1-15| 1-15| 1-15| 1-15| 1-15| |------+------+------+------+------+------+------+------| State 7| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-9 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 8| 1-16| 1-16| 18-1 | 19-1 | 19-1 | 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 9| 1-8 | 1-8 | 10-1 | 19-1 | 19-1 | 1-8 | 1-8 | 1-8 | |------+------+------+------+------+------+------+------| State 10| 1-2 | 1-8 | 10-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-8 | |------+------+------+------+------+------+------+------| State 11| 11-1 | 11-1 | 11-1 | 11-1 | 11-1 | 11-1 | 11-1 | 11-1 | |------+------+------+------+------+------+------+------| State 12| 1-26| 1-26| 1-26| 1-26| 1-26| 1-26| 1-26| 1-26| |------+------+------+------+------+------+------+------| State 13| 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | |------+------+------+------+------+------+------+------| State 14| 1-28| 1-28| 1-28| 1-28| 1-28| 1-28| 1-28| 1-28| |------+------+------+------+------+------+------+------| State 15| 1-2 | 15-5 | 15-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 16| 1-18| 1-18| 17-1 | 1-18| 1-18| 1-18| 1-18| 1-18| |------+------+------+------+------+------+------+------| State 17| 1-2 | 1-2 | 17-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 18| 1-2 | 1-2 | 18-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 19| 1-16| 1-16| 18-1 | 1-16| 1-16| 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 20| 1-21| 1-21| 4-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 21| 1-16| 1-21| 18-1 | 19-1 | 19-1 | 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 22| 1-13| 2-5 | 3-1 | 1-3 | 1-3 | 7-1 | 1-3 | 1-3 | |------+------+------+------+------+------+------+------| .bp Character Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |------+------+------+------+------+------+------+------| State 1| 1-3 | 1-3 | 5-1 | 1-3 | 1-3 | 1-10| 2-5 | 2-5 | |------+------+------+------+------+------+------+------| State 2| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 2-5 | 2-5 | |------+------+------+------+------+------+------+------| State 3| 1-2 | 1-2 | 20-20| 1-2 | 1-2 | 1-2 | 1-2 | 9-11| |------+------+------+------+------+------+------+------| State 4| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 8-5 | |------+------+------+------+------+------+------+------| State 5| 1-14| 1-14| 1-14| 1-14| 1-14| 1-14| 6-5 | 6-5 | |------+------+------+------+------+------+------+------| State 6| 1-15| 1-15| 1-12| 1-15| 1-15| 1-15| 6-5 | 6-5 | |------+------+------+------+------+------+------+------| State 7| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 8| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 9| 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | |------+------+------+------+------+------+------+------| State 10| 1-8 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-8 | 1-8 | |------+------+------+------+------+------+------+------| State 11| 11-1 | 11-1 | 11-1 | 11-1 | 11-1 | 11-1 | 11-1 | 11-1 | |------+------+------+------+------+------+------+------| State 12| 1-26| 1-26| 1-26| 1-26| 1-26| 1-26| 1-26| 1-26| |------+------+------+------+------+------+------+------| State 13| 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | |------+------+------+------+------+------+------+------| State 14| 1-28| 1-28| 1-28| 1-28| 1-28| 1-28| 1-28| 1-28| |------+------+------+------+------+------+------+------| State 15| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 15-1 | 15-1 | |------+------+------+------+------+------+------+------| State 16| 1-18| 1-19| 1-18| 1-19| 1-18| 1-18| 1-18| 1-18| |------+------+------+------+------+------+------+------| State 17| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 18| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 19| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 20| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-21| 21-5 | |------+------+------+------+------+------+------+------| State 21| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-21| 1-21| |------+------+------+------+------+------+------+------| State 22| 1-3 | 1-3 | 5-1 | 1-3 | 1-3 | 1-10| 2-5 | 2-5 | |------+------+------+------+------+------+------+------| .bp Character Value | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | |------+------+------+------+------+------+------+------| State 1| 2-5 | 2-5 | 11-22| 16-1 | 1-13| 13-23| 1-27| 1-4 | |------+------+------+------+------+------+------+------| State 2| 2-5 | 2-5 | 1-2 | 15-1 | 2-1 | 1-2 | 1-2 | 2-4 | |------+------+------+------+------+------+------+------| State 3| 9-11| 22-24| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 3-4 | |------+------+------+------+------+------+------+------| State 4| 8-5 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 4-4 | |------+------+------+------+------+------+------+------| State 5| 6-5 | 6-5 | 1-14| 1-14| 1-14| 1-14| 1-14| 5-4 | |------+------+------+------+------+------+------+------| State 6| 6-5 | 6-5 | 1-15| 1-15| 1-15| 1-15| 1-15| 6-4 | |------+------+------+------+------+------+------+------| State 7| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 7-4 | |------+------+------+------+------+------+------+------| State 8| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 8-4 | |------+------+------+------+------+------+------+------| State 9| 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 9-4 | |------+------+------+------+------+------+------+------| State 10| 1-8 | 1-8 | 1-2 | 1-8 | 1-8 | 1-2 | 1-2 | 10-4 | |------+------+------+------+------+------+------+------| State 11| 11-1 | 11-1 | 12-4 | 11-1 | 11-1 | 11-1 | 11-17| 11-1 | |------+------+------+------+------+------+------+------| State 12| 1-26| 1-26| 11-1 | 1-26| 1-26| 1-26| 1-26| 1-26| |------+------+------+------+------+------+------+------| State 13| 13-1 | 13-1 | 13-6 | 13-1 | 13-1 | 14-4 | 13-17| 13-1 | |------+------+------+------+------+------+------+------| State 14| 1-28| 1-28| 1-28| 1-28| 1-28| 13-7 | 1-28| 1-28| |------+------+------+------+------+------+------+------| State 15| 15-1 | 15-1 | 1-2 | 1-2 | 15-1 | 1-2 | 1-2 | 15-4 | |------+------+------+------+------+------+------+------| State 16| 1-18| 1-18| 1-18| 1-18| 1-18| 1-18| 1-18| 16-4 | |------+------+------+------+------+------+------+------| State 17| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 17-4 | |------+------+------+------+------+------+------+------| State 18| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 18-4 | |------+------+------+------+------+------+------+------| State 19| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 19-4 | |------+------+------+------+------+------+------+------| State 20| 21-5 | 1-21| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 20-4 | |------+------+------+------+------+------+------+------| State 21| 1-21| 1-21| 1-16| 1-16| 1-16| 1-16| 1-16| 21-4 | |------+------+------+------+------+------+------+------| State 22| 2-5 | 1-25| 11-22| 16-1 | 1-13| 13-23| 1-27| 1-4 | |------+------+------+------+------+------+------+------| .fi .sp 3 NOTES ON THE STATES .sp 2 .in 5 .un 4 1. Starting state. Return to this state after parsing a token or after a lexical error. Except if a decimal integer token is followed by an "h" or "H", the lexical analyzer will be in this state when called to parse the next token. .sp 2 .un 4 2. Enter this state if the token starts with any alphabetic character. .sp 2 .un 4 3. Enter this state if the token starts with a digit. .sp 2 .un 4 4. Enter this state from state 3, 5, or 20. The token contains digits and a decimal point. .sp 2 .un 4 5. Enter this state if the token starts with a decimal point. .sp 2 .un 4 6. Build keyword operator. Enter this state from state 5. .sp 2 .un 4 7. Asterisk starts a token. Enter this state from state 1 or 22. .sp 2 .un 4 8. Building float decimal token. Enter this state if a fixed decimal token is followed by a "d", "e", "D", or "E". Entered from state 4. .sp 2 .un 4 9. Enter this state from state 3. A decimal integer is followed by a "d", "e", "D", or "E". This is either a floating decimal like 60e-4 or a statement label followed by an identifier like: .sp 2 .un -5 60 eta = 0.0 .sp 2 .un 5 10. Enter this state from state 9. Something of the form 60e4 has been found. It is either a float decimal token or decimal integer followed by identifier. .sp 2 .un 5 11. Building a character string delimited by a quote character ("). This state is entered if the first character of a token is a quote. .sp 2 .un 5 12. Quote inside a quote delimited string. .sp 2 .un 5 13. Building a character string delimited by "'". This state is entered if the first character of a token is "'". .sp 2 .un 5 14. "'" inside a "'" delimited string. .sp 2 .un 5 15. Build identifier with "$". Enter this state from state 2. .sp 2 .un 5 16.{{"$" starts token. .sp 2 .un 5 17. Build a label argument. Enter this state from state 16. .sp 2 .un 5 18. Build the exponent field of a float decimal token. Enter this state from state 8, 19, or 21. .sp 2 .un 5 19. Another floating decimal state. Enter this state from state 8, 9, or 21. .sp 2 .un 5 20. Is the decimal point following a decimal integer part of the number or is it a keyword operator? Enter this state from state 3. .sp 2 .un 5 21. Is this a decimal integer followed by a keyword operator, or a float decimal token. Enter this state from state 20. .sp 2 .un 5 22. Enter this state if a dec_integer token was returned the last time, and the character following it was h or H. .in 0 .sp 3 NOTES ON THE ACTIONS .sp 2 These actions are performed in the procedure cardlex. They are chosen on a character/state basis. .sp 2 .in 5 .un 4 1. (c) Concatenate this character to the token and continue. .sp 2 .un 4 2. (d) The current character is not part of the current token being formed. Return the token as formed. This character will be the first character evaluated on the next call to this procedure. .sp 2 .un 4 3. (it) This character is the last (or only) character of the token. Concatenate it and return the token. .sp 2 .un 4 4. (sk) This character should be skipped. This action is usually used to ignore white space within a state. .sp 2 .un 4 5. (ca) This character is a letter. Make sure that it is lower case in the source segment, and in the source segment being created and then concatenate it to the token and continue. .sp 2 .un 4 6. (cq) A quote appears inside a "'" delimited string. If a new source segment is being created, the quote character must be doubled. This is due to the fact that the "'" is changed to a quote. .sp 2 .un 4 7. (cq2) The sequence '' appears within a string delimited by a "'". If a new source segment is being created, only one "'" should appear. This is due to the fact that the delimiter is a quote. .sp 2 .un 4 8. (bk_de) A "d", "e", "D", or "E" immediately followed a decimal integer token. The character offset of this character was saved and parsing continued to resolve the ambiguity. This action resets the parser so that the next character it parses will be the "d", "e", "D", or "E" immediately following the decimal integer. The decimal integer token is returned. .sp 2 .un 4 9. (cit) Concatenate this character and return the completed token. This action is used exclusively to create the expon token. .sp 2 .un 5 10. (it_exp) The current character is a "^". Return an expon token. .sp 2 .un 5 11. (cs_de) A "d", "e", "D", or "E" immediately follows a decimal integer. Save the current token length, and the character offset of the letter; then concatenate the letter to the token and continue. .sp 2 .un 5 12. (cit_kw) The current character is a decimal point. It is the last character of a keyword operator. Concatenate it and then look the keyword up in our table. Return the proper operator token or print an error message. .sp 2 .un 5 13. (e1) An invalid character starts a token. Print a message and get another token. .sp 2 .un 5 14. (e7) An invalid character follows a decimal point. Print a message and get another token. .sp 2 .un 5 15. (e8) Invalid character in a keyword operator. Print an error message and get another token. .sp 2 .un 5 16. (e10) Invalid character in exponent field. Print message and return a float decimal token. .sp 2 .un 5 17. (e2) Character string is missing a delimiter. Print message and get another token. .sp 2 .un 5 18. (e19) Invalid character follows a "$". Print message and get another token. .sp 2 .un 5 19. (dd) Return an asterisk token. .sp 2 .un 5 20. (cs_c) A decimal point immediately follows a decimal integer. Save the token length and the character offset; then concatenate the decimal point and continue. .sp 2 .un 5 21. (bk_c) The decimal point following the decimal integer is not part of the token. Reset the parser so that the next character parsed is the decimal point and return the decimal integer token. .sp 2 .un 5 22. (ststr) Turn on indicators that will indicate we are inside a character string. Needed when terminating a line. .sp 2 .un 5 23. (apos) Current character is "'". If fortran_stat_$apostrophe_mode is on, return an apostrophe token. Otherwise, turn on indicators that will indicate we are inside a character string. Needed when terminating a line. .sp 2 .un 5 24. (dsh) A decimal integer is followed by an "h" or "H". Return the decimal integer token but save a pointer to it. .sp 2 .un 5 25. (gh) A decimal integer was followed by an "h" or "H". Return a character string of the specified length. .sp 2 .un 5 26. (d_str) A quote delimited string was just terminated. Make sure that the line was terminated correctly. This action is provided to keep the created segment neat. Due to the way a character string is delimited, a character string that is the last token before the newline character would have a "%" following it. This state eliminates unneeded "%". .sp 2 .un 5 27. (none) End of statement encountered. Get another token. .sp 2 .un 5 28. (dstr) A "'" delimited string was just terminated. If a new source segment is being created, change "'" to a quote and perform action 26. .in 0 .sp 3 P_R_O_C_E_D_U_R_E_ -- cardlex .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses FORTRAN card-image source text. It is the only parser used if -card or -convert option is supplied by the user. It produces tokens, one per call, from the source text. .sp 2 This parser was designed to interact with statement_recognizer rather than parse an entire statement per call. This design was chosen to keep the parser innocent of semantics. Two cases require semantic knowledge: .sp 2 .in +5 .un 5 o{{{{A decimal integer followed by an "h" or "H" is either a statement label followed by a identifier starting with "h" or "H", or is a hollerith constant. .sp 2 .un 5 o{{{{The character "'" is either a string delimiter or an operator. .in -5 .sp 2 Semantic information is conveyed to cardlex through two external switches. If fortran_stat_$hollerith_mode is on, a decimal integer followed by an "h" or "H" is a hollerith constant. If fortran_stat_$apostrophe_mode is on, an encountered "'" is an operator. .sp 3 expand_log_const (internal procedure) .sp 2 This procedure is invoked when .t. or .f. appear in the source text and the -convert option was specified. This procedure replaces .t. with .true. and .f. with .false. in the source segment being created. If the operator is split across a card boundary, the entire constant will appear on the continuation line. .sp 3 flex_create_token (internal procedure) .sp 2 The logic in this procedure is derived from the include file create_token. It creates a token node and stores a pointer to it in the proper entry in the token hash table. .sp 3 initialize_lexer (internal procedure) .sp 2 This is an entry in flex_create_token that initializes the hash table. .sp 3 read_image (internal procedure) .sp 2 This procedure is the heart of the parser. It divides the source segment into card images. A card image is: .in +2 .un 2 .sp 1 o{all the text between two consecutive newline characters .sp 1 .un 2 o{all the text between the beginning of the segment and the first newline character .sp 1 .un 2 o{all the text between the last newline character and the end of the segment as specified by the bit count .sp 1 .un 2 o{the entire segment if there are no newline characters. .in -2 .sp 2 If the first character of the card image is "C", "*", or "c", the card image is a comment. If the sixth character is zero, blank, or tab, or the card image is not six characters long, the card image is an initial line. Anything else is a continuation line. .sp 2 This procedure returns after isolating an initial or continuation line. Comment lines are handled internally. If the end line is missing, or a parse error occurs, this procedure is called after the end of text is encountered. In this case the procedure manufactures a card image consisting of a semicolon followed by an end line. That should terminate compilation normally. .sp 2 If a listing segment is produced, this procedure calls pl1_print$for_lex to print each line of the source segment as it is parsed. .sp 3 terminate_line (internal procedure) .sp 2 This procedure converts card image continuation conventions to Multics continuation conventions if a new source segment is being created. Multics requires no explicit mark of continuation unless a token is split across two lines. .sp 2 Blank and tab characters that appear in the created segment immediately preceding a newline character are called trailing white space. Trailing white space is eliminated if it is not part of a character string token. Trailing white space can be introduced if the original source segment contained nonblank characters after column 72. .sp 2 If a token is being continued, a "%" is inserted. .sp 2 A newline character is inserted. .sp 2 A tab character is inserted, except if a character string is being continued. .sp 3 snare_char (internal procedure) .sp 2 This procedure insures that 72 characters are read from each card image. If a card image is less than 72 characters long, the difference is made up in space characters. If a card image is longer that 72 characters, all the characters after the 72nd are ignored. .sp 2 This procedure will not return to its caller if it cannot get another character. This will only occur when there are no more continuation cards for this statement. The character returned in this case is a newline. Control is redirected through the label variable "end_of_text". .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 cardlex entry(pointer, fixed bin(15)) .sp 2 Both arguments are return arguments. .in +5 .un 5 1. A pointer to the token created during this invokation of the procedure. .un 5 2. Character offset of the last character of this token relative to the base of the segment. This offset is used by error printing routines to determine how much of the segment to print. .in -5 .sp 3 .un 5 initialize_lex entry(pointer, fixed bin(15)) .sp 2 Both arguments are input arguments. .in +5 .un 5 1. A pointer to the source segment. It is assumed that this pointer has no character offset. .un 5 2. The character count for the source text. .in -5 .sp 2 This information is stored in internal static and used for the duration of the compilation. The token hash table is reset to no entries. Write access to the source segment is assumed and required. .sp 3 .un 5 write_last_line entry .sp 2 No arguments. After an end line is parsed, this entry is called to print the last line and check for text after the end line. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .nf .sp 2 initialize_lex .sp 1 fortran_parse .sp 3 cardlex .sp 1 statement_recognizer .sp 3 write_last_line .sp 1 statement_recognizer .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 parse_error -- 75, 76, 77, 78, 81, 82, 83, 84, 168, 169, 171, 172. pl1_get pl1_print$for_lex token_to_binary .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 card_lex_data fortran_stat_$apostrophe_mode fortran_stat_$convert_len fortran_stat_$convert_ptr fortran_stat_$convert_switch fortran_stat_$cur_statement fortran_stat_$expl_continuation_count fortran_stat_$hollerith_mode fortran_stat_$listing_on fortran_stat_$pathname fortran_stat_$seg_name fortran_stat_$source_ptr pl1_stat_$hash_table pl1_stat_$node_uses pl1_stat_$source_list_ptr tree_$ .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 create_token language_utility nodes rename source_id_descriptor source_list token token_list token_types .fi .in 0 .sp 3 P_R_O_C_E_D_U_R_E_ -- dcl .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure contains three independent blocks of code. The first is the declaration processor, the second is implicit declaration , and the last is the parser for implicit statements. .sp 3 DECLARATION PROCESSOR .sp 2 After all declaration statements have been parsed, and before executable statements are parsed, the declaration processor is called to fill in missing attributes for all symbol nodes in the symbol table. Symbols in the symbol table either appeared in the parameter list of the subprogram statement or in a declarative statement. The declaration processor assigns a storage class or mode if the user did not. .sp 2 The reference nodes for these symbols are completed at this time. .sp 2 The storage offsets are calculated for members of a common block. The first member of the block encountered triggers the processing for each block. .sp 2 If an array has variable bounds it must be a parameter or in automatic storage. Its bounds must be parameters, internal static, or in common. If the bounds are not parameters, the user is warned that bounds may not be defined at block activation. .sp 2 If a runtime symbol table is to be generated, array information from the symbol node is copied into the proper fields. .sp 2 The following statements are recognized as nondeclarative: .sp 2 .nf .in 5 Data Statement Entry Statement Equivalence Statement Namelist Statement Statement Function Definition Any Executable Statement .fi .in 0 .sp 3 IMPLICIT DECLARATIONS .sp 2 After all declarative statmements have been parsed, undeclared variables are declared according to the current implicit rules. If a variable does not begin with an alphabetic character, no data mode is assigned. .sp 2 The variables are placed in internal static storage. .sp 3 IMPLICIT STATEMENT PARSE .sp 2 The implicit statement is parsed piece by piece. A syntax error at the end of the statement will not prevent the preceding specifications from being used. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 declaration_processor entry .sp 2 No arguments or return arguments. .sp 3 .un 5 implicit_parse entry .sp 2 No arguments or return arguments. .sp 3 .un 5 make_declaration entry(pointer) returns(pointer) .sp 2 Input argument is a pointer to a token node. The token is an identifier. .sp 2 Return is a pointer to the reference node for the symbol created for the token. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf declaration_processor .sp 1 fortran_parse .sp 3 implicit_parse .sp 1 fortran_parse .sp 3 make_declaration .sp 1 declaration_parse fortran_io_parse fortran_reference_parse fortran_subroutine_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 copy_expression create_cross_reference create_operator create_statement$prologue create_symbol declare_descriptor error -- 21, 122, 139. parse_error -- 36, 37, 38, 39, 40, 73, 140, 173. statement_recognizer$back_up statement_recognizer$next_token token_to_binary type$fix_array_sizes .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$card_input fortran_stat_$cur_block fortran_stat_$modetable fortran_stat_$table .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 array block boundary cross_reference declare_type fortran language_utility nodes op_codes operator reference source_id_descriptor statement statement_types symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- declaration_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 3 This procedure parses the following statements: .sp 1 .in +5 .nf Abnormal Automatic Character Common Complex Data Dimension Double Precision Equivalence External Integer Logical Namelist Real .fi .in -5 .sp 2 Each statement type has a separate entry point, but all rely on the internal procedure list_parse to parse the statement. .sp 2 Except for data, equivalence, and namelist statements, these statements are parsed before the declaration processor processes the symbol table. In order to be brief, those statements that are parsed before the declaration processor will be called declarative statements in this description. .sp 2 The procedure checks for semantic as well as syntax errors, however, semantics checking for declarative statements is minimal, to allow the user to specify attributes in any order. The major semantic check is to thwart an attempt to declare attributes that conflict with existing ones. .sp 2 This procedure is invoked when the proper statement type is recognized. Two masks are set up by each entry point. One is the attribute bits to be turned on and the other is those attributes that conflict with the former attributes. .sp 2 Mode, Automatic, External, and Dimension statements are compiled by adding the new attributes after checking for conflicting attributes. .sp 2 Common statements cause the block name to acquire the structure and external attributes, and each member acquires the member attribute. In order to assign storage to the common block, the members are chained in order of appearance. During declaration processing, offsets in the block can be assigned by walking the chain. .sp 2 Data statements are parsed first by list_parse. When a slash is encountered, list_parse returns a chained list of references. These references are passed to initial_attribute which parses the data initializations and then returns. This process is repeated until the entire statement is parsed. This process is also performed for mode statements that have data initializations. .sp 2 Equivalence statements are parsed one group at a time. The first reference in the group is taken as the base, and a structure is declared with the offsets juggled to implement the equivalence specification. If the base is a member of common, the common block can be used as the base reference. .sp 2 Namelist statements are parsed and the namelist name is given the namelist attribute. The members of the namelist are put in an OK list. If the namelist group is referenced, these variables as well as the namelist name will always have storage generated, whether or not they are referenced individually. .sp 3 .in 5 .un 5 list_parse (internal procedure) .sp 2 Parses a general FORTRAN declaration list. It contains several label arrays that are used to choose the special processing required by statements. Each statement type is assigned an internal type number and this number is used to reference these label arrays. .sp 2 .nf 0. Dimension 1. Mode 2. Data 3. Implied Do Loop 4. External 5. Common 6. Equivalence 7. Automatic 8. Outer Equivalence 9. Namelist 10. Abnormal .fi .sp 2 .in +5 .un 5 action -- The symbol already has a declaration. A symbol is considered declared by_declare if it only appears as a parameter in the subprogram statement and declarative statements. .sp 2 For all statement types, this label array results in a cross reference node being generated. .sp 2 .un 5 action0 -- The identifier is not declared. If this is a declaration statement, just create a symbol. Otherwise, make a default declaration. .sp 2 .un 5 action1 -- The list starts with a left parenthesis. This is invalid for declarative and namelist statements. For data statements, the parenthesis indicates the beginning of an implied do group. For equivalence statements, the parenthesis indicates the beginning of the equvalence group. .sp 2 .un 5 action2 -- The new attributes have been added to the symbol node. Now any special processing is performed. For a common statement, each individual member must be added to the common block chain. Before the member is added the common block name must be declared. .sp 2 For external statements, if the symbol has been given a data mode, then the symbol is probably a function so declare a return value for it. If it is not, see if it is an external builtin. If "(abnormal)" follows the symbol, skip it if -card options is specified. .sp 2 For mode statements, it is possible that the symbol is actually a function and therefore the mode refers to the return value. Move the mode attributes to the return value. .sp 2 If a symbol is declared with double precision or complex mode and it is a parameter, change its alignment to word from double word. .sp 2 For data statements, build an fdata node for the symbol. .sp 2 For namelist statements, chain the members together. .sp 2 For dimension and automatic statements, no special processing is required. .sp 2 .un 5 action3 -- The list starts with a slash. This is invalid for all statements except common and namelist. .sp 2 For common blocks, the common name is parsed. If no name appears, assignment will be to blank common. .sp 2 For namelist groups, the previous group is processed, if such exists, and then the namelist name is parsed. There must be a namelist name. .sp 2 .un 5 action4 -- The symbol is not followed by array specifications. .sp 2 For equivalence statements, the symbol can now be processed. The offset specified by the reference node is the offset. .sp 2 Symbols in a dimension statement must have array specifications. .sp 2 For all others, parsing continues. .sp 2 .un 5 action5 -- Action after array specifications have been parsed. .sp 2 For data statements, the symbol must have the dimensioned attribute. The subscripts can be both constants and active implied do group indices. The fdata node for the symbol is set to indicate the subscripts specified. .sp 2 For equivalence statements, the symbol must have the dimensioned attribute. The subscripts must be positive constants. A new constant offset is calculated for this reference to the symbol. .sp 2 For dimension, mode, common, automatic, and namelist statements, the symbol is given the dimensioned attribute and the array specifications are stored in the symbol node. .sp 2 .un 5 action6 -- Appears in procedure list_end in order to allow various statement termination syntax. All of the statements are considered terminated if a semicolon is encountered. .sp 2 A comma will terminate an implied do group if it is the comma that immediately precedes the do group index. A right parenthesis will also terminate the group. A slash will terminate a mode or data statement list. .sp 2 A right parenthesis will terminate an equivalence group. .in -5 .sp 2 This procedure starts parsing at the beginning of the statement's list. The procedure consists of a single loop that is executed once for each member of the list. Special syntax or processing is handled through the use of the abovementioned label arrays. .sp 2 The basic flow of the procedure is: .in +5 .sp 2 .un 5 o{{{{If the first token of the list is a left parenthesis, use label array "action1" to determine the next step. If the first token of the list is not a left parenthesis and this is an equivalence statement, print an error message and process this list anyhow. .sp 2 .un 5 o{{{{If the first token of the list is a slash, use label array "action3" to determine the next step. .sp 2 .un 5 o{{{{Get the symbol node for the next element of this list. If it does not exist, use label array "action0" to create it. If it does exist, use label array "action" to determine if its declare type should be by_declare. .sp 2 .un 5 o{{{{Create a cross reference node for this list element. .sp 2 .un 5 o{{{{If the existing symbol attributes conflict with the new ones, print an error and skip this list element. .sp 2 .un 5 o{{{{Add the new attributes, then use label array "action2" to determine if there is any special processing required. .sp 2 .un 5 o{{{{If the symbol is followed by a left parenthesis, parse the bounds and then use label array "action5" to determine what to do with them. Otherwise use label array "action4" to determine what to do without them. .sp 2 .un 5 o{{{{Processing the the element is complete, determine if the list is complete. If it is return. Otherwise, repeat this process for the next element. .in -5 .sp 3 .un 5 list_end_test (internal procedure) .sp 2 Determines if the list is complete or if there is another element. In most cases, if the next token is not a comma the list is terminated. See label array "action6" above. .sp 3 .un 5 create_namelist (internal procedure) .sp 2 Creates an OK list for each namelist group parsed. It performs the required semantic validation for the namelist name. .sp 3 .un 5 next_token (internal procedure) .sp 2 Returns the next non-newline token. .sp 3 .un 5 get_sizes (internal procedure) .sp 2 Parses the *_k field of a mode statement. .sp 3 .un 5 get_integer (internal procedure) .sp 2 Gets the next token and ascertains if it is a fixed binary constant. .sp 3 .un 5 declare_bounds (internal procedure) .sp 2 Creates bound and array nodes for a symbol being dimensioned. .in 0 .sp 3 U__s_a_g_e .sp 2 The usage for all of the entry points is the same. They have no arguments and return no values. .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 .nf builtin_function$lookup_external create_array create_bound create_cross_reference create_list create_operator create_symbol create_token dcl$make_declaration declare_constant declare_constant$integer declare_temporary initial_attribute parse_error -- 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 25, 26, 27, 30, 31, 43, 140, 153, 154, 170, 178. statement_recognizer$back_up statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$card_input fortran_stat_$cur_block fortran_stat_$cur_statement fortran_stat_$equivalence_base fortran_stat_$list3_node fortran_stat_$list5_node fortran_stat_$ok_list .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 array block boundary cross_reference declare_type fdata_nodes fortran language_utility list nodes op_codes operator reference source_id_descriptor statement statement_types symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- flex .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is the standard Multics lexical analyzer. It is called to parse the user's source segment unless the -card or -convert option is given. .sp 2 This parser only parses one token per call. This design was chosen to keep the parser innocent of semantic knowledge. Only a procedure with semantic knowledge can decide if a decimal integer followed by an "h" is a hollerith constant. .sp 2 .in 5 .un 5 flex_create_token (internal procedure) .sp 1 Creates a token node and stores a pointer to it in the token hash table. The logic used to store the pointer is used by all routines that create tokens and is an include file create_token. .sp 2 .un 5 get_next_char (internal procedure) .sp 1 Returns after placing the next character of the source segment in input_char. If there are no more characters left in the segment, an error message is printed, the source pointer is fudged to point at a semicolon followed by an end line, and control is passed to the label variable "end_of_text". If a "%" is immediately followed by an newline, both characters are skipped. .sp 2 .un 5 initialize_lexer (internal procedure) .sp 1 An entry point in flex_create_token. This entry point is called to reset the token hash table. .sp 2 .un 5 print_line (internal procedure) .sp 1 Counts line numbers and prints the lines of the source segment as they are parsed. Printing is only done if the user requests it. .in 0 .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 flex entry(pointer, fixed bin(15)) .sp 1 Both arguments are return arguments. .in +4 .un 4 1. A pointer to the token parsed during this call. .un 4 2. Character offset of the last character of this token relative to the base of the segment. This offset is used by error printing routines to determine how much of the segment to print. .in -4 .sp 2 .un 5 initialize_lex entry(pointer, fixed bin(15)) .sp 1 Both arguments are input arguments. .in +4 .un 4 1. A pointer to the source segment. It is assumed that this pointer has no character offset. .un 4 2. The character count for the source text. .in -4 .sp 2 This information is stored in internal static and used for the duration of the compilation. The token hash table is reset to no entries. .sp 2 .un 5 write_last_line entry .sp 1 No arguments. After an end line is parsed, this entry is called to print the last line and check for text after the end line. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .nf .sp 2 initialize_lex .sp 1 fortran_parse .sp 3 cardlex .sp 1 statement_recognizer .sp 3 write_last_line .sp 1 statement_recognizer .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 parse_error -- 75, 76, 77, 78, 81, 82, 83, 84. pl1_get pl1_print$for_lex token_to_binary .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 ftn_lex_data fortran_stat_$expl_continuation_count fortran_stat_$hollerith_mode fortran_stat_$listing_on fortran_stat_$pathname fortran_stat_$seg_name fortran_stat_$source_ptr pl1_stat_$hash_table pl1_stat_$last_source pl1_stat_$node_uses pl1_stat_$source_list_ptr tree_$ .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 create_token language_utility nodes rename source_id_descriptor source_list symbol token token_list token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is the command program for the FORTRAN compiler. It is the only part of the compiler the user references directly. This procedure performs the following functions: .sp 2 .in 5 .un 5 o{{{{Prints the message "fortran". .sp 1 .un 5 o{{{{Maintains metering information about this compiler. .sp 1 .un 5 o{{{{Prints the blast message, if it exists. .sp 1 .un 5 o{{{{Switches and pointers that control the compiler are reset to default or initial values. .sp 1 .un 5 o{{{{The compiler attempts to get a pointer to "fortran_version_". If it is found, it is assumed that it is an ASCII segment and the first line contains version information. If the segment is not found, the version is "Multics FORTRAN Compiler.". .sp 1 .un 5 o{{{{The compiler attempts to get a pointer to "fortran_error_messages_". If it fails an error message is printed. Compilation continues in any event. This segment is assumed to contain error text. If this segment is not found, or is unintelligable, a severity of 2 is assigned and no error text is printed. .sp 1 .un 5 o{{{{Scans the user supplied options including the relative pathname of the segment to be compiled. All options are scanned although any error will prevent compilation. .sp 1 .un 5 o{{{{The source segment is initiated. If the first character of the source segment is a "%", expand_ is called to get include files. .sp 1 .un 5 o{{{{If any listing option is given, a listing file is initiated. Compilation information is put in the file. This includes source segment name, compiler name (version), compilation date, and compilation options. This file is maintained by interfacing through tssi_. .sp 1 .un 5 o{{{{If a converted source segment is to be created, it is initiated. If the segment cannot be created or if it is the same segment as the source segment, compilation is aborted. .sp 1 .un 5 o{{{{A handler is enabled for the listing_overflow condition. This condition will be raised by the print routines if a multi-segment file must be created or if another component of the multi-segment file is needed. .sp 1 .un 5 o{{{{A default error handler is enabled for the compiler. It will handle most faults that could occur and allows the compiler to abort gracefully. .sp 1 .un 5 o{{{{The three phases of the compiler are called. Interspersed among the calls is metering code. Before the code generator is called, an object segment is created. If it is the same segment as any of the others, compilation is aborted. .in 0 .sp 2 The entry point times may be called after a compilation to print timing information for the immediately preceding compilation. .sp 2 The entry point epilogue should be called to clean up after a compilation if one of the -debug options was given. .sp 2 The entry point blast should be called to deal with the blast message. This message can be set, turned on, or turned off by this entry. This message is generally used to inform compiler users of quirks. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran entry options(variable) .sp 1 This entry is called with at least one char(*) argument. Most of the valid arguments are discussed in the MPM. Some of the options to the compiler are useful primarily for debugging and testing and therefore do not appear in the MPM. .sp 2 .in +5 .un 5 -assembly .br A listing segment is created which only contains an object listing of the segment. Source, symbol table, and map are suppressed. .sp 2 .un 5 -cpdcls .br Compiler generated symbols are included in the symbol table listing. .sp 2 .un 5 -debug .br This option performs several functions. All segments initiated by the compiler will not be terminated or truncated at the end of the compilation. Used in conjunction with the Multics command stop_at, the compiler can be made to stop before the parsing of any statement. .sp 2 .un 5 -debug_cg .br The compiler will call the Multics debugger, debug, before calling the code generator. All segments initiated by the compiler will not be terminated or truncated at the end of the compilation. Used in conjunction with the Multics command stop_at, the code generator can be made to stop before generating code for any statement. .un 5 -link .br A link will be snapped to pl1_operators_ rather than getting the pointer from the stack header. .in -5 .sp 2 .un 5 times entry .sp 1 No arguments. .sp 2 .un 5 epilogue entry .sp 1 No arguments. .sp 2 .un 5 blast entry options(variable) .sp 1 If the first argument is "-on", blast messages are enabled. If the first argument is "-off", blast messages are disabled. If the first argument is "-set", the second argument becomes the blast message. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 The procedure fortran is invoked by the user. .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 .in 5 .un 5 clock_ -- Called to specify the last time a blast message was printed for the user. Called to specify time user subprogram was compiled. Called to specify time the blast message is set. .sp 2 .un 5 code_gen_ -- Called to generate object code for the compiler. .sp 2 .un 5 code_gen_$return_bit_count -- If listing segment overflow aborts the compilation, this entry gets the current bit count of the object segment. .sp 2 .un 5 com_err_ -- Called everywhere an error message has to be printed. .sp 2 .un 5 cu_$arg_ptr -- Called to get pointers to the arguments passed to an entry which has the options(variable) attribute. .sp 2 .un 5 cv_dec_ -- Called to convert line length of the user's terminal to fixed binary. .sp 2 .un 5 date_time_ -- Called to convert the time of this compilation to a character string for use in the listing segment. .sp 2 .un 5 debug -- Called before code_gen_ is called if -debug_cg was given. .sp 2 .un 5 default_handler$set -- Called to enable the compiler's default signal handler. This handler will allow the compilation to abort gracefully if a compiler error causes a fault. .sp 2 .un 5 error_$finish -- Called at the end of a compilation to finish up error printing for the compiler. .sp 2 .un 5 establish_cleanup_proc_ -- Called at th beginning of a compilation to set up a cleanup handler. This handler truncates the tree segments, if no -debug option was given and terminates source, object, and listing segments. .sp 2 .un 5 expand_ -- Called to expand any include files if the first character of the source segment is "%". .sp 2 .un 5 expand_path_ -- Called to get the absolute pathname of the user's source segment. .sp 2 .un 5 fortran_parse -- Called to parse the user's source segment and produce the internal representation. .sp 2 .un 5 fortran_symbol_print -- The address of this routine is passed to the code generator. It is called by the code generator to print symbol table information in FORTRAN compilation listings. .sp 2 .un 5 get_group_id_ -- Called to set the field fortran_stat_$user_id. .sp 2 .un 5 get_wdir_ -- Gets the current working directory pathname. Listing and object segments are placed in this directory. .sp 2 .un 5 hcs_$delentry_seg -- Deletes the copy of the source segment created for this compilation if the -card or -convert option was specified. .sp 2 .un 5 hcs_$get_max_length_seg -- Get the max length for each component of the listing segment or the max length of the listing segment. .sp 2 .un 5 hcs_$get_usage_values -- Gets time and paging information for various phases of the compiler. .sp 2 .un 5 hcs_$initiate_count -- Gets a pointer to the source segment or if -card or -convert, a pointer to a copy of the source segment. .sp 2 .un 5 hcs_$make_ptr -- Finds the segments "fortran_version_" and "fortran_error_messages_" or makes a pointer to a null segment. .sp 2 .un 5 hcs_$terminate_noname -- Terminates the source segment and the source segment being created. .sp 2 .un 5 hcs_$truncate_seg -- Sets the length of the object segment and of the source segment created as a result of the -convert option. .sp 2 .un 5 ioa_ -- Prints the following messages: .in +4 .nf "fortran" Blast message Timing messages "accepted" (When setting blast message) .fi .in -4 .sp 2 .un 5 ioa_$nnl -- Prints message "Begin code generator DB" if debug is called before the code generator is called. .sp 2 .un 5 ios_$changemode -- Gets the current line length of user_output. If user_output has no line length, a line length of 120 characters is used. .sp 2 .un 5 msf_manager_$get_ptr -- Creates the n_t_h component of a multi segment listing file. .sp 2 .un 5 optimizer -- Optimizes the internal representation if the -optimize option was given. .sp 2 .un 5 pl1_print$non_varying -- Puts a string in the listing segment but does not append a newline character. .sp 2 .un 5 pl1_print$non_varying_nl -- Puts a string in the listing segment and appends a newline character after it. .sp 2 .un 5 pl1_print$varying_nl -- Puts a varying string in the listing segment and appends a newline character after it. .sp 2 .un 5 pl1_signal_catcher -- This is the name of the default error handler enabled during a compilation. It handles errors which are due to compiler bugs neatly. This includes conditions like reference through a null pointer, etc. .sp 2 .un 5 prepare_symbol_map_ -- This procedure is called by the code generator to format the symbol map. .sp 2 .un 5 record_command_usage_$enter and record_command_usage_$exit -- These cause metering information about the FORTRAN compiler to be gathered. .sp 2 .un 5 revert_cleanup_proc_ -- Disables the compiler's cleanup procedure. .sp 2 .un 5 tree_manager$init and tree_manager$truncate -- Initialize and truncate the tree storage area. .sp 2 .in 0 .nf tssi_$clean_up_file tssi_$clean_up_segment tssi_$finish_file tssi_$finish_segment tssi_$get_file tssi_$get_segment .fi .in 5 These procedures create, maintain, and terminate files created by the compiler. These are the listing file and the segment created for -convert option. .in 0 .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 .nf cg_static_$debug cg_static_$stop_id error_table_$badopt error_table_$entlong error_table_$noarg error_table_$translation_failed error_table_$zero_length_seg fortran$ fortran_blast_$blast_message fortran_blast_$blast_on fortran_blast_$blast_time fortran_stat_$abort_label fortran_stat_$brief_error_mode fortran_stat_$card_input fortran_stat_$char_pos fortran_stat_$check_bounds fortran_stat_$compiler_name fortran_stat_$constant_list fortran_stat_$convert_len fortran_stat_$convert_ptr fortran_stat_$convert_switch fortran_stat_$debug_semant fortran_stat_$dummy_block fortran_stat_$error_messages fortran_stat_$error_width fortran_stat_$generate_symtab fortran_stat_$greatest_severity fortran_stat_$list_ptr fortran_stat_$listing_on fortran_stat_$max_list_size fortran_stat_$ok_list fortran_stat_$options fortran_stat_$pathname fortran_stat_$phase fortran_stat_$print_cp_dcl fortran_stat_$profile_length fortran_stat_$root fortran_stat_$seg_name fortran_stat_$severity_plateau fortran_stat_$source_index fortran_stat_$source_ptr fortran_stat_$stop_id fortran_stat_$table fortran_stat_$temporary_list fortran_stat_$user_id .fi .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 No include files for this procedure. .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_ .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This is the incoming transfer vector for the FORTRAN compiler. Currently it is used by the code generator to find the procedure fortran_io_op. .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_assign_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses assignment statements, assign statements and parameter statements. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_assign_parse entry (pointer, pointer, fixed bin(15)) .sp .in +5 .un 4 1. A pointer to the statement node for this statement. .sp .un 4 2. A pointer to the current block node. .sp .un 4 3. The statement type code. Type 1 is assign, 2 is assignment, and 47 is parameter. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_parse fortran_if_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 create_operator create_symbol create_token make_label parse_error -- 44,45,46,47,48,130,158,159,160,161. statement_recognize$back_up statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 None .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 declare_type fortran label language_utility nodes op_codes operator reference source_id_descriptor statement symbol token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_crse_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses call, return, stop, end, and parse statements. .sp 2 Call statements are actually parsed by fortran_reference_parse$call, however this procedure insures that the statement terminates correctly. .sp 2 Return statements are parsed by this procedure and tree nodes are generated. Abnormal return statements generate code to special case a return value of 0. .sp 2 For end statements, a standard return operator is generated. Nothing else is done by this procedure. .sp 2 For stop and pause statements, the statement is parsed and a standard call, with descriptors is generated. .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_if_parse fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 convert$to_target create_array create_bound create_label create_list create_operator create_statement create_symbol create_token declare_constant$char declare_constant$integer declare_temporary fortran_expression_parse fortran_reference_parse$call fortran_reference_parse$make_call fortran_reserve$declare_lib fortran_subscripter parse_error -- 59, 60, 61, 62, 63, 95 statement_recognizer$back_up statement_recognizer$next_token token_to_binary .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 .un 10 None .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 array block boundary declare_type fortran label language_utility list nodes op_codes operator reference source_id_descriptor statement_types statements symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_data .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This ALM segment constitutes the table of builtin functions for the compiler. Presently it specifies the following: .sp 2 .in 5 .nf # Name Args Opcode Indx Args Result Generic Table .sp 1 1 abs 1 010010100 real27 real27 40 1 22 13 2 aimag 1 010101010 cmpx27 real27 3 aint 1 010010101 real27 real27 4 alog 1 100111110 10 real27 real27 0 4 30 16 5 alog10 1 100111111 13 real27 real27 0 5 31 0 6 amax0 >_2 011000001* int35 real27 7 amax1 >_2 011000001 real27 real27 8 amin0 >_2 011000000* int35 real27 9 amin1 >_2 011000000 real27 real27 10 amod 2 010100100 real27 real27 11 atan 1 100111011 21 real27 real27 0 11 23 0 12 atan2 2 100111011 23 real27 real27 0 12 24 0 13 cabs 1 26 cmpx27 real27 14 ccos 1 20 cmpx27 cmpx27 15 cexp 1 9 cmpx27 cmpx27 16 clog 1 12 cmpx27 cmpx27 17 cmplx 2 010100010 real27 cmpx27 18 conjg 1 010100011 cmpx27 cmpx27 19 cos 1 100110011 18 real27 real27 0 19 26 14 20 csin 1 17 cmpx27 cmpx27 21 csqrt 1 6 cmpx27 cmpx27 22 dabs 1 010010100 real63 real63 23 datan 1 100111011 22 real63 real63 24 datan2 2 100111011 24 real63 real63 25 dble 1 000110001 real27 real63 26 dcos 1 100110011 19 real63 real63 27 ddim 1 011000010 real63 real63 28 dexp 1 101000000 8 real63 real63 29 dim 2 011000010 real27 real27 41 29 27 0 30 dlog 1 100111110 11 real63 real63 31 dlog10 1 100111111 14 real63 real63 32 dmax1 >_2 011000001 real63 real63 33 dmin1 >_2 011000000 real63 real63 34 dmod 2 27 real63 real63 35 dsign 2 010010110 real63 real63 36 dsin 1 100110001 16 real63 real63 37 dsqrt 1 100110000 5 real63 real63 38 exp 1 101000000 7 real27 real27 0 38 28 15 39 float 1 000110001 int35 real27 40 iabs 1 010010100 int35 int35 41 idim 2 011000010 int35 int35 42 idint 1 010010101 real63 int35 43 ifix 1 000110001 real27 int35 44 int 1 010010101 real27 int35 45 isign 2 010010110 int35 int35 46 max >_2 real27 real27 47 7 32 0 47 max0 >_2 011000001 int35 int35 48 max1 >_2 011000001* real27 int35 49 min >_2 real27 real27 50 9 33 0 50 min0 >_2 011000000 int35 int35 51 min1 >_2 011000000* real27 int35 52 mod 2 010100100 int35 int35 52 10 34 0 53 real 1 010101001 cmpx27 real27 54 sign 2 010010110 real27 real27 45 54 35 0 55 sin 1 100110001 15 real27 real27 0 55 36 20 56 sngl 1 000110001 real63 real27 57 sqrt 1 100110000 4 real27 real27 0 57 37 21 58 tanh 1 25 real27 real27 0 58 0 0 .fi .in 0 .sp 3 L__e_g_e_n_d .sp 2 .in 5 .un 4 1.{{This column is merely a sequence number. It is referenced by the generic field. .sp 2 .un 4 2.{{The name of the builtin function. .sp 2 .un 4 3.{{The number of arguments expected in a reference to the function. If the number is preceded by ">_", (the min and max functions), the number represents the minimum number of arguments expected. .sp 2 .un 4 4.{{If the function can be represented by an operator, this column has the bit representation of the operator opcode. If the opcode is followed by a "*", an assign operator is also generated to convert the result of the operator to another mode. .sp 2 .un 4 5.{{If the builtin is an external function, it may appear in an argument list as an entry value. The entry name for the builtin is not necessarily the same as the builtin name and therefore there is a table of entrynames for the external builtins. This field is the index into that table. .sp 2 .un 4 6.{{The mode and precision of the arguments to this function. .sp 2 .un 4 6.{{The mode and precision of the result of this function. .sp 2 .un 4 7.{{If the function name is also the name of a generic function, this field will specify the appropriate function to be used for each data mode. They are listed in the order, integer, real, double precision, complex. If the sequence number is zero, there is no function for that data mode. .in 0 .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_do_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is called to parse a statement that looks like a do statement. This procedure performs the final resolution as to whether the statement type is do or assignment. The statement type recognizer will assign the do statement type in two cases. .sp 2 .in 8 .un 3 1. The token immediately following the first reference of the statement is not an assignment token and the first two letters of the first token are "do." .sp 2 .un 3 2. The token immediately following the first reference of the statement is an assignment token and the first two letters of the first token are "do" and the third character is a digit. .sp 2 .in 0 The first case is either a do statement or syntax error. The other is a do statement or assignment statement. Each path will be described separately although actually their code is intermingled. .sp 2 In case 1, the first token will be the statement label of the continue statement. The subsequent tokens are scanned until an assignment token or semicolon token is found. Semicolon is a syntax error. The tokens following the assignment token are parsed as an expression. The next token must be a comma; it is skipped and the subsequent tokens are parsed as an expression. If a comma follows that expression, it is skipped and another expression is parsed. At this point the next token must be a newline or semicolon. .sp 2 Parsing continues with the first token after the ending label token. This is parsed as a left hand side references. The next token must be an assignment token. .sp 2 In case 2, the first token is an identifier and the token on the top of the stack must be an assignment token. This token is skipped and subsequent tokens are parsed as an expression. If the first nonnewline token after the expression is a comma, this is a do statement, the comma is skipped and the subsequent tokens are parsed as an expression. If a comma follows that expression, it is skipped and another expression is parsed. The next token must be a semicolon or newline. .sp 2 If there is no comma following the first expression it must be followed by either a newline or semicolon token. This is an assignment statement. Parsing continues with the first token of the statement. It and subsequent tokens are parsed as a left hand side reference. The token following the reference must be an assignment token. .sp 2 If in case 2, the statement parsed is a do statement, the left hand side is parsed differently. The first token is an identifier which must contain "do", a decimal integer, and additional characters following the number. The decimal integer is the do loop ending label. The additional characters constitute the first token of the left hand side reference, an identifier token The two required tokens are created and parsed. .sp 2 After parsing is complete, either a do statement or assignment statement is put in the three. If this is a do statement, the expressions for incrementing and testing the do loop index are put in a LIFO list. The items on this list are popped as the ending labels are parsed. .sp 2 A separate entry point is provided to check that do loops are nested properly. This entry point is called after every statement is parsed. If the ending label has been declared and it is legitimately placed, a statement is created to increment the index, followed by a statement to test its value and jump if looping should continue. This process is continued until a loop is found whose ending label has not yet been defined. .in 0 .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_do_parse entry (pointer) .sp 2 A pointer to the current statement node. This statement node is an assignment_statement but may be changed to a do_statement. .sp 2 .un 5 end_test entry .sp 2 No arguments. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_do_parse .sp fortran_parse .sp 3 end_test .sp fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 create_label create_list create_operator create_statement create_token error -- 97, 98. fortran_expression_parse fortran_operator_semantics fortran_reference_parse$left_side make_label parse_error -- 23, 91, 93, 94, 99, 156. statement_recognizer$back_up statement_recognizer$back_up_statement statement_recognizer$next_token statement_recognizer$top_of_stack .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$cur_block fortran_stat_$cur_statement fortran_stat_$equivalence_base fortran_stat_$list5_node .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 block declare_type fortran label language_utility list nodes op_code operator reference source_id_descriptor statement statement_types symbol token token_type .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_expression_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses expressions using a simple operator precedence technique. This procedure considers an expression to have the syntax: .sp 2 .nf := [ ] ... .fi .sp 2 The procedure builds a stack of operands and operators which are placed on the stack as they are found. Each operand placed on the stack is termed a primitive and obtained by call the internal procedure primitive. The operators placed on the stack are binary and unary operators whic are relational or arithmetic. .sp 2 A primitive is zero or more unary operators followed by a constant, a reference, a parenthesized expression, or a primitive exponentiated by a primitive. Primitives are evaluated from right to left. .sp 2 If there are operators on the stack, the precedence of the operator on the top of the stack is compared to the precedence of the most recently parsed operator. If the stacked operator has a equal or higher precedence, it is removed from the stack along with its operand(s) and replaced by an operand node. If there are operators left on the stack, this procedure is repeated. If the stacked operator has a lower precedence, the new operator is added to the stack and parsing continues. When the stack is reduced to one item, the expression is completely parsed. .sp 2 Parsing is done at two levels. At the expression level a simple operator precedence algoirithm is used. This is similar to the method presented by Graham in B__o_u_n_d_e_d_C__o_n_t_e_x_t_T__r_a_n_s_l_a_t_i_o_n. On the primitive level, a recursive internal procedure is used. .sp 2 An expression is parsed from left to right. When a primitive is encountered, a pointer to it is put on the stack. When an operator is encountered, its precedence is compared with the precedence of the top operator on the stack (LIFO). If the stacked operator has greater or equal precedence, an expression tree is created to represent the operator and its operand(s). A pointer to this expression replaces the operator and its operands on the stack. If the stacked operator has less precedence, the encountered operator is placed on the stack. If there is no stacked operator, the encountered operator is placed on the stack. If the encountered operator is an expression delimiter, it will force all stacked operators to be popped. If this process results in a zero length stack, the parse is complete. .sp 3 primitive (internal procedure) .sp 2 This procedure returns a pointer to the next primitive in the expression. Newline tokens are ignored. If a prefix plus sign is encountered it is skipped and the next token is parsed in its place. If a prefix minus sign is encountered, primitive is called to get the primitive following the minus sign. If the primitive is a token, the prefix minus sign is used to create a new token. Otherwise a negate operator is created and applied to the primitive. .sp 2 If the first token of a primitive is a left parenthesis, fortran_expression_parse is called. If the expression is terminated by a comma, the primitive must be a complex constant. Otherwise, the expression must be terminated by a right parenthesis. .sp 2 If the first token of a primitive is a constant, the primitive is a constant. If a decimal integer token is followed by a character string token, the primitive is a character string token. .sp 2 If the primitive is none of the above, fortran_reference_parse is called. .sp 2 After the primitive is parsed, the next token is looked at. If it is an expon, primitive is called to parse the primitive following that operator. .sp 2 The primitive parsed is returned. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_expression_parse entry (pointer) returns (pointer) .sp 2 The argument is a pointer to a token. This token is the first token of the expression. When this procedure returns, this argument will point to the first token which is not part of the expression. This interface prevents the need to back up the parse before and after calls to fortran_expression_parse. .sp 2 The return pointer is the expression parsed. This pointer will point to one of three node types. It will point to a token node if the expression was a constant. (The caller is responsible for converting the token to a constant.) It will point to a reference node if the expression was any reference besides a function or builtin reference. Finally, it will point to an operator node if the expression was a function or builtin reference, or contained any operators. Note that prefix operators (plus or minus) will combine with token nodes to form a new token node rather than an operator node. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_assign_parse fortran_crse_parse fortran_do_parse fortran_expression_parse fortran_expression_parse fortran_if_parse fortran_io_parse fortran_reference_parse go_to_parse stmnt_func_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 create_operator create_token fortran_expression_parse fortran_operator_semantics fortran_reference_parse statement_recognizer$back_up statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 None .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 fortran language_utility nodes op_codes operator source_id_descriptor token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_format_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is called to collect all the tokens which make up a format statement. The procedure general_format_parse_ actually parses the format statement and creates the "executable" form of it. After the format specifications are parsed, this procedure scans the specifications for the appearance of hollerith constants. If any are found, this procedure copies the values of the constants into the compiled string. .sp 2 If an apostrophe token is encountered, the user has tried to use an apostrophe as a string delimiter. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_format_parse entry (pointer) .sp 2 The argument is the statement pointer for this format statement. It is used to insure that the format statement has a label. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 .nf bindex$vs create_list create_token general_format_parse_ make_format parse_error -- 64, 65, 66, 143, 158, 166, 180, 145 statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$list3_node fortran_stat_$cur_block .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 declare_type fortran label language_utility list nodes operator source_id_descriptor statement symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_if_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses if statements. The expression appearing between the parentheses is parsed. If it is a logical constant, reference, or expression, the statement is parsed as a logical if; otherwise it is arithmetic. .sp 2 Arithmetic if statements must have at least one but no more than three dec_integer tokens following it. If the text input mode is not card-image input, all three labels must be present. If less than three labels are provided, this procedure creates a label on the statement following the if statement. That label is referenced in place of the omitted label(s). A three way jump is created. For logical if statements, a special statement recognizer entry point is called. It returns the statement type of the second part of the if statement. If the statement type of the second statement is valid, determined by a label array, the appropriate FORTRAN parse procedure parses the statement. .sp 2 If the second statement is a goto statement, a flag is set to indicate that initially the sense of the test should not be reversed. The goto statement is eliminated from the tree, although its target is saved. This target will be used in the conditional jump statement. .sp 2 If the second statement is not a goto statement, the same flag is set to indicate that initially the sense of the test should be reversed. A null statement is created after the second statement and is given a label. This is the target of the conditional jump statement. .sp 2 If the expression is not headed by an operator node, the expression has a true or false value. An operator node is created to precede the expression. The operator is a "jump_true" if the flag indicates no reversal, otherwise "jump_false". .sp 2 If the expression is headed by a "not_bits" operator (.not.), the sense of the flag is reversed and the process is repeated. .sp 2 If the expression is headed by a standard call operator, it has a true or false value and is treated as a reference. See above. .sp 2 If the expression is headed by a valid comparative opcode, the operator type is converted to the proper conditional jump. The sense of the flag is used to determine the operator. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_if_parse entry (pointer, pointer, fixed bin(15)) .sp 2 .in 8 .un 3 1. A pointer to the statement node created for the if statement being parsed. .sp .un 3 2. A pointer to the current block node. .sp .un 3 3. The statement type code number. This is never referenced. .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_if_parse fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 create_label create_list create_operator create_statement fortran_assign_parse fortran_crse_parse fortran_expression_parse fortran_if_parse fortran_io_parse fortran_operator_semantics go_to_parse make_label parse_error -- 24, 53, 54, 55, 57, 58, 120, 158 statement_recognizer$back_up statement_recognizer$from_if_parse statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$card_input .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 cross_reference declare_type fortran label language_utility list nodes op_codes operator reference source_id_descriptor statement statement_types symbol token token_list token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_io_op .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This is a code generator procedure. It is called to generate object code for all statements parsed by fortran_io_ The code generated for an I/O statement consists of storing information in the PS, loading the q-register with the file_number, and the a-register with a description of the function to be performed. A call is made to the appropriate entry in pl1_operators_. If the I/O statement requires data transmissions, the a-register is loaded with a simplified descriptor, and the a-register may be loaded with a count. A call is made to the appropriate entry in pl1_operators_. .sp 2 In order to perform its task, this procedure must know implementation dependent strategies and offsets. A summary follows. .sp 3 PS .sp 2 This is a storage block which was designed and implemented for the PL/I I/O statements. (See appropriate sections of this PLM.) FORTRAN follows the PL/I implementation except that the FORTRAN PS is always 48 words long and the fields of the PS have different definitions for each compiler. .sp 2 Only one PS exists for a given FORTRAN subprogram. The code generator provides prologue code to set several pointers. Not all need be set for a given procedure. They are: a pointer to the current stack frame for the subprogram; a pointer to the symbol table; a pointer to the symbol table block. .sp 2 The current implementation's offsets and field definitions can be obtained from the include file "fortran_ps". This procedure does not use that include file and must be changed repeatedly if the implementation is changed. .sp 3 Mini Descriptor .sp 2 For each I/O list element to be transmitted, this procedure generates a 36 bit descriptor tailored for the FORTRAN I/O runtime routine. The first six bits represent the mode. Only one will be on. The seventh bit is an array reference bit. If it is set, a second descriptor word will be created specifying the number of words in the array. The eighth bit is not used. The next 24 bits are the character count for a character variable, or are zero. The last four bits are unused. .sp 2 The first descriptor word is loaded into the a-register, the second, if it exists, is loaded into the q-register. Code in pl1_operators_ store these into the PS. .sp 3 OK List .sp 2 The OK list is a mechanism implemented for PL/I get and put data statements. These consist of a list of offsets into the runtime symbol table, one for each item in the get or put list. In FORTRAN, an OK list is built to represent a single namelist group. The first member of an OK list is always the name of the namelist group. .sp 2 Execution. The location of the PS is obtained. If the statement is a transmission, the following optional fields are stored: the direct access record member, the address of the string buffer, the address of the format specifications a pointer to the OK list, the address of the error routine, the address of the end of file routine, and the length of the string buffer. If the address of an OK list is stored, all elements in that list are flushed if the statement is a read statement. This prevents the code generator from missing a value read in at runtime. .sp 2 The file number is loaded into the q-register if this is not a string I/O statement. The job bits are loaded into the a-register and a "tsxO" into the appropriate operator code is generated. .sp 2 At this point, a file control statmenet or a transmission statement without an I/O list is completely specified. .sp 2 If the statement has a list, the internal procedure process_list is called. .sp 3 process_list (internal procedure) .sp 2 This procedure is passed a list node of n elements. Each element of the list could be one of the following node types: .sp 2 .in +5 .un 5 ftn_trans_loop -- This operator node indicates the occurance of an implied do loop. The second operand is the reference for the do loop index. The third operand is the initial value; the fourth is the final value; and the fifth is the increment. The initial value is assigned to the reference, after final and increment values are saved. The current text address is saved for use in the back transfer and process_list is called to process operand 1, the I/O list. When process_list returns, the increment is added to the reference. This is compared with the final value. A "j_le_a" is generated with a target of the address saved above. .sp 2 .un 5 reference or any other operator -- If the list element is "atomic", a simple reference without qualifiers, length or offset expressions, the code generator's state manager is called to erase any stored values. If the atomic is an array reference, the length of the array is loaded into the q-register and the array transmit entry is selected. Otherwise, the scalar entry is selected. If the list element is not atomic the scalar entry is selected. .sp 2 The mini descriptor is created by storing the mode, copying the reference node array reference bit and store either a character length or zero. The descriptor is loaded into the a-register. The selected operator call is made. .in 0 .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_io_op entry(pointer) .sp 2 The argument is a pointer to the FORTRAN I/O operator node to be compiled. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 This procedure is not referenced by any FORTRAN compiler procedures. It is referenced by the code generator procedure io_op to compile FORTRAN I/O operator nodes. .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 The following procedures are all from the code generator. .sp 2 .nf base_man$store_ptr_to c_a compile_exp compile_exp$save compile_exp$save_exp expmac expmac$zero generate_constant$bit_string generate_constant$real_fix_bin_1 load m_a prepare_operand state_man$erase_reg state_man$flush state_man$flush_ref store .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 cg_static_$cur_block cg_static_$text_base cg_static_$text_pos .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 block list op_codes operator reference symbol .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_io_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure pauses all FORTRAN file transmission statements, file control statements, and string transmission statements. The various statement types are distinguished by the type code provided by statement_recognizer. .sp 3 .in 5 .un 5 Create a PS .sp 2 A FORTRAN subprogram which has any file or string statements must have a work area available in the stack frame. This area is called the PS and is created the first time any of the above statements is encountered. It is a 48 word storage area which has special fields known to the code generator and FORTRAN I/O runtime routines. .sp 3 .un 5 Identify Statement Type and Begin Parse .sp 2 .in +5 .un 5 Read Statement. The file number may or may not be specivied. If the first token following "read" is a left parenthesis, a unit number is parsed; otherwise, a format reference is parsed. If this token is a newline, the statement is terminated. .sp .un 5 Print or Punch Statement. If the next token is a semicolon or a newline, the statement is terminated; otherwise a parse format reference. .sp 2 .un 5 Write Statement. The first token must be a left parenthesis. Parse the unit number following the parenthesis. .sp 2 .un 5 Endfile, Rewind, or Backspace Statement. Save the statement type. Parse the unit number. .sp 2 .un 5 Encode Statement. The first token must be a left parenthesis. Parse the string target reference. .sp 2 .un 5 Decode Statement. The first token must be a left parenthesis. Parse the string source reference. .sp 3 .un 5 Parse String Source or Target Reference .sp 2 If the statement is an encode statement, the string references must be a valid left hand side reference. The string reference must have the character or dimensioned attribute. It must be followed by a comma. The format reference is parsed. .sp 3 .un 5 Parse Unit Number Expression .sp 2 The unit number may be any integer expression. If a comma follows it, parse either a format reference or an ab normal return label. If an apostrophe follows it, parse a record number expression. If the expression is followed by a newline or semicolon and this is a file control statement the statement terminates normally. Otherwise text follows the logical end of the statement. .sp 3 .un 5 Parse Record Number Expression .sp 2 The record number may be any integer expression. .sp 3 .un 5 Parse Format Reference .sp 2 If the reference is a decimal integer, a format statement is intended. The designated label is given the format and allocate attributes. If this is a read statement, it is given the parsed_as_arg attribute. .sp 2 If the reference is an identifier, it is either a namelist name or a variable format reference. It either has the namelist, character, or dimensioned attribute. .sp 2 Any other reference is invalid. .sp 3 .un 5 Parse abnormal return labels .sp 2 There are two abnormal return labels "err=" and "end=". The latter may only appear in input statements. The general form is identifier, assignment, dec_integer. The dec_integer must be a statement label. .sp 3 .un 5 Parse List .sp 2 The procedure get_io_list parses the I/O list. This procedure is called only if there is an I/O list. It calls itself when an implied do loop is encountered. .sp 3 .un 5 Create FORTRAN I/O Operator Node .sp 2 After the statement is completely parsed, the procedure creates an operator node which represents the statement. The operator is a fortran_read (10 operands), a fortran_write (10 operands), or a ftn_file_manip (2 operands). Operands 1 and 2 are the same for all of these operators. Operands 1 through 10 are the same for fortran_read and fortran_write. .sp 2 .in 8 .un 3 1. Job Bits -- A string of bits which describe the I/O activity to be performed. .sp 2 .un 3 2. Unit Number -- A pointer to the tree segment whose value is the unit reference number. This field is null for string operations. .sp 2 .un 3 3. Record Number -- A pointer to the tree segment whose value is the record number in a direct access read or write statement. This operand is null if there is no record number. .sp 2 .un 3 4. String Reference -- A pointer to the reference node for string I/O statements. This operand is null for nonstring statements. .sp 2 .un 3 5. Format Reference -- A pointer to the reference node for the format specification. This is either a format statement or variable reference. This operand is null if there is no format specification. .sp 2 .un 3 6. Namelist Reference -- A pointer to a join operator. This join operator defines the namelist group. If this is not a namelist I/O statement, this operand is null. .sp .un 3 7. This operand is a pointer to the error label or is null. .sp 2 .un 3 8. This operand is a pointer to the end of file label or is null. .sp 2 .un 3 9. This operand is a reference or expression whose value is the length in characters of the string I/O record. If this is not a string I/O statement, this operand is null. .sp 2 .un 4 10. List -- If there is an I/O list, this operand points to a list node of n operands. Each element of this list node is either a reference or operator node. An implied do loop is represented by a ftn_trans_loop operator node. .sp 2 .in 11 .un 3 a. A pointer to a list node of n operands. Each element of the list is a single I/O element as described above. .sp 2 .un 3 b. A pointer to the reference node for the control variable of this loop. .sp 2 .un 3 c. A pointer to the initial value for the control variable. .sp 2 .un 3 d. A pointer to the final value for the control variable. .sp .un 3 e. A pointer to the increment for the control variable. .in 5 .sp 3 .un 5 Recognizing the End of a Statement .sp 2 Print, Punch, Read (without unit number) -- The statement may terminate after the keyword, after the format or namelist specification or after the list. .sp 2 Read, Write -- The statement may terminate after the right parenthesis which encloses the unit number, or after the list. .sp 2 Encode, Decode -- The statement may terminate after the right parenthesis, or after the list. .sp 2 Backspace, Endfile, Rewind -- The statement must end after the unit number expression. .in 0 .sp 3 get_io_list (internal procedure) .sp 2 .in 5 This procedure parses a general I/O list. A read statement list may only contain variable references or implied do loops. All input list elements and do loop control variables must be valid left hand side references. Implied do loops are handled by calling get_io_list. get_io_list returns an array of n pointers. The nth pointer points to the control variable. The do loop expressions are parsed by this level after the previous invocation returns the control reference. .sp 2 Output lists are more complex. An output element are expressions. Do loop control variables must be valid left hand side references. .sp 2 If there are no enclosing parentheses, identifier tokens are parsed as expressions. If there are parentheses, the token after the reference is examined. This involves reading one or more tokens. If the token following the reference is an equals sign, backup and parse a reference. If the following token is not an equals sign, back up and parse an expression. .sp 2 If a left parenthesis is encountered it is an expression, implied do loop, or complex constant. The subsequent tokens are scanned. If a matching right paren is found back up and parse as an expression. If a comma is found, which is not part of a reference and the two tokens following it are not an arithmetic constant and a right parenthesis, then back up and parse a complex constant. Otherwise back up and parse an expression. .sp 2 Any other token is parsed as an expression in an output list. .sp 2 After each element of the list, a comma, semicolon, or newline is expected. If a right parenthesis is encountered, there is a set of redundant parentheses or a syntax error. .in 0 .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_io_parse entry(pointer, pointer, fixed bin(15)) .sp 2 .in +4 .un 4 1. Pointer to the current block node. .sp 2 .un 4 2. Pointer to the current statement node. .sp 2 .un 4 3. Statement type. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_if_parse fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 convert create_cross_reference create_list create_symbol create_operator dcl$make_declaration declare_constant$bit declare_constant$integer fortran_expression_parse fortran_operator_semantics fortran_reference_parse fortran_reference_parse$left_side parse_error statement_recognizer$back_up statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 None .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 array block boundary cross_reference declare_type fortran fortran_job_bits label language_utility list nodes op_codes operator reference source_id_descriptor statement symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_operator_semantics .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure processes operator nodes. It returns a pointer to the operator parsed to it, a pointer to a equivalent operator or reference node. It checks the operands of the operator, and converts them if necessary to a common mode. If all the operands are constants, it "executes" the operator and returns that value as a constant. .sp 2 The operators are divided into six categories according to their meaning. The categories are: arithmetic, assignment, jump, logical (bit), relational and all others. .sp 2 This procedure is passed a pointer. If the pointer is null, or does not point to an operator node, or is not an operator in one of the first five categories., the procedure returns its input argument. .sp 3 .in 5 .un 5 Arithmetic Operators .sp 2 Arithmetic operators may be add, subtract, multiply, divide, negate, or exponentiate. All but negate have two source operands. Neither source operand may be a character or logical operand. If the operand(s) are constants, they are converted to a common mode and the operator is executed. .sp 2 If the operands are not constants and the operator is a negate, a target operand the same mode as the source operand is created and the operator node is returned. .sp 2 If the operands are not constants and the operator is add, subtract, multiply, or divide, the expression mode is taken as the mode of the more powerful of the two. If the modes are not equal, and either operand is an integer, the integer operand is converted to real as an intermediate step in the conversion to a common mode. The operator returned is the same operation and may contain new assign operator nodes as part of the mode conversions. .sp 2 If the operands are not constants and the operator is expon, certain mode combinations are disallowed. (See Users' Guide to Multics FORTRAN.) If the second operand (the exponent) is an integer constant, the special case x**1 is recognized and changed to a reference to x. .sp 3 .un 5 Logical Operators .sp 2 Lgoical operators are "not", "or", or "and". The operator "not" has one operand, the others have two. If the operands are constants, they are converted to bit strings and the operator is executed. The source operands must logical. .sp 3 .un 5 Assignment Operators .sp 2 The only assign operator is "assign". This code exists primarily to insure the semantic validity of an assignment. It also serves to provide a common method for converting tokens to their internal values. .sp 2 If the target operand is a temporary with no mode, the source operand is assumed to be a token node and it is converted using convert$to_target and the mode defined by the token. The internal procedure gettype should be the only code which knows the difference between a real and double precision token. .sp 2 The modes of the source and target are obtained. If the data types differ, the following combinations are eliminated as invalid: .sp 2 .in +5 .nf logical = character logical = arithmetic arithmetic = logical character = arithmetic character = logical .fi .in -5 .sp 2 If the source operand is an operator node whose target mode is identical to the mode of the assign operator target, the assign operator can be eliminated. .sp 2 If the source operand is an operator other than a "std_call" and its target mode differs from the target mode of the assign, then the assign operator can be eliminated if the two modes are real and double precision. .sp 2 Assignment of the forms: .sp 2 .nf .in +5 arithmetic = arithmetic character = character logical = logical .fi .in -5 .sp 2 are always valid. In the arithmetic case, mode conversion may occur. Real is used as an intermediate step between modes. .sp 2 The final case is arithmetic = character. This form is valid if the source operand is a constant. The left most word or words of the constant are assigned without conversion to the target operand. .sp 2 If an assignment assigns a zero, it is changed to an "assign_zero" operator. .sp 3 .un 5 Jump Operators .sp 2 The "jump" operator is not checked. The second operand for "jump_true" or "jump_false" must be of logical mode. For a "jump_three_way" the expression may not be complex, logical, or character. .sp 2 The remaining jumps involve a relational expression and are handled as relational operators. .sp 3 .un 5 Relational Operators .sp 2 There are six relational operators. Relations between two operands of mode integer, real, or double precision are not limited. Relations between two complex operands are limited to "equal" and "not_equal". A complex operand may not be related to an operand of another mode. Relations between two logical operands are limited to "equal" and "not_equal". A logical operand may not be related to an operand of another mode. Relations between two character operands or between a character operand and an integer, real or double precision operand operand are not limited. In a relation between a character operand and an arithmetic one, the leftmost word or words of the character operand are related without conversion to the arithmetic one. .sp 3 .un 5 Final Node Processing .sp 2 If either of operands is a constant, it is converted to the proper mode. In expressions involving mixed modes, the operands are converted to compatible modes. If the opeator class is not jump operators, the first operand of the operator is created as a temporary of the appropriate mode. The processed node is returned. .sp 3 .un 5 gettype (internal procedure) .sp 2 This procedure is the only procedure in the compiler that can distinguish a real token from a double precision token. If the rules change, this is the only procedure to be affected. Current FORTRAN rules differ from PL/I by one digit of precision. .sp 2 This procedure is called with a token, reference, or operator node .sp 2 If the input is a token node, it is assigned a mode. .sp 2 .in +5 .nf Token Type Mode .sp dec_integer integer char_string character fixed_dex 1 to 9 digits real .br 10 or more double precision flost_dec exponent character is "e" real exponent character is "d" double precision i_float_dec complex logical_constnat logical .fi .in -5 .sp 2 If the input is an operator node, the first operand must be a reference node and it is used to determine the mode. .sp 2 .in +5 .nf Attribute Mode .sp char character fixed integer complex complex bit logical float real if precision <=27 double precision if precision >27 .fi .in -5 .sp 3 .un 5 declare_char_as (internal procedure) .sp 2 This procedure takes a character constant and creates an arithmetic constant of the desired mode and precision. An eight character (two word) constant is created. It is the first eight characters of the original constant, or if the constant is less than eight characters, it is the constant with blank padding. If the desired mode is double precision or complex, all eight characters are used, otherwise only the first four are. A constant of the requested mode and precision is created whose bit value is the characters of the string. .sp 2 If there are more characters in the string than are needed, an error message is printed. .sp 3 .un 5 evaluate (internal procedure) .sp 2 This procedure will "execute" any operator whose operands are constants. It will return a pointer to the reference node of the resulting value. Only arithmetic, logical and relational operators are treated. .sp 2 .in +5 .un 5 Arithmetic Operators -- If either operand is a token it is converted to the proper value. If the operator is "negate", the operand is negated. If the operator is "exp", the operands must be compatible. If they are the result is returned. If the operator is any other operation, the operands are converted to a common mode and the operation is performed. .sp 2 .un 5 Logical Operators -- If either operand is a token it is converted to the proper constant. The bit operation is performed and the result returned. .sp .un 5 Relational Operations -- If either operand is a token, it is converted to the proper constant. If only one operand is logical or character, nothing is changed. The result of the relation is returned a a logical constant. .in -5 .sp 2 There are two internal procedures in evaluate. They are convert_arithmetic and convert_non_arith. These procedures convert tokens to constants, and change the modes of compiler constants. .in 0 .sp 3 U__s_a_g_e .in 5 .sp 2 .un 5 fortran_operator_semantics entry (pointer) returns(pointer) .sp 2 The input argument is a pointer to an operator node or is null. If the operator is not known to this procedure, no action is taken. .sp 2 The return pointer points to an operator node or a reference node which is equivalent to the input argument. The returned operator or reference node is acceptable to the code generator although the input may not be. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf builtin_function fortran_assign_parse fortran_do_parse fortran_expression_parse fortran_if_parse fortran_io_parse fortran_reference_parse fortran_subscripter prologue_entry stmnt_func_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 bindex$vs convert convert$to_target create_operator create_token cxp1_ declare_constant declare_constant$char declare_temporary fortran_parse$abort fortran_reference_parse$make_call fortran_reserve$declare_lib free_node on_data_$get_oncode parse_error share_expression .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 fortran language_utility list nodes op_codes operator reference source_id_descriptor symbol system token token_types .fi .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 None .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is the overseer for the parse and semantic phase of the FORTRAN compiler. .sp 2 .in 5 .un 5 o{{{{initializes the error utilities. The error utilities save a list of all compiler error and sort them by source line number. .sp .un 5 o{{{{initialize label variables for utility aborts. If a utility encounters an error, it must be able to pass control back to the overseer. .sp .un 5 o{{{{zero all special lists and create a root block node. Also set up the default mode vector. .sp .un 5 o{{{{initialize the token parser and the PL/I reserved name table to prevent codes generator problems. .sp .un 5 o{{{{initialize the statement recognizer and thereby get the statement type of the first statement. .sp .un 5 o{{{{parse the subprogram. .sp .in 0 This procedure contains several label arrays which control how a particular statement type is to be handled. At any point in a compilation some statement types will require unique processing that was not require at some other point. .sp 2 There are currently six sections to a FORTRAN compilation and forty-eight statement types .sp 3 Category I .sp 2 If the first statement of a subprogram is: .sp 2 .in 5 .nf block data character function complex function double precision function function integer function logical function real function subroutine .fi .in -5 .sp 2 then fortran_subroutine_parse is called to parse the statement and begin the creation of the current block node. A block data statement defines a main subprogram, all others are not. .sp 2 If the statement type is not one of those mentioned above, the subprogram is a main subprogram. A procedure statement is created whose root is a "std_entry" operator. An "ex_prologue" operator is the root of the first statement following the procedure statement. The statement node created for the current statement appears next. Try the statement type in category II. .sp 3 Category II .sp 2 This category is designed to pick up all declaration statements. .sp 2 Format, implicit, and parameter statements may appear in this category and are parsed. .sp 2 Any statement appearing in the category I list is out of sequence. An error message is printed and the statement is deleted. .sp 2 The following are parsed while remaining in this category: .sp 2 .in 5 .nf abnormal automatic character common complex dimension double precision external integer logical real .fi .in 0 .sp 2 Any other statement type results in the declaration processor being called; try the statement in category III. .sp 3 Category III .sp 2 All declaration statements have been parsed. The declaration processor has done its thing to the symbol table. Equivalence statements may now be parsed. Statements which were parsed in preceding categories are now considered out of sequence. Format, implicit, and parameter statements are parsed. .sp 2 If the statement is not equivalence, format, implicit or parameter, and it was not parsed in a preceding category, all declarations are now complete and automatic variables can have their initial attributes formatted correctly. Try it in Category III-a. .sp 3 Category III-a .sp 2 Parse namelist statements. Previous statement types are invalid. Format, implicit, and parameter are valid. If it is anything but an assignment statement, parse it as if this were category V. If it is an assignment statement, go to category IV and parse it as a statement function or an assignment. .sp 3 Category IV .sp 2 Parse statement functions, format, implicit, or parameter. .sp 3 Category V .sp 2 Parse the body of the subprogram. When an end line is encountered, generate tree stuff and then perform some checks. .sp 2 .in +5 .un 3 1. Make sure all do loops are terminated. The stack of unended do loops should be empty. .sp .un 3 2. All referenced statement labels must be defined. A label is put in the symbol table if it is referenced. If by the end of the compilation it does not belong to a statement, this is an error. .sp .un 3 3. If this is a block data subprogram, a link is snapped for each common block in the subprogram. This initializes the common block only if this link is the first link to it in the process. .sp .un 3 4. Format declaration are kept separate from other declarations. Loop through the format chain to make sure they are all defined. Then thread them into the declarations for the subprogram's block node. .sp .un 4 5. Go through the list of namelist groups and weed out those which were not referenced. This will reduce the object segment size by reducing the number of OK lists. .sp .un 3 6. In order to iron out differences between FORTRAN expression extent arrays and the code generator, descriptors must be created. However, expression extent array descriptors require executable code. FORTRAN does not use this code. So the descriptors and the related code are generated and then the tree is trimmed to remove the executable code. This is only interim measure. .in -5 .sp 3 abort entry .sp 2 .in 5 This entry is called when a nonrecoverable parse error occurs. It receives control via a nonlocal goto from the utility procedures or by calls from FORTRAN procedures. It does not return to its caller but instead performs a nonlocal goto to unwind the tangled parse sequence. .sp 2 If fortran_stat_$cur_statement points to a statement node, the statement root is nulled and the statement type is made "null_statement". An error message is then printed. .sp 3 .un 5 error entry .sp 2 This entry point is used by the utilities to print error messages. .sp 3 .in 0 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_parse entry (pointer, pointer, fixed bin(15)) .sp 2 .in 8 .un 3 1. A pointer to the root block node for this compilation. (Output) .sp .un 3 2. A pointer to the source segment for this compilation. (Input) .sp .un 3 3. The character count for the source segment. (Input) .in 0 .sp 3 abort entry (fixed bin(15), pointer) .sp 2 .in 8 .un 3 1. The error number. (Input) .sp .un 3 2. A pointer to the token, reference, symbol, etc. or null. (Input) .in 0 .sp 3 error entry (fixed bin(15), pointer) .sp 2 The arguments are identical to those for abort entry point. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_parse .sp fortran .sp 2 abort .sp fortran_operator_semantics All utility procedure aborts. .sp 2 .un 5 error .sp All utility procedure error conditions. .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 cardlex$initialize_lex create_block create_list create_operator create_statement create_symbol create_token dcl$declaration_processor dcl$implicit_parse declaration_parse$abnormal_parse declaration_parse$automatic_parse declaration_parse$character_parse declaration_parse$common_parse declaration_parse$complex_parse declaration_parse$data_parse declaration_parse$dimension_parse declaration_parse$double_precision_parse declaration_parse$equivalence_parse declaration_parse$external_parse declaration_parse$integer_parse declaration_parse$logical_parse declaration_parse$namelist_parse declaration_parse$real_parse declare_descriptor declare_temporary error error_ error_$initialize_error error_$no_text flex$initialize_lex fortran_assign_parse fortran_crse_parse fortran_do_parse fortran_do_parse$end_test fortran_format_parse fortran_if_parse fortran_io_parse fortran_parse$abort fortran_parse$error fortran_subroutine_parse go_to_parse parse_error 31, 33, 114 prologue_entry$auto_initial reserve$clear statement_recognizer statement_recognizer$init statement_recognizer$next_token stmnt_func_parse .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$card_input fortran_stat_$compiler_created_index fortran_stat_$constant_list fortran_stat_$cur_block fortran_stat_$cur_statement fortran_stat_$equivalence_base fortran_stat_$error_memory fortran_stat_$format_list fortran_stat_$generate_symbol fortran_stat_$list3_node fortran_stat_$list5_node fortran_stat_$modetable fortran_stat_$ok_list fortran_stat_$profile_length fortran_stat_$seg_name fortran_stat_$temporary_list fortran_stat_$util_abort fortran_stat_$util_error .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 block block_types declare_type fortran label language_utility list nodes op_codes operator reference source_id_descriptor statement statement_types symbol system token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_reference_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses all FORTRAN references. The general form of a reference is an identifier token followed optionally by a parenthesized list. The semantics of the reference is determined by a number of factors. .sp 2 .in 5 .un 5 o{{{{Presence or absence of a declaration for the identifier. .sp .un 5 o{{{{Presence or absence of a list. .sp .un 3 Reference context. It could be a call statement, left hand side of statement function, left hand side of an assignment statement (set reference), or expression. .in 0 .sp 2 If an identifier has already been declared, its attributes must be compatible with its context. If it has not been declared it is given those attributes which seem appropriate. .sp 2 Certain contexts require the existence of a list. If an undeclared identifier is followed by a list it is either an external reference, a builtin function reference, or a statement function definition. .sp 2 If the identifier is not followed by a list and is undeclared, it is valid in all contexts. If this is a call context, the identifier is declared as an entry constant, otherwise it is declared as a variable with its mode based on the current implicit rules. .sp 2 If an identifier is not followed by a list and is declared, it must be checked. If the context is lefthand side, the symbol asociated with the identifier may not have the entry or constant attribute. If the context is call the symbol must have the entry attribute. If the context is call and the symbol has the parameter attribute, and the symbol did not appear in a declare statement, it becomes an entry variable. .sp 2 If the identifier is not declared, and this is a call context, as it is declared as an entry constant. Otherwise it is declared as a variable. .sp 2 If a list follows the identifier it must be parsed. Each item is parsed individually. Label constants are valid only in call statement lists. .sp 2 If a list item is a external builtin or an entry and it is not followed by a list, then a label variable is created whose value is the builtin or entry. .sp 2 Otherwise the list element must be a valid expression. .sp 2 If the symbol is dimensioned it is processed as a subscripted reference. .sp 2 If the symbol is not declared, or does not have the entry attribute, and this is a statement function definition, the reference is a new statement function. Declare it if necessary. Remove its storage class. Create a list of n elements, one for each parameter and hang it from symbol.initial. Set the lock attribute to denote a statement function. Validate the parameters and save them in the list. .sp 2 No other types of subscripted references are permitted on the left hand side of an assignment statement. .sp 2 If the symbol has the builtin attribute, the context may not be a call statement. Otherwise a builtin reference is returned. .sp 2 If the symbol is a statement function name, the context may not be a call statement. Otherwise, the statement function expression is returned. .sp 2 If the symbol has the parameter attribute, it is either a parameter to one of the subprogram's entry points, or this is a function subprogram and the symbol represents a recursive function call to this subprogram. If this is a call context, the symbol may not be a function subprogram name. The symbol is call context must not have been declared in a declare statement. .sp 2 For a parameter attribute symbol in an external reference context, either a reference to the subprogram or a reference to a parameter entry variable, an external call is made. .sp 2 If the symbol has the entry attribute, it must have the returns attribute if it is an external reference and may not if it is a call statement. .sp 2 If none of the above attributes are set this identifier may not appear in a call context. It may appear as a function reference. .sp 2 If the symbol is a common member, or not in internal static storage it may not be made an entry variable. If it is the name of a builtin function, handle it as a builtin. Otherwise it is a mode declaration for the return value of an external function. Set up the proper declarations and create the call operators. .sp 2 If the identifier has no associated symbol, i.e., it was never declared, figure out what it is. If this is a statement function definition, the identifier is declared as a statement function .sp 2 If it is a left side context, it is invalid. .sp 2 If it is the same as a builtin name, declare it as a builtin. .sp 2 Otherwise declare it as a external function or subroutine name. Then generate an external call operator. .sp 2 After the reference is parsed, a simple loop is used to allocate its parent symbols. A cross reference node is created for ths identifier and the proecdure returns. Parameter reference nodes are not shared. .sp 3 make_call entry .sp 2 This entry point is provided to modularize the creation of "std_call" operator nodes. Whenever any procedure wishes to create such an operator, this entry must be called. This design minimizes reimplementation if the format of this operator is changed. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 fortran_reference_parse entry (pointer, pointer) returns (bit(1) aligned) .sp 2 .in 8 .un 3 1. A pointer to a token node. This points to the first token of the reference to be parsed. It is set by the caller. On returning from this entry point, the pointer points to the first token which is not part of the reference. .sp 2 .un 3 2. A pointer to the reference node produced. If an error occurs during processing, the pointer is null. .sp 2 .un 3 Return -- If the reference parse was successful, "1"b is returned. If an error occurs "0"b is returned. Some parse errors will also result in an error message being printed. .in 5 .sp 3 .in 5 .nf call entry (pointer, pointer) returns (bit(1) aligned) sf entry (pointer, pointer returns (bit(1) aligned) left_side entry ( pointer, pointer) returns (bit(1) aligned) .fi .sp 2 These entries are used in the same manner as fortran_reference_parse. .sp 3 .un 5 make_call entry (pointer, pointer, dim(128) pointer, fixed bin, bit(1) aligned) returns (pointer) .sp 2 .in +5 .un 3 1. Pointer to a reference node or null. If the operator node is to represent an external function call, this argument points to a reference node for the return temporary. For subroutine calls this argument is null. .sp 2 .un 3 2. Pointer to the reference node for the symbol to be called. .sp 2 .un 3 3. An array of pointers. Each pointer points to an argument of the call .sp 2 .un 3 4. The number of arguments. .sp .un 3 5. The descriptor switch. If this switch is on, descriptors must be generated for all arguments in the argument list. If it is off, no descriptors are generated. .sp 2 .un 5 Return -- A pointer to "std_call" operator. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_reference_parse .sp 1 fortran_expression_parse fortran_io_parse go_to_parse .sp 3 call .sp 1 fortran_crse_parse .sp 3 left_side .sp 1 fortran_assign_parse fortran_do_parse fortran_io_parse .sp 3 sf .sp 1 stmnt_func_parse .sp 3 make_call .sp 1 builtin_function fortran_crse_parse fortran_operator_semantics fortran_reference_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 builtin_function builtin_function$declare_entry builtin_function$lookup convert$to_target copy_expression create_cross_reference create_list create_operator create_symbol create_token dcl$make_declaration declare_descriptor declare_temporary fortran_expression_parse fortran_operator_semantics fortran_reference_parse$make_call fortran_subscripter make_label parse_error replace_parameters statement_recognizer$back_up statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$cur_block fortran_stat_$cur_statement .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 array boundary cross_reference declare_type fortran language_utility list nodes op_codes operator reference source_id_descriptor statement symbol system token_types tokens .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_reserve .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is called to create a declaration for an external library entry using the appropriate external name. The argument to this procedure is an index into a reserved name table. This table contains the appropriate name for the library entry requested. A token and symbol node are created. The symbol has the irreducible, entry, constant, and external attributes. The symbol's reference node is returned. .sp 3 U__s_a_g_e .sp 2 declare_lib entry (fixed bin(15)) returns (pointer) .sp 2 .in 5 The argument is the index of the desired routine. The procedures which invoke this entry point must know the index of the desired routine. .sp 2 Return is a pointer to the reference node of the symbol node for the desired routine. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf builtin_function fortran_crse_parse fortran_operator_semantics .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 create_symbol create_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$cur_block .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 boundary declare_type language_utility source_id_descriptor symbol token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_subroutine_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses the following statements: .sp 2 .in 5 .nf subroutine function mode function (mode is character, complex, double precision, integer, real logical) character function block data entry .fi .sp 2 .in 0 Processing of these statements is very similar. This procedure is called after a statement node has been created for the statement. This statement will contain a "std_entry" operator. .sp 2 Immediately following the standard entry will be an "ex_prologue" statement. .sp 2 If the statement is an entry statement, a go to statement will precede the standard entry statement. Its target will be a null statement which will follow all the statements generated to implement the entry point. .sp 2 If the statement is a block data statement, or this is a main subprogram, and identifier token is created for the segment entry name (without the ".fortran" suffix). A symbol node will be created for this token (see below). .sp 2 Subroutine, function, and entry statements may have parameter lists. These are parsed if they exist. .sp 2 A symbol node is created for the entry point name. It is given the external, entry, and constant attributes and is marked as externally referencable. .sp 2 If this is a function statement, a symbol is created whose mode is the mode of the return value for the function. If the statement does not declare a mode for the entry, no mode is assigned to the return value. The mode in this case will either be provided by a declaration statement or by the declaration processor. .sp 2 If this is a function or an entry to a function, the return value pointer is added to the argument list. .sp 2 For all statements which have parameter lists, the list must be processed. All parameters must have a qualifier which specifies its position in the list. Special techniques are used to handle a parameter which appears in different positions in different lists. If the parameter is a label variable, it is unique to the statement it appears in. It will always have a simple qualifier. If this is not an entry statement, a symbol node may be created but not mode attributes may be assigned. If it is an entry statement, type attributes are assigned if the variable did not already have some. .sp 2 If a parameter has appeared in another parameter list and its position there is not the same as this list, this parameter's qualifier must be an automatic pointer rather than a "param_ptr". The automatic pointer is set by each entry point in which that parameter appears. .sp 2 If a parameter's mode is complex or double precision, its alignment attributes must be fiddled. It is possible for a variable of these modes to be unaligned. Therefore the parameter has the unaligned rather then the aligned attribute. .sp 2 After processing the argument list, a "std_entry" operator is created and stored in the procedure statement. If there is an argument list, the arguments are stored as operands of the "std_entry" operator. Also, a chain of list nodes hang off of the entry's symbol.general. The first list element is a pointer to the next list node. The second is a pointer to the symbol node for the parameter. The parameters are chained so that the first list node in the chain is the first argument, and the last one is the last argument. .sp 2 If the parameter list includes label variables, a label array is created and initialized. An identifier token with the value "" is created. If it is not declared, it is declared as an automatic, variable label array. This has one dimension whose constant upper bound will be the maximum for the subprogram. The constant word size and constant bit size are based on the constant upper bound. If the -table option is specified the array will also have a variable upper bound. This variable upper bound is only used to validate an alternate return statement. It does not affect the storage type or size of the label array. This variable upper bound is zeroed in the prologue. Each entry point which has label variable parameters will redefine the value of the variable upper bound to the correct upper bound for the entry point. .sp 2 The label array is initialized by a series of assignment statements at each entry point. There is one assignment for each element of the array. The check_bounds switch is turned off in order to eliminate useless bound checking. .sp 3 assigntoqual (internal procedure) .sp 2 This procedure is parsed a statement node pointer and a position number. It produces an assignment statement which assigns to value of the specified parameter pointer to an automatic pointer specified by the variable "qual". .sp 3 U__s_a_g_e .sp 2 fortran_subroutine_parse entry (pointer, pointer, fixed bin(15)) .sp 2 .in 8 .un 3 1. A pointer to a procedure or entry statement node. This is the statement node for the statement being parsed. .sp 2 .un 3 2. A pointer to the containing block node. .sp 2 .un 3 3. The statement type of the statement to be parsed. .sp 2 .nf 0 a main subprogram 5 block data statement 10 complex function 15 double precision function 18 entry 23 function 30 integer function 32 logical function 37 real function 42 subroutine 45 character function .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s__t_h_a_t_I__n_v_o_k_e__t_h_i_s_P__r_o_c_e_d_u_r_e .sp 2 fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 create_array create_bound create_label create_list create_operator create_statement create_statement$prologue create_symbol create_token dcl$make_declaration declare_constant$integer declare_descriptor declare_temporary fortran_subscripter parse_error 49, 50, 51, 52, 142, 179 statement_recognizer$back_up statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$check_bounds fortran_stat_$root fortran_stat_$reg_name fortran_stat_$table .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 array block boundary declare_type fortran label language_utility list nodes op_codes operator reference source_id_descriptor statement statement_types symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_subscripter .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is called everytime there is a subscripted reference in FORTRAN. This includes alternate return and computed goto statements. If bound checking is to be done at runtime, this procedure generates the tree sequences necessary to accomplish this. .sp 2 Each subscript expression is converted to an integer value. At this point, precision is not important. .sp 2 The symbol's reference node is copied. This copy is made an unshared reference node with a reference count of one. If the reference node has a qualifier because it is a parameter, the qualifier field is nulled. This is done in case the qualifier field is subsequently changed. Copying will get us a new expression tree for the offset, however, the qualifier expression is not copied because currently it can only be shared reference node. .sp 2 The offset expression to be computed is expressed as follows: .sp 2 .in 5 .nf declaration is: a(b1, b2,...,bn) reference is: a(si, s2,...,sn) words per element is: w .sp the offset expression is: w(s1+s2b1+s3b1b2+...+snb1b2...b(n+1)) the virtual origin is: w(1+b1+b1b2+...+b1b2...b(n+1)) .sp 2 .fi .in 0 Both the offset and virtual origin can either be expressions or constants. In order to minimize unnecessary computations, the constant portions of each are removed from the respective expressions and comhined to form a constant offset. In this way a reference to an array with constant bounds and subscripts would have no address computation during execution. .sp 2 The algorithm used is a simple loop through the subscripts and multipliers. If the -subscriptrange option is given, a "bound_ck" operator is created. It will cause subscript checking to occur. .sp 2 Then the multiplier is picked up. If will either be a constant or an expression. If it is an expression, no simplification is possible. .sp 2 The subscript expression is evaluated. If the root of the expression is an "add" or "sub" operator, and the right operand is an integer constant, the constant is multiplied by the current multiplier and added to the constant offset. The operator node is removed and this process is repeated until the root is not an operator node or the operator is neither "add" or "sub". .sp 2 If the root of the subscript expression is a reference node and the associated symbol is a constant, the constant is multiplied by the current multiplier and added to the constant offset. .sp 2 If any part of the subscript expression is left, it is multiplied by the current multiplier expression and added to the offset expression. If the multiplier is a constant 1, no multiply ope operator is used. If the expression formed is the first part of the offset expression, no add operator is used. .sp 2 If there is a virtaul origin expression it is subtracted from the offset expression created; ( a negate operatior is used if there was no offset expression.) .sp 2 The constant offset computed is added to the constant offset in the reference node. .sp 2 If there is an offset expression, it is added to the reference node offset expression. If the reference node has not offset expression, no add operator is used. .sp 2 The reference node formed is returned. .sp 3 U__s_a_g_e .sp 2 fortran_subscripter entry (pointer, fixed bin(15), dim(128) pointer) returns (pointer) .sp 2 .in 8 .un 3 1. A pointer to a symbol node. This is the symbol to be subcripted. .sp .un 3 2. The number of subscripts presented. .sp .un 3 3. An array for holding pointers to the subscript expressions. .sp .un 10 Return -- A pointer to a reference node which represents the subscripted reference .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_crse_parse fortran_reference_parse fortran_subroutine_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 convert copy_expression create_operator create_reference declare_constant declare_temporary fortran_operator_semantics free_node parse_error 123 .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$check_bounds .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 array fortran language_utility nodes op_codes operator reference source_id_descriptor symbol system .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_symbol_print .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure prepares the information to be printed in the FORTRAN symbol table. It is called once for each segment of the table, ("NAMES DECLARED BY DECLARE STATEMENT", etc.) and processes an array of symbol nodes, ordered alphabetically on the identifier. After a line image is completely created, it is printed by a utility subprogram. .sp 2 This procedure is responsible for distinguishing referenced from unreferenced symbols. One of the arguments to this procedure specifies whether all symbols, only those referenced, or only thos unreferenced should be printed. .sp 2 Symbols names containing a vertical bar (|) were declared by the compiler and are common block names. In this case, only those characters appearing before the vertical bar are printed. If the symbol name is longer than thirty characters, it is printed on a line by itself. .sp 2 If the symbol is really a label, its class is "constant" and its mode is "label". Its location, and references are printed. .sp 2 If the symbol has the builtin attribute, its mode is "built-in function" and it has no class. Next is references are printed. .sp 2 If the symbol has the entry attribute, it is an "entry constant" if it also has the external attribute and its initial pointer is not null. Otherwise, it is a subroutine if its dcl_size pointer is null or it is a function. If this subroutine or function does not have the variable attribute it is an "internal" or "external link reference". .sp 2 If the symbol has the "namelist" attribute, it is a "namelist name". It has no mode. Its mode and references are printed. .sp 2 If the symbol has the "ptr" attribute, it is a compiler declared pointer. Its location, class, mode and references are printed. .sp 2 If the symbol has the "structure" attribute, it is a common block name or a compiler declare equivalence group. Everything is printed. .sp 2 If none of the above special attributes are set, the symbol is a FORTRAN variable. Its mode is obtained from its attributes. .sp 2 Variables are assigned a storage class based on the storage class attributes in the symbol node. .sp 2 If the symbol has a location, usually an offset relative to the stack frame, internal storage area, common block head, or equivalence base, it is computed and placed in the output line. Members of equivalence groups have their location printed as relative to the base of the storage class. .sp 2 If the symbol has the "lock" attribute, it is a statement function. If it is a character mode or a structure (common block or equivalence base), its constant size is printed. .sp 2 If it is an array, initialed or equivalenced, those attributes are printed. Finally, the cross reference nodes for the symbol are converted to character form and printed. .sp 3 var_type (internal procedure) .sp 2 This procedure returns the mode of the symbol passed to it. .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 This procedure is not referenced by the FORTRAN compiler, however, its address is passed to the code generator. .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 .nf binec$vs binoct pl1_print$non_varying_nl pl1_print$string_ptr_nl .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 None .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 cross_reference label nodes reference symbol system token .fi .sp 3 P_R_O_C_E_D_U_R_E_S_ -- fortran_lex_data .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This ALM segment defines the discrete state machine which defines tokens for the terminal line FORTRAN lexical analyzer. It is the table which drives the lexical analyzer. Currently there are 22 states, 24 character types and 26 actions. The character types and actions are defined by use in the procedure flex. .sp 3 C__h_a_r_a_c_t_e_r_T__y_p_e_s .sp 2 .in 8 .un 3 1. All invalid characters. That is all character not listed in any other type. .sp 2 .un 3 1. A-Z, a-z except c, x, d, e, h. d and e are potential exponent characters. h could signify the beginning of a hollerith constant. c could signify a comment line. x is isolated for historic reasons. .sp 2 .un 3 2. Digits. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, .sp 2 .nf .un 3 3. + 8. ( 13. c 18. " .un 3 4. - 9. ) 14. x 19. $ .un 3 5. * 10. . 15. d 20. _ .un 3 6. / 11. , 16. e 21. ' .un 3 7. = 12. ; 17. h 22. newline .fi .in 8 .un 4 23. Space or Tab. These two characters are interchangeable except in character strings. One tab is the same as one space. .in 0 .bp S__t_a_t_e_s_A__n_d_A__c_t_i_o_n_s .sp 2 Character Value | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | |------+------+------+------+------+------+------+------| State 1| 1-13| 2-1 | 5-1 | 1-3 | 1-3 | 9-1 | 1-3 | 1-3 | |------+------+------+------+------+------+------+------| State 2| 1-2 | 2-1 | 2-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 3| 1-13| 2-1 | 5-1 | 1-3 | 1-3 | 9-1 | 1-3 | 1-3 | |------+------+------+------+------+------+------+------| State 4| 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | |------+------+------+------+------+------+------+------| State 5| 1-26| 1-26| 5-1 | 1-26| 1-26| 1-26| 1-26| 1-26| |------+------+------+------+------+------+------+------| State 6| 1-2 | 1-2 | 6-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 7| 1-14| 8-1 | 6-1 | 1-14| 1-14| 1-14| 1-14| 1-14| |------+------+------+------+------+------+------+------| State 8| 1-15| 8-1 | 1-15| 1-15| 1-15| 1-15| 1-15| 1-15| |------+------+------+------+------+------+------+------| State 9| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-9 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 10| 1-16| 1-16| 18-1 | 19-1 | 19-1 | 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 11| 1-8 | 1-8 | 12-1 | 19-1 | 19-1 | 1-8 | 1-8 | 1-8 | |------+------+------+------+------+------+------+------| State 12| 1-2 | 1-8 | 12-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-8 | |------+------+------+------+------+------+------+------| State 13| 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | |------+------+------+------+------+------+------+------| State 14| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 15| 1-2 | 15-1 | 15-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 16| 1-18| 1-18| 17-1 | 1-18| 1-18| 1-18| 1-18| 1-18| |------+------+------+------+------+------+------+------| State 17| 1-2 | 1-2 | 17-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 18| 1-2 | 1-2 | 18-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 19| 1-16| 1-16| 18-1 | 1-16| 1-16| 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 20| 1-21| 1-21| 6-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 21| 1-16| 1-21| 18-1 | 19-1 | 19-1 | 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 22| 1-13| 2-1 | 5-1 | 1-3 | 1-3 | 9-1 | 1-3 | 1-3 | |------+------+------+------+------+------+------+------| .bp Character Value | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |------+------+------+------+------+------+------+------| State 1| 1-3 | 1-3 | 7-1 | 1-3 | 1-3 | 2-1 | 2-1 | 2-1 | |------+------+------+------+------+------+------+------| State 2| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 2-1 | 2-1 | 2-1 | |------+------+------+------+------+------+------+------| State 3| 1-3 | 1-3 | 7-1 | 1-3 | 1-3 | 4-4 | 2-1 | 2-1 | |------+------+------+------+------+------+------+------| State 4| 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | |------+------+------+------+------+------+------+------| State 5| 1-26| 1-26| 20-20| 1-26| 1-26| 1-26| 1-26| 11-11| |------+------+------+------+------+------+------+------| State 6| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 10-1 | |------+------+------+------+------+------+------+------| State 7| 1-14| 1-14| 1-14| 1-14| 1-14| 8-1 | 8-1 | 8-1 | |------+------+------+------+------+------+------+------| State 8| 1-15| 1-15| 1-12| 1-15| 1-15| 8-1 | 8-1 | 8-1 | |------+------+------+------+------+------+------+------| State 9| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 10| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 11| 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | |------+------+------+------+------+------+------+------| State 12| 1-8 | 1-2 | 1-2 | 1-2 | 1-2 | 0-0 | 1-8 | 1-8 | |------+------+------+------+------+------+------+------| State 13| 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | 13-1 | |------+------+------+------+------+------+------+------| State 14| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 15| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 15-1 | 15-1 | 15-1 | |------+------+------+------+------+------+------+------| State 16| 1-18| 1-18| 1-18| 1-18| 1-18| 1-18| 1-18| 1-18| |------+------+------+------+------+------+------+------| State 17| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 18| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | |------+------+------+------+------+------+------+------| State 19| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| |------+------+------+------+------+------+------+------| State 20| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-21| 1-21| 21-1 | |------+------+------+------+------+------+------+------| State 21| 1-16| 1-16| 1-16| 1-16| 1-16| 1-21| 1-21| 1-21| |------+------+------+------+------+------+------+------| State 22| 1-3 | 1-3 | 7-1 | 1-3 | 1-3 | 2-1 | 2-1 | 2-1 | |------+------+------+------+------+------+------+------| .bp Character Value | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | |------+------+------+------+------+------+------+------| State 1| 2-1 | 2-1 | 13-4 | 16-1 | 1-13| 1-3 | 3-6 | 1-4 | |------+------+------+------+------+------+------+------| State 2| 2-1 | 2-1 | 1-2 | 15-1 | 2-1 | 1-2 | 3-2 | 2-4 | |------+------+------+------+------+------+------+------| State 3| 2-1 | 2-1 | 13-4 | 16-1 | 1-13| 1-3 | 3-6 | 1-4 | |------+------+------+------+------+------+------+------| State 4| 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | 4-4 | 3-19| 4-4 | |------+------+------+------+------+------+------+------| State 5| 11-11| 22-24| 1-26| 1-26| 1-26| 1-26| 3-26| 5-4 | |------+------+------+------+------+------+------+------| State 6| 10-1 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 3-2 | 6-4 | |------+------+------+------+------+------+------+------| State 7| 8-1 | 8-1 | 1-14| 1-14| 1-14| 1-14| 3-14| 7-4 | |------+------+------+------+------+------+------+------| State 8| 8-1 | 8-1 | 1-15| 1-15| 1-15| 1-15| 3-15| 8-4 | |------+------+------+------+------+------+------+------| State 9| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 3-2 | 9-4 | |------+------+------+------+------+------+------+------| State 10| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 3-16| 10-4 | |------+------+------+------+------+------+------+------| State 11| 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 1-8 | 11-4 | |------+------+------+------+------+------+------+------| State 12| 1-8 | 1-8 | 1-2 | 1-8 | 1-8 | 1-2 | 3-2 | 12-4 | |------+------+------+------+------+------+------+------| State 13| 13-1 | 13-1 | 14-4 | 13-1 | 13-1 | 13-1 | 13-22| 13-1 | |------+------+------+------+------+------+------+------| State 14| 1-2 | 1-2 | 13-1 | 1-2 | 1-2 | 1-2 | 3-2 | 1-2 | |------+------+------+------+------+------+------+------| State 15| 15-1 | 15-1 | 1-2 | 1-2 | 15-1 | 1-2 | 3-2 | 15-4 | |------+------+------+------+------+------+------+------| State 16| 1-18| 1-18| 1-18| 1-18| 1-18| 1-18| 3-18| 16-4 | |------+------+------+------+------+------+------+------| State 17| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 3-2 | 17-4 | |------+------+------+------+------+------+------+------| State 18| 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 1-2 | 3-2 | 18-4 | |------+------+------+------+------+------+------+------| State 19| 1-16| 1-16| 1-16| 1-16| 1-16| 1-16| 3-16| 19-4 | |------+------+------+------+------+------+------+------| State 20| 21-1 | 1-21| 1-2 | 1-2 | 1-2 | 1-2 | 3-2 | 20-4 | |------+------+------+------+------+------+------+------| State 21| 1-21| 1-21| 1-16| 1-16| 1-16| 1-16| 3-16| 21-4 | |------+------+------+------+------+------+------+------| State 22| 2-1 | 1-25| 13-4 | 16-1 | 1-13| 1-3 | 3-6 | 1-4 | |------+------+------+------+------+------+------+------| .sp 3 NOTES ON THE STATES .sp 2 .sp 3 NOTES ON THE ACTIONS .sp 2 .sp 3 P_R_O_C_E_D_U_R_E_ -- fortran_xfer_vector .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This ALM subprogram is the outgoing transfer vector for the FORTRAN compiler. All calls to utility entry points are routed through this vector. This procedure has as synonyms, all of the names of the utility procedures. All utility entry point names are unique. .sp 2 This transfer vector is also used by fortran_io_op to reference the code generator procedure it needs. The list of compiler utilities is found in Section 2 of this PLM. The list of code generator utilities is found in Section 5 of this PLM in the paragraph on fortran_io_op. .sp 3 P_R_O_C_E_D_U_R_E_ -- general_format_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses format statements. It is called by both the compiler and the I/O runtime routines. The parser is basically a table driven discrete state machine. .sp 2 As the format statement is parsed, a symbolic form of the format specifications is stored in an array. This array is used to control the formatted I/O routines. This array is also what is stored as part of the user's subprogram if the format statement is parsed during a compilation. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 general_format_parse entry (char(1024), char(2048) fixed bin(35)) .sp 2 .in 5 .un 3 1. The format specification to be parsed. It must start with a left parenthesis and parsing will terminate with the matching right parenthesis. .sp 2 .un 3 2. The result of the parse. This is a structure of the form specified by the include file format_tables. .sp 2 .un 3 3. An error code. If the parse is successful, the value zero is returned. Otherwise, a nonstandard error code is returned. .sp 2 .in 10 .un 4 64 Syntax error in format statement. Misplaced comma. .sp 2 .un 5 144 Missing "(" in format statement. The first nonblank character of the format specification is not a left parenthesis. .un 5 .sp 2 145 Syntax error in specifying a format. .sp 2 .un 5 166 Format specification is longer than 1024 characters. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_format_parse ftn_io_format_ (formatted I/O runtime) .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 None .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 None .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 None .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- go_to_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses the three FORTRAN goto statements. It decides which type the statement is before parsing. The decision is based on the token immediately following the token goto. An identifier means an assigned goto statement; a dec_integer means an unconditional; and a left parenthesis is a computed goto. Any other token is a syntax error. .sp 2 For an unconditional goto statement, the dec_integer token is declared as a label. If the label already exists as the label on a format statement, an error is printed. If the label is undefined, it is flagged as being executable. .sp 2 A jump operator is put in the tree. .sp 2 For an assigned goto statement, the identifier must have the fixed attribute but not the dimentioned attribute. If a comma follows the identifier, there must be a parenthesized list. The list is scanned by list_scan. .sp 2 For a computed goto statement, a label array is created. The procedure list_scan scans the list and initializes the label array. The comma between the list and the expression is optional. After the expression is parsed, it is converted to integer if necessary. A pass is made to simplify the offset expression. The addition or subtraction of integer constant can be removed from the expression and made part of the constant offset. .sp 2 If the subscriptrange option is given, a "bound_ck" operator node is created. .sp 2 A reference node is created and given the proper constant and expression offsets. It is an unshared reference. .sp 3 list_scan (internal procedure) .sp 2 This procedure is called after the left parenthesis of a list of labels has been parsed. It will parse the list until a right parenthesis is encountered. The list is a series of decimal integers separated by commas. If the label is associated with a nonexecutable statement, an error is printed. If the label has not been associated with a statement, it is flagged as a label for an executable statement only. .sp 2 If a label array is being created (computed goto), then the pointer to the statement node of the first label in the list is stored in the statement field of the label array. If the first label is not defined yet, the procedure statement_recognizer will handle the assignment. An unshared reference node is created for the label array whose constant offset is one less than its position in the list. This is threaded in as the last label on the statement. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 go_to_parse entry (pointer) .sp 2 The pointer is to the statement node for the goto statement. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_if_parse fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 create_label create_list create_operator create_reference declare_constant declare_temporary fortran_expression_parse fortran_reference_parse free_node make_label parse_error -- 34, 35, 92, 158 statement_recognizer$back_up statement_recognizer$next_token .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$check_bounds fortran_stat_$cur_block .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 boundary declare_type fortran label language_utility list nodes op_codes operator reference source_id_descriptor statement symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- initial_attribute .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure parses data initializations for data and mode statements. Implied loops may appear in data statements. .sp 2 This procedure scans the constant list in a data or mode statement and prepares the initial attribute information to be included in the symbol nodes of the variables in the associated declaration list. If the statement being parsed is a data statement, assignment statements are inserted into the prologue for initialization of variables in automatic storage and the initial attribute deleted from the associated symbol nodes. Initialization of automatic variables indicated during a mode statement parse is simply "remembered" by the setting of block.no_stack; fortran_parse will perform final processing following equivalance statement parsing. .sp 2 When initial_attribute is called to parse a mode statement constant list, all the information required about the variables is contained within the associated symbol nodes. To make processing uniform, a "dummy" data statement declaration list node is constructed for each symbol just prior to its initialization. The same "dummy" node is used for each symbol. .sp 2 For each symbol, three values are required; the number of elements, the number of characters per element and the number of word per element. For character mode variables, the number of characters per word is directly available. For complex or double precision it is the compiler constant "characters_per_double". for all others it is "characters_per_word". Words per element is obtained by determining how many words are required to contain the characters. Number of elements is determined by dividing constant word size by words per element. If the symbol does not have a constant word size, an array with expression extents, data initialization is invalid. .sp 2 As each variable is prepared for initialization, it is determined if an implied-do began with its declaration. If the indices node pointer in the data declaration list node is null, one or more do loops must be initialized. .sp 2 The variable nest_level always indicates the current do nesting level. When a do loop is initialized nest_level is incremented by one. The array element begin_ptr (next_level) is set to point to the current data declaration node. This is used to determine which declaration represents the loop beginning during the declaration scan loop. At this declaration one must determine if any "inner" dos beyond the current level must be initialized by examining the appropriate "next" pointer in the indices by node chain; at other declarations the need to activate "inner" dos is determined by a nonnull indices node pointer in the data declaration node. The array element current_do (next_level) is set to point to the indices node associated with the current do. Thus if the current declaration node is pointed to by begin_ptr (next_level), then the pointer to an inner do indices node chain is current_do (nest_level) -> indices.next; otherwise it is simply data_list.index_ptr in the current declaraction node. .sp 2 The do control variable is i (next_level) and it is initialized to the first value in the associated indices node. Once the declaration node pointed to by current_do (nest_level) -> indices.end_ptr is processed, i(nest_level) is incremented and tested using values two and three in the indices node. When a do ending is determined, nest_level is reduced by one and any other do's ending at this declaration processed in turn. Otherwise, the subprogram logic (constant mapping, etc.) is repeated from begin_ptr (nest_level). .sp 2 The element offset is either set to zero or calculated using subscripting data retained in a subscripts node chain pointed to y the declaration node. It is calculated using the normal algorithm: .sp (value (i) *multiplier(i)) - virtual origin .sp The vaues are either constants (when subscripts.variable is null) or do index control variable values (when subscripts.variable is not null). In the latter case, the value specified in the subscripts node is the nest level of the do index to apply. If the value specified in the subscripts node is zero an error condition exists; if a variable subscript appears which does not match a do control variable an error is reported. For an ofset calculation resulting in a fixed overflow or one resulting in a value that exceeds the array size, an error is reported. .sp 2 In addition to an offset, a "number" is calculated which is 1 for a scalar or an array element (subscripting was specified) or is the number of elements as calculated above for an array (no subscripting occurred). .sp 2 If a subscripted reference occurs within an implied do loop, an attempt is made to eliminate implied do loops which are actually necessary. The following conditions must be met: .sp .in 8 .un 3 1. All subscripts must be do loop control variables. .sp .un 3 2. The left most subscript must be the control variable for the innermost loop. .sp .un 3 3. This symbol must be the only symbol within the do loop. .sp .un 3 4. The increment value for the do loop variable must be 1. .in 0 .sp 2 If all of the above are statisfied, the nest level is decremented by 1 and the element size is multiplied by .sp final_value - initial_value+1 .sp where final_value is the final value for the implied loop and initial_value is the initial value. .sp 2 If initial_value is equal to the constant lower bound for this subscript position,and final_value is equal to the constant upper bound for this subscript position, the entire process is repeated for the next do loop. .sp 2 Since a symbol may be initialized through several declarations in several statements and the elements may be initialized in any order, it is required to locate the position in any existing initial attribute node chain of the new initialization constant(s). This is done using the offset as calculcated above, and the repetition factors in existing nodes. .sp 2 During this process, the constant's offset is reduced and now represents the offset within the storage interval which corresponds to the original offset. .sp 2 When the current repetition factor is zero a new constant must be defined. An attempt is made to scan a new token. The previous occurrence of a slash or a semicolon implies a premature end of the constant list and an error is reported. Once a new token is retrieved it is examined for a statement ending (slash or semicolon). Either of these imply an omitted declaration and a null value is used. For all other cases it is determined if a repetition factor is specified by a look-ahead for an asterisk. If specified, the repetition factor must be decimal integer within the computer's range or an error is reported. If repetition is not specified, a factor equal to 1 is used. .sp 2 The constant is now parsed. If a comma is found, a null value is assumed. Thus one can say: .sp integer x(100) /50*1, 10*, 40*1/ .sp A complex constant is recognized by the leading left parenthesis and results in the creation of a new token to serve as the value .sp [-]a(+) b i (-) .sp where " [-]a,[(+)] b" is the constant declared. Finally, remaining token types permitted are dec_integer, fixed_dec, or float_dec; where preceded by a minus sign a new token is created as a concatenation of the sign and the original token. Note that if a nonnegative nonzero dec_integer token precedes a char_string token a fortran hollerith constant has occurred and the char_string token is used as the constant. .sp 2 If the token is an identifier, it might be the name of a named constant, an octal constant, or a short form of the logical constants. If the identifier is declared and the symbol has the constant attribute and a mode, it is a named constant. An integer named constant may be a data value or a repetition factor. .sp 2 If the first character of the identifier is an "o" and the length of the identifier is greater than one, it is parsed as an unsigned octal constant. If the length of the identifier is greater than one, but does not start with an "o", it is a syntax error. .sp 2 If the identifier has a length of one, it must be an "o", "t", or "f". If it is an "o", the token following it must be a sign, and the token following the sign must be a decimal integer. The integer will be parsed as an octal constant and the sign applied to the high order bit This is a signed octal constant. .sp 2 The string "t" and "f" denote .true. and .false. respectively. .sp 2 These three constants, signed octal, "t" and "f" are only recognized if either the -card or -convert option is specified. .sp 2 Octal and character strings required special processing and there are switches set to indicate if the constant is one of those two types. .sp 2 Assigning a character constant to a symbol is complex. Two cases exist. The length of the string is less than or equal to the character size of variable, or the length is greater. In the former, the initial value assigned is the entire string and the repetition factor is reduced. In the latter, a substring is taken. A variable saves the number of characters "used" in the string in the event that more substrings are needed. .sp 2 The initial value is stored in an ordered chain of initial values for the symbol. If the current initial value attempts to override a previous one, it is in error. Also, if the initial value for a particular array element is the same value as its predecessor or antecedent, the two nodes are combined. .sp 2 Once the particular initialization is complete it is necessary to determine if the initializations with that constant are done and with the list in general. A single character constant can be used to initialize an array if the array is not within an implied loop and the character length of the constant is greater than the number of characters per array element. .sp 2 If an array is being initialized there may be a need for more constants. Once the element count for the variable is reduced to zero, implied do loop indices are incremented and processing continues until the end of the list. .sp 2 After the variable list is completely satisfied, the chain for the variables is gone through once again. If this is a mode statement then the borrowed pointer is nulled..sp 2 If this is a data statement, all the special list nodes are released. These are all the nodes used to represent implied do loops and used to chain the symbol nodes. .sp 2 The loop must end at a slash with the repetition factor having reached zero. .sp 3 U__s_a_g_e .sp 2 initial_attribute entry (pointer, pointer) .sp .in 8 .un 3 1. This is either a pointer to a symbol node or a data_list node. If it is a symbol node then the data initialization occurred in a mode statement. Otherwise it is part of data statement. .sp .un 3 2. This is a pointer to a token. On entry to the procedure it points to a slash token. On return it points to the first token after the closing slash of the data initialization. If there is a syntax error, it points to the first to token of the next statement. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 declaration_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 .nf bindec$vs convert$to_target create_cross_reference create_list create_token declare_constant parse_error -- 1, 2, 3, 4, 5, 6, 7, 8, 88, 89, 253 prologue_entry$auto_initial statement_recognizer$back_up statement_recognizer$next_token token_to_binary .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$card_input fortran_stat_$cur_block fortran_stat_$cur_statement fortran_stat_$list3_node fortran_stat_$list_5_node .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 array block boundary cross_reference declare_type fdata_nodes fortran language_utility list nodes op_codes operator reference source_id_descriptor statement symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- make_format .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure handles the creation and referencing of all labels. There are separate entry points for executable labels and format statement labels. .sp 2 For format statement labels, leading zeros are ignored. An identifier token of the form "format.n" is created where n is the label in question. If the token has been declared, its associated symbol is returned. Otherwise, a symbol node is created for the token and the created symbol is returned. A cross reference node is created for the symbol. .sp 2 For execulabels labels, leading zeros are ignored. If the token has an associated label node its reference count is increased by one. If there is no label node, it is created and its reference count set to one. A cross reference node is created for the label node. .sp 3 U__s_a_g_e .sp 2 make_label entry (pointer) returns (pointer) .sp 2 The input argument is a pointer to a token node. .sp 2 The return value is a pointer to a label node. .sp 3 make_format entry (pointer returns (pointer) .sp 2 The input argument is a pointer to a token node. .sp 2 The return value is a pointer to a symbol node. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf make_format .sp 1 fortran_format_parse fortran_io_parse .sp 3 make_label .sp 1 fortran_assign_parse fortran_do_parse fortran_if_parse fortran_io_parse fortran_reference_parse go_to_parse statement_recognizer .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 create_cross_reference create_label create_list create_symbol create_token parse_error -- 74 .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$cur_block fortran_stat_$format_list fortran_stat_$statement_id .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 cross_reference declare_type label language_utility list nodes source_id_descriptor statement statement_types symbol token token_types .sp 3 .fi P_R_O_C_E_D_U_R_E_ -- prologue_entry .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is called to convert a string of initial values to assignment statements in the prologue sequence. This measure is needed to properly initialize automatic variables. .sp 2 The procedure initial_attribute parses data declarations and puts them in the proper form for internal static initializations. This procedure changes that format to a series of assignment statements in the prologue. The nodes which comprised the initializations are freed. .sp 2 Arrays which are initialized must have constant bounds and element size. .sp 2 If the value pointer is null, no values are stored for the corresponding elements. .sp 3 U__s_a_g_e .sp 3 .in 5 .un 5 prologue_entry$auto_initial entry (pointer) .sp 2 A pointer to a symbol node. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_parse initial_attribute .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 copy_expression create_operator create_statement$prologue create_symbol create_token declare_constant fortran_operator_semantics token_to_binary .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$cur_block fortran_stat_$list3_node .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 block boundary declare_type fortran language_utility list nodes op_codes operator reference source_id_descriptor statement statement_types symbol system token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- replace_parameters .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is called whenever a reference to a statement function is parsed. It is responsible for replacing every occurance of a formal parameter with its corresponding actual parameter. .sp 2 If the input pointer points to a statement function parameter node (sf_par_node), the corresponding actual argument is copied and returned. .sp 2 For standard call operators, the argument list is scanned. For other operators, all source operands are checked. .sp 2 For reference nodes, a cross reference node is created, and the allocate attribute is propogated to the symbol's parents. .sp 3 U__s_a_g_e .sp 2 .in .un 5 replace_parameters entry (pointer, dim(128) pointer, fixed bin(15)) returns (pointer) .sp 2 .in 10 .un 5 1. A pointer to the expression to be fixed up. This may be any pointer or null. If it is a node which is not known to the logic of the procedure it is returned without modification. .sp 2 .un 5 2. An array of pointers. The nth element of the array points to nth actual argument to the statement functions. .sp 2 .un 5 3. The number of arguments supplied in this statement function referenced. .sp 2 .un 5 Return -- A pointer to node created by this procedure, or the node passed to this procedure. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf fortran_reference_parse replace_parameters .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 convert$to_target copy_expression create_cross_reference declare_temporary parse_error 133 replace_parameters .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$cur_statement .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 cross_reference fortran if_par language_utility list nodes op_code operator reference source_id_descriptor statement symbol .sp 3 .fi P_R_O_C_E_D_U_R_E_ -- set_parameters .sp 2 F_u_n_c_t_i_o_n_s .sp 2 This procedure walks through an expression tree and replaces all references to statement function format parameter with "sf_par" nodes. It also turns off the allocate attribute for all symbols referenced in the expression. Thus the symbol is only allocated if the statement function is referenced. .sp 2 If the node is a reference node, its associated symbol has its allocate attribute removed. If the associated symbol is a format parameter, the node is replaced by a sf_par node. If the reference node has a quilifier expression, the procedure is called recursively for that. .sp 2 If the node is a standard call operator, the procedure is called recursively for each element of the argument list. .sp 2 If the node is any other operator node, the procedure is called recursively for each operand except the first. .sp 2 If the node is not one of the above, it is not changed. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 set_parameters entry (pointer, pointer) returns (pointer) .sp 2 .in 10 .un 5 1. a pointer to the node to be walked through .sp .un 5 2. A pointer to a list of n elements. The nth element is the nth formal parameter of the statement function. .sp 2 .un 5 Return -- the resulting node, see functions. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf set_parameters stmnt_func_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 pl1_get set_parameters .sp 2 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 None .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 fortran list nodes op_codes operator reference rename sf_par symbol .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- statement_recognizer .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure and its entry points perform an odd assortment of functions. .sp 2 .in 5 .un 5 o{{{{Recognizes statement type of a statement. The algorithm involves a table look up after a rudimentary parse of the first reference. .sp 2 .un 5 o{{{{statement labels are recognized and declared .sp 2 .un 5 o{{{{This procedure maintains the token stack of the statement being parsed. It is called to provide parsers with the tokens of the user subprogram. .in 0 .sp 2 The major part of this procedure does statement recognition and this will be covered first. .sp 2 Statement recognition is requested via three separate entry points. One to initialize, one normal entry, and one entry for logical if statements. .sp 2 The initialization entry point initializes all the internal static variables and then proceeds to the normal code sequence. The logical if entry sets a switch before proceeding to the normal code. This switch inhibits the recognition of statement labels. .sp 2 First, the end of the preceding statement must be found. If this is a normal call, the token stack is scanned for a newline or semicolon token. When one is found, the previous statement is considered ended. The next token, if it is not a newline or a semicolon is the first token of the statement. Semicolons are not skipped if the procedure is called from the if parse. .sp 2 If this is not a call from the if parse, statement length and sequence information is stored. Also if the debug option has been set and the current source sequence number is equal to the stop_id, "debug" is called. .sp 2 If the current token is a dec_integer, it is a statement label. The hollerith node switch is reset, then set to allow labelled assignment statements to start with the letter "h". .sp 2 End lines are recognized next. If the first token of the statement is "end" and the second is a newline or semicolon, and there is not statement label, the statement is an end line. .sp 2 Statements which do not begin with identifier tokens are considered assignment statements. If the statement begins with an identifier, it is skipped, and any parenthesized list which appears immediately after it. After these tokens are skipped, it hte next token is an assignment token, it is an assignemnt statement. Otherwise, the first token of the statement is looked up in a keyword table. If a match is found, the statement type is returned. .sp 2 A statement node of the proper type is created for the statement. If the user has defined a label for this statement, the label is processed. If the statement is not executable, the label may not be referenced as a format statement or as the target of a transfer of control. .sp 2 If the label appeared as the first element of a computed goto list of labels, this statement is the defining statement for the label array. .sp 2 If the statement is not an assignment statement, two situations may arise. Either the identifier is longer than the keyword or it is the same size. If it is longer, a second token is created with the "leftover" characters. .sp 2 There are four entries for token processing. Two, next_token and back_up are used generally. The other two are used while processing do statements (top_of_stack and back_up_statement). .sp 2 The entry next_token returns a pointer to the next token in the stack. Next refers to the token position following the value of current_index. If the next token is not in the list yet, a lexer is called to retrieve it. .sp 2 The entry back_up, backs the value of current_index by n; where n is an input argument. A pointer to the new current token is returned. .sp 2 The entry back_up statement, sets the value of current_index to the index of the first token of the statement. A pointer to the token is returned. .sp 2 The entry top_of_stack,sets the value of current_index to stack_index. A pointer to the token is returned. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 statement_recognizer entry (pointer) returns (fixed bin(8)) .sp 2 The pointer returned is a pointer to the statement node. The node is created by statement_recognizer. .sp 2 The fixed bin returned is the statement type of the statement. .sp 3 .un 5 back_up entry (fixed bin(15)) returns (pointer) .sp 2 input is number of tokens to back up. .sp 2 Return is pointer to the new token. .sp 3 .un 5 back_up_statement entry (1 returns (pointer) .sp 2 Returns a pointer to the first token of the statement. .sp 3 .un 5 from_if_parse entry (pointer) returns (fixed bin(8)) .sp 2 Argument is a return value. It is a pointer to the statement node. .sp 2 Return is statement type of statement recognized. .sp 3 .un 5 next_token entry () returns (pointer) .sp 2 Returns a pointer to the next token in the token list. .sp 3 .un 5 top_of_stack entry () returns (pointer) .sp 2 Returns a pointer to the last token parsed for the statement. .sp 3 .in 0 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf statement_recognizer and init .sp 2 fortran_parse .sp 3 from_if_parse .sp 2 fortran_if_parse .sp 3 back_up .sp 1 dcl declaration fortran_assign_parse fortran_do_parse fortran_expression_parse fortran_if_parse fortran_io_parse fortran_reference_parse fortran_subroutine_parse go_to_parse initial_attribute .sp 3 back_up_statement and top_of_stack .sp 2 fortran_do_parse .sp 3 next_token .sp 2 dcl declaration_parse fortran_assign_parse fortran_crse_parse fortran_do_parse fortran_expression_parse fortran_format_parse fortran_if_parse fortran_io_parse fortran_parse fortran_reference_parse fortran_subroutine_parse go_to_parse initial_attribute stmnt_func_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 cardlex cardlex$write_last_line create_statement create_token debug flex flex$write_last_list ioa_ make_label parse_error -- 129, 158, 165, 167 .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 fortran_stat_$apostrophe-node fortran_stat_$card_input fortran_stat_$cur_statement fortran_stat_$debug_semant fortran_stat_$expl_continuation_count fortran_stat_$hollerith_node fortran_stat_$profile_length fortran_stat_$st_length fortran_stat_$st_start fortran_stat_$statement_id fortran_stat_$stop_id tree_$ .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 block cross_reference declare_type fortran label language_utility list nodes reference source_id_descriptor statement statement_types token token_types .sp 3 .fi P_R_O_C_E_D_U_R_E_ -- stmnt_funct_parse .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure is called to parse what is either a statement function definition or the first assignment statement of the subprogram. The left hand side is parsed the "sf" entry of the reference parser. Mainly this entry allows undeclared subscripted references on the lefthand side of an assignment statement. If such is found, the reference parser will declare it as a statement function and parse it accordingly. .sp 2 The reference parser will create a list of n elements, one for each dummy argument, and set the lcok attribute. This attribute bit is borrowed by the FORTRAN compiler and used to denote a statement function. the symbol for the statement function is never allocated so the code generator is never confused. .sp 2 If the reference parser does not find a statement function definition on the left-hand side, the statement is an assignment statement. An assignment statement node is created. .sp 3 U__s_a_g_e .sp 2 .in 5 .un 5 stmnt_func_parse entry(bit(1) aligned, pointer) .sp 2 This is a return value. If the statement parsed is a statement function this will have the value "1"b. .sp 2 A pointer to the statement node for the statement to be parsed. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 fortran_parse .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 .nf create_operator fortran_expression_parse fortran_operator_semantics fortran_reference_parse$sf parse_error -- 135, 136, 137, 138 set_parameters statement_recognizer$next_token .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 fortran label language_utility list nodes op_codes operator reference source_id_descriptor statement statement_types symbol token token_types .fi .sp 3 P_R_O_C_E_D_U_R_E_ -- type .sp 2 F__u_n_c_t_i_o_n_s .sp 2 This procedure sets the bit and word size fields for a symbol dimensioned before it is given a mode. If the symbol has fixed bounds, there will be constants, otherwise they are expressions. .sp 3 U__s_a_g_e .sp 2 .fi .in 5 type$fix_array_sizes entry (pointer, fixed bin(24), fixed bin(24)) .sp 2 .in 8 .un 3 1. A pointer to the symbol node for which all this owrk is to be done. .sp 2. The constant work size for each element of the array. .sp 3. The constant bit size for each element of the array. .in 0 .sp 3 P__r_o_c_e_d_u_r_e_s_T__h_a_t_I__n_v_o_k_e_T__h_i_s_P__r_o_c_e_d_u_r_e .sp 2 .nf dcl declaration_parse .fi .sp 3 P__r_o_g_r_a_m_s_C__a_l_l_e_d .sp 2 .nf create_operator declare_constant declare_temporary parse_error -- 28 .sp 3 E__x_t_e_r_n_a_l_D__a_t_a .sp 2 None .sp 3 I__n_c_l_u_d_e_F__i_l_e_s .sp 2 language_utility array nodes op_codes operator reference source_id_descriptor symbol system .fi  sec6.runoff 03/29/79 1519.7rew 12/12/74 1748.7 220572 .ce 3 SECTION VI .sp FORTRAN I/O ROUTINES .sp 3 O_V_E_R_V_I_E_W_ .sp 2 The FORTRAN I/O routines provide the runtime support to implement FORTRAN I/O, encode and decode statements, and pause and stop statements. The pause and stop statements are each implemented by a single independent procedure. FORTRAN I/O, encode, and decode are implemented by five interdependent procedures. Most of this section will be devoted to the design and implementation of the FORTRAN I/O system. .sp In order to allow communication between the FI/O system procedures and between the user program and these procedures, a data structure is created by the user's program. Some fields are constant for a given program and are therefore initialized at block activation time. Others specify the details of the user's I/O request. Finally, there are fields which are used by the FI/O system to store values which must remain static through several procedure calls. Thus, this data structure also functions as the static storage for the FI/O system during a single I/O request. .sp D_A_T_A__S_T_R_U_C_T_U_R_E_S_ .sp 2 The only global data structure used in the FI/O system is called the PS. The name and structure are borrowed from the PL/1 I/O implementation. Only those fields set by the prologue code have the same values in PL/1 and FORTRAN. The method of setting and using the structure is different. .sp Currently, the following fields are defined in the structure: .sp .in 15 .un 4 1. A pointer to the stack frame of the user's subprogram. This field is set by prologue code and is therefore always valid. The FI/O system uses this pointer to build a label if the user has specified alternate processing after an error condition or end of file. This pointer is also used by the namelist procedure as the current stack frame. .sp .un 4 2. Two pointers to the runtime symbol table. One pointer points to the top of the symbol table, the other to the symbol table for the current block. These fields are set by prologue code only if the appropriate parts of the symbol table exist. Namelist I/O statements cause the creation of the symbol table. The user can also provide an argument to the compiler which will cause the creation of the symbol table. These pointers are only used by the namelist I/O processor. They are assumed to contain undefined values during all other I/O requests. .sp .un 4 3. A pointer to the format specification for this I/O request or else the value is undefined. For all formatted I/O requests, including encode and decode, this pointer indicates the specifications to be used. This pointer is set by the user subprogram just before the I/O request is made. The value of the pointer is undefined for non-formatted requests. .sp .un 4 4. A fixed binary number specifying the file reference number for the I/O request. This field is undefined for string I/O requests. The user subprogram loads the file reference number into the q-register before calling the fortran_read, fortran_write, of ftn_file_manip operator. The operator stores the value in the PS. .sp .un 4 5. The record number for a direct access I/O request. The user subprograms stores the record number in the PS. This field is undefined for sequential I/O requests. .sp .un 4 6. A pointer to a labeled statement in the user subprogram. This pointer is only set if the user includes "err=" in the I/O request. If an error occurs which the FI/O system cannot correct, either a message will print and execution will be aborted, or, if the "err=" appears, no message will print and execution will continue with the labeled statement. Currently, there is no way for the user to ascertain what caused the I/O request's failure. (End of file is not an error, see below.) .sp .un 4 7. A pointer to a labeled statement in the user subprogram. This pointer is only set if the user includes "end=" in the I/O request. This pointer is used in a manner similar to the error pointer (see above), however it is used when an end of file condition is reached. .sp .un 4 8. A pointer to the format in interpretive form. In order to improve performance, a format specification is parsed before the actual processing of data is initiated. The parse produces an alternate representation which is more readily used to drive the format routines. Format specifications which are in format statements are parsed at compile time and this pointer will assume the value of the user format pointer (see above). .sp .un 4 9. A pointer to the current buffer. For string I/O requests, this pointer will be set by the user subprogram to point to the first "record" of the request. For file I/O requests, the FI/O system will store a pointer to the buffer to be used. This field is always defined during an I/O operation. .sp .un 5 10. A pointer to the OK list for a namelist request. The OK list specifies the variables in the user program which are valid for the I/O request. For an input request, the list specifies the range of valid input variable names. For output, the list specifies the values to be output. This pointer is undefined for non-namelist requests. .sp .un 5 11. A string of bits which describe characteristics of the I/O request. The user subprogram loads the appropriate bit string into the a-register before calling the fortran_read, fortran_write, or ftn_file_manip operator. The operator stores the value into the PS. This bit string has the following subfields: .sp 2 .in 20 .un 4 1. error_label - 1 bit; if one, then field #6 above contains a valid pointer. Further, all error messages should be suppressed. .sp .un 4 2. end_label - 1 bit; if one, then field #7 above contains a valid pointer. So if an end of file is encountered, no message is printed. .sp .un 4 3. read - 1 bit; if the I/o request is for data transmittal, this bit indicates the direction. If one, this is an input request. .sp .un 4 4. format - 2 bits; this field indicates the type of I/O transmission requested. "00"b - free format or list-directed; "01"b - unformatted or binary; "10"b - formatted; " "11"b - namelist. .sp .un 4 5. mode - 2 bits; the file type as specified by the user's I/O statement. This field is in no way related to the file type of the actual file. "00"b - sequential; "01"b - direct access; "10"b - string I/O; "11"b - undefined. .sp .un 4 6. list - 1 bit; if one, this I/O request specifies a list of elments to be transmitted. This field has no meaning for control requests. .sp .un 4 7. control_type - 3 bits; this indicates the type of the I/O request. "000"b - data transmission (the read subfield indicates the direction); "001"b - endfile; "010"b and "011"b - rewind; "100"b, "101"b, "110"b, and "111"b - backspace. Actually, the compiler only generates the values "000"b , "001"b, "010"b, and "100"b and the current implementation uses the index builtin to determine the request type. .sp .un 5 12. The maximum length for the current buffer. For file I/O this value is calculated dynamically and is equal to the maximum segment length minus about 200 words. These words are reserved for FI/O control tables. For string I/O, this field specifies the virtual record size. .sp .un 5 13. A one word element descriptor. This descriptor is set by the user subprogram. The appropriate bit string is loaded into the a-register before the ftn_scalar_xmit operator is called. The operator stores the descriptor and then calls the FI/O system. The first six bits indicate the data type - integer, real, double precision; complex, logical, and character. The seventh bit is one if this is an array transmission. The next twenty- four bits constitute a fixed bin (23) value which is the length of a character variable and zero for all other data types. The eighth bit is not used. .sp .un 5 14. This field contains a fixed binary value which is equal to the number of words in an array if the array transmission bit is one (in the descriptor above). Otherwise this field is undefined. .sp .un 5 15. A pointer to the element to be transmitted. It is set by the user subprogram, however, during an array transmission, the pointer may be stepped through the array by an F/IO procedure. .sp 2 .in 0 B__u_f_f_e_r_T__a_b_l_e .sp 2 In order to maintain process-wide file information, an external static table is maintained. This table is created by copying the segment fortran_buffer_ into the user's process directory. This function is performed by the linker the first time fortran_buffer_ is referenced. The rest of the segment is used as buffer area by FI/O. The table contains ninety-nine entries, one for each file reference number. The following information is stored: .sp .in 15 .un 4 1. default_input - This bit (1) field is off for all files except 5 and 41. When a file is opened and the user has not made an attachment for it, nor is this a segment for that file, this bit is checked to see if the file should be attached to the user's terminal or to a segment. The value of this bit is never changed. .sp .un 4 2. default_output - This bit (1) field is off for all files except 6 and 42. Its function is identical to that of default_input except that default_input is attached to user_input and default_output is attached to user_output. The value of this bit is never changed. .sp .un 4 3. print_file - This bit (1) field is off for all files except 6 and 42. If this bit is on during an output operation, the first character of the record is treated as any other data character. This bit can be modified by the set_cc command. The close_file command does not affect this bit. .sp .un 4 4. attached - This bit (1) field is on if the file is currently active. If this bit is off, FI/O will attempt to attach and open it. .sp .un 4 5. fortran_attached - This bit (1) field is on if FI/O is responsible for attaching the file to a segment. Unless this bit is on, FI/O will not detach a file when it is closed in the FORTRAN sense. .sp .un 4 6. fortran_opened - this bit (1) field is on if FI/O is responsible for opening the file. Unless this bit is on, FI/O will not close a file when a FORTRAN endfile is requested. .sp .un 4 7. console_file - At the time the attach bit is set, this bit (1) field is set to one if the file attachment is ultimately directed at the user's terminal. Otherwise, it is zero. .sp .un 4 8. char_file - This bit (1) field is on if the file is not unformatted (i.e., list-directed, formatted, or namelist). It is set at attach time. .sp .un 4 9. previous - This bit (3) field specified the last FI/O request performed for this file. This field is modified every time the processing of a request is completed. .sp .un 5 10. first_record - This bit (1) field is set to on by an open, endfile, rewind, or backspace request. Due to the current implementation, files directed at segments do not have terminal newline characters until the file is closed. This allows the implementation of the plus sign (+) carriage control character by deferring the output of the newline until the appearance of the next record. .sp .un 5 11. append_newline - This bit (1) field is also used when dealing with print files which are directed at segments. .sp .un 5 12. switch_p - This pointer is initially null. When an I/O switch is made known to FI/O, its pointer is stored in this field to permit faster access to the switch. .sp 3 .in 0 P_R_O_C_E_D_U_R_E_S_ .sp P__r_o_c_e_d_u_r_e - fortran_io_ .sp FUNCTIONS .sp 2 This procedure is the interface between the FI/O system and external users. The commands set_cc and close_file also interface through this procedure. This procedure acts as a call forwarder to invoke the proper action procedure. .sp 2 USAGE .sp 2 .nf read_or_write entry (pointer) file_control entry (pointer) close_file entry (pointer) set_cc entry (pointer) element entry (pointer) terminate entry (pointer) .fi .sp 2 The pointer points to the PS. .sp PROCEDURES THAT INVOKE THIS PROCEDURE .sp None .sp PROGRAMS CALLED .nf .sp ftn_io_binary_ ftn_io_binary_$init ftn_io_control_ ftn_io_control_$abort ftn_io_control_$write ftn_io_format ftn_io_format_$init ftn_io_free_ ftn_io_free_$init ftn_io_namelist_ .sp .fi EXTERNAL DATA .sp .nf Fortran_buffer_ error_table_$no_file .sp INCLUDE FILES .sp fortran_buffer fortran_job_bits fortran_ss .fi .sp 2 P__r_o_c_e_d_u_r_e - ftn_io_binary_ .sp FUNCTIONS .sp 2 This procedure transmits data to and from unformatted files. The procedure either reads or writes one record to/from the file. When creating a file, the record is virtually unlimited in length. (The limit is 256K - 205 words.) While reading a record, the amount read is limited to the actual record length. I/O is actually done in words although the Multics file system deals with the data in units of characters. .sp 2 USAGE .sp 2 .nf ftn_io_binary_ entry (pointer) ftn_io_binar$init entry (pointer) .sp The pointer points to the PS. .sp PROCEDURES THAT INVOKE THIS PROCEDURE .sp 2 fortran_io_ .sp PROGRAMS CALLED .sp com_err_ ftn_io_control_$abort .sp EXTERNAL DATA .sp fortran_buffer_ .sp INCLUDE FILES .sp fortran_buffer fortran_job_bits fortran_ps .sp 2 P__r_o_c_e_d_u_r_e - ftn_io_control_ .sp FUNCTIONS .sp .fi This procedure interfaces between the Multics I/O system and FI/O system. It is also in charge of initializing the buffer for I/O. Finally, error conditions are reported to the user via the abort entry. The abort entry prints all available information about the I/O request, offers to close files for the user and then aborts execution by signalling command_abort_. This section of code is also used by the FORTRAN stop statement. .sp At the beginning of all file I/O requests this procedure is called to prepare both the file and the I/O buffers. The action performed by this procedure is based on the current request and the immediately previous request. The actions are indicated by the table below. .sp .ne 8 .ce Present Operation .sp .nf .ne 8 ____________|_R__e_a_d___W__r_i_t_e___B__a_c_k_s_p_a_c_e____R__e_w_i_n_d____E__n_d_f_i_l_e_ none | 2 4 0 0 6 read | 1 11 8 9 6 write | 5 3 8 9 6 backspace | 10 11 7 9 6 rewind | 10 11 0 0 6 .sp 2 .fi Actions .sp .in 10 .un 4 0. Do nothing. The previous operation on the file prevents the current request from having any effect on the file. .sp .un 4 1. Prepare the buffer then read one record. The file is already open. If the particular I/O routine needs more records it will call back to the entry ftn_io_control_$read for more. .sp .un 4 2. Read is first request to a file. Open the file, prepare the buffer, and read one record. Subsequent read requests which are part of this request will be handled by call ftn_io_control_$read. .sp .un 4 3. Prepare the buffer for a write request. No write can be performed at this time. All output routines are responsible for writing all records but the last one; fortran_io_ will write that one. .sp .un 4 4. Write is first request to the file. Open the file and prepare the buffer for a write. .sp .un 4 5. Read follows a write. Write out a newline character if it is needed, prepare the buffer and read a record. .sp .un 4 6. Endfile request after any other request. If the file is not active do nothing. If the file is open, add a newline character if it is needed and rewind the file. If the file cannot be rewound, ignore the error message. If FI/O system opened the file, close it. If FI/O system attached the file, detach it. Reset all bits in the file table entry except default_input, default_output, and print_file. .sp .un 4 7. Backspace after backspace. Backspace one record. .sp .un 4 8. Backspace after read or write. Insure the current record is terminated, then backspace one record. .sp .un 4 9. Rewind the file. .sp .un 5 10. Read after backspace or rewind. Indicate this is input file, prepare buffer, and read first record. .sp .un 5 11. Write after backspace, rewind, or read. Recheck the need to append newline characters, prepare the buffer and return. .in 0 .sp 2 Read Entry Point .sp 2 This entry point is called by input procedures which require additional input records. Each time this routine is called, another record is read from the designated file into the buffer. This entry point should be called only if more than one input record is required as the call to ftn_io_control_ reads the first record. .sp 2 Write Entry Point .sp 2 This entry point must be called to output every record created by an output procedure. Currently, the procedure fortran_io_ contains a call to this entry point so that output procedures need only make n-1 calls to ftn_io_control_$write for n records. .sp For list-directed, formatted, and namelist output requests, blank and tab characters which are not followed by any other characters, can be eliminated. This is trailing white space. This may result in a zero length record, but it is output anyhow. .sp For print files, it is necessary to remove the first character from the record and replace it with the appropriate carriage control character(s). Two sets of rules apply, one for terminal output and the other for non-terminal output. .sp 2 Abort Entry Point .sp 2 This entry point is used as the general error handler for the FI/O system. When an error occurs while processing an I/O request, the following steps must be taken: .sp .in 15 .un 4 1. Print a useful error message using the subroutine com_err_ if the field PS.job_bits.error_label equals zero. .sp .un 4 2. Call ftn_io_control_$abort (PS_pointer). PS_pointer is a pointer to the current PS. .sp .in 0 If PS.job_bits.error_label is one, a label variable is created and control is transferred back to that label. Otherwise, a message is printed specifying the current file reference number and I/O request. If any files are active, the question "close files?" is asked of the user via the command_query_ subroutine. An affirmative answer closes all active files. Control is then returned by signalling command_abort_. .sp 2 USAGE .sp 2 .nf ftn_io_control_$abort entry (pointer) ftn_io_control_ entry (pointer) ftn_io_control_$read entry (pointer) ftn_io_control_$write entry (pointer) .sp The pointer points to the current PS. .sp 2 PROCEDURES THAT INVOKE THIS PROCEDURE .sp 2 ftn_io_control fortran_io .sp read ftn_io_format_ ftn_io_namelist .sp write fortran_io ftn_io_format_ ftn_io_namelist_ .sp abort fortran_io_ ftn_io_binary_ ftn_io_format_ ftn_io_namelist_ .sp PROGRAMS CALLED .sp com_err_ command_query_ cu_$cl iox_$find_iocb signal_ sym_$syn_attach vfile_$vfile_attach .sp 2 EXTERNAL DATA .sp 2 error_table_$end_of_info error_table_$no_file error_table_$no_operation error_talbe_$no_record error_table_$noentry fortran_buffer_ sys_info$max_seg_size .sp 2 INCLUDE FILES .sp 2 fortran_buffer fortran_job_bits fortran_ps iocb .sp 2 P__r_o_c_e_d_u_r_e - ftn_io_format_ .fi .sp FUNCTIONS .sp 2 This procedure implemented formatted I/O. This includes string I/O. The format specification passed to this routine can either be a character string or previously compiled by the procedure general_format_parse_. If the format spec. is a character string, general_format_parse_ is called to compile it. .sp If the format spec. is a V-format, ftn_io_free_$init is called instead. .sp If the format spec. has no variable fields, then the occurrance of an I/O list is an error. .sp The format spec. is executed as necessary. When control is returned from this procedure, the record and format specifications are in a consistent state. It is therefore unnecessary to have any sort of termination call for this procedure. .sp This procedure is driven by the format specifications. The major entry point is called once per I/O element. The number of format specifications used is dependent upon the element. Scalar elements require one field except for complex which require two. Array references require one specification per array element except complex requires two. It is the user's responsibility to insure that the specification type is valid for the I/O elements data type. .sp The format spe ification is executed until an I/O element is required. If there is another I/O element it is transmitted and the execution continues as above. If there are no more elements for this call to the entry point control is returned. A subsequent call to the entry will start with the specification that stopped execution on the previous call. .sp Conversion from external to internal binary is performed within the PL/1 language using the convert builtin function to convert from float (or fixed) decimal to float (or fixed) binary. The procedure knows the machine representation of decimal numbers and ocnstructs them from the character input. .sp Conversion from float binary to external is performed by calling the procedure assign_round. This course was necessary as there is no variable precision decimal data type. The method used to produce the external form requires knowledge of the machine representation of decimal numbers. .sp Conversion from fixed binary to external is accomplished through a PL/1 picture. .sp Character, logical, hollerith, and other simple conversions are done using the PL/1 string builtin functions. .sp 2 .nf USAGE .sp .nf ftn_io_format_ entry (pointer) ftn_io_format_$init entry (pointer) .sp 2 .fi The pointer points to the PS. .sp 2 PROCEDURES THAT INVOKE THIS PROCEDURE .sp fortran_io .sp 2 PROGRAMS CALLED .sp 2 .nf assign_round comm_err ftn_io_control_$abort ftn_io_control_$read ftn_io_control_$write ftn_io_free_$init general_format_parse .sp 2 .fi EXTERNAL DATA .sp 2 fortran_buffers .sp 2 INCLUDE FILES .sp 2 .nf format_tables fortran_buffer fortran_job_bits fortran_ps .sp 2 .fi P__r_o_c_e_d_u_r_e - ftn_io_namelist_ .sp This procedure implements both namelist and list-directed I/O. The two are combined to reduce duplication of code. .sp 2 The implementation of namelist I/O uses the PL/1 compiler construct called an OK list. All members of a given namelist group are also members of the OK list for that namelist name. On output, it is a simple matter to step thrugh the list and output the appropriate values. On input, variable names provided by the user are checked for their appearance in the OK list. The procedure is called only once for an I/O statement. .sp 2 For list-directed I/O, a separate call is made for each element. The number of external fields created or read depends on whether the element is scalar or array and the data type. Complex elements require twice as many fields as any of the others. .sp 2 A single internal procedure creates external fields for either of the above output statements. The procedure is able to use pictures to produce the output thus insuring accuracy of the conversion and minimizing processing time. Each data type has a well defined output format which is invariant. .sp 2 Several internal procedures are involved in reading external fields. This is largely due to the differences between the external fields acceptable to namelist and list-directed input. However, numeric conversion routines are shared by these input requests. Numeric conversion is accomplished by invoking the PL/1 convert builtin function to create a binary value from a decimal value. The decimal value is created by parsing the external field and building the value. This procedure is aware of the machine representation of decimal value. .sp 2 USAGE .sp 2 .nf ftn_io_free entry (pointer) ftn_io_free_$init entry (pointer) ftn_io_namelist entry (pointer) .sp 2 Pointer points to the PS. .sp 2 PROCEDURES THAT INVOKE THIS PROCEDURE .sp 2 ftn_io_free ftn_io_namelist_ fortran_io_ .sp ftn_io_free_$init fortran_io_ ftn_io_format_ .sp 2 PROGRAMS CALLED .sp 2 assign_ com_err_ ftn_io_control_$abort ftn_io_control_$read stu_$decode_runtime_value stu_$find_runtime_symbol stu_$get.runtime_address .sp 2 EXTERNAL DATA .sp 2 fortran_buffer_ .sp 2 INCLUDE FILES .sp 2 fortran_buffer fortran_job_bits fortran_ps runtime symbol .sp 3 ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group BULL including BULL HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell BULL Inc., Groupe BULL and BULL HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato. Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, BULL or BULL HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by BULL HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved