| 1 | = FORTRAN/TK and Ratfor = |
| 2 | |
| 3 | Ratfor is a FORTRAN 77 preprocessor designed in the 70s to compensate some of the weird limitations of the FORTRAN 66 (later of the 77) standard, allow entirely structural programming and implement some new functionality.[[BR]] |
| 4 | From the [http://sepwww.stanford.edu/software/ratfor.html official homepage]:[[BR]] |
| 5 | Ratfor is preprocessor for FORTRAN code that allows us to use C-like flow expressions. Jon Claerbout believes that Ratfor is the best available expository language for mathematical algorithms. Ratfor was invented by Brian Kernigham who also co-wrote the first C book. You will not really need precise definitions of Ratfor to use it. Statements on a line may be separated by a ";". Statements may be grouped together with braces {}. Do loops do not require statement numbers because {} defines the range, etc. The Fortran relational operators .gt.,.ge,.ne., etc. may be written >,<=,!=,etc. Unfortunately, the Ratfor switch statement conflicts with implicit undefined declaration, consequently we never use it. Ratfor also frees you from FORTRANs strict indentation rules. Anything from a # to the end of the line is a comment. Ratfor offers quite a few more features more and we strongly recommend it to any FORTRAN programmer. |
| 6 | There's a [http://www.mit.edu:8001/afs/athena.mit.edu/astaff/project/docsourc/doc/unix.manual.progsupp2/08.ratfor/ratfor.PS documentation] about it. |
| 7 | |
| 8 | It was designed for standard FORTRAN 77, so you can use it with the [http://openwatcom.org/ Open Watcom FORTRAN 77] dialect, too. However a lot of Ratfor's functionality is already implemented in the dialect through FORTRAN extensions - in a way that looks native to FORTRAN - in my opinion even better than Fortran 90. Although FORTRAN/TK makes heavy use of FORTRAN extensions - Open Watcom FORTRAN has comparable functionality to Fortran 90 - it seems to be usable with Ratfor. |
| 9 | |
| 10 | == Pros == |
| 11 | |
| 12 | * Overcomes FORTRAN's strict source format (the separation in several source columns) from the punchcard age. These are still restrictions of the Open Watcom dialect, too. Ratfor merges a source line (with all of its continuations) and rearranges it in the strict FORTRAN source format. |
| 13 | * You can write more than one statement per line by separating them with ";". |
| 14 | * It implements a C-like for-statement that's not available in Open Watcom FORTRAN. |
| 15 | * Ratfor's structure statements (while, repeat/until, if, switch, for) feature a C-like syntax. DO-loop blocks use {}, too. Combined with the "#"-comment (comparable to Open Watcom's/Fortran 90's "!"-comment) it even looks a bit like Perl... This might or might not be an advantage for you. |
| 16 | * The define(x,y)-statement allows you to replace the "alpanumeric" string x within the source by an arbitrary string y. Open Watcom FORTRAN only supports PARAMETER-constants. |
| 17 | |
| 18 | == Cons == |
| 19 | |
| 20 | * You might prefer Open Watcom's FORTRAN-like syntax for its extensions over Ratfor's C-like syntax. |
| 21 | * The switch-statement of Ratfor has similar restrictions as Open Watcom's SELECT CASE regarding character expressions. However - though the switch-statement is translated to IF-statements - it cannot handle CHARACTER expressions at all. Also, contrary to SELECT CASE, "switch" does not support case-ranges. |
| 22 | * Some of Ratfor's statements, especially "include", conflict with Open Watcom FORTRAN's statements. "include" parses a given file by the preprocessor. If you want to use Open Watcom's "include" - to include ordinary FORTRAN files - you have to use "%" as the first character of a line to force the preprocessor to insert the (unmodified) line in the output file. So %c$include, %C$include, %*$include (inserts a pragma include) or "% include" (include-statement for program units; does the same as %c$include) will do the job. If you specify the -C commandline parameter for Ratfor, you can also use #$include... everywhere on the line - it will be translated to a "C"-comment. |
| 23 | * Code generated by Ratfor using a lot of the structure-statements might be (slightly) slower than code with Open Watcom statements because they are translated to relatively simple IF/GOTO-statements that might not be as highly optimized as native Open Watcom FORTRAN structure-statements. |
| 24 | * Compiler errors cannot always be assigned to a Ratfor-line and -statement so easily. |
| 25 | |
| 26 | == Compiling Ratfor == |
| 27 | |
| 28 | At first download the source code and extract it - it's public domain: http://sepwww.stanford.edu/ftp/sep-distr/ratfor77.tar.gz [[BR]] |
| 29 | It's written in standard C, so it can be easily compiled with Open Watcom C or most other C compilers.[[BR]] |
| 30 | For Open Watcom C, assuming you initialized all necessary environmental variables, you would have to issue: |
| 31 | {{{ |
| 32 | wcl386 getopt.c lookup.c rat4.c -fe=ratfor77.exe -DF77 -DS_CHAR=char -DGNU |
| 33 | }}} |
| 34 | It should be compiled for your host platform. Use the -l-switch to crosscompile for a certain platform. |
| 35 | |
| 36 | == FORTRAN/TK macros == |
| 37 | |
| 38 | There's a small Ratfor file included with FORTRAN/TK (at least in the subversion repository): [source:/trunk/fortrantk.r fortrantk.r].[[BR]] |
| 39 | Include it to be able to use some "macros" that kind of improve the readability of FORTRAN/TK code. For instance you can use a "z" at the end of character constants or separated from a variable symbol by a space instead of the "//dn" to mark the end of a parameter list. Also, you can use "NL" as a newline character constant (it will be replaced by "char(13)//char(10)") - this also isn't possible with ordinary PARAMETER-constants. To let FORTRAN/TK code look more like Tcl/Tk (with it's attribute-value-pairs) you can use some attributes followed by an underscore instead of the ordinary character constant followed by a colon. There are more or less just the standard attributes for now but you can easily extend the list yourself. There's an example of the [source:/trunk/examples/example.for FORTRAN/TK "example" program] translated to Ratfor code below. |
| 40 | |
| 41 | == FORTRAN/TK example program == |
| 42 | |
| 43 | Here's the [source:/trunk/examples/example.for simple "example" program] of FORTRAN/TK translated to Ratfor code which demonstrates some of Ratfor's features and should give you an impression of its look and feel: |
| 44 | {{{ |
| 45 | # FORTRAN/TK example |
| 46 | # for OpenWatcom FORTRAN/77 and the Ratfor77 preprocessor |
| 47 | # by Robin Haberkorn |
| 48 | |
| 49 | include '..\fortrantk.r' |
| 50 | %c$include fortrantk.fap |
| 51 | %c$include fortrantk.fi |
| 52 | |
| 53 | character*256 dum, dum2 |
| 54 | |
| 55 | # Init code: |
| 56 | if(TkInit('runtime'c)) stop 'FORTRAN/TK couldn''t get initialized!' |
| 57 | |
| 58 | call CreateWindow() |
| 59 | |
| 60 | # The main event loop: |
| 61 | repeat { |
| 62 | # we can't use switch for the event handling... |
| 63 | cmpval = TkWait() |
| 64 | if(cmp('Quit'c)) { |
| 65 | write(*,'(''EVENT: Exiting...'')'); break |
| 66 | |
| 67 | } else if(cmp('hellobtm_click'c)) { |
| 68 | dum2 = TkCget('.hellobtm'c, '-text'z) |
| 69 | write(*,'(''EVENT: The "'',A,''" button was clicked!'')') dum2(:ntlen(dum2)) |
| 70 | dum = TkMessageBox(message_ 'You pressed the "'//dum2(:ntlen(dum2))//'" button!'//NL// _ |
| 71 | 'Please choose "Yes" or "No".'c, _ |
| 72 | title_ 'FORTRAN/TK example'c, _ |
| 73 | type_ 'yesno'z) |
| 74 | write(*,'(''You choosed "'',A,2H".)') dum(:ntlen(dum)) |
| 75 | |
| 76 | } else if(cmp('changebtm_click'c)) { |
| 77 | write(*,'(''EVENT: changebtm_click'')') |
| 78 | dum = TkGet('.entry1'z) |
| 79 | call TkConfig('.hellobtm'c, text_ dum z) |
| 80 | write(*,'(''Text of .hellobtm changed to: "'',A,1H")') dum(:ntlen(dum)) |
| 81 | |
| 82 | } else write(*,'(''EVENT(unknown): '',A)') cmpval(:ntlen(cmpval)) |
| 83 | } |
| 84 | |
| 85 | call TkDestroy('.'z) # Exit code |
| 86 | if(TkUnload()) write(*,'(''FORTRAN/TK couldn'',1H'',''t get unloaded!'')') |
| 87 | |
| 88 | end |
| 89 | |
| 90 | subroutine CreateWindow() |
| 91 | %c$include fortrantk.fi |
| 92 | |
| 93 | # Change the window title and its size: |
| 94 | call TkWm('title'c, '.'c, 'FORTRAN/TK example'z) |
| 95 | call TkWm('geometry'c, '.'c, '=300x200'z) |
| 96 | |
| 97 | # Create the buttons and entry widgets and pack them to the window: |
| 98 | |
| 99 | call TkPack(TkButton('.hellobtm'c, _ |
| 100 | text_ 'Hello world'c, _ |
| 101 | rexx_ 'hellobtm_click'z), _ |
| 102 | TkButton('.exitbtm'c, _ |
| 103 | text_ 'EXIT'c, _ |
| 104 | underline_ '0'c, _ |
| 105 | rexx_ 'Quit'z)//'A', _ |
| 106 | expand_ 'yes'c, _ |
| 107 | fill_ 'both'z) |
| 108 | call TkPack(TkEntry('.entry1'z), _ |
| 109 | fill_ 'x'z) |
| 110 | call TkPack(TkButton('.changebtm'c, _ |
| 111 | text_ 'Change caption'c, _ |
| 112 | underline_ '0'c, _ |
| 113 | rexx_ 'changebtm_click'z), _ |
| 114 | expand_ 'yes'c, _ |
| 115 | fill_ 'both'z) |
| 116 | |
| 117 | # Set Entry widgets text: |
| 118 | call TkInsert('.entry1'c, '1'c, TkCget('.hellobtm'c, '-text'z)z) |
| 119 | |
| 120 | # Display Intro-MessageBox: |
| 121 | call TkTcl('update'z) # there's a bug in Windows Tcl/Tk |
| 122 | call TkMessageBox(message_ 'Welcome to the great FORTRAN/TK example '// _ |
| 123 | 'program.'//NL//'*Stunning*'c, _ |
| 124 | title_ 'FORTRAN/TK example'c, _ |
| 125 | icon_ 'info'z) |
| 126 | end |
| 127 | }}} |
| 128 | The above code might be outdated - it's also part of the FORTRAN/TK subversion repository: [source:/trunk/examples/example_ratfor.r example_ratfor.r]. |
| 129 | |
| 130 | To convert the example to FORTRAN code you would have to issue: |
| 131 | {{{ |
| 132 | ratfor77 -o example_ratfor.for example_ratfor.r |
| 133 | }}} |
| 134 | Alternatively, you can build the whole program using the [source:/trunk/examples/makefile makefile] in FORTRAN/TK's example directory. Assuming there's a "fortrantk.lib" in the the examples-subdirectory you'd have to issue: |
| 135 | {{{ |
| 136 | wmake example_ratfor |
| 137 | }}} |