
% Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
% All rights reserved.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are
% met:
%
%     - Redistributions of source code must retain the above copyright
%       notice, this list of conditions and the following disclaimer.
%
%     - Redistributions in binary form must reproduce the above copyright
%       notice, this list of conditions and the following disclaimer in
%       the documentation and/or other materials provided with the
%       distribution.
%
%     - Neither the name of The Numerical ALgorithms Group Ltd. nor the
%       names of its contributors may be used to endorse or promote products
%       derived from this software without specific prior written permission.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
% IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
% TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
% PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
% OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
% EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES-- LOSS OF USE, DATA, OR
% PROFITS-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
% LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
% SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

% *********************************************************************
\head{chapter}{Input Files and Output Styles}{ugInOut}
% *********************************************************************

In this chapter we discuss how to collect \Language{} statements
and commands into files and then read the contents into the
workspace.
We also show how to display the results of your computations in
several different styles including \TeX{}, FORTRAN and
monospace two-dimensional format.\footnote{\TeX{} is a
trademark of the American Mathematical Society.}

The printed version of this book uses the \Language{}
\TeX{} output formatter.
When we demonstrate a particular output style, we will need to
turn \TeX{} formatting off and the output style on so
that the correct output is shown in the text.

% *********************************************************************
\head{section}{Input Files}{ugInOutIn}
% *********************************************************************
%
In this section we explain what an {\it input file} is and
\index{file!input}
why you would want to know about it.
We discuss where \Language{} looks for input files and how you can
direct it to look elsewhere.
We also show how to read the contents of an input file into the
\spadgloss{workspace} and how to use the \spadgloss{history}
facility to generate an input file from the statements you have
entered directly into the workspace.

An {\it input} file contains \Language{} expressions and system
commands.
Anything that you can enter directly to \Language{} can be put
into an input file.
This is how you save input functions and expressions that you wish
to read into \Language{} more than one time.

To read an input file into \Language{}, use the \spadsys{)read}
system command.
\syscmdindex{read}
For example, you can read a file in a particular directory by issuing
\begin{verbatim}
)read /spad/src/input/matrix.input
\end{verbatim}
The ``{\bf .input}'' is optional; this also works:
\begin{verbatim}
)read /spad/src/input/matrix
\end{verbatim}
What happens if you just enter
\spadsys{)read matrix.input} or even \spadsys{)read matrix}?
\Language{} looks in your current working directory for input files
that are not qualified by a directory name.
Typically, this directory is the directory from which you invoked
\Language{}.
To change the current working directory, use the \spadsys{)cd} system command.
The command \spadsys{)cd} by itself shows the current
working
\index{directory!default for searching}
directory.
\syscmdindex{cd}
To change it to
\index{file!input!where found}
the \spadsys{src/input} subdirectory for user ``babar'',
issue
\begin{verbatim}
)cd /u/babar/src/input
\end{verbatim}
\Language{} looks first in this directory for an input file.
If it is not found, it looks in the system's directories, assuming
you meant some input file that was provided with \Language{}.

\beginImportant
If you have the \Language{} history facility turned on (which it is
by default), you can save all the lines you have entered into the
workspace by entering
\begin{verbatim}
)history )write
\end{verbatim}
\syscmdindex{history )write}

\Language{} tells you what input file to edit to see your
statements.
The file is in your home directory or in the directory you
specified with \spadsys{)cd}.
\syscmdindex{cd}
\endImportant

In \spadref{ugLangBlocks}
we discuss using indentation in input files to group statements
into {\it blocks.}

% *********************************************************************
\head{section}{The .fricas.input File}{ugInOutSpadprof}
% *********************************************************************

When \Language{} starts up, it tries to read the input file
{\bf .fricas.input} from your home
\index{start-up profile file}
directory.
\index{file!start-up profile}
It there is no {\bf .fricas.input} in your home directory, it reads the copy
located in its own {\bf src/input} directory.
\index{file!.fricas.input @{\bf .fricas.input}}
The file usually contains
system commands to personalize your \Language{} environment.
In the remainder of this section we mention a few things
that users frequently place in their
{\bf .fricas.input} files.

In order to have FORTRAN output always produced from your
computations, place the system command
\spadsys{)set output fortran on}
in {\bf .fricas.input}.
\syscmdindex{quit}
If you do want to be prompted for confirmation when you issue
the \spadsys{)quit} system command, place
\spadsys{)set quit protected}
in {\bf .fricas.input}.
\syscmdindex{set quit protected}
If you then decide that you do not want to be prompted, issue
\spadsys{)set quit unprotected}.
\syscmdindex{set quit unprotected}
This is the default setting
% so that new users do not leave \Language{}
% inadvertently.
\footnote{The
system command \spadsys{)pquit} always prompts you for
confirmation.}

To see the other system variables you can set, issue \spadsys{)set}
or use the \HyperName{} {\bf Settings} facility to view and change
\Language{} system variables.

% *********************************************************************
\head{section}{Common Features of Using Output Formats}{ugInOutOut}
% *********************************************************************

In this section we discuss how to start and stop the display
\index{output formats!common features}
of the different output formats and how to send the output to the
screen or to a file.
\index{file!sending output to}
To fix ideas, we use FORTRAN output format for most of the
examples.

