External classes are used to interface with code from other languages. Each external class is typically associated with an object file compiled from a language like C or Fortran. Each language identifier is associated with a Sather language extension. The extensions defined here are:
FORTRAN: interface to a superset of ANSI Fortran 77, X3.9-1978
C: interface to ANSI C, X3.159-1989
Interfaces to other languages, or alternate interfaces to C and Fortran, may be designated in the future using other identifiers.
Each external language extension may have its own restrictions on what may legally appear in an external class of that language and what the semantic interpretation of the external class contents is. The legality and semantics of subtyping and code inclusion are defined by the language extension. For the C and Fortran extensions, routines that have no body (abstract signatures) specify the interface for Sather code to call external code. Calls to such routines are compiled using the external language's name binding and parameter passing conventions. Routines with a body in an external class specify the interface for external code to call Sather code; such routines also use the external language's name binding and parameter passing conventions. No routines and signatures in external classes may conflict (See We say that the method signature f conflicts with g when) , and the corresponding external object file must provide a function that conforms according to the rules of the language interface. There may be platform specific transformations of external routine names (e.g. prepended underscore or truncation); it is an error if the external language namespace implementation does not permit the resulting name. The implementations or environments of other languages may impose other unavoidable constraints.
An external class which interfaces to Fortran is designated with the language identifier 'FORTRAN'. The following Fortran types are built into the extended library:
Table 15-1.
Sather type | Fortran type | < $F_SCALAR? |
---|---|---|
F_REAL | real | Yes |
F_DOUBLE | double precision | Yes |
F_INTEGER | integer | Yes |
F_COMPLEX | complex | Yes |
F_DOUBLE_COMPLEX | double precision complex | Yes |
F_LOGICAL | logical | Yes |
F_CHARACTER | character, character*1 | Yes |
F_STRING | character*n, n=2, 3... | No |
F_ARRAY{T}, F_ARRAYn{T} | array types: T < $F_SCALAR | No |
F_ROUT{...} | subroutine type | No |
F_HANDLER | exception handler type | No |
These external types also define appropriate creation routines which may be used for convenient casting between Sather and Fortran types. Only the types listed above may be used in the abstract signatures defined in a Fortran external class. Methods defined in external Fortran classes that have bodies (are not abstract signatures) may have other types in their signature, but if they do, these routines are not visible to Fortran code. Fortran external classes may not contain abstract iterator signatures and may not be parameterized. Routines without bodies in Fortran external classes may not be overloaded.
Fortran implementations pass arguments by reference. The scalar types have conventional immutable semantics (i.e. there is no aliasing visible within Sather) and are subtypes of $F_SCALAR. The other types maintain reference semantics. The F_ROUT{...} types behave like Sather routine closures and are created with a similar syntax (See Closure creation expressions), but all argument types must be Fortran types and at creation all arguments must be left unbound. Fortran exception handlers may be passed by passing an F_HANDLER object, which is constructed from a Sather routine closure.
The Sather implementation must assure that changes to 'out' and 'inout' arguments passed to a Fortran routine are not observed until the Fortran routine returns. It is a fatal error for a Fortran routine to modify arguments with 'in' mode.