Phrase reversals: Difference between revisions

m (added whitespace before the TOC (table of contents).)
(→‎{{header|Fortran}}: No shortcuts.)
Line 574:
The key here is the ability via F90 to specify an array span, as A(''first'':''last'':''step'') where the ''step'' can be negative... This facility is not available for CHARACTER variables where only TEXT(''first'':''last'') is available - no ''step'' is accommodated. However, one can have an array of CHARACTER*1 variables, and as an array they can be rolled bidirectionally. For convenience in initialising such an array, EQUIVALENCE(TEXT,ATXT) means that a normal multi-character text literal can be assigned to TEXT via the DATA statement, rather than having to specify the ATXT elements one at a time.
 
By identifying the first and last character position of each word in TEXT (or equivalently, their indices in ATXT) and storing them in arrays IST and LST, the i'th word can be fingered via IST(i) to LST(i) and of course a DO-loop can step in either direction. <lang Fortran> PROGRAM REVERSER !Just fooling around.
 
F90 allows a WHILE-loop, and writing something like <lang Fortran> DO WHILE (L1.LE.L .AND. ATXT(L1).LE." ")
L1 = L1 + 1
END DO</lang>
Would be rather more structured and involve fewer GO TOs and their labels, but alas, modern Fortran specifies that there is no specification as to whether or not both terms of an expression such as (A '''and''' B) will always be evaluated or instead there will be a shortcut: if A is ''false'' then the B term is ignored. And here, the A term checks whether or not L1 is within bounds and if it is not, then the B term should not be evaluated, not just because of the waste of effort but because to do so might involve accessing outside the definition of ATXT. As when the scan chases through the trailing spaces. One could make the array one longer, or rather, <code>L = LEN(TEXT) - 1</code> for this case but that would be messy, require explanation, be easily forgotten, and, typical ad-hoc testing would be unlikely to detect the mistake.
 
So, there's no option but to suck up the GO TOs...<lang Fortran> PROGRAM REVERSER !Just fooling around.
CHARACTER*(66) TEXT !Holds the text. Easily long enough.
CHARACTER*1 ATXT(66) !But this is what I play with.
1,220

edits