You can use the \spadsys{)set output}
system
\index{output formats!starting}
command to
\index{output formats!stopping}
toggle or redirect the different kinds of output.
\syscmdindex{set output}
The name of the kind of output follows ``output'' in the command.
The names are

\begin{texonly}
\begin{tabular}{@{}ll}
\bf fortran & for FORTRAN output. \\
\bf algebra & for monospace two-dimensional mathematical output. \\
\bf tex     & for \TeX{} output. \\
\bf mathml  & for Math ML output. \\
\bf texmacs & for Texmacs output. \\
\end{tabular}
\end{texonly}
\begin{htonly}
\begin{description}
\item[fortran]  for FORTRAN output.
\item[algebra]  for monospace two-dimensional mathematical output.
\item[tex]      for \TeX{} output.
\item[mathml]   for Math ML output.
\item[texmacs]  for Texmacs output.
\end{description}
\end{htonly}

For example, issue \spadsys{)set output fortran on} to turn on
FORTRAN format and
issue \spadsys{)set output fortran off} to turn it off.
By default, {\tt algebra} is {\tt on} and all others are {\tt off}.
\syscmdindex{set output fortran}
When output is started, it is sent to the screen.
To send the output to a file, give the file name without
\index{output formats!sending to file}
directory or extension.
\Language{} appends a file extension depending on the kind of
output being produced.
\xtc{
Issue this to redirect FORTRAN output to, for example, the file
{\bf linalg.sfort}.
}{
\spadcommand{)set output fortran linalg}
}
\nullXtc{
You must {\it also} turn on the creation of FORTRAN output.
The above just says where it goes if it is created.
}{
\spadcommand{)set output fortran on}
}
In what directory is this output placed?
It goes into the directory from which you started \Language{},
or if you have used the \spadsys{)cd} system command, the one
that you specified with \spadsys{)cd}.
\syscmdindex{cd}
You should use \spadsys{)cd} before you send the output to the file.

\nullXtc{
You can always direct output back to the screen by issuing this.
\index{output formats!sending to screen}
}{
\spadcommand{)set output fortran console}
}
\nullXtc{
Let's make sure FORTRAN formatting is off so that nothing we
do from now on produces FORTRAN output.
}{
\spadcommand{)set output fortran off}
}
\nullXtc{
We also delete the demonstrated output file we created.
}{
\spadcommand{)system rm linalg.sfort}
}

You can abbreviate the words ``\spad{on},'' ``\spad{off}'' and
``\spad{console}'' to the minimal number
of characters needed to distinguish them.
Because of this, you cannot send output to files called
{\bf on.sfort, off.sfort, of.sfort,
console.sfort, consol.sfort} and so on.

The width of the output on the page is set by
\index{output formats!line length}
\spadsys{)set output length}
for all formats except FORTRAN.
\syscmdindex{set output length}
Use \spadsys{)set fortran fortlength} to
change the FORTRAN line length from its default value of \spad{72}.

% *********************************************************************
\head{section}{Monospace Two-Dimensional Mathematical Format}{ugInOutAlgebra}
% *********************************************************************

This is the default output format for \Language{}.
\syscmdindex{set output algebra}
It is usually on when you start the system.
\index{output formats!monospace 2D}
\index{monospace 2D output format}

\nullXtc{
If it is not, issue this.
}{
\spadcommand{)set output algebra on \bound{algon}}
}
\nullXtc{
Since the printed version of this book
(as opposed to the \HyperName{} version)
shows output produced by the
\TeX{} output formatter,
let us temporarily turn off
\TeX{} output.
}{
\spadcommand{)set output tex off \bound{texoff}}
}
\nullXtc{
Here is an example of what it looks like.
}{
\spadcommand{matrix [[i*x^i + j*\%i*y^j for i in 1..2] for j in 3..4] \free{algon texoff}}
}
\begin{verbatim}
+     3           3     2+
|3%i y  + x  3%i y  + 2x |
|                        |
|     4           4     2|
+4%i y  + x  4%i y  + 2x +
\end{verbatim}

\nullXtc{
Issue this to turn off this kind of formatting.
}{
\spadcommand{)set output algebra off}
}
\nullXtc{
Turn \TeX{} output on again.
}{
\spadcommand{)set output tex on}
}

The characters used for the matrix brackets above are rather ugly.
You get this character set when you issue
\index{character set}
\spadsys{)set output characters plain}.
\syscmdindex{set output characters}
This character set should be used when your machine or your
version of \Language{}
does not support Unicode character set.
If your machine and your version of \Language{} support Unicode, issue
\spadsys{)set output characters default}
to get better looking output.

% *********************************************************************
\head{section}{TeX Format}{ugInOutTeX}
% *********************************************************************

\Language{} can produce \TeX{} output for your
\index{output formats!TeX @{\TeX}}
expressions.
\index{TeX output format @{\TeX} output format}
The output is produced using macros from the
\LaTeX{} document preparation system by
Leslie Lamport.\footnote{See Leslie Lamport, {\it LaTeX: A Document
Preparation System,} Reading, Massachusetts: Addison-Wesley
Publishing Company, Inc., 1986.}
The printed version of this book was produced using this formatter.

