<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE book PUBLIC 
    "-//OASIS//DTD DocBook XML V4.1.2//EN" 
    "docbook/docbookxx.dtd" [
<!ENTITY maxfunc SYSTEM "../madhouse/maxfunc.mad">
<!ENTITY newton1 SYSTEM "../madhouse/newton1.mad">
<!ENTITY newton2 SYSTEM "../madhouse/newton2.mad">
<!ENTITY quadratic SYSTEM "../madhouse/quadratic.mad">
<!ENTITY invsf SYSTEM "../madhouse/invsf.mad">
<!ENTITY truthtable SYSTEM "../madhouse/truthtable.mad">
<!ENTITY simpsfunc SYSTEM "../madhouse/simpsfunc.mad">
<!ENTITY simpsmain SYSTEM "../madhouse/simpsmain.mad">
<!ENTITY findroot SYSTEM "../madhouse/findroot.mad">
<!ENTITY transfunc SYSTEM "../madhouse/transfunc.mad">
<!ENTITY matrixmult SYSTEM "../madhouse/matrixmult.mad">
<!ENTITY jordan SYSTEM "../madhouse/jordan.mad">
<!ENTITY payroll SYSTEM "../madhouse/payroll.mad">
<!ENTITY altpayroll SYSTEM "../madhouse/altpayroll.mad">
<!ENTITY payrolltape SYSTEM "../madhouse/payrolltape.mad">
<!ENTITY mortgage SYSTEM "../madhouse/mortgage.mad">
<!ENTITY commutefunc SYSTEM "../madhouse/commutefunc.mad">
<!ENTITY commutemain SYSTEM "../madhouse/commutemain.mad">
<!ENTITY wordsearch SYSTEM "../madhouse/wordsearch.mad">
<!ENTITY factfunc SYSTEM "../madhouse/factfunc.mad">
<!ENTITY factmain SYSTEM "../madhouse/factmain.mad">
<!ENTITY gcdfunc SYSTEM "../madhouse/gcdfunc.mad">
<!ENTITY gcdmain SYSTEM "../madhouse/gcdmain.mad">
<!ENTITY tschebfunc SYSTEM "../madhouse/tschebfunc.mad">
<!ENTITY tschebmain SYSTEM "../madhouse/tschebmain.mad">
<!ENTITY scope1 SYSTEM "scope1.xml">
<!ENTITY scope2 SYSTEM "scope2.xml">
<!ENTITY scope3 SYSTEM "scope3.xml">
<!ENTITY scope4 SYSTEM "scope4.xml">
<!ENTITY retromuseum "http://catb.org/retro">

<!ENTITY scriptA "<emphasis>A</emphasis>">
<!ENTITY scriptF "<emphasis>B</emphasis>">
<!ENTITY scriptL "<emphasis>L</emphasis>">
<!ENTITY scriptM "<emphasis>M</emphasis>">
<!ENTITY scriptN "<emphasis>N</emphasis>">
<!ENTITY scriptS "<emphasis>S</emphasis>">
<!ENTITY scriptV "<emphasis>V</emphasis>">
<!ENTITY scriptl "<emphasis>l</emphasis>">

<!-- hack to defeat Emacs's special handling of dash-dash -->
<!ENTITY dd "--">

]>
<book>
<preface><title>Notes from the 21st century</title>

<sect1><title>MAD: An Appreciation</title>

<para>Most of this document is a faithful transcription of the
reference manual for MAD (Michigan Algorithm Decoder), an early
academic computer language from 1962.  The manual should be
accompanied by an implementation; if not, it can be found at the
<ulink url='&retromuseum;'>Retrocomputing Museum</ulink>.  MAD has
been revived as a work of reconstructive archeology, so that language
connoisseurs of the present and future will be able to appreciate what
computing life was like back in that day.</para>

<para>MAD was an extended dialect of ALGOL 58, first released in 1959
near the beginning of the great age of invention in compiled languages
that stretched from FORTRAN in 1955 until the rise to dominance of C
after 1985.  Study of it teaches a great deal about the uses and
background assumptions of computing in 1962 and earlier.</para>

<para>Some features of MAD are only superficially odd.  The all-caps 
listings look strange to modern eyes; the IBM 704 on which it was
implemented had a pre-ASCII, pre-EBCDIC six-bit character set with no
lower-case letters and lacks several punctuation marks that later
became standard.  The limitation to six characters in variable names,
labels, and strings reflects the compiler's primitive memory
management; it meant all of these could fit in one 36-bit machine
word.</para>

<para>A deeper difference from modern languages is the complete lack
of interactive I/O.  MAD was designed to run in a batch environment,
with programs submitted via card decks and sending output to line
printers or a card punch.  This limitation is a bit obscured in the
implementation that goes with these notes, because the card punch is
identified with Unix standard input and the line printer with Unix
standard output.  Thus, MAD I/O accidentally looks more flexible than
it was &mdash; modern MAD programs (assuming anyone were perverse
enough to write any new ones) could actually be part of
pipelines!</para>

<para>Punched-card input also explains some syntactic features that
will seem bizarre to modern eyes.  MAD statement labels lack a
delimiter like C's trailing colon because they were distinguished by
position (columns 1 to 10) on the card.  The line continuation syntax,
a digit in column 11, also relies on character position.  In the late
1960s and 1970s, when punched cards coexisted with interactive
timesharing, the term <quote>free-format</quote> was commonly used to
describe languages with the newer-style syntax that used
whitespace-delimited tokens without relying on card position, and
languages like MAD were called <quote>fixed-field</quote>.  When batch
computing vanished in the 1990s, both terms passed out of use.</para>

<para>By modern standards, the list manipulation statements (SET LIST,
SAVE DATA, SAVE RETURN, RESTORE DATA, RESTORE RETURN) are downright
peculiar.  We are accustomed to having a similar stack be managed
automatically by procedure entry and exit and the binding of local
variables, but that was an innovation of ALGOL 60 which was not
present in ALGOL 58.</para>

<para>Perhaps strangest to the modern eye is the exclusiveness with
which MAD is focused on numerical computations in applied
mathematics. String handling is rudimentary, and data structures other
than arrays are absent.  These gaps reflect not only the
non-interactive style of computing back then but the fact that what we
would today call systems programming (which drove the incorporation of
features like pointers, structures, unions, and typedefs in C) was not
yet done in non-assembler languages. The fact that the if statement is
called WHENEVER and the goto called TRANSFER is a mere cosmetic
trivium by comparison.</para>

<para>The expository style of the manual conveys as clearly as do the
language features that at this date the infant discipline of computer
science had yet to separate itself from applied mathematics.  All the
impedimenta of mathematical notation are present not just in the
formulas, but in the language syntax descriptions where script letters
are used as metavariables.  The whole is written in the rather stilted
over-formal prose one finds in the ordinary run of mathematical
papers.</para>

<para>Certain phrasings in the manual suggest that the authors thought
of flowcharts as the primary notation for programs, and considered MAD
code a sort of hand-compiled derivative of it.  This made sense at the
time, though it would have made much more sense if the authors had
actually settled on a consistent notation (the MAD manual uses at least
three conflicting styles). Programming languages were clumsy and
primitive, resources were scarce, and the typical complexity of
programs was very low.  By five years later (roughly three or four
Moore's-Law doublings) flowcharting was going out of fashion, probably
for the simple reason that flowcharts were getting too large to draw
and read!</para>

<para>There are some significant respects in which MAD was actually
rather advanced for its period.  The multiline WHENEVER statement
anticipated the free-format syntax of ALGOL 60's descendants,
including Pascal and C.  The DEFINE statement, which supports
syntactic extension of the language, was an interesting experiment not
emulated in most later designs.  And, as the Simpson's Rule example
illustrates, MAD even supported what was later called
<quote>higher-order programming</quote> &mdash; passing around
function-valued variables!</para>

<para>Also, MAD took care of details of running a job in ways that few
other languages of the time could do. MAD was what came to be called a
<quote>load-and-go</quote> compiler; unlike other languages of the
period in which jobs had to be launched by the operator after the card
deck had been loaded, the MAD system would ship either a diagnostic
listing or program output to the line printer immediately after the
deck compiled.  This fast turnaround was essential for a teaching
environment.  MAD also featured good diagnostics to help students find
and correct errors.  MAD's combination of a compiler with the simple
supervisor program that enabled load-and-go operation was considered
quite cutting-edge at the time and inspired a paper in the very first
issue of ACM Computing Surveys (<citetitle>Supervisory and Monitor
System</citetitle>, R.F. Rosin, March 1969).</para>

<para>On the other hand, there are some features of MAD which make one
truly wonder what the designers were thinking &mdash; the handling of
array indexing, for example, with two different addressing systems one
of which could mutate at runtime.  If 1962 weren't a couple of years
too early to attribute that to an LSD overdose it would make a
tempting hypothesis.</para>

<para>In most of the respects we've described, however, MAD is very
representative of its time.  This will become apparent from a look at
the Retrocomputing Museum implementation of CORC/CUPL, which is rather
similar (though less powerful).  MAD's grammar &mdash; ad-hoc and
festooned with many more keywords than a modern language would employ
&mdash; is very typical.  This entire family of languages became
extinct in the 1970s, snuffed out like dinosaurs by the meteoritic
impact of time-shared computing and teletypewriter-like interactive
terminals.</para>

<para>MAD did not expire entirely without issue.  Jerome Saltzer's
RUNOFF formatter, the original word-processing tool, was written in
MAD. It begat Multics ROFF, which begat Unix nroff and troff and
modern groff. These tools were the ancestors of all later
word-processing systems, and are still in use today. The TYPSET editor
that Saltzer wrote for use with RUNOFF influenced the design of Ken
Thompson's original QED editor enough that Saltzer would later
discover he could use the Unix ed(1) without reading its man
page.</para>

<para>MAD was named after Mad Magazine, which in those more innocent
days of the late 1950s and early 1960s was one of the cutting edges of
American humor.  Batch compilers of the period sent their error
listings to a line printer to be printed on fanfold paper.  It was
normal for such listings to begin with a cover page giving, among
other things, the time and date of compilation.  We are informed that
when the submitted program included errors, the original MAD compiler
also included on the cover page an image of the MAD Magazine mascot,
Alfred E. Neumann.  here is a version from 1960:</para>

<!-- literallayout format='linespecific' class='monospaced' -->
<mediaobject>
  <imageobject>
    <imagedata fileref='MAD-alfie-1960.jpg'/>
  </imageobject>
</mediaobject>

<para>For more on the history and versions of this language, <ulink
url="http://en.wikipedia.org/wiki/MAD_%28programming_language%29">Wikipedia
is informative</ulink>.</para>

</sect1>

<sect1><title>How This Implementation Differs From The Original MAD</title>

<para>The Retrocomputing Museum implementation of MAD translates MAD
code into compileable C.  It has been tested on the examples in the 
manual, which are included with the distribution.  This section is
a summary of differences: more details are given in notes attached
to the relevant sections.</para>

<para>Card images are read from standard input and printing is to
standard output (except PRINT ON LINE goes to standard error). Line
printer control codes are partly but not exactly simulated (see <xref
linkend='lptcodes'/>). Tape and drum devices are not supported.</para>

<para>The 704 had 36-bit words; MAD floats are translated to C
doubles, which on modern machines have 32 or 64 bits.  Precision and
overflow of numeric results will therefore differ.</para>

<para>In original MAD, a remark (comment) was flagged by 'R' in column 11
and the content of the comment could begin in column 12. This implementation 
does not count card columns; thus, the remark syntax is start of line
followed by whitespace followed by "R" <emphasis>followed by at least one 
whitespace character</emphasis>.</para>

<para>Interpretation of format strings probably does not quite match
the original, and the difference will affect READ FORMAT and WRITE
FORMAT.  Original MAD took input from card images in which input
fields had fixed column widths and no delimiters.  This is too painful
to simulate with a C printf/scanf string, so this implementation
cheats by inserting spaces (and thus requiring whitespace field
delimeters) between adjacent %-specifiers in repeated numeric
fields.</para>

<para>Character READ FORMATs into arrays cause their equivalents in the
generated C code to be declared with a base char type as would
be usual in C.  Perfect fidelity to the MAD behavior would have required
the data to be unpacked into int or double arrays, but that code 
would have been far more complicated to generate and hard to read.</para>

<para>In original MAD arguments were passed by name.  This is
difficult to simulate in C, so the generated code passes arguments by
value.  None of the examples given in the manual rely on
pass-by-reference, and given that all variables are global it is
difficult to imagine code that would.</para>

<para>Label arrays, array-mode variables, and the associated
computed-transfer statement are not implemented (mainly because the
manual did not include programs with which they could be tested).
Neither are multiple ENTRY points, EQUIVALENCE, ERASABLE, 
TAPE, or DRUM statements.</para>

<para>More seriously, though array references and assignments are
implemented, array I/O is not (except for the special case of
character arrays which are handled as strings).  The fact that the
size of arrays is dynamic appears to make this feature impossible
to compile; I conjecture that in the original MAD format strings
were actually interpreted at runtime by a service routine compiled
into the code.</para>

<para>Only the no-argument case of ERROR RETURN is supported.  The
language describing the more general case of this feature is deeply
confusing, and I was unable to extract a coherent semantics for
it.  None of the examples use the general case.</para>

<para>On the other hand, some limits in original MAD are not present
in this implementation, mainly because it would have required actual
effort to enforce them.  Names and string constants may be longer than
6 characters, and may contain underscores and lowercase
letters. Source lines are not limited to 72 chars long.</para>

<para>The .LS. (left shift), .RS. (right shift), .A. (bitwise and),
.V. (bitwise or) and .EV. (bitwise exclusive or) operations from CTSS
MAD are implemented in this compiler.</para>

<para>The READ AND PRINT DATA statement from 1966 MAD is supported.</para>

<para>All external function definitions must precede the program main
line.  It is unclear whether or not this was true in original
MAD.</para>

<para>We have not attempted to duplicate the exact format of
compile-time error messages from the original compiler.  Instead, this
implementation emits GCC-style error messages, and (on sufficient errors)
the head of Alfred E. Neumann <emphasis>after</emphasis> these.</para>

<para>The generated C is self-contained and does not require any
dedicated runtime support, except that the stdio and math libraries
must be linked with it.</para>
</sect1>

<sect1><title>Redactor's Notes</title>

<para>The remainder of this document, following this section) is an exact
transcription of the original Michigan Algorithm Decoder manual dated
February 1962.  Catherine Raymond typed it in from the original
velo-bound typed manual; Eric Raymond hand-corrected it, and moved the
result into PIC and XML-DocBook markup so both HTML and PostScript can
be generated from it.</para>

<para>Some material has been merged from the Revised Edition of 1966.
The merge is at present only partial.  Where the two versions differ
the changed texts always indicated with a revision attribute giving
the date are usually visibly indicated by redactors' notes.
Exception: the chapter-head epigraphs which are all from the 1966
version but not marked; in the 1966 original, the attributions on the
chapter-head epigraphs were right-justified. Further exception: In
some cases of minor wording changes, the 1962 text will not be
visible but is preserved in the XML masters.</para>

<para>The philosophy of this transcription is that the semantic
content of the manual is what is essential and is what should be
presented by rendering into HTML; the accidents of literal content
have in some cases been changed but should be reconstructable by
looking at the XML source transcription.  Thus, typos have been fixed in the
visible text, but the XML source includes a note adjacent to each one
explaining the fix. We have also corrected other minor errors like
off-by-ones in the indexing, but those fixes too are explained in the
XML masters.</para>

<para>We have been (necessarily) a little more relaxed about changes
in whitespace distribution, as DocBook doesn't give us the ability to
control that exactly.  Other notes in the XML source describe the few
places where we were not able to reproduce the original layout.</para>

<note><para>Redactor's comments in the body of the text are
decorated like this.</para></note>

<para>Typewriter underlining in the original is expressed by 
DocBook &lt;emphasis&gt; tags in this version, which will probably
render as italics.</para>

<para>The original hyphenation will probably not be discernible in the
visible rendering you see, though hyphen characters in the original
have been preserved as ISO soft-hyphen entities.</para>

<para>The program listings in the original failed to distinguish
between 0 and O, and between 1 and l; this does not reflect
incompetence but rather the fact that although computer line printers
of the period had separate forms for these character pairs,
typewriters of the period did not have.  This distinction has been
added in the present text.</para>

<para>Most of the original listings were typed so there was whitespace
between remark or continuation punches and following statements or
comments. The language's card-based, column-sensitive format did not
require this, however, and a few listings had a remark or continuation
character stuck to the first statement token.  These have been
whitespace-separated so that a modern token-oriented parser can read
them.</para>

<para>In the original, the description of flowcharting conventions 
in Chapter 1 include small hand-drawn geometrical shapes after each
of the items A, B, and the words "diamonds" and "rectangles" in item
D were corresponding shapes.</para>

<para>In the original, each example in the first two parts of Chapter
3 was introduced by a centered numbered header "Example N" with no
section numbering; examples in the third part had no headings at all.
These headers have been massaged or added to produce second-level
sections, and descriptive titles added because the Contents page
looked awful without them.  To remind the reader that these are
additions by the redactor, they are highlighted like redactor's
notes.</para>

<para>The PIC diagrams preserve the logic of the original hand-drawn
ones, but are not exact geometrical duplicates.  The proportions of
the flowchart elements are slightly different.  One detail we have not
preserved is that in Chapter 3, PRINT-statement boxes are left-right
reversed from their orientation in Chapter 2 (this shows in the
bottom curve.) Where the original used monospaced fonts and 
hand-drawn Greek characters, PIC and EQN give us typeset formulas
quite a bit better looking.</para>

<para>In the original, sections were numbered only down to three
levels deep. No per-chapter tables of contents were present.</para>

<para>The item lists bulleted a., b., c... and 1., 2., 3.... in this
transcription were bulleted (a), (b), (c)... and (1), (2), (3)...
in the original.  There does not seem to be a good way to generate
the original style in DocBook.</para>

<para>Special characters like white square (&squ;), back arrow
(&larr;), and the Greek letters were hand-drawn in the original
(except for the capital thetas, which were typed capital Os with bars
hand-drawn across them).  The original also some contained hand-drawn
script characters:</para>

<informaltable>
<tgroup cols='2'>
<thead>
<row>
<entry align='center'>in the original:</entry>
<entry align='center'>used for:</entry>
<entry align='center'>represented as:</entry>
</row>
</thead>
<tbody>
<row>
<entry align='center'>script-A</entry>
<entry>address metavariables</entry>
<entry align='center'>&scriptA;</entry>
</row>
<row>
<entry align='center'>script-F</entry>
<entry>format metavariables</entry>
<entry align='center'>&scriptF;</entry>
</row>
<row>
<entry align='center'>script-L</entry>
<entry>list metavariables</entry>
<entry align='center'>&scriptL;</entry>
</row>
<row>
<entry align='center'>script-M</entry>
<entry>general metavariables</entry>
<entry align='center'>&scriptM;</entry>
</row>
<row>
<entry align='center'>script-N</entry>
<entry>general metavariables</entry>
<entry align='center'>&scriptN;</entry>
</row>
<row>
<entry align='center'>script-S</entry>
<entry>statement metavariables</entry>
<entry align='center'>&scriptS;</entry>
</row>
<row>
<entry align='center'>script-V</entry>
<entry>vector metavariables</entry>
<entry align='center'>&scriptV;</entry>
</row>
</tbody>
</tgroup>
</informaltable>

<para>Footnotes were tagged with asterisks in the original rather than
being numbered.  Section references to section numbers have been
replaced with xref tags in order to generate hyperlinks in the HTML
rendering; as a result, they may render slightly differently than in
the original.  Notably, "section 1.1" becomes "Section 1.1"
(capitalized) and expressions like "sections 1.1.4 and 3.2" become
"Section 1.1.4 and Section 3.2".</para>

<para>The reference structure of the index has been faithfully
reproduced; that is, for each index reference a DocBook
&lt;indexterm&gt; tag was placed within the span of text defined by
the original page numbering (two off-by-one errors were corrected).
However, DocBook renders the index differently from the original.  The
original lacked the canned section headings, and references were by
page number rather than section name.</para>

<para>EPSLON and COMPLX and the like are not typos.  As pointed out
earlier, MAD variable names are limited to the 6 characters in a
six-bit character set that would fit in the IBM 704's 36-bit
word.</para>

<para>A few typos in the original have been fixed; if you're really
curious, comments in the XML source describe them.  Variant spellings
such as <quote>imbedded</quote> have been preserved.</para>

<para>The original was not continuously page-numbered.  Instead the
pages were numbered within each chapter with the chapter number as
a prefix; thus, page 6 of Chapter I was I.6.</para>

<para>In the Retrocomputing Museum implementation, statement boundaries
are detected by a preprocessing stage that places a marker before
every newline and then detects and erases markers that precede
whitespace followed by a continuation digit punch. This is strictly
conformant with the manual says in text, but some of the listings in
the manual lacked continuation punches that would be needed under this
rule.  Either these were transcription errors, or the original parser
had an undocumented capability to detect most continued statements
automatically. We have assumed the former and restored needed
continuation punches in several listings.</para>

<para>The above notes fail to properly convey just how primitive the
original document looks to a modern eye, and this is worth noting
because transcription into DocBook makes it look a lot less so.
Standards have risen in a world saturated with the Web and cheap page
printers.  The original manual's monospace fonts on yellowing paper
with hand-drawn figures and special characters look quaint and
ugly by contrast.</para>

</sect1>
</preface>
<!-- pagebreak -->
<preface><title>The Michigan Algorithm Decoder</title>

<note><para>This is the 1962 introduction.</para></note>

<para condition="1962">The Michigan Algorithm Decoder (MAD) is a
computer program which translates algebraic statements describing
algorithms to the equivalent machine instructions.  This descriptive
language &ndash; also called MAD &ndash; is explained in this manual.
The language was patterned after ALGOL 58, a proposed standard
language for the description of algorithms, with certain extensions
and adaptations which the authors believe make tbe language more
useful.  It should be undergtood in what follows that a computer
program may consist of several sections utilizing the language
described herein or other languages if desired.  The sections can be
translated independently and are linked together just prior to the
actual execution of the program.</para>

<para condition="1962">The original translating program was written
for an IBM 704 computer with 8192 words of magnetic core storage, 8192
words of magnetic drum storage and 6 magnetic tapes.  The program was
subsequently written for the IBM 790/90 computers with 32768 words of
core storage.  The features described in the appendices are included
only in this later version.  The programming and the preparation of
this manual were done at the University of Michigan Computing Center,
and the language has been widely used by University of Michigan
students and staff.</para>
<literallayout condition="1962">
                           B. Arden
                           B. Galler
                           R. Graham
</literallayout>

<note><para>This is the 1966 introduction. In the original, the title
was followed by two centered headers: "(The NAD Manual)" and "Revised
Edition - 1966".</para></note>

<epigraph revision="1966">
<attribution>Shakespeare: Hamlet</attribution>
<para>"Though this be madness, yet there is method in't."</para> 
</epigraph>

<para condition="1966">The Michigan Algorithm Decoder (MAD) is a
computer program which translates algebraic statements describing
algorithms to the equivalent machine instructions. This descriptive
language &ndash; also called MAD &ndash; is explained in this
manual. ALGOL 58, which was proposed at one time as a standard
language for the description of algorithms, was used as a pattern for
this language; the original translation program was written in 1959
for an IBM 704 computer with 8192 words of core storage. Translators
were subsequently written for thew IBM 709/90/94 machines by the
University of Michigan Computing Center staff. Interested groups
elsewhere have adapted the language for the IBM 7040, Philco 210-211,
and Sperry Rand 1107 machines. The translator was officially included
in the University of Michigan Executive System (UMES), but its
construction as a subroutine has per&shy;mitted its inclusion in a
number of different operating systems.</para>

<para condition="1966">Over the years a number of useful extensuins to
the language have been incorporated. These were documented as addenda
and revisions in the many printings of the First Editkion, which was
written by Arden, Galler, and Graham. This edition is a major
revision--done by Professor Elliott Organick of the University of
Houston--which incorporates these addenda and corrects a number of
shortcomings of the early version.  Donald W. Boettner and Bruce
J. Bolas of the University of Michigan assisted in this
revision.</para>

<para condition="1966">The MAD language has been widely used by the
students and staff of the University of Michigan and it has been used
at a number o other centers as well. There are a number of versions
extant and some of these may not contain all the features described
herein.</para>

<literallayout condition="1966">
                           Bruce W. Arden
</literallayout>

</preface>
<!-- pagebreak I.1 -->
<chapter><title>INTRODUCTION</title>

<epigraph revision="1966">
<attribution>Lewis Carroll, <citetitle>Alice In Wonderland</citetitle></attribution>
<para>"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."</para>
</epigraph>

<!-- revision="1962" In order to present a problem to a digital computer for
solution, it is necessary to transmit to the machine a statement of
the problem, a procedure for solving it (usually called an algorithm
<indexterm><primary>Algorithm</primary></indexterm>
for the solution of that problem), and the data which is needed in the
solution.  In fact, a statement of the problem is not really
necessary, since the algorithm and data are sufficent for a computer,
provided the algorithm is stated unambiguously and completely. -->

<para revision="1966">In presenting a problem to a digital computer
for solution, one transmits to the computer a procedure for solving it
(usually called an algorithm
<indexterm><primary>Algorithm</primary></indexterm> for the solution
of that problem) and the data for that particular case.  The algorithm
must be stated unambiguously and completely.</para>

<para>As a simple example, let us consider the problem of determining
the largest number in a collection of n + 1 numbers A = {
a<subscript>0</subscript>, a<subscript>1</subscript>,
a<subscript>2</subscript>, ... a<subscript>n</subscript> } with n &ge;
1.  A verbal description of the
procedure<indexterm><primary>Procedure</primary></indexterm>
(algorithm) might be:</para>

<procedure>
<step>
<para>Pick up the first number.</para>
</step>
<step>
<para>Compare it with the second number.</para>
</step>
<step>
<para>If the first is larger or if they are equal, keep the first one.</para>
</step>
<step>
<para>If the second is larger, keep the second one.</para>
</step>
<step>
<para>Whichever one was saved from this comparison is now compared with
the third number.</para>
</step>
<step>
<para>Continue to repeat steps 2 through 5 (each time moving down the
list) until the n+1st number has been included in the
comparison.</para>
</step>
<step>
<para>The number which has been finally saved is then the largest
number in the collection A.</para>
</step>
</procedure>

<para>Unfortunately, this method of description is not very precise.
Such words as "compare", "moving down the list", and "finally saved"
should really be spelled out more exactly.</para>

<!-- beginpage I.2 -->

<para>The following restatement of the procedure would probably be
more suitable:</para>

<procedure>
<step>
<para>Set Z = a<subscript>0</subscript>.</para>
</step>
<step>
<para>Let j = 1.</para>
</step>
<step>
<para>If J > n, the problem is done<footnote><para>This test is
redundant the first time, but after n times through steps (3) - (6) it
will terminate the process for us.<phrase revision="1966">It is
redundant the first time because if n &ge; 1 as set forth in the
problem statement, then for j = 1, j > n will always be
false.</phrase></para></footnote> go to step 7; otherwise go
on.</para>
</step>
<step>
<para>If Z &lt; a<subscript>j</subscript>, let Z =
a<subscript>j</subscript>; otherwise, go on.</para>
</step>
<step>
<para>Let j increase by 1.</para>
</step>
<step>
<para>Return to step 3.</para>
</step>
<step>
<para>Z is the answer.</para>
</step>
</procedure>

<para condition="1962">This may be illustrated by following "flow diagram":
<indexterm><primary>Flow Diagram</primary></indexterm></para>

<para condition="1966">Some further streamlining can be accomplished
in the phrasing of a procedure statement without losing any claroty.
This has to do with the way we donote the assigning of values to a
variable of the problem.</para>

<para condition="1966">Note that a statement like

<!-- In the original, 'a' was typoed as 'A' -->
<programlisting>
                "Let Z = a<subscript>0</subscript>"
</programlisting>

really means.

<programlisting>
                "Let Z acquire (or be assigned) the value a<subscript>0</subscript>"
</programlisting>
</para>

<para condition="1966">Now suppose we employ a special symbol, imn
particular, the left-pointing arrow (&larr;) to signify the process
of assigning a value Then

<programlisting>
                "Let Z &larr; a<subscript>0</subscript>"
</programlisting>

becomes a perfectly meaningful shorthand.</para>

<para condition="1966">By the same reasoning, the statement

<programlisting>
                "Let j increase by 1"
</programlisting>

can now be restated as j &larr; j + 1.</para>

<!-- merge of 1966 manual text ends --> 

<mediaobject>
  <imageobject>
    <imagedata fileref='fig01.png'/>
  </imageobject>
</mediaobject>

<para>Note that the following conventions have been used here:</para>

<orderedlist numeration='upperalpha'>
<listitem>
<para>Computation of subscripts or countiong occurs in diamond-shaped
boxes.</para>
</listitem>
<listitem>
<para>Actual computation occurs in rectangular boxes.</para>
</listitem>
<listitem>
<para>Decisions, based on comparisons occur in triangular
boxes.</para>
</listitem>
<listitem>
<para>The "=" inside computation boxes (both diamonds and rectangles) is
meant in the dynamic sense: "Compute the value of the expression on the
right and let that now be the value of the variable whose name appears
on the left."</para>
</listitem>
</orderedlist>

<!-- beginpage I.3 -->
   
<para>Although this problem does not require it, we frequently ask a
question like "Does j = n?"  The "=" in this context is a
<emphasis>relation</emphasis><indexterm><primary>Relation</primary></indexterm>
and yields either "YES or NO" when placed between two arithmetic
expressions.</para>

<para>We return to the example problems.  The algorithm exhibits an
important concept, which occurs in a great many procedurs; namely, it
contains a <emphasis>loop</emphasis>.  A loop has the following
characteristic properties:</para>

<orderedlist numeration='loweralpha'>
<listitem>
<para>It is repeated over and over until some conditions is satisfied
(occasionally this may be a very complex condition).  In the example,
the condition was "j > n".</para>
</listitem>
<listitem>
<para>Before the first "iteration," some initialization may be
performed.  In the example, Z - a<subscript>0</subscript> and j = 1.</para>
</listitem>
<listitem>
<para>After the "body" of the loop is performed, (the comparison, in
the example), some variable is incremented, and the termination
conditions is tested again. In our example, j is increased by 1, and
if j &le; n, the "body" of the loop is computed again - with the new
value of j.</para>
</listitem>
</orderedlist>

<para>It is often convenient to take advantage of this standard structure of
a loop, and use an "iteration box" in the flow diagram.  This box
would have to indicate the "scope"; i.e., the extent of the body of
the loop, the variable which is to be initialized and later
incremented, and the condition which will determine the number of
iterations in the execution of the loop.  The contents of a typical
iteration box, (not related to the example above) might be:</para>

<para>Repeat the computation through the box labelled (for example)
"BACK", starting with the variable &alpha; having the value 12, and
increasing it by the amount 3 after each time until either &alpha; >
90, or |x + y| &le; &epsi;.</para>

<indexterm><primary>Iteration Statement</primary></indexterm> 

<para>We shall abbreviate this by the form:</para>

<programlisting>
THROUGH BACK, FOR ALPHA = 12, 3 ALPHA .G. 90 .OR. .ABS. (X+Y) .LE. EPSLON
</programlisting>

