BSD 3 development
[unix-history] / usr / doc / ratfor / m2
CommitLineData
8340f87c
BJ
1.NH
2LANGUAGE DESCRIPTION
3.SH
4Design
5.PP
6Ratfor
7attempts to retain the merits of Fortran
8(universality, portability, efficiency)
9while hiding the worst Fortran inadequacies.
10The language
11.ul
12is
13Fortran except for two aspects.
14First,
15since control flow is central to any program,
16regardless of the specific application,
17the primary task of
18Ratfor
19is to conceal this part of Fortran from the user,
20by providing decent control flow structures.
21These structures are sufficient and comfortable
22for structured programming in the narrow sense of programming without
23.UC GOTO 's.
24Second, since the preprocessor must examine an entire program
25to translate the control structure,
26it is possible at the same time to clean up many of the
27``cosmetic'' deficiencies of Fortran,
28and thus provide a language which is easier
29and more pleasant to read and write.
30.PP
31Beyond these two aspects _ control flow and cosmetics _
32Ratfor
33does nothing about the host of other weaknesses of Fortran.
34Although it would be straightforward to extend
35it
36to provide
37character strings,
38for example,
39they are not needed by everyone,
40and of course
41the preprocessor would be harder to implement.
42Throughout, the design principle which has determined
43what should be in
44Ratfor
45and what should not has
46been
47.ul
48Ratfor
49.ul
50doesn't know any Fortran.
51Any language feature which would require that
52Ratfor
53really understand Fortran has been omitted.
54We will return to this point in the section
55on implementation.
56.PP
57Even within the confines of control flow and cosmetics,
58we have attempted to be selective
59in what features to provide.
60The intent has been to provide a small set of the most useful
61constructs,
62rather than to throw in everything that has ever been thought useful
63by someone.
64.PP
65The rest of this section contains an informal description
66of the
67Ratfor
68language.
69The control flow aspects will be
70quite familiar to readers used to languages like
71Algol, PL/I, Pascal, etc.,
72and the cosmetic changes are equally straightforward.
73We shall concentrate on
74showing what the language looks like.
75.SH
76Statement Grouping
77.PP
78Fortran provides no way to group statements together,
79short of making them into a subroutine.
80The standard construction
81``if a condition is true,
82do this group of things,''
83for example,
84.P1
85if (x > 100)
86 { call error("x>100"); err = 1; return }
87.P2
88cannot be written directly in Fortran.
89Instead
90a programmer is forced to translate this relatively
91clear thought into murky Fortran,
92by stating the negative condition
93and branching around the group of statements:
94.P1
95 if (x .le. 100) goto 10
96 call error(5hx>100)
97 err = 1
98 return
9910 ...
100.P2
101When the program doesn't work,
102or when it must be modified,
103this must be translated back into
104a clearer form before one can be sure what it does.
105.PP
106Ratfor
107eliminates this error-prone and confusing back-and-forth translation;
108the first form
109.ul
110is
111the way the computation is written in
112Ratfor.
113A group of statements can be treated as a unit
114by enclosing them in the braces { and }.
115This is true throughout the language:
116wherever a single
117Ratfor
118statement can be used,
119there can be several enclosed in braces.
120(Braces seem clearer and less obtrusive than
121.UL begin
122and
123.UL end
124or
125.UL do
126and
127.UL end ,
128and of course
129.UL do
130and
131.UL end
132already have Fortran meanings.)
133.PP
134Cosmetics
135contribute to the readability of code,
136and thus to its understandability.
137The character ``>'' is clearer than
138.UC ``.GT.'' ,
139so
140Ratfor
141translates it appropriately,
142along with several other similar shorthands.
143Although many Fortran compilers permit character strings in quotes
144(like
145.UL """x>100""" ),
146quotes are
147not allowed in
148.UC ANSI
149Fortran,
150so
151Ratfor
152converts it into the right number of
153.UL H 's:
154computers count better than people do.
155.PP
156Ratfor
157is a free-form language:
158statements may appear anywhere on a line,
159and several may appear on one line
160if they are separated by semicolons.
161The example above could also be written as
162.P1
163if (x > 100) {
164 call error("x>100")
165 err = 1
166 return
167}
168.P2
169In this case, no semicolon is needed at the end of each line because
170Ratfor
171assumes there is one statement per line
172unless told otherwise.
173.PP
174Of course,
175if the statement that follows the
176.UL if
177is a single statement
178(Ratfor
179or otherwise),
180no braces are needed:
181.P1
182if (y <= 0.0 & z <= 0.0)
183 write(6, 20) y, z
184.P2
185No continuation need be indicated
186because the statement is clearly not finished on the first line.
187In general
188Ratfor
189continues lines when it seems obvious that they are not yet done.
190(The continuation convention is discussed in detail later.)
191.PP
192Although a free-form language permits wide latitude in formatting styles,
193it is wise to pick one that is readable, then stick to it.
194In particular, proper indentation is vital,
195to make the logical structure of the program obvious to the reader.
196.sp
197.SH
198The ``else'' Clause
199.PP
200Ratfor
201provides an
202.UL "else"
203statement to handle the construction
204``if a condition is true,
205do
206this
207thing,
208.ul
209otherwise
210do that thing.''
211.P1
212if (a <= b)
213 { sw = 0; write(6, 1) a, b }
214else
215 { sw = 1; write(6, 1) b, a }
216.P2
217This writes out the smaller of
218.UL a
219and
220.UL b ,
221then the larger, and sets
222.UL sw
223appropriately.
224.PP
225The Fortran equivalent of this code is circuitous indeed:
226.P1
227 if (a .gt. b) goto 10
228 sw = 0
229 write(6, 1) a, b
230 goto 20
23110 sw = 1
232 write(6, 1) b, a
23320 ...
234.P2
235This is a mechanical translation;
236shorter forms exist,
237as they do for many similar situations.
238But all translations suffer from the same problem:
239since they are translations,
240they are less clear and understandable than code
241that is not a translation.
242To understand the Fortran version,
243one must scan the entire program to make
244sure that no other statement branches
245to statements 10 or 20
246before one knows that indeed this is an
247.UL if-else
248construction.
249With the
250Ratfor
251version,
252there is no question about how one gets to the parts of the statement.
253The
254.UL if-else
255is a single unit,
256which can be read, understood, and ignored if not relevant.
257The program says what it means.
258.PP
259As before, if the statement following an
260.UL if
261or an
262.UL else
263is a single statement, no braces are needed:
264.P1
265if (a <= b)
266 sw = 0
267else
268 sw = 1
269.P2
270.PP
271The syntax of the
272.UL if
273statement is
274.P1
275if (\fIlegal Fortran condition\fP)
276 \fIRatfor statement\fP
277else
278 \fIRatfor statement\fP
279.P2
280where the
281.UL else
282part is optional.
283The
284.ul
285legal Fortran condition
286is
287anything that can legally go into a Fortran Logical
288.UC IF .
289Ratfor
290does not check this clause,
291since it does not know enough Fortran
292to know what is permitted.
293The
294.ul
295Ratfor
296.ul
297statement
298is any Ratfor or Fortran statement, or any collection of them
299in braces.
300.SH
301Nested if's
302.PP
303Since the statement that follows an
304.UL if
305or
306an
307.UL else
308can be any Ratfor statement, this leads immediately
309to the possibility of another
310.UL if
311or
312.UL else .
313As a useful example, consider this problem:
314the variable
315.UL f
316is to be set to
317\-1 if
318.UL x
319is less than zero,
320to
321+1
322if
323.UL x
324is greater than 100,
325and to 0 otherwise.
326Then in Ratfor, we write
327.P1
328if (x < 0)
329 f = -1
330else if (x > 100)
331 f = +1
332else
333 f = 0
334.P2
335Here the statement after the first
336.UL else
337is another
338.UL if-else .
339Logically it is just a single statement,
340although it is rather complicated.
341.PP
342This code says what it means.
343Any version written in straight Fortran
344will necessarily be indirect
345because Fortran does not let you say what you mean.
346And as always, clever shortcuts may turn out
347to be too clever to understand a year from now.
348.PP
349Following an
350.UL else
351with an
352.UL if
353is one way to write a multi-way branch in Ratfor.
354In general the structure
355.P1
356if (...)
357 - - -
358else if (...)
359 - - -
360else if (...)
361 - - -
362 ...
363else
364 - - -
365.P2
366provides a way to specify the choice of exactly one of several alternatives.
367(Ratfor also provides a
368.UL switch
369statement which does the same job
370in certain special cases;
371in more general situations, we have to make do
372with spare parts.)
373The tests are laid out in sequence, and each one
374is followed by the code associated with it.
375Read down the list
376of decisions until one is found that is satisfied.
377The code associated with this condition is executed,
378and then the entire structure is finished.
379The trailing
380.UL else
381part handles the ``default'' case,
382where none of the other conditions apply.
383If there is no default action, this final
384.UL else
385part
386is omitted:
387.P1
388if (x < 0)
389 x = 0
390else if (x > 100)
391 x = 100
392.P2
393.SH
394if-else ambiguity
395.PP
396There is one thing to notice about complicated structures
397involving nested
398.UL if 's
399and
400.UL else 's.
401Consider
402.P1
403if (x > 0)
404 if (y > 0)
405 write(6, 1) x, y
406 else
407 write(6, 2) y
408.P2
409There are two
410.UL if 's
411and
412only one
413.UL else .
414Which
415.UL if
416does the
417.UL else
418go with?
419.PP
420This is a genuine ambiguity in Ratfor, as it is in many other programming
421languages.
422The ambiguity is resolved in Ratfor
423(as elsewhere) by saying that in such cases the
424.UL else
425goes with the closest previous
426.UL else 'ed un-
427.UL if .
428Thus in this case, the
429.UL else
430goes with the inner
431.UL if ,
432as we have indicated by the indentation.
433.PP
434It is a wise practice to resolve such cases by explicit braces,
435just to make your intent clear.
436In the case above, we would write
437.P1
438if (x > 0) {
439 if (y > 0)
440 write(6, 1) x, y
441 else
442 write(6, 2) y
443}
444.P2
445which does not change the meaning, but leaves
446no doubt in the reader's mind.
447If we want the other association, we
448.ul
449must
450write
451.P1
452if (x > 0) {
453 if (y > 0)
454 write(6, 1) x, y
455}
456else
457 write(6, 2) y
458.P2
459.SH
460The ``switch'' Statement
461.PP
462The
463.UL switch
464statement
465provides a clean way to express multi-way branches
466which branch on the value of some integer-valued expression.
467The syntax is
468.P1
469\f3switch (\fIexpression\|\f3) {
470
471 case \fIexpr1\f3 :
472 \f2statements\f3
473 case \fIexpr2, expr3\f3 :
474 \f2statements\f3
475 ...
476 default:
477 \f2statements\f3
478}
479.P2
480.PP
481Each
482.UL case
483is followed by a
484list of comma-separated integer expressions.
485The
486.ul
487expression
488inside
489.UL switch
490is compared against the case expressions
491.ul
492expr1,
493.ul
494expr2,
495and so on in turn
496until one matches,
497at which time the statements following that
498.UL case
499are executed.
500If no cases match
501.ul
502expression,
503and there is a
504.UL default
505section,
506the statements with it are done;
507if there is no
508.UL default,
509nothing is done.
510In all situations,
511as soon as some block of statements is executed,
512the entire
513.UL switch
514is exited immediately.
515(Readers familiar with C[4] should beware that this
516behavior is not the same as the C
517.UL switch .)
518.SH
519The ``do'' Statement
520.PP
521The
522.UL do
523statement in
524Ratfor
525is quite similar to the
526.UC DO
527statement in Fortran,
528except that it uses no statement number.
529The statement number, after all, serves only to mark the end
530of the
531.UC DO ,
532and this can be done just as easily with braces.
533Thus
534.P1
535 do i = 1, n {
536 x(i) = 0.0
537 y(i) = 0.0
538 z(i) = 0.0
539 }
540.P2
541is the same as
542.P1
543 do 10 i = 1, n
544 x(i) = 0.0
545 y(i) = 0.0
546 z(i) = 0.0
54710 continue
548.P2
549The syntax is:
550.P1
551do \fIlegal\(hyFortran\(hyDO\(hytext\fP
552 \fIRatfor statement\fP
553.P2
554The part that follows
555the keyword
556.UL do
557has to be something that can legally go into a Fortran
558.UC DO
559statement.
560Thus if a local version of Fortran allows
561.UC DO
562limits to be expressions
563(which is not currently permitted in
564.UC ANSI
565Fortran),
566they can be used in a
567Ratfor
568.UL do.
569.PP
570The
571.ul
572Ratfor statement
573part will often be enclosed in braces, but
574as with the
575.UL if ,
576a single statement need not have braces around it.
577This code sets an array to zero:
578.P1
579do i = 1, n
580 x(i) = 0.0
581.P2
582Slightly more complicated,
583.P1
584do i = 1, n
585 do j = 1, n
586 m(i, j) = 0
587.P2
588sets the entire array
589.UL m
590to zero, and
591.P1
592do i = 1, n
593 do j = 1, n
594 if (i < j)
595 m(i, j) = -1
596 else if (i == j)
597 m(i, j) = 0
598 else
599 m(i, j) = +1
600.P2
601sets the upper triangle of
602.UL m
603to \-1, the diagonal to zero, and the lower triangle to +1.
604(The operator == is ``equals'', that is, ``.EQ.''.)
605In each case, the statement that follows the
606.UL do
607is logically a
608.ul
609single
610statement, even though complicated,
611and thus needs no braces.
612.sp
613.SH
614``break'' and ``next''
615.PP
616Ratfor
617provides a statement for leaving a loop early,
618and one for beginning the next iteration.
619.UL "break"
620causes an immediate exit from the
621.UL do ;
622in effect it is a branch to the statement
623.ul
624after
625the
626.UL do .
627.UL next
628is a branch to the bottom of the loop,
629so it causes the next iteration to be done.
630For example, this code skips over negative values in an array:
631.P1
632do i = 1, n {
633 if (x(i) < 0.0)
634 next
635 \fIprocess positive element\fP
636}
637.P2
638.UL break
639and
640.UL next
641also work in the other Ratfor looping constructions
642that we will talk about in the next few sections.
643.PP
644.UL break
645and
646.UL next
647can be followed by an integer to indicate breaking or iterating
648that level of enclosing loop; thus
649.P1
650break 2
651.P2
652exits from two levels of enclosing loops,
653and
654.UL break\ 1
655is equivalent to
656.UL break .
657.UL next\ 2
658iterates the second enclosing loop.
659(Realistically,
660multi-level
661.UL break 's
662and
663.UL next 's
664are
665not likely to be much used
666because they lead to code that is hard to understand
667and somewhat risky to change.)
668.sp
669.SH
670The ``while'' Statement
671.PP
672One of the problems with the Fortran
673.UC DO
674statement
675is that it generally insists upon being done once,
676regardless of its limits.
677If a loop begins
678.P1
679DO I = 2, 1
680.P2
681this will typically be done once with
682.UL I
683set to 2,
684even though common sense would suggest that perhaps it shouldn't be.
685Of course a
686Ratfor
687.UL do
688can easily be preceded by a test
689.P1
690if (j <= k)
691 do i = j, k {
692 _ _ _
693 }
694.P2
695but this has to be a conscious act,
696and is often overlooked by programmers.
697.PP
698A more serious problem with the
699.UC DO
700statement
701is that it encourages that a program be written
702in terms of an arithmetic progression
703with small positive steps,
704even though that may not be the best way to write it.
705If code has to be contorted to fit the requirements
706imposed by the Fortran
707.UC DO ,
708it is that much harder to write and understand.
709.PP
710To overcome these difficulties,
711Ratfor
712provides a
713.UL while
714statement,
715which is simply a loop:
716``while some condition is true,
717repeat this group of statements''.
718It has
719no preconceptions about why one is looping.
720For example, this routine to compute sin(x)
721by the Maclaurin series
722combines two termination criteria.
723.P1 1
724.ta .3i .6i .9i 1.2i 1.5i 1.8i
725real function sin(x, e)
726 # returns sin(x) to accuracy e, by
727 # sin(x) = x - x**3/3! + x**5/5! - ...
728
729 sin = x
730 term = x
731
732 i = 3
733 while (abs(term)>e & i<100) {
734 term = -term * x**2 / float(i*(i-1))
735 sin = sin + term
736 i = i + 2
737 }
738
739 return
740 end
741.P2
742.PP
743Notice that
744if the routine is entered with
745.UL term
746already smaller than
747.UL e ,
748the
749loop will be done
750.ul
751zero times,
752that is, no attempt will be made to compute
753.UL x**3
754and thus a potential underflow is avoided.
755Since the test is made at the top of a
756.UL while
757loop
758instead of the bottom,
759a special case disappears _
760the code works at one of its boundaries.
761(The test
762.UL i<100
763is the other boundary _
764making sure the routine stops after
765some maximum number of iterations.)
766.PP
767As an aside, a sharp character ``#'' in a line
768marks the beginning of a comment;
769the rest of the line is comment.
770Comments and code can co-exist on the same line _
771one can make marginal remarks,
772which is not possible with Fortran's ``C in column 1'' convention.
773Blank lines are also permitted anywhere
774(they are not in Fortran);
775they should be used to emphasize the natural divisions
776of a program.
777.PP
778The syntax of the
779.UL while
780statement is
781.P1
782while (\fIlegal Fortran condition\fP)
783 \fIRatfor statement\fP
784.P2
785As with the
786.UL if ,
787.ul
788legal Fortran condition
789is something that can go into
790a Fortran Logical
791.UC IF ,
792and
793.ul
794Ratfor statement
795is a single statement,
796which may be multiple statements in braces.
797.PP
798The
799.UL while
800encourages a style of coding not normally
801practiced by Fortran programmers.
802For example, suppose
803.UL nextch
804is a function which returns the next input character
805both as a function value and in its argument.
806Then a loop to find the first non-blank character is just
807.P1
808while (nextch(ich) == iblank)
809 ;
810.P2
811A semicolon by itself is a null statement,
812which is necessary here to mark the end of the
813.UL while ;
814if it were not present, the
815.UL while
816would control the next statement.
817When the loop is broken,
818.UL ich
819contains the first non-blank.
820Of course the same code can be written in Fortran as
821.P1 1
822100 if (nextch(ich) .eq. iblank) goto 100
823.P2
824but many Fortran programmers (and a few compilers) believe this line is illegal.
825The language at one's disposal
826strongly influences how one thinks about a problem.
827.sp
828.SH
829The ``for'' Statement
830.PP
831The
832.UL for
833statement
834is another Ratfor loop, which
835attempts to carry the separation of
836loop-body from reason-for-looping
837a step further
838than the
839.UL while.
840A
841.UL for
842statement allows explicit initialization
843and increment steps as part of the statement.
844For example,
845a
846.UC DO
847loop is just
848.P1
849for (i = 1; i <= n; i = i + 1) ...
850.P2
851This is equivalent to
852.P1
853i = 1
854while (i <= n) {
855 ...
856 i = i + 1
857}
858.P2
859The initialization and increment of
860.UL i
861have been moved into the
862.UL for
863statement,
864making it easier to see at a glance
865what controls the loop.
866.PP
867The
868.UL for
869and
870.UL while
871versions have the advantage that they will be done zero times
872if
873.UL n
874is less than 1; this is not true of the
875.UL do .
876.PP
877The loop of the sine routine in the previous section
878can be re-written
879with a
880.UL for
881as
882.P1 3
883for (i=3; abs(term) > e & i < 100; i=i+2) {
884 term = -term * x**2 / float(i*(i-1))
885 sin = sin + term
886}
887.P2
888.PP
889The syntax of the
890.UL for
891statement is
892.P1
893for ( \fIinit\fP ; \fIcondition\fP ; \fIincrement\fP )
894 \fIRatfor statement\fP
895.P2
896.ul
897init
898is any single Fortran statement, which gets done once
899before the loop begins.
900.ul
901increment
902is any single Fortran statement,
903which gets done at the end of each pass through the loop,
904before the test.
905.ul
906condition
907is again anything that is legal in a logical
908.UC IF.
909Any of
910.ul
911init,
912.ul
913condition,
914and
915.ul
916increment
917may be omitted,
918although the semicolons
919.ul
920must
921always be present.
922A non-existent
923.ul
924condition
925is treated as always true,
926so
927.UL "for(;;)"
928is an indefinite repeat.
929(But see the
930.UL repeat-until
931in the next section.)
932.PP
933The
934.UL for
935statement is particularly
936useful for
937backward loops, chaining along lists,
938loops that might be done zero times,
939and similar things which are hard to express with a
940.UC DO
941statement,
942and obscure to write out
943with
944.UC IF 's
945and
946.UC GOTO 's.
947For example,
948here is a
949backwards
950.UC DO
951loop
952to find the last non-blank character on a card:
953.P1
954for (i = 80; i > 0; i = i - 1)
955 if (card(i) != blank)
956 break
957.P2
958(``!='' is the same as
959.UC ``.NE.'' ).
960The code scans the columns from 80 through to 1.
961If a non-blank is found, the loop
962is immediately broken.
963.UL break \& (
964and
965.UL next
966work in
967.UL for 's
968and
969.UL while 's
970just as in
971.UL do 's).
972If
973.UL i
974reaches zero,
975the card is all blank.
976.PP
977This code is rather nasty to write with a regular Fortran
978.UC DO ,
979since the loop must go forward,
980and we must explicitly set up proper conditions
981when we fall out of the loop.
982(Forgetting this is a common error.)
983Thus:
984.P1 1
985.ta .3i .6i .9i 1.2i 1.5i 1.8i
986 DO 10 J = 1, 80
987 I = 81 - J
988 IF (CARD(I) .NE. BLANK) GO TO 11
98910 CONTINUE
990 I = 0
99111 ...
992.P2
993The version that uses the
994.UL for
995handles the termination condition properly for free;
996.UL i
997.ul
998is
999zero when we fall out of the
1000.UL for
1001loop.
1002.PP
1003The increment
1004in a
1005.UL for
1006need not be an arithmetic progression;
1007the following program walks along a list
1008(stored in an integer array
1009.UL ptr )
1010until a zero pointer is found,
1011adding up elements from a parallel array of values:
1012.P1
1013sum = 0.0
1014for (i = first; i > 0; i = ptr(i))
1015 sum = sum + value(i)
1016.P2
1017Notice that the code works correctly if the list is empty.
1018Again, placing the test at the top of a loop
1019instead of the bottom eliminates a potential boundary error.
1020.SH
1021The ``repeat-until'' statement
1022.PP
1023In spite of the dire warnings,
1024there are times when one really needs a loop that tests at the bottom
1025after one pass through.
1026This service is provided by the
1027.UL repeat-until :
1028.P1
1029repeat
1030 \fIRatfor statement\fP
1031until (\fIlegal Fortran condition\fP)
1032.P2
1033The
1034.ul
1035Ratfor statement
1036part is done once,
1037then the condition is evaluated.
1038If it is true, the loop is exited;
1039if it is false, another pass is made.
1040.PP
1041The
1042.UL until
1043part is optional, so a bare
1044.UL repeat
1045is the cleanest way to specify an infinite loop.
1046Of course such a loop must ultimately be broken by some
1047transfer of control such as
1048.UL stop ,
1049.UL return ,
1050or
1051.UL break ,
1052or an implicit stop such as running out of input with
1053a
1054.UC READ
1055statement.
1056.PP
1057As a matter of observed fact[8], the
1058.UL repeat-until
1059statement is
1060.ul
1061much
1062less used than the other looping constructions;
1063in particular, it is typically outnumbered ten to one by
1064.UL for
1065and
1066.UL while .
1067Be cautious about using it, for loops that test only at the
1068bottom often don't handle null cases well.
1069.SH
1070More on break and next
1071.PP
1072.UL break
1073exits immediately from
1074.UL do ,
1075.UL while ,
1076.UL for ,
1077and
1078.UL repeat-until .
1079.UL next
1080goes to the test part of
1081.UL do ,
1082.UL while
1083and
1084.UL repeat-until ,
1085and to the increment step of a
1086.UL for .
1087.SH
1088``return'' Statement
1089.PP
1090The standard Fortran mechanism for returning a value from a function uses the name of the function as a variable which can be assigned to;
1091the last value stored in it
1092is the function value upon return.
1093For example, here is a routine
1094.UL equal
1095which returns 1 if two arrays are identical,
1096and zero if they differ.
1097The array ends are marked by the special value \-1.
1098.P1 1
1099.ta .3i .6i .9i 1.2i 1.5i 1.8i
1100# equal _ compare str1 to str2;
1101# return 1 if equal, 0 if not
1102 integer function equal(str1, str2)
1103 integer str1(100), str2(100)
1104 integer i
1105
1106 for (i = 1; str1(i) == str2(i); i = i + 1)
1107 if (str1(i) == -1) {
1108 equal = 1
1109 return
1110 }
1111 equal = 0
1112 return
1113 end
1114.P2
1115.PP
1116In many languages (e.g., PL/I)
1117one instead says
1118.P1
1119return (\fIexpression\fP)
1120.P2
1121to return a value from a function.
1122Since this is often clearer, Ratfor provides such a
1123.UL return
1124statement _
1125in a function
1126.UL F ,
1127.UL return (expression)
1128is equivalent to
1129.P1
1130{ F = expression; return }
1131.P2
1132For example, here is
1133.UL equal
1134again:
1135.P1 1
1136.ta .3i .6i .9i 1.2i 1.5i 1.8i
1137# equal _ compare str1 to str2;
1138# return 1 if equal, 0 if not
1139 integer function equal(str1, str2)
1140 integer str1(100), str2(100)
1141 integer i
1142
1143 for (i = 1; str1(i) == str2(i); i = i + 1)
1144 if (str1(i) == -1)
1145 return(1)
1146 return(0)
1147 end
1148.P2
1149If there is no parenthesized expression after
1150.UL return ,
1151a normal
1152.UC RETURN
1153is made.
1154(Another version of
1155.UL equal
1156is presented shortly.)
1157.sp
1158.SH
1159Cosmetics
1160.PP
1161As we said above,
1162the visual appearance of a language
1163has a substantial effect
1164on how easy it is to read and understand
1165programs.
1166Accordingly, Ratfor provides a number of cosmetic facilities
1167which may be used to make programs more readable.
1168.SH
1169Free-form Input
1170.PP
1171Statements can be placed anywhere on a line;
1172long statements are continued automatically,
1173as are long conditions in
1174.UL if ,
1175.UL while ,
1176.UL for ,
1177and
1178.UL until .
1179Blank lines are ignored.
1180Multiple statements may appear on one line,
1181if they are separated by semicolons.
1182No semicolon is needed at the end of a line,
1183if
1184Ratfor
1185can make some reasonable guess about whether the statement
1186ends there.
1187Lines ending with any of the characters
1188.P1
1189= + - * , | & ( \(ru
1190.P2
1191are assumed to be continued on the next line.
1192Underscores are discarded wherever they occur;
1193all others remain as part of the statement.
1194.PP
1195Any statement that begins with an all-numeric field is
1196assumed to be a Fortran label,
1197and placed in columns 1-5 upon output.
1198Thus
1199.P1
1200write(6, 100); 100 format("hello")
1201.P2
1202is converted into
1203.P1
1204 write(6, 100)
1205100 format(5hhello)
1206.P2
1207.SH
1208Translation Services
1209.PP
1210Text enclosed in matching single or double quotes
1211is converted to
1212.UL nH...
1213but is otherwise unaltered
1214(except for formatting _ it may get split across card boundaries
1215during the reformatting process).
1216Within quoted strings, the backslash `\e' serves as an escape character:
1217the next character is taken literally.
1218This provides a way to get quotes (and of course the backslash itself) into
1219quoted strings:
1220.P1
1221"\e\e\e\(fm"
1222.P2
1223is a string containing a backslash and an apostrophe.
1224(This is
1225.ul
1226not
1227the standard convention of doubled quotes,
1228but it is easier to use and more general.)
1229.PP
1230Any line that begins with the character `%'
1231is left absolutely unaltered
1232except for stripping off the `%'
1233and moving the line one position to the left.
1234This is useful for inserting control cards,
1235and other things that should not be transmogrified
1236(like an existing Fortran program).
1237Use `%' only for ordinary statements,
1238not for the condition parts of
1239.UL if ,
1240.UL while ,
1241etc., or the output may come out in an unexpected place.
1242.PP
1243The following character translations are made,
1244except within single or double quotes
1245or on a line beginning with a `%'.
1246.P1
1247.ta .5i 1.5i 2i
1248== .eq. != .ne.
1249> .gt. >= .ge.
1250< .lt. <= .le.
1251& .and. | .or.
1252! .not. ^ .not.
1253.P2
1254In addition, the following translations are provided
1255for input devices with restricted character sets.
1256.P1
1257.ta .5i 1.5i 2i
1258[ { ] }
1259$( { $) }
1260.P2
1261.SH
1262``define'' Statement
1263.PP
1264Any string of alphanumeric characters can be defined as a name;
1265thereafter, whenever that name occurs in the input
1266(delimited by non-alphanumerics)
1267it is replaced by the rest of the definition line.
1268(Comments and trailing white spaces are stripped off).
1269A defined name can be arbitrarily long,
1270and must begin with a letter.
1271.PP
1272.UL define
1273is typically used to create symbolic parameters:
1274.P1
1275define ROWS 100
1276define COLS 50
1277.if t .sp 5p
1278dimension a(ROWS), b(ROWS, COLS)
1279.if t .sp 5p
1280 if (i > ROWS \(or j > COLS) ...
1281.P2
1282Alternately, definitions may be written as
1283.P1
1284define(ROWS, 100)
1285.P2
1286In this case, the defining text is everything after the comma up to the balancing
1287right parenthesis;
1288this allows multi-line definitions.
1289.PP
1290It is generally a wise practice to use symbolic parameters
1291for most constants, to help make clear the function of what
1292would otherwise be mysterious numbers.
1293As an example, here is the routine
1294.UL equal
1295again, this time with symbolic constants.
1296.P1 3
1297.ta .3i .6i .9i 1.2i 1.5i 1.8i
1298define YES 1
1299define NO 0
1300define EOS -1
1301define ARB 100
1302
1303# equal _ compare str1 to str2;
1304# return YES if equal, NO if not
1305 integer function equal(str1, str2)
1306 integer str1(ARB), str2(ARB)
1307 integer i
1308
1309 for (i = 1; str1(i) == str2(i); i = i + 1)
1310 if (str1(i) == EOS)
1311 return(YES)
1312 return(NO)
1313 end
1314.P2
1315.SH
1316``include'' Statement
1317.PP
1318The statement
1319.P1
1320 include file
1321.P2
1322inserts the file
1323found on input stream
1324.ul
1325file
1326into the
1327Ratfor
1328input in place of the
1329.UL include
1330statement.
1331The standard usage is to place
1332.UC COMMON
1333blocks on a file,
1334and
1335.UL include
1336that file whenever a copy is needed:
1337.P1
1338subroutine x
1339 include commonblocks
1340 ...
1341 end
1342
1343suroutine y
1344 include commonblocks
1345 ...
1346 end
1347.P2
1348This ensures that all copies of the
1349.UC COMMON
1350blocks are identical
1351.SH
1352Pitfalls, Botches, Blemishes and other Failings
1353.PP
1354Ratfor catches certain syntax errors, such as missing braces,
1355.UL else
1356clauses without an
1357.UL if ,
1358and most errors involving missing parentheses in statements.
1359Beyond that, since Ratfor knows no Fortran,
1360any errors you make will be reported by the Fortran compiler,
1361so you will from time to time have to relate a Fortran diagnostic back
1362to the Ratfor source.
1363.PP
1364Keywords are reserved _
1365using
1366.UL if ,
1367.UL else ,
1368etc., as variable names will typically wreak havoc.
1369Don't leave spaces in keywords.
1370Don't use the Arithmetic
1371.UC IF .
1372.PP
1373The Fortran
1374.UL nH
1375convention is not recognized anywhere by Ratfor;
1376use quotes instead.