\noOutputXtc{
To turn on \TeX{} output formatting, issue this.
\syscmdindex{set output tex}
}{
\spadcommand{)set output tex on \bound{texon}}
}
Here is an example of its output.
\begin{verbatim}
matrix [[i*x^i + j*\%i*y^j for i in 1..2] for j in 3..4]

\begin{fricasmath}{1}
\begin{MATRIX}{2}3\TIMES \ImaginaryI \TIMES \SUPER{\SYMBOL{y}}{3}+\SYMBOL{x}&%
3\TIMES \ImaginaryI \TIMES \SUPER{\SYMBOL{y}}{3}+2\TIMES \SUPER{\SYMBOL{x}}{2%
}\\4\TIMES \ImaginaryI \TIMES \SUPER{\SYMBOL{y}}{4}+\SYMBOL{x}&4\TIMES %
\ImaginaryI \TIMES \SUPER{\SYMBOL{y}}{4}+2\TIMES \SUPER{\SYMBOL{x}}{2}%
\end{MATRIX}%
\end{fricasmath}
\end{verbatim}
\begin{texonly}
With the definition of the fricasmath environment as defined in
fricasmath.sty this formats as
\begin{fricasmath}{1}
\begin{MATRIX}{2}
3\TIMES \ImaginaryI \TIMES \SUPER{\SYMBOL{y}}{3}+\SYMBOL{x}&%
3\TIMES \ImaginaryI \TIMES \SUPER{\SYMBOL{y}}{3}+2\TIMES \SUPER{\SYMBOL{x}}{2%
}\\4\TIMES \ImaginaryI \TIMES \SUPER{\SYMBOL{y}}{4}+\SYMBOL{x}&4\TIMES %
\ImaginaryI \TIMES \SUPER{\SYMBOL{y}}{4}+2\TIMES \SUPER{\SYMBOL{x}}{2}%
\end{MATRIX}%
\end{fricasmath}
\end{texonly}
To turn \TeX{} output formatting off, issue
\spadsys{)set output tex off}.
The \LaTeX{} macros in the output generated by \Language{}
are generic. See the source file of \spadtype{TexFormat} for
appropriate definitions of these commands.

% *********************************************************************
\head{section}{Math ML Format}{ugInOutMathML}
% *********************************************************************

\Language{} can
\index{output formats!Math ML Format}
produce Math ML format output for your
\index{Math ML Format}
expressions.

\noOutputXtc{
To turn Math ML Format on, issue this.
\syscmdindex{set output mathml}
}{
\spadcommand{)set output mathml on}
}
Here is an example of its output.
\begin{verbatim}
x+sqrt(2)

<math xmlns="http://www.w3.org/1998/Math/MathML" mathsize="big" display="block">
<mrow><mi>x</mi><mo>+</mo><msqrt><mrow><mn>2</mn></mrow></msqrt></mrow>
</math>
\end{verbatim}
\noOutputXtc{
To turn Math ML Format output formatting off, issue this.
}{
\spadcommand{)set output mathml off}
}
%
% *********************************************************************
\head{section}{Texmacs Format}{ugInOutTexmacs}
% *********************************************************************

\Language{} can
\index{output formats!Texmacs Format}
produce Texmacs Scheme format output for your
\index{Texmacs Format}
expressions.  This is mostly useful for interfacing with Texmacs.

\noOutputXtc{
To turn Texmacs Format on, issue this.
\syscmdindex{set output texmacs}
}{
\spadcommand{)set output texmacs on}
}
Here is an example of its output.
\begin{verbatim}
x+sqrt(2)

scheme: (with "mode" "math"
(concat (concat  "x" ) "+" (sqrt (concat  "2" )))
)
\end{verbatim}
\noOutputXtc{
To turn Texmacs Format output formatting off, issue this.
}{
\spadcommand{)set output texmacs off}
}

% *********************************************************************
\head{section}{FORTRAN Format}{ugInOutFortran}
% *********************************************************************

In addition to turning FORTRAN output on and off and stating where the
\index{output formats!FORTRAN}
output should be placed, there are many options that control the
\index{FORTRAN output format}
appearance of the generated code.
In this section we describe some of the basic options.
Issue \spadsys{)set fortran} to see a full list with their current
settings.

The output FORTRAN expression usually begins in column 7.
If the expression needs more than one line, the ampersand character
\spadSyntax{&} is used in column 6.
Since some versions of FORTRAN have restrictions on the number of lines
per statement, \Language{} breaks long expressions into segments with
a maximum of 1320 characters (20 lines of 66 characters) per segment.
\syscmdindex{set fortran}
If you want to change this, say, to 660 characters,
issue the system command
\syscmdindex{set fortran explength}
\spadsys{)set fortran explength 660}.
\index{FORTRAN output format!breaking into multiple statements}
You can turn off the line breaking by issuing
\spadsys{)set fortran segment off}.
\syscmdindex{set fortran segment}
Various code optimization levels are available.
%
\noOutputXtc{
FORTRAN output is produced after you issue this.
\syscmdindex{set output fortran}
}{
\spadcommand{)set output fortran on \bound{forton}}
}
\noOutputXtc{
For the initial examples, we set the optimization level to 0, which is the
lowest level.
\syscmdindex{set fortran optlevel}
}{
\spadcommand{)set fortran optlevel 0 \bound{opt0}\free{forton}}
}
\noOutputXtc{
The output is usually in columns 7 through 72, although fewer columns
are used in the following examples so that the output
\index{FORTRAN output format!line length}
fits nicely on the page.
}{
\spadcommand{)set fortran fortlength 60}
}
\xtc{
By default, the output goes to the screen and is displayed
before the standard \Language{} two-dimensional output.
In this example, an
assignment to the variable \spad{R1} was generated because this is
the result of step 1.
}{
\spadcommand{(x+y)^3 \free{opt0}}
}
\xtc{
Here is an example that illustrates the line breaking.
}{
\spadcommand{(x+y+z)^3 \free{opt0}}
}