<para>Here we have substituted ".G." for ">", ".LE." for "&le;",
".ABS. (X+Y)" for "|x + y|".  (The reason for these simple
substitutions is the lack of characters such as >, &le; as input to
the computer.  Such details are fully presented 
<!-- beginpage I.4 --> 
in Chapter II of this manual.)</para>

<note><para>The IBM 704 on which MAD was implemented had a
very primitive pre-ASCII character set.  It did not even include
lowercase letters, let alone fancy punctuation like &lt; and &gt;.
ASCII still lacks &le; and &ge;, but writing these as &lt;= and &gt;=
became universal in later ASCII-based languages.</para></note>

<para>The flow diagram for our previous example, then, may be
rewritten as follows: (In order to keep the notation familiar when
possible, the above-mentioned character substitutions will not be made
in diagrams.)</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig02.png'/>
  </imageobject>
</mediaobject>

<para>The three operators specified in a "THROUGH" statement are
written in a single box to indicate the correspondence to a single
statement.</para>

<para>The question still remains: How does one communicate the
algorithm to the computer?  A translator such as
MAD<indexterm><primary>Translator</primary></indexterm> is designed
according to the philosophy: Once the algorithm has been stated, as in
a flow diagram, it should be presented to the computer directly in
that form, or as near to it as possible.  The "translator" then has
the job of producing a translation from a flow diagram in a form
acceptable as input to the translator, the user's work ends with the
diagram itself.</para>

<para>It should be remembered that the MAD language was designed with several 
important criteria in mind:</para>

<orderedlist numeration='loweralpha'>
<listitem>
<para>Speed of translation - the choice of some words of more than six
characters (e.g. WHENEVER, TRANSFER, THROUGH) enables the translator
to recognize the statement type with a minimum of analysis.</para>
</listitem>
<listitem>
<para>Generality - a few restrictions on the construction of
statements and expressions have been introduced as possible.</para>
</listitem>
<!-- beginpage I.5 -->
<listitem>
<para>Ease of adding to the language - desired additions can be
made easily, since most of the necessary information can be stored in
tables during translation.</para>
</listitem>
</orderedlist>

<para>It is obvious that a different set of criteria could lead to a
different language.  The details of the form of statements in this
"input language" are the subject of Chapter II.<footnote><para>The
reader may find some clarifying effect if he rereads Chapter I after
reading Chapter II.</para></footnote></para>

<para>We are concerned here with introducing some of the basic ideas,
such as the loop, etc.  The input form of our example would be:</para>

<programlisting>
	DIMENSION A(100)
	Z = A (0)
	THROUGH BACK, FOR J = 1, 1, J .G. N
BACK	WHENEVER Z .L. A(J), Z = A(J)
	INTEGER J, N
	END OF PROGRAM
</programlisting>

<para>The DIMENSION statement <indexterm><primary>DIMENSION
Statement</primary></indexterm> assigns a block of storage in the
computer large enough to handle a<subscript>0</subscript>,
a<subscript>1</subscript>, a<subscript>2</subscript>,
... a<subscript>100</subscript>, if necessary.  The INTEGER statement
declares J and N to be integers.  We have already seen that different
shaped boxes are used for operations on integers, such as subscript
modification and counting.  The reason for this is that integer
arithmetic can be done more simply and efficiently, usually with less
round-off error, than arithmetic on non-integers.  [Numbers which may
have fractional parts are usually written in the so-called "scientific
notation", <indexterm><primary>Scientific
Notation</primary></indexterm> such as 3.1 &times;
10<superscript>-6</superscript> are called floating point numbers.]
<indexterm><primary>Constants, Floating Point</primary></indexterm>
Numbers are assumed to be in the floating-point mode unless otherwise
declared, as in the INTEGER statement in the example.
<indexterm><primary>INTEGER Statement</primary></indexterm> The
WHENEVER statement above is to be interpreted in the sense: Whenever
the following condition (in this case Z &lt;
a<subscript>j</subscript>) is satisfied, do the specified action (Z =
a<subscript>j</subscript>), otherwise just go on.</para>

<indexterm><primary>Floating Point</primary></indexterm>

<para>It is interesting to ask just how complicated a condition can be
used in making decisions.  We have seen that such conditions may occur
in iterations statements, and "WHENEVER" statements, etc., for the
purose of making binary (i.e., "yes" or "no") choices.  An expression
which can be labelled 
<!-- beginpage I.6 -->
"True" or "False" is exactly what is needed here.  Such expressions
are called <emphasis>Boolean</emphasis><footnote><para>After the
logician George Boole.</para></footnote>
<emphasis>expressions</emphasis><indexterm><primary>Boolean</primary></indexterm>,
and usually involve "and", "or", "not", and possibly other such words
connecting shorter expressions involving &lt;, &le;, =, &ne;, &gt;,
and &ge;.  For example, the following is a Boolean expression:</para>

<programlisting>
((x - 3)<superscript>3</superscript> &lt; y and i &le; j) or x &ge; 3
</programlisting>

<para>This will be "true" for some values of x and y, and "false" for
others.  It might then occur in statements such as:</para>

<programlisting>
WHENEVER ((X - 3) .P. 3 .L. Y .AND. I .LE. J) .OR. X .GE. 3,
TRANSFER TO AGAIN
</programlisting>

<para>or in the iteration statement</para>

<programlisting>
THROUGH ALPHA, FOR BETA = 1, 1, (X - 3) .P. 3 .L. Y .AND.
I. .LE. J) .OR. X .GE. 3
</programlisting>

<para>where .P. denotes exponentiation (i.e., "to the power").</para>

<para>Returning again to the example problem on the largest of a set
of numbers, we observe that no provision was made for obtaining the
values of n, a<subscript>0</subscript>, a<subscript>1</subscript>,
..., a<subscript>n</subscript> on which to perform our computation,
nor was any provision made for producing an answer.  Normally, each
program would contain suitable input and output statements, such as
are described in Chapter II and illustrated in Chapter III.  Let us
assume instead that we are interested in making out little algorithm
available for use in any other program, as a pre-packaged "function",
in the sense that, given n and a<subscript>0</subscript>, ...,
a<subscript>n</subscript>, this function computes as its value the
largest of a<subscript>0</subscript>, ..., a<subscript>n</subscript>.
<indexterm><primary>EXTERNAL FUNCTION</primary></indexterm>
In this case we shall call our algorithm an EXTERNAL FUNCTION, and
give it a name, say MAX., since it will be written and translated
externally with respect to the program which will later call upon it.
The program will now be written:</para>

<!-- beginpage I.7 after "FUNCTION RETURN Z" in this listing -->
<programlisting>
&maxfunc;
</programlisting>

<para>The first statement specifies the inputs to the function to be N and
A, the second statement indicates the point of entry, the FUNCTION
RETURN statement specifies the value of Z as the desired value of the
function, and the other statements are as before.  Any program using
the function now need only call upon it by name, as in the statement:</para>

<programlisting>
LARGEQ = 1. + MAX. (6,Q)/3.
</programlisting>

<para>Note that the set (in this use of MAX.) whose largest element is
desired is called Q, and N has the value 6.  No DIMENSION statement is
needed for A is the EXTERNAL FUNCTION definition program above, since
A is there only as a "dummy variable", anyway.  When
<emphasis>used</emphasis>, with a concrete set Q, we would expect a
DIMENSION statement for Q in the program that calls on MAX. for a
value.<indexterm><primary>DIMENSION Statement</primary></indexterm></para>

<para>For a second example consider the problem of repeatedly solving,
by Newton's method<indexterm><primary>Newton's
Method</primary></indexterm> , of the equation f(x) -
a<superscript>x</superscript> + x = 0, taking a different value for a
each time but with the restriction that a &ge; 1.  This method
involves the repeated evaluation of the formula</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation1.png'/>
  </imageobject>
</mediaobject>

<para>(the prime denotes the derivative with respect to x) until
x<subscript>i+1</subscript> is a root - i.e., until
f(x<subscript>i+1</subscript>) = 0.  Actually, in the numerical
solution of equations where we deal with approximate numbers the
latter condition becomes: until |f(x<subscript>i+1</subscript>)| &lt;
&epsi;, where &epsi; is a small positive number.</para>

<para>To evaluate the iterative formula above the first time it is
necessary to have an initial approximation, x<subscript>0</subscript>,
to the desired root.  The use of the index, i, as well as the initial
subscript zero suggests that we will produce a sequence,
x<subscript>0</subscript>, x<subscript>1</subscript>,
... x<subscript>n</subscript>, of approximations to the root.
However, from the computational point of view we do no need all of
these values simultaneously, since to evaluate the formula it is
sufficient to know only the last value, x, produced.  We can
say</para>

<programlisting>
x is replaced by x - f(x)/f'(x)
</programlisting>

<para>Often a left arrow (&larr;) is used to mean "is replaced by" but
in the actual 
<!-- beginpage I.8 --> 
statements produced for the computer the "=" symbol conventionally has
this meaning.<indexterm><primary>Equals Sign</primary></indexterm></para>

<para>It is important to realize what the "=" means in this context;
it is different from the usual use of the symbol where it indicated a
<emphasis>relation</emphasis>.<indexterm><primary>Relation</primary></indexterm>
When the "=" symbol is used as such a "replacement operator" the item
on the left of the "=" is always the <emphasis>name</emphasis> of a
<emphasis>variable</emphasis>.  The variable may have a complicated
subscript but nevertheless it is not an expression, but the name of a
variable.  The item on the right of the symbol is an expression
involving one or more constants, variables, etc.  The operation
implied is simply that the value of the express on the right becomes
the <emphasis>value</emphasis> of the variable whose name appears on
the left.  This is referred to as substitution.</para>

<indexterm><primary>Substitution</primary></indexterm>

<para>For our specific example, then, the evaluation of the iterative
formula could be described as</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation2.png'/>
  </imageobject>
</mediaobject>
<!-- in the original there was a comma hung out to the right of the listing -->

<para>although we will for convenience break this into two statements.
The entire computational procedure can be represented by the following
flow diagram.</para>

<!-- Figure 3 had x+x in one box caption where it needed x=x -->
<mediaobject>
  <imageobject>
    <imagedata fileref='fig03.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage I.9 -->

<para>The corresponding statements are:</para>

<programlisting>
&newton1;
</programlisting>

<orderedlist>
<listitem><para>The first statement, labelled ST, causes a value for
a,x, and &epsi; to be read into computer storage.  A block of adjacent
storage location in the computer (a "vector") named ALPHA is
designated as containing a description of how the three numbers were
punched on the card.  <indexterm><primary>Vector</primary></indexterm>
(This description &ndash; which is the value of ALPHA &ndash; is
described in a later statement; see (9) below.)</para></listitem>

<listitem><para>The second statement is a simple conditional which causes
the statement labelled PRT to be the next one executed if a &lt;
1.  Otherwise, the next one in ssequence (labelled REPEAT in
this case) will be executed.</para></listitem>

<listitem><para>The statement labelled REPEAT computes
a<superscript>x</superscript> + x using the current value of x, and
places the result of this computation in a storage location named
F.</para></listitem>

<listitem><para>The next statement divides the value F of the function
by the derivative of the function (log<subscript>e</subscript> a
&middot; a<superscript>x</superscript> + 1.0), evaluated using the
current value of x, subtracts this quotient from the current value of
x and the resulting difference is stored as the current value of x.
The name ELOG. is the name for the function
log<subscript>e</subscript> and the item in parentheses following this
name indicated the variable whose natural logarithm is
desired.</para></listitem>

<!-- beginpage I.10 -->

<listitem><para>The following statement is a simple conditional which
causes the function and iterative formula to be evaluated
again if |f(x)| &ge; &epsi;.  Otherwise, (i.e., |f(x)| &lt;
&epsi;), the next statement in sequence is executed.</para></listitem>

<listitem><para>The PRINT statement<indexterm><primary>PRINT
Statement</primary></indexterm> causes three numbers - the current
values of a, x and &epsi; to be printed.  The arrangement and form of
the numbers on the printed page are controlled by the format
description which is the value of the vector named
ALPHA.<indexterm><primary>Format</primary></indexterm></para></listitem>

<listitem><para>The TRANSFER statement following causes the statement
labelled ST to be the next one performed.
<indexterm><primary>TRANSFER Statement</primary></indexterm>
</para></listitem>

<listitem><para>The statement labelled PRT is the one executed immediately
after the first statement whenever a &lt; 1.0.  This statement
causes the current value of a to be printed (here a must be &lt;
1.0) according to a format description stored in BETA.  The
format description also causes the printing of some constant
alphabetic information preceding thenumber; namely, the remark
"A TOO SMALL, A = ".</para></listitem>

<listitem><para>The next two statements following the last TRANSFER TO
ST set the initial values of two vectors named ALPHA and BETA.
Although VECTOR VALUES statements<indexterm><primary>VECTOR VALUES
Statements</primary></indexterm> can be used to preset vectors to
specified numeric values, in both instances here the values are
<emphasis>format descriptions</emphasis>.  The strings of characters
between the dollar signs (MAD quotation marks!) are to be taken
literally as they appear and stored in designated vectors.  The actual
format specifications are described in more detail in Chapter II, but,
for example, the first description: S1,3F15.6* means that the first
item is to be a space (S1), followed by three (3) numbers printed with
a decimal point but no exponent (F), each occupying fifteen card or
print positions (15), and that there will be six positions to the
right of the decimal point (.6).  The asterisk
(*)<indexterm><primary>Asterisk</primary></indexterm> indicates the
termination of the description.</para></listitem>

<listitem><para> The final statement indicates the end of the statements
and is the last statement executed when a definite termination
to the problem is known.  In our particular example, the
computer would continue until it has exhausted the given input
values of a, x, &epsi;.</para></listitem>
</orderedlist>

<!-- beginpage I.11 -->

<para>The final example before the description of the language in
Chapter II is a more general and more elaborate illustration of
Newton's method.<indexterm><primary>Newton's
Method</primary></indexterm> Here, we consider the solution of the
equation x<superscript>3</superscript> +
ax<superscript>2</superscript> + bx + c = 0, starting with some input
value for x<subscript>0</subscript>, using the iterative
formula:</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation3.png'/>
  </imageobject>
</mediaobject>

<para>which is obtained from the standard Newton's Method formula</para>

<!-- Yes, this is repeated from earlier -->
<mediaobject>
  <imageobject>
    <imagedata fileref='equation1.png'/>
  </imageobject>
</mediaobject>

<!-- in the original, "problem" here was "probelm" -->
<para>for the problem f(x) = 0.  (Here f(x) =
x<superscript>3</superscript> + ax<superscript>2</superscript> + bx +
c).  We shall specify quantities &epsi;<subscript>1</subscript> and
&epsi;<subscript>2</subscript>, and stop the iteration when the
following condition is satisfied:</para>

<blockquote role='centered'><para>
(|x<subscript>i+1</subscript> - x<subscript>i</subscript>| &lt; &epsi;<subscript>1</subscript>
and
|f(x<subscript>i</subscript>)| &lt; &epsi;<subscript>2</subscript>)
or
i &le; n<subscript>0</subscript>
</para></blockquote>

<para>where n<subscript>0</subscript> is some upper limit to the
number of equations which we can tolerate.  The inequaliies involving
&epsi;<subscript>1</subscript> and &epsi;<subscript>2</subscript> may
be illustrated by the graph below, We are requiring that at
x<subscript>i</subscript> the value of the function
f(x<subscript>i</subscript>) be between the upper and lower bounds 
&epsi;<subscript>1</subscript> and -&epsi;<subscript>2</subscript>.
Also the distance d between x<subscript>i+1</subscript> and
x<subscript>i</subscript> should be less than
&epsi;<subscript>1</subscript>.  Observe that we are never concerned
with more than two successive aproximations to the root &mdash; say x 
and x<subscript>m</subscript> (for next x) &mdash; and that the
incrementing of i is not really necessary.</para>

<!-- beginpage I.12 -->

<!-- The "NO CONVERGENCE" literal in figure 4 was missing a trailing quote. -->
<mediaobject>
  <imageobject>
    <imagedata fileref='fig04.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage I.13 -->

<!-- This listing in the original was defective,
missing continuation punches everywhere but in INTERNAL FUNCTION F. -->

<programlisting>
&newton2;
</programlisting>

<para>The first statement, labelled GAMMA, would cause the program to
read from the data card the numbers a, b, c,
x<subscript>0</subscript>, &epsi;<subscript>1</subscript>,
&epsi;<subscript>2</subscript>, and n<subscript>0</subscript>.  The
format of the input information is to be found in a block of storage
labelled "CARD" whose values are set later in the program by a VECTOR
VALUES statement.  The vector CARD actually has as values the format
information in alphabetic form (sometimes called Hollerith, or
binary-coded decimal (BCD)
<indexterm><primary>BCD</primary></indexterm>
<indexterm><primary>Hollerith (BCD)</primary></indexterm> form). The
con&shy;struction and analysis of format information is thoroughly
discussed in Chapter II.</para>

<!-- beginpage I.14 at the soft hyphen above -->

<para>The second statement in the program causes the inout
information, properly labeled., to print out, preceded by the title
"SOLUTION OF CUBIC EQUATION".  The appropriate alphabetic information
is contained in the format information which is t be found in the
vector TITLE, as set by a VECTOR VALUES statement
<indexterm><primary>VECTOR VALUES
Statements</primary></indexterm>later in the program.</para>

<!-- in the original, there was a run-on typo, "NO CONVERGENCEis" -->
<para>Two functions are defined in this program, and each is
designated as an INTERNAL FUNCTION.  The statement following that
whuich is labelled BETA illustrates a conditional output statement.
If the iteration is terminated because i &ge;
n<subscript>0</subscript>, the alphabetic information NO CONVERGENCE 
is printed before the values of I and X are printed, otherwise that
remark is not printed.  The final transfer to GAMMA cause the program
to start over with a new set of data, if additional data is present,
otherwise, the computation is automatically terminated.</para>

<para>The VECTOR VALUES statement, illustrated here, may be used to
cause vectors (and matrices) to be initialized to any desired value
(even alphabetic values) before the program computation is begun.  Of
course, these values could be computed or read in as input, if
desired, so that the data for a problem could be preceded by its own
description of format, in problems where the format may change from
one set of data to another.</para>
</chapter>

<!-- beginpage II.1 -->
<chapter><title>DESCRIPTION OF THE LANGUAGE</title>

<sect1><title>Constants, Variables, Operations, and Expressions</title>

<sect2 id='constants'><title>Constants</title>

<indexterm><primary>Constants</primary></indexterm>

<para>There are four classes of constants: Integer, floating point,
alphabetic, and Boolean.</para>

<sect3><title>Integer Constants</title>

<indexterm><primary>Constants, Integer</primary></indexterm>
<indexterm><primary>Integer Constants</primary></indexterm>

<para>Integer constants contain from 2 to 10 decimal digits.  The
decimal point is assumed to be immediately to the right of the
rightmost digit, but is <emphasis>always</emphasis> omitted.  Integers
may be positive or negative, and while the "+" sign may be omitted,
the "-" sign must be present if the number is negative (e.g., 2, -2, 0,
+0, -0. 100 are all integers).  Leading (but not following) zeros may
be omitted (e.g., 5 and 005 represent the same integer, but 3 and 300
do not.</para>

<note><para>There is a subtle difference from modern practice here.
In 2004, major contemporary languages (perhaps unfortunately) follow
C's lead and interpret leading 0 as a directive to evaluate the 
following digits in octal.  The Retrocomputing Museum implementation
of MAD implements the original MAD behavior.</para></note> 
</sect3>

<sect3><title>Floating Point Constants</title>

<indexterm><primary>Constants, Floating Point</primary></indexterm>
<indexterm><primary>Floating Point</primary></indexterm>

<para>Floating point constants may be written with or without
exponents.  <indexterm><primary>Exponent</primary></indexterm> If
written without an exponent, the constant contains from one to eight
digits and a decimal point ".", which must be written, but which may
appear anywhere in the number.  Thus, 0., 1.5, -0.05, +100.0, .1 and
-4. are all floating-point constants.  If the number is written with
an exponent, it must contain from one to eight digits with or without
a decimal point, followed by the letter "E", followed by the exponent
of the power of 10 that multiplies the number.  (If the decimal point
is omitted, it is assumed to be immediately to the left of the letter
"E".)  The exponent m consists of one or two digits preceded by a sign
(although a "+" sign may be omitted), and must satisfy the condition
-38 &ge; m &ge; 38.  Examples of floating-point constants with
exponent are;

<!-- beginpage II.2 -->

.05E-2(= .05 &times; 10<superscript>-2</superscript>) -.05E2(= -.05
&times; 10<superscript>2</superscript>),
5E02(=5.0&times;10<superscript>2</superscript>),
5.E2(-5.0&times;10<superscript>2</superscript>).</para>

<para>Negative floating point constants must be preceded by a
"-" sign.  Positive constants may be preceded by a "+" sign.</para>
</sect3>

<sect3><title>Alphabetic Constants</title> 

<para>An alphabetic constant <indexterm><primary>Alphabetic
Constants</primary></indexterm> <indexterm><primary>Constants,
Alphabetic</primary></indexterm> consists of from one to six
admissible characters<indexterm><primary>Admissible
Characters</primary></indexterm> preceded and followed by the
character "$".<indexterm><primary>$ Sign</primary></indexterm>
The admiss- ible characters include all letters of the
alphabet, the digits 0 through 9, the special characters +, -(minus
sign), -(dash), *, /, =, ). (. ., the comma "," and the blank space,
to be represented here occasionally (but not punched on input cards),
as the character "&squ;".  Thus the following are alphabetic
constants: $ABCD$, $TO BE$, $DEC. 4$, $5 +3=8$.  Note that blank
spaces<indexterm><primary>Blank Spaces</primary></indexterm>
<indexterm><primary>Spaces, Blank</primary></indexterm>, while
ignored elsewhere in the language, count as characters in alphabetic
constants. An alphabetic constant is stored internally as an integer,
and any constant containing fewer than six characters will be extended
to six characters by adding blanks on the right; thus $ABCD$ will
appear internally as $ABCD&squ;&squ;$
</para>

<note><para>The Retrocomputing Museum implementation neither enforces
the six-character limit nor blank-pads constants. These features were
an artifact of packing six-bit characters into the IBM 704's 36-bit
machine word.</para>

<para>The way the original is worded suggests that minus sign and dash
were different characters in the character set that the Michigan 709
was using.  They are rendered with the same glyph in the original, but
this may be a collision enforced by period typewriters (like 0 and O
being indistinguishable).</para>
</note>
</sect3>

<sect3><title>Boolean Constants</title>

<!-- In the original, this was incorrectly referred to II.4 -->
<indexterm><primary>Constants, Boolean</primary></indexterm>

<para>There are two Boolean constants &ndash; "true", which is written
1B, and "false" which is written 0B.
<indexterm><primary>Boolean Constants</primary></indexterm>
<indexterm><primary>0B</primary></indexterm>
<indexterm><primary>1B</primary></indexterm></para> 
</sect3>  
</sect2>  
<sect2><title>Variables</title>

<indexterm><primary>Variable</primary></indexterm> 

<para>The name of a variable consists of one to six letters or digits,
the first of which must be a letter.  If the variable is defined as an
n-dimensional array variable<indexterm><primary>Array
Variables</primary></indexterm> (see <xref
linkend='dimension_declaration'/>) then the name of an element of the
array consists of the variable name, (i.e one to six letters or
digits, starting with a letter), followed by the appropriate
subscripts separated by commas and enclosed in parentheses. Thus the
following are "single variables:": X51, ALPHA6, LAMBDA, GROSS,
<indexterm><primary>Single Variables</primary></indexterm>
while the following are elements of arrays: BETA(C1, C2, 6), X15(Y, Z1),
J(6), J(Z1 + 5 *Z2, 5). (See <xref linkend='subscripts'/> for the
description of subscripts.)
Parentheses<indexterm><primary>Parentheses</primary></indexterm>
enclosing subscripts may not be omitted.</para>
</sect2>

<!-- beginpage II.3 -->

<sect2 id='statement_labels'><title>Statement Labels</title> 

<indexterm><primary>Statement Labels</primary></indexterm>
<indexterm><primary>Vector, Statent Label</primary></indexterm>

<para>A statement may be labelled or unlabelled.  Labels are used to
refer to a statement in other statements.  A statement label consists
of from one to six letters or digits, the first of which must be a
letter, e.g. IN or BACK.  A statement label may be an element of a
statement label vector,<indexterm><primary>Statement Label
Vector</primary></indexterm> in which case the vector name is followed
by a <emphasis>constant</emphasis> integer subscript enclosed in
parentheses, e.g. S(2) or LBL(3).  A statement label appears in the
label field (i.e. columns 1-10) of the statement it identifies.  When
a statement extends to additional cards (i.e. cards identified by a
digit punched in col. 11) the statement label need not be punched on
the additional cards.</para>
</sect2>

<sect2 id='functions'><title>Functions</title> 

<indexterm><primary>Function Name</primary></indexterm>

<indexterm><primary>Name</primary></indexterm>

<para>The name of a function consists of one to six letters or digits
followed by a period "." which must be written.  The first character
of a function name must be a letter.  If the function is
single-valued, then the value of the function is represented by
following the function name by the proper number of arguments (see
<xref linkend='funcdefs'/> for the definition of function) separated
by commas and enclosed in parentheses.  Thus, ADD51., COS., POLY., and
FUNCT3. are function names, while ADD51. (X,Y,ADD.), POLY. (N, VJ, 7)
and COS. (X) are values of functions.</para>
</sect2>

<sect2><title>Arithmetic Operations</title>

<indexterm><primary>Operations, Arithmetic</primary></indexterm>

<para>The following arithmetic
operations<indexterm><primary>Arithmetic
Operations</primary></indexterm> are available:</para>

<orderedlist numeration='loweralpha'>
<listitem><para>Addition, written as "+", e.g., Z5 + D.
<indexterm><primary>Addition</primary></indexterm></para></listitem>

<listitem><para>Subtraction, written as "-", e.g., Z5 - D.  (Note,
both the minus sign and the dash are accepted.)
<indexterm><primary>Subtraction</primary></indexterm>
</para></listitem>

<listitem><para>Multiplication, written as "*", e.g. Z5*D.  (Note that the
"*" may not be omitted.  It is illegal to write Z5D, since it
would be impossible to distinguish such a product from the
variable Z5D.)<indexterm><primary>Multiplication</primary></indexterm>
</para></listitem>

<listitem><para>Division, written as "/"; e.g., Z5/D.  If both Z5 and
D are integers, the result is again an integer; e.g., the "fractional
part" of the true quotient is truncated (not rounded).  For example,
if Z5 = 7, and D = 3, the Z5 = D will have the value 2.
<indexterm><primary>Division</primary></indexterm> 
<indexterm><primary>Integer Division</primary></indexterm></para></listitem>

<!-- beginpage II.4 -->
<listitem><para>Exponentiation, written as ".P.", e.g., Z5.P.D, and
meaning (Z5)<superscript>D</superscript>, i.e., Z5 raised to the power
D.<indexterm><primary>Exponentiation</primary></indexterm></para></listitem>

<listitem><para>Negation, written as "-", e.g., -ALOHA, meaning the
"negative of ALOHA."<indexterm><primary>Negation</primary></indexterm>
Thus -X.P.-.5 means -(X<superscript>-.5</superscript>).  <!-- in the
original, 'graph continued with ", the negative of the" -->
</para></listitem>
</orderedlist>
</sect2>

<sect2><title>Arithmetic Expressions</title>

<indexterm><primary>Expression, Arithmetic</primary></indexterm>

<para>Arithmetic expressions<indexterm><primary>Arithmetic
Expressions</primary></indexterm> are defined inductively as
follows:</para>

<orderedlist numeration='loweralpha'>
<listitem><para>All integer, floating point, and alphabetic constants,
integer and floating point individual variables, subscripted integer
and floating point array variables, and integer and floating point
values of functions are arithmetic expressions.</para></listitem>

<listitem><para>If E and F are any arithmetic expressions and V and
individual or subscripted array variable, then the following
are also arithmetic expressions: +E, -E, .ABS.E, E + F, E - F,
E * F, E/F, E.P.F, and (E).<indexterm><primary>.ABS.</primary></indexterm>
<indexterm><primary>Absolute Value</primary></indexterm>
<indexterm><primary>.P.</primary></indexterm>
</para></listitem>

<listitem><para>The only arithmetic expressions are those arising in
(a) and (b).</para></listitem>
</orderedlist>
</sect2>

<sect2><title>Boolean Operations</title>

<indexterm><primary>Operations, Boolean</primary></indexterm>

<para>The following Boolean, or logical, operations
<indexterm><primary>Boolean Operations</primary></indexterm>
 are available in the language (where M and P are boolean expressions):</para>

<orderedlist numeration='loweralpha'>
<listitem><para>.NOT.M has the value 1B if and only if M has the value
0B.<indexterm><primary>.NOT.</primary></indexterm></para></listitem>

<listitem><para>(M) has the same value as M.</para></listitem>

<listitem><para>M.OR.P has the value 0B if and only if both M and P
have the value 0B.<indexterm><primary>.OR.</primary></indexterm>
</para></listitem>

<listitem><para>M.AND.P has the value 1B if and only if both M and P
have the value 1B.
<indexterm><primary>.AND.</primary></indexterm></para></listitem>

<listitem><para>M.THEN.P has the value 0B if and only if M has the
value 1B and P has the value 0B.</para>
<indexterm><primary>.THEN.</primary></indexterm>
</listitem>

<!-- beginpage II.5 -->

<listitem><para>M.EQV.P has the value 1B if and only if M and P have
the same values.  <indexterm><primary>.EQV.</primary></indexterm>
</para></listitem>
</orderedlist>

<para>Thus, .NOT., .OR., .AND., .THEN., AND .EQV. correspond to the
usual logical operations, ~, &or;, &and;, &sup;, and &equiv;.</para>
</sect2>

<sect2 id='boolean_expressions'><title>Boolean Expressions</title>

<indexterm><primary>Expression, Boolean</primary></indexterm>

<para>Boolean expressions are defined inductively as follows:
<indexterm><primary>Boolean Expressions</primary></indexterm>
</para>

<orderedlist numeration='loweralpha'>
<listitem><para>Boolean constants, Boolean individual variables,
Boolean subscripted array variables and Boolean-valued functions are
Boolean expressions.  (see <xref linkend="functions"/> and
<xref linkend='mode_declaration'/>).</para></listitem>

<listitem><para>If H and F are arithmetic expressions: then H.L.F.,
H.LE.F, H.E.F., H.NE.F, H.G.F., H.GE.F, are Boolean
expressions, where the meanings are H &lt; F, H &le; F, H = F, H &ne;
F, H &gt; F, and H &ge; F, respectively.</para></listitem>

<listitem><para>If M and P are Boolean expressions, then the following are
also Boolean expressions: .NOT.M,(M), M.OR.P, M.AND.P,
M.THEN.P, and M.EQV.P.</para></listitem>

<listitem><para>The only Boolean expressions are those that arise in (a),
(b), and (c).</para></listitem>
</orderedlist>

<para>Examples of Boolean expressions are: (X .G. 3 .AND. Y .LE. 2)
.OR. (GAMMA .L.  EPSILN), and ((P .AND. Q) .THEN. Q) .EQV. (P
.OR. .NOT.P), where P and Q are Boolean variables.</para>
</sect2>

<sect2><title>Parentheses Conventions</title>

<indexterm><primary>Parentheses</primary></indexterm>

<para>Parentheses are used in the same way as in ordinary algebra and
logic to specify the order of the computation.  Also, certain
conventions are used to allow deletion of parentheses.
<indexterm><primary>Deletion of Parentheses</primary></indexterm> The
conventions used here are the same as in ordinary algebra and logic,
namely: Parentheses may be omitted, subject to the rules (A) and (B)
below, but redundant parentheses are allowed.
<indexterm><primary>Redyndant Parentheses</primary></indexterm></para>

<para>(A) Within any expression the sequence of computation, unless
otherwise indicated by parentheses, is:</para>

<!-- beginpage II.6 -->
<literallayout>
.ABS., + (as unary operations)
.P.
- (as a unary operator)
*, /
+, - (as binary operations, i.e., addition and subtraction)

.E., .NE., .G., .GE., .L., .LE.
.NOT.
.AND.
.OR.
.THEN.
.EQV.
, (as used to separate function arguments)
=
</literallayout>

<para>Examples:</para>

<orderedlist>
<listitem><para>.ABS.(B - C) means |B - C|, while .ABS.B - C means |B| - C.</para></listitem>
<listitem><para>-B + C means (-B) + (C), while -(B + C) means the negation of the sum.</para></listitem>
<listitem><para>B.P. - X + Y  means B<superscript>-X</superscript> + Y, while B.P.(-X + Y) means B<superscript>-X</superscript>+Y.</para></listitem>
<listitem><para>K2/Z - 3 (K2/Z) - 3, while K2/(Z - 3) implies that Z -
3 is denominator.</para></listitem>
<listitem><para>A * B + C means (A * B) + C.</para></listitem>
<listitem><para>A.P.3/J means (A<superscript>3</superscript>)/J</para></listitem>
<listitem><para>X.L. Y + 3 means (X) .L. (Y + 3).</para></listitem>
<listitem><para>P.AND..NOT.P .EQV.Q means (P.AND.(.NOT.P)).EQV.Q.</para></listitem>
<listitem><para>Z = X + Y /QA means Z = (X + Y/QA))</para></listitem>
<listitem><para>A = -B.P.X means A = -(B<superscript>X</superscript>).</para></listitem>
</orderedlist>

