LIBRARY OF THE UNIVERSITY OF ILLINOIS AT URBANA-CHAMPAIGN 5>iQ.W XJtl»T j/6>r W^ Report No. U26 S f /&.*.-/<-' V PLONE: A LOAD-AND-GO COMPILER FOR A BASIC SUBSET OF PL1 by Albert Lee Winterbauer January 15, 1971 THE LIBRARY OK IHE NOV 9 1972 UNIVERSITY OF ILLINOIS AT URBANA-CHAMPAIGN DEPARTMENT OF COMPUTER SCIENCE UNIVERSITY OF ILLINOIS AT URBANA-CHAMP, IHI UN:FJgr3B !H0 Report No. k26 PLONE: A LOAD-AND-GO COMPILER FOR A BASIC SUBSET OF PL1 by Albert Lee Winterbauer January 15, 1971 Department of Computer Science University of Illinois at Urbana-Champaign Urbana, Illinois 6l801 "^Submitted in partial fulfillment of the requirements for the Master of Science degree in Computer Science, February 1971- Digitized by the Internet Archive in 2013 http://archive.org/details/ploneloadandgoco426wint Ill ACKNOWLEDGMENT The original design and preliminary coding of the PLONE compiler was done in a seminar course on compilers led by Professor Robert S. Northcote at the University of Illinois during the Fall Semester of 1969* The seminar members made decisions on how large a subset of PL1 should be implemented, incorporated some restrictions which would allow a load-and-go type compiler, decided on coding conventions, and outlined most of the logical development of the PLONE compiler . The job of coding and debugging the PLONE compiler was continued during the Spring and Summer of 1970 as individual study projects by members of the original seminar and others. The project, which was financed by the University of Illinois, Department of Computer Science, was terminated in the Summer of 1970. Those who have worked on the PLONE project and their areas of concentration are: Anita Bension Control Statements Angie Gaffney System Interface John Gaffney Scanner and Parser Marty Kaplan Symbol Table Bruce Leasure Symbol Table Robert Mercer Parser Marty Michel Input-Output John Read Input -Output Jay Tummelson Arithmetic Albert Winterbauer Control Statements The author would also like to acknowledge the typist, Gayanne Carpenter, for her work . IV TABLE OF CONTENTS Page ACKNOWLEDGMENT iii 1. DESIGN GOALS 1 1.1. Student Oriented Compiler 1 1.2. High Speed Compilation 1 1.3- Large Enough Subset of PL1 1 l.U. Good Error Diagnostics 2 2. THE PLONE LANGUAGE 3 2.1. EBCDIC Character Set 3 2.2. Variable Names k 2.3. Recognition of Statements k 2.3.1. Card Format k 2.3.2. Statement Format 5 2. 3. 3» Comments 5 2.3.U. Use of Blanks 5 2.k. PLONE Data Types 6 2.U.I. Arithmetic Values 6 2.U.2. Character Strings 7 2.U.3. Bit Strings 8 2.k.k. Labels 8 2A.5. Arrays 8 2.U.6. Default Attributes 9 2.U.7. The DECLARE Statement 9 2.U.8. PLONE Variables 12 2.U.8-1. FIXED) 12 2.U.8.2. FLOAT 12 2.U.8.3- CHARACTER 12 2.k.Q.k. BIT 13 2.U.8-5- LABEL 13 2.^.8.6. Arrays 13 2.5. Evaluation of Expressions Ik 2.5.L Simple Expressions Ik 2.5.2. Array Operations 16 2.6. Conversion Rules 18 2.6.1. Arithmetic Conversion Rules 18 2.6.2. Rules for the Concatenation Operator ... 19 2.6.3- Rules for the Relational Operators .... 19 2.6.U. Rules for the Logical Operators 19 2.7. Assignment Statements 20 2.7.1. Simple Assignment Statements 20 2.7.2. Multiple Assignment Statements 21 2.8. Blocks 22 2.8.1. BEGIN Blocks 22 2.8.2. PROCEDURE Blocks 23 2.8.3- Scope of Identifiers in Nested Procedures 26 TABLE OF CONTENTS v 2-9* Control Statements 2.10 2.9 2.9 2.9 2.9 2.9 2.9 2.9 GOTO IF DO STOP/EXIT CALL RETURN END Input-Output 2.10.1. Stream Input-Output Statements 2.10.2. Data Lists 2.10.3. Format Lists 2. 10.5. Options 2.11. Error Control 2.11.1. ON Conditions 2.11.2. Prefix Conditions Page 27 27 28 29 32 32 35 35 36 36 37 38 in >+2 3. STATUS REPORT, >+6 APPENDIX A. A BNF SYNTAX SPECIFICATION FOR THE PLONE LANGUAGE. B. LIST OF ACCEPTABLE KEYWORD ABBREVIATIONS C. PLONE ATTRIBUTES 50 56 57 1. DESIGN GOALS 1.1. Student Oriented Compiler The primary goal in writing a load-and-go PL1 compiler for the IBM 360-75 system at the University of Illinois is to try to alleviate the poor program turnaround time for general users of the system which occurs each semester when the basic computer science students begin programming in PL1. The basic computer science courses are currently using the IBM PLl(F) compiler, which requires nearly 30 seconds of real time to compile and execute even the simplest of programs. 1.2 . High Speed Compilation A design goal for the PLONE compiler is that it be a fast load-and-go compiler which will compile programs of less than 100 state- ments in one or two seconds. In order to compile quickly, no attempt has been made to optimize object code when the optimization would result in an increase in compile time. PLONE was also designed as a batch-type compiler specifically to reduce system overhead time between jobs. 1-3 ■ Large Enough Subset of PL1 In order to keep the PLONE compiler small enough to allow it to exist as a semi -permanent in-core compiler, several deletions from the complete PL1 language were made, but the features deemed important to a beginning PL1 programmer were retained. In particular, character strings, bit strings, BEGIN blocks, internal procedure, prefix conditions, and ON conditions are included while the more advanced features such as pointer variables, "based storage, controlled storage, record input- output, external procedures, and multi-tasking have been excluded. A complete syntax specification of the language (PLONE) implemented is given in Appendix A. l.U. Good Error Diagnostics Since PLONE is essentially a student orientated compiler, it is important that both compile-time and execution-time diagnostic messages should be as self-explanatory as possible. Also, since PLONE is a load-and-go compiler resident in core at all times, it is necessary to keep compiled programs from overwriting any of the compiler. For this reason, all subscripts are checked for validity upon each construc- tion of a subscript and references to substrings of character and bit strings are always checked to insure that they are valid. 2. THE PLONE LANGUAGE 2.1. EBCDIC Character Set PLONE recognizes the EBCDIC 60-character set. The 60 char- acters recognized are: 29 alphabetic characters: A-Z alphabet $ currency symbol (&J commercial "at" sign # number sign 10 numeric characters: 0-9 21 special characters: = equal sign blank + plus sign minus sign * asterisk (multiplication sign) / slash (divide sign) left parenthesis ) right parenthesis , comma period (decimal point) °lo percent sign ' apostrophe ; semicolon colon 1! ,11 not sign ampersand ("and" sign) ii it or sign > "greater than" sign < "less than" sign — break character ? question mark The group of alphabetic characters and the group of numeric characters when intermixed are referred to as alphanumeric characters. 2 .2 . Variable Names PLONE variable names may be from 1 to 31 characters long, the first of which must be alphabetic. The remaining characters may consist of alphanumeric characters and the break character. Some examples of PLONE variable names are: PLONE X2 GROSS_PAY $ $_ Note: No embedded blanks are allowed in variable names. 2.3. Recognition of Statements 2.3.1. Card Format Statements may be punched anywhere in columns 2-72 of a card. Column 1 and columns 73-80 are ignored by the PLONE compiler. 2.3-2. Statement Format Each PLONE statement is terminated by a semicolon. As many- statements may be punched on a card as will physically fit in columns 2-72. A statement may be split across two or more cards. Card boundaries have nothing to do with the termination or separation of statements since only semicolons are used for statement termination. 2.3-3- Comments Comments consist of text which a programmer wishes to have printed on the output listing but which does not contain statements to be compiled. Comments in PLONE are preceded by the characters "/*" and followed by "*/". For example, the statement /*THIS IS A COMMENT */ would be ignored by the PLONE compiler, but would be printed on the output listing. The text of the comment obviously must not contain the two-character sequence "*/". 2.3.U. Use of Blanks Blanks are handled by the PLONE compiler in the following manner: (a) One or more blanks is equivalent to one blank. Hence, if a blank is required, one blank is sufficient, but more may be used if desired. (b) Certain keywords must be separated by at least one blank. For example, GET EDIT (A) (F(l0,5)); must contain a blank between "GET" and "EDIT". (c) Blanks are not necessary before or after an operator, but may be used if desired. The statement X=A+B; may be written as X = A + B; (d) No embedded blanks are allowed in variable names. If a separation of parts of the variable name is appropriate, use the break character. Some examples are: Valid Invalid GROSS_PAY GROSS PAY LAST_MONTHS_RECEIPTS LAST MONTHS RECEIPTS 2.U. PLONE Data Types 2.H.I. Arithmetic Values Arithmetic constants having the FIXED attribute are written as integers with no explicit decimal point. Negative integers are preceded by a minus sign ("-"). All integers are stored internally as four -byte twos complement fixed point numbers. Arithmetic constants with the FLOAT attribute are numbers which are written with an explicit decimal point. They may be written optionally with an E-type exponent. The following table summarizes the use of arithmetic constants. 1 X 1 X 10000 (1 x 10 5 ) X 6.3 -8 X 6.75 (675 x 10" 2 ) PLONE Constant FIXED FLOAT Numerical Value 1 x 1. 1.E5 6-3 -8 x 675E-2 All arithmetic constants written as integers (no decimal point) have the FIXED attribute . They are stored internally as four byte fixed point numbers. Constants written with a decimal point have the attribute FLOAT and are stored as eight byte floating point numbers. 2.U.2. Character Strings A character string constant is any sequence of characters enclosed in apostrophes. Some examples are: (a) 'THIS IS A CHARACTER STRING' (b) 'SO IS THIS' (c) '1' (d) '123ABC Character string constants have a fixed length. The examples above have 26, 10, 1, and 6 as their lengths, respectively. A character string variable may be of fixed or varying length. If the attribute VARYING is listed in the declaration for the character string variable, the string may take on any length from zero to the maximum length specified. See Appendix C for more information. 8 2.U.3- Bit Strings A bit string differs from a character string only in the restriction that it contains only zeroes and ones. A bit string constant is similar to a character string constant, except that it is followed by the character 'B'. For example, '001'B 'l'B 'lll'B "1000'B 'O'B are all legal bit strings. 2.U.U. Labels A statement label constant is an identifier which precedes a statement and is set off from the statement by a colon. Blanks are not required before or after the colon. Some examples are: X: A=A+1; Z: A=A*3; XZ : A=A/2 ; ZX:ZZ: A=A+11; The identifiers X, Z, XZ, ZX, and ZZ are statement label constants. In this example, ZX and ZZ are both labels to the same statement. If the programmer writes the statement GO TO Z; somewhere in his program, then execution of this statement would cause program control to be transferred to the statement labeled "z". 2.U.5- Arrays Arrays are used to hold aggregates of data which may be referenced by the array name which is followed by a subscript in parentheses. If the variable A were a single-dimensioned array of 10 elements, then in storage 10 contiguous locations would be set aside for the elements. If the lower bound on the subscripts were 1, then reference to A(l) would be a reference to the first element in storage. Likewise, A(10) refers to the last element of the array. The subscript within parentheses may be an expression. The expression will be converted to an integer in order to access the array element. The array may have more than one subscript (up to seven) . In this case the array elements are stored row-wise--the rightmost subscript varies the fastest. For example, if A is a two-dimensional array whose first subscript has lower bound 1 and upper bound 10 and whose second subscript has lower bound 1 and upper bound 3, then the array elements are stored in the following order: A(l,l),A(l,2),A(l, 3),A(2,l), . . . A(10,2),A(10, 3) • See Section 2.U.8.6. for more information about arrays. 2.U.6. Default Attributes All PLONE variable names take on default attributes if the programmer does not explicitly specify them in a DECLARE statement. All variables beginning with the letters A-H, 0-Z, #, $, or (6; take on the attribute FLOAT. Variables whose first letter is I-N take on the attribute FIXED. 2.U.7. The DECLARE Statement In the course of writing a program it is often convenient to have all variables used in the program to have the attribute FLOAT or to make some variables beginning with the letter A or B, say, to be FIXED. Changing the default attributes of one or more variables may be done in an explicit DECLARE statement. It is also necessary to 10 explicitly declare character string, bit string, and label variables. The DECLARE statement for a given variable may lie anywhere in the program with the restriction that it must precede the first use of the variable. As many DECLARE statements may be used as necessary, but as many variables may be declared in one DECLARE statement as desired. The general format of the DECLARE statement is: the word DECLARE followed by a single variable name or a list of variable names separated by commas and enclosed in parentheses followed by a list of attributes. The variable or the list of variables take on the attributes listed in the attribute list. If other variables or lists of variables should take on different attributes than those listed, the first variables and their attributes should be followed by a comma, and then the next variables can be given attributes as before. The DECLARE statement, like all PLONE statements, is terminated with a semicolon. The following examples are included to show some of the different forms of the DECLARE statement. (a) DECLARE X FIXED, Y CHARACTER (5); In this example, X is given the attribute FIXED, by default it would have been FLOAT. Note that this declaration for X must precede the first use of X in the block in which the DECLARE statement lies . See Section 2.8. for a discussion of block structure and scope of identifiers. The variable Y is declared to be a character string of length 5. (b) DECLARE (X,Y) FIXED; Both X and Y are given the attribute FIXED, since they are grouped in parentheses, thus forming a list of variables, all of which take on the same attributes. 11 A complete list of the attributes which may he used, and their meanings, is summarized in the following table. See Appendix C, "PLONE ATTRIBUTES", for a more complete explanation. AUTOMATIC BIT BIT(n) CHARACTER CHARACTER (n) ENTRY (attributes separated by commas) FIXED FIXED BINARY FLOAT FLOAT BINARY FLOAT DECIMAL INITIAL LABEL RETURNS (attributes) STATIC VARYING Allocate storage for this variable upon each entry to the containing block Make this a bit string of length one Make this a bit string of length n Make this a character string of length one Make this a character string of length n Request automatic conversion of the named procedure's parameters Make variable a four byte twos complement number Same as FIXED Make variable an eight byte floating point binary number Same as FLOAT Same as FLOAT Give the variable an initial value Make variable a label variable Change default attributes of returned value from a function procedure to the attributes listed Storage for this variable is allocated once only at compile time- -not upon entry to the block This bit or character string is varying in length--the length attribute is a maximum value and not an absolute length 12 2.4.8. PLONE Variables 2.4.8.1. FIXED A FIXED variable can represent any integer in the range -2147483648 to +2147483647. Note that the FIXED attribute may also he specified as FIXED BINARY. Internally a FIXED variable is represented as a four byte fixed point number. 2.4.8.2. FLOAT A FLOAT variable may represent any number in the range 10 ' to 10"' with 16 significant digits. Note that the FLOAT attribute may also be specified as FLOAT DECIMAL or as FLOAT BINARY. Internally, a FLOAT variable is represented as an eight byte floating point binary number. 2.4.8.3- CHARACTER A character string may contain a maximum of 255 characters . A string variable may either be constant or varying in length. To make a character string variable varying, use the VARYING attribute in its declaration. If the VARYING attribute is not specified, the string variable is constant in length and is padded with blanks on the right if it is given a character string value which is shorter than its maximum length. If the string variable is given a character string value which is longer than its maximum length, the extra rightmost characters are truncated before the assignment is made. 13 2.4.8-4. BIT A bit string differs only from a character string internally in that it is composed solely of zeroes and ones. Bit strings have a maximum length of 255 an| 3- "bit string variables may be varying in length. 2.U.8-5- LABEL A label variable is declared by giving the variable the attribute LABEL in a DECLARE statement. If the variable J were a label variable, then a statement such as GO TO J; may be executed if J has been assigned the value of a label constant in an assignment statement before the GOTO statement is executed. Since J may take on the value of any label constant, this type of transfer may be used when different transfer destinations are required at different times during program execution. 2.4.8.6. Arrays An array is declared by specifying the dimension attribute for an array name in a DECLARE statement, as in the example: DECLARE A(10), B(l0,10), C(l:15), D(3,3,3)j declares A,B,C, and D to be arrays. A has 10 elements, B has 100 elements, C has 15, and D has 27. The array A could have been declared as DECLARE A(l:10); which explicitly declares A to be an array of 10 elements, with subscripts 1 through 10. If the first subscript is not explicitly shown, it is 1U assumed to "be 1. Subscripts must take on integer values, or the expressions for the subscripts will be converted to integer values. They may also take, on negative or zero integer values. For example, DECLARE AA(-5:5); makes AA an 11 element array with subscripts -5, -h, -3, -2, -1, 0, 1, 2, 3, ^-> 5« Note that D is an array with three subscripts—the maximum number of subscripts is seven. In the declaration: DECLARE A(10,10), C(8,8,8); A is a two-dimensional matrix with 100 elements, and C, a three-dimen- sional matrix, has 512. Note that the storage of arrays internally is row-wise--a two-dimensional matrix would be stored by rows; arrays of more than two dimensions are stored according to the rule that the rightmost subscript varies the fastest. For example, DECLARE X(2,2,2), Y(3,*0; The order of storage of the elements of array X is: X(l, 1, l), X(l, 1,2), X(l,2,l), X(l,2,2), X(2,l,l), X(2,l,2), X(2,2,l), X(2,2,2); and the order for the Y array is: Y(l,l), Y(l,2), Y(l,3), Y(l,U), Y(2,l), Y(2,2), Y(2,3), Y(2,*0, Y(3,l), Y(3,2), Y(3,3), Y(3,*0 . An array may store CHARACTER, BIT, LABEL, FIXED, and FLOAT data. This may be declared explicitly in the DECLARE statement or may take on FIXED or FLOAT values by default. 2.5. Evaluation of Expressions 2.5.I. Simple Expressions The operators in PLONE are : 15 Arithmetic Operators ** exponentiation * multiplication / division + addition, unary plus subtraction, unary minus String Operator concatenation Relational Operators < less than > greater than = equal 1 = not equal -1 > not greater than -1 < not less than < = less than or equal to > = greater than or equal to Logical Ope irat ors and or not A PLONE expression is evaluated in the following manner: The PLONE operators are part of a hierarchy. The lower numbered operators are higher in the hierarchy and are performed first. The operators 16 within any one level are all at the same hierarchy and are performed as they are encountered. The hierarchy of the operators is: 1. **, unary -, unary +, 2. *,/ 3- +, - k 5 6 7 <,-»<,< =, =, -i =,>=,>, -i > The operators at level 1. are evaluated from right to left. The expression Z**-6 then would be Z -6 All other operations are evaluated 6C from left to right. The expression 6/A*C is evaluated as — . Expressions in parentheses are taken as a unit: 6/(A*C) is evaluated as -r^ . 2.5.2. Array Operations The elements of an array may all be assigned the same value or may be set equal, element by element, to the elements of an array or array expression in one statement by using array operations. For example, DECLARE A(10), B(10); A=0; /* ALL 10 ELEMENTS OF A ARE SET TO ZERO */ A(l)=l; /* JUST THE FIRST ELEMENT OF A IS SET TO ONE */ B=A; /* B IS SET EQUAL TO A, TERM BY TERM */ Array operations may be performed only if all the arrays in the expression have exactly the same number of subscripts and the bounds for each subscript are the same. Note that this restriction applies only to the arrays which are used in array operations, not to the use of individual elements of any array. For example, IT DECLARE (A,B) (10), C(15); A=A+B; B=B+C; /* ILLEGAL*/ a=a+b*c(5); The expression A+B is an array expression, hence, the arrays must have the same dimensions. However, the expression A+B*C(5) is legal since C(5) is an individual array element and, therefore, the dimensions of C have nothing to do with the array expression. The arithmetic in an array expression is performed sequentially first with the first elements in storage and then with each succeeding number in storage. Thus, it is often important to know how the elements are stored. If there is only one subscript, there is no problem—the elements are stored sequentially. If there is more than one subscript, the storage is row-wise, as discussed in Section 2.U.8.6. The need to know the order of the stored elements is important since the expression. (Now assuming A to be a 2 x 2 array); A=A(1,2)*AJ is a legal statement whose result can easily be confusing if the above rule is not know. In this example, the value of A(l,2) changes during the course of the operation. Note that r A=A*A;" is array multiplication and not matrix multiplication. The expression "A=A*A; " has exactly the same effect as the four simple assignment statements: A(1,1)=A(1,1)*A(1,1) A(1,2)=A(1,2)*A(1,2) A(2,1)=A(2,1)*A(2,1) A(2,2)=A(2,2)*A(2,2) 18 2 .6. Conversion Rules 2.6.1. Arithmetic Conversion Rules When more than one data type is used in an arithmetic expression, conversions are made automatically as follows: if FIXED and FLOAT variables are used together, then a temporary FLOAT variable is created internally and is set to the FLOAT value of the FIXED expression. Arithmetic is then performed using the FLOAT variables. Likewise, if a CHARACTER variable is used with an arithmetic operator, a temporary arithmetic variable is created which contains the numeric representation of the character string. If the character string cannot be converted to a number, then a conversion error will be recognized and the program will be terminated at this point. The hierarchy for converting values of different types is as follows : 1 . FLOAT 2. FIXED 3 • CHARACTER k. BIT Whenever two variables having values of different types are the operands to an operator, the variable with the higher-numbered type is converted internally to the type of the other variable, if possible. 19 2.6-2. Rules for the Concatenation Operator When the string operator is used: (a) if either of the operands is a character string, then the other operand, if it is not already a character string, is converted to a character string; (t>) if neither operand is a character string but one is a bit string, then the other operand is converted to a bit string; (c) if neither operand is a character string or a bit string, both operands are converted to character strings. 2.6.3- Rules for the Relational Operators The relational operators may have operands of any type, but the result is always a bit string. For example, in the expression D=A=B; the leftmost "=" is the assignment operator; the other "= " is the relational operator. The logical expression A=B is evaluated: the result is 'O'B if they are not equal and is 'l'B if they are equal. The assignment of the result to D will require a conversion if D is not a bit string variable . 2.6.U. Rules for the Logical Operators The operands for the logical operations "and", "or", and "not" are converted to bit strings, and the result is a bit string. The result of the "and" operation ( "&") is 'l'B if both operands are, or can be converted to 'l'B; otherwise the result is 'O'B. The result of the "or" ') operation is 'O'B if both operands are, or can be converted to, 'O'B; otherwise the result is 'l'B. The result of the "not" ("-j") 20 operation is 'l'B if the operand is, or can "be converted to, 'O'B; and is 'O'B otherwise. The following truth tahle illustrates all possibilities . Values of Operands Results of Operations X Y X&Y xlY -.X 'O'B 'l'B . 'l'B 'l'B 'l'B 'O'B 'l'B 'O'B 'l'B 'l'B 'O'B 'O'B 'O'B 'O'B 'O'B *0'B 'l'B 'O'B 'l'B 'O'B 'O'B 'l'B 'l'B 'l'B Logical expressions are used in the IF statement, in the WHILE clause of the DO statement, and in the assignment statement. The result of any logical expression is a bit string of length one, and can be used as such in an assignment statement. For example, in the statement Z = Y | | X&Y; the result of "X&Y" is a bit string of length one which is concatenated to the bit string of length one, Y, and is assigned to the bit string Z. See Section 2. 9-2. for more information about the IF statement, Section 2.9-3- for information about the DO statement, and Sections 2.U.3 and 2.U.8.1+. about hit strings. 2 .7 . Assignment Statements 2.7.I. Simple Assignment Statements An assignment statement is used to assign a value to a variable or array member. Its general format is: X = expression; 21 the expression on the righthand side of the "= " is evaluated and the resultant value is stored in the storage location for the variable or " ti array member on the lefthand side of the "=". In the case X = X+l; the value stored in the storage location X is incremented by one. The "=" is the assignment operator ; it does not denote equality. If the value of the expression is of a different type than that of the variable to which it will be assigned, then it will be converted to the correct type before the assignment is performed. For example, DECLARE A FIXED, B FLOAT; A=1.2365; B=l6; In the first assignment statement the expression on the righthand side of the assignment is a floating point expression, while A is a fixed point variable. The value I.2365 will be truncated to the integer value 1 before the assignment is made. In the second assignment statement the value of the expression is fixed point while B is a floating point variable. In this case, the integer 16 is converted to its floating point equivalent before the assignment is made. 2 .7 .2 . Multiple Assignment Statements The multiple assignment statement has the format: a list of variable names separated by commas, the assignment operator, and then an expression. For example, X,Y,I=A+B; 22 This is the same as writing the three assignment statements: X=A+B; Y=A+B; I=A+B; The multiple assignment statement is simply a shorthand way of setting more than one variable equal to the same expression and is particularly useful for assigning zero to a lot of values during initialization. 2.8. Blocks 2.8.1. BEGIN Blocks A BEGIN block has the following form: BEGIN: (a list of statements usually including a DECLARE statement for one or more arrays, although the DECLARE statement is not required) END ; Execution proceeds sequentially into the block from the statement preceding the BEGIN statement. All arrays in a DECLARE statement in the BEGIN block are then allocated storage. Execution continues until control is transferred out of the BEGIN block, either by proceeding sequentially through the block or by a GOTO to a statement outside of the block. The storage allocated to the arrays of the BEGIN block is then freed. All variables local to the BEGIN block (listed in a DECLARE statement within the block) are no longer known and cannot be referenced from outside the BEGIN block. This includes simple variables as well as arrays. If a BEGIN block contains another BEGIN block, the inner BEGIN has access to all variables in the containing BEGIN. 23 The BEGIN block is useful to the programmer in the situation where large arrays are needed at different times during the execution of a program, but not enough core storage would be available to hold all the arrays at the same time . It is also useful in helping the programmer to identify independent logical parts of a program. A simple example of a BEGIN block follows: BEGIN; DECLARE A (1000); GET LIST (A); DO 1=1 TO 1000; SUM = SUM + A(l); END; END; In this example, an array is read in all at once, then each element is added to the variable "SUM" which is known in the containing block. When the BEGIN block is finished, all storage used by the array is freed for later use by the program. 2.8.2. PROCEDURE Blocks A PROCEDURE has the following form: label: PROCEDURE (optional parameter list) optional attribute list; (a list of statements of any type) END; Every procedure must have a label by which the procedure may be referenced. The parameter list, which is not always necessary, is a list of variables which are used to transmit information between the called procedure and the calling procedure. The calling procedure has 2k a matching parameter list with the same number and type of arguments as there are in the called procedure's parameter list. See Section 2.9.5., "CALL" statement for more information about the parameter list. The attribute list is used if the procedure is a function procedure . It lists the attributes of the returned value of the procedure . See Section 2.9.6., "RETURN" statement, for more information. Note that if the attributes listed differ from the default values, the name of the procedure must he declared in the calling procedure and the RETURNS attribute must be used to specify the attributes of the returned value. The above form is the form for the internal procedure, whereas the whole program is called an external procedure and must have as its first statement: label: PROCEDURE OPTIONS (MAIN); Every PROCEDURE statement must have a matching END statement. A simple example of a complete PLONE program is: PROG: PROCEDURE OPTIONS (MAIN); DECLARE I FLOAT; 1=5; END; The external procedure is the whole program; there are no internal procedures. Another example which contains an internal procedure is: PR0G2 : PROCEDURE OPTIONS (MAIN); PROD : PROCEDURE (X,Y); RETURN (X*Y); END: A=5i v=T; X=PROD (A,V) END; 25 In this example PROD is a function procedure . In the calling procedure A and V are assigned values and these values are passed to the PROD procedure. In PROD X and Y, respectively, take on the values of A and V. They actually refer to the same storage location. Note that the first executable statement of the external procedure is the statement A=5; since an internal procedure may be invoked only by a reference to its name in a function reference or in a CALL statement . It can never be invoked by proceeding sequentially into the procedure from the statement proceding the PROCEDURE statement for the internal procedure . Instead, the whole procedure is skipped and execution resumes at the first executable statement following the END statement for the procedure. Note that PLONE requires that the parameters in a parameter list should be the same in number and type as in the procedure definition , If automatic conversion to the required type if desired, the ENTRY attribute in a DECLARE statement in the body of the calling procedure may be used. For a description of the ENTRY attribute see Appendix C. When a procedure is called, storage is allocated for all variables internal to the called procedure. When a RETURN statement is encountered, all storage used is then deallocated. If it is desired that a variable retain the same storage location throughout the duration of a program, the STATIC attribute must be specified for that variable. See Appendix C for an explanation of the STATIC attribute . 26 2.8.3* Scope of Identifiers in Nested Procedures PLONE allows block structures of the following form: One external procedure (main program) internal procedures or BEGIN blocks All variables that are not explicitly declared in an internal procedure, including all internal procedures and the main procedure, have the attribute EXTERNAL, which means that they are known throughout the program. All variables explicitly declared in an internal procedure are known only within that internal procedure. Note that this allows multiple use of the same variable name, so that one name may refer to several different internal storage locations, the correct one in any instance depending on the context in which the name is used. The situation is similar for the use of BEGIN blocks: variables known in the block containing the BEGIN block are also known in the BEGIN block, providing they are not named the same as one of the variables in the DECLARE statement for the BEGIN block. These declared variables are local to the BEGIN block, and are not known outside the BEGIN block. 27 The following example illustrates the use of identical names: PROG : PROCEDURE OPTIONS (MAIN); x=5; Y=10; SI: PROCEDURE; DECLARE X FIXED; X=15; Y=Y+X; RETURN END; CALL SI; Y=Y/X; END; There are two variables named X in this example. They refer to different storage locations and are actually completely unrelated. After the statement "CALL SI; "has been executed, the value of Y is 25 • However, after the statement "Y=Y/X; ", the value of Y is then 5, since the X in this statement is the X (=5) of the procedure PROG and not the X (=15) of the internal procedure SI. 2.9- Control Statements 2.9.1. GOTO The GOTO statement transfers control to another section of the program by specifying the statement label of the statement to which control is to be transferred. For example, if LI is a statement label constant, execution of the statement GOTO LI; will cause the statement labeled LI to be the next executable statement. If LI is in a different block than the GOTO statement, the block that contains LI must be active, i.e. it must not be in a block which is internal to the present one. Control cannot be transferred to the 28 middle of an inactive BEGIN block or to a procedure name . A procedure may be invoked by a CALL statement or a function reference, but never by a GOTO statement. A label variable may be specified instead of a statement label constant, providing the label variable has been assigned the value of a statement label constant before the GOTO statement is executed. For example, DECLARE L LABEL; L=L1; GOTO L; would transfer control to statement LI. The label assignment statement r L=Ll; is legal only if L is a label variable and LI is a label variable or a statement label constant. Label variables may not be used in arithmetic expressions. The keyword GOTO may be separated into the two words GO and TO with any number of intervening spaces and still be recognized as the GOTO keyword. 2.9.2. IF An IF statement evaluates a logical expression; if the value of the expression is true (takes on the value 'l'B), then the THEN clause is executed; while if it is false (takes on the value 'O'B), then the ELSE clause is executed. If no ELSE clause is present, the THEN clause is skipped and execution begins at the first executable statement following the IF statement is the expression is false. For example, IF A=B THEN GO TO L; ELSE A=B; 29 If A equals B, control is transferred to statement L. If A is not equal to B the ELSE clause is executed: A is set equal to B and then control goes to the statement following the whole IF statement. A THEN clause or an ELSE clause may be a single statement, a BEGIN block, or a DO group. See Section 2.9.3- for an explanation of DO groups. The THEN or ELSE clause may not be a PROCEDURE, END, FORMAT, or DECLARE statement. It may be another IF statement. However, if IF statements are nested and not all of the IF statements contain ELSE clauses, the ELSE clauses present are assumed to belong to the innermost IF statement. For example, IF A=B THEN IF M=K THEN B=R; ELSE B=S; In this example, there is no ELSE clause f or 'IF A=B THEN...". If the ELSE clause should go with the outermost IF, then the use of an additional ELSE with a null statement would be required to resolve the ambiguity. The above statement would then be: LF A=B THEN IF M=K THEN B=R; ELSE; ELSE B=S; The null statement consists simply of a semicolon. Nothing is executed. Instead, control is passed to the next executable statement. In the example above, if control were passed to the ELSE clause containing the null statement, nothing would be done except to transfer control to the first statement after the second ELSE clause . 2.9.3. DO The DO group is a logical grouping of statements which are considered as a unit. They may be a simple group which is to be executed 30 once, such as might form a THEN clause or an ELSE clause or they may he a group which is to be executed repeatedly until some stopping criterion is raised. The simple DO group has the form: DO; (a group of statements) END; An example of the typical use of a simple DO group is: IF A=B THEN DO; A=2*A; B=l; GOTO L; END; ELSE B=B+1; The DO group tells the compiler that all three statements of the THEN clause should he executed if A is equal to B. The iterative DO group has the form: DO (loop conditions); (a group of statements) END; The loop conditions may he : (a) starting, incrementing, and stopping values for a specified loop variable. (b) a WHILE condition, a logical expression that is evaluated prior to each iteration of the DO loop. (c) a combination of (a) and (b) . (d) a list of several groups of conditions which will be used successively as preceding conditions are satisfied. The simplest condition of type (a) is simply to list a value for the loop variable : DO 1=6; 31 The variable I is the loop variable. It is set equal to 6 before executing the statements in the DO loop. Another form specifies a lower and an upper bound: DO 1=1 TO 6; I is initially set to 1. After each pass through the loop it is incremented by one before the next iteration. The last value I takes on for execution of the DO loop is 6. After this last pass through the loop, I is incremented to 7 > which is greater than 6, the upper bound, and thus the loop conditions have been satisfied. The loop is not executed again. Control passes to the first executable statement following the END statement for the DO loop. If an increment other than 1 is desired, the BY clause is used: DO R=l TO 2 BY .1; R is incremented by .1 instead of 1. If the BY increment is negative, the expression in the TO clause is a lower bound instead of an upper bound . A WHILE condition lists a logical expression: DO WHILE (A=6); The WHILE expression is evaluated: if it is true, the loop is executed repetitively; if false, the loop is not executed and control passes to the first executable statement after the DO group. The WHILE clause may be used with an iterative specification. For example, DO 1=1 TO 10 WHILE (J=0); 32 For the loop to be executed, both the WHILE and the iterative card signs discussed separately above must be met. It is possible to list several sets of conditions under which the same loop may be executed. After one set of conditions is satisfied, the next set is used. For example, DO 1=1,2, k TO 8,10 TO 100 WHILE (J=6); The loop will be executed with I sequentially set to : 1, 2, k, 5, 6, 7, 8, and then to 10, 11,..., 100 provided J=6. The loop variable may be FIXED, FLOAT, CHARACTER, or BIT, as long as the expressions for the starting, incrementing, and boundary conditions are of the same type or can be converted to the same type. 2.9-U. STOP/EXIT The forms of the STOP and EXIT statements, respectively, are: STOP; EXIT; Execution of a STOP or an EXIT statement causes the FINISH condition to be raised. If no ON-condition has been specified for the FINISH condition, the program will be terminated. (STOP and EXIT have exactly the same effect.) See Section 2.11.1. for a discussion of ON conditions . 2.9.5. CALL The CALL statement has the form: the keyword CALL followed by the name of the procedure being called. If there is a parameter list, it is enclosed in parentheses and follows the procedure name. 33 For example, CALL SUB (X,Y,Z); The procedure name SUB must have been declared ENTRY in the block the CALL statement is located, so that the compiler will know that the identifier SUB is a procedure name. The parameter list is optional in the sense that not every called procedure requires parameters. However, if the called procedure is expecting parameters, then there must be the required number of parameters, and each parameter must be of the correct type. Automatic conversion of parameters can be specified by the ENTRY attribute. See Appendix C for an explanation of the ENTRY attribute . Each parameter may be a variable name, a constant, an entry name, an array name, an array element, or an expression. If only the value of some variable is to be passed to a called procedure (and the value of the variable is to be left unchanged in the calling procedure), then the programmer should make the compiler believe an expression is being passed as an argument. For example, CALL SUB (X,Y,Z+0); would leave the value of Z unchanged in the calling program, while the values of X and Y may be altered by the called procedure. Note: Enclosing Z in parentheses: "CALL SUB (X,Y, (Z) ) ; "is identical to "CALL SUB (X,Y,Z); ". 3^ When a RETURN statement in the called procedure is executed, execution returns to the statement following the CALL statement in the calling procedure . The following is an example of both a function reference and a reference "by a CALL statement: EX: PROCEDURE OPTIONS (MAIN); EXCHANGE : PROCEDURE (X,Y); /^EXCHANGE PARAMETERS*/ T=X; X=Y; Y=T; RETURN; END; REVERSE PROCEDURE (X ) ; /^RETURN l/X IF X NOT ZERO, ZERO IF X IS ZERO*/ IF X=0 THEN RETURN (0) ; RETURN (l/X); END; A=3; B=U; CALL EXCHANGE (A,B); /*A IS NOW k AND B IS 3*/ A= REVERSE (B) ; /*A IS NOW .33333---V END; EXCHANGE is a called procedure which works only on parameters and external variables. It does not takeon a value itself. REVERSE is a function procedure. The name REVERSE takes on the returned value in the calling procedure. Note that a function procedure may also change parameters and external variables. See Section 2.8.2. for more infor- mation about function procedures and Section 2. 9 .6. for the RETURN statement. 35 2.9-6. RETURN The RETURN statement, which has either the form "RETURN;" or 'RETURN (expression) ; "returns control from a called procedure to the calling procedure. If the RETURN statement is of the first form, the procedure must have been invoked by a CALL statement. If of the second form, the procedure must have been invoked by a function reference. The RETURN statement causes program control to be passed back to the first executable statement following the CALL statement, or back to the point of the function reference. Before control is passed back to the calling procedure, all storage used by AUTOMATIC arrays is freed. If the RETURN statement is returning the value of an expression, the reference to the called procedure must have been a function call. The value in the returned expression is used as the value of the function name in the calling procedure . 2.9.7. END The END statement is used to close every PROCEDURE, BEGIN block, and DO group. It is logically necessary to the structure of the PLONE program. If it is desired to end more than one block or DO group at the same point, one END statement will suffice: the outermost block or group must have a label, which is listed following the END keyword. Use of this label following the keyword END will close all blocks and DO groups begun between the listed label and the END statement This method of closing is equivalent to explicitly writing out all the END statements separately. An example would be: 36 L: BEGIN; DO J=l TO 5; DO 1=1 TO 10; END L; The end statement ends the BEGIN block and both the DO groups. 2 . 10 . Input -Output 2 . 10 . 1 . Stream Input-Output Statements PLONE reads data from cards and prints information on a high-speed printer. The input-output statements are stream orientated. Card boundaries and new print lines, unless explicitly specified other- wise, have no special significance; that is, as much information is read from a card or written to a line as specified. The next read or write operation begins at the point where the previous operation left off. When one card is completely read or one line is completely printed, the read will go to the beginning of the next card and the write will go to the beginning of the next line automatically. Data may be read from data cards, 80 characters per card. Printed output, 132 characters per line, may be sent to the high-speed printer . 37 The GET statement is used to read data from cards and the PUT statement is used to print information on the printer. A simple input-output statement has the form: the keyword GET or PUT, one or more blanks, the keyword EDIT, a data list, and a format list. For example, GET EDIT (X,Y,Z) ((3)F(10)); PUT EDIT (A,B,A*B) ((3)F(10)); The GET statement gets values for the variables X, Y, and Z from data cards according to the specified format "(3) F(10)" (format is discussed in Section 2. 10. 3-). The PUT statement prints out the values of A and B and the value of the expression A*B- Note that there must be a format list following the data list. There may also be more than one pair of data lists and format lists. For example, GET EDIT (A,B) ( (2)F(lO) ) (X, Y) (SKIP, (2)E(10,2)); Values for A and B are read in according to the first format list, while values for X and Y are read in according to the second. 2.10.2. Data Lists A data list for a GET statement may be composed of variable names, subscripted variable names, and array names separated by commas. An expression or constant may not be specified. Data is read from data cards for the variables listed, beginning with the leftmost name specified. Every data item must have an associated format item which specifies the format with which the data is to be read. If a multi- dimensional array name is li sted there must be a format item for each array element. 38 The data list for a PUT statement is similar, except that the values of expressions and constants may also be printed out. A data list may be printed out repetitively with an implied-DO group. Usually an implied-DO group is used to print out array elements. An implied-DO group has the following form: a left parenthesis, a list of data elements separated by commas, one or more blanks, the keyword DO, DO specifications as explained in Section 2.9«3«> a nd a right parenthesis. For example, the data list (A(I,I), B(I,I) DO 1=1 TO 2) references the diagonal elements of A and B in the order: A(l, 1), B(l,l), A(2,2), B(2,2). Implied-DO groups maybe nested; for example, ((A(I,J) DO J=1,2,U) DO 1=1,3) The outermost DO is initiated first, then the innermost DO is begun. The innermost DO is completely satisfied before returning to the outermost. In the above example, the elements are treated in the following order: A(l,l), A(l,2), A(l,U), A(3,l), A(3,2), A(3,*0- 2.10.3- Format Lists A format list is used with EDIT directed input-output to specify the exact image of the data to be read or printed. Format lists appear in GET and PUT statements following the data lists and in FOEMAT statements, where they are used as remote format lists. For example, 39 PUT EDIT (A,B, (C(I)DO 1=1 TO 2),D) ( (2) (F(5,2),X(3) ),R(LABL) ) LABL'.FORMAT ((2) (E(lO,3), X(2)), A(12)); The variables A and B are printed out as fixed point integers in fields 5 spaces wide, each followed by 3 blank spaces. The array elements C(l), C(2), and the variable D are printed according to the remote format LABL. The two elements of C are printed in fields 10 wide, each field followed by two blank spaces. D is printed as a character string of length 12 . If the following statements were executed prior to the PUT statement above: A=l6.35; B=18.U; c(i)=i6.ie8; c(2)=-185-^e-3; D=' CHARACTER TO'; the output line would be : *###■*■■*-*■*■**■*■**■**■# xx x x x x x *-x^****-x^******-x^-x^*******-x--x-* 16.35 18. HO 1.610E 09 -1.85HE-01 CHARACTER TO The line of asterisks is used to show each column explicitly. If a data list contains more items than the format list has format items, the format list is reused, starting at the beginning, until the data list is exhausted. If the data list has fewer items than the format list, the excess format items are ignored. The following table lists the format items and their effects. In the table "w" is the field width. It specifies exactly how many characters of the input card or output line are to be used; "d" is the number of digits to the right of the decimal point to be printed, or, for input, specifies how many of the digits are to the right of an imaginary decimal point--that 1+0 is, if no decimal point is included in the input data, the rightmost d digits are taken to be digits to the right of the decimal point (if a decimal point is included with the input data, the "d" information is ignored); "p" is a scale factor--the number in storage will he printed as that number multiplied by 10 . F(w,d, p ) E(w,d,p) A(w) B(w) X(n) COLUMN(n) SKIP(n) LINE(n) PAGE R (label) Print right justified as a fixed point number; d and p are optional, d is taken to be zero if omitted. If p is specified, d must also be specified. If d is zero, no decimal point will be printed. Print right justified in field as an E-type number (e.g. xxxEyy) where xxx is the mantissa and yy is the decimal exponent. The E-type number 1-35E5 is a representation of 1-35 x HP); pis optional. Print as a character string left justified in the field; w is optional and taken to be one if absent. Print as a bit string in field; w is optional and taken to be one if absent. Skip n columns on output line, relative to current print position, (i.e. insert a field of n blanks). Space to n column from left margin of the output or input line . Skip n cards or lines; n is optional and is taken to be one if absent. Skip to line n (output only). Start at top of next page (output only). Effectively, insert format list from the FORMAT statement specified by "label" into the current format list at this point. 1+1 • 2.10.4. Options PLONE allows the three options SKIP, LINE, and PAGE with PUT statements and the option SKIP for use with GET statements. These keywords may lie after the GET or PUT keyword or after the last format list. The action of any of these options is performed prior to any reading or writing no matter where the option is specified. On input the SKIP option may be used to skip one or more cards before reading a new card. For example, GET SKIP (2) EDIT (X) (F(10)); would skip two cards before reading a value for X from the first 10 columns of the third card. If part of a card had been read prior to the execution of this statement, the rest of that card and one additional card would be skipped before reading a value for X. Note that this statement functions identically with the following statement: GET EDIT (X) (F(10)) SKIP (2); since skipping is performed prior to the read operation. If the expression in parentheses had been omitted, one card would have been skipped. For output all three options may be used, although only one option may be used in any GET or PUT statement. The SKIP option is similar to the input SKIP option: the specified number of lines is skipped before printing. The LINE option must be followed by an expression in parentheses denoting that line on the page where printing is to begin. If this line number has already been passed, printing begins at the top of the next page. The PAGE option specifies that printing should begin at the top of the next page. No expression is used with the PAGE option . U2 2 . 11 . Error Control 2 . 11 . 1 ON Conditions ON conditions allow the programmer to specify an action to be taken in the event of one of the following events happening: UNDERFLOW FLOAT arithmetic results in an exponent which is too small to be represented; OVERFLOW FLOAT arithmetic operation results in an exponent which is too large to be represented; FLXEDOVERFLOW FIXED arithmetic operation results in a number which is too large to be represented; ZERODIVIDE An attempt to divide by zero has taken place, either FLOAT or FIXED; ENDFILE A GET statement has been issued, but no more data is available to be read; ERROR Any of the above interruptions has taken place and no ON condition has been specified; FINISH A condition raised by encountering the end of a program, or by the ERROR condition being raised with no ON condition present. The ON statement has the following format: the keyword ON followed by one of the keywords listed above followed by an ON unit . The keyword SNAP may optionally appear after the keyword for the condition specified. The condition may be any of the six conditions listed above. The ON unit may be a simple statement, a BEGIN block, or the keyword SYSTEM. The ON unit is executed only when the condition specified arises. The use of ON statements can be used for diagnostic purposes. The statement ON ERROR GO TO PRINT ALL; ^3 would transfer control to "PRINT_ALL", where all the values of the variables in the program could be printed. This would be used to catch any program error. An ON statement could be used to transfer control to the execution phase of the program following the input of an unknown amount of data. For example, ON ENDFILE (SYSIN) GO TO CALC ; would transfer control to "CALC " when the input file was empty, and a read attempt was made. Note that the ENDFILE condition is raised only when the input file is completely empty- -it cannot be used when there are more than one data set to be used by the program. In this case, the programmer should separate each data set by special marker cards and check each input card to see if it is a "marker" card. If a simple statement is specified, it is usually a GOTO state- ment, but if another statement such as a PUT statement is specified, that one statement is executed and then the FINISH condition is raised. If the simple statement is a null statement, the interrupt is to be ignored and execution is to proceed at the point after which the interrupt occurred. The FINISH condition cannot be ignored. If the keyword SYSTEM is used, then the standard action will be taken. The standard action for UNDERFLOW, OVERFLOW, FIXED OVERFLOW, ZERODTVTDE, and ENDFILE is to raise the ERROR condition. The standard action for ERROR is to raise the FINISH condition. If the FINISH condition is raised and no ON unit has been specified, the program is terminated. kk If the keyword SNAP is specified after the condition, a traceback table showing exactly where the interrupt occurred will be printed before the ON unit is executed. If SNAP is not specified, no such traceback will be printed. The ON statement is an executable statement which remains in effect throughout the block containing the ON statement itself. The ON unit for a given condition may be altered by executing another ON state- ment for that condition. If the ON unit for a given condition is changed in an internal procedure or BEGIN block, the previous ON unit is restored upon exit from the procedure or BEGIN block. 2.11.2. Prefix Conditions Prefix conditions may be attached to PROCEDURE blocks, BEGIN blocks, or simple statements. They specify whether a given type of error should cause an interrupt or be ignored. The following are the prefix keywords and their actions: NOFIXEDOVERFLOW Ignore FIXEDOVERFLOW interrupts, the result is undefined; NOUNDERFLOW Ignore UNDERFLOW, the result is set to zero; NOOVERFLOW Ignore OVERFLOW, the result is undefined; NOZERODIVIDE Ignore ZERODIVIDE, the result is undefined; FIXEDOVERFLOW Raise ERROR condition upon occurrence; UNDERFLOW Raise ERROR condition upon occurrence; OVERFLOW Raise ERROR condition upon occurrence; ZERODIVIDE Raise ERROR condition upon occurrence. ^ The prefix condition is enclosed in parentheses and followed by a colon , It precedes a PROCEDURE statement, a BEGIN statement, or a simple statement. It is effective for the whole procedure, whole BEGIN block, or just for the one statement, respectively. An example: (NOFIXEDOVERFLCW):MAIN: PROCEDURE OPTIONS (MAIN); (FIXEDOVERFLOW): J=I**2 END; The FIXEDOVERFLOW interrupt is disabled throughout the entire program, execept for the one statement: J=I**2; kG 3- STATUS REPORT The coding of the PLONE project was originally "broken down into six parts: scanner, parser, symbol table, arithmetic, input-output, and control statements. Later, code was written to provide system interface for a resident batch-type compiler: Job Control Language was scanned and PLONE input was sent directly to PLONE' s input file. The purpose of the scanner is to search for the next symbol in the character input stream and to categorize it according to the language being parsed. For PLONE, a special scanner was required since PL1 allows several multiple-character terminal symbols such as the exponentiation operator, the concatenation operator, and several of the relational operators . In addition, it was deemed necessary that the scanner recognize repetition factors for character strings. For example, (3) 'ABC* would be expanded to: 'ABCABCABC Other duties include: (a) Entering bit and character strings into a buffer for use at run time . (b) Converting fixed and floating point constants to their machine values and storing them in a table for run time usage . (c) Checking to see if identifiers are really keywords. l+T (d) Providing suitable buffering of the input character stream to match the requirements of the parser. (e) Ignoring comments. (f) Doing a certain amount of syntax checking on the symbol being scanned. This includes checking for invalid (non-PLl) characters in the input stream, identifiers longer than 31 characters, bit or character strings longer than 255 characters, bit strings that contain other than ones and zeroes, E's in a floating point constant that are not followed by one or more integers . (g) Checking for buffer overflows. The parser is responsible for syntax checking and calling the semantic action routines which insert compiled code into core. The parser recognized the PLONE language by checking Floyd Production tables The Floyd Production tables were the largest single part of the PLONE compiler, taking approximately 30,000 bytes of storage. PLONE expressions were compiled by leaving a pointer to the original input line and then calling a semantic action routine which compiled arithmetic code without being called again by the parser. This was done to try to speed the compilation time of expressions . Also to speed compilation time, all integers were made four byte fixed point numbers, all floating point numbers were eight bytes (double precision), and bit strings were character strings composed solely of zeroes and ones. For input-output, only EDIT-directed input-output was imple- mented, although LIST-directed and DATA-directed input-output are in the language specification. kQ The control statements were written to conform to IBM's PL1 specification; however, no coding of DO statements was actively written and debugged. The symbol table was designed to fit in the high end of the region of core storage allocated to the PLONE compiler and object code area. The PLONE compiler would lie in the low end of core storage and object code would be compiled between the compiler and the symbol table, starting directly after the compiler and building towards the symbol table, which would in turn be building in the opposite direction towards the object code. If the object code began to overflow the symbol table, no more code would be compiled; however, syntax checking would continue with the symbol table still being built. If the symbol table began to overflow onto the compiler, syntax checking would be halted and the job would be terminated with an appropriate error message. The coding for PLONE is incomplete. Much compile time code has been written, but few go-time routines have been written. Much of the code written should be rewritten, since modifications were made as time progressed which made much of the code already written bulky and out-of-date. The programmers involved in the coding of PLONE were students who were learning how to write a compiler by writing a compiler. Most are aware now of how the coding should have been done, but are now gone or have moved on to new areas of interest. As an educational project it may be regarded as successful. However, poor access time on the 360/75 and other factors prevented final completion of the project. ^9 Probably the most significant results of the PLONE project are the scanner and parser, and the language itself. Starting with these items, a group of hard-working programmers should be able to write the semantic action routines needed to compile the object code The language PLONE should be a good introduction to PL1 for the beginning programmer and the scanner and parser are nearly completed, 50 APPENDIX A A BNF SYNTAX SPECIFICATION FOR THE PLONE LANGUAGE : := : := # ; : := [ $ EL [ function attribute> ] ] | [ # OPTIONS # ( # MAIN # ) ] : := LIST [ # : ] : := # ( LIST [ ] SEP # , # ) : := EL : := [