Note in the above examples that integers are generally converted to
\index{FORTRAN output format!integers vs. floats}
floating point numbers, except in exponents.
This is the default behavior but can be turned off by issuing
\spadsys{)set fortran ints2floats off}.
\syscmdindex{set fortran ints2floats}
The rules governing when the conversion is done are:
\begin{enumerate}
\item If an integer is an exponent, convert it to a floating point
number if it is greater than 32767 in absolute value, otherwise leave it
as an integer.
\item Convert all other integers in an expression to floating
point numbers.
\end{enumerate}
These rules only govern integers in expressions.
Numbers generated by \Language{} for \spad{DIMENSION} statements are also
integers.

To set the type of generated FORTRAN data,
\index{FORTRAN output format!data types}
use one of the following:
\begin{verbatim}
)set fortran defaulttype REAL
)set fortran defaulttype INTEGER
)set fortran defaulttype COMPLEX
)set fortran defaulttype LOGICAL
)set fortran defaulttype CHARACTER
\end{verbatim}

\xtc{
When temporaries are created, they are given a default type of
{\tt REAL.}
Also, the {\tt REAL} versions of functions are used by default.
}{
\spadcommand{sin(x) \free{opt1}}
}
\noOutputXtc{
At optimization level 1, \Language{} removes common subexpressions.
\index{FORTRAN output format!optimization level}
\syscmdindex{set fortran optlevel}
}{
\spadcommand{)set fortran optlevel 1 \bound{opt1}\free{forton}}
}
\xtc{
}{
\spadcommand{(x+y+z)^3 \free{opt1}}
}
\noOutputXtc{
This changes the precision to {\tt DOUBLE}.
\syscmdindex{set fortran precision double}
Substitute \spad{single} for \spad{double}
\index{FORTRAN output format!precision}
to return to single precision.
\syscmdindex{set fortran precision single}
}{
\spadcommand{)set fortran precision double \free{opt1}\bound{double1}}
}
\xtc{
Complex constants display the precision.
}{
\spadcommand{2.3 + 5.6*\%i  \free{double1}}
}
\xtc{
The function names that \Language{} generates depend on the chosen
precision.
}{
\spadcommand{sin \%e  \free{double1}}
}
\noOutputXtc{
Reset the precision to \spad{single} and look at these two
examples again.
}{
\spadcommand{)set fortran precision single \free{opt1}\bound{single1}}
}
\xtc{
}{
\spadcommand{2.3 + 5.6*\%i  \free{single1}}
}
\xtc{
}{
\spadcommand{sin \%e  \free{single1}}
}
\xtc{
Expressions that look like lists, streams, sets or matrices cause
array code to be generated.
}{
\spadcommand{[x+1,y+1,z+1] \free{opt1}}
}
\xtc{
A temporary variable is generated to be the name of the array.
\index{FORTRAN output format!arrays}
This may have to be changed in your particular application.
}{
\spadcommand{set[2,3,4,3,5] \free{opt1}}
}
\xtc{
By default, the starting index for generated FORTRAN arrays is \spad{0}.
}{
\spadcommand{matrix [[2.3,9.7],[0.0,18.778]] \free{opt1}}
}
\noOutputXtc{
To change the starting index for generated FORTRAN arrays to be \spad{1},
\syscmdindex{set fortran startindex}
issue this.
This value can only be \spad{0} or \spad{1}.
}{
\spadcommand{)set fortran startindex 1 \free{opt1}\bound{start1}}
}
\xtc{
Look at the code generated for the matrix again.
}{
\spadcommand{matrix [[2.3,9.7],[0.0,18.778]] \free{start1}}
}

% *********************************************************************
\head{section}{General Fortran-generation utilities in \Language{}}{ugGeneralFortran}
% *********************************************************************

This section describes more advanced facilities which are available to users
who wish to generate Fortran code from within \Language{}.  There are
facilities to manipulate templates, store type information, and generate
code fragments or complete programs.

% ----------------------------------------------------------------------
\head{subsection}{Template Manipulation}{ugGenForTemplate}
% ----------------------------------------------------------------------

A template is a skeletal program which is ``fleshed out'' with data when
it is processed.  It is a sequence of {\em active} and {\em passive} parts:
active parts are sequences of \Language{} commands which are processed as if they
had been typed into the interpreter; passive parts are simply echoed
verbatim on the Fortran output stream.