<para>(B) Within an expression operations appearing on the same line
of the list in (A) are to be performed from left to right, unless
otherwise indicated by parentheses.</para>

<!-- beginpage II.7 -->
<para>Examples:</para>

<indexterm><primary>Expression, Compound</primary></indexterm>
<indexterm><primary>Subexpression</primary></indexterm>

<orderedlist>
<listitem><para>A + B - C + D - E means (((A + B) - C) + D) - E.</para></listitem>
<listitem><para>X/Z * Y/R * S means (((X/Z) * Y/R) * S.</para></listitem>
</orderedlist>
</sect2>

<sect2 id='expression_modes'><title>Mode of Expressions</title>

<indexterm><primary>Mode</primary></indexterm>

<para>The kind of arithmetic performed on a constant, variable or
function value is determined by its mode.  There are five modes in
MAD; floating point, integer, Boolean, statement
label,<indexterm><primary>Statement Labels</primary></indexterm> and
function name.<indexterm><primary>Function Name</primary></indexterm>
Floating point, integer, and Boolean constants were described in <xref
linkend='constants'/>.  Alphabetic constants are assumed to be of
integer mode.  <xref linkend='mode_declaration'/> describes how the
modes of variables and functions are specified.</para>

<para>If an expression consists entirely of one constant, one
variable, or one function value, the mode is that of the constant,
variable, of functional value itself.  If the expression is a compound
expression; i.e., consists of two or more subexpressions joined by
logical or arithmetic operations, the following rule applies:</para>

<para>If an expression is a Boolean expression as defined in <xref
linkend='boolean_expressions'/>, then its mode is Boolean.  An
arithmetic expression is considered to be in the floating point mode
if any operand of any arithmetic expression in the expression is in
the floating point mode.  If all operands are integer (or alphabetic),
then the expression is considered to be in the integer mode.  In this
determination arguments, though not values, of functions are
ignored.<indexterm><primary>Compound Expression</primary></indexterm></para>

<para>Thus, if Y, Z, and W are floating point variables, while the
function GCD. and the variables I and J are in the integer mode, then
the expressions</para>

<literallayout>
Y = GCD.(I, J)
Y + Z - I
I + 1.
GCD. (I, J)/Z
</literallayout>

<para>are all floating point expressions while the expressions</para>

<literallayout>
I + GCD.(I, J)
(I + J)/3
I + 1
GCD.(I, J)/I
</literallayout>
<!-- beginpage II.8 -->
<para>are all integer expressions.</para>

<para>If an expression has subexpressions of different modes, a conversion
may be necessary before some of the operations can be performed.
Thus, in the expression</para>

<para role='centered'>
Y + 3
</para>

<para>if Y is in the floating point mode it cannot be added directly
to the integer 3. But for one precaution the user need not be
concerned with this since the instructions necessary for the
conversion of the integer to floating point form before adding are
automatically inserted by the translator during the translation
process.  
<indexterm><primary>Conversion, Integer to Floating Point</primary></indexterm>
The precaution is that if the integer being converted is
greater than 134,217,728 (i.e. 2<superscript>27</superscript>) then an
improper conversion will take place.</para>

<indexterm><primary>Integer Conversions</primary></indexterm>

<para>In some cases, however, the user must understand the sequence in
which the conversions will be made.  Consider the expression</para>

<para role='centered'>
(Y + 7/3) + (I * J/K)
</para>

<para>where Y is in the floating point mode, and I, J, and K are in the
integer mode.  According to the parenthesizing conventions, the
computation will proceed in the following order (where the T's are
temporary locations):</para>

<literallayout>
T<subscript>1</subscript> = I * J
T<subscript>2</subscript> = T<subscript>1</subscript>/K
T<subscript>3</subscript> = 7/3
T<subscript>4</subscript> = Y + T<subscript>3</subscript>
T<subscript>5</subscript> = T<subscript>4</subscript> + T<subscript>2</subscript>
</literallayout>

<para>and T<subscript>5</subscript> will be the value of the
expression.</para>

<para>Now, since both I and J are integers, the first multiplication
will be integer multiplication, and T<subscript>1</subscript> will be
an integer.  Since the following involves two integers, it will be
integer division, and, if K happens to have a larger value than
T<subscript>1</subscript> the quotient is 0.  Similarly,
T<subscript>3</subscript> will have the value 2 because of the
division of two integers.  In the computation of
T<subscript>4</subscript>, however, we have "mixed modes", since Y is
floating point and T<subscript>3</subscript> is integer.  There
I<subscript>3</subscript> will be automatically converted to floating
point before adding.  Likewise, in the next step, 
<!-- beginpage II.9 -->
the integer T<subscript>2</subscript> will be converted to floating
point before adding to the floating point number.
<indexterm><primary>Floating Point Subscripts</primary></indexterm></para>

<para>In other words, although the mode of the expression is floating
point because of the presence of the floating point variable Y, some
of the computation (until Y is involved) is performed in integer
arithmetic, and this may occasionally cause the final value to be
different from the value one might expect from a different analysis.</para>

<para>In the example above, the divisions would be performed in the
floating point mode if the expression were written:</para>

<para role='centered'>
(Y + 7./3) + (I * J)/(K + 0.)
</para>

<para>Of course, many times the expression will be written as
originally stated just to achieve the "truncation" effect.</para>

<para>A statement label (appearing in the label field of a statement)
is a constant of statement label mode.<indexterm><primary>Statement
Labels</primary></indexterm> A function
name<indexterm><primary>Function Name</primary></indexterm> with no
arguments (e.g. SIN.) is a constant of a function name mode.  A single
constant, variable, or function value of statement label (function
name) mode is an expression of statement label (function name) mode.
There are no other expressions of statement label (function name)
mode.  If A and B are both statement label (function name) expressions
then A.E.B. and A.NE.B are Boolean expressions except when A or B are
elements of a vactor which has been preset by a VECTOR VALUES
statement (see <xref linkend='VECTOR_VALUES'/>).  In this exceptional
case A.E.B. and A.NE.B are not expressions.</para>
</sect2>

<sect2 id='subscripts'><title>Subscript Expressions</title>

<indexterm><primary>Subscripts</primary></indexterm>

<para><emphasis>Any</emphasis> arithmetic expression may be used as a
subscript expression for an element of a linear array.  If the value
of the expression is in the floating point mode (see
<xref linkend='expression_modes'/>), it is truncated to integer form before
being used as a subscript.  The expressions for subscripts of elements
of an array whose dimension is two or greater must be of integer
mode. Moreover, for arrays of dimension three or greater the use of
subscripts having other than integer mode will not be caught as an
error.  Subscript expressions may contain variables with subscripts,
etc.</para>

<para>Examples of subscripted variables: J(3), K10(Z + 5 * XY/T),
MP(A, B + 6 * J, I * 6/TDX), MA(K(Z + 5) + T(1) + 6).</para>
</sect2>
</sect1>  

<sect1><title>Statements (Executable)</title>

<indexterm><primary>Executable Statements</primary></indexterm>

<sect2 id='substitution'><title>Substitution Statement</title>

<indexterm><primary>Substitution Statement</primary></indexterm>

<!-- beginpage II.10 -->
<para>This statement has the form illustrated by</para>

<para role='centered'>
ALPHA = Y + Z + F.(X, Y, Z)
</para>

<para>That is, the left side of the "=" sign
<indexterm><primary>Equals Sign</primary></indexterm> consists of the
name of a variable (either an individual variable or a subscripted
array variable), and the right side consists of any expression of the
same mode.  The only exceptions to this mode requirement are the
cases: (1) If the variable on the left is of integer mode then the
value of a floating point expression of the right will be converted to
integer mode.  <indexterm><primary>Conversion, Floating Point to
Integer</primary></indexterm> <indexterm><primary>Floating Point
Conversion</primary></indexterm> (2) if the variable on the left is of
floating point mode then the value of an integer expression on the
right will be converted to floating point mode.
<indexterm><primary>Conversion, Integer to Floating
Point</primary></indexterm>
</para>

<para>The substitution statement is to be interpreted as "(1) Compute the
value of the expression on the right, (2) convert it, if necessary, to
the mode of the variable on the left of the "=" sign, and (3) give the
variable on the left the value which results from steps (1) and (2)."
(See <xref linkend='expression_modes'/> for mode of expressions.)</para>

<para>Thus, if Y is a floating point variable, then the statement</para>

<para role='centered'>
Y = 1
</para>

<para>will cause the integer 1 to be converted to floating point and then
stored in the location called "Y"; i.e., Y will now have the value 1.
(as a floating point number).  If the statement were written</para>

<para role='centered'>
Y = 1.
</para>

<para>then the floating point number 1. would be stored in the
location "Y"; i.e., Y would again have the floating point value 1.,
but in this case the conversation of the integer is unnecessary, thus
speeding up the computation.</para>

<indexterm><primary>Integer Conversions</primary></indexterm>

<para>When a floating point number is to be converted to an integer,
it is first expressed as a number with both an integer part and a
fractional part, and then the fractional part is truncated.  Thus, the
following floating point numbers:</para>

<para role='centered'>
3E5, .3E0, .34568127E2, - .345681E10
</para>

<para>would convert to the following integers, respectively:</para>

<para role='centered'>
300000, 0, 34, -3456810000.
</para>
</sect2>

<sect2><title>Transfer Statement</title>

<indexterm><primary>TRANSFER Statement</primary></indexterm>

<para>This statement has the form:  TRANSFER TO &scriptS;</para>

<para>Here &scriptS; may be any statement label or any expression in
<!-- beginpage II.11 -->
statement label mode which labels an executable statement.  Execution
of this statement causes the computation to continue from the
statement whose label is the value of &scriptS;.  Examples: TRANSFER TO
SUMX, TRANSFER TO SWTCH (K + 2) (if K=4 then the value of SWTCH(K+2)
is SWTCH(6)).</para>

</sect2>

<sect2><title>Conditional Statements</title>

<indexterm><primary>Conditional Statement</primary></indexterm>

<para>There are two types of conditional statements.</para>

<para>(a) Simple Conditional</para>

<indexterm><primary>Conditional, Simple</primary></indexterm>
<indexterm><primary>Simple Conditional</primary></indexterm> 

<para role='centered'>
WHENEVER B,Q
</para>

<para>Here B is a Boolean expression and Q any executable statement
except the following: end of program, another conditional, iteration,
and function entry.  If at the time of execution of this statement,
the expression B has the value 1B, the statement Q is executed.  If,
however, B=0B, then Q is skipped and computation continues from the
next statement in sequence.  The comma in this statement, as in other
statements containing punctuation, must be written.</para>

<para>Examples:</para>

<para role='centered'>
WHENEVER XM.LE.1, TRANSFER TO END
WHENEVER I.GE.N.AND.J.NE.I-1, I=0
</para>


<para>(b) Compound Conditional</para>

<!-- Original has hand-drawn large right curly braces pointing at each -->
<!-- theta from the left, indicating the scope of the conditional body -->
<programlisting>
        &scriptS;<subscript>1</subscript>        WHENEVER B<subscript>1</subscript>
        
                ...
                ...        &THgr;<subscript>1</subscript>
                
        &scriptS;<subscript>2</subscript>        OR WHENEVER B<subscript>2</subscript>
                ...
                ...        &THgr;<subscript>2</subscript>
                ...
                ...
        &scriptS;<subscript>k</subscript>        OR WHENEVER B<subscript>k</subscript>
                ...
                ...        &THgr;<subscript>k</subscript>
        &scriptS;<subscript>k</subscript>+1        END OF CONDITIONAL
</programlisting>

<indexterm><primary>END OF CONDITIONAL Statement</primary></indexterm>

<para>Often the last condition B<subscript>k</subscript> is always
true.  This may be expressed by the statement</para>
<!-- beginpage II.12 -->

<programlisting>
OR WHENEVER 1B
</programlisting>

<para>or alternately the statement</para>

<indexterm><primary>Otherwise</primary></indexterm>

<programlisting>
OTHERWISE
</programlisting>

<para>The &scriptS;<subscript>i</subscript> are statement labels which
need not be used unless desired.  k may equal one (if no "OR
WHENEVER..." statements are used). Here B<subscript>1</subscript>,
..., B<subscript>k</subscript> are Boolean expressions, and the
execution of this block of statements is as follows.</para>

<para>Each B<subscript>1</subscript> is tested in turn, starting with
B<subscript>1</subscript>.  It B<subscript>1</subscript> has the value
0B, then B<subscript>2</subscript> is tested, etc.  As soon as some
expression, say B<subscript>j</subscript>, has the value 1B, then the
statements between (but not including)
&scriptS;<subscript>j</subscript> and
&scriptS;<subscript>j+1</subscript>
(i.e. &THgr;<subscript>j</subscript>) are executed.  At this point the
execution of the entire block is considered ended, and computation
continues from the first statement after the declaration labelled
&scriptS;<subscript>k+1</subscript>.  In other words, at most one of
the alternative computations is performed; e.g., that one which
immediately follows the first expression B<subscript>1</subscript>
which has the value 1B.  If none of the B<subscript>i</subscript> has
the value 1B, none of the computation in the scope of these statements
is performed.</para>

<para>Example:  The evaluation of the function whose graph is</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig05.png'/>
  </imageobject>
</mediaobject>

<para>might be given by the section of the program:</para>

<programlisting>
WHENEVER X .LE. 0. .OR. 1. .LE. X .AND. X .L. 2. .OR. X .GE.3
 Y = 0.
OR WHENEVER 0 .LE. X .AND. X. .L. 3.
 Y = 1.
END OF CONDITIONAL
</programlisting>

<para>This section of program could be rewritten in another way.</para>

<!-- beginpage II.13 after "Y = X" -->
<programlisting>
WHENEVER 0. .LE. X .AND. X .L. 1.
Y = X
OR WHENEVER 2. .LE. X .AND. X .L. 3.
Y = 1.
OTHERWISE
Y = 0.
END OF CONDITIONAL
</programlisting>

<para>The indentation of the statements between the conditional statements
is not required but contributes to the readability.
<indexterm><primary>Indentation of Statements</primary></indexterm></para>
</sect2>

<sect2><title>CONTINUE Statement</title>

<indexterm><primary>CONTINUE Statement</primary></indexterm>

<para>This statement has the simple form:</para>

<programlisting>
CONTINUE
</programlisting>

<para>It serves as an entry point in the program, and causes no computation
to be performed by its presence or absence.</para>
</sect2>

<sect2 id='THROUGH'><title>THROUGH (Iteration) Statement</title>

<indexterm><primary>Iteration Statement</primary></indexterm> 
<indexterm><primary>Iteration Variable</primary></indexterm> 

<para>The following program segment illustrates the use of this
statement.</para>

<programlisting>
   .
   .
   .
A = D(1, 1)
THROUGH ST1, FOR I = 1, I .G. 10
THROUGH ST1, FOR J = 1, J .G. 10
WHENEVER A .LE. D(I, J), TRANSFER TO ST1
K = I
L = J
    ST1 CONTINUE
   .
   .
   .
</programlisting>

<para>This statement causes the block of statements which follows
immediately afterwards to be repeatedly executed, each time varying
the value of some variable, until the specified list of values for
that variable is exhausted, or until some specified condition is
satisfied.  The THROUGH statement may take either of the following two
forms.</para>

<para>(a) THROUGH &scriptS;, FOR VALUES OF V =
E<subscript>1</subscript>, E<subscript>2</subscript>, ...,
E<subscript>m</subscript></para> <para>Here &scriptS; is the statement
label of the last executable statement in the block to be repeated.
The block of statements following (and not including) the THROUGH
statement, up to <emphasis>and including</emphasis> the statement
whose label is &scriptS;, will be called the "scope" of the THROUGH
statement.  <indexterm><primary>Scope</primary></indexterm> 
Following the word OF appears the name of the iteration
variable (in 
<!-- beginpage II.14 -->
the illustration: V), which may be either an individual variable or
subscripted array variable of any mode.
<indexterm><primary>Mode</primary></indexterm> To the right of the "="
sign may appear any number of expressions E<subscript>1</subscript>,
... E<subscript>m</subscript>.  The modes of the
E<subscript>1</subscript> bear the same relationship to the mode of V
as they would in the statement V = E<subscript>1</subscript> (see
<xref linkend='substitution'/>).</para>

<para>The execution of this statement causes the statements within its
"scope" to be executed, first with V = E<subscript>1</subscript>, then
again with V = E<subscript>2</subscript>, and so on, until the list of
expressions is exhausted.  Computation then proceeds with the
statement immediately following statement &scriptS;.  At this time the
iteration variable will have the value of the expression
E<subscript>m</subscript> unless 
<!-- beginpage II.15 -->
its value was changed during the final iteration. An example of this
type of statement is:</para>

<programlisting>
	THROUGH A, FOR VALUES OF BETA = 3, 4, X5, Y(6 + I) + 3
	J = 5 = BETA + 6
	J1 = J .P..5 - 1
   A    X(BETA) = J1 * COS.(2. * THETA)
</programlisting>

<para>(b) THROUGH &scriptS;, FOR V = E<subscript>1</subscript>,
E<subscript>2</subscript>, B</para>

<para>Here &scriptS; is a statement which defines the "scope" exactly
as in (a) above (with the exception: If &scriptS; is the label of the
THROUGH statement itself, the iteration will proceed as described
below, but the scope will be empty, and the iteration will consist
only of the incrementing of V by E<subscript>2</subscript> and the
testing.)  Following the word FOR is the name of the iteration
variable (in the illustration: V), which may be an individual variable
or subscripted array variable of any mode.  The modes of
E<subscript>1</subscript> and E<subscript>2</subscript> are subject to
the rules which would apply to the statements V =
E<subscript>1</subscript> and V = V + E<subscript>2</subscript>.  B is
a Boolean expression.</para>

<para>The execution of the statement proceeds as follows: The variable
V is set equal to E<subscript>1</subscript>.  If the value of B = 1B,
the scope of the THROUGH statement is not executed.  If the value of B
= 0B, the scope is executed.  V is then incremented by
E<subscript>2</subscript>, and B is tested again. In general, as soon
as B = 1B, the scope is not executed, and the computation proceeds
from the statement immediately following statement &scriptS;!.  Each
time B = 0B, the statements in the scope are executed, then V is
incremented by E<subscript>2</subscript>, and B is tested again.
Thus, when the iteration is finished and B = 1B, V has the value used
during the last computation of the scope, incremented by
E<subscript>2</subscript>.  The scope will not have been executed for
this value of V.  (The value of V will be E<subscript>1</subscript>,
of course, if B = 1B before the scope is executed at all.)  If, at any
time, the computation transfers out of the iteration to another part
of the program, the value of V will be the current value at the time
the transfer was made.</para>

<para>In all cases, every reference to an expression
E<subscript>1</subscript> will involve its current value at the time
of reference.  Moreover, the variable 
<!-- beginpage II.16 --> 
V may have its value changed at any time during the execution of the
scope.  In a statement of the form (a), the value of V will be reset
by the value of the next E<subscript>1</subscript> for the next
computation of the scope.  In a statement of form (b), the current
value of V will be used for incrementing, testing, etc.</para>

<para>Examples:</para>

<para>(i) To evaluate the polynomial
c<subscript>n</subscript>x<superscript>n</superscript> +
c<subscript>n-1</subscript>x<superscript>n+1</superscript> + ...+
c<subscript>1</subscript>x + c<subscript>0</subscript> using the
formula (...((c<subscript>n</subscript>x +
c<subscript>n-1</subscript>)x + c<subscript>n-2</subscript>)x + ...+
c<subscript>1</subscript>)x + c<subscript>0</subscript> (nested
multiplication), we may write the program:</para>

<programlisting>
	INTEGER J,N
	Y = 0
	THROUGH POLY, FOR J = N, -1, .L. 0
  POLY  Y = X * Y + C(J)
</programlisting>
  
<para>(For the meaning of the statement INTEGER J,N see <xref
linkend='mode_declaration'/>).</para>

<para>(ii) A Newton's Method<indexterm><primary>Newton's
Method</primary></indexterm> solution (X<subscript>k+1</subscript> =
x<subscript>k</subscript> -
f(x<subscript>k</subscript>)/f'(x<subscript>k</subscript>)) of the
equation f(x) = cos x - x = 0 could be written as a single statement,
using the criterion "|f(x)| &lt; &epsi; and |x<subscript>k</subscript>
- x<subscript>k</subscript>+1| =
|f(x<subscript>k</subscript>)/f'(x<subscript>k</subscript>)| &lt; |
&epsi;" for stopping the iteration:</para>

<programlisting>
  NEW	THROUGH NEW, FOR X = X0, (COS.(X)-X)/(SIN.(X) + 1.),
  	1	.ABS.(COS.(X) - (X) .L. EPSLON .AND.
	2	.ABS.(COSX.(X) - (X)/(SIN.(X) + 1.) ) .L. EPSLON
</programlisting>
	
<para>where X0 is the initial guess.</para>

<para>(iii) If the transformation of the iteration variable is to be
performed within the scope of the iteration, one may use a zero
increment.  <indexterm><primary>Zero Increment for
Iteration</primary></indexterm> E.g., if J is an integer variable, and
the scope of the iteration is to be performed for those multiples of 2
which are not multiples of 5 and which are less than the value of the
integer K, one might write the iteration as follows:</para>

<!-- beginpage II.17 -->

<indexterm><primary>Iteration, Nested</primary></indexterm> 

<programlisting>
	THROUGH END, FOR J = 2, .GE. K
	...
	...
	J = K J + 2
END	WHENEVER J .E. (J/5) * 5, J = J + 2
</programlisting>

<para>(iv) A table-look-up procedure using an interation statement.
<indexterm><primary>Table Lookup</primary></indexterm> 
Suppose that a string of alphabetic (or numeric) characters (i.e., a
"sentence") has been decomposed into single characters stored in C(1),
C(2), ..., C(K), where K is the length of the string.  Then the first
occurrence of a comma could be found as follows:</para>

<programlisting>
LOOK	THROUGH LOOK, FOR I = 1, 1, C(I), .E. $, $ .OR. I .G. K
	WHENEVER I .G. K, TRANSFER TO NOCOMA		
</programlisting>

</sect2>
<sect2><title>Nested Iteration Statements</title>

<!-- 
In the original, the phrase ", indicated by ... below" was not present.
Instead, a large open-brace at the left of the diagram pointed at the word
"scope", indicating the body section filled with ellipses.
-->
<para>As indicated in <xref linkend='THROUGH'/>, the "scope" of an
iteration statement is the block of statements designated for repeated
execution, <phrase role='note'>indicated by ... below:</phrase></para>

<programlisting>
	THROUGH END, FOR V = E<subscript>1</subscript>, E<subscript>2</subscript>, B
	...
	...
END	...
</programlisting>

<para>Some of the statements within the scope of an iteration may,
themselves, be iteration statements.  However, if iteration statement
<emphasis>b</emphasis> is in the scope of iteration
<emphasis>a</emphasis>, then the scope of <emphasis>b</emphasis> must
be entirely within the scope of <emphasis>a</emphasis>.  The following
diagrams represent some valid configurations:</para>
<indexterm><primary>Scope</primary></indexterm> 

<indexterm><primary>Valid Iteration Configuration</primary></indexterm> 

<!-- beginpage II.18 -->
&scope1;

<para>Here, although the scopes of <emphasis>a</emphasis> and
<emphasis>b</emphasis> both end on statement K, iteration
<emphasis>b</emphasis> is incremented and tested first.  Therefore,
iteration <emphasis>b</emphasis> is completed before iteration
<emphasis>a</emphasis> is incremented:</para>

&scope2;
	
<para>The following diagram represents an invalid configuration:</para>

&scope3;

<!-- beginpage II.19 --> 
<para>When iteration statements occur in the scope of other iteration
statements, they are said to be "nested".  The "nesting depth" of an
iteration statement is the number of iteration statements in whose
scope it appears.  The nesting depth of an iteration may not exceed
50.  <indexterm><primary>Depth, Nesting, of Iteration</primary></indexterm>
<indexterm><primary>Nesting Depth of Iteration</primary></indexterm>
For example:</para>

&scope4;

<para>In example (5), iteration <emphasis>a</emphasis> has a nesting
depth 0, iteration <emphasis>b</emphasis> has nesting depth 1, and
iteration <emphasis>c</emphasis> has nesting depth 2.  In example (3),
both <emphasis>b</emphasis> and <emphasis>c</emphasis> have nesting
depths of 1.</para>

<para>There are no restrictions on jumping into or out of the
statements in the scope of an iteration.</para>

</sect2>

<!-- beginpage II.20 -->
<sect2><title>Pause Statement</title>

<indexterm><primary>PAUSE Statement</primary></indexterm>

<programlisting>
PAUSE NO. n
</programlisting>

<para>This statement indicates a breakpoint in the program, and it
causes the computer to stop in such a way that the operator can
manually start it and automatically go on to the next statement in the
program.  The number n is an octal integer containing up to 5 digits,
which will be displayed on the computer console for the operator to
note when the computer stops, thus indicating the point in the program
at which the stop occurred.</para>

<note><para>The Retrocomputing Museum implementation handles this by
generating code that prints the octal number to standard output, then
waits for the user to press Enter.</para></note>
</sect2>

<sect2><title>Function Statement</title>

<para>Normally, the value of a function will occur as part of an expression, as in the statement:</para>

<indexterm><primary>Value of a Function</primary></indexterm> 

<programlisting>
Z = COS.(X)/SIN.(X + 2.)
</programlisting>

<para>Certain functions, however, may stand alone as separate
statements, as a statement calling for the sorting of a list, etc.
This would appear as:</para>

<programlisting>
EXECUTE LSORT.(ARRAY, MAP, N)
</programlisting>

<indexterm><primary>EXECUTE Statement</primary></indexterm>

<para>(See <xref linkend='funcdefs'/> for definition of functions).
Here ARRAY, MAP, N are the "arguments" of the function (subroutine)
LSORT.  Arguments and parentheses may be omitted in an EXECUTE
statement if the function has no arguments.</para>

</sect2>
<sect2 id='ERROR_RETURN'><title>Error Return Statement</title>

<para>Provision is made for including an error return in function
definition programs (see <xref linkend='funcdefs'/>).  The form of the
statement is simply:</para>

<programlisting>
ERROR RETURN
</programlisting>

<indexterm><primary>ERROR RETURN Statement</primary></indexterm>

<para>(An example of its use is shown near the end of <xref
linkend='internal_and_external'/>).</para>

<para>In order to use it in a function evaluation, the last
(right-most) argument of the function must be the label of a statement
or a variable in statement label mode, whose value is the label of a
statement to which a transfer is made in case the ERROR RETURN
statement is executed.</para>

<note><para>This language is confusing, and doesn't seem to match the
actual uses of ERROR RETURN in the examples.  The Retrocomputing
Museum implementation ignores it.</para></note>

<para>Even though an error return has been provided in the definition
of a function, in the use of the function the last argument may be
omitted.  If it is omitted, execution of the ERROR RETURN statement
will cause control 
<!-- beginpage II.21 --> 
to be transferred to the operating system in which the translated
program is imbedded, with an error indication.</para>

<note><para>The Retrocomputing Museum implementation generates code
that prints ERROR RETURN and terminates the program.</para></note>

</sect2>
<sect2><title>End of program Statement</title>

<indexterm><primary>END OF PROGRAM Statement</primary></indexterm>

<para>This statement has the form:  END OF PROGRAM.</para>

<!-- "in which" below is just "which" in the original -->
<para>This statement must be the last statement in the program, both
physically (i.e., the last card) and in the sequence of computation.
Execution of this statement will transfer control to the operating
system in which the translated program is imbedded.  An alternate way
of terminating a program - i.e., returning to the operating system -
is to attempt to execute an input statement when the data has been
exhausted.</para>

</sect2>
<sect2><title>Function return</title>

<indexterm><primary>FUNCTION RETURN Statement</primary></indexterm>

<programlisting>
FUNCTION RETURN &scriptN;
</programlisting>

<para>This statement is used in a function definition to indicate a
return to the calling program.  &scriptN; is an expression whose value is to
be the output of this function considered as a single valued function.
&scriptN; need not be specified if outputs are specified in the argument list
(see <xref linkend='funcdefs'/>).</para>

</sect2>
<sect2><title>Entry to a function</title>

<indexterm><primary>Function Entry</primary></indexterm>

<para>Entry points to a function being defined are indicated by</para>

<programlisting>
ENTRY TO &scriptN;
</programlisting>

<para>where &scriptN; is the name of this entry (see <xref
linkend='funcdefs'/>).<indexterm><primary>RNTRY TO
Statement</primary></indexterm>
</para>

<note><para>The Retrocomputing Museum implementation supports only
one entry point per function.  Attempting to specify more than one
will raise a compile-time error.</para></note>

</sect2>
<sect2 id='list_statements'><title>List Manipulation Statements</title>

<indexterm><primary>List Manipulation</primary></indexterm> 

<para>These statements facilitate the writing of recursive internal
and external functions.  (see <xref linkend='funcdefs'/>) They cause
the designation and use of a vector for the temporary storage of data
and action transfer instructions.  (i.e. function returns).</para>

<orderedlist numeration='loweralpha'>
<listitem>
<!-- in the original, there was something like a script V here -->
<para>SET LIST TO &scriptL;</para>

<indexterm><primary>SET LIST TO Statement</primary></indexterm> 

<para>&scriptL; is the name of an array element designated as the initial
location to be used for temporary storage.  Consecutive elements will
be used as required by the following statements.</para>
</listitem>
<!-- beginpage II.22 -->
<listitem>
<para>SAVE DATA &scriptL;</para>

<para>&scriptL; is a list of: 1) single or subscripted variable names, 2) array
segments of the form A(i<subscript>1</subscript>, ...,
i<subscript>n</subscript>) ... A(j<subscript>1</subscript>, ...,
j<subscript>n</subscript>) where the i, j subscripts may be any valid
subscript expression and n &ge; 1, 3) constants, or 4)
expressions&mdash;separated by commas.  This statement causes the current
values of the elements of the list as consecutive elements of the
currently designated temporary storage vector&mdash;starting with the first
currently available element.  &scriptL; is the same as any input-output list
(see sec. 2.14).</para>
</listitem>
<listitem>
<para>SAVE RETURN</para>

