Artifact 2a292563d47780a0664c64d88e82cad0f7da7ef01817fedf21e7afd97b0c512b:
- Executable file
r37/doc/manual2/gentran.tex
— part of check-in
[f2fda60abd]
at
2011-09-02 18:13:33
on branch master
— Some historical releases purely for archival purposes
git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/trunk/historical@1375 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 16382) [annotate] [blame] [check-ins using] [more...]
- Executable file
r38/doc/manual2/gentran.tex
— part of check-in
[f2fda60abd]
at
2011-09-02 18:13:33
on branch master
— Some historical releases purely for archival purposes
git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/trunk/historical@1375 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 16382) [annotate] [blame] [check-ins using]
\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}