-
Notifications
You must be signed in to change notification settings - Fork 19
Description
Over the last few months, I've gone through the process of "depastafying" some old codes with the goal to remove all instances of GO TO. I did this because in many cases deconstructing the code was the only way I could figure what it was doing. In a large percentage of cases, the GO TOs are used in cases where we would today use IF-THEN-ELSE-ENDIF blocks and the modifications are straightforward. In other cases where you have interlacing branch-backwards, branch-forward GO TOs that iterate through blocks of code, I've found that combinations of unindexed DO, the BLOCK construct and internal subroutines are needed. Finally, the third most frequent use of GO TOs is to jump out of an iteration directly to output statements that print error or other information prior to exiting or stopping. Based on this experience, I've come up with a few modifications that I think would be helpful for those as foolish as me that feel the need to exteriminate GO TO in all its forms.
First, I would like to propose a new construct I call an ITERATION that combines the functionality of BLOCK and unindexed DOs into a single construct. Currently, you can exit BLOCK but not CYCLE it. Unindexed DO allows both. Just about every Fortran code ever written will have the
following code fragment;
Integer :: reccount = 0
10 Read(7, ('(A)'). ERR=20, END=30) buf
! Translate buf to something
reccount = reccount + 1
GO TO 10
20 Print something
RETURN
30 Print EOF message
My mod would replace this with
READLOOP: ITERATION
Integer :: ioval
Integer :: reccount = 0
Character(LEN=80) :: buffer
Read(7, '(A)', IOSTAT=ioval) buffer
If (ioval /= 0) EXIT READLOOP
End ITERATION READLOOP
This is a simple example but the utility of it really becomes clear when you have to use a BLOCK statement around a large block of code just to handle exiting out of the enclosed BLOCK to some error handling code (usually selected by a SELECT CASE parameter set prior to exiting the BLOCK). I know that this replicates current capabilities by I've always felt that unindexed DO was a poor syntax choice (one of many syntax "crimes" I believe were made by prior committes and have to date gone unpunished)
In addition, I would like to implement an EXIT_TO clause in all the named constructs (DO, BLOCK, etc) that allows you to jump directly to another named construct. The constraint is unlike GO TO it can only jump to the beginning of a block of code contained in another named construct
Example
Do i=1,n
If (error_detected) EXIT_TO error_output
End Do
! lots of lines of code inbetween
error_output: Block
! process error code etc
End Block error_output
Finally, if we still have a need for statement labels, at least let them be fully alphanumeric instead of just numbers. This would make them a lot more readable. In particular, I would like to be able to assign a meaningful label to FORMAT statements that reflect what they are doing.
Example
Write (7,threeReals) a, b, c
threeReals: Format(3(f10.5))
I know you can do the same using character strings but for the target application( refactoring old code) I think this would be a useful feature.
I can supply examples of real code where I've use both BLOCK and unindexed DO to remove GO TO if that would help
Another reason for proposing these is a hope that some enterprising young person in search of a Masters or Ph.D. thesis topic will develop some open source refactoring tools based on AI/Deep Learning that can remove Go Tos automatically. Maybe a Google Summer of Code project. These constructs would give the refactoring tools something to convert the old code into.
Just some ideas based on recent experience