COMMENT  VALID 00266 PAGES C REC PAGE DESCRIPTION C00001 00001 C00036 00002 C00039 00003 C00043 00004 SAIL USER MANUAL TABLE OF CONTENTS C00046 00005 SAIL USER MANUAL TABLE OF CONTENTS C00050 00006 SAIL USER MANUAL PROGRAMS AND BLOCKS C00052 00007 SAIL USER MANUAL PROGRAMS AND BLOCKS C00055 00008 SAIL USER MANUAL PROGRAMS AND BLOCKS C00058 00009 SAIL USER MANUAL ALGOL DECLARATIONS C00060 00010 SAIL USER MANUAL ALGOL DECLARATIONS C00062 00011 SAIL USER MANUAL ALGOL DECLARATIONS C00064 00012 SAIL USER MANUAL ALGOL DECLARATIONS C00066 00013 SAIL USER MANUAL ALGOL DECLARATIONS C00068 00014 SAIL USER MANUAL ALGOL DECLARATIONS C00071 00015 SAIL USER MANUAL ALGOL DECLARATIONS C00074 00016 SAIL USER MANUAL ALGOL DECLARATIONS C00079 00017 SAIL USER MANUAL ALGOL DECLARATIONS C00084 00018 SAIL USER MANUAL ALGOL DECLARATIONS C00088 00019 SAIL USER MANUAL ALGOL DECLARATIONS C00092 00020 SAIL USER MANUAL ALGOL DECLARATIONS C00095 00021 SAIL USER MANUAL ALGOL DECLARATIONS C00099 00022 SAIL USER MANUAL ALGOL DECLARATIONS C00103 00023 SAIL USER MANUAL ALGOL DECLARATIONS C00106 00024 SAIL USER MANUAL ALGOL DECLARATIONS C00110 00025 SAIL USER MANUAL ALGOL DECLARATIONS C00114 00026 SAIL USER MANUAL ALGOL DECLARATIONS C00119 00027 SAIL USER MANUAL ALGOL DECLARATIONS C00123 00028 SAIL USER MANUAL ALGOL DECLARATIONS C00128 00029 SAIL USER MANUAL ALGOL DECLARATIONS C00132 00030 SAIL USER MANUAL ALGOL DECLARATIONS C00134 00031 SAIL USER MANUAL ALGOL STATEMENTS C00136 00032 SAIL USER MANUAL ALGOL STATEMENTS C00138 00033 SAIL USER MANUAL ALGOL STATEMENTS C00140 00034 SAIL USER MANUAL ALGOL STATEMENTS C00143 00035 SAIL USER MANUAL ALGOL STATEMENTS C00147 00036 SAIL USER MANUAL ALGOL STATEMENTS C00150 00037 SAIL USER MANUAL ALGOL STATEMENTS C00154 00038 SAIL USER MANUAL ALGOL STATEMENTS C00157 00039 SAIL USER MANUAL ALGOL STATEMENTS C00159 00040 SAIL USER MANUAL ALGOL STATEMENTS C00162 00041 SAIL USER MANUAL ALGOL STATEMENTS C00165 00042 SAIL USER MANUAL ALGOL STATEMENTS C00169 00043 SAIL USER MANUAL ALGOL STATEMENTS C00172 00044 SAIL USER MANUAL ALGOL STATEMENTS C00177 00045 SAIL USER MANUAL ALGOL STATEMENTS C00182 00046 SAIL USER MANUAL ALGOL STATEMENTS C00183 00047 SAIL USER MANUAL ALGOL EXPRESSIONS C00185 00048 SAIL USER MANUAL ALGOL EXPRESSIONS C00187 00049 SAIL USER MANUAL ALGOL EXPRESSIONS C00189 00050 SAIL USER MANUAL ALGOL EXPRESSIONS C00191 00051 SAIL USER MANUAL ALGOL EXPRESSIONS C00195 00052 SAIL USER MANUAL ALGOL EXPRESSIONS C00199 00053 SAIL USER MANUAL ALGOL EXPRESSIONS C00202 00054 SAIL USER MANUAL ALGOL EXPRESSIONS C00206 00055 SAIL USER MANUAL ALGOL EXPRESSIONS C00210 00056 SAIL USER MANUAL ALGOL EXPRESSIONS C00215 00057 SAIL USER MANUAL ALGOL EXPRESSIONS C00219 00058 SAIL USER MANUAL ALGOL EXPRESSIONS C00224 00059 SAIL USER MANUAL ALGOL EXPRESSIONS C00227 00060 SAIL USER MANUAL ALGOL EXPRESSIONS C00228 00061 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS C00230 00062 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS C00232 00063 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS C00237 00064 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS C00242 00065 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS C00247 00066 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS C00251 00067 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS C00252 00068 SAIL USER MANUAL BACKTRACKING C00254 00069 SAIL USER MANUAL BACKTRACKING C00256 00070 SAIL USER MANUAL BACKTRACKING C00259 00071 SAIL USER MANUAL BACKTRACKING C00263 00072 SAIL USER MANUAL BACKTRACKING C00266 00073 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00269 00074 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00272 00075 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00277 00076 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00281 00077 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00284 00078 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00287 00079 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00290 00080 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00294 00081 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00298 00082 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00301 00083 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00303 00084 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00306 00085 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00310 00086 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00313 00087 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00317 00088 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00320 00089 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00322 00090 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00325 00091 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00328 00092 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00331 00093 SAIL USER MANUAL INPUT/OUTPUT ROUTINES C00333 00094 SAIL USER MANUAL EXECUTION TIME ROUTINES C00336 00095 SAIL USER MANUAL EXECUTION TIME ROUTINES C00339 00096 SAIL USER MANUAL EXECUTION TIME ROUTINES C00342 00097 SAIL USER MANUAL EXECUTION TIME ROUTINES C00345 00098 SAIL USER MANUAL EXECUTION TIME ROUTINES C00348 00099 SAIL USER MANUAL EXECUTION TIME ROUTINES C00351 00100 SAIL USER MANUAL EXECUTION TIME ROUTINES C00355 00101 SAIL USER MANUAL EXECUTION TIME ROUTINES C00358 00102 SAIL USER MANUAL EXECUTION TIME ROUTINES C00361 00103 SAIL USER MANUAL EXECUTION TIME ROUTINES C00364 00104 SAIL USER MANUAL EXECUTION TIME ROUTINES C00366 00105 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00368 00106 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00370 00107 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00373 00108 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00377 00109 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00381 00110 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00384 00111 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00388 00112 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00391 00113 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00394 00114 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00398 00115 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00401 00116 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00404 00117 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00407 00118 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00411 00119 SAIL USER MANUAL MACROS AND CONDITIONAL COMPILATION C00413 00120 SAIL USER MANUAL LEAP DATA TYPES C00417 00121 SAIL USER MANUAL LEAP DATA TYPES C00419 00122 SAIL USER MANUAL LEAP DATA TYPES C00421 00123 SAIL USER MANUAL LEAP DATA TYPES C00424 00124 SAIL USER MANUAL LEAP DATA TYPES C00428 00125 SAIL USER MANUAL LEAP DATA TYPES C00433 00126 SAIL USER MANUAL LEAP DATA TYPES C00438 00127 SAIL USER MANUAL LEAP DATA TYPES C00443 00128 SAIL USER MANUAL LEAP DATA TYPES C00444 00129 SAIL USER MANUAL LEAP STATEMENTS C00446 00130 SAIL USER MANUAL LEAP STATEMENTS C00448 00131 SAIL USER MANUAL LEAP STATEMENTS C00450 00132 SAIL USER MANUAL LEAP STATEMENTS C00455 00133 SAIL USER MANUAL LEAP STATEMENTS C00459 00134 SAIL USER MANUAL LEAP STATEMENTS C00463 00135 SAIL USER MANUAL LEAP STATEMENTS C00467 00136 SAIL USER MANUAL LEAP STATEMENTS C00471 00137 SAIL USER MANUAL LEAP STATEMENTS C00475 00138 SAIL USER MANUAL LEAP STATEMENTS C00479 00139 SAIL USER MANUAL LEAP STATEMENTS C00483 00140 SAIL USER MANUAL LEAP STATEMENTS C00487 00141 SAIL USER MANUAL LEAP STATEMENTS C00491 00142 SAIL USER MANUAL LEAP STATEMENTS C00495 00143 SAIL USER MANUAL LEAP STATEMENTS C00499 00144 SAIL USER MANUAL LEAP STATEMENTS C00503 00145 SAIL USER MANUAL LEAP STATEMENTS C00508 00146 SAIL USER MANUAL LEAP STATEMENTS C00511 00147 SAIL USER MANUAL LEAP STATEMENTS C00512 00148 SAIL USER MANUAL LEAP EXPRESSIONS C00514 00149 SAIL USER MANUAL LEAP EXPRESSIONS C00516 00150 SAIL USER MANUAL LEAP EXPRESSIONS C00518 00151 SAIL USER MANUAL LEAP EXPRESSIONS C00521 00152 SAIL USER MANUAL LEAP EXPRESSIONS C00526 00153 SAIL USER MANUAL LEAP EXPRESSIONS C00530 00154 SAIL USER MANUAL LEAP EXPRESSIONS C00533 00155 SAIL USER MANUAL LEAP EXPRESSIONS C00537 00156 SAIL USER MANUAL PROCESSES C00539 00157 SAIL USER MANUAL PROCESSES C00542 00158 SAIL USER MANUAL PROCESSES C00546 00159 SAIL USER MANUAL PROCESSES C00550 00160 SAIL USER MANUAL PROCESSES C00554 00161 SAIL USER MANUAL PROCESSES C00558 00162 SAIL USER MANUAL PROCESSES C00562 00163 SAIL USER MANUAL PROCESSES C00566 00164 SAIL USER MANUAL PROCESSES C00571 00165 SAIL USER MANUAL PROCESSES C00573 00166 SAIL USER MANUAL EVENTS C00575 00167 SAIL USER MANUAL EVENTS C00579 00168 SAIL USER MANUAL EVENTS C00583 00169 SAIL USER MANUAL EVENTS C00587 00170 SAIL USER MANUAL EVENTS C00591 00171 SAIL USER MANUAL EVENTS C00594 00172 SAIL USER MANUAL EVENTS C00597 00173 SAIL USER MANUAL EVENTS C00600 00174 SAIL USER MANUAL PROCEDURE VARIABLES C00602 00175 SAIL USER MANUAL PROCEDURE VARIABLES C00606 00176 SAIL USER MANUAL PROCEDURE VARIABLES C00610 00177 SAIL USER MANUAL PROCEDURE VARIABLES C00613 00178 SAIL USER MANUAL PROCEDURE VARIABLES C00615 00179 SAIL USER MANUAL INTERRUPTS C00619 00180 SAIL USER MANUAL INTERRUPTS C00623 00181 SAIL USER MANUAL INTERRUPTS C00627 00182 SAIL USER MANUAL INTERRUPTS C00631 00183 SAIL USER MANUAL INTERRUPTS C00634 00184 SAIL USER MANUAL INTERRUPTS C00638 00185 SAIL USER MANUAL INTERRUPTS C00641 00186 SAIL USER MANUAL INTERRUPTS C00645 00187 SAIL USER MANUAL INTERRUPTS C00648 00188 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00651 00189 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00654 00190 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00657 00191 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00660 00192 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00663 00193 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00666 00194 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00669 00195 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00672 00196 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00676 00197 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00679 00198 SAIL USER MANUAL LEAP AND PROCESS RUNTIMES C00680 00199 SAIL USER MANUAL BASIC CONSTRUCTS C00683 00200 SAIL USER MANUAL BASIC CONSTRUCTS C00687 00201 SAIL USER MANUAL BASIC CONSTRUCTS C00692 00202 SAIL USER MANUAL BASIC CONSTRUCTS C00696 00203 SAIL USER MANUAL BASIC CONSTRUCTS C00698 00204 SAIL USER MANUAL USING SAIL C00701 00205 SAIL USER MANUAL USING SAIL C00705 00206 SAIL USER MANUAL USING SAIL C00708 00207 SAIL USER MANUAL USING SAIL C00710 00208 SAIL USER MANUAL USING SAIL C00714 00209 SAIL USER MANUAL USING SAIL C00718 00210 SAIL USER MANUAL USING SAIL C00722 00211 SAIL USER MANUAL USING SAIL C00727 00212 SAIL USER MANUAL USING SAIL C00732 00213 SAIL USER MANUAL USING SAIL C00735 00214 SAIL USER MANUAL DEBUGGING SAIL PROGRAMS C00739 00215 SAIL USER MANUAL DEBUGGING SAIL PROGRAMS C00743 00216 SAIL USER MANUAL DEBUGGING SAIL PROGRAMS C00747 00217 SAIL USER MANUAL DEBUGGING SAIL PROGRAMS C00751 00218 SAIL USER MANUAL DEBUGGING SAIL PROGRAMS C00755 00219 SAIL USER MANUAL DEBUGGING SAIL PROGRAMS C00758 00220 SAIL USER MANUAL APPENDICES C00762 00221 SAIL USER MANUAL APPENDICES C00766 00222 SAIL USER MANUAL APPENDICES C00770 00223 SAIL USER MANUAL APPENDICES C00773 00224 SAIL USER MANUAL APPENDICES C00774 00225 SAIL USER MANUAL APPENDICES C00777 00226 SAIL USER MANUAL APPENDICES C00780 00227 SAIL USER MANUAL APPENDICES C00781 00228 SAIL USER MANUAL APPENDICES C00785 00229 SAIL USER MANUAL APPENDICES C00789 00230 SAIL USER MANUAL APPENDICES C00793 00231 SAIL USER MANUAL APPENDICES C00796 00232 SAIL USER MANUAL APPENDICES C00800 00233 SAIL USER MANUAL APPENDICES C00804 00234 SAIL USER MANUAL APPENDICES C00805 00235 SAIL USER MANUAL APPENDICES C00810 00236 SAIL USER MANUAL APPENDICES C00815 00237 SAIL USER MANUAL APPENDICES C00818 00238 SAIL USER MANUAL APPENDICES C00822 00239 SAIL USER MANUAL APPENDICES C00824 00240 SAIL USER MANUAL APPENDICES C00828 00241 SAIL USER MANUAL APPENDICES C00832 00242 SAIL USER MANUAL APPENDICES C00836 00243 SAIL USER MANUAL APPENDICES C00840 00244 SAIL USER MANUAL APPENDICES C00843 00245 C00846 00246 SAIL USER MANUAL APPENDICES C00849 00247 SAIL USER MANUAL APPENDICES C00850 00248 SAIL USER MANUAL REFERENCES C00853 00249 SAIL USER MANUAL INDEX C00855 00250 C00857 00251 SAIL USER MANUAL INDEX C00859 00252 SAIL USER MANUAL INDEX C00861 00253 SAIL USER MANUAL INDEX C00863 00254 SAIL USER MANUAL INDEX C00865 00255 C00867 00256 SAIL USER MANUAL INDEX C00869 00257 SAIL USER MANUAL INDEX C00871 00258 SAIL USER MANUAL INDEX C00873 00259 SAIL USER MANUAL INDEX C00875 00260 SAIL USER MANUAL INDEX C00877 00261 SAIL USER MANUAL INDEX C00879 00262 SAIL USER MANUAL INDEX C00881 00263 SAIL USER MANUAL INDEX C00883 00264 SAIL USER MANUAL INDEX C00885 00265 SAIL USER MANUAL INDEX C00886 00266 C00887 ENDMK C; SAIL USER MANUAL TABLE OF CONTENTS T A B L E O F C O N T E N T S                SECTION PAGE 1 PROGRAMS AND BLOCKS 1 SYNTAX 1 2 SEMANTICS 2 2 ALGOL DECLARATIONS 1 SYNTAX 4 2 RESTRICTIONS 8 3 EXAMPLES 9 4 SEMANTICS 10 5 SEPARATELY COMPILED PROCEDURES 22 3 ALGOL STATEMENTS 1 SYNTAX 26 2 SEMANTICS 29 4 ALGOL EXPRESSIONS 1 SYNTAX 42 2 TYPE CONVERSION 45 3 SEMANTICS 47 5 ASSEMBLY LANGUAGE STATEMENTS 1 SYNTAX 56 2 SEMANTICS 57 6 BACKTRACKING 1 INTRODUCTION 63 2 SYNTAX 63 3 SEMANTICS 64 SAIL USER MANUAL TABLE OF CONTENTS 7 INPUT/OUTPUT ROUTINES 1 EXECUTION TIME ROUTINES IN GENERAL 68 2 I/O CHANNELS AND FILES 69 3 BREAK CHARACTERS 74 4 I/O ROUTINES 79 5 TELETYPE AND PSEUDO-TELETYPE ROUTINES 85 8 EXECUTION TIME ROUTINES 1 TYPE CONVERSION ROUTINES 89 2 STRING MANIPULATION ROUTINES 93 3 LIBERATION-FROM-SAIL ROUTINES 94 4 BYTE MANIPULATION ROUTINES 96 5 OTHER USEFUL ROUTINES 97 9 MACROS AND CONDITIONAL COMPILATION 1 SYNTAX 100 2 DELIMITERS 102 3 MACROS 104 4 MACROS WITH PARAMETERS 108 5 CONDITIONAL COMPILATION 110 6 TYPE DETERMINATION AT COMPILE TIME 112 7 MISCELANEOUS FEATURES 113 10 LEAP DATA TYPES 1 INTRODUCTION 115 2 SYNTAX 116 3 SEMANTICS 118 11 LEAP STATEMENTS 1 SYNTAX 124 2 RESTRICTIONS 126 3 SEMANTICS 126 4 SEARCHING THE ASSOCIATIVE STORE 130 12 LEAP EXPRESSIONS 1 SYNTAX 143 2 SEMANTICS 146 SAIL USER MANUAL TABLE OF CONTENTS 13 PROCESSES 1 INTRODUCTION 151 2 SYNTAX 151 3 SEMANTICS 152 14 EVENTS 1 SYNTAX 161 2 INTRODUCTION 162 3 SAIL DEFINED CAUSE AND INTERROGATE 162 4 USER DEFINED CAUSE AND INTERROGATE 165 15 PROCEDURE VARIABLES 1 SYNTAX 169 2 SEMANTICS 170 16 INTERRUPTS 1 INTRODUCTION 174 2 IMMEDIATE INTERRUPTS 175 3 DEFERRED INTERRUPTS 178 4 MORE COMPLICATED DEFERRED INTERRUPTS 179 17 LEAP AND PROCESS RUNTIMES 1 TYPES AND TYPE CONVERSION 183 2 MAKE AND ERASE BREAKPOINTS 185 3 PNAME RUNTIMES 186 4 OTHER USEFUL RUNTIMES 187 5 GENERAL PROCESS RUNTIMES 189 6 RUNTIMES FOR USER CAUSE AND INTERROGATE PROCEDURES 191 18 BASIC CONSTRUCTS 1 SYNTAX 194 2 SEMANTICS 195 SAIL USER MANUAL TABLE OF CONTENTS 19 USING SAIL 1 FOR BEGINNERS 199 2 THE COMPLETE USE OF SAIL 200 3 COMPILING SAIL PROGRAMS 201 4 LOADING SAIL PROGRAMS 207 5 STARTING SAIL PROGRAMS 207 6 STORAGE REALLOCATION WITH THE REENTER COMMAND 208 20 DEBUGGING SAIL PROGRAMS 1 ERROR MESSAGES 209 2 DEBUGGING 212 A APPENDICES 1 TYPE CONVERSION . . . . . . . . . . . . 215 2 SAIL RESERVED WORDS . . . . . . . . . . . 217 3 SAIL PRE-DECLARED IDENTIFIERS . . . . . . . 217 4 CHARACTER-IDENTIFIER EQUIVALENCES . . . 218 5 PARAMETERS TO THE OPEN FUNCTION . . . . 218 6 BREAKSET MODES . . . . . . . . . . . . 220 7 MTAPE COMMANDS . . . . . . . . . . . . 220 8 COMPILE SWITCHES . . . . . . . . . . . . 221 9 VALID RESPONSES TO ERROR MESSAGES . . . 221 10 ERROR CODES . . . . . . . . . . . . . 223 11 INDICES FOR INTERRUPTS . . . . . . . . . . 225 12 BIT NAMES FOR PROCESS CONSTRUCTS . . . . 227 13 STATEMENT COUNTER SYSTEM . . . . . . . . . 230 14 ARRAY IMPLEMENTATION . . . . . . . . . . 233 15 STRING IMPLEMENTATION . . . . . . . . . . 235 16 PROCEDURE IMPLEMENTATION . . . . . . . . . 236 R REFERENCES 243 I INDEX 243 SAIL USER MANUAL PROGRAMS AND BLOCKS SECTION 1   PROGRAMS AND BLOCKS    1.1 - SYNTAX  ::= ::= ; ::= BEGIN ::= BEGIN ::= ; ::= END ::= END ::= ; ::= BEGIN ::= BEGIN ::= ::= ::= ::= ::= 1 SAIL USER MANUAL PROGRAMS AND BLOCKS ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= : ::= 1.2 - SEMANTICS  DECLARATIONS  SAIL programs are organized in the traditional block structure of ALGOL-60. Declarations serve to define the data types and dimensions of simple and subscripted (array) variables (arithmetic variables, strings, sets, and items). They are also used to describe procedures (subroutines) and name program labels. Any identifier referred to in a program must be described in some declaration. An identifier may only be referenced by statements within the scope (see page 10) of its declaration. STATEMENTS  As in ALGOL, the statement is the fundamental unit of operation in the SAIL language. Since a statement within a block or compound statement may itself be a block or compound statement, the concept of statement must be understood recursively. The block representing the program is known as the "outer block". 2 SAIL USER MANUAL PROGRAMS AND BLOCKS All blocks internal to this one will be referred to as "inner blocks". BLOCK NAMES   The block name construct is used to describe the block structure of a SAIL program to a symbolic debugging routine (see page 212). The name of the outer block becomes the title of the binary output file (not necesarily the file name). In addition, if a block name is used following an END, the compiler compares it with the block name which followed the corresponding BEGIN. A mismatch is reported to the user as evidence of a missing (extra) BEGIN or END somewhere. The construct is equivalent in action to the alone; that is, the string constant serves only as a comment. EXAMPLES  Given: S is a statement, Sc is a Compound Statement, D is a Declaration, B is a Block. Then: (Sc) BEGIN S; S; S; ... ; S END (Sc) BEGIN "SORT" S; S; ... ;S END "SORT" (B) BEGIN D; D; D; ... ; S; S; S; ... ; S END (B) BEGIN "ENTER NEW INFO" D; D; ... ; S; ... ;S END are syntactically valid SAIL constructs. 3 SAIL USER MANUAL ALGOL DECLARATIONS SECTION 2   ALGOL DECLARATIONS   2.1 - SYNTAX  ::= ::= , ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= REAL ::= INTEGER ::= BOOLEAN ::= STRING ::= EXTERNAL 4 SAIL USER MANUAL ALGOL DECLARATIONS ::= INTERNAL ::= SAFE ::= FORWARD ::= RECURSIVE ::= FORTRAN ::= SIMPLE ::= OWN ::= SHORT ::= ::= ::= ARRAY ::= ::= ::= , ::= [ ] ::= ::= , ::= : ::= 5 SAIL USER MANUAL ALGOL DECLARATIONS ::= ::= PRELOADWITH ::= ::= , ::= ::= [expression] ::= LABEL ::= PROCEDURE ::= PROCEDURE ::= ::= ::= ( ) ::= ::= ; ::= 6 SAIL USER MANUAL ALGOL DECLARATIONS ::= ; ::= ::= ::= REFERENCE ::= VALUE ::= ::= ARRAY ::= PROCEDURE ::= LET ::= ::= , ::= = ::= CLEANUP ::= REQUIRE ::= ::= , 7 SAIL USER MANUAL ALGOL DECLARATIONS ::= ::= INITIALIZATION ::= STRINGSPACE ::= SYSTEMPDL ::= STRINGPDL ::= ARRAYPDL ::= NEWITEMS ::= PNAMES ::= LOADMODULE ::= LIBRARY ::= SOURCEFILE ::= SEGMENTFILE ::= SEGMENTNAME ::= POLLINGPOINTS ::= VERSION ::= ERRORMODES ::= DELIMITERS ::= BUCKETS ::= MESSAGE 2.2 - RESTRICTIONS  For simplicity, the typequalifiers are listed in only one syntactic class. Although their uses are always valid when placed according to the above syntax, most of them only have meaning when applied to particular subsets of these productions: SAFE is only meaningful in array declarations. INTERNAL/EXTERNAL have no meaning in formal parameter declarations. SIMPLE, FORWARD, RECURSIVE, and FORTRAN have meaning only in procedure type specifications. SHORT has meaning only when applied to INTEGER or REAL entities. 8 SAIL USER MANUAL ALGOL DECLARATIONS For array declarations in the outer block substitute for in the productions for and . A label must be declared in the innermost block in which the statement being labeled appears (more information, page 31). The syntax for procedure declarations requires semantic embellishment (see page 14) in order to make total sense. In particular, a procedure body may be empty only in a restricted class of declarations. 2.3 - EXAMPLES  Let I,J,K,L,X,Y, and P be identifiers, S a statement: () INTEGER I,J,K EXTERNAL REAL X,Y INTERNAL STRING K () INTEGER ARRAY X[0:10,0:10] REAL ARRAY Y[X:P(L)]; Comment illegal in outer block STRING ARRAY I[0:IF BIG THEN 30 ELSE 3] () LABEL L,X,Y () PROCEDURE P; S PROCEDURE P(INTEGER I,J; REFERENCE REAL X; REAL Y) ; S INTEGER PROCEDURE P (REAL PROCEDURE L; STRING I,J; INTEGER ARRAY K); S EXTERNAL PROCEDURE P(REAL X) FORWARD INTEGER PROCEDURE X(INTEGER I) FORTRAN REAL PROCEDURE SIN Note that these sample declarations are all given without the semicolons which would normally separate them from the surrounding declarations and statements. Here is a sample block to bring it all together (again, let S be any statement, D any declaration, and other identifiers as above): 9 SAIL USER MANUAL ALGOL DECLARATIONS BEGIN "SAMPLE BLOCK" INTEGER I,J,K; REAL X,Y; STRING A; INTEGER PROCEDURE P(REFERENCE REAL X); BEGIN "P" D; D; D; ... ;S; ... ; S END "P"; REAL ARRAY DIPHTHONGS[0:10,1:100]; S; S; S; S END "SAMPLE BLOCK" 2.4 - SEMANTICS  SCOPE OF DECLARATIONS    Every block automatically introduces a new level of nomenclature. Any identifier declared in a block's head is said to be LOCAL to that block. This means that: a. The entity represented by this identifier inside the block has no existence outside the block. b. Any entity represented by the same identifier outside the block is completely inaccessible (unless it has been passed as a parameter) inside the block. An identifier occurring within an inner block and not declared within that block will be nonlocal (global) to it; that is, the identifier will represent the same entity inside the block and in the block or blocks within which it is nested, up to and including the level in which the identifier is declared. The Scope of an entity is the set of blocks in which the entity is represented, using the above rules, by its identifier. An entity may not be referenced by any statement outside its scope. TYPE QUALIFIERS   An array, variable, or procedure declared OWN will behave as if it were declared globally to the current procedure; the OWN type qualifier on a variable, etc. declared in a block not nested inside a procedure declaration will have no effect. This means that in a 10 SAIL USER MANUAL ALGOL DECLARATIONS second call of a procedure with OWN locals (or a recursive call) the OWN variables will not be reinitialized they will have the values that they had when the first call of the procedure finished. Furthermore, OWN arrays, etc. will not be deallocated upon exiting the procedure they are declared in. INTERNAL and EXTERNAL procedures, variables, etc. let one link programs that are loaded together, but were compiled separately. See page 22 for more information. RECURSIVE, SHORT, FORTRAN, FORWARD, SIMPLE, and SAFE will be explained when the data types they modify are discussed. NUMERIC DECLARATIONS   Identifiers which appear in type declarations with types REAL or INTEGER can subsequently be used to refer to numeric variables. An Integer variable may take on values from -2^35 to 2^35-1 (-2^26 to 2^26-1 for SHORT INTEGERS). A Real variable may take on positive and negative values from about 10^-38 to 10^38 with a precision of 27 bits (same range for SHORT REALs as for SHORT INTEGERs. REAL and INTEGER variables (and constants) may be used in the same arithmetic expressions; type conversions are carried out automatically (see page 46 below) when necessary. The advantage of SHORT reals and integers is that the conversion from integer to real is sped by a factor of 8 if either the integer or the real is SHORT. See page 46 for more information. The BOOLEAN type is identical to INTEGER. As you will see, BOOLEAN and algebraic expressions are really equivalent syntactically. The syntactic context in which they appear determines their meaning. Non- zero integers correspond to TRUE and 0 corresponds to FALSE. The declarator BOOLEAN is included for program clarity. STRING DECLARATIONS   A variable defined in a String declaration is a two-word descriptor containing the information necessary to represent a SAIL character string. A String may be thought of as a variable-length, one-dimensional array of 7-bit ASCII characters. Its descriptor contains a character count and a byte pointer to the first character (see page 235). Strings originate as constants at compile time (page 197), as the result of a String INPUT operation from some device (see page 79), or from the concatenation or decomposition of already existing strings (see page 52 and page 53). 11 SAIL USER MANUAL ALGOL DECLARATIONS When strings appear in arithmetic operations or vice-versa, a somewhat arbitrary conversion is performed to obtain the proper type (by arbitrary we do not mean to imply random -- see page 46). For this reason arithmetic and String variables are referred to as "algebraic variables" and their corresponding expressions are called "algebraic expressions" (to differentiate them them from the variables and expressions of LEAP -- see page 115). ARRAY DECLARATIONS   In general, any data type which is applicable to a simple variable may be applied in an Array declaration to an array of variables. The entity represented by the name of an Array, qualified with subscript expressions to locate a particular element (e.g. A[I,J]) behaves in every way like a simple variable. Therefore, in the future we shall refer to both simple variables and single elements of Arrays (subscripted variables) as "variables". The formal syntax for can be found on page 195. For an Array which is not qualified by the SAFE attribute, nor had a NOWSAFE statement done on it (NowSafe - see page 40), each subscript will be checked to ensure that it falls within the lower and upper bounds given for the dimension it specifies. Subscripts outside the bounds trigger an error message and job abortion. The SAFE declaration inhibits this checking, resulting in faster, smaller, and bolder code. There is no limit to the number of dimensions allowed for an Array. However, the efficiency of Array references tends to decrease for large dimensions. Avoid large dimensionality if it is not necessary. OWN Arrays are available in part. They must be declared with constant bounds, since fixed storage is allocated for these Arrays. They are NOT initialized when the program is started or restarted (except in preloaded Arrays, see page 12). A certain degree of extra efficiency is possible in accessing these Arrays, since they may be assigned absolute core locations by the compiler, eliminating some of the address arithmetic. Constant bounds always add a little efficiency, even in inner blocks. Arrays declared in the outer block must have constant bounds, since no variable may yet have been assigned a value. They are thus automatically made OWN. For more details concerning the internal structure of Arrays see page 212 and page 233. PRELOAD SPECIFICATIONS   Any OWN arithmetic or String Array may be "pre-loaded" at compile time with constant information by preceding its declaration with a . This specification gives the values which 12 SAIL USER MANUAL ALGOL DECLARATIONS are to be placed in consecutive core locations of the Arrays declared immediately following the . "Immediately", in this case, means all identifiers up to and including one which is followed by boundpairlist brackets (e.g. in REAL ARRAY X,Y,Z[0:10],W[1:5]; -- preloads X,Y, and Z; not W). It is the user's responsibility to guarantee that the proper values will be obtained under the subscript mapping, namely: arrays are stored by rows; if A[I,J] is stored in location 10000, then A[I,J+1] is stored in location 10001. The current values of pre-loaded Arrays will not be lost by restarting the program; they will not be re-initialized or re- preloaded. For preloaded String Arrays, this means you may have invalid string descriptors after a restart: the contents of the array will not change over the restart, but string space will change, leaving the elements of the array pointing off into the boondocks. Algebraic type conversions will be performed at compile-time to provide values of the proper types to pre-loaded Arrays. All expressions in these specifications must be constant expressions -- that is, they must contain only constants and algebraic operators. The compiler will not allow you to fill an Array beyond its capacity. You may, however, provide a number of elements less than the total size of the Array; remaining elements will be set to zero or to the null string. Example: PRELOADWITH [5] 0, 3, 4, [4] 6, 2; INTEGER ARRAY TABL[1:4,1:3]; The first five elements of TABL will be initialized to 0 (bracketed number is used as a repeat argument). The next two elements will be 3 and 4, followed by four 6's and a 2. The array will look like this: 1 2 3  1 | 0 0 0 2 | 0 0 3 3 | 4 6 6 4 | 6 6 2 PROCEDURE DECLARATIONS   If a Procedure is typed, it may return a value (see page 36) of the specified type. If formal parameters are specified, they must be 13 SAIL USER MANUAL ALGOL DECLARATIONS supplied with actual parameters in a one to one correspondence when they are called (see page 53 and page 38). FORMAL PARAMETERS   Formal parameters, when specified, provide information to the body (executable portion) of the Procedure about the kinds of values which will be provided as actual parameters in the call. The type and complexity (simple or Array) are specified here. In addition, the formal parameter indicates whether the value (VALUE) or address (REFERENCE) of the actual parameter will be supplied. If the address is supplied, the variable whose identifer is given as an actual parameter may be changed by the Procedure. This is not the case if the value is given. To pass a PROCEDURE by value has no readily determined meaning. ARRAYs passed by value (requiring a complete copy operation) are not implemented. Therefore these cases are noted as errors by the compiler. The proper use of actual parameters is further discussed on page 38 and page 53. FORWARD PROCEDURE DECLARATIONS    A Procedure's type and parameters must be described before the Procedure may be called. Normally this is accomplished by specifying the procedure declaration in the head of some block containing the call. If, however, it is necessary to have two Procedures, declared in some block head, which are both accessible to statements in the compound tail of that block and to each other, the FORWARD construct permits the definition of the parameter information for one of these Procedures in advance of its declaration. The Procedure body must be empty in a forward procedure declaration. When the body of the Procedure described in the forward declaration is actually declared, the types of the Procedure and of its parameters must be identical in both declarations. The declarations must appear at the same level (within the same block head). Example: 14 SAIL USER MANUAL ALGOL DECLARATIONS BEGIN "NEED FORWARD" FORWARD INTEGER PROCEDURE T1(INTEGER I); COMMENT PARAMS DESCRIBED; INTEGER PROCEDURE T2(INTEGER J); RETURN (T1(J)+3); COMMENT CALL T1 ; INTEGER PROCEDURE T1 (INTEGER I); COMMENT ACTUALLY DEFINE T1; RETURN (IF I=15 THEN I ELSE T2(I-1)); COMMENT CALLS T2; ... K_T1(L); ... ; L_T2(K); ... END "NEED FORWARD"; Notice that the forward declaration is required only because BOTH Procedures are called in the body of the block. These procedures should also be declared RECURSIVE if recursive entrance is likely. If only T1 were called from statements within the block, this example could be implemented as: BEGIN "NO FORWARD" RECURSIVE INTEGER PROCEDURE T1(INTEGER I); BEGIN INTEGER PROCEDURE T2(J); RETURN (T1(J)+3); RETURN( IF I=15 THEN I ELSE T2(I-1)); END "T1"; ... K_T1(L); ... END "NO FORWARD"; RECURSIVE PROCEDURES   If a Procedure is to be entered recursively, the compiler must be instructed to provide code for allocating new local variables when the Procedure is called and deallocating them when it returns. Use the type-qualifier RECURSIVE in the declaration of any recursive Procedure. 15 SAIL USER MANUAL ALGOL DECLARATIONS The compiler can produce much more efficient code for non-recursive Procedures than for recursive ones. We feel that this gain in efficiency merits the necessity for declaring Procedures to be recursive. If a Procedure which has not been declared recursive is called recursively, all its local variables (and temporary storage locations assigned by the compiler) will behave as if they were global to the Procedure -- they will not be reinitialized, and when the recursive call is complete, the locals of the calling procedure will reflect the changes made to them during the recursive call. Otherwise, no ill effects should be observed. SIMPLE PROCEDURES   Standard procedures contain a short prologue that sets up some links on the stack and a descriptor that is used by the storage allocation system, the go to solver, and some other routines. For most procedures, this overhead is insignificant. However, for small procedures that just do a few simple statements and exit, this overhead is excessive and unneeded. To skip the prologue, just include SIMPLE in the attribute list for the procedure. RESTRICTIONS: 1. Simple procedures may not be Recursive. 2. ARRAY locals must be OWN. 3. Set and List locals must be OWN (Sets and list are part of Leap, page 115). 4. Procedures declared local to a simple procedure must also be of of type SIMPLE, and may not reference any of the parameters of the outer simple procedure. 5. One may not GO TO a statement outside the body of the simple procedure. EXTERNAL PROCEDURES   A file compiled by SAIL represents either a "main" program or a collection of independent procedures to be called by the main program. The method for preparing such a collection of Procedures is described in page 22. The EXTERNAL and FORTRAN type-qualifiers allow description of the types of these Procedures and their parameters. An EXTERNAL or FORTRAN procedure declaration, like the FORWARD declaration, does not include a procedure body. Both declarations instead result in requests to the loader to provide the addresses of these Procedures to all statements which call them. This 16 SAIL USER MANUAL ALGOL DECLARATIONS means that an EXTERNAL Procedure declaration (or the declaration of any External identifier) may be placed within any block head, thereby controlling the scope of this External identifier within this program. Any SAIL Procedure which is referenced via these external declarations must be an INTERNAL Procedure. That is, the type- qualifier INTERNAL must appear in the actual declaration of the Procedure. Again, see page 22. The type-qualifier FORTRAN is used to describe the type and name of an external Procedure which is to be called using a DEC Fortran calling sequence. All parameters to Fortran Procedures are by reference. In fact, the procedure head part of the declaration need not be included unless the types expected by the Procedure differ from those provided by the actual parameters--the number of parameters supplied, and their types, are presumed correct. Fortran Procedures are automatically External Procedures. See page 18, page 38, page 53 for more information about Fortran Procedures. Example: FORTRAN PROCEDURE MAX; Y_MAX(X,Z); PARAMETRIC PROCEDURES   The calling conventions for Procedures with Procedures as arguments, and for the execution of these parametric Procedures, are described on page 38 and page 53. Any Procedure PP which is to be used as a parameter to another Procedure CP must not have any Procedure or array parameters, or any parameters called by value. In other words, PP may only have simple reference parameters. The number of parameters supplied in a call on PP within CP, and their types, will be presumed correct, and should not be specified in the procedure head. Example: 17 SAIL USER MANUAL ALGOL DECLARATIONS PROCEDURE CP (INTEGER PROCEDURE FP); BEGIN INTEGER A,I; REAL X; ... A_FP(I,X); COMMENT I AND X PASSED BY REFERENCE, NO TYPE CONVERSION; END "CP"; INTEGER PROCEDURE PP (REFERENCE INTEGER J; REFERENCE REAL Y); BEGIN ... END "PP"; ... CP(PP); DEFAULTS IN PROCEDURE DECLARATIONS     If no VALUE or REFERENCE qualification appears in the description, the following qualifications are assumed: VALUESimple Integer, String, or Real Variables. REFERENCE Arrays, Contexts and Procedures. RESTRICTIONS ON PROCEDURE DECLARATIONS     1) Fortran Procedures can not handle String parameters. Nor can a Fortran Procedure return a string as a result. 2) Labels may never be passed as arguments to Procedures. 3) Procedures may not have the type "CONTEXT". 4) Context parameters must always be passed by reference. ALLOCATION AND DEALLOCATION    All simple variables (integer, real, string, boolean) are allocated at compile time. Non-own simple variables that are local to a recursive procedure are an exception to this and are allocated (on the stack) upon instantiation of the procedure; they are deallocated when the instantiation is terminated. All outer block arrays are allocated at compile time. All Own arrays 18 SAIL USER MANUAL ALGOL DECLARATIONS are allocated at compile time. All other arrays are allocated when the block of their definition is entered, and deallocated when it is exited. INITIALIZATION AND REINITIALIZATION    Upon allocation, everything is initialized to 0 or the NULL string (except preloaded arrays, which are initialized to their the values of their PRELOAD). Nothing is reinitialized unless the program is restarted by typing ^C and REEnter. This lack of reinitialization is noticeable when one enters a block for the second time, and that block is not the body of a recursive procedure. For example, STRING PROCEDURE READIN; BEGIN INTEGER CHANNEL, BRTAB; IF BRTAB=0 THEN BRTAB _ INIT(CHANNEL); RETURN(INPUT(CHANNEL, BRTAB )); END; will return a string from an input operation with every call. However, on the first call, it will do some initialization of the I/O channel because BRTAB is 0 then, whereas it is not for any of the other calls. If READIN were a recursive procedure, CHANNEL and BRTAB would be allocated and hence initialized with every call. When one REEenters a program, some things are reinitilized and some are not. Namely, strings and non-preloaded arrays will be reinitialized, but simple variables will not. Preloaded arrays will not be re-preloaded. SYNONYMS  The Sail Synonym permits one to declare any identifier to act as a reserved word. The effect of the reserved word is not changed; it may be used as well as the new identifier. Synonyms follow the same scope rules that identifiers used for variables, arrays, etc. do. Since Sail permits one to declare almost any reserved word to be an identifier for variables, procedures, etc. (see about restrictions on identifiers, page 196), synonyms are used to keep the effect of the reserved word available. For example, 19 SAIL USER MANUAL ALGOL DECLARATIONS LET BEG = BEGIN; PROCEDURE BEGIN; BEG .....; END; ... IF OK THEN BEGIN; ... CLEANUP DECLARATIONS   The CLEANUP declaration requires a list of procedure names following the "CLEANUP" token. Each procedure specified must be SIMPLE and have no formal parameters. The specified procedures will be called at the exit of the block that the CLEANUP declaration occurs in. They will be called in the order of their appearance on the list, and before any of the variables of the block are deallocated. NOTE: If the block is part of a process (see about processes, page 151) that is being terminated, the cleanup procedures will be called before the terminate is completed. Cleanup procedures are normally used in connection with processes to "cleanup" a block by terminating the processes dependent on that block (it is an error to leave processes active that depended on an exited block). REQUIREMENTS  The user may, using the REQUIRE construct, specify to the compiler conditions which are required to be true of the execution-time environment of his programs. All requirements are legal at either declaration or statement level. The requirements fall into three classifications, described as follows: Group 1 -- Space requirements -- STRINGSPACE, SYSTEMPDL, etc. The inclusion of the specification "REQUIRE 1000 STRINGSPACE" will ensure that at least 1000 words of storage will be available for storing Strings when the program is run. Similar provisions are made for various push-down stacks used by the execution-time routines and the compiled code. If a parameter is specified twice, or if separately compiled procedures are loaded (see page 22), the sum of all such specifications will be used. These parameters could also be typed to the loaded program just before execution (see page 208), but it is often more convenient to specify differences from the standard 20 SAIL USER MANUAL ALGOL DECLARATIONS sizes in the source program. Use these specifications only if messages from the running program indicate that the standard allocations are not sufficient. Group 2 -- Other files -- LOADMODULE, LIBRARY, SOURCEFILE, etc. The inclusion of the specification REQUIRE "PROCS1" LOADMODULE, "HELIB[1,3]" LIBRARY; would inform the Loader that the file PROCS1.REL must be loaded and the library HELIB.REL[1,3] searched whenever the program containing the specification is loaded. The parameter for both features should be a string constant of one of the above forms. The device DSK, and file extension .REL are the only values permitted for these entries, and are therefore assumed. LOADMODULES (.REL files to be loaded) may themselves contain requests for other LOADMODULES and LIBRARYs. LIBRARYs may only contain requests for other LIBRARYs. Duplicate specifications are in general merged into single requests (if a file is requested twice, it will be loaded only once). SAIL automatically places a request for the library "SYS:LIBSAn" in each main program, where n is the version number of the current Sail library of runtime routines. The inclusion of REQUIRE "SYS:PREAMB.SAI" SOURCEFILE will cause the compiler to save the state of the current input file, then begin scanning from PREAMB. When PREAMB is exhausted, SAIL will resume scanning the original file on the line directly following the REQUIRE. SOURCEFILEs may be nested to a depth of about 10 levels. Restrictions: A SOURCEFILE request must be followed by a semicolon (only one per REQUIREment), and must be the last text on the line in which it appears. SOURCEFILE switching must not be specified from within a DEFINE body (see page 104). The SEGMENTNAME, SEGMENTFILE specifications are currently applicable only to the Stanford "global model" users of SAIL. They allow specification of the name of a special non-sharable "HISEG", and the name of the file used to create this HISEG. These specifications may, like the space REQUIREments, be overridden by using the system REENTER command (see page 208). Group 3 -- other - INITIALIZATION, VERSION Before the execution of a program, Sail runs through an initialization routine. The user can specify things that he wants done at initialization time by declaring a Procedure without arguments, then saying 21 SAIL USER MANUAL ALGOL DECLARATIONS REQUIRE procedurename INITIALIZATION. The named procedure will be run called as the first executable statement in the outer block of the program (even if the REQUIRE appeared in a Source or REL file). Require-initialization procedures will be run in the order in which they were Required. WARNING: you should not Require initialization of a procedure which is declared inside another procedure. REQUIRE n VERSION (n a non-zero integer) will flag the resultant RELfile as version n. When a program loaded from several such RELfiles is started, the Sail allocatin code will verify that all specified versions are equal. A non-fatal error message is generated if any disagree. As much as will fit of the version number is also stored in lh(JOBVER), where JOBVER is location 137. Other requirements: PNAMES - see page 186; POLLING POINTS - see page 159; DELIMITERS - see page 102; BUCKETS - see page 131; NEWITEMS - see page 146; MESSAGE - see page 113; ERRORMODE - see page 210. COMMENT: You have probably noticed that a great deal of prior knowledge is required for proper understanding of this section. For more information about storage allocation, see page 208 below. The form and use of .REL files and libraries are described in "The Stanford A-I Project Monitor Manual" [Moorer] and [Weiher]. 2.5 - SEPARATELY COMPILED PROCEDURES    When a program becomes extremely large it becomes useful to break the program up into several files which can be compiled separately. This can be done in SAIL by preparing one file as a main program, and one or more other files as programs each of which contains one or more procedures to be called by the main program. The main program must contain EXTERNAL declarations for each of the procedures declared in the other files (EXTERNAL declarations have no procedure body). The non-main program files must have the following characteristics: 22 SAIL USER MANUAL ALGOL DECLARATIONS 1) All procedures to be called from the main program (or procedures in other files) must be qualified with the INTERNAL attribute when they are declared. External procedure declarations with headings identical to those of the actual declarations must appear in all those programs which call these procedures. 2) These internal procedures must be uniquely identifiable by the first six characters of their identifiers. In general, any two internal procedure names (or any other Internal variables in the same core image) with the same first six characters will cause incorrect linkages when the programs are loaded. 3) The reserved word ENTRY, followed by a semi-colon must be the first item in the program (preceding even the BEGIN for its outer block). No starting address will be issued for a program containing an Entry Specification. Since no starting address is present for this file, entry to code within it may only be to the procedures it contains. The statements in the outer block, if any, can never be executed. 4) Should you desire your separatedly compiled procedures to be collected into a user library, include a list of their identifiers between the ENTRY and the semi-colon of the Entry Specification of the program containing those procedure declarations. The format of libraries is described in [Weiher]. The identifier(s) appearing in the entry list may be any valid identifiers, but usually they will be the names of the procedures contained in the file. No checking is done to see if entry identifiers are ever really declared in the body of the program. 5) Any variables (simple or array) which appear in the outer block of a Separately Compiled Procedure program will be global to the procedures in this program, but not available to the main program (unless they are themselves connected connected to the main program by Internal/External declarations -- see below). Arithmetic arrays in these outer blocks will always be zero when the program is first loaded, but will never be cleared as others are by restarting your program (see reinitialization, page 19). Any variable, procedure or label may contain the attribute INTERNAL or EXTERNAL in its declaration (ITEMS may not -- items are part of 23 SAIL USER MANUAL ALGOL DECLARATIONS leap, page 115). The INTERNAL attribute does not affect the storage assignment of the entity it represents, nor does it have any effect on the behavior of the entity (or the scope of its identifier) in the file wherein it appears. However, its address and (the first six characters of) its name are made available to the loader for satisfying External requests. No space is ever allocated for an External declaration. Instead, a list of references to each External identifier is made by the compiler. This list is passed to the loader along with the first six characters of the identifier name. When an Internal name matching it is found during loading, its associated address is placed in each of the instructions mentioned on the list. No program inefficiency at all results from External/Internal linkages (belay that -- references to External arrays are sometimes more inefficient). The entity finally represented by an External identifier is only accessible within the scope of the External declaration. FORTRAN PROCEDURES   For a program written in DEC FORTRAN IV to run in the SAIL environment, the following restrictions must be observed: 1) It must be a SUBROUTINE or FUNCTION, not a main program. 2) It must not execute any FORTRAN I/O calls. The UUO structures of the two languages are not compatable. 3) It must be declared as a Fortran Procedure (see page 40) in the SAIL program which calls it. The type bits required in the argument addresses for Fortran arguments are passed correctly to these routines. The SAIL compiler will not produce a procedure to be called from FORTRAN. ASSEMBLY LANGUAGE PROCEDURES    The following rules should be observed: 24 SAIL USER MANUAL ALGOL DECLARATIONS 1) The ENTRY, INTERNAL, and EXTERNAL pseudo-ops should be used to obtain linkages for procedure names and "global" identifiers (remember that only six characters are used for these linkage names. 2) Accumulators F (currently '12), P (currently '17) and SP ('16) should be preserved over function calls. P may be used as a push-down pointer for arithmetic values and return addresses. SP is the string stack pointer. String results are returned on this stack. Arithmetic results are returned in AC 1. 3) Those who wish to provide their own UUO handlers or to increase their core size should read the relevant sections of the implementation manual. There are no other known processors which will produce SAIL- compatible programs. In particular, the LISP 1.6 system, by its very nature, contains storage allocation conflicts which are difficult to resolve. If a great need for this kind of compatibility develops it can be provided. 25 SAIL USER MANUAL ALGOL STATEMENTS SECTION 3   ALGOL STATEMENTS   3.1 - SYNTAX  ::= _ ::=  ::= ::= ELSE ::= IF THEN ::= GO TO ::= GOTO ::= GO ::= 26 SAIL USER MANUAL ALGOL STATEMENTS ::= FOR _ DO ::= NEEDNEXT ::= ::= , ::= ::= STEP UNTIL ::= STEP WHILE ::= WHILE DO ::= NEEDNEXT ::= DO UNTIL ::= NEEDNEXT ::= ::= ::= CASE OF BEGIN ::= CASE OF BEGIN 27 SAIL USER MANUAL ALGOL STATEMENTS ::= END ::= END ::= ::= ; ::= [ ] ::= ; [ ] ::= RETURN ::= RETURN ( ) ::= DONE ::= DONE ::= NEXT ::= NEXT ::= CONTINUE ::= CONTINUE ::= ::= ::= ( ) 28 SAIL USER MANUAL ALGOL STATEMENTS ::= ::= , ::= ::= ::= ::= NOWSAFE ::= NOWUNSAFE 3.2 - SEMANTICS  ASSIGNMENT STATEMENTS   The assignment statement causes the value represented by an expression to be assigned to the variable appearing to the left of the assignment symbol. You will see later (see page 48) that one value may be assigned to two or more variables through the use of two or more assignment symbols. The operation of the assignment statement proceeds in the following order: a) The subscript expressions of the left part variable (if any - Sail defines "variable" to include both array elements and simple variables) are evaluated from left to right (see Expression Evaluation Rules, page 49). b) The expression is evaluated. c) The value of the expression is assigned to the left part variable, with subscript expressions, if any, having values as determined in step a. This ordering of operations may usually be disregarded. However it becomes important when expression assignments (page 48) or function calls with reference parameters appear anywhere in the statement. For example, in the statements: I_3; A[I]_3+(I_1); 29 SAIL USER MANUAL ALGOL STATEMENTS A[3] will receive the value 4 using the above algorithm. A[1] will not change. Any algebraic expression (REAL, INTEGER (BOOLEAN), or STRING) may be assigned to any variable of algebraic type. The resultant type will be that of the left part variable. The conversion rules for assignments involving mixed types are mildly amusing. They are identical to the conversion rules for combining mixed types in algebraic expresions (see page 46 below). SWAP ASSIGNMENT   The  operator causes the value of the variable on the left hand side to be exchanged with the value of the variable on the right hand side. Arithmetic (REALINTEGER) type conversions are made, if necessary; any other type conversions are invalid. Note that the  operator may not be used in assignment expressions. CONDITIONAL STATEMENTS   These statements provide a means whereby the execution of a statement, or a series of statements, is dependent on the logical value produced by a Boolean expression. A Boolean expression is an algebraic expression whose use implies that it is to be tested as a logical (truth) value. If the value of the expression is 0 or NULL, the expression is a FALSE boolean expression, otherwise it is TRUE. See about type conversion, page 46. IF STATEMENT - The statement following the operator THEN (the "THEN part") is executed if the logical value of the Boolean expression is TRUE; otherwise, that statement is ignored. IF ... ELSE STATEMENT - If the Boolean expression is true, the "THEN part" is executed and the statement following the operator ELSE (the "ELSE part") is ignored. If the Boolean expression is FALSE, the "ELSE part" is executed and the "THEN part" is ignored. AMBIGUITY IN CONDITIONAL STATEMENTS     The syntax given here for conditional statements does not fully explain the correspondences between THEN-ELSE pairs when conditional statements are nested. An ELSE will be understood to match the immediately preceding unmatched THEN. Example: 30 SAIL USER MANUAL ALGOL STATEMENTS COMMENT DECIDE WHETHER TO GO TO WORK; IF WEEKEND THEN IF GIANTSONTV THEN BEGIN PHONEEXCUSE("GRANDMOTHER DIED"); ENJOY(GAME); SUFFER(CONSCIENCEPANGS) END ELSE IF REALLYSICK THEN BEGIN PHONEEXCUSE("REALLY SICK"); ENJOY(0); SUFFER(AGONY) END ELSE GO TO WORK; GO TO STATEMENTS    Each of the three forms of the Go To statement means the same thing -- an unconditional transfer is to be made to the "target" statement labeled by the label identifier. The following rules pertain to labels: 1) All label identifiers used in a program must be declared. 2) The declaration of a label must be local to the block immediately surrounding the statement it identifies (see exception below). Note that compound statements (BEGIN-END pairs containing no declarations) are not blocks. Therefore the block BEGIN "B1" INTEGER I,J; LABEL L1; ... IF BE3 THEN BEGIN "C1" ... L1: ... ... END "C1"; ... GO TO L1 END "B1" is legal. 3) Rule 2 can be violated if the inner block(s) have no array declarations. E.g.: 31 SAIL USER MANUAL ALGOL STATEMENTS Legal Illegal BEGIN "B1" BEGIN "B1" INTEGER I,J; INTEGER I,J; LABEL L1; LABEL L1; ... ... BEGIN "B2" BEGIN "B2" REAL X; REAL ARRAY X [1:10]; ... ... L1: ... L1:... ... ... END "B2"; END "B2"; GO TO L1; GO TO L1; END "B1" END "B1" 4) No Go To statement may specify a transfer into a FOREACH statement (FOREACH statements are part of LEAP -- page 115), or into complicated For loops (those with For Lists or which contain a NEXT statement). Labels will seldom be needed for debugging purposes. The block name feature (see page 212) and the listing feature which associates with each source line the octal address of its corresponding object code (see page 204) should provide enough information to find things easily. Many program loops coded with labels can be alternatively expressed as For or While loops, augmented by DONE, NEXT, and CONTINUE statements. This often results in a source program whose organization is somewhat more transparent, and an object program which is more efficient. FOR STATEMENTS   For, Do and While statements provide methods for forming loops in a program. They allow the repetitive execution of a statement zero or more times. These statements will be described by means of SAIL programs which are functionally equivalent but which demonstrate better the actual order of processing. Refer to these equations for any questions you might have about what gets evaluated when, and how many times each part is evaluated. Let VBL be any algebraic variable, AE1, ... , AE8 any algebraic expressions, BE a Boolean expression, TEMP a temporary location, S a statement. Then the following SAIL statements are equivalent: Using For Statements -- 32 SAIL USER MANUAL ALGOL STATEMENTS FOR VBL _ AE1, AE2, AE3 STEP AE4 UNTIL AE5, AE6 STEP AE7 WHILE BE, AE8 DO S; Equivalent formulation without For Statements -- VBL_AE1; S; VBL_AE2; S; VBL_AE3; Comment STEP-UNTIL loop; LOOP1: IF (VBL-AE5) * SIGN(AE4)  0 THEN BEGIN S; VBL_VBL+AE4; GO TO LOOP1 END; VBL_AE6; Comment STEP-WHILE loop; LOOP2: IF BE THEN BEGIN S; VBL_VBL+AE7; GO TO LOOP2 END; VBL_AE8; S; If AE4 (AE7) is an unsubscripted variable, changing its value within the loop will cause the new value to be used for the next iteration. If AE4 (AE7) is a constant or an expression requiring evaluation of some operator, the value used for the step element will remain constant throughout the execution of the For Statement. If AE5 is an expression, it will be re-evaluated before each iteration, so watch this possible source of inefficiency. Now consider the For Statement: FOR VBL_AE1 STEP CONST UNTIL AE2 DO S; where const is a positive constant. The compiler will simplify this case to: 33 SAIL USER MANUAL ALGOL STATEMENTS VBL_AE1; LOOP3: IF VBL  AE2 THEN BEGIN S; VBL_VBL+CONST; GO TO LOOP3 END; If CONST is negative, the line at LOOP3 would be: LOOP3: IF VBL  AE2 THEN BEGIN The value of VBL when execution of the loop is terminated, whether it be by exhaustion of the For list or by execution of a DONE, NEXT or GO TO statement (see page 36, page 37, page 31), is the value last assigned to it using the algorithm above. This value is therefore always well-defined. The statement S may contain assignment statements or procedure calls which change the value of VBL. Such a statement behaves the same way it would if inserted at the corresponding point in the equivalent loop described above. WHILE STATEMENT   The statement: WHILE BE DO S; is equivalent to the statements: LOOP: IF BE THEN BEGIN S; GO TO LOOP END; DO STATEMENT   The statement: DO S UNTIL BE; is equivalent to the sequence: 34 SAIL USER MANUAL ALGOL STATEMENTS LOOP: S; IF BE THEN GO TO LOOP; CASE STATEMENTS   The statement: CASE AE OF BEGIN S0; S1; S2 ... Sn END is functionally equivalent to the statements: TEMP_AE; IF TEMP<0 THEN ERROR ELSE IF TEMP = 0 THEN S0 ELSE IF TEMP = 1 THEN S1 ELSE IF TEMP = 2 THEN S2 ... ELSE IF TEMP = n THEN Sn ELSE ERROR; For applications of this type the CASE statement form will give significantly more efficient code than the equivalent If statements. Notice that dummy statements may be inserted for those cases which will not occur or for which no entries are necessary. For example, CASE AE OF BEGIN S0; ; ; S3; ; ; S6; END provides for no actions when AE is 1,2,4,5, or 7. When AE is 0, 3, or 6 the corresponding statement will be executed. However, slightly more efficient code may be generated with a second type of Case statement that numbers each of its statement with [n] where n is an integer constant. The above example using this type of Case statement is then: CASE AE OF BEGIN [3] S3; [0] S0; [6] S6 END; All the statements must be numbered, and that the numbers must all be non-negative integers constant expressions, although them may be in any order. Block names (i.e. any string constant) may be used after the BEGIN and END of a Case statement with the same effect as block names on blocks or compound statements. (see about block names on page 3). 35 SAIL USER MANUAL ALGOL STATEMENTS RETURN STATEMENT   This statement is invalid if it appears outside a procedure declaration. It provides for an early return from a Procedure execution to the statement calling the Procedure. If no return statement is executed, the Procedure will return after the last statement representing the procedure body is executed (see page 14). An untyped Procedure (see page 38) may not return a value. The return statement for this kind of Procedure consists merely of the word RETURN. If an argument is given, it will cause the compiler to issue an error message. A typed Procedure (see page 53) must return a value as it executes a return statement. If no argument is present an error message will be given. If the Procedure has an algebraic type, any algebraic expression may be returned as its value; type conversion will be performed in a manner described on page 46. If no RETURN statement is executed in a typed Procedure, the value returned is undefined (it could be anything -- try it, it's fun). DONE STATEMENT   The statement containing only the word DONE may be used to terminate the execution of a FOR, WHILE, or DO (also FOREACH - see page 133) loop explicitly. Its operation can most easily be seen by means of an example. The statement FOR I_1 STEP 1 UNTIL n DO BEGIN S; ... IF BE THEN DONE; ... END is equivalent to the statement FOR I_1 STEP 1 UNTIL n DO BEGIN S; ... IF BE THEN GO TO EXIT; ... END; EXIT: In either case the value of I is well-defined after the statement has been executed (see page 34). 36 SAIL USER MANUAL ALGOL STATEMENTS The DONE statement will only cause an escape from the innermost loop in which it appears, unless a block name follows "DONE". The block name must be the name of a block or compound statement (a "Loop Block") which is the object statement of some FOR, WHILE, or DO statement in which the current one is nested. The effect is to terminate all loops out to (and including) the Loop Block, continuing with the statement following this outermost loop. For example: WHILE TRUE DO BEGIN "B1" ... IF OK THEN DO BEGIN "B2" ... FOR I_1 STEP 1 UNTIL K DO IF A[I]=FLAGWORD THEN DONE "B1"; ... END "B2" UNTIL COWSCOMEHOME; ... END "B1"; Here the block named "B1" is the "loop block". NEXT STATEMENT   A Next statement is valid only in a For Statement, While Statement, or Do Statement (or Foreach - see page 133). Processing of the loop statement is temporarily suspended. When the NEXT statement appears in a For loop, the next value is obtained from the For List and assigned to the controlled variable. The termination test is then made. If the termination condition is satisfied, control is passed to the statement following the For Statement. If not, control is returned to the inner statement following the NEXT statement. In While and Do loops, the termination condition is tested. If it is satisfied, execution of the loop terminates. Otherwise it resumes at the statement within the loop following the NEXT statement. Unless a block name follows NEXT, the innermost loop containing the NEXT statement is used as the "Loop Block" (see page 36). The terminating condition for the loop block is checked. If the condition is met, all inner loops are terminated (in DONE fashion) as well. If continuation is indicated, no inner-loop FOR-variable or WHILE-condition will have been affected by the NEXT code. The reserved word NEEDNEXT must precede FOR, WHILE, or DO in the "Loop Block", and must not appear between this block and the NEXT statement. Example: 37 SAIL USER MANUAL ALGOL STATEMENTS NEEDNEXT WHILE EOF DO BEGIN S_INPUT(1,1); NEXT; Comment check EOF and terminate if TRUE; T_INPUT(1,3); PROCESSINPUT(S,T); END; CONTINUE STATEMENT   The Continue statement is valid in only those contexts valid for the DONE statement (see page 36); the "Loop Block" is determined in the same way (i.e. implicitly or by specifying a block name). All loops out to the Loop Block are terminated as if DONE had been requested. Control is transferred to a point inside the loop containing the Loop Block, but after all statements in the loop. Example: FOR I_1 STEP 1 UNTIL N DO BEGIN ... CONTINUE; ... END is semantically equivalent to: FOR I_1 STEP 1 UNTIL N DO BEGIN LABEL CONT; ... GO TO CONT; ... CONT: END PROCEDURE STATEMENTS   A Procedure statement is used to invoke the execution of a Procedure (see page 14). After execution of the Procedure, control returns to the statement immediately following the Procedure statement. SAIL does allow you to use typed Procedures as procedure statements. The value returned from the Procedure is simply discarded. The actual parameters supplied to a Procedure must in match the formal parameters described in the procedure declaration, modulo Sail type conversion. Thus one may supply an integer expression to a real formal, and type conversion will be performed as on page 46. 38 SAIL USER MANUAL ALGOL STATEMENTS If an actual parameter is passed by VALUE, only the value of the expression is given to the Procedure. This value may be changed or examined by the Procedure, but this will in no way affect any of the variables used to evaluate the actual parameters. Any algebraic expression may be passed by value. Neither Arrays nor Procedures may be passed by value (use ARRBLT, page 98, to copy arrays). See the default declarations for parameters in page 18. If an actual parameter is passed by REFERENCE, its address is passed to the Procedure. All accesses to the value of the parameter made by the Procedure are made indirectly through this address. Therefore any change the Procedure makes in a reference parameter will change the value of the variable which was used as an actual parameter. This is sometimes useful. However if it is not intended, use of this feature can also be somewhat confusing as well as moderately inefficient. Reference parameters should be used only where needed. Variables, constants, Procedures, Arrays, and most expressions may be passed by reference.No String expressions (or String constants) may be reference parameters. If an expression is passed by reference, its value is first placed in a temporary location; a constant passed by reference is stored in a unique location. The address of this location is passed to the Procedure. Therefore, any values changed by the Procedure via reference parameters of this form will be inaccesible to the user after the Procedure call. If the called program is an assembly language routine which saves the parameter address, it is dangerous to pass expressions to it, since this address will be used by the compiler for other temporary purposes. A warning message will be printed when expressions are called by reference. The type of each actual parameter passed by reference must match that of its corresponding formal parameter, modulo Sail type conversion. The exception is reference string formals, which must have string variables (of string array elements) actual passed to them. If an algebraic type mismatch occurs the compiler will create a temporary variable containing the converted value and pass the address of this temporary as the parameter. A warning message will be printed. An exception is made for Fortran calls (see page 40). PROCEDURES AS ACTUAL PARAMENTERS     If an actual parameter to a Procedure PC is the name of a Procedure PR with no arguments, one of three things might happen: 39 SAIL USER MANUAL ALGOL STATEMENTS 1) If the corresponding formal parameter requires a value of a type matching that of PR (in the loose sense given above in page 38), the Procedure is evaluated and its value is sent to the Procedure PC. 2) If the formal parameter of PC requires a reference Procedure of identical type, the address of PR is passed to PC as the actual parameter. 3) If the formal parameter requires a reference variable, the Procedure is evaluated, its result stored, and its address passed (as with expressions in the previous paragraph) as the parameter. If a Procedure name followed by actual parameters appears as an actual parameter it is evaluated (see functions, page 53). Then if the corresponding formal parameter requires a value, the result of this evaluation is passed as the actual parameter. If the formal parameter requires a reference to a value, it is called as a reference expression. FORTRAN PROCEDURES   If the Procedure being called is a Fortran Procedure, all actual parameters must be of type INTEGER (BOOLEAN) or REAL. All such parameters are passed by reference, since Fortran will only accept that kind of call. For convenience, any constant or expression used as an actual parameter to a Fortran Procedure is stored in a temporary cell whose address is given as the reference actual parameter. It was explained in page 14 that formal parameters need not be described for Fortran Procedures. This allows a program to call a Fortran Procedure with varying numbers of arguments, a feature which exists in DEC Fortran. No type conversion will be performed for such parameters, of course. If type conversion is desired, the formal parameter declarations should be included in the Fortran procedure declaration; SAIL will use them if they are present. To pass an Array to Fortran, mention the address of its first element (e.g. A[0], or B[1,1]). NOWSAFE and NOWUNSAFE    The NOWSAFE and NOWUNSAFE statements both take a list of Array names (names only - no indicies) following them. From a NOWSAFE until the end of the program or the next NOWUNSAFE, the specified arrays will not have bounds checking code emitted for them. If an array has had a NOWSAFE done on it, or has been declared SAFE, 40 SAIL USER MANUAL ALGOL STATEMENTS NOWUNSAFE will cause bounds checking code to be emitted until the array is made safe again (if ever). Note that NOWSAFE and NOWUNSAFE are compile time statements. "IF BE THEN NOWSAFE ..." will not work. 41 SAIL USER MANUAL ALGOL EXPRESSIONS SECTION 4   ALGOL EXPRESSIONS   4.1 - SYNTAX  ::= ::= ::= ::= ::= IF THEN ELSE ::= _ ::= CASE OF ( ) ::= ::= , ::= ::= 42 SAIL USER MANUAL ALGOL EXPRESSIONS ::= ::= ::=  ::= ::=  ::=  ::= ::= ::= ::= ::= ::= < ::= > ::= = ::=  ::=  ::=  ::= ::= MAX 43 SAIL USER MANUAL ALGOL EXPRESSIONS ::= MIN ::= ::= ::= + ::= - ::= LAND ::= LOR ::= EQV ::= XOR ::= ::= ::= * ::= / ::= % ::= LSH ::= ROT ::= MOD ::= DIV ::= & ::= ::= ^ ::= ::= - ::= LNOT ::= ABS ::= [ ] ::=  44 SAIL USER MANUAL ALGOL EXPRESSIONS ::= ::= ::= LOCATION ( ) ::= ( ) ::= ::= TO ::= FOR ::= ::= ::= ::= ::= ::= 4.2 - TYPE CONVERSION   Sail automatically converts between the data types Integer, Real, String and Boolean. The following table illustrates by description and example these conversions. The data type boolean is identical to integer under the mapping TRUE0 and FALSE=0. 45 SAIL USER MANUAL ALGOL EXPRESSIONS F |To r | o | INTEGER REAL STRING m| I | | Left justify | The right 7 bits N | | and raise to | are converted to T | | appropriate | to a 1 character E | | power. | string with that G | | 13451.345@3 | ASCII code. E | | -678-6.78@2 | 48  "0" R||| | | | R | Drop decimal | | Convert to inte- E | fractions. | | ger then convert A | 1.345@2134 | | to string. L | -6.7999@1-67 | | 4.8@1  "0" | 2.3@-2 0 | | 4.899@1  "0" ||| | The ASCII code| Convert to in-| S | for the first | teger then | T | character of | to real. | R | string. | | I | "0SUM" 48 | "0SUM" 4.8@1 | N | NULL  0 | NULL  0 | G||| NOTES: The NULL string is converted to 0, but 0 is converted to the one character string with the ASCII code of 0. If the absolute value of an integer is greater than 134217728, then some low order significance will be lost in the conversion to real; otherwise, conversion to real and then back to integer will result in the same integer value. If a real number has magnitude greater than 134217728, then conversion to integer will produce an invalid result. Conversion from real to integer can be sped by a factor of 8 if SHORT reals and integers are used. It is only necessary that one of the data types be SHORT; both the number to be converted and the variable need not be SHORT. SHORTness is a dominate quality in algebraic binary operations. That is, the sum of a SHORT real and a regular real will be treated as a SHORT real. SHORT integers and reals must have an absolute magnitude of less than 134217728. The binary arithmetic, logical, and String operations which follow will accept combinations of arguments of any algebraic types. The type of the result of such an operation is sometimes dependent on the type of its arguments and sometimes fixed. An argument may be 46 SAIL USER MANUAL ALGOL EXPRESSIONS converted to a different algebraic type before the operation is performed. The following table describes the results of the arithmetic and logical operations given various combinations of Real and Integer inputs. ARG1 and ARG2 represent the types of the actual arguments. ARG1' and ARG2' represent the types of the arguments after any necessary conversions have been made. OPERATION ARG1 ARG2 ARG1' ARG2' RESULT + - INT INT INT INT INT* * ^ % REAL INT REAL REAL REAL MAX MIN INT REAL REAL REAL REAL REAL REAL REAL REAL REAL LAND LOR INT INT INT INT INT EQV XOR REAL INT REAL INT REAL INT REAL INT REAL INT REAL REAL REAL REAL REAL LSH ROT INT INT INT INT INT REAL INT REAL INT REAL INT REAL INT INT INT REAL REAL REAL INT REAL / INT INT REAL REAL REAL REAL INT REAL REAL REAL INT REAL REAL REAL REAL REAL REAL REAL REAL REAL MOD DIV INT INT INT INT INT REAL INT INT INT INT INT REAL INT INT INT REAL REAL INT INT INT * If ARG2 is negative for the operatore "^", then the result is real. 4.3 - SEMANTICS  CONDITIONAL EXPRESSIONS   A conditional expression returns one of two possible values depending on the logical truth value of the Boolean expression. If the Boolean expression (BE) is true, the value of the conditional expression is the value of the expression following the delimiter THEN. If BE is 47 SAIL USER MANUAL ALGOL EXPRESSIONS false, the other value is used. If both expressions are of an algebraic type, the precise type of the entire conditional expression is that of the "THEN part". Unlike the nested If statement problem, there can be no ambiguity for conditional expressions, since there is an ELSE part in every such expression. Example: FOURTHDOWN(YARDSTOGO,YARDLINE, IF YARDLINE < 70 THEN PUNT ELSE IF YARDLINE < 90 THEN FIELDGOAL ELSE RUNFORIT) ASSIGNMENT EXPESSIONS   The somewhat weird syntax for an assignment expression (it is equivalent to that for an assignment statement) is nonetheless accurate: the two function identically as far as the new value of the left part variable is concerned. The difference is that the value of this left part variable is also retained as the value of the entire expression. Assuming that the assignment itself is legal (following the rules given in page 29 above), the type of the expression is that of the left part variable. This variable may now participate in any surrounding expressions as if it had been given its new value in a separate statement on the previous line. Only the _ operator is valid in assignment expressions. The  operator is valid only at statement level. Example: IF (I_I+1) < 30 THEN I_0 ELSE I_I+1; CASE EXPRESSIONS   The expression CASE AE OF (E0, E1, E2, ... , En) is equivalent to: IF AE=0 THEN E0 ELSE IF AE=1 THEN E1 ELSE IF AE=2 THEN E2 ... ELSE IF AE=n THEN En ELSE ERROR The type of the entire expression is therefore that of E0. If any of 48 SAIL USER MANUAL ALGOL EXPRESSIONS the expressions E1 ... En cannot be fit into this mold an error message is issued by the compiler. Case expressions differ from Case statements in that one may not use the [n] construct to number the expressions. Example: OUT(TTY,CASE ERRNO OF("BAD DIRECTORY", "IMPROPER DATA MODE", "UNKNOWN I/O ERROR", ... "COMPUTER IN BAD MOOD")); SIMPLE EXPRESSIONS   Simple expressions are simple only in that they are not conditional, case, or assignment expressions. There are in fact some exciting complexities to be discussed with respect to simple expressions. PRECEDENCE OF ALGEBRAIC OPERATORS     The binary operators in SAIL generally follow "normal" precedence rules. That is, exponentiations are performed before multiplications or divisions, which in turn are performed before additions and subtractions, etc. The bounding operators MAX and MIN are performed after these operations. The logical connectives  and , when they occur, are performed last (  before ). The order of operation can be changed by including parentheses at appropriate points. In an expression where several operators of the same precedence occur at the same level, the operations are performed from left to right. See page 50 for special evaluation rules for logical connectives. TABLE OF PRECEDENCE ^ * / % & MOD DIV LSH ROT + -   LAND LOR MAX MIN =  <  >    EXPRESSION EVALUATION RULES    SAIL does not evaluate expressions in a strictly left-to-right fashion. If we are not constrained to a left-to-right evaluation, (as is ALGOL 60), we can in some cases produce considerably better code than a strict left-to-right scheme could achieve. Intuitively, The essential features (and pitfalls) of this evaluation rule can be illustrated by a simple example: 49 SAIL USER MANUAL ALGOL EXPRESSIONS b _ 2.6 ; c _ b + (b _ b/2); The second statement is executed as follows: divide b by 2 and assign this value (1.3) to b. Add this value to b and assign the sum to c. Thus c gets 2.6. If the expressions were evaluated in a strictly left-to-right manner, c would get 2.6 + 1.3. The evaluation scheme can be stated quite simply: code is generated for the operation represented by a BNF production when the reduction of that BNF production takes place. That is, b + (b _ b/2) isn't reduced until after (b _ b/2) is reduced, so the smaller expression gets done first. "" (OR)  If an algebraic expression has as its major connective the logical connective "", the expression has the logical value TRUE (arithmetic value some non-zero integer) if either of its conjuncts (the expressions surrounding the "") is true; FALSE otherwise. AB does NOT produce the bit-wise Or of A and B if they are algebraic expressions. Truth values combined by numeric operators will in general be meaningless (use the operators LOR and LAND for bit operations). The user should be warned that in an expression containing logical connectives, only enough of the expression is evaluated (from left to right) to uniquely determine its truth value. Thus in the expression (J<3  (K_K+1) > 0), K will not be incremented if J is less than 3 since the entire expression is already known to be true. Conversely in the expression (X 0  SQRT(X)>2) there is never any danger of attempting to extract the square root of a negative X, since the failure of the first test testifies to the falsity of the entire expression -- the SQRT routine is not even called in this case. "" 50 SAIL USER MANUAL ALGOL EXPRESSIONS (AND)  If a disjunctive expression has as its major connective the logical connective "", the expression has the logical value TRUE if both of its disjuncts are TRUE; FALSE otherwise. Again, if the first disjunct is FALSE a logical value of FALSE is obtained for the entire expression without further evaluation. "" (NOT)  The unary Boolean operator  applied to an argument BE(a relational expression, see Syntax) has the value TRUE if BE is false, and FALSE if BE is true. Notice that A is not the bitwise complement of A, if A is an algebraic value. If used as an algebraic value, A is simply 0 if A0 and some non-zero Integer otherwise. "<>=" (RELATIONS)  If any of the binary relational operators is encountered, code is produced to convert any String arguments to Integer numbers. Then type conversion is done as it is for the + operations (see page 46. The values thus obtained are compared for the indicated condition. A Boolean value TRUE or FALSE is returned as the value of the expression.. Of course, if this expression is used in subsequent arithmetic operations, a conversion to integer is performed to obtain an integer value. MAX MIN   A MAX B (where A and B are appropriate expressions -- see the Syntax) has the value of the larger of A and B (in the algebraic sense). Type conversions are performed as if the operator were `+'. `0 MAX X MIN 10' is X if 0X10, 0 if X<0, 10 if X>10. "+-" (ADDITION AND SUBTRACTION)     The + and - operators will do integer addition (subtraction) if both arguments are integers (or converted to integers from strings); otherwise, rounded Real addition or subtraction, after necessary conversions, is done. LAND LOR XOR EQV LNOT      LAND, LOR, XOR, and EQV carry out bit-wise And, Or, Exclusive Or, and Equivalence operations on their arguments. No type conversions are done for these functions. The logical connectives  and  do not have this effect -- they simply cause tests and jumps to be compiled. The type of the result is that of the first operand. This allows expressions of the form X LAND '777777777, where X is Real, if they are really desired. The unary operator LNOT produces the bitwise complement of its (algebraic) argument. No type conversions (except strings to 51 SAIL USER MANUAL ALGOL EXPRESSIONS integers) are performed on the argument. The type of the result (meaningful or not) is the type of the argument. "*/%" (MULTIPLICATION AND DIVISION)    The operation * (multiplication), like + and -, represents Integer multiplication only if both arguments are integers; Real otherwise. Integer multiplication uses the IMUL machine instruction -- no double-length result is available. The / operator (division) always does rounded Real division, after converting any Integer arguments to Real. The % operator has the same type table as +, -, and *. It performs whatever division is appropriate. DIV MOD   DIV and MOD force both arguments to be integers before dividing. X MOD Y is the remainder after X DIV Y is performed: X MOD Y = X - (X DIV Y)*Y . LSH ROT   LSH and ROT provide logical shift operations on their first arguments. If the value of the second argument is positive, a shift or rotation of that many bits to the left is performed. If it is negative, a right-shift or rotate is done. To obtain an arithmetic shift (ASH) operation, multiply or divide by the appropriate power of 2; the compiler will change this operation to a shift operation. "&" (CONCATENATION)  This operator produces a result of type String. It is the String with length the sum of the lengths of its arguments, containing all the characters of the second string concatenated to the end of all the characters of the first. The operands will first be converted to strings if necessary as described in page 46 above. Numbers can be converted to strings representing their external forms (and vice- versa) through explicit calls on execution time routines like CVS and CVD (see page 68 below). NOTE: Concatenation of constant strings will be done at compile time where possible. For example, if SS is a string variable, SS&'12&'15 will result in two runtime concatenations, while SS&('12&'15) will result in one compile time concatenation and one runtime concatenation. "^" 52 SAIL USER MANUAL ALGOL EXPRESSIONS (EXPONENTIATION)  A factor is either a primary or a primary raised to a power represented by another primary. As usual, evaluation is from left to right, so that A^B^C is evaluated as (A^B)^C. In the factor X^Y, a suitable number of multiplications and additions is performed to produce an "exact" answer if Y is a positive integer. Otherwise a routine is called to approximate ANTILOG(Y LOG X). The result has the type of X in the former case. It is always of type Real in the latter. SUBSTRINGS  A String primary which is qualified by a substring specification represents a part of the specified string. ST[X FOR Y] represents the Xth through the (X + Y - 1)th characters of the String ST. ST[X TO Y] represents the Xth through Yth characters of ST. Consider the ST[X TO Y] case. If Y > LENGTH(ST), (LENGTH is a runtime which returns the number of characters in the string -- see page 93) Y _ LENGTH(ST); if Y<0, Y_0; in either case the right half of the global Integer SKIP is set to TRUE. If X  1 it is set to 1. If X > (the modified) Y, it is set to Y+1 (null string guaranteed). In either case the left half of SKIP is made TRUE. The ST[X FOR Y] operation is converted to the ST[X TO Y] case before the substring operation is performed. To examine the above conditions, declare EXTERNAL INTEGER SKIP, clear it, and look at it after any interesting substring operation. "" (SPECIAL LENGTH OPERATOR)    This special primary construct is valid only within substring brackets. It is an algebraic value representing the length of the most immediate string under consideration. Example: A[4 to ] throws out the first 3 characters of A. A[3 for B[-1 for 1]] uses the next to the last character of string B as the number of characters for the A substring operation. FUNCTION DESIGNATORS   A function designator defines a single value. This value is produced by the execution of a typed user Procedure or of a typed execution- time routine (See chapters 7 and 9 for execution-time routines). For a function designator to be an algebraic primary, its Procedure must be declared to have an algebraic type. Untyped Procedures may only be called from Procedure statements (see page 38). The value obtained from a user-defined Procedure is that provided by a Return 53 SAIL USER MANUAL ALGOL EXPRESSIONS Statement within that Procedure. If the Procedure does not execute a Return Statement, the value might be anything at all. A Return Statement in a typed Procedure must mention a value (see page 36). The rules for supplying actual parameters in a function designator are identical to those for supplying parameters in a procedure statement (see page 38). UNARY OPERATORS   The unary operator ABS is valid only for algebraic quantities. It returns the absolute value of its argument. -X is equivalent to (0-X). No type conversions are performed. MEMORY AND LOCATION    One's core image can be considered a giant one dimensional array, which may be accessed with the MEMORY construct. MEMORY [ ] One can store and retrieve from the elements of MEMORY just as with any other array. However, when retrieving from MEMORY, one can specify the type of the accessed element by including type declarator reserved words after the . For example: ..._ MEMORY[X, INTEGER] ..._ MEMORY[X, REAL] ..._ MEMORY[X, ITEM] COMMENT items and sets are part of Leap; ..._ MEMORY[X, SET] ..._ MEMORY[X, INTEGER ITEMVAR] Note that one can not specify the contents of memory to be an array or a string. LOCATION is a predeclared Sail routine that returns the index in MEMORY (i.e. the address in core relative to the starting address of one's program) of the Sail construct furnished it. The following is a list of constructs it can handle and what LOCATION will return. 54 SAIL USER MANUAL ALGOL EXPRESSIONS CONSTRUCT x LOCATION(x) RETURNS variables address of the variable array name address of a word containing the the address of the first word of the array header array element address of that element procedure name address of the procedures entry code labels address of the label 55 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS SECTION 5   ASSEMBLY LANGUAGE STATEMENTS    5.1 - SYNTAX  ::= ::= ::= ::= ; ::= STARTCODE ::= QUICKCODE ::= END ::= END ::= ; ::= ::= ::= ::=
::= , ::= ,
56 SAIL USER MANUAL ASSEMBLY LANGUAGE STATEMENTS ::=
::= ::= @ ::= ::= ( ) ::= ::= ::= ::= [ ] ::= ::= ::= PDP-opcode 5.2 - SEMANTICS  Within a STARTCODE (QUICKCODE) block, statements are processed by a small and weak, but hopefully adequate, assembly language translator. Each "instruction" places one instruction word into the output file. An instruction consists of