123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- \chapter{GENTRAN: A code generation package}
- \label{GENTRAN}
- \typeout{{GENTRAN: A code generation package}}
- {\footnotesize
- \begin{center}
- Barbara L. Gates \\
- RAND \\
- Santa Monica CA 90407-2138 \\
- U.S.A. \\[0.1in]
- Michael C. Dewar \\
- School of Mathematical Sciences, The University of Bath \\
- Bath BA2 7AY, England \\[0.05in]
- e--mail: mcd@maths.bath.ac.uk
- \end{center}
- }
- \ttindex{GENTRAN}
- GENTRAN is an automatic code GENerator and TRANslator which runs under
- \REDUCE. It constructs complete numerical programs based on sets of
- algorithmic specifications and symbolic expressions. Formatted
- FORTRAN, RATFOR, PASCAL or C code can be generated through a series of
- interactive commands or under the control of a template processing
- routine. Large expressions can be automatically segmented into
- subexpressions of manageable size, and a special file-handling
- mechanism maintains stacks of open I/O channels to allow output to be
- sent to any number of files simultaneously and to facilitate recursive
- invocation of the whole code generation process. GENTRAN provides the
- flexibility necessary to handle most code generation applications. It
- is designed to work with the SCOPE code optimiser.
- GENTRAN is a large system with a great many options. This section
- will only describe the FORTRAN generation facilities, and in broad
- outline only. The full manual is available as part of the \REDUCE\
- documentation.
- \section{Simple Use}
- A substantial subset of all expressions and statements in the \REDUCE{}
- programming language can be translated directly into numerical code.
- The {\bf GENTRAN} command takes a \REDUCE\ expression, statement, or
- procedure definition, and translates it into code in the target
- language.
- \begin{describe}{Syntax:}
- {\bf GENTRAN} {\it stmt} [ {\bf OUT} {\it f1,f2,\dots\ ,fn} ]{\it ;}
- \end{describe}
- {\it stmt} is any \REDUCE\ expression, statement (simple, compound, or
- group), or procedure definition that can be translated by GENTRAN into the
- target language.
- {\it stmt} may contain any number of calls
- to the special functions {\bf EVAL}, {\bf DECLARE}, and {\bf LITERAL}.
- {\it f1,f2,\dots\ ,fn } is an optional argument list containing one or more
- {\it f}'s, where each {\it f} is one of:
- \par
- \begin{tabular}{lll}
- {\it an atom} &= &an output file\\
- {\bf T} &= &the terminal\\
- {\bf NIL} &= &the current output file(s)\\
- \ttindex{ALL"!*} {\bf ALL!*} &= &all files currently open for output \\
- & & by GENTRAN (see section~\ref{GENTRAN:output})\\
- \end{tabular}
- If the optional part of the command is not given, generated code is simply
- written to the current output file. However, if it is
- given, then the current output file is temporarily overridden. Generated
- code is written to each file represented by
- {\it f1,f2,\dots\ ,fn} for this command only. Files which were open prior
- to the call to {\bf GENTRAN} will remain open after the call, and files
- which did not exist prior to the call will be created, opened, written to,
- and closed. The output stack will be exactly the same both before and
- after the call.
- {\bf GENTRAN} returns the name(s) of the file(s) to which code was
- written.
- \index{GENTRAN package ! example}
- \begin{verbatim}
- 1: GENTRANLANG!* := 'FORTRAN$
- 2: GENTRAN
- 2: FOR I:=1:N DO
- 2: V(I) := 0$
- DO 25001 I=1,N
- V(I)=0.0
- 25001 CONTINUE
- \end{verbatim}
- \section{Precision}
- \label{precision}
- \index{precision}\index{DOUBLE switch}
- By default {\bf GENTRAN} generates constants and type declarations in
- single precision form. If the user requires double precision output
- then the switch {\bf DOUBLE} must be set {\bf ON}.
- \index{PRECISION command}\index{PRINT"!-PRECISION command}
- To ensure the correct number of floating point digits are
- generated it may be necessary to use either the {\bf PRECISION} or
- {\bf PRINT!-PRECISION} commands. The former alters the number of
- digits \REDUCE\ calculates, the latter only the number of digits
- \REDUCE\ prints. Each takes an integer argument. It is not possible to set
- the printed precision higher than the actual precision. Calling {\bf
- PRINT!-PRECISION} with a negative argument causes the printed
- precision to revert to the actual precision.
- \subsection{The EVAL Function}
- \label{eval}
- \begin{describe}{Syntax:}
- {\bf EVAL} {\it exp}
- \end{describe}\ttindex{EVAL}
- \begin{describe}{Argument:}
- {\it exp} is any \REDUCE\ expression or statement which, after evaluation
- by \REDUCE, results in an expression that can be translated by
- GENTRAN into the target language.
- \end{describe}
- When {\bf EVAL} is called on an expression which is to be translated, it
- tells {\bf GENTRAN} to give the expression to \REDUCE\ for evaluation
- first, and then to translate the result of that evaluation.
- \begin{verbatim}
- f;
- 2
- 2*X - 5*X + 6
- \end{verbatim}
- We wish to generate an assignment statement for the quotient
- of F and its derivative.
- \begin{verbatim}
- 1: GENTRAN
- 1: Q := EVAL(F)/EVAL(DF(F,X))$
- Q=(2.0*X**2-(5.0*X)+6.0)/(4.0*X-5.0)
- \end{verbatim}
- \subsection{The :=: Operator}
- \index{:=:}
- \label{rsetq}\index{GENTRAN ! preevaluation}\index{rsetq operator}
- In many applications, assignments must be generated in which the
- left-hand side is some known variable name, but the
- right-hand side is an expression that must be evaluated. For
- this reason, a special operator is provided to indicate that the expression
- on the right-hand side is to be evaluated prior to translation. This
- special operator is {\bf :=:} ({\em i.e.} the usual \REDUCE\ assignment operator
- with an extra ``:'' on the right).
- \begin{describe}{\example}
- \begin{verbatim}
- 1: GENTRAN
- 1: DERIV :=: DF(X^4-X^3+2*x^2+1,X)$
- DERIV=4.0*X**3-(3.0*X**2)+4.0*X
- \end{verbatim}
- \end{describe}
- \subsection{The ::= Operator}
- \label{lsetq}
- \index{matrices ! in GENTRAN}
- When assignments to matrix or array elements must be generated, many
- times the indices of the element must be evaluated first. The special
- operator\index{::=}\index{lsetq operator}
- {\bf ::=} can be used within a call to {\bf GENTRAN}
- to indicate that the indices of the matrix or
- array element on the left-hand side of the assignment are to
- be evaluated prior to translation. (This is the usual \REDUCE{}
- assignment operator with an extra ``:'' on the left.)
- \begin{describe}{\example}
- We wish to generate assignments which assign zeros to all elements
- on the main diagonal of M, an n x n matrix.
- \begin{verbatim}
- 10: FOR j := 1 : 8 DO
- 10: GENTRAN
- 10: M(j,j) ::= 0$
- M(1,1)=0.0
- M(2,2)=0.0
- :
- :
- M(8,8)=0.0
- \end{verbatim}
- \end{describe}
- {\bf LSETQ} may be used interchangeably with {\bf ::=} on input.\ttindex{LSETQ}
- \subsection{The ::=: Operator}
- \label{lrsetq}
- \index{::=:} \index{lrsetq operator}
- In applications in which evaluated expressions are to be assigned to
- array elements with evaluated subscripts, the {\bf ::=:} operator can be
- used. It is a combination of the {\bf ::=} and {\bf :=:} operators described
- in sections~\ref{rsetq} and ~\ref{lsetq}.
- \index{matrices ! in GENTRAN}
- \begin{describe}{\example}
- The following matrix, M, has been derived symbolically:
- \newpage
- \begin{verbatim}
- ( A 0 -1 1)
- ( )
- ( 0 B 0 0)
- ( )
- ( -1 0 C -1)
- ( )
- ( 1 0 -1 D)
- \end{verbatim}
- We wish to generate assignment statements for those elements
- on the main diagonal of the matrix.
- \begin{verbatim}
- 10: FOR j := 1 : 4 DO
- 10: GENTRAN
- 10: M(j,j) ::=: M(j,j)$
- M(1,1)=A
- M(2,2)=B
- M(3,3)=C
- M(4,4)=D
- \end{verbatim}
- \end{describe}
- The alternative alphanumeric identifier associated with {\bf ::=:} is
- {\bf LRSETQ}.\ttindex{LRSETQ}
- \section{Explicit Type Declarations}
- \label{explicit:type}
- Type declarations are automatically generated each time a subprogram
- heading is generated. Type declarations are constructed
- from information stored in the GENTRAN symbol table. The user
- can place entries into the symbol table explicitly through calls
- to the special GENTRAN function {\bf DECLARE}.\index{DECLARE function}
- \begin{describe}{Syntax:}
- {\bf \ \ DECLARE} {\it v1,v2,\dots\ ,vn} {\bf :} {\it type;}
- or
- \begin{tabular}{ll}
- {\bf DECLARE}\\
- {\bf $<$$<$}\\
- &{\it v11,v12,\dots\ ,v1n} {\bf :} {\it type1;}\\
- &{\it v21,v22,\dots\ ,v2n} {\bf :} {\it type2;}\\
- & :\\
- & :\\
- &{\it vn1,vnn,\dots\ ,vnn} {\bf :} {\it typen;}\\
- {\bf $>$$>$}{\it ;}
- \end{tabular}
- \end{describe}
- \begin{describe}{Arguments:}
- Each {\it v1,v2,\dots\ ,vn} is a list of one or more variables
- (optionally subscripted to indicate array dimensions), or
- variable ranges (two letters separated by a ``-''). {\it v}'s are
- not evaluated unless given as arguments to {\bf EVAL}.
- Each {\it type} is a variable type in the target language. Each
- must be an atom, optionally preceded by the atom {\bf IMPLICIT}.
- \index{IMPLICIT option}
- {\it type}'s are not evaluated unless given as arguments to {\bf EVAL}.
- \end{describe}
- The {\bf DECLARE} statement can also be used to declare subprogram
- types ({\em i.e.\ } {\bf SUBROUTINE} or {\bf FUNCTION}) for
- \index{SUBROUTINE}\index{FUNCTION} FORTRAN and RATFOR code, and
- function types for all four languages.
- \section{Expression Segmentation}
- \label{segmentation}\index{segmenting expressions}
- Symbolic derivations can easily produce formulas that can be anywhere
- from a few lines to several pages in length. Such formulas
- can be translated into numerical assignment statements, but unless they
- are broken into smaller pieces they may be too long for a compiler
- to handle. (The maximum number of continuation lines for one statement
- allowed by most FORTRAN compilers is only 19.) Therefore GENTRAN
- \index{continuation lines}
- contains a segmentation facility which automatically {\it segments},
- or breaks down unreasonably large expressions.
- The segmentation facility generates a sequence of assignment
- statements, each of which assigns a subexpression to an automatically
- generated temporary variable. This sequence is generated in such a
- way that temporary variables are re-used as soon as possible, thereby
- keeping the number of automatically generated variables to a minimum.
- The facility can be turned on or off by setting the mode
- \index{GENTRANSEG switch} switch {\bf GENTRANSEG} accordingly ({\em
- i.e.\ }by calling the \REDUCE\ function {\bf ON} or {\bf OFF} on it). The user
- can control the maximum allowable expression size by setting the
- \ttindex{MAXEXPPRINTLEN"!*}
- variable {\bf MAXEXPPRINTLEN!*} to the maximum number of characters
- allowed in an expression printed in the target language (excluding
- spaces automatically printed by the formatter). The {\bf GENTRANSEG}
- switch is on initially, and {\bf MAXEXPPRINTLEN!*} is initialised to
- 800.
- \section{Template Processing}\label{GENTRAN:template}
- \index{GENTRAN ! templates}\index{templates}\index{code templates}
- In some code generation applications pieces of the target numerical
- program are known in advance. A {\it template} file containing a
- program outline is supplied by the user, and formulas are derived in
- \REDUCE, converted to numerical code, and inserted in the corresponding
- places in the program outline to form a complete numerical program. A
- template processor is provided by GENTRAN for use in these
- applications.
- \label{templates}\index{GENTRANIN command}
- \begin{describe}{Syntax:}
- {\bf GENTRANIN} {\it f1,f2,\dots\ ,fm} [{\bf OUT} {\it f1,f2,\dots\
- ,fn\/}]{\it ;}
- \end{describe}
- \begin{describe}{Arguments:}
- {\it f1,f2,\dots\ ,fm\/} is an argument list containing one or more
- {\it f\/}'s,
- where each {\it f\/} is one of:
- \begin{center}
- \begin{tabular}{lll}
- {\it an atom}& = &a template (input) file\\
- {\bf T}& = &the terminal\\
- \end{tabular}
- \end{center}
- {\it f1,f2,\dots\ ,fn\/} is an optional argument list containing one or more
- {\it f\/}'s, where each {\it f\/} is one of:
- \begin{center}
- \begin{tabular}{lll}
- {\it an atom}& = &an output file\\
- {\bf T}& = &the terminal\\
- {\bf NIL}& = &the current output file(s)\\
- {\bf ALL!*}& = &all files currently open for output \\
- & & by GENTRAN (see section~\ref{GENTRAN:output}) \\
- \end{tabular}
- \end{center}
- \end{describe}
- {\bf GENTRANIN} processes each template file {\it f1,f2,\dots\ ,fm}
- sequentially.
- A template file may contain any number of parts, each of which
- is either an active or an inactive part. All active parts start with
- the character sequence {\bf ;BEGIN;} and end with {\bf ;END;}. The end
- of the template file is indicated by an extra {\bf ;END;} character
- sequence.\index{;BEGIN; marker} \index{;END; marker}
- Inactive parts of template files are assumed to contain code in the
- target language. All inactive parts are
- copied to the output.
- Active parts may contain any number of \REDUCE\ expressions, statements,
- and commands. They are not copied directly to the output. Instead,
- they are given to \REDUCE\ for evaluation in algebraic mode. All output
- generated by each evaluation is sent to the output file(s). Returned
- values are only printed on the terminal.\index{GENTRAN ! preevaluation}
- Active parts will most likely contain calls to {\bf GENTRAN} to
- generate code. This means that the result of processing a
- template file will be the original template file with all active
- parts replaced by generated code.
- If {\bf OUT} {\it f1,f2,\dots\ ,fn} is not given, generated code is simply
- written to the current-output file.
- However, if {\bf OUT} {\it f1,f2,\dots\ ,fn}
- is given, then the current-output file
- is temporarily overridden. Generated code is written to each file
- represented by {\it f1,f2,\dots\ ,fn} for this command only. Files
- which were open prior to the call to {\bf GENTRANIN} will remain open
- after the call, and files which did not exist prior to the call will
- be created, opened, written to, and closed. The output-stack will be
- exactly the same both before and after the call.
- {\bf GENTRANIN} returns the names of all files written to by this
- command.
- \newpage
- \begin{describe}{\example}
- Suppose we wish to generate a FORTRAN subprogram to compute the
- determinant of a 3 x 3 matrix. We can construct a template
- file with an outline of the FORTRAN subprogram and \REDUCE\ and
- GENTRAN commands to fill it in:
- \index{matrices ! in GENTRAN}
- Contents of file {\tt det.tem}:
- \end{describe}
- \begin{verbatim}
- REAL FUNCTION DET(M)
- REAL M(3,3)
- ;BEGIN;
- OPERATOR M$
- MATRIX MM(3,3)$
- MM := MAT( (M(1,1),M(1,2),M(1,3)),
- (M(2,1),M(2,2),M(2,3)),
- (M(3,1),M(3,2),M(3,3)) )$
- GENTRAN DET :=: DET(MM)$
- ;END;
- RETURN
- END
- ;END;
- \end{verbatim}
- \begin{describe}{}
- Now we can generate a FORTRAN subprogram with the following
- \REDUCE\ session:
- \begin{verbatim}
- 1: GENTRANLANG!* := 'FORTRAN$
- 2: GENTRANIN
- 2: "det.tem"
- 2: OUT "det.f"$
- \end{verbatim}
- Contents of file det.f:
- \end{describe}
- \begin{verbatim}
- REAL FUNCTION DET(M)
- REAL M(3,3)
- DET=M(3,3)*M(2,2)*M(1,1)-(M(3,3)*M(2,1)*M(1,2))-(M(3,2)
- . *M(2,3)*M(1,1))+M(3,2)*M(2,1)*M(1,3)+M(3,1)*M(2,3)*M(1
- . ,2)-(M(3,1)*M(2,2)*M(1,3))
- RETURN
- END
- \end{verbatim}
- \section{Output Redirection}\label{GENTRAN:output}
- \index{GENTRAN ! file output}
- \index{GENTRANOUT command}\index{GENTRANSHUT command}
- The {\bf GENTRANOUT} and {\bf GENTRANSHUT} commands are identical to
- the \REDUCE\ {\bf OUT} and {\bf SHUT} commands with the following
- exceptions:
- \begin{itemize}
- \item {\bf GENTRANOUT} and {\bf GENTRANSHUT} redirect {\it only\/}
- code which is printed as a side effect of GENTRAN commands.
- \item {\bf GENTRANOUT} allows more than one file name to be given
- to indicate that generated code is to be sent to two or more
- files. (It is particularly convenient to be able to
- have generated code sent to
- the terminal screen and one or more file simultaneously.)
- \item {\bf GENTRANOUT} does not automatically erase existing files; it
- prints a warning message on the terminal and asks the user whether the
- existing file should be erased or the whole command be aborted.
- \end{itemize}
|