.# st --- statement type .de st [statement name] .bp .bf .ce [1] .Sh "[1]" .sp 3 .en st .# .# sy --- syntax section .de sy [number of lines] .ne [1] .ul Syntax: .be .en sy .# .# fu --- function section .de fu [number of lines] .ee .ne [1] .ul Function: .be .in -5 .en fu .# .# xm --- example section .de xm [number of lines] .in +5 .ee .ne [1] .ul Example: .be .en xm .CH "Appendixes" .MH "Appendix A -- Implementation of Control Statements" This appendix contains flowcharts of the code produced by the Ratfor control statements along with actual examples of the code Ratfor produces. .pp In different contexts, a given sequence of Ratfor control statements can generate slightly different code. First, where possible, statement labels are not produced when they are not referenced. For instance, a [bf repeat] loop containing no [bf break] statements will have no "exit" label generated, since one is not needed. Second, [bf continue] statements are generated only when two statement numbers must reference the same statement. Finally, internally generated [bf goto] statements are omitted when control can never pass to them; e.g. a [bf when] clause ending with a [bf return] statement. .pp These code generation techniques make no fundamental difference in the control-flow of a program, but can make the code generated by very similar instances of a control statement appear quite different. Please keep in mind that the examples of Fortran code generated by 'rp' are included for completeness, and are not necessarily character-for-character descriptions of the code that would be obtained from preprocessing. Rather, they are intended to illustrate the manner in which the Ratfor statements are implemented in Fortran. .st Break .sy 1 break [] .fu 1 .fi Causes an immediate exit from the referenced loop. .nf .xm 15 for (i = length (str); i > 0; i = i - 1) if (str (i) ~= ' 'c) break i=length(str) goto 10002 10000 i=i-1 10002 if((i.le.0))goto 10001 if((str(i).eq.160))goto 10003 goto 10001 10003 goto 10000 10001 continue .ee .st Do .sy 2 do .fu 27 | V --------------------- | | | initialize do | | | --------------------- |<----------------------------------------- V | --------------------- | | | | | | | | | | --------------------- | | | V | * | * * --------------------- | * * false | | | * do satisfied? * --->| reinitialize do |----->| * * | | * * --------------------- * | true V .xm 8 do i = 1, 10 array (i) = 0 do 10000 i=1,10 10000 array(i)=0 .ee .st For .sy 4 for ([]; []; []) .fu 38 | V --------------------- | | | | | | --------------------- -------------->| | V | * | * * | * * false | * * ------>| | * * | | * * | | * | | | true | | V | | --------------------- | | | | | | | | | | | | | | --------------------- | | | | | V | | --------------------- | | | | | | | | | | | | | | --------------------- | | | | | V | |--------------- | | |------------------ V .xm 16 for (i = limit - 1; i > 0; i = i - 1) { array_1 (i) = array_1 (i + 1) array_2 (i) = array_2 (i + 1) } i=limit-1 goto 10002 10000 i=i-1 10002 if((i.le.0))goto 10001 array1(i)=array1(i+1) array2(i)=array2(i+1) goto 10000 10001 continue .ee .st If .sy 4 if () .fu 14 | V * * * --------------------- * * true | | * * --->| |----->| * * | | | * * --------------------- | * | | false | |<----------------------------------------- V .xm 12 if (a == b) { c = 1 d = 1 } if((a.ne.b))goto 10000 c=1 d=1 10000 continue .ee .st "If - Else" .sy 6 if () else .fu 21 | V * * * true * * false |<----- * * ----->| | * * | | * * | V * V --------------------- --------------------- | | | | | | | | | | | | --------------------- --------------------- | | V V ---------------------------------- | V .xm 13 if (i >= MAXLINE) i = 1 else i = i + 1 if((i.lt.102))goto 10000 i=1 goto 10001 10000 i=i+1 10001 continue .ee .st Next .sy 3 next [] .fu 5 .fi All loops nested within the loop specified by are terminated. Execution resumes with the next iteration of the loop specified by . .nf .xm 25 # output only strings containing no blanks for (i = 1; i <= LIMIT; i = i + 1) { for (j = 1; str (j, i) ~= EOS; j = j + 1) if (str (j, i) == ' 'c) next 2 call putlin (str (1, i), STDOUT) } i=1 goto 10002 10000 i=i+1 10002 if((i.gt.50))goto 10001 j=1 goto 10005 10003 j=j+1 10005 if((str(j,i).eq.-2))goto 10004 if((str(j,i).ne.160))goto 10006 goto 10000 10006 goto 10003 10004 call putlin(str(1,i),-11) goto 10000 10001 continue .ee .st Repeat .sy 5 repeat [until ()] .fu 21 | |<----------------- V | --------------------- | | | | | | | | | | --------------------- | | | V | * | * * | * * false | * * ------>| * * * * * | true V .xm 12 repeat { i = i + 1 j = j + 1 } until (str (i) ~= ' 'c) 10000 i=i+1 j=j+1 if((str(i).eq.160))goto 10000 .ee .st Return .sy 3 return [ '(' (if specified) to be assigned to the function name, and then causes a return from the subprogram. .nf .xm 7 integer function fcn (x) ... return (a + 12) integer function fcn (x) ... fcn=a+12 return .ee .st Select .sy 19 select when () when () when () . . . when () [cc]mc * [cc]mc [ifany ] [else ] .fu 53 | V * * * --------------------- * * true | | * * --->| |->| * * | | | * * --------------------- | * | | false | V | * | * * --------------------- | * * true | | | * * --->| |->| * * | | | * * --------------------- | * | | false | V | * | * * --------------------- | * * true | | | * * --->| |->| * * | | | * * --------------------- | * | | false | V | . . . . . . | false | V | * | * * --------------------- | * * true | | | * * --->| |->| * * | | | * * --------------------- | * | | false | V V --------------------- --------------------- | | | | | | | | | | | | --------------------- --------------------- | | | V |<------------------------------------- V .xm 19 select when (i == 1) call add_record when (i == 2) call delete_record else call code_error goto 10001 10002 call addre0 goto 10000 10003 call delet0 goto 10000 10001 if((i.eq.1))goto 10002 if((i.eq.2))goto 10003 call codee0 10000 continue .ee .st "Select ()" .sy 18 select () when (, , ...) when (, , ...) when (, , ...) . . . when (, , ...) [cc]mc * [cc]mc [ifany ] [else ] .fu 53 | V * * * --------------------- * i0 == * true | | * i1.1 or i1.2 * --->| |->| * or ... * | | | * * --------------------- | * | | false | V | * | * * --------------------- | * i0 == * true | | | * i2.1 or i2.2 * --->| |->| * or ... * | | | * * --------------------- | * | | false | V | * | * * --------------------- | * i0 == * true | | | * i3.1 or i3.2 * --->| |->| * or ... * | | | * * --------------------- | * | | false | V | . . . . . . | false | V | * | * * --------------------- | * i0 == * true | | | * in.1 or in.2 * --->| |->| * or ... * | | | * * --------------------- | * | | false | V V --------------------- --------------------- | | | | | | | | | | | | --------------------- --------------------- | | | V |<------------------------------------- V .xm 26 select (i) when (4, 6, 3003) call add_record when (2, 12, 5000) call delete_record else call code_error integer aaaaa0,aaaab0 ... aaaaa0=i goto 10001 10002 call addre0 goto 10000 10003 call delet0 goto 10000 10001 aaaab0=aaaaa0-1 goto(10003,10004,10002,10004,10002, * 10004,10004,10004,10004,10004, * 10003),aaaab0 if(aaaaa0.eq.3003)goto 10002 if(aaaaa0.eq.5000)goto 10003 10004 continue 10000 continue .ee .st While .sy 4 while () .fu 25 | -------------->| | V | * | * * | * * false | * * ------>| | * * | | * * | | * | | | true | | V | | --------------------- | | | | | | | | | | | | | | --------------------- | | | | | V | |--------------- | | |------------------ V .xm 10 while (str (i) ~= EOS) i = i + 1 10000 if((str(i).eq.-2))goto 10001 i=i+1 goto 10000 10001 continue .ee