Suppose, for example, that we have the following template, stored in
the file ``test.tem'':
\begin{verbatim}
-- A simple template
beginVerbatim
      DOUBLE PRECISION FUNCTION F(X)
      DOUBLE PRECISION X
endVerbatim
outputAsFortran("F",f)
beginVerbatim
      RETURN
      END
endVerbatim
\end{verbatim}
The passive parts lie between the two
tokens {\tt beginVerbatim} and \texht{\linebreak}{} {\tt endVerbatim}.  There
are two active statements: one which is simply a \Language{} (
{\tt --})
comment, and one which produces an assignment to the current value
of {\tt f}.  We could use it as follows:
\begin{verbatim}
(4) ->f := 4.0/(1+X^2)

           4
   (4)   ------
          2
         X  + 1

(5) ->processTemplate "test.tem"
      DOUBLE PRECISION FUNCTION F(X)
      DOUBLE PRECISION X
      F=4.0D0/(X*X+1.0D0)
      RETURN
      END

   (5)  "CONSOLE"
\end{verbatim}

(A more reliable method of specifying the filename will be introduced
below.)  Note that the Fortran assignment {\tt F=4.0D0/(X*X+1.0D0)}
automatically converted 4.0 and 1 into DOUBLE PRECISION numbers; in
general, the \Language{} Fortran generation facility will convert
anything which should be a floating point object into either
a Fortran REAL or DOUBLE PRECISION object.
\noOutputXtc{
Which alternative is used is determined by the command
}{
\spadcommand{)set fortran precision}
}

It is sometimes useful to end a template before the file itself ends (e.g. to
allow the template to be tested incrementally or so that a piece of text
describing how the template works can be included).  It is of course possible
to ``comment-out'' the remainder of the file.  Alternatively, the single token
{\tt endInput} as part of an active portion of the template will cause
processing to be ended prematurely at that point.

The \spadfun{processTemplate} command comes in two flavours.  In the first case,
illustrated above, it takes one argument of domain \spadtype{FileName},
the name of the template to be processed, and writes its output on the
current Fortran output stream.  In general, a filename can be generated
from {\em directory}, {\em name} and {\em extension} components, using
the operation \spadfun{filename}, as in
\begin{verbatim}
processTemplate filename("","test","tem")
\end{verbatim}
There is an alternative version of \spadfun{processTemplate}, which
takes two arguments (both of domain \spadtype{FileName}).  In this case the
first argument is the name of the template to be processed, and the
second is the file in which to write the results.  Both versions return
the location of the generated Fortran code as their result
({\tt "CONSOLE"} in the above example).

It is sometimes useful to be able to mix active and passive parts of a
line or statement.  For example you might want to generate a Fortran
Comment describing your data set.  For this kind of application we
provide three functions as follows:
\begin{texonly}
\begin{center}
\begin{tabular}{p{1.8in}p{2.6in}}
\spadfun{fortranLiteral} & writes a string on the Fortran output stream \\
 & \\
\spadfun{fortranCarriageReturn} & writes a carriage return on the Fortran output stream \\
& \\
\spadfun{fortranLiteralLine} & writes a string followed by a return
on the Fortran output stream \\
\end{tabular}
\end{center}
\end{texonly}
\begin{htonly}
\newline
\spadfun{fortranLiteral}\tab{25}writes a string on the Fortran output stream\newline
\spadfun{fortranCarriageReturn}\tab{25}writes a carriage return on the Fortran output stream\newline
\spadfun{fortranLiteralLine}\tab{25}writes a string followed by a return on the Fortran output stream\newline
\end{htonly}
\xtc{
So we could create our comment as follows:
}{
\spadcommand{m := matrix [[1,2,3],[4,5,6]]\bound{m}}
}
\xtc{
}{
\spadcommand{fortranLiteralLine(concat ["C\ \ \ \ \ \ The\ Matrix\ has\ ", nrows(m)::String, "\ rows\ and\ ", ncols(m)::String, "\ columns"])\$FortranTemplate \free{m}}
}
\xtc{
or, alternatively:
}{
\spadcommand{fortranLiteral("C\ \ \ \ \ \ The\ Matrix\ has\ ")\$FortranTemplate}
}
\xtc{
}{
\spadcommand{fortranLiteral(nrows(m)::String)\$FortranTemplate}
}
\xtc{
}{
\spadcommand{fortranLiteral("\ rows\ and\ ")\$FortranTemplate}
}
\xtc{
}{
\spadcommand{fortranLiteral(ncols(m)::String)\$FortranTemplate\free{m}}
}
\xtc{
}{
\spadcommand{fortranLiteral("\ columns")\$FortranTemplate}
}
\noOutputXtc{
}{
\spadcommand{fortranCarriageReturn()\$FortranTemplate}
}

We should stress that these functions, together with the \spadfun{outputAsFortran}
function are the {\em only} sure ways
of getting output to appear on the Fortran output stream.  Attempts to use
\Language{} commands such as \spadfun{output} or \spadfunX{writeline} may appear to give
the required result when displayed on the console, but will give the wrong
result when Fortran and algebraic output are sent to differing locations.  On
the other hand, these functions can be used to send helpful messages to the
user, without interfering with the generated Fortran.