<para>This statement will appear in the scope of the definition of a
function (see <xref linkend='funcdefs'/>) and cause the reentry point
to the calling program to be stored as the next available element of
the currently designated temporary storage vector.</para>
</listitem>
<listitem>
<para>RESTORE DATA &scriptL;</para>

<indexterm><primary>RESTORE DATA Statement</primary></indexterm>
<indexterm><primary>RESTORE RETURN</primary></indexterm> 

<para>&scriptL; is a list of single or subscripted variable names or
array segments of the type described in (b).  If the list designates n
names (not necessarily n items in the list) the values of the last n
elements of the currently designated temporary storage vector become
the values of the list variables.  The order of this value assignment
assuming k used locations in temporary storage vector, left to right
in the list correspond to k, k-1, ... k - n + 1 elements of the
temporary storage vector are then made available for use by successive
SAVE statements.</para>
</listitem>
<listitem>
<para>RESTORE RETURN</para>

<para>This statement will appear in this scope of a function definition and
causes the current last element in the currently designated temporary
storage vector to be used as the reentry point to the program calling
the function.  The last element of temporary storage is then made
available for use by successive SAVE statements.</para>
</listitem>
</orderedlist>
</sect2>
<!-- beginpage II.23 -->
<sect2><title>Input-Output Statements</title>

<indexterm><primary>Input-Output Statements</primary></indexterm>

<note><para> The Retrocomputing Museum implementation does not
implement TAPE and DRUM statements.</para></note>

<indexterm><primary>Input-Output List</primary></indexterm>

<para>In this section the follwing definition the following
definitions will hold.  &scriptF; is the location of a format
specification vector (see <xref linkend='format_specs'/>) which must
be an integer variable name. &scriptN; is an expression whose value is
to be either a tape number or a drum number.  &scriptL; is an
input-output list.  Elements of &scriptL; may be: 1) single variable
names or array names with subscripts;, 2)
blocks<indexterm><primary>blocks. Input-Output</primary></indexterm>
of the form A(i<subscript>i</subscript>, ...,
i<subscript>n</subscript>) ... A(j<subscript>i</subscript>,
...j<subscript>n</subscript>) where the i's and j's may be any
subscript expression and n &ge; 1.  In addition, when &scriptL;
designates an output list, the elements of &scriptL; may be: 3)
constants or 4) expressions.  Elements of a list are separated by
commas.  Example of an output list: AB, D, 2.5, MTX(1) ... MTX(N),
P(14), J(I, K).  Example of a list which may be ysed either for input
or output: A, B, K(3), J(25*I - L), A(K+1)... A(L*2).  To completely
understand the operation of statements which make an explicit
reference to "TAPE" or "DRUM" it is advisable to read the sections of
the IBM 704 Reference Manual which describes the operation of these
units (See <emphasis>Restrictions</emphasis> below).</para>

<indexterm><primary>Format</primary></indexterm>

<variablelist>
<varlistentry>
<term>(a) PRINT FORMAT &scriptF;, &scriptL;</term>
<listitem>
<para>Prints &scriptL; according to format &scriptF; on the off-line
printer.<indexterm><primary>PRINT FORMAT Statement</primary></indexterm>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>(b) PRINT ON LINE FORMAT &scriptF;, &scriptL;</term>
<listitem>
<para>Prints &scriptL; according to format &scriptF; on the on-line
printer.  This statement is used for comments to the operator.  After
&scriptL; has been printed a skip of 1/6 page is automatically
produced, allowing the operator to read the comment.
<indexterm><primary>PRINT ON LINE FORMAT Statement</primary></indexterm>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>(c) PUNCH FORMAT &scriptF;, &scriptL;</term>
<listitem>
<para>Punches &scriptL; on cards according to format &scriptF;.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>(d) READ FORMAT &scriptF;, &scriptL;</term>
<listitem>
<para>Reads cards into &scriptL; according to format &scriptF;.
<indexterm><primary>READ FORMAT Statement</primary></indexterm></para>
</listitem>
</varlistentry>
<varlistentry>
<term>(e) READ BCD TAPE &scriptN;, &scriptF;, &scriptL;</term>
<term>WRITE BCD TAPE &scriptN;, &scriptF;, &scriptL;</term>
<listitem>
<para>Transmits &scriptL; to or from tape &scriptN; in BCD form
according to format &scriptF;.
<indexterm><primary>READ BCD TAPE</primary></indexterm>
<indexterm><primary>READ BINARY TAPE</primary></indexterm>
<indexterm><primary>WRITE BCD TAPE</primary></indexterm>
<indexterm><primary>WRITE BINARY TAPE</primary></indexterm>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>(f) READ BINARY TAPE &scriptN;, &scriptL;</term>
<listitem>
<para>Transmit to &scriptL; from tape &scriptN; until &scriptL; is exhausted or a complete type record has been read.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>WRITE BINARY TAPE &scriptN;, &scriptL;</term>
<!-- beginpage II.24 -->
<listitem>
<para>Transmits &scriptL; to tape &scriptN; in binary form as one record.
<indexterm><primary>WRITE BINARY TAPE</primary></indexterm></para>
</listitem>
</varlistentry>
<varlistentry>
<term>(g) READ DRUM &scriptN;, &scriptA;, &scriptL;</term>
<term>WRITE DRUM &scriptN;, &scriptA;, &scriptL;</term>
<listitem>
<para>Transmits &scriptL; to or from drum &scriptN; starting with drum
address &scriptA; (where &scriptA; is an integer expression).</para>
<indexterm><primary>READ DRUM</primary></indexterm>
<indexterm><primary>WRITE DRUM</primary></indexterm>
</listitem>
</varlistentry>
<varlistentry>
<term>(h) REWIND TAPE &scriptN;</term>
<listitem>
<para>Rewinds tape &scriptN;.
<indexterm><primary>REWIND TAPE Statement</primary></indexterm> 
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>(i) END OF FILE TAPE &scriptN;
<indexterm><primary>END OF FILE TAPE Statement</primary></indexterm>
</term>
<listitem>
<para>Writes an end of file mark on tape &scriptN;.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>(j) BACKSPACE RECORD OF TAPE &scriptN;
<indexterm><primary>BACKSPACE RECORD statement</primary></indexterm>
</term>
<listitem>
<para>Move tape &scriptN; back to beginning of last record.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>(k) BACKSPACE FILE OF TAPE &scriptN;, IF LOAD POINT TRANSFER TO &scriptS;
<indexterm><primary>BACKSPACE FILE statement</primary></indexterm>
</term>
<listitem>
<para>Tape &scriptN; is moved backward until an en-of-file mark, the
load point gap, or the load point is encountered.  If an end-of-file
mark has been written previously, executing this statement backspaces
over the end-of-file mark and stops just in front of it (since the
end-of-file mark must be passed over to be recognized). If the tape is
already at the load point, the program goes to the executable
statement labelled &scriptS; (where &scriptS; is a statement label or
variable of statement label mode.)  If the phrase ", IF LOAD POINT
TRANSFER TO &scriptS;" (including the comma) is omitted no transfer is
made even if at load point.</para>
</listitem>
</varlistentry>
</variablelist>    

<sect3><title>End of File and End of Tape</title>

<indexterm><primary>End of File Condition</primary></indexterm>

<para>If an error (improperly formed format specifications, invalid data, a
tape check, etc.) occurs during any input-output statement except READ
DRUM or WRITE DRUM, the subroutine ERROR. is automatically entered.
The subroutine ERROR. sets an error flag and returns control to the
system in which the translated program is imbedded.
<indexterm><primary>ERROR Subroutine</primary></indexterm></para>

<para>If an end-of-file is encountered while executed a READ FORMAT,
READ BCD TAPE, or READ BINARY TAPE statement the subroutine SYSTEM. (a
subroutine which returns control to the system in which the translated
program is imbedded) is automatically entered.  This action can be
changed by executing the statement EXECUTE SETEOF.  (&scriptS;).  The
subroutine SETEOF. 
<indexterm><primary>SETEOF Subroutine</primary></indexterm>
<indexterm><primary>SYSTEM Subroutine</primary></indexterm>
 
<!-- beginpage II.25 --> 
sets the read routines to transfer to the executable statement
labelled &scriptS; when an end-of-file is encountered.  If the
statement EXECUTED SETEOF. (0) is executed the read routines will be
reset to enter SYSTEM. when an end-of-file is encountered.</para>

<para>Normally, if an end-of-tape is encountered while executing a
WRITE BCD TAPE or WRITE BINARY TAPE statement, the tape is rewound, a
comment indicating this is printed for the operator, and the computer
is halted so that the operator can replace the tape.  The program is
then continued from where the end-of-tape was detected.  Thus, no
information is lost and the new tape is a continuation of the old one.
This action can be changed by executing the statement EXECUTE
SETETT. (&scriptS;).  <indexterm><primary>SETETT
Subroutine</primary></indexterm> The subroutine SETETT. sets the write
tape routines to transfer to the executable statement labelled
&scriptS; when an end-of-tape <indexterm><primary>End Of Tape
Condition</primary></indexterm> is encountered.  The tape is not
rewound nor is any comment printed for the operator and the computer
does not stop before this transfer occurs.  Executing EXECUTE
SETETT.(0) will reset the write tape routines to the normal
action.</para>

<para>The subroutines SETEOF. and SETETT. may be executed as many
times as desired.  Only one setting is in effect for end-of-file (that
specified by the latest execution of SETOFF.) and end-of-tape (that
specified by the latest execution of SETETT.), i.e., each setting
cancels the previous one.</para>
</sect3>
</sect2>
<sect2 id='format_specs'><title>Format Specifications</title>
<!-- in the original this title, unlike other sect2s, was all-capsed -->

<indexterm><primary>Format</primary></indexterm>

<para>When information is read from (or punched in) a card into (or
from) a computer, it is necessary to know how this information has
been allocated among the available columns of the card.  Similarly,
whenever information is to be printed by a printer (either on-line of
off-line), it is necessary to know how this information has been
allocated among the columns available on the printer.  A description
of each allocation is called a format specification.  Usually, but not
always, such a specification is accompanied by a list of variables
whose values are to be printed or punched or whose values are to be
read.  (Occasionally, the information is contined entirely in the
format specification, so the list may be empty.)  A format
specification is a string of alphabetic characters (as 
<!-- beginpage II.26 --> 
described below) terminated by an "*"<indexterm><primary>Array
Variables</primary></indexterm>.  This string is stored six characters
per computer word in a vector with integer mode.  This vector may be
preset (see <xref linkend='VECTOR_VALUES'/>), computed, or read in as
data.</para>

<sect3 id='carriage_control'><title>Carriage Control</title>

<indexterm><primary>Carriage Control</primary></indexterm>

<para>Every format specification consists of a description of the allocation
of available columns, and the form in which the particular information
is to appear.  Specifications for reading or punching cards and
printing of information are identical, whith the following exceptions:</para>

<para>(a) A card has only 72 available
columns<footnote><para>Actually, 80 columns may be used, provided the
proper computer hardware configuration is available.  The use of 72
columns is always safe, however, and strongly
recommended. </para></footnote> while a line of print has 120
available columns.  Any attempt to allocate more than the available
number of columns will cause an error return (see <xref
linkend='ERROR_RETURN'/>).</para>

<para>(b) The first column of a card has no special significance.  The first
(left-most) character of a line of print is treated differently.  This
character governs printer carriage control, much as skipping to a new
page, double spacing, etc.  and should not contin information to be
printed.  The user has effectively 119 available columns on a line of
print, but he must always include the first character as a code to
control the vertical spacing for that line.</para>

<para>For example, the specification</para>

<programlisting>
S16, 6HBETA =I2*
</programlisting>

<para>will indicate that the line (or card) starts with a skip of 16 columns
and then prints (or reads or punches) the characters "BETA =" followed
by an integer field of two columns.  If a card is involved, the letter
"B" in "BETA" will be found in column 17, due to the skip of 16
columns.  However, if a line is to be printed, the "B" will print in
column 16 of the printed page, since the first character of the line
(in this case, the first of the 16 columns to be skipped) is detached,
to be interpreted as carriage control leaving an effective skip of 15
columns.  The effect of a "blank" character on carriage control is to
move to the next line before printing, as will be seen from the
following table.  In each case the carriage control character is
effective before the rest of the specification is carried out.</para>

<!-- beginpage II.27 -->

<informaltable frame='none' colsep='0' rowsep='0' role='centered'>
<tgroup cols='2'>
<tbody>
<row><entry>Blank  </entry> <entry>Single space</entry></row>
<row><entry>0      </entry> <entry>Double space</entry></row>
<row><entry>+      </entry> <entry>No space</entry></row>
<row><entry>1      </entry> <entry>Skip to next page</entry></row>
<row><entry>2      </entry> <entry>Skip to next half-page</entry></row> 
<row><entry>4      </entry> <entry>Skip to next quarter page</entry></row>
</tbody>
</tgroup>
</informaltable>

<note id='lptcodes'>
<para>These were the standard control codes for IBM line printers, which
assumed they were printing to 132x66 fanfold paper.  There isn't a lot
of point in simulating them on a modern page printer.  The
Retrocomputing Museum implementation implements them by prefixing the
output string:</para>

<informaltable frame='none' colsep='0' rowsep='0' role='centered'>
<tgroup cols='2'>
<tbody>
<row><entry>Blank  </entry> <entry>No prefix</entry></row>
<row><entry>0      </entry> <entry>\n</entry></row>
<row><entry>+      </entry> <entry>Not supported, no prefix.</entry></row>
<row><entry>1      </entry> <entry>Form feed</entry></row>
<row><entry>2      </entry> <entry>Two vertical tabs</entry></row> 
<row><entry>4      </entry> <entry>One vertical tab</entry></row>
</tbody>
</tgroup>
</informaltable>
</note>

<para>As another example, the specification</para>

<para role='centered'>
6H1PHI  =  F6.3^*
</para>

<para>would cause a skip to the next page (because the first character is a
"1"), and cause "PHI =" to be printed, followed by a fixed point
number.  As will be explained below, the "6H" that appears in the
specification indicates that 6 Hollerith (or BCD) characters follow,
e.g., "1PHI =".  Note that blanks are counted as characters here.  It
should be understood that this special behavior with regard to column
1 pertains to lines that are to be printed (either on-line or
off-line), and not at all to cards.</para>

</sect3>
<sect3><title>The Basic Field Description</title>

<para>Each specification describes successive fields across the
available columns, starting fromthe left.  If the specification
describes fewer than the total number of available columns, the line
(or card) will automatically be filled in with blanks.  But, as
indicated above, if more than the total number of available columns is
included in the specification, an error return (see <xref
linkend='ERROR_RETURN'/>) will result.</para>

<para>The basic field description consists of a letter followed by an
integer.  The letter indicates the form of the information in the
external medium as follows:</para>

<indexterm><primary>Field Description (Format)</primary></indexterm>

<informaltable frame='none' colsep='0' rowsep='0'>
<tgroup cols='2'>
<tbody>
<row>
  <entry>S
    <indexterm><primary>S Field (Format)</primary></indexterm>
  </entry>
  <entry>Skip (or blank information)</entry>
</row>
<row>
  <entry>I
    <indexterm><primary>I Field (Format)</primary></indexterm>
  </entry>
  <entry>Integer</entry>
</row>
<row>
  <entry>F
    <indexterm><primary>F Field (Format)</primary></indexterm>
  </entry>
  <entry>Fixed point number (Internally floating point)</entry>
</row>
<row>
  <entry>E
     <indexterm><primary>E Field (Format)</primary></indexterm>
  </entry>
  <entry>Floating point number</entry>
</row>
<row>
  <entry>K
    <indexterm><primary>K Field (Format)</primary></indexterm>
  </entry>
  <entry>Octal number</entry>
</row>
<row>
  <entry>C
    <indexterm><primary>C Field (Format)</primary></indexterm>
  </entry>	
  <entry>Characters</entry>
</row>
</tbody>
</tgroup>
</informaltable>

<para>(For the purposes of input-output the Boolean values 0B, 1B are
considered as integers and will be punched in cards and appear in
print as 0, 1.) 
<!-- beginpage II.28 -->
The integer indicates the size of the field; i.e.,
the number of available columns to be used.  For example, K3 indicates
a 3-column octal field, C23 indicates a 23-column character field,
andf S31 indicates a blank field of 31 columns.</para>

<para>For F and E fields, i.e., fixed and floating point numbers, there is
always the question of the placement of the decimal point, the form of
the numbers, etc. in addition to the field size.
<indexterm><primary>Decimal Point in Format</primary></indexterm></para>

<para>For this reason, the basic field description for E and F fields
requires an additional integer giving the number of places after the
decimal point that are to be rounded and printed (or read, or
punched).  This integer is always taken <emphasis>mod 10</emphasis>.
For example, the specificaiton (F20.3) and the specification (F20.13)
both describe a twenty column fixed point field in which a number will
occur with three digits to the right of the decimal point.  The
decimal point <emphasis> in the specification itself </emphasis> must
always be present for E and F fields.</para>

<para>Within the <emphasis> numeric </emphasis> type fields, E, F, I, and K,
"+" signs are not printed or punched, nor are they necessary on input
cards.  However, "-" signs may not be omitted on input, and are always
printed and punched.  If the field description gives a field size
larger than the number requires, the number is pushed as far right as
possible.  If the field size given in a specification is too small,
information is printed, punched, or read from the <emphasis> right
</emphasis> end of the field until the field is exhausted, and the
left end of the number is truncated, including sign.  It is important,
therefore, to be sure to provide a large enough field to handle the
information required.  In fact, some spacing can be achieved by giving
large field sizes, since blanks automatically occur to the left of a
number pushed to the right end of an over-sized field.</para>

</sect3>
<sect3><title>The Form of the Number</title>

<para>Integers (I fields) and octal numbers (K fields) are printed, punched,
etc., directly, without any decimal point.  Numbers <emphasis> printed
</emphasis> or <emphasis> punched in E fields </emphasis> have the
form (if 5 decimal places are requested, for example):</para>

<para role='centered'>
+0.x<subscript>1</subscript>x<subscript>2</subscript>x<subscript>3</subscript>x<subscript>4</subscript>x<subscript>5</subscript>E&plusmn;n<subscript>1</subscript> n<subscript>2</subscript>
</para>
<!-- beginpage II.29 -->

<para>where n<subscript>1</subscript>n<subscript>2</subscript> is the
exponent.  On <emphasis>input cards</emphasis> numbers in E fields
must have an exponent of the form</para>

<para role='centered'>
E&plusmn;n<subscript>1</subscript>n<subscript>2</subscript>
</para>

<para>although if the sign is punched, the "E" may be omitted.  Similarly,
if the "E" is punched, a "+" may be omitted, as well as a leading zero
in the exponent.  The exponent must be counted in the field size.</para>

<para>Numbers to be <emphasis> printed or punched </emphasis> in
<emphasis> F fields </emphasis> have the form (if 5 decimals digits
are requested, for example):</para>

<para role='centered'>
&plusmn;x<subscript>1</subscript>x<subscript>2</subscript>x<subscript>3</subscript>x<subscript>4</subscript>x<subscript>5</subscript>x<subscript>6</subscript>x<subscript>7</subscript>x<subscript>8</subscript>
</para>

<para>although "+" signs are not printed.  <emphasis> On input cards
</emphasis> "+" signs may be omitted, but not "-".</para>

<para>On both E and F input data on cards, blanks are regarded as
zeros, and any number of digits may be used, but only 8 digits of
accuracy are retained.  Moreover, E and F input data need not have the
decimal point punched.  If the decimal point is not punched, the field
specification determines its position.  For example, the punched
number +9032 described by the specification F10.2 would be understood
to be the number +90.32 because the 2 in the specification indicates 2
decimal places to the right of the point.  Similarly, the punched
number +9032E3 described by the specification E10.4 would be
understood to be the number +.9032E3.  If the decimal point is
punched, however, it completely overrides the setting of the point by
the specification.  The entire specification must be present,
however.</para>

</sect3>
<sect3><title>Permissible Conversion</title>

<para>It should be understood that there must be a relationship
between the form of a number inside the computer and its external
form.  In other words, a number described by an I field specification
is assumed to be an integer in storage.  A number described by E or F
specification is assumed to be in floating point form in storage.
Similarly a number govern by a K specification will be handled by
direct binary-octal conversion.  Information decribed by a C
specification is assumed to be in alphabetic (BCD) form both inside
the computer and outside.</para>

</sect3>
<!-- beginpage II.30 -->
<sect3 id='field_repetition'><title>Repetition of Basic Field Specifications</title>

<para>If several consecutive fields can be described by the same basic
specification, reptition may be avoided by prefixing the basic
specification by its multiplicity.  For example, the
specification</para>

<para role='centered'>
3F10.3, E18.4, 2E9.1, 3I2*
</para>

<para>is a short way of writing:</para>

<para role='centered'>
F10.3, F10.3, F10.3, E18.4, E9.1, E9.1, I2, I2, I2*.
</para>

<para>Either specification may be used, of course.  A group of basic
specifications may be repeated by enclosing the group in parentheses
and preceding the left parenthesis by the multiplicity.  Thus</para>

<para role='centered'>
3E10.3, 2(I2,3F10.1), 2C5*
</para>

<para>would be equivalent to the following:</para>

<para role='centered'>
E10.3, E10.3, E10.3, I2, F10.1, F10.1, F10.1, I2, F10.1, F10.1, F10.1, C5, C5*
</para>

<para>Such grouping parentheses may not be nested.</para>

</sect3>
<sect3><title>Scale Factors</title>

<para>One extra feature is allowed when reading or printing E and F
fields.  A "scale factor" may be applied to an <emphasis> F number
</emphasis> according to the formula</para>

<para role='centered'>Printed number = Internal number x
10<superscript>Scale factor</superscript></para>

<indexterm><primary>Scale Factor (Format)</primary></indexterm> 

<para>(where the scaling is accomplished before the conversion is
done).  The "scale factor", followed by the letter
"P"<indexterm><primary>P Prefix (Format)</primary></indexterm> is
prefixed to the basic field specification, as in the example</para>

<para role='centered'>
-2P2F7.3, F7.3*
</para>

<para>Thus, three numbers which would print 0.522 -1.567 93.671
according to the specification 3F7.3* would print instead 0.005 -0.16
93.671 if the specification -2P2F7.3, F7.3* were used.  It must be
noted that for <emphasis> F fields </emphasis> this scale factor
actually changes the values of the numberse to which it applies.  It
affects only those numbers to which it is directly applied, however.
For <emphasis> E fields </emphasis>, the "scale factor" causes the
number itself to be modified, but the exponent is correspondingly
modified so the true value of the number remains <emphasis> unchanged
</emphasis>.  Thus the number 0.9321E-3 would print as 0.9321E-03
<!-- beginpage II.31 -->
according to the specification E18.4*, but it would print as
93.2100E-05 according to the specification 2PE18.4*.  Unlike an F
number, the <emphasis> value </emphasis> is the same in either
case.</para>

</sect3>
<sect3><title>Multiple Specifications</title>

<indexterm><primary>Multiple Specifivcations (Format)</primary></indexterm>

<para>Several specifications may be condensed into one larger one by
the use of the character "/".  Each appearance of "/" (except as part
of a Hollerith field-see <xref linkend='hollerith_fields'/>)
<indexterm><primary>Hollerith (BCD)</primary></indexterm> indicates
that the specification of a new line (or card) is to be started with
what follows.  A pair "//" causes a blank line (or card), three "///"
cause two blank lines (or cards), etc.  Thus, the specification</para>

<para role='centered'>
3F10.3/I2, K18, 2C5/7I3*
</para>

<para>implies that one line (or card) is described by the
specification 3F10.3, and the next line (or card) is described by the
specification I2,K18,2C5, and the next by 7I3.  It must be noted that
each line (if printing is being described) is described individually
here, and must <emphasis> include its own carriage control </emphasis>
(see <xref linkend='carriage_control'/>).
<indexterm><primary>Carriage Control</primary></indexterm>
</para>

</sect3>
<sect3 id='hollerith_fields'><title>Hollerith fields</title>

<para>Although the C specification is available for transmitting
characters (Hollerith information) to and from storage, it is often
convenient to include strings of Hollerith characters directly in the
format specification.  This is done by means of a basic Hollerith
field specification consisting of the string of characters to be
transmittted, preceded by a count of these characters and the letter
"H".  Thus, if the specification</para>

<para role='centered'>
1H1 F10.3, 6HBETA = E10.2
</para>

<para>were used in printing one would obtain a new page skip, because
of the one column Hollerith field containing the character "1".  Then
a ten column F number would print, followed by the characters "BETA ="
and a floating point ten column field.  Note that blanks are
completely ignored throughout all format specifications except when
they occur as characters in a Hollerith string.  Note also, that while
every field specification of types S, I, E, F, K, and C must be
followed by commas<indexterm><primary>Comma (in
Format)</primary></indexterm>, the comma may be omitted after a
<!-- beginpage II.32 -->
Hollerith string of the type
described here.  The comma may be used, however, if desired.</para>
</sect3>

<sect3><title>Character fields</title>

<para>It has been stated above that a <emphasis> number </emphasis>
appearing in an oversize field is pushed as far as possible to the
<emphasis> right</emphasis>.  In the case of C information
(characters) 
<indexterm><primary>C Field (Format)</primary></indexterm>
<indexterm><primary>Character Field (Format)</primary></indexterm>, 
any information occurring in an
oversize field is pushed to the <emphasis> left </emphasis>, while in
either case, unused columns of the field are filled with blanks.
Similarly, in the case the specification describes too small a field,
characters are taken from the <emphasis> left end </emphasis> of the
field until the field is exhausted.</para>

<para>Thus, if a card contins the characters: ABCDEFGHIJK in column 1
through 11, and it is read according to the specification 2C3*, the
two six character words that are read into the computer are:</para>

<literallayout>
			ABC&squ;&squ;&squ;
			DEF&squ;&squ;&squ;
</literallayout>

<para>(where "&squ;" denotes "blank"), while the specification C6* would
cause a single word to be read:</para>

<para role='centered'>
ABCDEF
</para>

<para>and C7, C3* would cause the words:</para>

<para role='centered'>
ABCDEF and HIJ&squ;&squ;&squ;
</para>

<para>to be read (since at most six characters can go into one word of
storage).<indexterm><primary>Bocks, Input-Output</primary></indexterm></para>

</sect3>
<sect3><title>Relationship between the List and the Specification</title>

<indexterm><primary>Input-Output List</primary></indexterm>

<para>The "list" consists of a set of names of variables to or from
which information is to flow.  Except for Hollerith strings imbedded
in the format specification itself (see <xref
linkend='hollerith_fields'/>) and the S fields, each field in the
specification refers to one item on the list.  For this purpose, a
regional entry on the list, such as A(6) ...A(8), counts as several
names of variables (in this case, the three variables A(6), A(7), and
A(8).)  During the transmission of information, the input or output
subroutine scans both the list and the specification simultaneously,
correlating corresponding entries, and associating a field size, a
type of conversion, etc. to each variable. 
<!-- beginpage II.33 -->
If a Hollerith string is
encountered in the specification, it is immediately transmitted, and
it is not associated with any item on the "list."</para>

<para>For example, if the list consisted of:</para>

<para>A, B(1,1), I, K, where I and K were integers, and the others floating
point, and the specification was</para>

<para role='centered'>
1H1, F11.3, -2PE14.4, S13, 3HM =I3, S9, 3HJ =I3*
</para>

<para>we might find a printed line something like the following (at the top of the next page because of the 1H1):</para>

<para role='centered'>
456.010 -16.1251E+02			M = 50			J = 17
</para>

<para>The same list would look the following way with the
specification 1H1, 2F11.3, S16, 3HM =I3, S9, 3HJ = 13*:</para>

<para role='centered'>
456.101  -1612.510			M = 50			J = 17
</para>

<para>As stated above, a specification may not account for more than
72 columns on a card.  It may happen, however, that a list calls for
more information than can appear on a single card.  Or perhaps only a
certain part of each card is to be read.  The determining factor in
every case is whether or not the entire list has been accounted for.
After each cards is read according to the format specification, the
list is consulted; if not yet satisfied, another card is read, and so
on.  It is important to realize that the specification is not
necessarily scanned from the beginning when a new card is read.  In
fact, the specification scanner moves to the left from the end of the
specification (the *) until it hits a left parenthesis not in an H
field.  (If there is no left parenthesis, it will move to the
beginning of the specification).  It then examines the characters just
to the left of this left parenthesis to see if they are a multiplicity
indication (see <xref
linkend='field_repetition'/>). <indexterm><primary>Multiplicity</primary></indexterm>
From this left parenthesis (together with the multiplicity, if any) to
the end of the specification now becomes the format specification
until the list is satisfied.  A similar statement may be made for
printed or punched output.</para>

<para>Thus, in the specification:</para>

<para role='centered'>
3F10.3 /4(F10.3, 6HBETA = I2)*
</para>
<!-- beginpage II.34 -->

<para>the first line printed (or read) would have three fixed point numbers,
subsequent lines would all be printed (or read) according to the
specification</para>

<para role='centered'>
4(F10.3, 6HBETA =I2)*
</para>

<para>As an example, one might have an integer on a first data card,
followed by many cards, each with six floating point numbers.  The
specification might then be:</para>

<para role='centered'>
I6/(6E10.5)*
</para>

<para>Only the first six columns would be read on the first cards, and only
60 columns would be read on subsequent cards.  The remaining columns
are ignored and may contain any <emphasis> legitimate </emphasis>
Hollerith characters.</para>

<para>If a specification contains a Hollerith string of the form
nHa<subscript>1a</subscript><subscript>2</subscript>...a<subscript>n</subscript>, certain conventions are observed.  (1) If the list is
satisifed, but the next field specification is a Hollerith string, the
string is transmitted, anyway.  (2) On input, i.e., reading from
cards, when a Hollerith string is encountered in the specification,
the information in the corresponding columns of the input card will be
brought in and will replace the BCD string itself within the format
specification.  This can then be used as a specification for output,
for example.  This is useful for labelling a set of data and causing
the label to appear on the output along with a date, etc.</para>

<para>Thus, a card punched as follows:</para>

<para role='centered'>
1 DATA SET NO. 3-A		JULY 31, 1959			J. DOE
</para>

<para>might be read in with a format specification</para>

<para role='centered'>
72H				(72 blank spaces)			*.
</para>

<para>Later, this specification could be used to print the same information
as a heading for the results.  Note the "1" provided for carriage
control for the printing.</para>

<para>WARNING: The specifications S72* and 72(1H )*, while indicating 72
blank spaces, do not allow the reading in of an entire card, as
indicated above, since they do not really provide a storage region of
72 characters in length into which the information on the card may be
read and stored until needed.</para>
</sect3>
</sect2>
</sect1>
<!-- beginpage II.35 -->

<sect1><title>Declarations (Non-executable statements)</title>

