.; DESCRIPTION FOR K&P'S ^RATFOR\\ AS IMPLEMENTED ON THE 11 .; REVISION 0 22 MARCH 77 .; Edited to comments by EOM -- PDM 77-6-2 .NUMBER 1 THIS PAGE INTENTIONALLY BLANK .SKIP 6 .; LEAVE A BLANK PAGE FOR T. OF C. PRINTED AT END OF DOCUMENT .SPACING 1 .TAB STOPS 9 17 25 33 41 49 57 65 .PAPER SIZE 60,70 .TITLE ###############^^A-RCB-0091-SP-1########THE RATFOR PRE-PROCESSOR\\ .PAGE .LEFT MARGIN 5 .PARAGRAPH ^^INTRODUCTION\\ .PARAGRAPH ^^RATFOR\\ (^R^A^TIONAL ^F^O^RTRAN) IS A LANGUAGE BASED ON ^^FORTRAN\\. ^TO ^^FORTRAN\\, ^^RATFOR\\ ADDS MODERN CONTROL STRUCTURES INCLUDING ^^IF-ELSE, WHILE, REPEAT-UNTIL, FOR, BREAK, \A\N\D NEXT. \\^THERE ARE ALSO SOME COSMETIC DIFFERENCES BETWEEN ^^RATFOR\\ AND ^^FORTRAN\\:## ^^RATFOR\\ STATEMENTS ARE FORMAT-FREE; THERE CAN BE MORE THAN ONE ^^RATFOR\\ STATEMENT PER LINE; AND THE ^^RATFOR\\ CONTINUATION CONVENTION IS DIFFERENT. ^ALSO, THE ^^RATFOR\\ ^D^O STATEMENT IS SLIGHTLY DIFFERENT FROM THE ^^FORTRAN\\ ^D^O. ^FINALLY, THERE IS NO ARITHMETIC ^I^F IN ^^RATFOR\\. ^APART FROM THESE DIFFERENCES, ^^RATFOR\\ IS ^^FORTRAN\\. .PARAGRAPH ^BOTH THE DESIGN OF THE ^^RATFOR\\ LANGUAGE AND THE STRUCTURE OF THE ^^RATFOR\\ PROCESSOR PROGRAM ARE GIVEN BY ^KERNIGHAN AND ^PLAUGER IN THEIR BOOK "^SOFTWARE ^TOOLS" (^ADDISON-^WESLEY, ^DON ^MILLS, ^ONTARIO, 1976). ^THE VERSION OF ^^RATFOR\\ DESCRIBED HERE CONTAINS THE FOLLOWING DIFFERENCES FROM THAT DESCRIBED IN THE BOOK: .NOFILL .NOJUSTIFY .SKIP .LEFT MARGIN 15 1) ^THREE NEW STATEMENTS - ^^BREAK GROUP, DEFINELIST, \\AND^^ RETURN (EXPRESSION)\\ - HAVE BEEN IMPLEMENTED. .SKIP 2) ^THE CONTINUATION CONVENTION IS SLIGHTLY DIFFERENT. .SKIP 3) ONLY ' CAN DELIMIT ^HOLLERITH CONSTANTS (" IS FOR OCTAL CONSTANTS). .SKIP 4) >> IS THE SHORTFORM FOR .^^GT\\. AND << IS THE SHORTFORM FOR .^L^T. SINCE THE ^^FORTRAN IV-PLUS \\COMPILER USES THE SINGLE SYMBOLS < AND > IN VARIABLE ^^FORMAT\\ EXPRESSIONS. .FILL .JUSTIFY .LEFT MARGIN 5 .PARAGRAPH ^WHY BOTHER WITH ^^RATFOR\\?##^TO ANSWER THIS QUESTION, ^KERNIGHAN AND ^PLAUGER STATE:##"^YOU MAY WONDER WHY WE MAKE SUCH AN ISSUE OF [AVOIDING ^G^O^T^O]. ^AFTER ALL, YOU CAN DO ANYTHING, AND MORE, WITH [^G^O^T^O] THAN YOU CAN WITH THE ^^RATFOR\\ CONTROL STATEMENTS. ^IT TURNS OUT, THOUGH, THAT THE EXTRA FREEDOM PERMITTED BY ^G^O^T^O IS JUST WHAT YOU ^^DON'T\\ WANT. ^BY RESTRICTING YOURSELF TO A SMALL SET OF CONTROL FLOW STRUCTURES, YOU TEND TO WRITE CODE THAT IS BETTER THOUGHT OUT, MORE READABLE, AND HENCE LESS ERROR PRONE." .PARAGRAPH ^THE ^^RATFOR\\ PROCESSOR PRODUCES A ^^FORTRAN\\ PROGRAM WHICH MAY BE COMPILED WITH ANY ^^FORTRAN\\ COMPILER. .BLANK 3 .TEST PAGE 14 .SKIP 4 .HL 1 ^^RATFOR\\ ^CONTROL ^STATEMENTS .INDEX ^^RATFOR C\\ONTROL ^STATEMENTS .SKIP 2 .HL 2 ^^IF\\ .INDEX ^^IF\\ .PARAGRAPH ^THE ^^IF\\ STATEMENT TAKES THIS FORM: .NOFILL .NOJUSTIFY .LEFT MARGIN 15 ^^IF(\\ LOGICAL EXPRESSION ) STATEMENT .FILL .JUSTIFY .LEFT MARGIN 5 ^THE LOGICAL EXPRESSION IS EVALUATED, AND THE STATEMENT IS PERFORMED ONLY IF THE EXPRESSION IS TRUE. ^THE STATEMENT MAY BE ANY ^^RATFOR\\ STATEMENT. ^FOR EXAMPLE:^^ .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .SKIP IF( A .LE. B .OR. C .NE. D) CALL TRYIT(A,B,C,D) .FILL .JUSTIFY .LEFT MARGIN 5 .TEST PAGE 6 .SKIP 2 .HL 2 \\^GROUPING ^STATEMENTS .INDEX ^G\\ROUPING ^STATEMENTS .PARAGRAPH ^WE MAY WONDER WHAT USE THE ^I^F STATEMENT IS SINCE IT LOOKS LIKE IT CAN CONTROL ONLY ONE STATEMENT, JUST LIKE THE ^^FORTRAN\\ LOGICAL ^I^F. ^THE TRICK IS THAT ^^RATFOR\\ ALLOWS STATEMENTS TO BE GROUPED BY THE BRACKETS [ AND ]. ^THESE GROUPED STATEMENTS ARE TREATED AS IF THEY WERE ONE STATEMENT. ^FOR EXAMPLE: .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .SKIP .TEST PAGE 5 ^^IF(A .GT. B) [ CALL FLIP(A,B) FLIPPED=.TRUE. C=B ] .FILL .JUSTIFY .LEFT MARGIN 5 \\^IT DOES NOT REALLY MATTER WHERE THE BRACKETS APPEAR. ^FOR EXAMPLE, WE CAN SAY : .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .SKIP .TEST PAGE 4 ^^IF(A .GT. B) [CALL FLIP(A,B) FLIPPED=.TRUE. C=B] .FILL .LEFT MARGIN 5 .JUSTIFY .PARAGRAPH \\^IF WE ARE LUCKY ENOUGH TO HAVE A TERMINAL WITH LOWER CASE SYMBOLS, WE CAN TYPE { INSTEAD OF [ AND } INSTEAD OF ]. .PARAGRAPH \\^^RATFOR\\ USES BRACKETS TO GROUP STATEMENTS. ^SOME LANGUAGES USE SPECIAL KEYWORDS LIKE ^^BEGIN \A\N\D END\\ INSTEAD OF BRACKETS. ^KERNIGHAN AND ^PLAUGER RECOMMMEND THAT INDENTING BE USED TO EMPHASIZE STATEMENT GROUPING OR LOOPS, AND PREFER BRACKETS TO KEYWORDS BECAUSE THEY ARE EASIER TO TYPE AND LESS OBTRUSIVE. ^IF WE LIKE KEYWORDS, THE SECTION ON THE ^^DEFINE\\ STATEMENT (2.5) SHOWS HOW TO USE THEM IN ^^RATFOR\\. .PARAGRAPH .TEST PAGE 12 .SKIP 2 .HL 2 ^^IF-ELSE\\ .INDEX ^^IF-ELSE\\ .SKIP .LEFT MARGIN 15 .NOFILL .NOJUSTIFY ^THE FORM OF THE ^^IF-ELSE \\IS: ^I^F (LOGICAL EXPRESSION) STATEMENT1 ^^ELSE\\ STATEMENT2 .FILL .JUSTIFY .LEFT MARGIN 5 ^THE LOGICAL EXPRESSION IS EVALUATED, AND IF TRUE STATEMENT1 IS PERFORMED. ^OTHERWISE, STATEMENT2 IS DONE. ^AN ^^ELSE\\ ALWAYS GOES WITH THE NEAREST "UN-^^ELSE\\D" ^^IF\\. (^NOTE: THE ^^ELSE\\ MUST START A NEW STATEMENT.) ^FOR EXAMPLE: .NOFILL .NOJUSTIFY .LEFT MARGIN 15 .TEST PAGE 4 ^^IF( I .LE. J) MIN =I ELSE MIN = J .TEST PAGE 8 IF( SWITCH .OR. .NOT. (A .LE. B)) [ CALL TEST(A) C = ATAN2(A,B) ] ELSE [ CALL ERROR CALL EXIT ] .PARAGRAPH .TEST PAGE 12 \\^WE CAN ALSO BUILD AN ^^IF-ELSE\\ CHAIN TO SELECT ONE CASE FROM MANY:^^ IF(CHAR .EQ. ')' ) NPAR=NPAR-1 ELSE IF (CHAR .EQ. '(') NPAR=NPAR+1 ELSE IF (CHAR .EQ. ';') [ NPAR=0 CALL ENDSTA ] ELSE CALL ERROR .FILL .LEFT MARGIN 5 .JUSTIFY \\^THIS IS INDENTED TO EMPHASIZE THE SELECTION OF ONE OF MANY CHOICES. .PARAGRAPH .TEST PAGE 6 .SKIP 2 .HL 2 ^^WHILE\\ .INDEX ^^WHILE\\ .SKIP .NOFILL .NOJUSTIFY .LEFT MARGIN 15 ^FORM: ^^WHILE\\( LOGICAL EXPRESSION ) STATEMENT .FILL .LEFT MARGIN 5 .JUSTIFY ^THE LOGICAL EXPRESSION IS EVALUATED, AND THE STATEMENT IS PERFORMED IF, AND ONLY IF, THE EXPRESSION IS TRUE. ^AFTER THE STATEMENT IS PERFORMED, THE EXPRESSION IS RE-EVALUATED, AND THE STATEMENT IS DONE AGAIN IF THE EXPRESSION IS STILL TRUE. ^THIS LOOP CONTINUES UNTIL THE EXPRESSION IN THE ^^WHILE\\ BECOMES FALSE. ^THE STATEMENT WILL NOT BE DONE AT ALL IF THE LOGICAL EXPRESSION IS INITIALLY FALSE. .PARAGRAPH ^FOR EXAMPLE: .NOFILL .NOJUSTIFY .TEST PAGE 2 ^^WHILE( BUF(I) .NE. INDEX .AND. I .LE. N) I=I+1 .SKIP .FILL .JUSTIFY .TEST PAGE 8 .HL 2 ^^REPEAT .INDEX ^^REPEAT\\ .SKIP .NOFILL .NOJUSTIFY \\^FORM: ^^REPEAT\\ STATEMENT .FILL .JUSTIFY ^THIS CONTROL STRUCTURE CAUSES THE STATEMENT TO BE PERFORMED FOREVER UNLESS THE LOOP IS BROKEN BY A STATEMENT LIKE THE ^^BREAK\\ STATEMENT (SECTION 2.9). ^FOR EXAMPLE: .NOFILL .NOJUSTIFY .TEST PAGE 5 .SKIP ^^REPEAT [ CALL INPUT CALL XEQ CALL OUTPUT ] .SKIP .TEST PAGE 9 .FILL .JUSTIFY .HL 2 ^^REPEAT-UNTIL .INDEX ^^REPEAT\\ .NOFILL .NOJUSTIFY SKIP F\\ORM: ^^REPEAT\\ STATEMENT ^^UNTIL\\ (LOGICAL EXPRESSION) .FILL .JUSTIFY ^THE STATEMENT IS PERFORMED, AND THEN THE LOGICAL EXPRESSION IN THE ^^UNTIL\\ IS EVALUATED. ^IF THE EXPRESSION IS FALSE, THE STATEMENT IS PERFORMED AGAIN, AND THIS LOOP CONTINUES UNTIL THE LOGICAL EXPRESSION BECOMES TRUE. ^FOR EXAMPLE: .NOFILL .NOJUSTIFY .SKIP .TEST PAGE 5 ^^LOGICAL DONE REPEAT [ CALL INPUT CALL DOIT(DONE) ] UNTIL (DONE) \\^NOTICE THAT THE STATEMENT IS ALWAYS DONE AT LEAST ONCE. .FILL .JUSTIFY .TEST PAGE 8 .SKIP 2 .HL 2 ^^FOR\\ .INDEX ^^FOR\\ .SKIP .NOFILL .NOJUSTIFY ^FORM: ^^FOR\\(INITIALIZE; LOGICAL EXPRESSION; RE-INITIALIZE) STATEMENT .FILL .JUSTIFY .SKIP ^THE ^^FOR\\ STATEMENT PROVIDES A POWERFUL LOOPING FACILITY. ^THE INITIALIZE AND RE-INITIALIZE PORTIONS OF THIS STATEMENT CAN BE ANY ^^FORTRAN\\ (NOT ^^RATFOR\\) STATEMENTS; THEY SHOULD BE RELATED TO CONTROL OF THE ^^FOR\\ LOOP. .PARAGRAPH ^FIRST, THE INITIALIZE STATEMENT IS DONE. ^IF THE LOGICAL EXPRESSION IS THEN FALSE, THE STATEMENT AND RE-INITIALIZE PORTIONS ARE SKIPPED. ^OTHERWISE, FIRST THE STATEMENT AND THEN THE RE-INITIALIZE PORTIONS ARE PERFORMED. ^THE LOGICAL EXPRESSION IS THEN RE-EVALUATED, AND THE PROCESS REPEATS. ^THIS TEST-STATEMENT-RE-INITIALIZE LOOP CONTINUES UNTIL THE LOGICAL EXPRESSION BECOMES FALSE. ^OF COURSE, THE ^^FOR\\ STATEMENT MAY NOT BE DONE AT ALL IF THE EXPRESSION IS INITIALLY FALSE. ^THE ^^FOR\\ IS EQUIVALENT TO THIS ^^WHILE:\\ .NOFILL .NOJUSTIFY .TEST PAGE 5 INITIALIZE ^^WHILE\\ (LOGICAL EXPRESSION) [ STATEMENT RE-INITIALIZE ] .FILL .JUSTIFY ^THE ^^FOR\\ IS PREFERABLE BECAUSE IT GATHERS ALL THE LOOP CONTROL INFORMATION INTO ONE STATEMENT. .PARAGRAPH ^ANY COMBINATION OF THE INITIALIZE, TEST, OR RE-INITIALIZE PORTIONS MAY BE OMITTED. ^IF THE TEST IS OMITTED, THE RESULT IS AN INFINITE LOOP. ^HOWEVER, IF TWO OR MORE PARTS ARE OMITTED, A ^^WHILE\\ OR ^^REPEAT\\ STATEMENT IS PROBABLY A CLEARER CHOICE. .PARAGRAPH ^AT ITS SIMPLEST, THE ^^FOR\\ STATEMENT IS A ^^DO\\ LOOP WITH THE TEST AT THE TOP. ^BY MAKING THE TEST EXPRESSION COMPOUND, WE CAN (SAY) GO THROUGH A WHOLE ARRAY AND STOP EITHER AT THE END OR WHEN SOME SPECIAL ELEMENT IS FOUND. ^SEE THE FIRST TWO EXAMPLES OF THE ^^FOR\\. ^THE ^^FOR\\ STATEMENT IS ALSO HANDY FOR CONTROLLING LOOPS THAT HAVE NO INHERENT ARITHMETIC PROGRESSION: STEPPING THROUGH LINKED LISTS OR HASH TABLES ARE TWO EXAMPLES OF THIS (SEE THE THIRD EXAMPLE OF THE ^^FOR\\). .PARAGRAPH ^SOME EXAMPLES: .NOFILL .NOJUSTIFY .TEST PAGE 2 ^^FOR(I=1; I .LE. N; I=I+1) VEC(I)=0 .TEST PAGE 2 ^^FOR(I=1; I .LE. N .AND. VEC(I) .NE. ISTOP; I=I+1) CALL PROCES(VEC(I)) .TEST PAGE 2 ########FOR(I=H(KEY);#K.LE.TSIZ#.AND.#TAB(I).NE.KEY;#I=REH(I)) K=K+1 .TEST PAGE 2 FOR(;CODE .GT. 0; CODE=DONE-1) CALL OUT(CHARS(CODE)) .TEST PAGE 4 FOR(I=1;;I=I+1) [ CALL DOIT(I) CALL CHKHLT(I) ] .TEST PAGE 2 FOR(I=1; I .LE. N) CALL BUMP(I) .TEST PAGE 7 .FILL .JUSTIFY .SKIP 2 .HL 2 ^^DO\\ .INDEX ^^DO\\ .NOFILL .NOJUSTIFY .SKIP ^FORM: ^^DO\\ LIMITS STATEMENT .FILL .JUSTIFY ^HERE, LIMITS ARE THE STANDARD ^^FORTRAN\\ ^^DO\\ LIMITS, SUCH AS "^I = 1, ^N". ^THIS IS SIMPLY A ^^FORTRAN\\ ^^DO\\, EXCEPT THAT ^^RATFOR\\ TAKES CARE OF GENERATING A LABEL, AND PUTTING A LABELLED ^^CONTINUE\\ AT THE END OF THE LOOP. ^JUST ABOUT EVERY ^^DO\\ CAN BE REPLACED WITH A ^^FOR\\; THE CONVERSE IS CERTAINLY NOT THE CASE (E.G. THE SECOND EXAMPLE OF THE ^^FOR\\). .PARAGRAPH ^AN EXAMPLE OF A ^^DO\\ IS: .NOFILL .NOJUSTIFY .TEST PAGE 5 ^^DO I=ISTART, IEND [ K=IVEC(I) IVEC(I)=JVEC(I) JVEC(I)=K ] .SKIP .FILL .JUSTIFY .TEST PAGE 7 .HL 2 ^^BREAK\\ .INDEX ^^BREAK\\ .NOFILL .NOJUSTIFY .SKIP ^FORM: ^^BREAK\\ .FILL .JUSTIFY ^THE ^^BREAK\\ STATEMENT MUST ALWAYS APPEAR WITHIN SOME LOOPING ^^RATFOR\\ STATEMENT (I.E. ^^FOR, DO, REPEAT, WHILE\\). ^WHEN EXECUTED, IT CAUSES THE LOOP TO BE BROKEN, AND EXECUTION CONTINUES WITH THE STATEMENT FOLLOWING THE LAST STATEMENT IN THE LOOP. ^FOR EXAMPLE: .NOFILL .NOJUSTIFY .TEST PAGE 6 ^^REPEAT [ CALL INPUT(CHAR) IF(CHAR .EQ. EOF) BREAK CALL HANDLE(CHAR) ] .FILL .JUSTIFY \\^IF THE ^^BREAK\\ APPEARS WITHIN NESTED ^^RATFOR\\ LOOPS, ONLY THE INNERMOST LOOP IS BROKEN. .PARAGRAPH ^A DIFFERENT FORM OF THE ^^BREAK\\ STATEMENT LOOKS LIKE THIS: .BLANK ^^BREAK GROUP\\ .BLANK ^THIS DOES NOT BREAK LOOPS, BUT INSTEAD BREAKS BRACKETTED STATEMENT GROUPS. ^IT MUST ALWAYS APPEAR WITHIN A GROUP OF STATEMENTS ENCLOSED BY [ AND ]. ^WHEN EXECUTED, CONTROL GOES TO THE PLACE IMMEDIATELY BEFORE THE ], WHICH MEANS THAT THE REMAINING STATEMENTS IN THE GROUP ARE SKIPPED. ^LIKE ^^BREAK\\, ^^BREAK GROUP\\ AFFECTS ONLY THE INNERMOST GROUP. ^AN EXAMPLE OF ^^BREAK GROUP\\ USE IS GIVEN IN SECTION 2.6. .INDEX ^^BREAK GROUP\\ .TEST PAGE 6 .SKIP 2 .HL 2 ^^NEXT\\ .NOFILL .NOJUSTIFY .SKIP ^FORM: ^^NEXT\\ .FILL .JUSTIFY ^LIKE THE ^^BREAK\\, THE ^^NEXT\\ STATEMENT ALWAYS APPEARS WITHIN A ^^RATFOR\\ LOOP. ^IT CAUSES THE REMAINDER OF THE INNERMOST LOOP TO BE SKIPPED, AND GOES TO THE NEXT ITERATION OF THIS LOOP. ^TO BE SPECIFIC, ^^NEXT\\ GOES TO: .NOFILL .NOJUSTIFY .SKIP 1)##THE START OF A ^D^O OR BARE ^^REPEAT,\\ 2)##THE TEST EXPRESSION OF AN ^^UNTIL \O\R WHILE,\\ 3)##THE RE-INITIALIZE OF A ^^FOR\\. .FILL .JUSTIFY .TEST PAGE 4 .SKIP 2 .HL 2 ^N\\ESTING .INDEX ^N\\ESTING .PARAGRAPH ^THIS IMPLEMENTATION OF ^^RATFOR\\ ALLOWS ^^RATFOR\\ STATEMENTS TO BE NESTED TO A MAXIMUM DEPTH OF 50. ^FOR EXAMPLE, THESE ^^FOR\\ STATEMENTS ARE NESTED TO A DEPTH OF TWO, AND THE ^^IF-ELSE\\ BRINGS THE TOTAL NESTING DEPTH TO FOUR: .NOFILL .NOJUSTIFY .TEST PAGE 6 ^^FOR(I=1; I .LE. N; I=I+1) FOR(J=1; J .LE. M; J=J+1) IF( I .EQ. J) MATRIX(I,J)=1 ELSE MATRIX(I,J)=0 .FILL .JUSTIFY \\^NOTICE THAT THERE ARE NO BRACKETS GROUPING THE INNER ^^FOR \O\R \T\H\E IF-ELSE. \\^SINCE THE ^^FOR\\ STATEMENTS EACH CONTROL ONLY ONE ^^RATFOR\\ STATEMENT, THESE GROUPING BRACKETS ARE OPTIONAL. ^THEY COULD BE INCLUDED, IF DESIRED. ^HOWEVER, THE LESS BRACKETS THERE ARE IN A LISTING, THE EASIER IT IS TO READ. ^LET INDENTING SHOW THE FLOW OF THE PROGRAM TO A READER; THE BRACKETS ARE FOR THE COMPUTER. ^OFTEN A LOOP WILL CONSIST OF AN ^^IF\\ OR ^^IF-ELSE\\ LIKE THE ABOVE ^^FOR\\; THE BRACKETS ARE UNNEEDED IN THIS CASE. ^THE RULE IS:##A ^^RATFOR\\ STATEMENT CONTROLS THE IMMEDIATELY FOLLOWING STATEMENT AND ANY STATEMENTS CONTROLLED BY THIS FOLLOWING STATEMENT. .BLANK 2 .TEST PAGE 5 .SKIP 4 .HL 1 ^^COSMETICS .INDEX ^C\\OSMETICS .TEST PAGE 6 .SKIP 2 .HL 2 ^C\\ONTINUATION AND ^STATEMENT ^FORMAT .INDEX ^C\\ONTINUATION AND ^STATEMENT ^FORMAT .PARAGRAPH ^^RATFOR\\ STATEMENTS CAN APPEAR ANYWHERE ON THE LINE. ^IF A STATEMENT HAS A LABEL, IT IS PLACED JUST BEFORE THE BEGINNING OF THE STATEMENT AND IS FOLLOWED BY AT LEAST ONE BLANK OR TAB. ^WE CAN PLACE A TAB IN FRONT OF ALL UNLABELLED STATEMENTS, IF WE WANT. .PARAGRAPH ^^RATFOR\\ CONTINUATION CONVENTIONS ARE DIFFERENT FROM ^^FORTRAN\\'S. ^ANY LINE ENDING IN A ",", "_&", OR "!" IS AUTOMATICALLY CONTINUED. ^SINCE CONTINUED STATEMENTS ARE USUALLY EITHER LISTS OF THINGS SEPARATED BY COMMAS (E.G. ^^FORMAT\\) OR LONG LOGICAL EXPRESSIONS, THE AUTOMATIC CONTINUATION IS OFTEN ENOUGH. ^ALSO, ANY LINE ENDING IN AN UNDERSCORE ('__') IS CONTINUED WITH THE UNDERSCORE REMOVED. (^NOTICE THAT THE UNDERSCORE PRINTS AS A BACK ARROW.) ^THERE IS NO LIMIT TO THE NUMBER OF CONTINUATIONS, BUT THE ^^FORTRAN\\ COMPILER MAY FAIL IF A LOT OF ^^FORTRAN\\ CONTINUATIONS RESULT FROM A LONG ^^RATFOR\\ STATEMENT. .TEST PAGE 4 .SKIP 2 .HL 2 ^C\\OMMENTS .INDEX ^C\\OMMENTS .PARAGRAPH ^^RATFOR\\ USES THE NUMBER SIGN ("_#") TO INDICATE COMMENTS. ^IF A _# IS FOUND ANYWHERE ON THE LINE, INCLUDING THE START, THE REST OF THAT LINE IS IGNORED. ^THE ^^FORTRAN\\ ^C COMMENT CONVENTION IS ^^NOT\\ USED SINCE ^^RATFOR\\ STATEMENTS CAN START IN THE FIRST COLUMN OF THE LINE. ^ALSO, THE "!" IS USED AS A SHORTFORM FOR ".^O^R." IN ^^RATFOR\\. .PARAGRAPH ^IF A LINE CONTAINING A _# IS TO BE CONTINUED, PRETEND THAT THE _# COMMENT IS NOT THERE WHEN SETTING UP THE CONTINUATION. ^FOR EXAMPLE, THE COMMAS IN THE FOLLOWING ^^INTEGER\\ STATEMENT PROVIDE AUTOMATIC CONTINUATION AS DISCUSSED IN SECTION 2.1: .NOFILL .NOJUSTIFY ^^INTEGER SUM, _#THE SUM OF THE VARIABLES SMALL, _#THE SMALLEST MEMBER AVERAG _#INTEGER VERSION OF AVERAGE OF INPUT .FILL .JUSTIFY .PARAGRAPH .TEST PAGE 5 .SKIP 2 .HL 2 \\^SEMI-^COLONS AND ^NULL ^STATEMENTS .INDEX ^S\\EMI-COLONS AND ^NULL ^STATEMENTS .PARAGRAPH ^^RATFOR\\ ALLOWS MANY STATEMENTS TO BE ON ONE LINE IF THEY ARE SEPARATED BY SEMI-COLONS. ^FOR EXAMPLE: .NOFILL .NOJUSTIFY .TEST PAGE 3 ^^IF(SWITCH) [ TEMP=VEC(I); VEC(I) = VEC(J); VEC(J) = TEMP ] .FILL .JUSTIFY .PARAGRAPH \\^ANY STATEMENT STARTING WITH A SEMI-COLON IS A NULL STATEMENT AND PRODUCES NO ^^FORTRAN\\ CODE. ^THE NULL STATEMENT CAN BE USED AS THE BODY OF A LOOP WHEN ALL THE WORK REQUIRED OF THE LOOP IS DONE IN THE CONTROLLING ^^RATFOR\\ STATEMENT. ^FOR EXAMPLE, THIS ^^FOR\\ ADVANCES ^I TO THE FIRST NON-BLANK CHARACTER IN ^^TEXT: .NOFILL .NOJUSTIFY .TEST PAGE 2 ^^FOR(I=1; TEXT(I) .EQ. ' '; I=I+1) ; .FILL .JUSTIFY \\^THE NULL STATEMENT CAN ALSO BE WRITTEN AS []. .TEST PAGE 6 .SKIP 2 .HL 2 ^S\\HORTFORMS .INDEX ^S\\HORTFORMS .PARAGRAPH ^^RATFOR\\ PERMITS THE FOLLOWING ABBREVIATIONS FOR ^^FORTRAN\\ LOGICAL OPERATORS: .NOFILL .NOJUSTIFY .TEST PAGE 10 << .^^LT. == .EQ. >> .GT. >= \O\R => .GE. <= \O\R =< .LE. <> \O\R >< .NE. ~= \O\R _^= .NE. _& .AND. ! .OR. | .OR. _^ .NOT. ~ .NOT. .FILL .JUSTIFY \\^THE TRANSLATION TO THE REGULAR ^^FORTRAN\\ LOGICAL OPERATORS DOES NOT OCCUR IN QUOTE-TYPE ^HOLLERITH CONSTANTS. .TEST PAGE 9 .SKIP 2 .HL 2 ^^DEFINE\\ .INDEX ^^DEFINE\\ .PARAGRAPH .NOFILL .NOJUSTIFY ^FORM: ^^DEFINE\\ NAME CHARACTERS .FILL .JUSTIFY .PARAGRAPH \\^THE NAME CAN BE ANY STRING OF LETTERS OR DIGITS WITH BLANKS OR TABS ON BOTH SIDES. ^FROM HERE ON IN THE PROGRAM, WHEREVER NAME OCCURS IN THE PROGRAM, IT IS REPLACED BY THE CHARACTERS. ^THESE CHARACTERS CAN BE ANY STRING OF CHARACTERS NOT INCLUDING A BLANK OR TAB. ^THE CHARACTERS ARE TERMINATED BY THE FIRST BLANK OR TAB, OR BY THE END OF THE LINE. ^ALTERNATIVELY, THE CHARACTERS CAN BE A ^HOLLERITH CONSTANT WHICH MAY INCLUDE BLANKS OR TABS. ^THEN THE ^HOLLERITH CONSTANT REPLACES 'NAME' WHEREVER 'NAME' APPEARS. ^TWO THINGS SHOULD BE NOTED: THE ^^DEFINE\\ STATEMENT IS NOT PUT IN THE ^^FORTRAN\\ OUTPUT, AND THE ^^DEFINE\\ STATEMENT MAY NOT BE CONTINUED. ^WHEN THE DEFINED NAME APPEARS IN THE PROGRAM, IT MUST BE SURROUNDED BY BLANKS OR OTHER NON-ALPHANUMERICS TO BE RECOGNIZED. ^DEFINITIONS ARE REMEMBERED ACROSS SUBPROGRAMS. .PARAGRAPH ^THERE IS NO LIMIT TO THE LENGTH OF NAME OR CHARACTERS, EXCEPT THAT THE ENTIRE ^^DEFINE\\ STATEMENT MUST FIT ON ONE LINE. ^^RATFOR\\ LIMITS THE TOTAL NUMBER OF DEFINE\\D NAMES TO 257. ^THE TOTAL LENGTH OF ALL DEFINE\\D NAMES AND REPLACEMENT TEXT CANNOT EXCEED 2048 CHARACTERS. .PARAGRAPH ^THE FOLLOWING EXAMPLES ILLUSTRATE SOME COMMON USES OF ^^DEFINE\\: .NOFILL .NOJUSTIFY .TEST PAGE 11 ^^DEFINE NEWLINE "012 DEFINE BLANK ' ' DEFINE CHARACTER LOGICAL*1 DEFINE MAXINPUT 100 . . . CHARACTER INP(MAXINPUT) CALL READER(INP) FOR(I=1; I<=MAXINPUT _& INP(I)<>BLANK _& INP(I)<>NEWLINE; I=I+1) ; .TEST PAGE 6 \\WOULD BE TRANSLATED AS IF IT WERE WRITTEN:^^ LOGICAL*1 INP(100) CALL READER(INP) FOR(I=1; I<=100 _& INP(I)<>' ' _& INP(I)<>"012; I=I+1) ; .FILL .JUSTIFY \\^DEFINE\\D NAMES HAVE BEEN USED TO HIDE THE REPRESENTATION OF A "NEW LINE" AND THE MAXIMUM SIZE (DIMENSION) OF THE VECTOR ^^INP\\. ^THIS MAKES IT EASIER TO CHANGE THESE VALUES, AND EASIER TO UNDERSTAND THE PROGRAM. .PARAGRAPH ^IF THE CHARACTERS IN THE ^^DEFINE\\ TEXT THEMSELVES CONTAIN A DEFINED NAME, IT TOO IS REPLACED. ^FOR EXAMPLE, THE ABOVE DEFINITION OF ^^NEWLINE\\ COULD HAVE BEEN WRITTEN AS:^^ .NOFILL .NOJUSTIFY .TEST PAGE 2 DEFINE NEWLINE LF DEFINE LF "012 .FILL .JUSTIFY \\^IT DOES NOT MATTER IN WHAT ORDER THE DEFINITIONS APPEAR; THE REPLACEMENT OCCURS WHEN ^^NEWLINE\\ IS USED, NOT WHEN IT IS DEFINE\\D. .PARAGRAPH ^AS PROMISED ABOVE, HERE IS A WAY TO USE KEYWORDS INSTEAD OF BRACKETS FOR GROUPING STATEMENTS:^^ .NOFILL .NOJUSTIFY .TEST PAGE 8 DEFINE START [ DEFINE FINISH ] IF(A >> B) START CALL PARTA CALL PARTAA FINISH ELSE START CALL PARTB CALL PARTBB FINISH .FILL .JUSTIFY \\^OF COURSE, WE CANNOT DEFINE\\ ^^END\\, SINCE IT HAS OTHER PURPOSES IN ^^FORTRAN\\. .TEST PAGE 5 .SKIP 2 .HL 2 ^^DEFINELIST\\ .INDEX ^^DEFINELIST\\ .SKIP .NOFILL .NOJUSTIFY ^FORM: ^^DEFINELIST\\ INTEGER NAME1 NAME2 NAME3 NAME4 NAME5 ... .FILL .JUSTIFY .BLANK ^THE INTEGER MUST BE GREATER THAN 0 AND LESS THAN 30000. ^THE NAMES ARE SEPARATED BY BLANKS OR TABS. ^THE ^^DEFINELIST\\ STATEMENT MAY BE CONTINUED WITH THE UNDERSCORE. ^THE ACTION OF THE STATEMENT IS THIS: ^THE FIRST NAME IS DEFINED AS THE INTEGER, THE SECOND AS THE INTEGER PLUS ONE, AND SO ON. ^FOR EXAMPLE: .NOFILL .NOJUSTIFY ^^DEFINELIST 1000 ALPHA BETA GAMMA DELTA .BLANK \\IS A SHORTFORM FOR THIS SET OF DEFINES: .BLANK .TEST PAGE 4 ^^DEFINE ALPHA 1000 DEFINE BETA 1001 DEFINE GAMMA 1002 DEFINE DELTA 1003 .FILL .JUSTIFY .PARAGRAPH \\^THE INTEGER PART OF THIS STATEMENT ALLOWS THE PROGRAMMER TO CONTROL WHERE THE DEFINITIONS START. ^IF THE SAME NAMES ARE USED IN SEPARATELY COMPILED SUBPROGRAMS, THIS CAN BE USED TO MAKE SURE THAT THE NAMES ARE DEFINED TO THE SAME VALUE. .PARAGRAPH ^WHY PROVIDE A ^^DEFINELIST\\ STATEMENT?##^THE ANSWER TO THIS QUESTION IS BEST GIVEN BY AN EXAMPLE, AND WHAT BETTER EXAMPLE THAN THE ^^RATFOR\\ PROCESSOR PROGRAM ITSELF. ^INSIDE THIS PROGRAM, SPECIAL CHARACTERS LIKE [ AND ], AND KEYWORDS LIKE ^^IF\\, ARE ENCODED AS INTEGERS. ^FOR EXAMPLE, IF ^^STATYP\\ IS THE INTEGER ENCODING OF THE THING WE ARE NOW EXAMINING, WE CAN SEE IF IT IS AN ^^IF\\ STATEMENT AS FOLLOWS: .BLANK .NOFILL .NOJUSTIFY .TEST PAGE 2 ^^IF(STATYP .EQ. 7)\\ HANDLE IF, ETC. .FILL .JUSTIFY .BLANK ^ENCODING THINGS AS INTEGERS LIKE THIS COULD CAUSE PROBLEMS. ^IT LEADS TO MISTAKES (AND DID SEVERAL TIMES DURING ^^RATFOR\\'S DEBUGGING), AND MAKES THE PROGRAM HARD TO READ. ^WITH ^^DEFINELIST\\, WE CAN WRITE: .BLANK .NOFILL .NOJUSTIFY .TEST PAGE 2 ^^DEFINELIST 1000 LBRACK RBRACK SEMICOL EOF LEXIF LEXELSE __ LEXWHILE LEXREPEAT LEXUNTIL LEXFOR LEXDO\\ ETC. .BLANK ^NOW, WE CAN WRITE: .BLANK .TEST PAGE 5 ^^IF( STATYP .EQ. LEXIF ) \\SOMETHING ^^ELSE IF (STATYP .EQ. LEXELSE)\\ SOMETHING ELSE ^^ELSE\\ ETC. .FILL .JUSTIFY .PARAGRAPH ^SINCE THE NAMES IN THE ^^DEFINELIST\\ ARE ASSIGNED ORDERED VALUES, WE CAN WRITE: .NOFILL .NOJUSTIFY .BLANK .TEST PAGE 2 ^^IF(STATYP .GT. EOF)\\ HANDLE IF, ELSE, ETC. .FILL .JUSTIFY .BLANK ^THIS SHOULD BE USED WITH CARE, SINCE IT CAN OBSCURE THE WORKINGS OF A PROGRAM. .PARAGRAPH ^THE ^^DEFINELIST\\ AND COMPUTED ^^GOTO\\ CAN BE USED AS A ^^CASE\\ STATEMENT: .NOFILL .NOJUSTIFY .TEST PAGE 15 ^^DEFINE CASE GOTO IF( STATYP .GT. EOF ) [ CASE(LEXIF, LEXELSE, LEXWHILE, \E\T\C.), STATYP-EOF [ LEXIF CALL DOIF BREAK GROUP LEXELSE IF(\\ EVERYTHING ^O^K)^^ CALL DOELSE ELSE CALL ERROR BREAK GROUP \E\T\C. ] ] .BLANK .FILL .JUSTIFY \\^HOW DOES THIS WORK?##^SINCE ^^LEXIF\\ ETC. ARE DEFINED AS INTEGERS, THEY CAN BE USED AS STATEMENT NUMBERS TOO. ^THE COMPUTED ^^GOTO\\ INDEX MUST START AT 1, SO FIRST WE SUBTRACT ^^EOF. T\\HE ^^BREAK GROUP\\ STATEMENT IS USED TO SEPARATE THE DIFFERENT CASES, SO THE ENTIRE BLOCK, CONTROLLED BY ^^GOTO\\, MUST BE GROUPED WITH BRACKETS. .PARAGRAPH ^WHENEVER ^^RATFOR\\ SEES A STATEMENT CONSISTING ONLY OF A STATEMENT NUMBER, IT ATTACHES THE STATEMENT NUMBER TO A ^^CONTINUE\\. ^SO, WE CAN COMBINE CASES JUST BY WRITING THE CASE NAMES ON SEPARATE LINES. ^FOR EXAMPLE, IN THE ABOVE ^^CASE\\, WE MIGHT USE SOMETHING LIKE THIS: .BLANK .NOFILL .NOJUSTIFY .TEST PAGE 4 ^^LEXREPEAT LEXUNTIL \\SOMETHING COMMON TO ^^REPEAT \A\N\D UNTIL BREAK GROUP\\ .BLANK ^ANOTHER WAY TO DO THIS IS TO PUT SEMI-COLONS AFTER EACH CASE NAME: .BLANK .TEST PAGE 3 ^^LEXREPEAT; LEXUNTIL\\ SOMETHING COMMON TO ^^REPEAT \A\N\D ^^UNTIL\\ ^^BREAK GROUP\\ .BLANK .FILL .JUSTIFY ^SINCE ^^LEXIF\\ ETC.#ARE USED AS STATEMENT LABELS IN THIS CONTEXT, WE MUST BE CAREFUL NOT TO DUPLICATE THESE LABELS ELSEWHERE IN THE SAME SUBPROGRAM. .TEST PAGE 6 .SKIP 2 .HL 2 ^^INCLUDE\\ .INDEX ^^INCLUDE\\ .PARAGRAPH .NOFILL .NOJUSTIFY ^FORM: .BLANK ^^INCLUDE\\ FILENAME .BREAK ^^INCLUDE\\ FILENAME/^L .BLANK .FILL .JUSTIFY ^THE STATEMENTS IN FILE FILENAME ARE PLACED IN THE ^^FORTRAN\\ OUTPUT. ^THE DEFAULT EXTENSION FOR FILENAME IS ^^".RAT\\". ^THE ^^FORTRAN IV-PLUS\\ COMPILER ALSO PROVIDES AN ^^INCLUDE\\ STATEMENT, BUT IT DEMANDS QUOTES AROUND THE FILENAME AND DOES NOT SUPPORT DEFAULT EXTENSIONS FOR THE FILENAME. ^IF A LISTING OF THE INCLUDED FILE IS REQUIRED, THE SECOND FORM OF THE ^^INCLUDE\\ STATEMENT IS USED. ^THE /^L SWITCH ON THE FILENAME CAUSES THE FILE TO BE LISTED. .PARAGRAPH ^IF ^^RATFOR\\ IS UNABLE TO OPEN FILENAME, IT PUTS "[1,1]" IN FRONT OF THE GIVEN FILENAME AND TRIES TO OPEN THIS NEW FILENAME. ^THIS ALLOWS A LIBRARY OF ^^INCLUDE\\ FILES; SUCH FILES COULD CONTAIN ^^DEFINE\\ STATEMENTS FOR STANDARD NAMES. .PARAGRAPH ^^INCLUDE\\ IS OFTEN USED TO COPY A FILE CONTAINING A ^^COMMON\\ BLOCK DEFINITION. ^WE CAN SET UP SUCH A FILE WITH LOTS OF COMMENTS LIKE THIS: .BLANK .NOFILL .NOJUSTIFY .TEST PAGE 5 ^^INTEGER NAMES(257), LENGTH(257) LOGICAL*1 TEXT(2048) COMMON /TABLES/ NAMES, _#HASH TABLE POINTERS LENGTH, _#LENGTH OF DEFINED NAMES TEXT _#HOLDS DEFINED NAMES AND TEXT .BLANK .FILL .JUSTIFY \\(^NOTE THE USE OF COMMAS FOR AUTOMATIC CONTINUATION.) ^NOW IF THIS FILE WAS NEEDED IN A SUBPROGRAM, ALL WE NEED SAY IS: .BLANK ^^INCLUDE TABLES\\ .BLANK WHERE ^^TABLES.RAT\\ IS THE FILE NAME. ^IN ADDITION, ^^RATFOR\\ WILL NOT CLUTTER UP THE LISTING OF THIS SUBPROGRAM WITH THESE STATEMENTS. .PARAGRAPH .TEST PAGE 2 ^ALL ^^RATFOR\\ STATEMENTS IN THE INCLUDED FILE ARE PROCESSED. ^YOU CAN USE AN INCLUDED FILE OF ^^DEFINE\\ STATEMENTS, FOR INSTANCE. .PARAGRAPH .TEST PAGE 2 ^^INCLUDE\\ STATEMENTS MAY BE NESTED TO A MAXIMUM DEPTH OF TWO. ^AN ^^INCLUDE\\ MAY APPEAR IN AN INCLUDED FILE, BUT THAT IS AS FAR AS IT CAN GO. .TEST PAGE 6 .SKIP 2 .HL 2 ^L\\OGICAL ^OPERATORS _&_& AND !! .INDEX ^L\\OGICAL OPERATORS _&_& AND !! .PARAGRAPH ^THE OPERATORS _&_& AND !! ARE CLOSELY RELATED TO _& (.^^AND\\.) AND ! (.^O^R.). ^THEY CAN BE USED IN ANY ^^RATFOR\\ STATEMENT THAT NEEDS A LOGICAL EXPRESSION (I.E. ^^IF, WHILE, FOR, UNTIL). T\\HE IMPORTANT THING ABOUT _&_& AND !! IS THAT THEY ALLOW US TO CONTROL THE ORDER IN WHICH A LOGICAL EXPRESSION IS EVALUATED. ^FOR EXAMPLE, SUPPOSE WE WANTED TO SEARCH A VECTOR ^^VEC\\ OF 10 ELEMENTS FOR THE FIRST NON-ZERO ELEMENT. ^A FIRST ATTEMPT AT A SOLUTION MIGHT BE: .BLANK .NOFILL .NOJUSTIFY .TEST PAGE 2 ^^FOR( I=1; I<=10 _& VEC(I)<>0; I=I+1)\\ ; .BLANK .FILL .JUSTIFY ^THIS WILL NOT WORK. ^^FORTRAN\\ MAY ALLOW THE SUBEXPRESSION ^^VEC(I)<>0\\ TO BE EVALUATED WHEN ^I IS GREATER THAN 10. ^THIS WOULD LEAD TO A REFERENCE OUT OF THE BOUNDS OF ^^VEC\\. ^IN ^^RATFOR\\ WE CAN USE _&_& INSTEAD OF _&, AND THEN THE PART ^I<=10 WILL ALWAYS BE DONE BEFORE ^^VEC(I)<>0\\; FURTHERMORE, THE SUBEXPRESSION ^^VEC(I)<>0\\ IS EVALUATED ONLY IF ^I<=10 IS TRUE. ^TO BE PRECISE, WHEN _&_& USED, THE LEFT SUBEXPRESSION IS EVALUATED FIRST, AND THE RIGHT SUBEXPRESSION IS EVALUATED ONLY WHEN THE LEFT SUBEXPRESSION IS TRUE. ^A CORRECT SOLUTION TO THE PROBLEM IS: .BLANK .TEST PAGE 2 .NOFILL .NOJUSTIFY ^^FOR(I=1; I<=10 _&_& VEC(I)<>0; I=I+1) ; .FILL .JUSTIFY .PARAGRAPH \\^SIMILARLY, !! GIVES US CONTROL OVER THE ORDER IN WHICH TWO LOGICAL EXPRESSIONS ARE ^O^RED. ^A WORDIER SOLUTION TO THE ABOVE PROBLEM IS: .BLANK .NOFILL .NOJUSTIFY .TEST PAGE 5 ^^REPEAT [ IF(I >> 10 !! VEC(I) <> 0) BREAK I=I+1 ] .FILL .JUSTIFY .PARAGRAPH \\^TO BE PRECISE, WHEN !! IS USED, THE LEFT SUBEXPRESSION IS EVALUATED AND, IF TRUE, THE REMAINDER OF THE EXPRESSION IS SKIPPED. ^OTHERWISE, THE RIGHT SUBEXPRESSION IS DONE. .PARAGRAPH ^AN EXPRESSION IS ALLOWED TO CONTAIN ANY NUMBER OF _&_& AND !! SYMBOL PAIRS. ^IF THERE ARE SEVERAL, THE EXPRESSION IS EVALUATED STRICTLY FROM LEFT TO RIGHT. ^FOR EXAMPLE: .BLANK .TEST PAGE 7 .NOFILL .NOJUSTIFY ^^A >> B _&_& C << D !! E <> F\\ .BLANK IS EVALUATED LIKE THIS: .BLANK 1)## IF ^A <= ^B NO MORE IS DONE AND THE EXPRESSION IS FALSE, 2)## ELSE, IF ^C << ^D NO MORE IS DONE AND THE EXPRESSION IS TRUE, 3)## ELSE, THE VALUE OF THE EXPRESSION IS ^E <> ^F. .BLANK .TEST PAGE 9 ^ON THE OTHER HAND, .BLANK ^^ E <> F !! C << D _&_& A >> B .BLANK \\IS EVALUATED LIKE THIS: .BLANK 1)## ^IF ^E <> ^F, THE EXPRESSION IS TRUE AND NO MORE IS DONE, 2)## ELSE IF ^C >= ^D, NO MORE IS DONE AND THE EXPRESSION IS FALSE, 3)## ELSE THE VALUE OF THE EXPRESSION IS THE VALUE OF ^A >> ^B. .FILL .JUSTIFY .PARAGRAPH ^THE OPERATORS _&_& AND !! CANNOT APPEAR WITHIN PARENTHESES (EXCEPT FOR THE OUTERMOST PARENTHESES ENCLOSING THE EXPRESSION). ^THE CHARACTER PAIR || CAN BE USED FOR !!. .TEST PAGE 7 .SKIP 2 .HL 2 ^^RETURN\\ .INDEX ^^RETURN\\ .SKIP .NOFILL .NOJUSTIFY ^FORM: .BLANK 1 ^^RETURN\\( EXPRESSION ) .BLANK 1 .FILL .JUSTIFY .TEST PAGE 2 ^THIS SPECIAL RETURN STATEMENT IS USED IN FUNCTION SUBPROGRAMS. ^WHEN ^^RATFOR\\ FINDS A FUNCTION STATEMENT, IT REMEMBERS THE FUNCTION NAME. ^A ^^RETURN\\ STATEMENT LIKE THIS APPEARING IN A FUNCTION CAUSES THIS ^^FORTRAN\\ CODE TO BE PRODUCED: .BLANK 1 .TEST PAGE 2 FUNCTION NAME = (EXPRESSION) .BREAK ^^RETURN\\ .BLANK 1 .PARAGRAPH ^THE ^^RATFOR\\ ^^RETURN\\ STATEMENT MAKES IT SIMPLER TO SEE WHAT A FUNCTION IS RETURNING. ^FOR EXAMPLE, HERE IS A LOGICAL FUNCTION ^^SEARCH\\ WHICH RETURNS TRUE IFF THE INTEGER ^^INT\\ IS IN THE VECTOR ^^VEC\\ (WHICH HAS ^N ELEMENTS): .BLANK 1 .TEST PAGE 7 .NOFILL .NOJUSTIFY ^^LOGICAL FUNCTION SEARCH(VEC,N,INT) INTEGER VEC(N),N,INT FOR(I=1; I<=N; I=I+1) IF(VEC(I) == INT) RETURN(.TRUE.) RETURN(.FALSE.) END .FILL .JUSTIFY .PARAGRAPH \\^^RATFOR\\ WILL ONLY RECOGNIZE THE ^^FUNCTION\\ STATEMENT IF THE WORD ^^FUNCTION\\ IS SURROUNDED BY BLANKS OR TABS. ^ALSO, A ^^FUNCTION\\ STATEMENT MUST BE THE FIRST NON-^^RATFOR\\ STATEMENT IN A SOURCE FILE, OR THE FIRST NON-^^RATFOR\\ STATEMENT AFTER AN ^^END\\ STATEMENT. ^THIS FORM OF THE ^^RETURN\\ SHOULD ONLY BE USED IN FUNCTION SUBPROGRAMS. ^OF COURSE, WE CAN STILL USE THE NORMAL ^^RETURN\\ STATEMENT ANYWHERE. .TEST PAGE 16 .SKIP 2 .HL 1 ^R\\UNNING ^^RATFOR\\ .INDEX ^R\\UNNING ^^RATFOR\\ .TEST PAGE 6 .SKIP 2 .HL 2 ^C\\OMMAND ^LINE .INDEX ^C\\OMMAND ^LINE .PARAGRAPH ^THE ^^MCR\\ LINE FOR ^^RATFOR\\ TAKES ONE OF THESE FOUR FORMS: .NOFILL .NOJUSTIFY .BLANK 1)##^^OUTPUT,LIST=INPUT1,INPUT2,... 2)##OUTPUT=INPUT1,INPUT2,... 3)##,LIST=INPUT1,INPUT2,... 4)##=INPUT1,INPUT2,... .BLANK .FILL .JUSTIFY .PARAGRAPH \\^THE ^^FORTRAN\\ OUTPUT IS WRITTEN INTO FILE ^^OUTPUT\\, IF THIS FILE NAME IS PRESENT. ^IF IT IS NOT, NO ^^FORTRAN\\ OUTPUT IS PRODUCED. ^AFTER EACH ^^FORTRAN\\ STATEMENT, ^^RATFOR\\ PLACES A "!" (FOR COMMENTING) AND THE NUMBER OF THE ^^RATFOR\\ STATEMENT WHICH PRODUCED THIS ^^FORTRAN\\ STATEMENT. ^THESE NUMBERS ARE USED TO CROSS-REFERENCE COMPILE-TIME ERROR MESSAGES PRODUCED BY THE ^^FORTRAN\\ COMPILER. ^ONCE THE TYPING ERRORS ARE OUT OF THE PROGRAM, THE ^^FORTRAN\\ COMPILER'S LISTING IS NO LONGER NEEDED. ^THE ^^RATFOR\\ LISTING SHOULD BE USED FOR DOCUMENTATION AND DEBUGGING. ^NOTE THAT THE LISTING FILE CANNOT BE AUTOMATICALLY SPOOLED. .PARAGRAPH ^THIS LISTING IS PLACED IN THE FILE ^^LIST\\ WHEN THIS FILE NAME IS PRESENT. ^EVERY ^^RATFOR\\ STATEMENT IS NUMBERED TWICE:##ONCE WITH A ^^RATFOR\\ NUMBER, AND ONCE WITH A ^^FORTRAN\\ NUMBER. ^THE ^^FORTRAN\\ NUMBER IS IN PARENTHESES. ^IT IS THE NUMBER OF THE FIRST ^^FORTRAN\\ STATEMENT PRODUCED BY THIS ^^RATFOR\\ STATEMENT. ^WHAT USE IS THIS?## ^IT ALLOWS US TO USE THE ^^FORTRAN\\ COMPILER'S DEBUGGING SWITCHES LIKE /^^TR\\ AND /^C^K IN THE ^^FORTRAN\\ COMPILE. ^IF EXECUTION-TIME ERRORS OCCUR, THE CLEAN ^^RATFOR\\ LISTING CAN BE CONSULTED TO FIND THE BAD STATEMENT. ^SOMETIMES, THE NUMBER OF THE BAD STATEMENT MIGHT NOT APPEAR ON THE ^^RATFOR\\ LISTING; FOR EXAMPLE, WE MAY GET AN EXECUTION-TIME ERROR IN STATEMENT 14, AND LOOK AT THE ^^RATFOR\\ LISTING ONLY TO FIND: .BLANK .NOFILL .NOJUSTIFY .TEST PAGE 2 (12) ^^ELSE IF (VEC(I) >> 0) [ (15) CALL PROCES(VEC(I)) .BLANK .FILL .JUSTIFY \\^THERE IS NO 14. ^THE REASON IS THAT ^^ELSE\\ HAS PRODUCED 3 STATEMENTS, AND NUMBER 14 IS ONE OF THEM. ^SO THE ERROR IS IN THE ^^ELSE IF\\. .PARAGRAPH ^IF THE FOURTH FORM OF THE COMMAND LINE IS USED, ^^RATFOR\\ LISTS ALL ^^RATFOR\\ ERROR MESSAGES AND THE BAD ^^RATFOR\\ STATEMENTS ON THE TERMINAL. ^WHEN MANY INPUT FILES ARE USED, THEY ARE EFFECTIVELY CONCATENATED. .PARAGRAPH ^WE CAN TYPE IN THE ^^RATFOR\\ COMMAND LINE LIKE THIS: .BREAK ^^MCR>RAT\\###COMMAND LINE .BREAK ^^RATFOR\\ EXECUTES THE COMMAND LINE AND QUITS. ^ANOTHER POSSIBLITY IS TO TYPE JUST "^^RAT\\" TO ^^MCR. R\\ATFOR WILL PROMPT FOR A COMMAND LINE, EXECUTE IT, AND PROMPT AGAIN. ^WHEN ITS PROMPT IS ANSWERED BY A _^^Z, ^^RATFOR\\ QUITS. ^^RATFOR\\ ALLOWS ONE LEVEL OF INDIRECT COMMMAND FILE. .PARAGRAPH ^THE DEFAULT EXTENSIONS ARE:##.^F^T^N FOR THE OUTPUT FILE, .^L^S^T FOR THE ^^RATFOR\\ LISTING, .^R^A^T FOR THE INPUT FILE, AND .^^CMD\\ FOR THE COMMAND FILE. .TEST PAGE 6 .SKIP 2 .HL 2 ^H\\INTS AND ^CAVEATS .INDEX ^H\\INTS AND ^CAVEATS .PARAGRAPH ^IN ^^RATFOR\\, THE KEYWORDS ^^IF, ELSE, REPEAT, UNTIL, DO, FOR, WHILE, NEXT, \A\N\D BREAK\\ ARE RESERVED WORDS AND SHOULD NOT BE USED AS IDENTIFIERS. ^THE KEYWORDS MUST BE FOLLOWED BY A BLANK, TAB, '(', OR SOME OTHER SPECIAL CHARACTER TO BE RECOGNIZED. ^^RATFOR\\ DOES NOT CARE ABOUT THE CASE OF KEYWORDS; WE CAN WRITE ^^REPEAT\\, REPEAT, OR EVEN ^REA^PE^AT. ^THE SAME APPLIES TO NAMES APPEARING IN ^^DEFINE\\ STATEMENTS. ^ALSO, ^^RATFOR\\ TRANSLATES ANY LOWER CASE LETTERS, OUTSIDE OF QUOTE-TYPE ^HOLLERITHS, TO UPPER CASE SO WE CAN WRITE ^^FORTRAN\\ STATEMENTS IN LOWER CASE TOO. .PARAGRAPH ^^RATFOR\\ RECOGNIZES ONLY QUOTE-TYPE ^HOLLERITHS. ^H OR ^R TYPE ^HOLLERITHS MAY BE USED, BUT ANY SHORTFORMS LIKE == OR ! APPEARING IN THEM WILL BE TRANSLATED. ^ALSO, QUOTE-TYPE ^HOLLERITHS ARE LIMITED TO 100 CHARACTERS, AND MAY NOT EXTEND ACROSS A LINE BOUNDARY (EVEN IF THE LINE IS CONTINUED). .PARAGRAPH ^THERE IS NO ARITHMETIC ^I^F IN ^^RATFOR\\ (GOOD RIDDANCE!) .PARAGRAPH ^^RATFOR\\ USES ^^FORTRAN\\ LABELS IN THE RANGE 23000 THROUGH 23999, SO THESE SHOULD BE AVOIDED IN THE USER'S PROGRAM. .PARAGRAPH ^^RATFOR\\ SILENTLY TRUNCATES ANY INPUT LINES LONGER THAN 100 CHARACTERS. ^ALL BLANK OR EMPTY LINES ARE IGNORED BY ^^RATFOR\\; HENCE WHITE SPACE MAY BE USED FREELY TO EMPHASIZE LOOPS AND TO SEPARATE DECLARATIONS. .PARAGRAPH ^IT IS DIFFICULT TO TOTALLY ELIMINATE THE ^^GOTO\\. ^IT CAN BE USED IN CODE THAT HANDLES ERRONEOUS INPUT. ^SOMETIMES, THE ONLY THING THE CODE CAN DO, WHEN IT FINDS UNCORRECTABLE INPUT, IS TO ^^GOTO\\ SOME PLACE AT THE BOTTOM OF THE SUBPROGRAM FOR ERROR HANDLING. ^BY THE WAY, THESE ^^GOTO\\S ARE BY NO MEANS ALWAYS REQUIRED. ^OFTEN, AN ^^IF-ELSE\\ WITH A ^^RETURN\\ IN THE ERROR HANDLING PART WILL DO THE TRICK. ^ONLY WHEN THERE ARE SO MANY NESTED ^^IF-ELSE\\S, THAT THE CODE BECOMES UNWIELDY, MAY A ^^GOTO\\ BE NEEDED. .PARAGRAPH .TEST PAGE 12 .SKIP 4 .HL 1 ^^BUILDING ^RATFOR\\\\ .INDEX ^B\\UILDING ^^RATFOR\\ .PARAGRAPH ^^RATFOR\\ IS BUILT AND INSTALLED WITH THESE COMMANDS: .NOFILL .NOJUSTIFY .SKIP 1 ^^MCR>FLX =MM:RAT.FTN,MCRAT.FTN,RAT.CMD,RAT.ODL/DO MCR>F4P F4P>RAT=RAT F4P>MCRAT=MCRAT F4P>_^Z MCR>TKB @RAT [NOTE: RATFOR MAY BE BUILT FOR RSX11M BY EXCUTING RATMAK.CMD INSTEAD OF THE ABOVE PROCEDURE.] MCR>INS RAT .FILL .JUSTIFY .TEST PAGE 6 .SKIP 4 .HL 1 ^^EXAMPLE\\ .PARAGRAPH ^HERE IS A ^^RATFOR\\ PROGRAM WHICH COMPUTES THE FIRST TEN TWIN PRIMES. ^TWIN PRIMES ARE CONSECUTIVE ODD NUMBERS THAT ARE PRIME. ^NOTE THE HEAVY USE OF THE ^^FOR\\ STATEMENT IN THE PROGRAM; MANY LOOPS ARE NATURALLY EXPRESSED BY THE ^^FOR\\. .SKIP 2 .NOFILL .NOJUSTIFY .TESTPAGE 17 _# \\TWIN PRIME PRINTER ^^integer test,count,test2 logical prime write(5,1) 1 format(' List of First 10 Twin Primes' //) for (test=3; count<=10; test=test+2) if (prime(test) _& prime(test+2)) { test2=test+2 write(5,10) test,test2 10 format(5x,2i7) count=count+1 } call exit end .TEST PAGE 17 _# \\RETURN TRUE IFF N IS A PRIME INTEGER^^ logical function prime(n) integer n,factor if (n==2) return (.true.) else if (n<=1 || mod(n,2)==0) return (.false.) else { for (factor=3; factor*factor<=n; factor=factor+2) if (mod(n,factor)==0) return (.false.) return (.true.) } end .TEST PAGE 14 List of First 10 Twin Primes 3 5 5 7 11 13 17 19 29 31 41 43 59 61 71 73 101 103 107 109 137 139 .NUMBER 0 .PAGE .CENTER ^^A-RCB-0091-SP-1 .BLANK 1 .CENTER RATFOR .BLANK 1 .CENTER THE RATFOR PRE-PROCESSOR .BLANK 4 .NOFILL .NOJUSTIFY ##########^^INDEX\\ .SKIP .FILL .JUSTIFY .PRINT INDEX