% ----------------------------------------------------------------------
\head{subsection}{Manipulating the Fortran Output Stream}{ugGneForManipulating}
% ----------------------------------------------------------------------
\texht{\exptypeindex{FortranOutputStackPackage}}{}

Sometimes it is useful to manipulate the Fortran output stream in a program,
possibly without being aware of its current value.  The main use of this is
for gathering type declarations (see ``Fortran Types'' below) but it can be useful
in other contexts as well.  Thus we provide a set of commands to manipulate
a stack of (open) output streams.  Only one stream can be written to at
any given time.  The stack is never empty---its initial value is the
console or the current value of the Fortran output stream, and can be
determined using
\xtc{
}{
\spadcommand{topFortranOutputStack()\$FortranOutputStackPackage}
}
(see below).
The commands available to manipulate the stack are:
\begin{texonly}
\begin{center}
\begin{tabular}{ll}
\spadfun{clearFortranOutputStack} & resets the stack to the console \\
 & \\
\spadfun{pushFortranOutputStack} & pushes a \spadtype{FileName} onto the stack \\
 & \\
\spadfun{popFortranOutputStack} & pops the stack \\
 & \\
\spadfun{showFortranOutputStack} & returns the current stack \\
 & \\
\spadfun{topFortranOutputStack} & returns the top element of the stack \\
\end{tabular}
\end{center}
\end{texonly}
\begin{htonly}
\newline
\spadfun{clearFortranOutputStack}\tab{25}resets the stack\newline
\spadfun{pushFortranOutputStack}\tab{25}pushes a \spadtype{FileName} onto the stack\newline
\spadfun{popFortranOutputStack}\tab{25}pops the stack\newline
\spadfun{showFortranOutputStack}\tab{25}returns the current stack\newline
\spadfun{topFortranOutputStack}\tab{25}returns the top element of the stack\newline
\end{htonly}
These commands are all part of \spadtype{FortranOutputStackPackage}.

% ----------------------------------------------------------------------
\head{subsection}{Fortran Types}{ugGenForTypes}
% ----------------------------------------------------------------------

When generating code it is important to keep track of the Fortran types of
the objects which we are generating.  This is useful for a number of reasons,
not least to ensure that we are actually generating legal Fortran code.  The
current type system is built up in several layers, and we shall describe each
in turn.

% ----------------------------------------------------------------------
\head{subsection}{FortranScalarType}{ugGenForScalarType}
% ----------------------------------------------------------------------
\texht{\exptypeindex{FortranScalarType}}{}

This domain represents the simple Fortran datatypes: REAL, DOUBLE PRECISION,
COMPLEX, LOGICAL, INTEGER, and CHARACTER.
It is possible to \spadfun{coerce} a \spadtype{String} or \spadtype{Symbol}
into the domain, test whether two objects are equal, and also apply
the predicate functions \spadfunFrom{real?}{FortranScalarType} etc.

% ----------------------------------------------------------------------
\head{subsection}{FortranType}{ugGenForType}
% ----------------------------------------------------------------------
\texht{\exptypeindex{FortranType}}{}

This domain represents ``full'' types: i.e., datatype plus array dimensions
(where appropriate) plus whether or not the parameter is an external
subprogram.  It is possible to \spadfun{coerce} an object of
\spadtype{FortranScalarType} into the domain or \spadfun{construct} one
from an element of \spadtype{FortranScalarType}, a list of
\spadtype{Polynomial Integer}s (which can of course be simple integers or
symbols) representing its dimensions, and
a \spadtype{Boolean} declaring whether it is external or not.  The list
of dimensions must be empty if the \spadtype{Boolean} is {\tt true}.
The functions \spadfun{scalarTypeOf}, \spadfun{dimensionsOf} and
\spadfun{external?} return the appropriate
parts, and it is possible to get the various basic Fortran Types via
functions like \spadfun{fortranReal}.
\xtc{
For example:
}{
\spadcommand{type:=construct(real,[i,10],false)\$FortranType}
}
\xtc{
or
}{
\spadcommand{type:=[real,[i,10],false]\$FortranType\bound{type}}
}
\xtc{
}{
\spadcommand{scalarTypeOf type\free{type}}
}
\xtc{
}{
\spadcommand{dimensionsOf type\free{type}}
}
\xtc{
}{
\spadcommand{external?  type\free{type}}
}
\xtc{
}{
\spadcommand{fortranLogical()\$FortranType}
}
\xtc{
}{
\spadcommand{construct(integer,[],true)\$FortranType}
}

% ----------------------------------------------------------------------
\head{subsection}{SymbolTable}{ugGenForSymbolTable}
% ----------------------------------------------------------------------
\texht{\exptypeindex{SymbolTable}}{}

This domain creates and manipulates a symbol table for generated Fortran code.
This is used by \spadtype{FortranProgram} to represent the types of objects in
a subprogram.  The commands available are:\newline
\begin{texonly}
\begin{center}
\begin{tabular}{ll}
\spadfun{empty} & creates a new \spadtype{SymbolTable} \\
 & \\
\spadfunX{declare} & creates a new entry in a table \\
 & \\
