Strip block comments: Difference between revisions

→‎{{header|Fortran}}: Once one has an axe, ...
(→‎{{header|Fortran}}: Once one has an axe, ...)
Line 568:
As ever, there arises the question "How long is a piece of string?" as having once abandoned decks of cards, there is no longer a definite upper bound for the length of a record. So, as ever, the classic response of "surely big enough", here 6666 characters. F90 enables the creation of a protocol for varying-length strings, and F2000 formalises this, but, there is no provision for reading a record of input into a variable that is made large enough for the record just being read, as is almost the case for pl/1 - where the receiving variable would be declared <code>ACARD CHARACTER(6666) VARYING</code> and the READ statement sets the length according to what has been read - but only up to the pre-specified upper limit.
 
So, a reversion to F77 style (which introduced CHARACTER variables) and so, not employing the MODULE protocol of F90 to share information - COMMON statements instead. Though not purely F77 as there is the PARAMETER statement, and the usage of I0 format. The Q format code was a common extension to F77, and reports on the number of characters as yet unread in the input record. This allows the receiving variable to be sized to fit, as in ACARD(1:LC) except that to prevent overflow, LC appears via MIN(LC,LOTS). If this was not done, then the receiving variable would be padded to the end with spaces at a cost in cpu time to supply, and then to scan backwards to find the last non-blank. This would also trim off any trailing spaces that were in the input record.
 
If the text delimiters were single characters only, similar to text literals, it would be easy: scan the text character by character and change state accordingly, though there would be complications if say two quote characters in a row were to signify a single internal quote. A DO-loop would do for the scan. But with multi-character delimiters the scan would have to lurch over a match, and fiddling the index variable of a DO-loop is frowned upon. So instead, slog it out. And be annoyed afresh by the indeterminacy of boolean expression evaluation of the form (A '''and''' B) or (A '''or''' B) in the context where the test is (''safe'' '''and''' ''test'') because the test might provoke an out-of-bounds fault if not safely within bounds. Like, THIS is being tested against the text in ACARD, but it must not compare beyond the end of the text in ACARD.
 
The removal of delimited text is taken literally: an incoming card's content might be entirely within a block comment and so be entirely rejected; if so, a null line results in ALINE, and it is ''not'' written to the output file. In other words, lines of block comment are not preserved as blank lines, nor as null lines, they are not there. Only if a line contains text outside of a block comment will it survive. Outside delimited block comments, spaces are just as valid as any other symbol, and are preserved. So, for example, it is <code>a = b + c ;</code> not <code>a = b + c ;</code> - two spaces after the = sign. Similarly, trailing spaces on a line survive - though I have UltraEdit set to trim trailing spaces and it is not clear whether the example source is to be regarded as containing them or not.
Line 640:
IF (LL.GT.0) THEN !If there is any.
WRITE (OUT,23) ALINE(1:LL) !There is.
23 FORMAT (">",A,"<") !Just text, but with added bounds.
NL = NL + 1 !Count a line.
END IF !So much for output.
Line 647:
100 WRITE (MSG,101) NC,NL !Be polite.
101 FORMAT (I0," read, ",I0," written.")
END !No attention to context, such as quoted strings.
END
 
PROGRAM TEST
Line 663:
END !All open files are closed on exit..
</lang>
 
Output: the report is "16 read, 8 written." And in the output file appears...
<pre>
> <
> function subroutine() {<
> a = b + c ;<
> }<
> <
> <
> function something() {<
> }<
</pre>
Where for expository purposes the > ... < mark the bounds of the surviving text, thus showing surviving spaces.
Once one has an axe in one's hands, everything looks like a tree. A slight variation produces the following stump:
<pre>
> END<
> !No attention to context, such as quoted strings.<
> PROGRAM TEST<
> INTEGER MSG,KBD,INF,OUT<
> COMMON /IODEV/MSG,KBD,INF,OUT<
> KBD = 5<
> MSG = 6<
> INF = 10<
> OUT = 11<
> OPEN (INF,FILE="Laconic.for",STATUS="OLD",ACTION="READ")<
> OPEN (OUT,FILE="Src.txt",STATUS="REPLACE",ACTION="WRITE")<
> CALL UNBLOCK("")<
> END !All open files are closed on exit..<
</pre>
Where the source statement is <code>CALL UNBLOCK("SUBROUTINE","END ")</code> Note that if the ending delimiter were to be "END" there would be trouble. While "end" in the commentary would be missed because I use capitals for Fortran source but normal for commentary, there are plenty of other "END" sequences. Using "END " still would not work because of END IF, but "END " does work - once I added a comment on the line so that the line doesn't end with "END", and, used spaces rather than a tab after the END.
 
F90 allows the syntax END SUBROUTINE UNBLOCK (and insists on it within a MODULE) but F77 does not, otherwise the statement could have been <code>CALL UNBLOCK("SUBROUTINE","END SUBROUTINE")</code> which would be rather more structured.
 
=={{header|F_Sharp|F#}}==
1,220

edits