To: WG5 From: Keith Bierman Subject: Fortran Pre-Processor What follows is a Sun internal document describing an "fpp". The code is complete, and we expect to have it ready for public distribution this summer. As with FDLIBM and UCBTST we will be making the code copyright, but generally redistributable without fee and with really minimal strings (see netlib for those "products"). From a user perspective "fpp" can be viewed as a bug fixed "cpp" as automatically invoked by most unix f77's. It is likely to show up in Sun products at some point in time. There may be earlier "test" releases available to those with a serious interest. Hopefully this will satisfy the requests for a preprocessor, and neither WG5 nor X3J3 will have to invest a lot of time on this. We would be happy to have both the specification and even the implementation become standards if someone else wants to do all the paperwork ;> When the code is released there will be full attribution of the authors. Prakash was the author of the following specification document. Author: Prakash Narayan 1.0 Title: fpp A Fortran preprocessor for FORTRAN 77 and Fortran 90 programs. 2.0 Specification Frequently Fortran programmers need to maintain more than one version of a code. There may also be a need to run the code in different environments. For the programmer, the best solution is to have a single source file that can be preprocessed to extract the version needed for each special purpose. Thus, if an error is discovered in one version that applies to all versions, it needs to be rectified only once. The feature from a preprocessor that meets the above requirement is conditional code inclusion. In addition, it will be useful to have some more functionality. A facility to specify preprocessor variables and a mechanism to include definitions kept in external files. There is a need for a Fortran specific preprocessor because existing preprocessors are language specific. Historically, C compilers include preprocessing capabilities. There also exist stand-alone C preprocessor utilities. This is, however, tied heavily into the C language syntax and source form. fpp will provide Fortran specific facilities that C programmers have long grown to expect in UNIX environments. Some of the functionality that fpp will implement can, potentially, be reused in other tools. fpp would have to analyze Fortran source, evaluate Fortran expressions and generate Fortran output. These are the building blocks that other tools (which will be defined later, for enriching the Fortran environment) will need. So creating this utility is a win for our users and a win for us. The following section specifies the commands of fpp in more detail. 3.0 Detailed Specifications Preprocessor Source Preprocessor source is ordinary Fortran source with interspersed preprocessor statements. All preprocessor statements begin with a special character, #. It may only appear at the first character position in a line. The # should be immediately followed by the text of the preprocessor command. Preprocessor directives may not appear inside Fortran comments. Also the preprocessor will not modify the text inside a Fortran comment. The preprocessor will operate on both fixed form source and free form source. Fixed form source files will have the extension .F and free form source files will have the extension .F90. Note that the fixed form file name convention applies to both FORTRAN 77 and Fortran 90. Files with such extensions will be preprocessed first before the appropriate compiler is invoked. If, during the expansion of a macro, the column width of a line exceeds column 72 (for fixed form) or column 132 (for free form), the preprocessor will insert appropriate continuation cards. Preprocessor Variables Preprocessor variables are needed to specify the conditions in conditional inclusion constructs. So, #define name string results in every occurrence of the token "name" [outside of comments, IMPLICIT statement bounds, text in FORMAT statements & string literals] being replaced by "string". Inline replacements with arguments are permitted: #define name (arg1 [,arg2]...) string-with-args-inserted Examples: #define SOLARIS_2 .TRUE. #define CONVERT(TO_FARENHEIT) ((TO_FARENHEIT*9)/5)+32 Preprocessor variables are available from the point of definition till the end of the compilation unit. (ie. global scoping across the file) Conditional Inclusion of Code This is modeled on the cpp Conditional Inclusion construct. #if condition1 block1 [#elif condition2 block2 ] ... [#else blockn ] #endif or #ifdef name block #endif #ifndef name block #endif The conditions are fpp expressions with preprocessor variables (specified by #define statements). Note that the conditions may be specified within parentheses. Also note that fpp expressions are a superset of cpp expressions in that they can evaluate Fortran logical literals. So, .TRUE. is valid in an fpp expression. The preprocessor evaluates these conditions to get a true or false result. The expressions may not evaluate floating point values or include intrinsic functions. Example: #define SOLARIS_2 .TRUE. #if (SOLARIS_2) CALL SOLARIS_2 (X,Y,Z) #else CALL SOLARIS_1 (X,Y,Z) #endif Including Files Sometimes, it is convenient to collect preprocessor variables in a file. This is possible with #include filename Nesting of #include is permitted. #include statement may not appear in a continued line (ie. the first statement in an included file may not be a continuation line) Preprocessor Intrinsic Functions defined(name) provides the definition status of a name. This is, typically, used in a #if statement. Command line options fpp is typically invoked from the Fortran compiler driver. It can also be invoked stand alone. fpp takes in the following options: -Dname Define name as 1. This is the same as if a #define name 1 line appeared in the source file that fpp is processing. -Dname=def This is the same as if a #define name def line appeared in the source file that fpp is processing. -IdirectoryInsert `directory' into the search path for #include files with names not beginning with '/'. So, #include files with names enclosed in double-quotes (") are searched first in the directory of the file with the #include line, then in directories named with the -I options, and lastly, in the directories from the standard list. -UnameRemove any initial definition of `name', where `name' is predefined by the preprocessor. -YdirectoryUse `directory' in place of the standard list of directories when searching for #include files. 4.0 Implementation One possibility when this code is completed is that we would like to consider placing the preprocessor in public domain. That is, we would like to be able to freely distribute the source code. In order for us to do this, the source code cannot contain any proprietary code. So the source code should not borrow code from either the FORTRAN 77 front-end or the Fortran 90 front end. Naturally, some of the algorithms may be the same. So, that is ok. Note: the code shall be freely distributable, but not strictly speaking public domain. For an example, see the fdlibm that Sun contributed to netlib. 5.0 Conclusion The attempt in this proposal is to stick as close as possible to the existing cpp syntax. The only changes are to make this preprocessor Fortran aware. To this extent, the expansion of macros is done sensitive to the context. This will allow existing programs to move over without change.