\spadfun{fortranTypeOf} & returns the type of an object in a table \\
 & \\
\spadfun{parametersOf} & returns a list of all the symbols in the table \\
 & \\
\spadfun{typeList} & returns a list of all objects of a given type \\
 & \\
\spadfun{typeLists} & returns a list of lists of all objects sorted by type \\
 & \\
\spadfun{externalList} & returns a list of all {\tt EXTERNAL} objects \\
 & \\
\spadfun{printTypes} & produces Fortran type declarations from a table\\
\end{tabular}
\end{center}
\end{texonly}
\begin{htonly}
\spadfun{empty}\tab{25}creates a new \spadtype{SymbolTable}\newline
\spadfunX{declare}\tab{25}creates a new entry in a table \newline
\spadfun{fortranTypeOf}\tab{25}returns the type of an object in a table \newline
\spadfun{parametersOf}\tab{25}returns a list of all the symbols in the table \newline
\spadfun{typeList}\tab{25}returns a list of all objects of a given type \newline
\spadfun{typeLists}\tab{25}returns a list of lists of all objects sorted by type \newline
\spadfun{externalList}\tab{25}returns a list of all {\tt EXTERNAL} objects \newline
\spadfun{printTypes}\tab{25}produces Fortran type declarations from a table\newline
\end{htonly}
\xtc{
}{
\spadcommand{symbols := empty()\$SymbolTable\bound{symbols}}
}
\xtc{
}{
\spadcommand{declare!(X, fortranReal()\$FortranType, symbols)\free{symbols}}
}
\xtc{
}{
\spadcommand{declare!(M,construct(real,[i,j],false)\$FortranType,symbols)\free{symbols}}
}
\xtc{
}{
\spadcommand{declare!([i,j], fortranInteger()\$FortranType, symbols)\free{symbols} \bound{i j} }
}
\xtc{
}{
\spadcommand{symbols\free{symbols}}
}
\xtc{
}{
\spadcommand{fortranTypeOf(i,symbols)\free{symbols i}}
}
\xtc{
}{
\spadcommand{typeList(real,symbols)\free{symbols}}
}
\xtc{
}{
\spadcommand{printTypes symbols\free{symbols}}
}

% ----------------------------------------------------------------------
\head{subsection}{TheSymbolTable}{ugGenForTheSymbolTable}
% ----------------------------------------------------------------------
\texht{\exptypeindex{TheSymbolTable}}{}

This domain creates and manipulates one global symbol table to be used, for
example, during template processing. It is
also used when
linking to external Fortran routines. The
information stored for each subprogram (and the main program segment, where
relevant) is:
\begin{itemize}
\item its name;
\item its return type;
\item its argument list;
\item and its argument types.
\end{itemize}
Initially, any information provided is deemed to be for the main program
segment.
\xtc{
Issuing the following command indicates that from now on all information
refers to the subprogram \spad{F}.
}{
\spadcommand{newSubProgram(F)\$TheSymbolTable}
}
\xtc{
It is possible to return to processing the main program segment by issuing
the command:
}{
\spadcommand{endSubProgram()\$TheSymbolTable}
}
The following commands exist:
\begin{texonly}
\begin{center}
\begin{tabular}{p{1.6in}p{2.8in}}
\spadfunX{returnType} & declares the return type of the current subprogram \\
 & \\
\spadfun{returnTypeOf} & returns the return type of a subprogram \\
 & \\
\spadfunX{argumentList} &  declares the argument list of the current subprogram \\
 & \\
\spadfun{argumentListOf} &  returns the argument list of a subprogram \\
 & \\
\spadfunX{declare} & provides type declarations for parameters of the current subprogram \\
 & \\
\spadfun{symbolTableOf} & returns the symbol table  of a subprogram \\
 & \\
\spadfun{printHeader} & produces the Fortran header for the current subprogram \\
\end{tabular}
\end{center}
\end{texonly}
\begin{htonly}
\newline
\spadfunX{returnType}\tab{25}declares the return type of the current subprogram \newline
\spadfun{returnTypeOf}\tab{25}returns the return type of a subprogram \newline
\spadfunX{argumentList}\tab{25}declares the argument list of the current subprogram \newline
\spadfun{argumentListOf}\tab{25}returns the argument list of a subprogram \newline
\spadfunX{declare}\tab{25}provides type declarations for parameters of the current subprogram \newline
\spadfun{symbolTableOf}\tab{25}returns the symbol table  of a subprogram \newline
\spadfun{printHeader}\tab{25}produce the Fortran header for the current subprogram \newline
\end{htonly}
In addition there are versions of these commands which are parameterised by
the name of a subprogram, and others parameterised by both the name of a
subprogram and by an instance of \spadtype{TheSymbolTable}.
\xtc{
}{
\spadcommand{newSubProgram(F)\$TheSymbolTable \bound{forPleasure}}
}
\xtc{
}{
\spadcommand{argumentList!(F, [X])\$TheSymbolTable\free{forPleasure}}
}
\xtc{
}{
\spadcommand{returnType!(F,real)\$TheSymbolTable \free{forPleasure}}
}
\xtc{
}{
\spadcommand{declare!(X,fortranReal(),F)\$TheSymbolTable \free{forPleasure}}
}
\xtc{
}{
\spadcommand{printHeader(F)\$TheSymbolTable\free{forPleasure}}
}