<indexterm><primary>Declarations</primary></indexterm>
<indexterm><primary>Non-Executable Statements</primary></indexterm>

<para>Declarations are non-executable statements, and, except for
function declarations, they may occur anywhere in the program.  Their
purpose is to furnish information to the translator program or to the
reader of the program.  Declarations may have statement
labels,<indexterm><primary>Statement Labels</primary></indexterm> but
these labels are ignored by the translator, and may not be referred to
in other statements.</para>

<sect2><title>Remark Declaration</title>

<indexterm><primary>Remark Declaration</primary></indexterm>

<para>A remark declaration consists of any string of characters
acceptable to the computer.  This statement is completely ignored by
the translator, and furnishes information to the reader of the
program.  Every card of the remark declaration must have an "R" in
column 11.</para>

</sect2>
<sect2 id='mode_declaration'><title>Mode Declaration</title>

<para>All variables and function values are assumed to have the normal mode
unless declared otherwise.  Any of the other modes may be specified as
the normal mode by writing the following declarations:</para>

<indexterm><primary>Mode</primary></indexterm>
<indexterm><primary>Mode Declaration</primary></indexterm>

<para role='centered'>
NORMAL MODE IS &scriptM;
</para>

<para>where &scriptM; is one of the following phrases; INTEGER, BOOLEAN, STATEMENT
LABEL, FUNCTION NAME, or FLOATING POINT.  Only one such declaration
may appear in a program and it is in effect for the whole program, no
matter where it occurs in the program.  If a variable or function
value is to have a mode different from the normal mode then its modes
must be declared in a declaration of the following form:</para>

<para role='centered'>
&scriptM; V, L, ..., F., ..., BFN.
</para>

<para>where &scriptM; is one of the phrases; INTEGER, BOOLEAN, STATEMENT LABEL,
FUNCTION NAME, or FLOATING POINT; for example, BOOLEAN
P,Q,DIGIT.TRUTH.  Following &scriptM; is the list of variables and functions
whose values are to be of mode &scriptM;.  A program may contain any number
of such mode declarations but a name may not be declared to be of two
different modes.</para>

<para>All constants are automatically assigned modes by the translator
(see <xref
linkend='constants'/><indexterm><primary>Constants</primary></indexterm>
).  Other automatic assignments of modes are:</para>
<!-- beginpage II.36  -->

<!-- not clear what this is referring to -->
<indexterm><primary>Single Variable</primary></indexterm>

<orderedlist numeration='loweralpha'>
<listitem><para>A name appearing in the statement label field is
assigned statement label mode (see <xref
linkend='statement_labels'/>)<indexterm><primary>Statement
Labels</primary></indexterm>.</para></listitem>

<listitem><para>A function name<indexterm><primary>Function
Name</primary></indexterm> constant is assigned function name mode
(see <xref linkend='funcdefs'/>).</para></listitem>

<listitem><para>A vector appearing as the dimension vector of some
array<indexterm><primary>Array Variables</primary></indexterm> in a
dimension declaration is assigned integer mode (see <xref
linkend='dimension_declaration'/>).
<indexterm><primary>Vector</primary></indexterm>
</para></listitem>

<listitem><para>A vector which is preset by a vector values
declaration is assigned a mode consistent with the assigned values
(see <xref linkend='VECTOR_VALUES'/>).<indexterm><primary>Dimension
Vector</primary></indexterm> <indexterm><primary>VECTOR VALUES
Statements</primary></indexterm></para></listitem>
</orderedlist>

</sect2>
<sect2 id='dimension_declaration'><title>Dimension Declaration</title>

<indexterm><primary>DIMENSION Statement</primary></indexterm>

<para>Variables may be declared to be array variables, such as vectors or
matrices of various dimensions, rather than individual variables.</para>

 <para>Each array is stored in a region whose elements may be referred
to by means of a single subscript, such as A(0), A(1), B(16), etc.
Even elements of higher dimensional arrays may be referred to in this
way at any time.  We shall call the subscript thus associated with
each element of an array its "linear
subscript."<indexterm><primary>Linear Subscript</primary></indexterm>
If A is an array then the name A is equivalent to A(0), e.e., the name
A written without a subscript is assumed to have a subscript of
zero.<indexterm><primary>Zero subscript</primary></indexterm></para>

<para>Two dimensional matrices are stored internally by rows, i.e., an
m &times; n matrix will be stored in the order: a<subscript>11</subscript>,
a<subscript>12</subscript>, a<subscript>13</subscript>, ...,
a<subscript>1n</subscript>, a<subscript>21</subscript>, ...,
a<subscript>2n</subscript>, ... a<subscript>mn</subscript>.  In
general, matrices are stroed in the order determined by varying the
right-most subscript first, then the next right-most, etc. Thus, an m
&times; n &times; p &times; q matrix would be stored in the order:
a<subscript>1111</subscript>, a<subscript>1112</subscript>, ...,
a<subscript>111q</subscript>, a<subscript>1121</subscript>,
a<subscript>1122</subscript>, ... a<subscript>112q</subscript>, ...,
a<subscript>11pq</subscript>, a<subscript>1211</subscript>,...,
a<subscript>1npq</subscript>, ... a<subscript>mnpq</subscript>.</para>

<indexterm><primary>Matrix Notation</primary></indexterm> 

<para>Elements of higher dimensional arrays may be referred to not only by
their linear subscripts but also by the usual matrix notation, such as
A(1,1), A(I,J), B(I+6,J/3+3).</para>

<para>Although any number of dimension declarations may be used in a
program, as many variables as desired may be "declared" in any
dimension declaration.  The declaration consists of the word
DIMENSION, followed by
<!-- beginpage II.37 -->
the variables to be declared.  Each variable is
immediately followed by one or two arguments (separated by a comma)
enclosed in parentheses, as follows:</para>

<para>The first argument is a positive integer constant, specifying the
largest linear subscript which an element of the array is expected to
assume during the execution of the program.  The size of the region
allocated is this number plus one, regardless of whether the program
actually makes use of this amount or not.</para>

<para>The second argument, given only for arrays with dimension n > 1,
is the name of the first element in the "dimension vector" for this
array.  If this name is D(k) (k must be an integer constant), the
vactor D is automatically assigned integer mode.  D may not be
declared to be other than integer.  In addition, D must itself be
dimensioned, either by declaration or by presetting its values (<xref
linkend='VECTOR_VALUES'/>) to have its largest linear subscript &le;
k+n.  Assuming that elements of the array to be dimensioned are to be
referred to as A(I<subscript>1</subscript>, I<subscript>2</subscript>,
I<subscript>n</subscript>), the elements of the linear array D,
i.e. D(k), D(k + 1), ...D(k + n), must be preset (or set during
computation) to the values</para>

<literallayout>
        D(k) = n
        D(k + 1) = the linear subscript which corresponds to A(1,1, ...1) - commonly set to 1
        D(k + 2) = current upper bound of I<subscript>2</subscript> (i.e., the current highest value of I<subscript>2</subscript> during the computation)
        D(k + 3) = current upper bound of I<subscript>3</subscript>
        D(k + 4) = current upper bound of I<subscript>4</subscript>
        .
        .
        .
</literallayout>

<para>The lower bound of each subscript is assumed to be unity.
<indexterm><primary>Range of Scubscripts</primary></indexterm></para>

<para>Thus, in the statement: DIMENSION XA(400, V), YT(300, K(3)) where V(0)
= 2,V(1) = 6, v(2) = 13, K(3) = 3, K(4) = 4, K(5) = 8, and K(6) = 9, the
variables XA and YT are designated as 2-dimensional and 3-dimensional
arrays respectively.  Considering the array element XA(I,J), the range
of J may be expressed by 1 &le; J &le; 8 and 1 &le; K &le; 9.  The
array XA will have a storage region of length 401 set aside for it,
e.g., XA(0), ...XA(400), and the 395 elements XA(6), XA(7), ...,
XA(400) may also be referred to as XA(1,1), XA(1,2), ...XA(31,5)
respectively.  The matrix will be located at various places in the XA
region depending on the value of V(1) at the time a reference is made
ot a matrix element during execution of the program.  Observe that
this ability to vary the location of the initial array element (i.e.,
<!-- beginpage II.38 -->
the array element with unit indices) within the linear array allows
the effective use of negative subscripts - in spite of the fact that
the defined ranges of the subscripts are positive.</para>

<para>Similarly, the matrix YT will have 301 locations set aside for it,
although these do not all have to be used.  The base element of YT,
i.e., YT(1,1, 1) will correspond to the element YT(4) since K(4) = 4.</para>

<para>If the array is a
 vector,<indexterm><primary>Vector</primary></indexterm> i.e.,
 one-dimensional, a special convention is adopted.  Only the first
 argument is given to the DIMENSION declaration.  Thus, in the
 statement</para>

<para role='centered'>
DIMENSION V(10)
</para>

<para>the array V is specified as consisting of the eleven elements V(0),
..., V(10).  If a variable appears in more than one dimension
declaration, the highest linear subscript will be used; however, the
dimension vector must be the same in all occurrences.  Negative
subscripts are not available for vectors.</para>

<para>Dimensioning is automatic in two situations</para>

<para>(a) In case a statement label
vector,<indexterm><primary>Statement Label
Vector</primary></indexterm> say L, is used (see <xref
linkend='statement_labels'/>) and n is the highest subscript used on
L in the statement label field (i.e., if L(m) appears then m &le; n),
then n + 1 locations are reserved for L.  L may also appear in a
dimension declaration in which case the highest linear subscript is
used.</para>

<para>(b) If part of all of a linear array is set by a VECTOR VALUES
declaration<indexterm><primary>VECTOR VALUES
Statements</primary></indexterm> the array need not appear in a
dimension statement unless the maximum linear subscript implied by the
initial values is not sufficiently high.</para>

</sect2>
<sect2><title>Equivalence Declaration</title>

<indexterm><primary>EQUIVALENCE Declaration</primary></indexterm>

<para>This declaration has the form</para>

<para role='centered'>
EQUIVALENCE (A,B), (MATRIX, XARRAY), (C, D(3))
</para>

<para>and implies that the variables A and B are to represent the same
storage location throughout the program, that MATRIX and XARRAY are to
represent the same storage location through the program, etc.  (Two
variables which
<!-- beginpage II.39 -->
represent the same location always have the same value at any given
time.)  Thus, any number of equivalences may be established by one
EQUIVALENCE declaration, and any number of such declarations may occur
(at any place) in a program.  They will be treated as one combined
declaration, however.</para>

<para>Variables whose names appear within the same set of parentheses
need not have the same mode.  The mode must be established by the
appropriate MODE declaration
<indexterm><primary>Mode</primary></indexterm> for each of the
variables.  Occurrences within an EQUIVALENCE declaration do not
establish mode.</para>

<para>A nonsubscripted array variable<indexterm><primary>Array
Variables</primary></indexterm> name in an EQUIVALENCE statement
represents that element of the array (considered as a one-dimensional
vector) whose subscript is zero.  Reference in an EQUIVALENCE
statement to an array element of any number of dimensions may be made
by linear-subscript only (i.e., as an element of a vector).  Note that
occurrence of any elements from any two arrays in the same perentheses
implies equating the entire arrays accordingly.</para>

<note><para> The Retrocomputing Museum implementation does not
implement EQUIVALENCE.</para></note>

</sect2>
<sect2 id='ERASABLE'><title>ERASABLE Declaration</title>

<indexterm><primary>ERASABLE</primary></indexterm>

<para>This declaration has the form</para>

<para role='centered'>
ERASABLE MATRIX, XARRAY, YARRAY
</para>

<para>and implies that the arrays and individual variables listed after the
word ERASABLE (which need not have the same number of dimensions) are
disjoint (i.e., non-overlapping in storage), but are assigned to a
special section of storage which is separate from the usual storage of
variables and 
<!-- beginpage II.40 -->
arrays.  Each ERASABLE declaration eliminates the effect of previous
assignments to this special section of storage, thus allowing several
arrays to occupy the same storage at different times.  It should be
understood that this storage is accessible to, andmay be used by,
subroutines.</para>

<note><para>This declaration is a memory-footprint optimization hack.
The Retrocomputing Museum implementation does not implement
it.</para></note>

</sect2>
<sect2><title>PROGRAM COMMON Declaration</title>

<indexterm><primary>PROGRAM COMMON</primary></indexterm>

<para>This declaration has the form</para>

<para role='centered'>
PROGRAM COMMON MATRIX, X, Y1, BC
</para>

<para>and implies that the arrays and individual variables listed
after the words PROGRAM COMMON (which ned not have the same number of
dimensions)<indexterm><primary>DIMENSION
Statement</primary></indexterm> are disjoint (i.e., non-overlapping in
storage), but are assigned to a special section of storage which is
separate from the usual storage of variables and arrays, and separate
from ERASABLE storage (see <xref linkend='ERASABLE'/>).</para>

<para>One use of this statement provides for several sections or a program
to refer to variables and arrays by the same names, while being
translated and checked out separately.  A program divided up this way
would have the form of a main program and several external function
programs, with the main program being used primarily to call on each
of the external functions in turn.  Although variables and arrays to
be used jointly by several external functions can be communicated as
arguments to the functions, assigning them to PROGRAM COMMON makes
them available to all sections.</para>

<para>Note that storage is actually <emphasis> reserved </emphasis> for
PROGRAM COMMON only in the main program (not in external functions,
although the proper address assignment occurs there, also).  Any such
declarations occurring in external function definitions must therefore
occur also in the main program.</para>

<para>Another use for the PROGRAM COMMON assignment is in the case of a
segmented program, i.e., a program so large that it is written in
blocks which will occupy the same section of storage and be brought in
one at a time.  If one block of a program is to use the results of the
previous block's computation, the variables involved should be
specified as being in the PROGRAM COMMON region.  Then they will not
be destroyed in the process of bringing in the new block of program.
The PROGRAM COMMON and DIMENSION declarations which set up this
storage allocation must be identical in all blocks in which these
arrays and variables are to be used, except that later segments may
add additional names <emphasis> at the end of the list </emphasis>.</para>

<para>PROGRAM COMMON declarations do not affect variables and arrays which
have already been assigned to this common section of storage.  If
another such statement occurs in a program, the arrays and variables
listed therein are considered appended to the previous list of PROGRAM
COMMON arrays and variables.  If a program is broken up into a main
program and several external functions, the <emphasis> main program
must be loaded into the computer first </emphasis> if PROGRAM COMMON
is used at all.</para>

<note><para> The Retrocomputing Museum implementation does not
implement COMMON.</para></note>

</sect2>
<sect2 id='VECTOR_VALUES'><title>Presetting Vectors</title>

<indexterm><primary>Presetting Vectors</primary></indexterm>

<!-- The script L in this section is lowercase in the original -->
<para>Any vector or portion of a vector (or array when considered as a
vector, i.e., using linear subscripts) may be preset by a declaration
<!-- beginpage II.41 -->
of the following form:</para>

<!-- not clear what this is referring to -->
<indexterm><primary>Hollerith (BCD)</primary></indexterm> 

<para>(a) VECTOR VALUES &scriptV; = c<subscript>0</subscript>,
c<subscript>1</subscript>, ... c<subscript>&scriptL;</subscript>
<indexterm><primary>VECTOR VALUES Statements</primary></indexterm></para>

<para>Here &scriptV; is of the form N(n) or simply N, if n = 0.  The
elements N(n), ... N(n + &scriptL;) are preset to the values
c<subscript>0</subscript>, c<subscript>1</subscript> ...,
c<subscript>&scriptL;</subscript>, where the c<subscript>i</subscript>
may be any constants.  N is automatically set to have the same mode as
c<subscript>0</subscript> and given a storage reservation of n +
&scriptL; + 1 locations, i.e., this is equivalent to writing DIMENSION
N(N + &scriptL;).  N may appear in a mode declaration provided it is
consistent with the mode of c<subscript>0</subscript>.  If N appears
in other VECTOR VALUES or DIMENSION declarations the maximum length
given or implied for N is used for storage assignment.  The
c<subscript>1</subscript> must all be of the same mode.</para>

<para>(b) VECTOR VALUES &scriptV; = $ k<subscript>1</subscript>
... k<subscript>m$</subscript>,
$k<subscript>m</subscript>+1... k<subscript>p$</subscript>, ...
<indexterm><primary>$ Sign</primary></indexterm></para>

<!-- the m/6 here is $m over 6$ in eqn notation -->
<para>Here the k<subscript>i</subscript> may be any valid characters
(including blanks but excluding "$") and &scriptL; (used as in (a) above) is
equal to the smallest integer &ge; m/6.</para>

<!-- the original had a typo in the first sentence, duplicated "and" --> 
<para>This declaration is useful for presetting dimension vectors and and
format descriptions.  The presetting is done at the time of
translation.  The constants c<subscript>i</subscript> are loaded (as
part of the translated program) into &scriptV;.  This declaration
produces no computation at execution time.  However, the values of
&scriptV; may be modified by other statements in the program during
execution.</para>

<para>Vectors which have been assigned to ERASABLE storage (see
section <xref linkend='ERASABLE'/>)
<indexterm><primary>ERASABLE</primary></indexterm> may not be preset
by a VECTOR VALUES statement.  Vectors which have been assigned to the
PROGRAM COMMON section of storage (see section 3.6) can be preset with
<emphasis>numerical or alphabetical </emphasis> information only (not
statement labels<indexterm><primary>Statement
Labels</primary></indexterm> or function names) and then only if it is
a single section program (i.e., storage is loaded with instructions
only once) or, if it is a multiple section program, the PROGRAM
COMMON<indexterm><primary>PROGRAM COMMON</primary></indexterm> region
is identical in all sections of the program.</para>

</sect2>
<sect2 id='funcdefs'><title>Function Definitions</title>

<indexterm><primary>Function Definition</primary></indexterm>
<indexterm><primary>INTERNAL FUNCTION</primary></indexterm> 

<!-- the xrefs here were in the form "subsection 3.8.x" in the original -->

<para>There are two main types of functions: The <emphasis> internal
</emphasis> function and the <emphasis> external </emphasis> function.
<indexterm><primary>EXTERNAL FUNCTION</primary></indexterm> Since
these are quite similar in many ways, that part of the description
which is specific to external functions will be 

<!-- beginpage II.42 --> 

given in <xref linkend='external_functions'/>, that which is specific
to internal functions in <xref linkend='internal_functions'/>, and
that which is common to both types will follow in subsection <xref
linkend='internal_and_external'/>.  Throughout this section a
single-valued function will be called a "function", and a function
with multiple outputs and/or multiple exits will be called a
"procedure".<indexterm><primary>Procedure</primary></indexterm> For
the purposes of this manual a recursive function is one whose
definition contains calls for the function being defined &dd; or calls
for functions which ultimately call the one being defined.  
<indexterm><primary>Recursive functions</primary></indexterm> Recursive
functions have the same structure as other functions although, in
general, they will include statements of the type described in <xref
linkend='list_statements'/>, and certain considerations should be
borne in mind when constructing such functions.  These considerations
arise from the fact that<emphasis>
names</emphasis><indexterm><primary>Name</primary></indexterm>,
instead of values, are used as function arguments.  The problem is
considered in more detail in the examples in Chapter III.</para>

<sect3 id='external_functions'><title>External Function Definitions</title>

<indexterm><primary>EXTERNAL FUNCTION</primary></indexterm>

<indexterm><primary>Function Name</primary></indexterm>

<!-- In the original, "variables and functions in the main program"
was typoed as "variables and function in the main program" (incorrect
singular).  --> 
<para>These statements define functions not yet available in the
language or as standard package programs ("subroutines").  The
designation "EXTERNAL" implies that the statements which follow are to
be translated indpendently of the main program in which they are to be
used.  (Because of this independence this block of statements is to be
considered an entirely separate program, and must have its own
DIMENSION<indexterm><primary>DIMENSION Statement</primary></indexterm>
and MODE <indexterm><primary>Mode</primary></indexterm> declaration,
etc.)  The word "EXTERNAL" also implies that occurrences of variables
and functions in the current function definition program have no
relation whatever with occurrences of similarly named variables and
functions in the main program (or other definition programs), and no
difficulties will be encountered because of the use of similar names.
The modes of the arguments (if other than the normal mode), must be
declared in the usual way (see <xref linkend='mode_declaration'/>),
but arrays<indexterm><primary>Array Variables</primary></indexterm>
which are arguments need not be
dimensioned.<indexterm><primary>Arguments of
Functions</primary></indexterm></para>

</sect3>
<sect3 id='internal_functions'><title>Internal Function Definitions</title>

<indexterm><primary>INTERNAL FUNCTION</primary></indexterm> 

