Tonto | ||
---|---|---|
<< Previous | Next >> |
The actual text transformations that are performed by the foo preprocessor are now described.
The keyword function is automatically prepended to every foo routine name contained in a module or program which uses the result syntax. Otherwise the routine is assumed to be a subroutine, and the subroutine keyword is prepended.
A dummy variable self is automatically inserted as the first argument of every foo routine.
Every foo routine contained in a module XXXX which is not deemed to be a functional or subroutinal (see the Section called Functionals and subroutinals>) has appended a type declaration of the form XXXX :: self.
The end keyword may be substituted for end do, end if, end subroutine, end function, end module, end select end type, end interface.
In module XXXX, if x, y, ..., z stand for allowed Fortran95 names, and if x is the name of a record of the derived type xxxx_type used in that module, and defined in file types.foo, then the following transformation is performed:
If x is not the name of a record of the derived type used in the module, and if .x(y, ... , z) is not part of an expression, then following transformation is performed: If x is not the name of a record of the derived type used in the module, and if .x(y, ... , z) is part of an expression, then the following transformation is performed:If x, y, ..., z stand for allowed Fortran95 names, and if w is the name of a Fortran variable, and if w.x(y, ... , z) is not part of an expression, and if x is a type component of the variable w then following transformation is performed:
If w.x(y, ... , z) is not part of an expression, and If x is not a type component of the variable w the following transformation is performed: If w.x(y, ... , z) is part of an expression, then the following and if x is a type component of the variable w then following transformation is performed: If w.x(y, ... , z) is part of an expression, then the following and if x is not a type component of the variable w then following transformation is performed:The dot notation . can be viewed as a synonym for the structure separator %. They are not the same, however, since the internal type structure of the variable shell may change at some later date so that component shell%ex is no longer present. A routine ex_(shell) can always be arranged to exist to simulate the missing structure component. This greatly facilitates the maintainability of the code supposing that the internal structure of the type changes. However, it should be kept in mind for compute intensive routines that the % notation is more efficient than a routine call.
A generic interface file xxxx.int is automatically generated for module XXXX, The generic name used for every routine f in the module is f_.
If the same routine name f appears in a module or program (k+1) times, then foo changes these names into the Fortran95 names f, f_1, ..., f_k.
The module procedure keyword is automatically inserted within any explicit generic interface definition appearing in a module.
If the string [recursive] appears at the end of the line where the routine name appears, the routine is deemed recursive, and the keyword recursive is placed before the keyword function or subroutine in the emitted Fortran95 code.
If the string [pure] appears at the end of the line where the routine name appears, the routine is deemed conditionally pure, and the keyword PURE is placed before the keyword function or subroutine in the emitted Fortran95 code. The attribute intent(in) is also added to the first argument self.
If the string [PURE] appears at the end of the line where the routine name appears, the routine is deemed unconditionally pure, and the keyword pure is placed before the keyword function or subroutine in the emitted Fortran95 code. The attribute intent(in) is also added to the first argument self.
If the string [elemental] appears at the end of the line where the routine name appears, the routine is deemed conditionally elemental, and the keyword ELEMENTAL is placed before the keyword function or subroutine in the emitted Fortran95 code. The attribute intent(in) is also added to the first argument self.
If the string [ELEMENTAL] appears at the end of the line where the routine name appears, the routine is deemed unconditionally elemental, and the keyword elemental is placed before the keyword function or subroutine in the emitted Fortran95 code. The attribute intent(in) is also added to the first argument self. In module XXXX, foo performs the following transformation on the recursive routine shown below:
In a module XXXX, if the string [functional] appears at the end of the line where a function name appears, the function is deemed to be a functional, meaning that its first argument self is a routine, and the automatic declaration XXXX :: self is suppressed.
In a module XXXX, if the string [subroutinal] appears at the end of the line where a subroutine name appears, the subroutine is deemed to be a subroutinal, meaning that its first argument self is a routine, and the automatic declaration XXXX :: self is suppressed.
The reason for declaring a functional or subroutinal explicitly is that the automatic declaration of the first argument, self, must be suppressed, in order that it does not conflict with the required explicit interface for the routine self. In addition, the intention of the routine is made clearer.
In module REAL, foo performs the following transformation on the functional shown below:
|
|
|
In addition, an explicit interface must be defined for self, which is transformed as shown:
If the macro ENSURE(cond,"message"), DIE_IF(cond,"message"), or WARN_IF(cond,"message") appears in routine f of module XXXX, where cond stands for a logical expression and message stands for the text of some error message, then foo will insert the name of the module and routine at the beginning of the error message text, yielding the new error message text "in XXXX:f ... message"
In routine read of module MOL, foo changes the precondition macro ENSURE as follows:
|
|
|
If the "first keyword is not name", i.e. word/="name", then the following error message is generated by routine read in the output:
ERROR: in MOL:read ... first keywrord must be name |
The macros ENSURE, DIE_IF, or WARN_IF are commonly used to ensure that a specific set of conditions hold before the start, or at the end of, a routine. In this way, errors can be detected and handled at an early stage without propagation. They are therefore called precondition or postconditon macros.
If the macro DIE("message") or WARN("message") appears in routine f of module XXXX, where message stands for the text of some error message, then foo will insert the name of the module and routine at the beginning of the error message text, yielding the new error message text "in XXXX:f ... message"
If the string [leaky] appears at the end of the line where the routine name appears, the routine is deemed to be leaky, meaning that within the body of the routine more memory has been allocated than deallocated.
Any routine with the string create, or destroy as part of its name is automatically deemed to be leaky.
For every routine f in module XXXX, the macro STACK("XXXX:f") is inserted before the first line of code which is not a precondition macro.
For every routine f which is leaky or pure, the macro UNSTACK is inserted before the end function or end subroutine keywords in the last line of the routine.
For every routine f which is not leaky or pure, the macro CHECK is inserted before the first line of code which is not a precondition macro.
The macro STACK(X) stands for call stack_(tonto,X). tonto is a memory and call-stack manager object used by TONTO. This routine call places the current routine name X onto a call stack, which may later be used to print a call-stack traceback in the event of controlled error. The routine call also sets to zero a variable which is used to keep track of the memory used in this routine. The amount of memory used or released by dynamic allocation is monitored in the tonto system variable.
The following transformations are made by foo
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
| |||
|
|
|
The C preprocessor macros defined in the macros file shall constitute part of the definition of the foo language.