% ----------------------------------------------------------------------
\head{subsection}{Advanced Fortran Code Generation}{ugGenForAdvanced}
% ----------------------------------------------------------------------

This section describes facilities for representing Fortran statements, and
building up complete subprograms from them.

% ----------------------------------------------------------------------
\head{subsection}{Switch}{ugGenForSwitch}
% ----------------------------------------------------------------------
\texht{\exptypeindex{Switch}}{}

This domain is used to represent statements like {\tt x < y}.  Although
these can be represented directly in \Language{}, it is a little cumbersome.
% since currently \Language{} performs several transformations on
% conditional operators, for example {\tt x >= y } is transformed to
% {\tt not(x < y)}, which while logically equivalent may be different
% from desired result.

Instead we have a set of operations, such as \spadfun{LT} to represent
\spad{<},
to let us build such statements.  The available constructors are:
\begin{texonly}
\begin{center}
\begin{tabular}{ll}
\spadfun{LT} & $<$ \\
\spadfun{GT} & $>$ \\
\spadfun{LE} & $\leq$ \\
\spadfun{GE} & $\geq$ \\
\spadfun{EQ} & $=$ \\
\spadfun{AND} & $and$\\
\spadfun{OR} & $or$ \\
\spadfun{NOT} & $not$ \\
\end{tabular}
\end{center}
\end{texonly}
\begin{htonly}
\newline
\spadfun{LT}\tab{25}\texht{$<$}{<} \newline
\spadfun{GT}\tab{25}\texht{$>$}{>} \newline
\spadfun{LE}\tab{25}\texht{$\leq$}{<=} \newline
\spadfun{GE}\tab{25}\texht{$\geq$}{>=} \newline
\spadfun{EQ}\tab{25}\texht{$=$}{=} \newline
\spadfun{AND}\tab{25}\texht{$and$}{{\tt and}}\newline
\spadfun{OR}\tab{25}\texht{$or$}{{\tt or}} \newline
\spadfun{NOT}\tab{25}\texht{$not$}{{\tt not}} \newline
\end{htonly}
\xtc{
So for example:
}{
\spadcommand{LT(x,y)\$Switch}
}

% ----------------------------------------------------------------------
\head{subsection}{FortranCode}{ugGenForCode}
% ----------------------------------------------------------------------

This domain represents code segments or operations: currently assignments,
conditionals, blocks, comments, gotos, continues, various kinds of loops,
and return statements.
\xtc{
For example we can create quite a complicated conditional statement using
assignments, and then turn it into Fortran code:
}{
\spadcommand{c := cond(LT(X,Y),assign(F,X),cond(GT(Y,Z),assign(F,Y),assign(F,Z))\$FortranCode)\$FortranCode \bound{c}}
}
\xtc{
}{
\spadcommand{printCode c\free{c}}
}

The Fortran code is printed
on the current Fortran output stream.

% ----------------------------------------------------------------------
\head{subsection}{FortranProgram}{ugGenForProgram}
% ----------------------------------------------------------------------
\texht{\exptypeindex{FortranProgram}}{}

This domain is used to construct complete Fortran subprograms out of
elements of \spadtype{FortranCode}.  It is parameterised by the name of the
target subprogram (a \spadtype{Symbol}), its return type (from
\spadtype{Union}(\spadtype{FortranScalarType},``void'')),
its arguments (from \spadtype{List Symbol}), and
its symbol table (from \spadtype{SymbolTable}).  One can
\spadfun{coerce} elements of either \spadtype{FortranCode}
or \spadtype{Expression} into it.

\xtc{
First of all we create a symbol table:
}{
\spadcommand{symbols := empty()\$SymbolTable\bound{symbols}}
}
\xtc{
Now put some type declarations into it:
}{
\spadcommand{declare!([X,Y],fortranReal()\$FortranType,symbols)\free{symbols}}
}
\xtc{
Then (for convenience)
we set up the particular instantiation of \spadtype{FortranProgram}
}{
\spadcommand{FP := FortranProgram(F,real,[X,Y],symbols)\free{symbols}\bound{FP}}
}
\xtc{
Create an object of type \spadtype{Expression(Integer)}:
}{
\spadcommand{asp := X*sin(Y)\bound{asp}}
}
\xtc{
Now \spadfun{coerce} it into \spadtype{FP}, and print its Fortran form:
}{
\spadcommand{outputAsFortran(asp::FP)\free{FP asp}}
}

We can generate a \spadtype{FortranProgram} using \spadtype{FortranCode}.
For example:
\xtc{
Augment our symbol table:
}{
\spadcommand{declare!(Z,fortranReal()\$FortranType,symbols)\free{symbols}\bound{Z}}
}
\xtc{
prepare conditional:
}{
\spadcommand{cc := cond(LT(X,Y),assign(F,X),assign(F,Y))\$FortranCode \bound{cc}}
}
\xtc{
and transform the conditional expression we prepared earlier:
}{
\spadcommand{outputAsFortran([cc,returns()\$FortranCode]::FP) \free{FP cc Z}}
}