<para>These statements define functions not yet available in the
language or as standard package programs ("subroutines").  The
designation "INTERNAL" implies that the definition program which
follows is to be translated as part of the main program.  The word
"INTERNAL" also implies that any variables or functions not listed as
arguments in the definition of the 
<!-- beginpage II.43 --> 
function (but used in its evaluation), are understood to be the same
as elsewhere in the main program, and the current values of these
variables and functions will be used.  Names of variables and
functions which occur as arguments of the function being defined are
designated "dummy arguments" (or "bound
variables")<indexterm><primary>Bound Variables</primary></indexterm>
<indexterm><primary>Dummy Arguments</primary></indexterm>.  They must
be distinct from those appearing elsewhere in the program.  The
modes<indexterm><primary>Mode</primary></indexterm> of dummy arguments
(if other than normal mode) must be declared in the usual way, but
arrays<indexterm><primary>Array Variables</primary></indexterm> which
are arguments need not be dimensioned.<indexterm><primary>DIMENSION
Statement</primary></indexterm></para>

<para>One form of internal function definition (not available as an external
function definition because the latter must be a complete, independent
program) is the one sentence definition, which has the form:</para>

<para role='centered'>
INTERNAL FUNCTION SUMSQ.(X,Y,Z) = X * X + Y + Z * Z - T * T
</para>

<para>As indicated above, X, Y, and Z, as they occur here, are dummy
<!-- beginpage II.44 -->
variables, and (X, Y, Z) is the dummy
variable<indexterm><primary>Dummy Arguments</primary></indexterm>
list. The current value of T, however, will be obtained and used each
time the value of the function is needed.  An example of the use of
the function so defined would be:</para>

<para role='centered'>
A = 1.-SUMSQ. (U, V + 3, W) .P..5
</para>

<para>Only nonsubscripted names of variables (either individual or array) or
names of functions (without arguments) may appear in the dummy
variable list.  For this type of function definition no END OF
FUNCTION statement is required.  In the user of the function is an
expression, the arguments may be any expressions that agree in mode
<indexterm><primary>Mode</primary></indexterm>
with the corresponding argument in the declaration.</para>

<para>In the example:</para>

<para role='centered'>
INTERNAL FUNCTION POLY.  (N, X, FN.) = FN. (J*X).P.N - X/XBAR
</para>

<para>which might be used in the statement</para>

<para role='centered'>
BETA ZQ = POLY.(M + 1, Y, SIN.) + POLY.(M -1, Z, COS.)
</para>

<para>it is understood that if N is in the integer mode, then so are Y and
Z. Both M and N would have had to be declarted to be in the integer
mode, of course.  Similarly, the values of SIN. and COS. must be the
same mode as the values of FN.  Moreover in the use of functions this
mode correspondence cannot be checked by the translator.</para>

<para>The function POLY. has as one of its arguments the name of a function.
In the statement BETA the function used in the first term to the right
of the "=" sign is SIN. and in the second term COS..  Hence statement
BETA is then equivalent to:</para>

<para role='centered'>
ZQ = SIN.(J * Y).P.(M + 1) - Y/XBAR + COS.(J*Z).P.(M-1)-Z/XBAR.
</para>

</sect3>
<sect3 id='internal_and_external'><title>Internal and External Functions</title>
<indexterm><primary>Function Definition</primary></indexterm>
<indexterm><primary>INTERNAL FUNCTION</primary></indexterm> 

<para>Each function definition (except single statement definitions
described in <xref linkend='internal_functions'/>) may define any
number of functions and/or any number of procedures.  Within one
function definition all functions and procedurews defined must use
exactly the same set of arguments.  In other words, the functions
CPADD.(X,Y,A,B)and CPMPY.(X,Y,A,B) may be defined, if desired, by one
definition, but the functions SIN.(X) and ARCTAN.(X.Y) would require
separate definitions.
<!-- beginpage II.45 -->
Similarly, the procedures RXSUB. and ADAMS. could be defined by the
same definition if they have the same outputs, say Z and W, and the
same input parameters, say X, Y, T, and N.  However, if they did not
have exactly the same outputs and the same inputs, they would require
separate declarations.</para>

<para>In the <emphasis>use</emphasis> of a function (i.e., the
<emphasis>call</emphasis><indexterm><primary>Function
Call</primary></indexterm> for it) the arguments may be constants,
variables, or expressions.  However, if one of the arguments appears
to the left of an "=" sign <indexterm><primary>Equals
Sign</primary></indexterm> in a substitution statement in the defining
program it is not meaningful to use a constant or an expression for
that argument in the call.  As mentioned earlier, the arguments in the
call for a function cannot be checked for correspondence in mode and
number to arguments in the definition.</para>

<para>The general form of all function definition programs is as
follows:</para>

<indexterm><primary>Function Return</primary></indexterm>

<programlisting>
INTERNAL FUNCTION (X)
ENTRY TO COS.
...
...
...
ENTRY TO SIN.
...
...
...
FUNCTION RETURN ALPHA + J - 3
ENTRY TO TAN.
...
...
...
FUNCTION RETURN BETA/K5 - 4 * D
END OF FUNCTION
</programlisting>

<indexterm><primary>ENTRY TO Statement</primary></indexterm>

<indexterm><primary>END OF FUNCTION Statement</primary></indexterm>

<para>The first statement (INTERNAL FUNCTION (X)) is a function
declaration (i.e., <emphasis>declares</emphasis> that the following
statements define a function).  
<!-- erroneously referred to II.44  -->
<indexterm><primary>EXTERNAL FUNCTION</primary></indexterm>
If this is defining an external function, the declaration would be
EXTERNAL FUNCTION (X).  Following the words INTERNAL (or EXTERNAL)
FUNCTION is the dummy variable list ((X) in this example).  The END OF
FUNCTION declaration is the last statement in the function definition
program.  (In an external 

<!-- beginpage II.46 --> 

function definition this is also the last statement in the program.)
An entry must provided for each function being defined, but several
functions may share any number of FUNCTION RETURN statements.  
<indexterm><primary>Function Return</primary></indexterm>
An entry statement merely marks a point of entry, and does not effect the
sequence of computation in any way.  The expression after the word
"RETURN" indicates that on this return the value of the function is to
be the value of that expression. This expression must agree in mode
with the function whose value it supplies; this agreement is not
checked.  The definitions of functions whose calls are intended to be
included in expressions must have an expression following the FUNCTION
RETURN statement.  If the calls for a function are to appear in an
EXECUTE STATEMENT (generally such functions have multiple outputs) the
FUNCTION RETURN statement may appear without an accompanying
expression.<indexterm><primary>Function Call</primary></indexterm></para>

<para>An example of a definition for
procedures<indexterm><primary>Procedure</primary></indexterm> is as
follows:</para>

<indexterm><primary>EXTERNAL FUNCTION</primary></indexterm>

<programlisting>
EXTERNAL FUNCTION (M, N, I, P, Q)
STATEMENT LABEL N, I
...
...
...
FUNCTION RETURN
...
...
...
WHENEVER B, TRANSFER TO I
...
...
...
TRANSFER TO N
END OF FUNCTION
</programlisting>

<para>In this example, N and I are actual alternate exits, and B represents
some Boolean expression.</para>

<para>It is important to note that internal function definitions of
any kind whatever (including the single statement definition of <xref
linkend='internal_functions'/>) may occur anywhere in the program,
<indexterm><primary>INTERNAL FUNCTION</primary></indexterm> 
except within another internal function definition.  Internal function
definitions may occur within external function definitions, however.
External function definitions may not occur within any other programs,
not even within other external function definitions.  Each external
function definition must be a complete, self-contained program.</para>
<!-- beginpage II.47 after the last hyphen -->

<para>The following is an example of a function whose value is 1/x if
0 &lt; x &le; 1 and 1/x^2 if x &gt; 1.  If x &le; 0, one obtains an
error return (see <xref linkend='ERROR_RETURN'/>).</para>

<programlisting>
&invsf;
</programlisting>

<para>(Here the statments are all labelled only for reference in what
follows.)</para>

<para>The list of dummy variables<indexterm><primary>Dummy
Arguments</primary></indexterm> in the declaration statement itself
(statement A in the preceding paragraph) may contain only
nonsubscripted variable names (either individual or
array)<indexterm><primary>Array Variables</primary></indexterm> or
function names (without
arguments). <indexterm><primary>Name</primary></indexterm> Within the
definition program itself (the statements between statement A and
statement B), a function name will usually occur with arguments, and
an array variable will usually occur with subscripts.</para>

<indexterm><primary>Function Definition</primary></indexterm>

<para>A few comments about the last example.  This definition program
defines a single-valued function of X, called INVSF..  Since no mode
declaration is given it is assumed by the translator that X is
floating point.  The value of INVSF.(X) is computed by the use of a
compound conditional.  If 0 &lt; x &le; 1, (statement G) then
statement C is executed, causing a return<indexterm><primary>Function
Return</primary></indexterm> to the calling program with the value
1/x.  If the condition 0 &lt; x &le; 1 is not true, then the condition
X > 1 is tested (statement H).  If X &gt; 1, statement D is executed.
Finally, if neither of the conditions 0 &lt; x &le; 1 or x &gt; 1 is
true, then statement I finds that X &le; 0 and statement E (the error
return) is executed.  If</para>

<!-- beginpage II.48 after Z = T(I) + INVSP.(Y) *T(I-1) -->

<programlisting>
         A = B - D
         Z = T(I) + INVSF.(Y) *T(I-1)
         Y(I) = Z + R(J) * 2.5
</programlisting>

<para>is part of a program and the error return statement is executed during
the evaluation of INVSF.(Y) (i.e., Y &le; 0), then control is returned to
the system in which the translated program is embedded, with an error
flag set.  If</para>

<programlisting>
	A = B - D
     F  Z = T(X) + INVSF.(Y, ER)* T(I-1)
     S Y(I) = Z = R(J) * 2.5
     	...
	...
    ER  Z = 0
    L   Y(I) = 1.
    	...
</programlisting>

<para>is part of a program and Y &le; 0, then when the ERROR RETURN
statement is executed <indexterm><primary>ERROR RETURN
Statement</primary></indexterm> control transfers to statement ER
(then goes on to L), instead of finishing the execution of statement F
(and then going on to S).  Note that the END OF FUNCTION statement
will never be executed, but must be present in the definition.</para>
<indexterm><primary>END OF FUNCTION Statement</primary></indexterm>
<indexterm><primary>Function Return</primary></indexterm>

</sect3>
</sect2>
</sect1>
<sect1><title>Restrictions</title>

<para>Variable names appearing as <emphasis>dummy</emphasis> arguments
in any function declaration may not appear in a PROGRAM COMMON,
<indexterm><primary>PROGRAM COMMON</primary></indexterm>,
ERASABLE<indexterm><primary>ERASABLE</primary></indexterm>, or
EQUIALENCE declaration.<indexterm><primary>Dummy
Arguments</primary></indexterm><indexterm><primary>EQUIVALENCE
Declaration</primary></indexterm></para>

<para>The name of a function with the period deleted must not be used
as the name of a variable or as a statement label.  A statement label
must not be identical with any variable
name.<indexterm><primary>Statement Labels</primary></indexterm>
<indexterm><primary>Variable</primary></indexterm> 
</para>

<para>The translator automatically calls on some subroutines, hence the
following names may not be used as variable names or statement labels
in a MAD program.  They may be used as function names only when
referring to these subroutines.  (These subroutines will be described
in Chapter 4).</para>

<programlisting>
	SYSTEM.		SETEOF.		PRINT.		READ.
	ERROR.		SETETT.		COMMNT.		TAPERD.
	TAPEWR.		PUNCH.				SETERR.
</programlisting>
<indexterm><primary>COMMNT Subroutine</primary></indexterm>
<indexterm><primary>ERROR Subroutine</primary></indexterm>
<indexterm><primary>PRINT Subroutine</primary></indexterm>
<indexterm><primary>PUNCH Subroutine</primary></indexterm>
<indexterm><primary>READ Subroutine</primary></indexterm>
<indexterm><primary>SETEOF Subroutine</primary></indexterm> 
<indexterm><primary>SETETT Subroutine</primary></indexterm>
<indexterm><primary>SYSTEM Subroutine</primary></indexterm>
<indexterm><primary>TAPERD Subroutine</primary></indexterm>
<indexterm><primary>TAPEWR Subroutine</primary></indexterm>
<indexterm><primary>Subroutines</primary></indexterm>
<!-- beginpage II.49 -->

<para>If a block designation
A(i<subscript>1</subscript>,...,i<subscript>n</subscript>)...A(j<subscript>i</subscript>,...,j<subscript>n</subscript>)
is used in an input-output list &scriptL; for reading or writing
<emphasis> binary tape </emphasis> or <emphasis> drum </emphasis>, the
linear subscript corresponding to
i<subscript>i</subscript>,...i<subscript>n</subscript> may not
be greater than the linear subscript corresponding to
J<subscript>1</subscript>,...,j<subscript>n</subscript>.
While the list for a binary tape or drum statement is transmitted in
the sequence written, a block
A(i<subscript>1</subscript>,...,i<subscript>n</subscript>)...A(j<subscript>1</subscript>,...,j<subscript>n</subscript>)
within the list is actually transmitted in reverse order, i.e., in the
sequence
A(j<subscript>1</subscript>,...,j<subscript>n</subscript>) to
A(i<subscript>1</subscript>,...,i<subscript>n</subscript>).</para>

</sect1>
</chapter>
<!-- beginpage III.1 -->
<chapter><title>EXAMPLES</title>

<indexterm><primary>Scientific Examples</primary></indexterm> 

<para>Note:The following illustrates how some programs may be writtten
in the MAD language.  Since they were written to illustrate as many
features of the language as possible, they are not necessarily the
most efficient or elegant programs which could have been written.
They have all been tested on the computer, however, and are
correct.</para>

<para>The flow chart notation used here varies somewhat from the
illustrations of Chapter 1.<indexterm><primary>Flow
Diagram</primary></indexterm> The variation is consistent with present
computing practice where many individualistic forms are encountered
and, moreover, causes no difficulty due to the essentially graphic
nature of charts.  In particular, iterations are present by the
form:</para> <!-- yes, that's "present", not "represented" -->

<mediaobject>
  <imageobject>
    <imagedata fileref='fig06.png'/>
  </imageobject>
</mediaobject>

<indexterm><primary>Iteration Statement</primary></indexterm> 

<indexterm><primary>Scope</primary></indexterm> 

<para>Here the scope of the iteration lies between the hexagonal box
and diamond box A, and the calculation proceeds from A when the stated
relation is true.</para>

<sect1><title>Scientific Examples</title>

<indexterm><primary>Examples, Scientific</primary></indexterm>

<sect2><title>Example 1<emphasis role='note'>: Compute roots of linear
and quadratic equations</emphasis></title>

<para><emphasis>Problem:</emphasis> To solve the quadratic equation
ax<superscript>2</superscript> + bx + c = 0 for various sets of
coefficients a, b, and c.</para>

<para><emphasis>Analysis:</emphasis> Let x<subscript>1</subscript> and
x<subscript>2</subscript> be the two roots of the equation.  Then
their values are found by the formulas,</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation4.png'/>
  </imageobject>
</mediaobject>

<para>whenever a &ne; 0.  The single root x<subscript>1</subscript> of
the equation when a = 0 is x<subscript>1</subscript> = -c/b. The input
values of a, b, and C are printed immediately after they are brought
in to help in finding trouble spots during the development of the
program (not as necessary here as in longer problems, but a good
idea!).</para>
<!-- beginpage III.2 -->

<para><emphasis>Flow Diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig07.png'/>
  </imageobject>
</mediaobject>
<!-- beginpage III.3 -->

<para><emphasis>The Program:</emphasis></para>

<programlisting>
&quadratic;
<!-- beginpage III.4 -->
*DATA
          4.          -8.          4.
          0            5.         10.
          1.           1.          1.
</programlisting>

</sect2>
<sect2><title>Example 2<emphasis role='note'>: Printing the truth table of a Boolean expression</emphasis></title>

<indexterm><primary>Truth Table</primary></indexterm>

<para><emphasis>Problem:</emphasis> A logical (Boolean) expression
such as (P .AND. Q) .OR.(.NOT. P .AND. R .AND. S).OR.(R .OR. P) will
have a value TRUE or FALSE (represnted here by 1B and 0B,
respective&shy;ly) depending on the "input values" of the variables
involved: P,Q,R,S.  Thus, if P = 1B, Q = R = S = 0B, then the total
expression T will have the value 1B.  The entire table of outputs for
all possible inputs would be as follows:</para>

<!-- 
original table had:
(a) vertical rules between all columns, with the one between S and T doubled
(b) a horizontal rule separating header from body
(c) a horizontal rule separating the first 8 rows from the last 8 
-->
<informaltable colsep='0' rowsep='0' frame='all'>
<tgroup cols='5'>
<thead>
<row>
<entry>P</entry><entry>Q</entry><entry>R</entry><entry>S</entry><entry>T</entry>
</row>
</thead>
<tbody>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;0B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
<row>
<entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry><entry>&nbsp;&nbsp;&nbsp;&nbsp;1B&nbsp;&nbsp;&nbsp;&nbsp;</entry>
</row>
</tbody>
</tgroup>
</informaltable>

<para>The problem is to write a program to generate the entire "truth
table" for the given expression T.</para>
<!-- beginpage III.5 -->

<para><emphasis>Flow Diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig08.png'/>
  </imageobject>
</mediaobject>
<!-- beginpage III.6 -->

<para><emphasis>The Program:</emphasis></para>

<programlisting>
&truthtable;
</programlisting>

<para>Note: Although it would have meant only a slight change in the
format information, no attempt was made here to label the "0" and "1"
that print as values in the table as Boolean, i.e., "0B" and "1B".
This points up the fact that <emphasis>internally</emphasis> 0B and 1B
are stored as 0 and 1, respectively.  Also, the statement</para>

<indexterm><primary>NORMAL MODE IS Statement</primary></indexterm>

<para role='centered'>
NORMAL MODE IS BOOLEAN
</para>

<para>could have been used as tthe second statement of this program
instead of the BOOLEAN declaration.<indexterm><primary>Boolean</primary></indexterm></para>

</sect2>
<!-- beginpage III.7 -->
<sect2><title>Example 3<emphasis role='note'>: Simpson's Rule approximation of a definite integral</emphasis></title>

<indexterm><primary>Simpson's Rule</primary></indexterm> 

<para><emphasis>Problem:</emphasis> To approximate 
<subscript>a</subscript>&int;<superscript>b</superscript> f(x) by Simpson's
Rule, for an arbitrary interval [a, b] using N equal subintervals
(where N is an arbitrary even integer).</para>

<para><emphasis>Analysis:</emphasis>By Simpson's Rule</para>

<!--
This is not a displayed equation in the original, but sort of inlined.
Also the a attached to the integral sign is before it, not after,
but eqn doesn't seem to be able to do that.
-->
<mediaobject>
  <imageobject>
    <imagedata fileref='equation5.png'/>
  </imageobject>
</mediaobject>

<para>where y<subscript>i</subscript> =
f(x<subscript>i</subscript>), and a = x<subscript>0</subscript>,
x<subscript>1</subscript>, ... x<subscript>N</subscript> = b are the
partition points of the interval [a,b].</para>

<para><emphasis>Method:</emphasis> We shall write the program in the
form of an external function, so that it could be used with any other
program.  The evaluation of f(x) could be accomplished by another
external function or an internal function.</para>

<para><emphasis>Flow Diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig09.png'/>
  </imageobject>
</mediaobject>
<!-- beginpage III.8 -->

<para><emphasis>The Program:</emphasis></para>

<programlisting>
&simpsfunc;
</programlisting>

<para>If, for some reason, the integral of sin 3x - cos(rx + 1) were
needed if 0 &le; x &le; 3, and the integral of sin 3x - cos(rx)
otherwise, the program might then be as follows:</para>
<!-- beginpage III.9 -->

<para><emphasis>The Program:</emphasis></para>

<!-- beginpage III.10 after H = (B-A)/N -->
<programlisting>
&simpsmain;
</programlisting>

<para><emphasis>External Functions:</emphasis></para>

<programlisting>
&simpsfunc;
*DATA
         0          2.         10          10.
</programlisting>

<para>An alternate way to write the first eight lines of this
program, illustrating one use of the FUNCTION NAME mode, would
be:</para>

<programlisting>
READ	READ FORMAT INPUTS,A,B,N,R
	INTEGER N
	WHENEVER 0. .LE. R .AND. R .LE. 3
	S = F1.
	OTHERWISE
	S = F2.
	END OF CONDITIONAL
	PRINT FORMAT RESULT,A,B,N,R,SIMPS.(A,B,N,S)
	TRANSFER TO READ
	FUNCTION NAME S
</programlisting>
</sect2>
<!-- beginpage III.11 -->
<sect2><title>Example 4<emphasis role='note'>: Find roots of a function by half-interval approximation</emphasis></title>

<para><emphasis>Problem:</emphasis> To find a real solution (if it
exists) of the equation f(x) = 0 (where f is a continuous function)
obn an arbitrary interval [a, b], provided the roots (if there are
more than one) are at least &epsi; apart.</para>

<para><emphasis>Analysis:</emphasis> We specify a, b, and &epsi; as
parameters.  The method used will be "half-interval convergence," in
which the function is evaluated at x -a, and then the interval is
scanned for a change of sign<footnote><para>A change of sign is
detected when the numbers involved have a negative
product.</para></footnote> in the value of f(x). If no change of sign
is found, the scanning is repeated with a step size for searching half
of the previous size. If the step size becomes smaller than &epsi;,
and no change of sign is found, the process is terminated, and comment
is printed: "NO SOLUTION".</para> 

<!-- the original formula used a horizontal division bar and no parens -->
<para>If a change of sign is found between x<subscript>L</subscript>
and x<subscript>R</subscript>, the value of f is computeed at
x<subscript>M</subscript> = (x<subscript>L</subscript> +
x<subscript>R</subscript>)/2, i.e. the midpoint of the interval of
uncertainty [x<subscript>L</subscript>, x<subscript>R</subscript>]. We
then determine which one of the intervals [x<subscript>L</subscript>,
x<subscript>M</subscript>]. [x<subscript>M</subscript>,
x<subscript>R</subscript>] now contains a change in sign.  We then
compute the value of f at the midpoint of that smaller interval, etc.,
until the interval being considered finally has length less that
&epsi;, at which time either end may be taken as the solution with an
error less than &epsi;.</para>

<para>The method used here to handle the x<subscript>M</subscript>
cpomputation is perhaps not the most obvious one. It consists of 
a simple loop in which the value of x is adjusted by h&prime; = -h/2, then
h&prime;&prime; - h&prime;/2 = h/4, etc., until h is small enough. The
adjustment of x is either to the left or to the right, depending on
the occurrence or non-occurrence, respectively, of a change of sign
between f(a) and f(x).</para>

<para>It should be understood that this method may not find a root
which is one of a pair of roots which either coincide or are less that
&epsi; apart.</para>

<!-- beginpage III.12 -->
<para><emphasis>Flow diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig10.png'/>
  </imageobject>
</mediaobject>
<!-- beginpage III.13 -->

<para><emphasis>Program:</emphasis> It is assumed here that f
(referred to as F. in the program) will be defined as an internal
function.)</para>

<para><emphasis>Definition:</emphasis> SIGN.(Z) = Z/|Z|</para>

<note><para>A sample F. is actually specified in the listing.
Specifying F this way makes more sense if one recalls that MAD
programs were punched-card decks.  An internal function definition was
typically a single card that could be slipped anywhere into the 
program deck.</para></note>

<!-- beginpage III.14 after the VECTOR VALUES ABEPS line -->
<programlisting>
&findroot;
*DATA
          1.          2.          .01
</programlisting>
</sect2>
<!-- beginpage III.15 -->
<sect2><title>Example 5<emphasis role='note'>: Compute the transpose of a matrix</emphasis></title>

<indexterm><primary>Matrix Transpose Example</primary></indexterm> 

<para><emphasis>Problem:</emphasis> Find the transpose A' of an n&times;n
matrix A = (a<subscript>ij</subscript>).</para>

<para><emphasis>Analysis:</emphasis> If we write A' =
(b<subscript>ij</subscript>) then b<subscript>ij</subscript> =
a<subscript>ji</subscript>.  We shall inter&shy;change
symmetrically-placed pairs of elements, leaving untouched elements on
the main diagonal. The program will be in the form of an external
function.<indexterm><primary>Function Definition</primary></indexterm></para>

<para><emphasis>Flow diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig11.png'/>
  </imageobject>
</mediaobject>

<para><emphasis>Program:</emphasis></para>

<programlisting>
&transfunc;
</programlisting>

<para>Note: No dimension information is needed for A, since it is an
argument in a function <emphasis>definition</emphasis> program.  The
function would be <emphasis>called</emphasis> with a statement of the
form EXECUTE TRANS.(A, N).</para>

<note><para>The Retrocomputing Museum implementation cannot yet
compile this example.  The problem is the array I/O.</para></note>

</sect2>
<!-- beginpage III.16 -->
<sect2><title>Example 6<emphasis role='note'>: Matrix multiplication</emphasis></title>

<para><emphasis>Problem:</emphasis> Multiply the matrix A =
(a<subscript>ij</subscript>) by the matrix B =
(b<subscript>ij</subscript>) to produce the matrix X =
(c<subscript>ij</subscript>), i.e. C = A &middot; B.  Assume tha A has
dimensions m &times; n with m &middot; n &le; 1500, B has dimensions n
&times; p with n &middot; p &le; 1500, and C has dimensions m &times;
p with m &middot; p &le; 1500.</para>

<para><emphasis>Analysis:</emphasis>  An element c<subscript>ij</subscript>
of C is computed by the formula</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation6.png'/>
  </imageobject>
</mediaobject>

<para><emphasis>Flow diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig12.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage III.17 -->

<note><para>The Retrocomputing Museum implementation cannot yet
compile this example.  The problem is the EQUIVALENCE declaration;
there is no general way to implement this in generated C.</para></note>

<!-- this heading is omitted in the original -->
<para><emphasis>The Program:</emphasis></para>

<programlisting>
&matrixmult;
<!-- beginpage III.18 -->
* DATA
   2   3   3
          1.           2.           3.           4.          5.          6.
          7.           8.           9.          10.         11.         12.
         13.          14.          15.
</programlisting>

<note><para>The Retrocomputing Museum implementation cannot yet
compile this example.  The problem is the array I/O.</para></note>
</sect2>
<!-- beginpage III.19 -->
<sect2><title>Example 7<emphasis role='note'>: Solve simultaneous linear equations</emphasis></title>

<indexterm><primary>Jordan Elimination Method Example</primary></indexterm> 

<para><emphasis>Problem</emphasis> Solve a system of n &le; 20 simultaneous
linear equations in n unknowns, assuming that one does not encounter a
zero on the main diagonal of the coefficient matrix during the
solution process.</para>

<!-- The original had a typo, "Elimation" for "Elimination" -->
<para><emphasis>Analysis</emphasis>: We shall use a Jordan Elimination
Method, in which each diagonal coefficient is used to "clear" all
other coefficients in its column to zero by appropriate
multiplications and subtractions. Since we shall divide the "clearing
row" by the diagonal element in that row before clearing t;he column,
we shall finish the process with only a diagonal of ones and the
solution to the problem as the resulting right hand side of the
equations.</para>

<para>We denote the system of equations to be solved by:</para>

<programlisting>
         a<subscript>11</subscript>x<subscript>1</subscript> + a<subscript>12</subscript>x<subscript>2</subscript>  + ... + a<subscript>1n</subscript>x<subscript>n</subscript> = a<subscript>1</subscript>,n+1

(1)      a<subscript>21</subscript>x<subscript>11</subscript> + a<subscript>22</subscript>x<subscript>2</subscript> + ... + a<subscript>2n</subscript>x<subscript>n</subscript> = a<subscript>2</subscript>,n+1

           .       .             .        .
           .       .             .        .
           .       .             .        .
	a<subscript>n1</subscript>x<subscript>1</subscript>  + a<subscript>n2</subscript>x<subscript>2</subscript> + ...  + a<subscript>nn</subscript>x<subscript>n</subscript> = a<subscript>n</subscript>,n+1
</programlisting>

<para>We divide the first row by its diagonal element
a<subscript>11</subscript>.  Then to clear a<subscript>21</subscript>
ato zero we substract a<subscript>21</subscript> times the first row
from the second row, and so on.  In general, to clear
a<subscript>ik</subscript> to zero (after row K has been divided by
a<subscript>kk</subscript>), we subtract a<subscript>ik</subscript>
times row k from row i (i&ne;k).  A typical element
a<subscript>ij</subscript> is thus transformed each time by the
formulas:</para>

<programlisting>
(2)      a<subscript>kj</subscript> = a<subscript>kj</subscript>/a<subscript>kk</subscript>

(3)      a<subscript>ij</subscript> = a<subscript>ij</subscript>-a<subscript>ik</subscript>a<subscript>kj</subscript>  (i&ne;k)
</programlisting>

<para>where the value of a<subscript>kj</subscript> in (3) is the result of
(2).  These transformations are performed for k = 1, 2, ..., n.  For
each (fixed) k, we will let i = 1, 2, ...., k-1, k+1, ..., n, so as to
operate on all rows except i=k.  While transforming each row we will
cycle on j from right to left; i.e., j = n+1, n, n-1, ... k, and we
stop at j = k since for j &lt; k there is no change in the matrix.</para>
<!-- beginpage III.20 -->

<para>The array</para>

<programlisting>
			a<subscript>11a</subscript><subscript>12</subscript> ... a<subscript>1</subscript>,n+1
			     .          .
			     .          .
	A = (a<subscript>ij</subscript>)    =       .          .
			     .          .
			a<subscript>n1a</subscript><subscript>n2</subscript> ... a<subscript>n</subscript>,n+1
</programlisting>

<para>is called the "matrix of coefficients" of the system (1).</para>

<para>It should be understood that this method, involving the assumption of
no zeros on the diagonal and not searching for the largest element of
a row to use as a divisor (to minimize round-off error), is not
satisfactory from a mathematical point of view.  It could serve as a
basis for a larger, more complete program, however, and serves here
only as an example problem.</para>

<!-- beginpage III.21 -->
<para><emphasis>Flow diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig13.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage III.22 -->

<para><emphasis>The Program:</emphasis></para>

<indexterm><primary>SAVE DATA</primary></indexterm> 
<indexterm><primary>SAVE RETURN</primary></indexterm> 

<programlisting>
&jordan;
<!-- beginpage III.23 hust before VECTOR VALUES RESULT -->
* DATA
   3
          1.           1.           1.           6.         -1.           0
          0.          -1.          -1.          -2.         -9.        -32.
</programlisting>

<note><para>The Retrocomputing Museum implementation cannot yet
compile this example.  The problem is the array I/O.</para></note>

</sect2>
</sect1>
<!-- beginpage III.24 -->
<sect1><title>Business Data Processing Examples</title>

<indexterm><primary>Business Data Processing Examples</primary></indexterm>
<indexterm><primary>Examples, Business Data Processing</primary></indexterm>
<indexterm><primary>Social Security Example</primary></indexterm>

<sect2><title>Example 1<emphasis role='note'>: Payroll Processing</emphasis></title>

<para><emphasis>Problem:</emphasis> Compute the social security deduction
and accumulated gross pay.  The program should read a card containing:
(a) the employee's name, (b) his payroll number, (c) his gross pay for
the current week, and (d) his accumulated gross pay for the current
year (but not including item (c)).  For each card read, the program
should print (a) and (b) from the card, and, in addition, print (e)
the updated gross pay, (f) the social security deduction for the
current week, and (g) the net pay for the current week, taking into
account only the social security deduction.</para>

<para><emphasis>Analysis:</emphasis> The social security deduction is
currently 3% of the gross pay until the accumulated gross pay for the
year exceeds from $4800.00.  The updated gross pay can be computed
from the formula, (e) = (c) + (d).  The social security deduction has
already been made on (d).  There are thus three cases to consider:</para>

<orderedlist>
<listitem><para>(d) &ge; 4800.00, in this case (f) = 0.</para></listitem>
<listitem><para>(d) &lt; 4800.00  and (c) + (d) &gt; 4800.00, 
in this case (f) = 3% of 4800.00 - (d)</para></listitem>
<listitem><para>(c) + (d) &gt; 4800.00, 
in this case f = 3% of (c).</para></listitem>
</orderedlist>

<para>The information on the cards to be read will be in the following
format:</para>

<informaltable>
<tgroup cols='2'>
<thead>
<row><entry><emphasis>Card Columns</emphasis></entry><entry><emphasis>Information</emphasis></entry></row>
</thead>
<tbody>
<row><entry>1-30</entry><entry>(a) employee's name</entry></row>
<row><entry>31-38</entry><entry>(b) payroll number</entry></row>
<row><entry>39-44</entry><entry>(c) gross pay for the current week in the form XXX.XX</entry></row>
<row><entry>45-52</entry><entry>(d) accumulated gross pay for the current year in the form XXXXX.XX</entry></row>
</tbody>
</tgroup>
</informaltable>

<para>The printed output will be in the following format:</para>
<!-- beginpage III.25 -->

<informaltable>
<tgroup cols='2'>
<thead>
<row><entry><emphasis>Line Columns</emphasis></entry><entry><emphasis>Information</emphasis></entry></row>
</thead>
<tbody>
<row><entry><emphasis>Line Columns</emphasis></entry><entry><emphasis>Information</emphasis></entry></row>
<row><entry>1</entry><entry>Carriage control for printer</entry></row>
<row><entry>2-31</entry><entry>(a) employee's name</entry></row>
<row><entry>32-34</entry><entry>Blank</entry></row>
<row><entry>35-42</entry><entry>(b) payroll number</entry></row>
<row><entry>43-45</entry><entry>Blank</entry></row>
<row><entry>46-53</entry><entry>(e) updated gross pay for current year in the form XXXXX.XX</entry></row>
<row><entry>54-56</entry><entry>Blank</entry></row>
<row><entry>57-61</entry><entry>(f) social security deduction for current week in the form XX.XX</entry></row>
<row><entry>62-64</entry><entry>Blank</entry></row>
<row><entry>65-70</entry><entry>(g) net pay for current week in the form XXX.XX</entry></row>
</tbody>
</tgroup>
</informaltable>

<para><emphasis>Flow chart:</emphasis> We will use the following
abbreviations:</para>

<informaltable>
<tgroup cols='2'>
<tbody>
<row><entry>NAME</entry><entry>for employee's name (a).</entry></row>
<row><entry>PAYNR</entry><entry>for payroll number  (b).</entry></row>
<row><entry>GROSSW</entry><entry>gross pay for current week (c).</entry></row>
<row><entry>AGROSY</entry><entry>accumulated gross pay for current year (d).</entry></row>
<row><entry>UGROSY</entry><entry>updated gross pay for current year (e)</entry></row>
<row><entry>FICA</entry><entry>social security deduction for current week (f).</entry></row>
<row><entry>NET PAY</entry><entry>net pay for current week (g).</entry></row>
</tbody>
</tgroup>
</informaltable>

<!-- Bogus presentation-level hack to keep the table and diagram apart -->
<para>&nbsp;</para>

<!-- beginpage III.26 -->
<mediaobject>
  <imageobject>
    <imagedata fileref='fig14.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage III.27 -->

<para><emphasis>The Program:</emphasis></para>

<programlisting>
&payroll;
* DATA
GEORGE WASHINGTON                        12345678 100.    4800.
JOHN ADAMS                               12345679 200.    4900.
THOMAS JEFFERSON                         12345680 200.    4600.
JAMES MADISON                            12345681 200.    4700.
JOHN QUINCY ADAMS                        12345682 100.     300.
</programlisting>

<!-- beginpage III.28 -->
<para><emphasis>Alternate Program:</emphasis></para>

<programlisting>
&altpayroll;
* DATA
GEORGE WASHINGTON                        12345678 100.    4800.
JOHN ADAMS                               12345679 200.    4900.
THOMAS JEFFERSON                         12345680 200.    4600.
JAMES MADISON                            12345681 200.    4700.
JOHN QUINCY ADAMS                        12345682 100.     300.
</programlisting>

<!-- beginpage III.29 -->

<!-- This was an unnumbered section in the original -->
<sect3><title>Notes on these programs:</title>

<para>1. The maximum number of characters which can be stored in one machine
word is six.  Hence, we need five machine words to store the 30
characters allowed for the employee's name.  We need to give a
dimension declaration stating that NAME is actually be a block and
that NAME(5) is the last word of this block.  In the read and print
statements we specify that the whole block is to be read or printed by
writing NAME(1) ... NAME(5) and giving the format specification 506,
i.e., 5 words of 6 characters.</para>

<para>2. Since the payroll number is an integer (i8, i.e., and 8 digit
integer) we give an integer mode declaration stating that PAYNR is an
integer.  Similarly, since alphabetic information is assumed to be in
the integer mode, NAME is also declared to be integer.</para>
</sect3>
</sect2>

<!-- beginpage III.30 -->
<sect2><title>Example 2<emphasis role='note'>: Payroll Tape Processing</emphasis></title>

<indexterm><primary>Payroll Example</primary></indexterm>

<para>Problem: Assume that a master tape is available containing basic
information for each employee: (1) The employee number, (2) his hourly
rate, (3) gross pay to date, (4) amount of withholding tax withheld to
date, (5) social security deduction withheld to date, (6) net pay to
date, and (7) the number of exemptions.  Input will be in the form of
m cards representing the current pay record, containing the employee's
number and the number of hours worked during the current week.  Pay is
to be copmuted at time and a half for any hours worked over forty.
(We shall assume that the input deck is already sorted according to
increasing employee number, but we shall provide for cards which may
be out of order.  The last input card must have an employee number
greater than the last employee number of the master tape.</para>

<para>The withholding tax W is to be computed by the formula:</para>

<para role='centered'>W = .18(Gross pay = 13 n)</para>

<para>where n is the number of exemptions.  If n is negative, we set W
= 0 (see Note 2 below).  The social security deduction FICA is 3 per
cent of gross pay up to $4800, with no deduction for gross pay over
$4800.</para>

<para>A program is desired which will produce a listing (for each input
card) of (a) employee number, (b) gross pay this week, (c) withholding
tax, (d) FICA, (e) net pay for the week.  Moreover, a new updated
master tape shojuld be prepared, with provision for saving the
previous master tape as well.  As much checking as possible should be
incorporate, including specifying to the operator the number of the
master tape needed, and the number to be assigned to the new tape
produced by the program, and the automatic checking that the correct
tape has been mounted on the unit.</para>

<para>Note 1: Abbreviations used here are outlined in Example 1,
except for the following new terms:</para>
<!-- beginpage III.31 -->

<informaltable>
<tgroup cols='2'>
<tbody>
<row><entry>AWITHY</entry><entry>accumulated withholding tax for year</entry></row>
<row><entry>AFICAY</entry><entry>accumulated social security deduction for year</entry></row>
<row><entry>ANETY</entry><entry>accumulated net pay for year.</entry></row>
<row><entry>EXEMPT</entry><entry>no. of exemptions</entry></row>
</tbody>
</tgroup>
</informaltable>

<para>Note 2: In the computations of the gross pay for the current week we
shall find it useful to be able to compute a function (which we shall
call EXCESS.) of two numbers, say a and b, whose value is 0 if a &le; b,
and a-b if a &gt; b.  A formula for this function is</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation7.png'/>
  </imageobject>
</mediaobject>

<para>where | | denotethe usual "absolute value".  In fact, by using
this function, a simple one-line formula for this function is:</para>

<para role='centered'>FICA = .03 EXCESS.((GROSSW - EXCESS.(AGROSY, 4800.)),0)</para>

<para>where AGROSY is assumed to already contain GROSSW, i.e., to have
been updated already.  We shall also apply this function in the case
of the withholding tax to guarantee that we do not make a negative
deduction. Thus </para>

<para role='centered'>W = .18*EXCESS. (GROSSW, 13*EXEMPT)</para>
 
<para>Note 3: To check the order of input cards (normally in order of
increasing employee number with a large employee number greater than
the last employee number on the master tape) the program uses the
subroutine SETEOF.(LABEL), where LABEL is the statement label of a
statement to be executed if an end of file condition is detected
during reading.</para>
 
<para>Since the last input card has a large employee number the first
end of file condition is normally detected at the end of processing,
but an illegal input card may also exist with a high employee number.
After the first end of file is detected the end of file return is
changed and the input tape checked for end of file.  If no end of file
exists a 
<!-- beginpage III.32 -->
comment is printed to change tapes and processing begins
again.</para>
 
<!-- beginpage III.33 -->
<para role='note'><emphasis>Flow diagram:</emphasis></para>

<!-- this figure spanned pages III.33 and III.34 in the original -->
<mediaobject>
  <imageobject>
    <imagedata fileref='fig15.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage III.35 -->
<para role='note'><emphasis>The Program:</emphasis></para>

<indexterm><primary>NORMAL MODE IS Statement</primary></indexterm>

<!-- this listing spans pages III.35, III.36, and III.36A -->
<programlisting>
&payrolltape;
</programlisting>

<note><para>The Retrocomputing Museum implementation cannot yet
compile this example.  The problem is the TAPE statement.</para></note>

</sect2>
<!-- beginpage III.37 -->
<sect2><title>Example 3<emphasis role='note'>: Mortgage Payment Processing</emphasis></title>

<indexterm><primary>Mortgage Example</primary></indexterm>

<!-- "principle" usage error is in original -->
<para>Problem: Mortgage Payment.  The type of mortgage we consider is
the fixed principle type for which each installment consists of an
interest payment, a fixed amount to be deducted from the outstanding
principal, and an additional amount to be placed in escrow&dd;to be used
to make insurance and tax payments.</para>
 
<!-- The original says "interest rage" and "nortage number" --> 
<para>Assume that a master card file is available containing the
following information for each mortgage: (1) the mortgage number; (2)
amount of outstanding principal; (3) annual payment on principal; (4)
interest rate; (5) annual escrow payment; and (6) current escrow
balance.  There is also a file of cards available containing the
current payment record consisting of mortgage number and amount of
payment received.  The master file and current payment file are
assumed to be in order of increasing mortgage number.</para>
 
<!-- Original says "a and a interest payment" -->
<para>The program is to read a card from the current payment record
and check to see if it is acceptable.  A payment is deemed acceptable
if it consists of a single normal payment (i.e., a payment consisting
of a single principal payment, a single escrow payment,  and
an interest payment for a single period) or if it consists of exactly
two normal payments and any number (i=0, 1, 2, ...) of principal
payments.</para>
 
<para>Note 1: Since the Michigan Algorithm Decoder uses the dollar
sign as the delimiter for characters it is not possible to print out
the dollar sign in a hollerith field.  Using the - $=$ sets up the
proper bit configuration for the dollar sign in storage since single
characters appear in the left most position of the word.  This
character constant can be named and put on the list of items to be
printed out.</para>
 
<para>Note 2: The current payments are processed until the file is
exhausted.  The detection of the end of file on reading tranfers
control to the section of the program which punches the new master
file.</para>
 
<!-- beginpage III.38 -->
<para><emphasis>Flow diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig16.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage III.39 -->

<mediaobject>
  <imageobject>
    <imagedata fileref='fig17.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage III.40 -->
<para role='note'><emphasis>The Program:</emphasis></para>

<programlisting>
&mortgage;
</programlisting>

</sect2>
<!-- beginpage III.42 -->
<sect2><title>Example 4<emphasis role='note'>: Actuarial computation</emphasis></title>
<indexterm><primary>Actuarial Example</primary></indexterm>

<para><emphasis>Problem</emphasis>: Computation of actuarial commutation
columns based on an arbitrary set of mortality rates and an interest
rate, as an external function to be used by another program.</para>

<!-- first script-l in this 'graph was a plain lowercase l in the original --> 
<para><emphasis>Analysis</emphasis>: Commutation columns, which are
very important tools in actuarial problems are generated very easily
by means of the formulas given below.  The quantities
M<subscript>x</subscript>, N<subscript>x</subscript>, and
D<subscript>x</subscript> in these formulas occur most often in
combination, as in the computation of P<subscript>x</subscript>.
Assuming a population of some initial size (at x =
b<subscript>0</subscript>) (here 1,000,000),
&scriptl;<subscript>x</subscript> is the number living a t age x (so
that &scriptl;<subscript>bo</subscript> = 1,000,000),
q<subscript>x</subscript> is the mortality <emphasis>rate</emphasis>,
and d<subscript>x</subscript> is the number of deaths at age x. Thus
d<subscript> x</subscript> =
q<subscript>x</subscript>&middot;&scriptl;<subscript>x</subscript>.
The quantity D<subscript>x</subscript> is computed by the formula
D<subscript>x</subscript> =
&scriptl;<subscript>x</subscript>(1+i)<superscript>-x</superscript>.
It can be used, for example, to compute the cost of term insurance,
since C<subscript>x</subscript>/D<subscript>x</subscript> is the
premium for one-year term insurance of $1 at age x.</para>

<para> The sums M<subscript>x</subscript> and
N<subscript>x</subscript> are obtained by the formula</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation8.png'/>
  </imageobject>
</mediaobject>

<para>We note that for some w. we always have
q<subscript>x</subscript> = l, so that l<subscript>w+1</subscript> = 0
(since &scriptl;<subscript>w+1</subscript> =
&scriptl;<subscript>w</subscript>-d<subscript>w</subscript> =
&scriptl;<subscript>w</subscript>-&scriptl;<subscript>w</subscript> =
0), therefore D<subscript>w+1</subscript> =0,
d<subscript>w+1</subscript> = 0,
C<subscript>w+1</subscript> = 0, and the sums for
M<subscript>x</subscript> and
N<subscript>x</subscript> are actually finite sums.</para>

<para>The three most useful quantities computed here are
(1)P<subscript>x</subscript> =
M<subscript>x</subscript>/N<subscript>x</subscript>, which is the
annual premium payable for an entire life for $1 of whole life
insurance, (2)A<subscript>x</subscript> =
M<subscript>x</subscript>/D<subscript>x</subscript>, which is the
single premium payable at age x for $1 of whole life insurance, and 
(2)a<subscript>x</subscript> =
N<subscript>x</subscript>/D<subscript>x</subscript>, which is the
present value at age x of a whole life annuity of $1, first payment
at age x.</para>

<para>Printing of results is under the control of an input variable
PRINT.  Certain relationships must hold between some independently
computed values, and these are used as checks on the compuatation:</para>

<para role='centered'>
M<subscript>b<subscript>0</subscript></subscript> +
N<subscript>b<subscript>0</subscript>+1</subscript> =
N<subscript>b<subscript>0</subscript>+1</subscript> =
N<subscript>b<subscript>0</subscript></subscript>/(1+i)</para>
<!-- beginpage III.43 -->

<para role='centered'>P<subscript>x</subscript> =
1/a<subscript>x</subscript> - i/(1+i)</para>

<para>These cannot be expected to come out exactly equal, because of
round-off, but they should differ by very little.</para>

<!-- beginpage III.44 -->
<para><emphasis>Flow diagram:</emphasis></para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig18.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage III.45 -->

<para><emphasis>The Program:</emphasis></para>

<programlisting>
&commutemain;
</programlisting>

<para><emphasis>The External Functions:</emphasis></para>

<programlisting>
&commutefunc;
</programlisting>

<!-- beginpage III.46 after "M(OMEGA) = C(OMEGA)" in listing --> 
<!-- beginpage III.47 after line labeled GAMMA in listing --> 

<note><para>The Retrocomputing Museum implementation cannot yet
compile this example.  The problem is the array I/O.</para></note>

</sect2>
</sect1>
<!-- beginpage III.48 -->
<sect1><title>Symbol Manipulation and Recursive Function Examples</title>
<sect2><title><emphasis role='note'>Example 1: Find a word in a string</emphasis></title>

<indexterm><primary>Exammples, Recursive Functions</primary></indexterm>
<indexterm><primary>Examples, Symbol Manipulation</primary></indexterm>
<indexterm><primary>Recursive Functions</primary></indexterm>
<indexterm><primary>Subroutines</primary></indexterm>
<indexterm><primary>Symbol Manipulation Examples</primary></indexterm>

<para><emphasis>Problem:</emphasis> Find the first occurrence of an
arbitrary word in a given text.</para>

<para><emphasis>Analysis:</emphasis> Let N be the number of characters in
the text and T(1)...T(N) be the text stored one character per
word. Let L be the number of letters in the word which is stored one
character per word in W(1)...W(L).</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig19.png'/>
  </imageobject>
</mediaobject>

<!-- beginpage III.49 -->

<!-- beginpage -->
<programlisting>
&wordsearch;
</programlisting>

</sect2>
<!-- beginpage III.50 -->
<sect2><title><emphasis role='note'>Example 2: Compute the factorial function</emphasis></title>
<para><emphasis>Problem:</emphasis> Evaluate the recursive function,</para>


<para role='centered'>f(0) = 1</para>
<para role='centered'>f(n) = f(n-1) * n</para>

<note><para>Due to a reproduction error in the 1962 original, the
Analysis paragraph below is somewhat mangled (the right-hand side
sliced off). Italicized text in the paragraph is from the 1966
edition.</para></note>

<para><emphasis>Analysis:</emphasis> This is the definition of n!
Alth<emphasis>ough n! can be evaluated</emphasis> directly
using a THROUGH statement, <emphasis>in this example it will 
</emphasis> be evaluated using its recursive def<emphasis>inition to
illustrate</emphasis> how recursive functions can be
handl<emphasis>ed.</emphasis></para>

<!-- These refer to statements in the example -->
<indexterm><primary>List Manipulation</primary></indexterm> 
<indexterm><primary>RESTORE DATA Statement</primary></indexterm>
<indexterm><primary>RESTORE RETURN</primary></indexterm> 
<indexterm><primary>SAVE DATA</primary></indexterm> 
<indexterm><primary>SAVE RETURN</primary></indexterm> 
<indexterm><primary>SETERR Subroutine</primary></indexterm> 
<indexterm><primary>SETETT Subroutine</primary></indexterm> 

<programlisting>
&factfunc;
</programlisting>
<!-- beginpage III.51 -->

<para>In order to use this function, the calling program would have to
specify a list for use in the SAVE and RESTORE stayements.  The
following is an example of a program which uses FACT.</para>

<!-- ysed in the lising below -->
<indexterm><primary>SET LIST TO Statement</primary></indexterm> 

<programlisting>
&factmain;
</programlisting>

</sect2>
<!-- beginpage III.52 -->
<sect2><title><emphasis role='note'>Example 3: Compute greatest common
divisor</emphasis></title>
<para><emphasis>Problem:</emphasis> To find the greatest common
divisor of two integers Y and Z.</para>

<para><emphasis>Analysis:</emphasis> The greatest common divisor is
defined recursively by three equations</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation9.png'/>
  </imageobject>
</mediaobject>

<para>Where REM.(A,B) is the remainder of A/B.  This function expects
the arguments to be found on the temporary storage list as the two
most recent additions.  The use of the list as a parameter list makes
the establishment of dummy variables unnecessary. This is less
efficient than the usuall way of defining functions, but serves to
remove many pitfalls encountered in using dummy variables with
recursive functions.</para>

<!-- beginpage III.53 -->
<programlisting>
&gcdfunc;
</programlisting>
<!-- beginpage III.54 -->

<indexterm><primary>Value of a Function</primary></indexterm> 

<!-- used in the listing above -->
<indexterm><primary>SET LIST TO Statement</primary></indexterm> 

<para><emphasis>Note:</emphasis> When called upon for a value, a
function such as GCD, must have at least one argument (in this example
a dummy argument of zero is used) even though the argument is never
called upon.  This is because GCD. is the <emphasis>name</emphasis> of
the function, wgile GCD.(...) is the <emphasis>value</emphasis> of the
function.</para>

<para><emphasis>Note:</emphasis> The SET LIST TO statement need be
executed only once, either in the main program or in a subprogram(but
before any use of SAVE or RESTORE), since the SAVE and RESTORE
statements always refer to the current list.</para>

<!-- beginpage III.55 -->

<para>An example of a program using GCD. is:</para>

<programlisting>
&gcdmain;
</programlisting>

</sect2>
<!-- beginpage III.56 -->
<sect2><title><emphasis role='note'>Example 4: Evaluate Tschebychev polynomials</emphasis></title>

<indexterm><primary>Tschebychev Polynomial Example</primary></indexterm>

<para><emphasis>Problem:</emphasis> To evaluate Tschebychev polynomials.</para>

<para><emphasis>Analysis:</emphasis> The Tschebychev polynomial T(N,X)
is defined recursively as follows:</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation10.png'/>
  </imageobject>
</mediaobject>

<para>It is important to understand that when an expression is written
as an argument of a function its value is computed and stored in a 
temporary location.  It is this location (or address) which is actually
used as the argument of the function.  The implication of this use of
a temporary location is that often expressions cannot be used as
arguments of recursive functions.</para>

<!-- beginpage III.57 -->
<programlisting>
&tschebfunc;
</programlisting>
<!-- beginpage; -->

<para>A program which uses TSCHEB. is:</para>

<programlisting>
&tschebmain;
</programlisting>

</sect2>
</sect1>
</chapter>
<!-- beginpage IV.1 -->
<chapter><title>Mechanics of Using MAD</title>

<sect1><title>Card Format</title>

<indexterm><primary>Card Format</primary></indexterm>

<para>MAD Statements are punched according to the following card format:</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='fig20.png'/>
  </imageobject>
</mediaobject>

<para>1.1 Statement labels may be punched anywhere in cols. 1-10.
Spaces are not relevant.</para>

<para>1.2 Column 11<indexterm><primary>Column 11 (Card
 Format)</primary></indexterm> is used to designate a remark (R) or,
 alternatively, a continuation of a statement (0, 1, 2, ..., 9).  The
 digits used to indicate continuation cards need not be in any
 particular order but there may be at most 10 cards in a
 statement.</para>

<para>1.3 The statement may start anywhere in cols. 12-72.  With the
exception of characters enclosed between "$" spaces are not relevant.
(Spaces may not be relevant even if they are so enclosed (see section
2.15) on format specifications).<indexterm><primary>$
Sign</primary></indexterm></para>

<para>1.4 The identification information in cols. 73-80 is not used by
the computer for any purpose but printing during translation and is
arbitrary.  Actually, it is good practice to use the first four of the
available eight columns for the first four digits of the project
number (i.e., for R10AN use R10A).  Presumably, the last four would
contain some sequence code.<indexterm><primary>Identification (Card
Format)</primary></indexterm>
</para>

</sect1>
<sect1><title>Diagnostics</title>

<indexterm><primary>Diagnostics</primary></indexterm>

<para>During the process of translation many kinds of errors in the
formation of statements and the allocation of storage can be
detected. To understand this error detection and the subsequent
printing of diagnostic 
<!-- beginpage IV.2 -->
comments some knowledge of the structure of the
translator is helpful.  The translation from statements to machine
code is accomplished in three major sections:</para>

<orderedlist>
<listitem><para>The decomposition of the original statements into
arrays of binary operations and pseudo-operations.</para></listitem>

<listitem><para>The analysis of all of the declarative information in
order to allocate variable storage and identify the arithmetic types
(i.e. modes) of variables.</para></listitem>

<listitem><para>The combination of the information produced from (1)
and (2) to translate the arrays to relocatable binary
programs.<indexterm><primary>Relocatable Binary
Programs</primary></indexterm></para></listitem>
</orderedlist>

<para>When an error is encountered in one of these sections the
translation does not proceed to the next section.  However, insofar as
possible, the entire set of statements is processed through the
section in which the error is detected and therefore more than one
error may be detected.  It should be understood, then, that not all
detectable errors may be found because:</para>

<orderedlist  numeration='loweralpha'>
<listitem><para>They are detectable only in a later stage of the
translation.</para></listitem>

<listitem><para>Some types of errors make it impossible to attempt
further detection within the section in which it
occurs.</para></listitem>

<listitem><para>One error may actually obscure another error.</para></listitem>
</orderedlist>

<para>Occasionally, an error in one statement may be such that it causes the translator to misinterpret a second statement, thus giving an error indication
even though no error exists in the later statement.</para>

<para>The printed diagnostic comment may very often have an alternative or
ambiguous form.  This results from the fact that it is frequently not
possible to determine what form was intended&dd;merely that the present
structure is not admissible&dd;and therefore some of the alternative
possibilities are suggested by the comment.</para>

</sect1>
<sect1><title>Structure of Subroutines</title>

<indexterm><primary>Subroutines</primary></indexterm>

<note><para>This section describes the mechanics of writing
MAD-accessible subroutines in IBM 709 assembler.  For tolerably
obvious reasons, the Retrocomputing Museum implementation does
not support this.</para></note>

<para>The information in this and the following sections of Chapter IV are
in much greater detail in other Computing Center write-ups.  However,
the following sections should be sufficient for the general use of
MAD.</para>
<!-- beginpage IV.3 -->

<!-- the original had a typo in this 'graph, "Probram" for "Program" -->
<para>Subroutines which are written for use by MAD programs&dd;whether
written in MAD as functions or in SAP<footnote><para>SAP is the SHARE
Assembly Program which permits the writing of actual machine
instructions in symbolic form.</para></footnote><indexterm>
<primary>SAP</primary></indexterm> &dd;must be relocatable
<indexterm><primary>Relocatable Binary Programs</primary></indexterm>
and must operate from the calling sequences the translator produces.
Consider, for example the function call - FN. (A,B,C) - which might
appear in the body of a statement. Assume that B is an array which has
an associated dimension vector BDIM.  Using SAP notation for
illustrative purposes, the calling sequence produced would be</para>

<programlisting>
		TSX	FN,4
		TXH	A
		TXH	B,0, BDIM
		TXH	C
</programlisting>

<para>Input-output routines utilize two types of parameters&dd;the
regional and single variable types.<indexterm><primary>Subroutine
Parameters</primary></indexterm> In addition an error return is given
as well as a format specification location.  The parameter operation
code used is TXI and the end of the parameter list is indicated by a
TXI operation with a blank address.  Thus the statement</para>

<programlisting>
	READ FORMAT FMT, BETA, X(1) ... X(100), K
</programlisting>

<para>would produce the calling sequence</para>

<programlisting>
		TSX	READ,4
		TXI	ERROR
		TXI	FMT
		TXI 	BETA
		TXI	X-1, 0, X-100
		TXI	K
		TXI
</programlisting>

<para>On occasion it is useful to use the regional notation in subroutines
which are not in the input-output category, for example, G. (GAMMA,
DELTA, Z(10)...Z(20)).  The calling sequence would be</para>

<programlisting>
		TSX	G, 4
		TXH	GAMMA
		TXH	DELTA
		TIX	Z-10, 0, Z-20
</programlisting>
<!-- beginpage IV.4 -->

<!-- not clear what this is referring to -->
<indexterm><primary>Hollerith (BCD)</primary></indexterm> 

<para>It is important to notice that in this example, as well as in the
first, the parameters&dd;if executed as instructions&dd;would produce no
operation.</para>

<para>It is beyond the scope of this manual to discuss the structure
of relocatable programs (see IBM FORTRAN II Manual).  It is sufficient
to say that a relocatable program must contain&dd;in adidtion to the
actual instructions in the program&dd;information as to which
addresses must be relocated at the time of loading for execution and
which addresses must not.<indexterm><primary>Relocatable Binary
Programs</primary></indexterm> In addition, the first card (or record)
of such programs must contain information about the size of the
program, the number of subroutines it calls on, the amount of stroage
it will share with other subroutines, the location of the list of
subroutines it calls on, and the names by which the routine itself is
referred to.  The symbolic names of the subroutines called on must
appear as the first words after this information.</para>

<para>The execution of MAD programs requires the use of a loading
routine to relocate and store the program and subroutines.  A slightly
modified BSS FORTRAN loader<indexterm><primary>BSS Fortran
Loader</primary></indexterm> is automatically produced by the
University of Michigan executive routine.  Also there are certain
subroutines which may be automatically called for by a MAD program
without an explicit reference to them in the source program.</para>

</sect1>
<sect1><title>Systems Subroutines</title>

<note><para>The Retrocomputing Museum implementation does
not support these routines or reserve these names.</para></note>

<para>The use of the following names for functions (subroutines)
should be avoided except where the operation is the one indicated
here.</para>

<variablelist>
<varlistentry>
<term>SYSTEM</term>
<listitem><para>Entry to this routine causes a return to the operating
system.  The END OF PROGRAM statement produces a call for this
routine.  <indexterm><primary>END OF PROGRAM Statement</primary></indexterm> 
<indexterm><primary>SYSTEM Subroutine</primary></indexterm>
</para></listitem>
</varlistentry>

<varlistentry>
<term>ERROR</term> 

<listitem><para>Entry to this routine also causes a return to the
operating system.  However, if a dump of storage was requested of the
operating system such a print of storage will be produced before the
return to the system.  The ERROR RETURN statement may produce a call
for this routine.<indexterm><primary>ERROR RETURN
Statement</primary></indexterm> <indexterm><primary>ERROR
Subroutine</primary></indexterm> </para></listitem>
</varlistentry>

<varlistentry>
<term>TAPEWR </term> <listitem><para>Entry to this subroutine causes
BCD information to be written on tape.  The arguments are: (1)
location of the format specification, (2) tape number, and (3) a list of
<!-- beginpage IV.5 -->
variables to be written.  The WRITE BCD TAPE ... statement produces
a call for this subroutine.
<indexterm><primary>Hollerith (BCD)</primary></indexterm>
<indexterm><primary>TAPEWR Subroutine</primary></indexterm>
<indexterm><primary>WRITE BCD TAPE</primary></indexterm>
<indexterm><primary>WRITE BINARY TAPE</primary></indexterm>
</para></listitem>
</varlistentry>

<varlistentry>
<term>PRINT</term> <listitem><para>Similar to TAPEWR above except that
the use of tape 6 (the output tape) is implied.  The PRINT FORMAT
... statement <indexterm><primary>PRINT FORMAT
Statement</primary></indexterm> produces a call for this
subroutine.<indexterm><primary>PRINT Subroutine</primary></indexterm>
</para></listitem>
</varlistentry>

<varlistentry>
<term>TAPERD</term>
<listitem><para>Entry to this subroutine causes BCD information to be
read from tape.  The arguments are: (1) location of the format
specification, (2) tape number, and (3) a list of variable to be read.
The READ BCD TAPE . . . statement produces a call for this
routine.
<indexterm><primary>READ BCD TAPE</primary></indexterm>
<indexterm><primary>READ BINARY TAPE</primary></indexterm>
<indexterm><primary>TAPERD Subroutine</primary></indexterm>
</para></listitem>
</varlistentry>

<varlistentry>
<term>READ</term>
<listitem><para>Similar to TAPERD above except that the use of tape 7
(the input tape) is implied.  The READ FORMAT . . . statement produces
a call for this subroutine.  <indexterm><primary>READ
Subroutine</primary></indexterm></para></listitem>
</varlistentry>

<varlistentry>
<term>PUNCH</term> <listitem><para>Entry to this subroutine causes BCD
information to be written on tape 5 (punch output type).  The
arguments are the same as PRINT and the PUNCH FORMAT . . . statement
produces the call. <indexterm><primary>PUNCH
Subroutine</primary></indexterm></para>
<indexterm><primary>READ FORMAT Statement</primary></indexterm>
</listitem>
</varlistentry>

<varlistentry>
<term>COMMNT
<indexterm><primary>COMMNT Subroutine</primary></indexterm>
</term> 
<listitem><para>Entry to this subroutine causes
BCD informtion to be printed on the attached (on-line) printer.  The
arguments are the same as PRINT except that the line spacing is not
given in the format specification since an automatic 1/6 page skip is
produced.  The statement producing the call is PRINT ON LINE
. . . .<indexterm><primary>PRINT ON LINE FORMAT Statement</primary></indexterm>
</para></listitem>
</varlistentry>

<varlistentry>
<term>SETEOF</term>
<listitem><para>This name may appear explicitly in the form
SETEOF.(S).  where S is an expression in the statement label mode
designating the point of return when an end-of-tape is encountered
during the reading or the writing of magnetic tape.
<indexterm><primary>SETEOF Subroutine</primary></indexterm> 
</para></listitem>
</varlistentry>

<varlistentry>
<term>SETETT</term>
<listitem><para>This name may appear explicitly in the form
SETETT.(S).  where S is an expression in the statement label mode
designating the point of return when an end-of-tape is encountered
during the reading or the writing of magnetic tape.</para></listitem>
</varlistentry>

<varlistentry>
<term>SETERR</term>
<listitem><para>This name may appear explicitly in the form
SETERR.(S), where S is an expression in statement label mode
designating a point of return after an illegal data 
<!-- beginpage IV.6 -->
character or illegal format specification has been encounterered by an
input-output subroutine.<indexterm><primary>Bocks,
Input-Output</primary></indexterm>
<indexterm><primary>SETERR Subroutine</primary></indexterm> 
</para></listitem>
</varlistentry>

</variablelist>

<para>It should be understood thatthe subroutines described above may
be called by other subroutines as well as statements.  Thus, for
example, SETEOF is called by TAPERD, TAPEWR calls PRINT, and all of
the input-output routines call ERROR.</para>
</sect1>
</chapter>

<!-- beginpage DEFINE.1 -->
<appendix><title>The DEFINE Statement in MAD</title>

<note><para>DEFINE is not supported in the Retrocomputing Museum
implementation.</para></note>

<para>The following describes a procedure by which new operators and
mode conversion operations may be introduced into the MAD language and
used immediately thereafter in the rest of the program.  As each
definition is processed, the sequence of machine-like operations
defining the behavior of the operator becomes part of the translator,
just as the sequence for any already existing operator in the MAD
language.  The definition is "temporary", in that it applies only the
program or external function definition which contains the definition
program.  In every case, the definition program must precede the first
use of the operator or conversion being defined.  A definition may
refer to previously defined operators and conversions, but not to
operators or conversions not yet defined.  An example is given
immediately below, to which reference may be made while reading the
complete explanation which follows it.</para>

<programlisting>
	Example:

		DEFINE BINARY OPERATOR .LOGADD., PREDECENCE SAME AS .OR.
		MODE STRUCTURE 2 .LOGADD.2 TO 2, 1 .LOGADD.1 TO 1


		JMP	*+1, MQ, *+7
		STQ	T
		CAL	A
		ORA	B
		SLW	T+1
		CLA	T+1
		OUT	AC
		STO	T
		JMP	*-6
		END
</programlisting>

<para>This example illustrates some, but not all, of the pertinent facts about definitions.</para>

<sect1><title>Operator name</title>

<para>The name of the operator being defined consists of a sequence of
<emphasis>letters</emphasis> (at most six), preceded and followed by
periods (e.g. .LOGADD.).</para>

</sect1>
<!-- beginpage DEFINE.2 -->
<sect1><title>Modes</title>

<para>The modes already existing in MAD are referred to in operator
and conversion definition programs by numeric codes:</para>

<programlisting>
	Floating Point	0
	Integer		1
	Boolean		2
	Function Name	3
	Statement Label	4
</programlisting>

<para>The user may find it necessary to introduce new modes to accompany
newly defined operators.  These are introduced via mode declarations
similar to those of the form</para>

<para role='centered'>INTEGER	J,M,P,GCD.,E</para>

<para>except that the new modes are designated by number, as, for
example,</para>

<para role='centered'>MODE NUMBER 5 MP, GR, V., T</para>

<para>The available numbers are 5, 6, and 7, and these may represent any
modes desired.  This mode declaration does not carry any information
as to the nature of the arithmetic implied by the mode; it merely
declares certain variables and function values to be of that mode.
The interpretation of the mode is implicit in the operator and
conversion definition programs.  Mode declarations may occur anywhere,
as before, except within operator and conversion definition programs.</para>

</sect1>
<sect1><title>The DEFINE Statement</title>

<para>The first statement of an operation definition program is</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation11.png'/>
  </imageobject>
</mediaobject>

<para>where .NAME. is the name of the operator being defined (the operator
may be either binary or unary), and .OPER. 
is the name or symbol of some exist&shy;ing or previously defined
operator.  This statement establishes the precedence (relative to the
missing-parenthesis convention) of the operator .NAME. as being (1)
immediately above that of .OPER. (but below all those already above
.OPER.), (2) equal to that of .OPER., or (3) immediately below that of
.OPER. 
<!-- beginpage DEFINE.3 -->
(but above all those already below .OPER.). The name .OPER. could also
be a single character, such as *, +(binary), -(binary), or /.  Unary
minus can be referred to in such statements by the name -U.  Unary
plus should not be used.</para>

</sect1>
<sect1><title>The MODE STRUCTURE STATEMENT</title>

<para>The choice of an appropriate sequence of instructions to perform
a given operation assumes knowledge not only of the operator in
question, but also of the modes of the operands.  Thus A + B will be
computed via one sequence if A and B are both floating point numbers,
and via the same floating point sequence preceeded by an
integer-to-floating point conversion sequence if one of the operands
is an integer and the other is a floating point number.  The
specification of an operator together with the modes of its operands
(or operand, if unary) will be called a <emphasis>context</emphasis>,
and indicated by expressions such as 1 + 1, 0 .ADD. 0, .ABS. 0, 1
.P. 0.  In these expressions, the integers represent the
<emphasis>modes</emphasis> of the operands, and if the operator is
unary, the mode is given only for the right-most (or
<emphasis>b</emphasis>) operand position.  The left operand will be
referred to as the <emphasis>a</emphasis> operand.</para>

<para>A <emphasis>mode scheme</emphasis> may be described as being of
one of two types:</para>

<para>(1) <emphasis>M TO r,</emphasis> used for operator definitions, or
<emphasis>M TO N,</emphasis> where M and N are contexts containing the
same operators but different in exactly one operand mode, and r is a
mode number.  Examples of mode schemes are 2 .LOGADD .2 to 2, 1 + 1 TO
1, 1 .ADD. 0 To 1 .ADD. 1.  In the first case the operator .LOGADD. is
applied to two Boolean arguents to produce a Boolean result.  In the
second case we have ordinary integer addition, producing an integer
result.  The third example illustrates a mode conversion.  The
operator .ADD. has occurred with an <emphasis>a</emphasis> operand in
floating point mode and a <emphasis>b</emphasis> operand in integer
mode.  The mode scheme given describes the conversation of the
<emphasis>b</emphasis> operand to floating point mode.  These schemes
are used in MODE STRUCTURE statements (see below) to indicate the
effect of the associated sequence on the operands involved.  Reference
will be made below to schemes of "type 1" and "type 2" as indicated
above, and to the M and N contexts and the mode number r which appear
in these schemes.</para>

<!-- beginpage DEFINE.4 -->
<para>After the DEFINE statement (but not necessarily immediately
after) must be one or more <emphasis>sequence definition
programs</emphasis>.  Each of these programs consists of one MODE
STRUCTURE statement followed by a "sequence".  In case a new mode is
created, one may find occasion to write definition programs without
any new operators being defined.</para>

<!-- in the original, first occurrence of "type" lacked a closing quote -->
<para>Immediately after the words MODE STRUCTURE is a list of one or more
mode schemes, separated by commas.  In any one MODE STRUCTURE
statement all mode schemes must be of the same "type" (see above),
which will then be referred to as the "type" of the MODE STRUCTURE
statement itself, and as the "type" of the sequence definition program
which contains this statement.  A statement of type I will precede a
sequence which will accept as input one or two operands and produce a
result.  (See "sequence" below.)  The "sequence" will be inserted in
the object program, however, only when the operator and modes of the
operands correspond to a context appearing in one of the mode schems
in the MODE STRUCTURE statement.  Thus, in the example above, if the
operator .LOGADD. appears between two operands of Boolean or integer
mode, the sequence which follows will be processed as outlined below.
If .LOGADD. appears between two operands, either (or both) of which is
of a different mode, this sequence will not be applicable.  If no
other sequence definition programs are provided, the context being
translated is illegal, and an error indication is produced.  the mode
number r is taken as the mode of the result of the computation which
results from the sequence.  This is needed in establishing contexts of
succeeding operations.</para>

<para>Since schemes of type 2 require their M and N contexts to agree in the
operator they contain and one of the mode numbers, they have the form:
2.LOGADD. 1 to 2 .LOGADD. 2.  The sequence which follows a MODE
STRUCTURE statement containing <emphasis>this</emphasis> scheme will
be written so as to perform the conversion of the second operand of
.LOGADD. from integer to Boolean form in some manner.</para>

<para>The following general rules apply to all sequence definition
programs:</para>

<para>(1) A context appearing in an M position may not already exist in the
MAD language or appear in the M position in another MODE STRUCTURE
statement.</para>

<!-- beginpage DEFINE.5 -->

<para>(2) Every context appearing in the program containing the
definition program must appear in an M position in some MODE STRUCTURE
statement.  This applies in particular to contexts occurring in N
positions in MODE STRUCTURE statements of type 2.</para>

<sect2><title>The Sequence</title>

<para>Occasionally the sequence which would follow a particular MODE
STRUCTURE statement is known to agree exactly with some existing
sequence in MAD or some <emphasis>previously defined
sequence</emphasis>.  In this case, the entire sequence may be
replaced by the statement SAME SEQUENCE as [script]S, where [script]S
is some mode scheme for which a sequence is already available in MAD
or has been previously encountered.  For example, one might write:</para>

<programlisting>
	MODE STRUCTURE   5 + 5 TO 5
	SAME SEQUENCE AS 1 + 1 TO 1
</programlisting>

<para>for some new mode numbered 5 for which addition happens to coincide
with integer addition.  (Presumably, some other operator will differ
in its mode 5 behavior from its integer behavior.)  When a new
sequence is needed, it must follow immediately the MODE STRUCTURE
statement to which it belongs.</para>

<para>There are five kinds of instructions which may occur in the sequence:  
(1) END - this must be the physically last instruction of the
sequence.  It has no significance except to terminate the definition
sequence.  
(2) OUT AC and OUT MQ - these terminate the
<emphasis>processing</emphasis> of the sequence and indicate that the
result of carryin gout the object program computation will be left in
the accumulator or MQ register, respectively.
(3) JMP - <emphasis>unconditional</emphasis> transfer <emphasis>during
processing of the sequence</emphasis>.  This is illustrated in the
example by the introduction of the form</para>

<para role='centered'>JMP *-6</para>

<para>It consists merely of a local reference (* &plusmn; integer constant),
and refers to the <emphasis>processing</emphasis> of the sequence
<emphasis>during compilation</emphasis>.  This instruction will not
appear in the object program generated.  The * may only occur in JMP
instructions.  (4) JMP - <emphasis>conditional</emphasis> transfer
<emphasis>during processing of the sequence</emphasis>.  This is
illustrated in the example by the instruction</para>

<para role='centered'>JMP *+1, MQ, *+7</para>

<!-- beginpage DEFINE.6 -->
<para>This refers to the symbol MQ, which is one of four logical
propositions:</para>

<variablelist>
<varlistentry>
<term>MQ:</term>
<listitem>
<para>The result of the <emphasis>previous</emphasis> operation was
left in the MQ register.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>AC:</term>
<listitem>
<para>The result of the <emphasis>previous</emphasis> operation was
left in the accumulator.</para> 
</listitem>
</varlistentry>
<varlistentry>
<term>AT:</term>
<listitem>
<para>The current <emphasis>a</emphasis> operand is the result of the
previous operation.</para> 
</listitem>
</varlistentry>
<varlistentry>
<term>BT:</term>
<listitem>
<para>The current <emphasis>b</emphasis> operand is the result of the
previous operation.</para> 
</listitem>
</varlistentry>
</variablelist>

<para>(Note: The <emphasis>a</emphasis> and <emphasis>b</emphasis> operands
refer to the context: A .NAME. B, where A is omitted for unary
operators.)</para>

<para>The conditional transfer instruction indicates in the "tag" position
the logical proposition (e.g., MQ) in the "address" (left-most)
position the local reference to which the processing next proceeds if
the proposition is <emphasis>true</emphasis>, and in the "decrement"
(right-most) position the local reference to which the processing next
proceeds if the proposition is <emphasis>false</emphasis>.  (The
symbol "*" refers to the location in the sequence in which the "*"
itself is found.)  Thus, in the example, if the result of the previous
operation was in the MQ register, processing moves next to the STQ T
instruction while if it was not in the MQ register, processing moves
next to the STO T instruction.  This illustrates the need for
<emphasis>always</emphasis> saving the previous result if it is not
used immediately.  (5) Object program instructions in the form of a
3-letter mnemonic operation code (taken from the list given in the
Appendix), followed by the usual address, tag, and/or decrement parts
as in the standard 704 codes.  (SAP extended operations codes are not
included i the Appendix and may <emphasis>not</emphasis> be used.)  In
object program instructions the tag, if any, must be one of the digits
0 through 7, and if there is a decrement part, the tag digit may not
be omitted and the address part may not be omitted.  Address and
decrement parts must be one of the following:</para>

<variablelist>
<varlistentry>
<term>A -</term>
<listitem>
<para>refers to the <emphasis>a</emphasis> operand (not used for unary 
operations)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>B -</term>
<listitem>
<para>refers to the <emphasis>b</emphasis> operand Note: A and B may
not appear in instructions such as STO, itc., which change their
values.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>T -</term>
<listitem>
<para>refers to the temporary in which the result of the previous
operation must be stored if not used.  This temporary may not be used
for any other purpose.</para>
</listitem>
</varlistentry>
<!-- beginpage DEFINE.7 -->
<varlistentry>
<term>T + integer constant -</term>
<listitem>
<para>refers to other temporaries which may be used in the sequence.
There must be <emphasis>exactly two occurrences</emphasis> of
any temporary name so used.  One may not assume these
temporaries are located contiguously in storage.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>LOG + integer constant -</term>
<listitem>
<para>local object program reference, i.e., a reference in the object
program, effective at the time of execution of the object program, not
during translation.  (There is no provision here for a "location
field" such as columns 1-6 in SAP.)  "LOG" refers to the location in
which "LOG" occurs, and may not occur in a JMP instruction.</para>
</listitem>
</varlistentry>
</variablelist>

<sect3><title>Integer Constants</title>

<para>C1 - symbolic name for the constant integer 1</para>

<para>CF - symbolic name for the constant
+233000000000<subscript>8</subscript>, useful for certain
conversions.</para>

<para>Note: All integers used in definition sequences are interpreted as
usual.  Integers may not exceed 1023.</para>

</sect3>
</sect2>
<sect2><title>Processing</title>

<para>After the definition program has been absorbed into the translator,
the sequence is processed interpretively at each occurrence of the
defined operator in some legal context, i.e., the first instruction is
examined and if it is an unconditional transfer or conditional
transfer (JMP), the transfer is made to the appropriate instruction in
the sequence. If it is an object program instruction (operation code
other than JMP, OUT, or END), the appropriate translation of the
instruction is included in the machine-language version of the object
program, which is being generated.  If it is an OUT instruction, the
procerssing of the sequence stops, with the setting of a switch in the
translator to indicatte whether the result of this operation remains
in the accumulator or MQ register.  (The END instruction should never
be encountered <emphasis>during processing</emphasis> of the
sequence.)</para>

</sect2>
<sect2><title>Examples:</title>

<para>(1) The following program could be used to define floating point
multiplication if it were not already in the MAD language.  The three
sequence definition programs define floating point multiplication and
two conversions, respectively.</para>
<!-- beginpage DEFINE.8 -->
<programlisting>
	DEFINE BINARY OPERATOR .FMPY., PRECEDENCE SAME AS *(
	MODE STRUCTURE 0 .FMPY.0 TO 0

JMP	*+4,AC,*+1
JMP	*+1,MQ,*+4
JMP	*+4,AT,*+1
JMP	*+7,BT,*+5
STO	T
LDQ	A
FMP	B
OUT	AC
STQ	T
JMP	*-4
FMP	A
OUT	AC
END

	MODE STRUCTURE 1 .FMPY. 0 TO 0.FMPY.0

JMP	*+5,MQ,*+1
JMP	*+1,AC,*+5
JMP	*+5,AT,*+1
STO	T
JMP	*+2
STQ	T
CLA	A
ORA	CF
FAD	CF
OUT	AC
END

	MODE STRUCTURE 0 .FMPY. 1 to 0.FMPY.0
JMP	*+5,MQ,*+1
JMP	*+1,AC,*+5
JMP	*+5,BT,*+1
STO	T
JMP	*+2
STO	T
JMP	*+2
STQ	T
CLA	B
ORA	CF
FAD	CF
OUT	AC
END
</programlisting>
<!-- beginpage DEFINE.9 -->
<para>(2) The unary operator .SHIFT., which shifts an integer in the
address part into the decrement part of a word, would be defined as
follows (where mode 5 indicates an integer in the decrement part of
the word):</para>

<programlisting>
	DEFINE UNARY OPERATOR .SHIFT., PRECEDENCE SAME AS .ABS.
	MODE STRUCTURE .SHIFT. 1 TO 5

JMP *+3, MQ, *+1
JMP *+1, AC, *+3
JMP *+3, BT, *+5
STQ  T
CLA  B
ASL  18
OUT  AC
STO  T
JMP  *-4
END
</programlisting>

<para>One would also have to provide for all contexts in which mode 5
variables or constants might appear.  In particular, one might needf
the following (in the case of "*", the "TO r" in a type 1 scheme may
be omitted.):</para>

<programlisting>
	MODE STRUCTURE 5 = 5

JMP *+1, BT, *+2
JMP *+2, AC, *+4
CLA  B
STO  A
OUT  AC
STQ  A
OUT  MQ
END
</programlisting>

<para>Of course, this could also have been written:</para>

<programlisting>
	MODE STRUCTURE 5 = 5
	SAME SEQUENCE AS 1 = 1
</programlisting>

<para>(3) Another example, illustrating the use of the local object
program reference (LOC) is the operator .BIT., a Boolean binary
operator whose value is 1B if A has a 1 in bit position B, and 0B
otherwise.  (Bits are numbered here from the left, 0-35.)</para>
<!-- beginpage DEFINE.10 -->
<programlisting>
	DEFINE BINARY OPERATOR .BIT., PRECEDENCE SAME AS .E.

	MODE STRUCTURE 1 .BIT.1 TO 2, 2.BIT.1 TO 2, 0.BIT.1 TO 2

JMP *+6, MQ, *+1
JMP *+1, AC, *+7
JMP *+1, BT, *+13
LDQ A
STA LOC+1               &lt;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;&mdash;
JMP *+6
JMP *+3, AT, *+1
STQ T
LDQ A
CLA B
STA LOC+1
RQL 0
PXD
LGL 1
OUT AC
STO T
JMP *-8

	MODE STRUCTURE 1 .BIT.0 TO 1.BIT.1,
      1 2 .BIT. 0 TO 2.BIT. 1, 0 .BIT. 0 TO 0 .BIT. 1

        SAME SEQUENCE AS 1 = 0
</programlisting>

<para>Note that in the instruction indicated by the arrow the address
(LOC+1) is that which will appear in the object program, not that
which is in the sequence definition program.  This sequence could be
written more elegantly but was written in this way to illustrate the
use of LOC.</para>

</sect2>
<sect2><title>Card Forms</title>

<para>The DEFINE and MODE STRUCTURE statements are punched (as any
other MAD statements) starting in (or after) column 12.  Instructions
in the sequence must have the "operation code" in columns 8-10, and
the rest of the instruction in (or after) column 12.  Blanks are
ignored throughout, except in operating codes.</para>

</sect2>
<!-- beginpage DEFINE.11 -->
<sect2><title>Operation Codes</title>

<programlisting>
ACL			LDA			STA
ADD			LDQ			STD
ADM			LFM			STO
ALS			LGL			STP
ANA			LLS			STQ


ANS			LRS			STZ
ARS			LTM			SUB
BSF			LXA			SXD
BST			LXD			TIX
CAD			MPR			TLQ

CAS			MPY			TMI
CHS			MSE			TNO
CLA			NOP			TNX
CLM			ORA			TNZ
CLS			ORS			TOV

COM			PAX			TPL
CPY			PBT			TOC
DCT			PDX			TQP
DVH			PSE			TRA
DVP			PXD			TSX

EFM			RDS			TTR
ETM			REW			TXH
ETT			RND			TXI
FAD			RQL			TXL
FDH			RTT			TZE

FDP			SBM			UFA
FMP			SLQ			UFM
FSB			SLW			UFS
HPR			SSM			WEF
HTR			SSP			WRS
LBT
</programlisting>

</sect2>
</sect1>
</appendix>
<!-- beginpage SIMPLIFIED.1 -->
<appendix><title>Simplified Input-Output Statements</title>

<sect1><title>(a) READ DATA</title>

<para>This statement causes information to be read from cards; no list of
variable names or format specification is necessary.  The values to be
read and the variable names are punched in the data cards in a
sequence of fields of the form:</para>

<para role='centered'>v<subscript>1</subscript> = n<subscript>1</subscript>, v<subscript>2</subscript> = n<subscript>2</subscript> , v<subscript>3</subscript> = n<subscript>3</subscript>, ...., v<subscript>k</subscript> = n<subscript>k</subscript> *</para>

<para>The v<subscript>1</subscript>, ..., v<subscript>k</subscript> are the
variable names and n<subscript>1</subscript>, ... ,
n<subscript>k</subscript> are the corresponding values.  Reading is
continued from card to card until the terminating mark * is
encountered.  Fields cannot be divided between cards, so the last
character in a card not terminated by an asterisk would normally be a
comma.  However, as a convenience, the end of the card is treated as
an implied comma and hence this final comma may be omitted.  The
variable names may designate single variables or elements of linear
and two-dimensional arrays.  The subscripts on the array vaiables must
be integer constants.  The values may be floating point, integer,
octal, Boolean, or alphabetic with the forms descibed in the section
on constants in the MAD manual (See section
<xref linkend='constants'/>).</para>

<para>For convenience in entering values of array elements it is
possible to designate only one variable name and have successive
numbers, written without names, interpreted as the consecutive values
of the array, i.e.,</para>

<para role='centered'>V(j) = n<subscript>1</subscript>, n<subscript>2</subscript>, n<subscript>3</subscript> . . . , n<subscript>k</subscript></para>

<para>would be the same as</para>

<para role='centered'>V(j) = n<subscript>1</subscript>. V(j + 1) + n<subscript>2</subscript>, ..., V(j + k - 1) = n<subscript>k</subscript></para>

<para>For 2-dimensional arrays successive numbers will be entered in
succeeding columns of the designated row until the row - as determined
from the current value of the dimension vector - is filled, and then
the next row will be started.</para>

<para>Zeros must be punched; adjacent commas (,,) are simply skipped.
Blanks are ignored throughout except between dollar signs (which are
used only to delimit a string of Hollerith characters).</para>

<para>Six or less Hollerith characters - delimited by dollar signs -
may be values of single integer variables.  Longer strings of
Hollerith characters may be entered as elements of arrays.  Such
strings are divided into six character groups for storage.</para>

<!-- beginpage SIMPLIFIED.2 -->
<para>As an example illustrating many of the features described herein
consider the data card set:</para>

<programlisting>
		X1 = 1.2, Y1 = -6.8, INDEX = 4, A(4) = 3.1, -10.93,
		12.6, MATRIX (2,1) = 25 E-2, 1.8 E-10, 3.14 E-8,
		STRING (1) = $ END OF PROBLEM $ *
</programlisting>

<para>It is important to remember that, since such cards are data
cards, they should not be included as an integral part of the MAD
statements but handled as ordinary data.</para>

</sect1>
<sect1><title>(b) PRINT COMMENT &scriptS;</title>

<para>Here &scriptS; designates a string of no more than 120 Hollerith
characters.  These characters may not include dollar signs and here
blanks are valid characters.  The string, delimited by dollar signs as
indicated, will be printed.  The first character will be interpreted
as a carriage control code and will not be printed.  For convenience
the carriage control code is reproduced here:</para>

<informaltable frame='none' colsep='0' rowsep='0' role='centered'>
<tgroup cols='2'>
<thead>
<row><entry>Character</entry><entry>Result</entry></row>
</thead>
<tbody>
<row><entry>blank  </entry> <entry>single space</entry></row>
<row><entry>+      </entry> <entry>no space</entry></row>
<row><entry>-      </entry> <entry>triple space</entry></row>
<row><entry>0      </entry> <entry>double space</entry></row>
<row><entry>1      </entry> <entry>space to top of next page</entry></row>
<row><entry>2      </entry> <entry>space to next half-page</entry></row> 
<row><entry>4      </entry> <entry>space to next quarter page</entry></row>
<row><entry>8      </entry> <entry>space to next one sixth page</entry></row>
</tbody>
</tgroup>
</informaltable>

<para>An example statement is:</para>

<para role='centered'>PRINT COMMENT $1 JOHN PUBLIC, MATH 373 PROBLEM 1$</para>

</sect1>
<sect1><title>(c) PRINT RESULTS &scriptL;</title>

<para>Here &scriptL; designates a list of variable names or block
designations.  Expressions may not appear in the list although
subscripts of variables in the list may be expressions.  The printed
output is analogous to the input in that the numbers printed are
preceded by the appropriate variable name and an equal sign - e.g., X
= -12.4 - and only the initial elements of arrays are so labelled.
Elements of three and higher demensional [typo?]  arrays will be
labelled with the equivalent linear subscript.  If dummy variables (in
a function definition) are included in the list the specific values
assigned to such variables during execution will not be labelled but
simply preceded by ... .</para>

<para>An example statement is:</para>

<para role='centered'>PRINT RESULTS X1, Y1, Z(1) . . . Z(N + 1), MTX (1,1) ...MTX(M,N)</para>

</sect1>
</appendix>
<appendix><title>Supplement to the MAD Manual</title>
<!-- beginpage SUPPLEMENT.1 -->
<para role='centered'>November 15, 1960</para>

<note><para>Most of these extended features are not supported by the
Retrocomputing Museum implementation, mainly because we have no test
programs for them. Octal constants are supported.</para></note>

<para>The notes which appear below describe several new features which have
been added to MAD.  Existing programs need not be changed in any way.
Most programs will be reduced in size and execution time, however, if
they are recomplied to take advantage of the internal improvements
that have been made with regard to the translation of Boolean
expressions and which are described below (see (8)).  Included here,
also, are some comments on reducing the size of some subroutines.</para>

<para>(1) The Appendix to this supplement describes the new DEFINE facility.
By means of this facility, new operators can be added temporarily to
MAD, as well as new modes of arithmetic.</para>

<para>(2) Along with integer, floating point, Boolean, and alphabetic
constants, one may now write <emphasis>octal</emphasis> constants.
These constants are written as twelve digit octal integers followed by
the letter K, except that leading zeros may be omitted.  If one or
more <emphasis>decimal</emphasis> digits follow the letter K, this is
interpreted as an octal scale factor.  This 127K2 would be the octal
integer 000000012700, and 1K10 would produce the octal number
010000000000.</para>

<para>(3) Any constant (integer, floating point, Boolean, alphabetic,
or octal) may be declared to be of a mode other than its normally
assigned mode by following the constant by the letter M and the digit
code for that mode.  The digit codes are:</para>

<programlisting>
	0	Floating point
	1	Integer
	2	Boolean
	3	Function Name
	4	Statement Label
</programlisting>

<para>The new modes 5, 6, and 7, which may be defined as described in
the Appendix, may also be used.  The constant is converted
<emphasis>as usual</emphasis>, but then is assigned the indicated
mode, if the letter M is used.  Thus, if some new mode numbered 
<!-- beginpage SUPPLEMENT.2 -->
6 were defined for certain integers, then the appearance of the
constant 32M6 would assign mode 6 to the decimal integer 32.  The
appearance of 32KM6 would assign mode 6 to the octal constant 32, and
the appearance of $AB$M6 would assign the mode 6 to the constant $AB$.
Similarly, the appearance of 32.1E-1M6 would assign mode 6 to the
number 3.21 which appears in storage in the usual floating point
form.</para>

<para>(4) A subroutine is not available, called ZERO., which will
accept as arguments single variables or blocks (i.e., an "input list")
and very efficiently (i.e., using STZ and TIX operations) store +0 in
these locations.  This saves writing an iteration loop.</para>

<para>(5) In addition to the usual notation for a block:  e.g., A(6) ...A(N), MAD will now accept the traditional use of commas as well:</para>

<para role='centered'>A(6), ... , A(N)</para>

<!-- in the original, "debugging" was typoed as "degugging" -->
<para>(6) A list of variables used in the program, but to which only one
reference is made, is printed out for each MAD program.  This list
does not include any variables appearing in PROGRAM COMMON, ERASABLE,
DIMENSION, VECTOR VALUES, or EQUIVALENCE statements.  Variables
appearing in this list are all assigned to the same location, under
the assumption that they are not purposely used for anything except
perhaps redundant labelling of statements.  This list has proven to be
a valuable debugging aid, since misspelled names almost
invariably show up on this list.  It should therefore be checked
carefully whenever it appears.</para>

<para>(7) In order to conserve storage, it may be desirable to store, for
example, only one half of symmetric matrix or an upper (or lower)
triangular matrix, etc.  Perhaps only the non-zero elements of a
sparse matrix might be stored, also.  For such arrays, it is necessary
to use a subscription subroutine other than the standard one supplied
by MAD which expects to find the entire matrix stored by rows (in the
two-dimensional case).  Such special subscription subroutines may now
be written as any other internal or external functions in MAD or in
SAP, as usual.  The arguments must be the array name, followed by the
n subscripts (integer expressions) in the usual order.  The value of
the function which is to be computed is the <emphasis>linear
subscript</emphasis> to be used to obtain the value desired.  For
example, if one wished to store only 
<!-- beginpage SIMPLIFIED.3 -->
the upper triangle (plus diagonal) of an upper triangular
two-dimensional array (by rows, starting as A(2)), the subscription
function F, could be defined as follows: (We shall assume a constant
zero stored at A(1))</para>

<mediaobject>
  <imageobject>
    <imagedata fileref='equation12.png'/>
  </imageobject>
</mediaobject>

<para>where n is the nubmer of columns in the matrix A, and b is the
base point.  Of course, if n (and/or b) is not a constant, it will
have to be made available to the subscription subroutine, probably via
PROGRAM COMMON, as will the base point, if used.  It will
automatically be available, of course, if the subroutine is written as
an <emphasis>internal</emphasis> function.  Note that in the case i >
j, we give as the value of F.(A,i,j) the <emphasis>linear
subscript</emphasis> 1 of the value 0, rather than the value
itself.</para>

<para>In order to notify MAD that such a subscription function is to be
used, one merely inserts the name of the function as the first entry
of the dimension vector of the appropriate array, moving the number of
dimensions, etc., down by one in the dimension vector.  Thus, the
above example might be indicated as follows:</para>

<programlisting>
	DIMENSION A(100, ADIM)
	VECTOR VALUES ADIM = F.,2,2,10
</programlisting>

<para>if there were ten columns.  Although dimension information could
always be computed or brought in as data instead of via a VECTOR
VALUES declaration, the one exception to this is now the name of the
subscription function.  If used, it <emphasis>must</emphasis> occur as
the first entry in a VECTOR VALUES declaration, and it must be
followed immediately by at least one integer in the same declaration.
It should be understood that if this feature is used, references to
matrix elements by means of subscripts are made as if the matrix were
stored as originally described in the MAD manual.  Thus, subroutines
do not need to know whether a calling program is or is not using such
storage conservation functions.</para>

<!-- beginpage SIMPLIFIED.4  at soft hyphen-->

<para>Two special subscription functions are available from the subroutine
library: (a) SYMM. will handle two-dimensional symmetric arrays for
which only the upper half (plus diagonal) is stored by rows.  (b)
TRANSP. will handle a two dimensional array stored by rows (in full)
but considered to be in trans&shy;posed form.  In other words, if a matrix
B is designated as having subscription function TRANSP., then a call
of B(6,2) will, in fact, produce the linear subscript of B(2,6).</para>

<para>Both SYMM. and TRANSP. automatically have access to the dimension
vector (including the base point), so no provision need to be made for
putting any information in PROGRAM COMMON, for example.  In fact, if
the subscription function is written in SAP, it may be able to use the
fact that MAD provides the address of the dimension vector in the
decrement part of the parameter which contains the address of the
array, in this case the first parameter.  Note, however, that the
dimension information has been moved down by one because of the
presence of the name of the subscription function; and this must be
accounted for in any references to the dimension vector.</para>

<para>In order to accommodate this new feature, the MAD library
subroutines (03310, (03311, and (MTX have been modified.  Anyone using
special subscription subroutines should discard any previously punched
versions of these library subroutines.  Note, also, that TRANS and
TRANS1 may not be used for transposing matrices stored in short form,
since they were not written to recognize special subscription
fuctions.</para>

<para>(8) A Boolean expression usually contains one or more atomic Boolean
expressions consisteing of two arithmetic expressions on either side
of a relation.  Exampls of atomic Boolean expressions are X + 3
.LE. Y, I, .E. 1, and so on.  It has been found possible to save as
many as 60% of the object program instructions formerly generated for
atomic Boolean expressions.  Moreover, the object programs now
produced will skip the evaluation of the remaining terms of a
disjunction (an "or" expression) as soon as one terms has the value
1B, and a similar statement holds for conjunctions ("and"
expressions).  These changes are entirely internal to MAD, and require
no change in MAD source programs.  A recompilation will be necessary,
however, to obtain the shorter, faster object program which results.
In order to obtain the maximum benefit from the skipping behavior
indicated above, it is necessary to understand that the atomic Boolean
epxressions in a complex Boolean expression are evaluated from right
to left, and the one most likely to be "true" in a conjunction, and
the one most likely to be "false" in a conjunction, should be placed
as far toward the right end of the expression as possible.</para>

<!-- SIMPLIFIED.5 -->
<para>Thus, if one were testing for values of X between 0 and 2 and
between 5 and 6, one might write</para>

<para role='centered'>WHENEVER 0 .L. X .AND  X .L. .OR. 5  .L. X .AND X .L. 6</para>

<para>If one knew that for the data expected, the values of X would
occur most often between -1 and 2, one would do better to write the
above as follows:</para>

<para role='centered'>WHENEVER X .L. 6 .AND. 5 .L. X .OR. X .L. 2 .AND. 0 .L. X</para>

<para>(9) There is a table within MAD in which are recorded all
occurrences of parameters within an external or internal
<emphasis>function definition</emphasis>.  Since all such occurrences
must be initialized on each entry to the subroutine, it is very
desirable that the number of entries in this table be kept as small as
possible.  This is especially important when a diagnostic comment is
generated saying that this table has in fact overflowed!  (The
diagnostic comment produced in this case is PARAMETER USE TABLE
EXCEEDED.)</para>

<para>There are several ways to cut down the entries in this table and
thus speed up the execution of the subroutine and shorten its length
as well.  (1) If X is an <emphasis>input</emphasis> to the subroutine
and its value is used several times, start off the subroutine's
computation with the substitution statement Y = X and use Y instead of
X everywhere.  Only this substitution statement will then need to be
initialized with the address of X.  (2) If the
<emphasis>address</emphasis> of a variable is needed, as in the case
of an <emphasis>output</emphasis> argument, or an argument which is an
array name, one cannot use the method just given in (1).  One can
instead put the variable or array in PROGRAM COMMON by means of
(identical) declarations in both the main program and the subroutine.
Then the variable or array should <emphasis>not</emphasis> be used as
an argument at all, and the initialization is thus avoided.  Note that
in this case (identical) dimension declarations are necessary for such
arrays in both the main program <emphasis>and the
subroutine</emphasis>.</para>

<para>(10) A new logical operation is now available in MAD, the
"exclusive or", written as .EXOR..  The precedence of .EXOR. is the
same as the precedence of .OR., and its definition is: M .EXOR. N has
the value 1B if and only if either M or N has the value 1B, but not
both.</para>
<!-- SIMPLIFIED.6 -->
<para>(11) Most diagnostic comments printed for errors in part I of
the translation now include references to the appropriate section of
the MAD manual.  These references appear in parentheses following the
comment.  For example, (II.1.1.4) refers to Chapter II, section 1.1.4
which is titled <emphasis>Boolean Constants</emphasis>.</para>

<para>(12) Each use of the subscript notation A(i,j) where A is an m x
n array, involves evaluation of the expression n(i - 1) + (j - 1) + b
where n = the number of columns in A and b = the base point, i.e.,
A(1,1,) &equiv; A(b).  A method which is <emphasis>much more
efficient</emphasis> is to preset or compute at the beginning of the
program, the vector: V(1) = b-1, V(2) = b-1+n, V(3) = b=1+2n, ...,
V(m) = b-1+(m-1)n.  The i<superscript>th</superscript> element in the
vector is the linear subscript in A of the element in A immediately
preceding the first element in the i<superscript>th</superscript> row.
To refer to A(i,j) one now writes A(V(i)+j).  The base point and
number of columns may be changed during computation, but each time
either is changed the elements of V must be recomputed.  The usual
subscript restrictions still hold, i.e.  i &le; 0, (V(i)+j) &le; 0.  For
example, if A is a 4 x 3 matrix (m = 4, n = 3) and b = 1, then V(1) =
0, V(2) = 3, V(3) 6, and V(4) = 9.</para>
</appendix>

<appendix><title>Index</title>
<!-- stray index entries go here -->
<indexterm><primary>Array</primary><see>Vector</see></indexterm>
<indexterm><primary>BCD (Hollerith)</primary><see>Hollerith (BCD)</see></indexterm>
<indexterm><primary>Call For Function</primary><see>Function Call</see></indexterm>
<indexterm><primary>Calling Sequence</primary><see>Function Call</see></indexterm>
<indexterm><primary>Characters, Admissible</primary><see>Admissible Characters</see></indexterm>
<indexterm><primary>Conditional, Compound</primary><see>Compoound Conditional</see></indexterm>
<indexterm><primary>Conditional, Simple</primary><see>Simple Conditional</see></indexterm>
<indexterm><primary>Dummy Variables</primary><see>Dummy Arguments</see></indexterm>
<indexterm><primary>Error Detection</primary><see>Diagnostics</see></indexterm>
<indexterm><primary>FOR</primary><see>Iteration Statement</see></indexterm>
<indexterm><primary>FOR VALUES OF</primary><see>Iteration Statement</see></indexterm>
<indexterm><primary>Function Arguments</primary><see>Arguments of Functions</see></indexterm>
<indexterm><primary>Function Statement</primary><see>Execute Statement</see></indexterm>
<indexterm><primary>Function Value</primary><see>Value of a Function</see></indexterm>
<indexterm><primary>Hierarchy of Parentheses</primary><see>Parentheses</see></indexterm>
<indexterm><primary>Individual Variables</primary><see>Single Variables</see></indexterm>
<indexterm><primary>Input-Output Blocks</primary><see>Blocks, Input-Output</see></indexterm>
<indexterm><primary>Labels, Statement</primary><see>Statement, Labels</see></indexterm> 
<indexterm><primary>List, Input-Output</primary><see>Input-Output List</see></indexterm> 
<indexterm><primary>Matrices</primary><see>Array Variables</see></indexterm> 
<indexterm><primary>One-Dimensuiional Array</primary><see>Vector</see></indexterm>
<indexterm><primary>OR WHENEVER Statement</primary><see>Conditional Statement</see></indexterm>
<indexterm><primary>Parameters, Subroutine</primary><see>Subroutine Parameters</see></indexterm>
<indexterm><primary>Precedence Hierarchy</primary><see>Parentheses</see></indexterm>
<indexterm><primary>R (Column 11)</primary><see>Remark Declaration</see></indexterm>
<indexterm><primary>Regional Notation</primary><see>Blocks, Input-Output</see></indexterm>
<indexterm><primary>Specifications, Format</primary><see>Format Specifications</see></indexterm>
<indexterm><primary>Statement, Execurtable</primary><see>Executable Statements</see></indexterm>
<indexterm><primary>Statements,
Input-Output</primary><see>Input-Output Statements</see></indexterm>
<indexterm><primary>Statements,
Non-Executable</primary><see>Non-Executable Statements</see></indexterm>
<indexterm><primary>Subscript, Linear</primary><see>Linear Subscript</see></indexterm>
<indexterm><primary>Subscript, Negative</primary><see>Negative Subscript</see></indexterm>
<indexterm><primary>THROUGH Statement</primary><see>Iteration Statement</see></indexterm>
<indexterm><primary>Transpose of a Matrix</primary><see>Matrix Transpose</see></indexterm>
<indexterm><primary>Truncation</primary><see>Intrger Division</see></indexterm>
<indexterm><primary>Variables, Bound</primary><see>Bound Variables</see></indexterm>
<indexterm><primary>Variables, Dummy</primary><see>Dummy Variables</see></indexterm>
<indexterm><primary>Vector, Presetting</primary><see>Presetting Vectors</see></indexterm>

<index/>
</appendix>
</book>
<!--
Local Variables:
compile-command: "make mad-manual.html"
End:
-->
