\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename marst.info
@settitle GNU MARST 2.7 User's Guide
@c %**end of header

@copying
Copyright @copyright{} 2000, 2001, 2002, 2007, 2013 Free Software
Foundation, Inc.

GNU MARST is part of the GNU project released under the aegis of GNU.

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that
the entire resulting derived work is distributed under the terms of
a permission notice identical to this one.

Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions.
@end copying

@dircategory Programming
@direntry
* marst: (marst).               GNU Algol-to-C Translator
@end direntry

@titlepage
@title GNU MARST
@subtitle GNU Algol-to-C Translator
@subtitle User's Guide for Version 2.7
@subtitle March 2013
@author Andrew Makhorin
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage

@contents

@ifnottex
@node Top
@top GNU MARST User's Guide
@end ifnottex

@menu
* Introduction::                Introduction
* Installation::                Installation
* Invocation::                  Program Invocation
* Example::                     Usage Example
* Language::                    Input Language
* Io::                          Input/Output
* Extensions::                  Language Extensions
* Converter::                   Converter Utility
* Thanks::                      Acknowledgments
@end menu

@node Introduction
@chapter Introduction

GNU MARST is an Algol-to-C translator. It automatically translates
programs written in the algorithmic language @w{Algol 60} into the
ANSI C 89 programming language.

The processing scheme is the following:

@sp 1
@example
                Algol-60 source program
                           |
                           V
                    +-------------+
                    |    MARST    |
                    +-------------+
                           |
                           V
                     C source code
                           |
                           V
                    +-------------+
     algol.h ------>| C compiler  |<------ Standard headers
                    +-------------+
                           |
                           V
                      Object code
                           |
                           V
                    +-------------+
      ALGLIB ------>|   Linker    |<------ Standard libraries
                    +-------------+
                           |
                           V
                    +-------------+
  Input data ------>| Executable  |-------> Output data
                    +-------------+
@end example
@sp 1

@noindent
where:

@table @asis
@item Algol 60 source program
a text file that contains a program written in the algorithmic language
@w{Algol 60} (see below about coding requirements);
@item MARST
the MARST translator, a program that converts source Algol program to
the C programming language. This program is part of GNU MARST;
@item C source code
a text file that contains the C source code generated by the MARST
translator;
@item @code{algol.h}
the header file that contains declarations of all objects used by every
program generated by the MARST translator. This file includes some
standard headers (@code{stdio.h}, @code{stdlib.h}, etc.), however,
no other headers are used explicitly in the generated code. This file
is part of GNU MARST;
@item Standard headers
standard header files (they are used only in the header file
@code{algol.h});
@item C compiler
the C compiler, a program that converts C program to machine
instructions;
@item Object code
a binary file that contains object code produced by the C compiler;
@item ALGLIB
the library (archive) file that contains object code for all standard
and library routines used by Algol programs. Some of these routines,
which correspond to standard Algol procedures (@i{ininteger},
@i{outreal}, etc.) are written in @w{Algol 60} and translated to the
C programming language with the MARST translator. Source code of all
library routines is part of GNU MARST. In this distribution the library
has the name @code{libalgol.a};
@item Standard libraries
the standard C run-time libraries;
@item Linker
the linker, a program that resolves external references and produces
an executable module;
@item Executable
a binary file that contains ready-to-run Algol 60 program in an
loadable (executable) form;
@item Input data
input text file(s) read by Algol program;
@item Output data
output text file(s) written by Algol program.
@end table

@node Installation
@chapter Installation

To build and install GNU MARST under GNU/Linux you need to use the
standard installation procedure. For details please see file
@code{INSTALL} included in the distribution.

As a result of installation the following four components will be
installed:

@table @code
@item marst
as a rule, into @code{usr/local/bin};
@item macvt
as a rule, into @code{usr/local/bin};
@item algol.h
as a rule, into @code{usr/local/include} and/or @code{usr/include};
@item libalgol.a
as a rule, into @code{usr/local/lib}.
@end table

@node Invocation
@chapter Program Invocation

To invoke the MARST translator the following syntax should be used:

@sp 1
@code{marst} [@i{options} ...] [@i{filename}]
@sp 1

Options:

@table @asis
@item @code{-d}, @code{--debug}
run translator in debug mode

If this option is specified, the translator emits elementary syntactic
units of the source Algol program to the output C code in the form of
comments.

This option is useful for localizing syntax errors more precisely. For
example, @w{Algol 60} allows comments of three kinds: ordinary
comments, @w{@b{end}-@b{end}} comments, and extended parameter
delimiters. Therefore it is easy to make a mistake, for example, if you
forgot a comma between the @b{end} bracket and the next statement.

@item @code{-e} @i{nnn}, @code{--error-max} @i{nnn}
maximal error allowance

This option specifies maximal error allowance. The translator stops
processing after the specified number of errors detected. The value of
@i{nnn} should be in the range from 0 to 255. If this option is not
specified, the default option @code{@w{-e 0}} is used meaning that the
translation continues until the end of the input file.

@item @code{-h}, @code{--help}
display help information and @code{exit(0)}

@item @code{-l} @i{nnn}, @code{--linewidth} @i{nnn}
desirable output line width

This option specifies the desirable line width for the output C code
produced by the translator. The value @i{nnn} should be in the range
from 50 to 255. If this option is not specified, the default option
@code{@w{-l 72}} is used.

Note that the actual line width may happen to be larger than @i{nnn},
because the translator is not able to break the output text at any
place. However, this happens relatively seldom.

@item @code{-o} @i{filename}, @code{--output} @i{filename}
name of an output text file to write the produced C code

If this option is not specified, the translator uses the standard
output by default.

@item @code{-t}, @code{--notimestamp}
don't write the time stamp to the output C code

By default the translator writes date and time of translation to the
output C code as a comment.

@item @code{-v}, @code{--version}
display translator version and @code{exit(0)}

@item @code{-w}, @code{--nowarn}
don't display warning messages

By default the translator displays warning messages which reflect
potential errors and non-standard features used in the source Algol
program.
@end table

To translate a program written in @w{Algol 60} you need to prepare the
program in a plain text file and specify the name of that file in the
command line. If the name of the input text file is not specified, the
translator uses the standard input by default.

Note that the translator reads the input file @emph{twice}, therefore
this file can be only a regular file, but not a pipe, terminal input,
etc. Thus, if the standard input is used, it should be redirected to
a regular file.

For one run the translator is able to process only one input text file.

@node Example
@chapter Usage Example

The following example shows how you may use the MARST translator in
most practical cases.

At first, you prepare a source @w{Algol 60} program, say, in a text
file named @code{hello.alg}:

@sp 1
@example
begin
   outstring(1, "Hello, world!\n")
end
@end example
@sp 1

@noindent
Then you translate this program to the C programming language:

@sp 1
@example
marst hello.alg -o hello.c
@end example
@sp 1

@noindent
and get the text file named @code{hello.c}, which you need to compile
and link in an usual way (remember about specifying Algol and math
libraries for the linker):

@sp 1
@example
gcc hello.c -lalgol -lm -o hello
@end example
@sp 1

@noindent
And finally, you run executable

@sp 1
@example
./hello
@end example
@sp 1

@noindent
and see what you have. That's all.

@node Language
@chapter Input Language

The input language of the MARST translator is a hardware representation
of the reference language @w{Algol 60} described in the following IFIP
document:

Modified Report on the Algorithmic Language @w{ALGOL 60}.
@i{The Computer Journal}, @w{Vol. 19}, @w{No. 4}, @w{Nov. 1976},
@w{pp. 364---79}. (This document is an official IFIP standard. It is
@emph{not} part of GNU MARST.)

Source @w{Algol 60} program is coded as a plain text file using ASCII
character set.

Basic symbols should be coded as follows:

@ifnottex
@example
Basic symbol            Hardware representation
-----------------------------------------------
a, b, ..., z            a, b, ..., z
A, B, ..., Z            A, B, ..., Z
0, 1, ..., 9            0, 1, ..., 9
+                       +
-                       -
x                       *
/                       /
integer division        %
exponentiation          ^ (or **)
<                       <
not greater             <=
=                       =
not less                >=
>                       >
not equal               !=
equivalence             ==
implication             ->
or                      |
and                     &
not                     !
,                       ,
.                       .
ten (10)                # (pound sign)
:                       :
;                       ;
:=                      :=
(                       (
)                       )
[                       [
]                       ]
opening quote           "
closing quote           "
array                   array
begin                   begin
Boolean                 Boolean (or boolean)
code                    code
comment                 comment
do                      do
else                    else
end                     end
false                   false
for                     for
go to                   go to (or goto)
if                      if
integer                 integer
label                   label
own                     own
procedure               procedure
real                    real
step                    step
string                  string
switch                  switch
then                    then
true                    true
until                   until
value                   value
while                   while
@end example
@end ifnottex

@iftex
@tex
$$\vbox
{
\settabs 5 \columns
\+ Basic symbol & Representation & Basic symbol & Representation & \cr
\+ \hrulefill & \hrulefill & \hrulefill & \hrulefill & \cr
\+ $a, b, \dots, z$ & \tt{a}, \tt{b}, \dots, \tt{z} & ] & \tt{]}  & \cr
\+ $A, B, \dots, Z$ & \tt{A}, \tt{B}, \dots, \tt{Z} & ` & \tt{"}  & \cr
\+ $0, 1, \dots, 9$ & \tt{0}, \tt{1}, \dots, \tt{9} & ' & \tt{"}  & \cr
\+ $+$       & \tt{+}           & \bf{array}     & \tt{array}     & \cr
\+ $-$       & \tt{-}           & \bf{begin}     & \tt{begin}     & \cr
\+ $\times$ & \tt{*} & \bf{Boolean}  & \tt{Boolean} (\tt{boolean})& \cr
\+ $/$       & \tt{/}           & \bf{code}      & \tt{code}      & \cr
\+ $\div$    & \tt{\%}          & \bf{comment}   & \tt{comment}   & \cr
\+ $\uparrow$ & \tt{\^{}} (\tt{**}) & \bf{do}    & \tt{do}        & \cr
\+ $<$       & \tt{<}           & \bf{else}      & \tt{else}      & \cr
\+ $\leq$    & \tt{<=}          & \bf{end}       & \tt{end}       & \cr
\+ $=$       & \tt{=}           & \bf{false}     & \tt{false}     & \cr
\+ $\geq$    & \tt{>=}          & \bf{for}       & \tt{for}       & \cr
\+ $\neq$    & \tt{!=}   & \bf{go to}     & \tt{go to} (\tt{goto})& \cr
\+ $\equiv$  & \tt{==}          & \bf{if}        & \tt{if}        & \cr
\+ $\supset$ & \tt{->}          & \bf{integer}   & \tt{integer}   & \cr
\+ $\vee$    & \tt{|}           & \bf{label}     & \tt{label}     & \cr
\+ $\wedge$  & \tt{\&}          & \bf{own}       & \tt{own}       & \cr
\+ $\neg$    & \tt{!}           & \bf{procedure} & \tt{procedure} & \cr
\+ $,$       & \tt{,}           & \bf{real}      & \tt{real}      & \cr
\+ $.$       & \tt{.}           & \bf{step}      & \tt{step}      & \cr
\+ $_{10}$   & \tt{\#}          & \bf{string}    & \tt{string}    & \cr
\+ $:$       & \tt{:}           & \bf{switch}    & \tt{switch}    & \cr
\+ $;$       & \tt{;}           & \bf{then}      & \tt{then}      & \cr
\+ $:=$      & \tt{:=}          & \bf{true}      & \tt{true}      & \cr
\+ $($       & \tt{(}           & \bf{until}     & \tt{until}     & \cr
\+ $)$       & \tt{)}           & \bf{value}     & \tt{value}     & \cr
\+ $[$       & \tt{[}           & \bf{while}     & \tt{while}     & \cr
}
$$
@end tex
@end iftex

Any symbol can be surrounded by any number of white-space characters
(i.e. by spaces, @code{HT}, @code{CR}, @code{LF}, @code{FF}, and
@code{VT}). However, any multi-character symbol should contain
no white-space characters. Moreover, a letter sequence is recognized as
a keyword if and only if there is no letter or digit that immediately
precedes or follows the sequence (except the keyword @code{@w{go to}}
that may contain zero or more spaces between @code{go} and @code{to}).

@page

For example:

@table @code
@item ... 123 then abc ...
@code{then} will be recognized as @b{then} symbol
@item ... 123then abc ...
@item ... 123 thenabc ...
@code{then} will be recognized as letters @i{t}, @i{h}, @i{e}, @i{n},
but not as @b{then} symbol
@item ... 123 th en abc ...
@code{th en} will be recognized as letters @i{t}, @i{h}, @i{e}, @i{n}
@end table

Note that identifiers and numbers can contain white-space characters.
This feature may be used in the case when an identifier is the same as
keyword. For example, identifier @i{label} may be coded as
@code{@w{la bel}} or @code{@w{lab el}}. Note also that white-space
characters are non-significant (except when they are used within
character strings), so @code{abc} and @code{@w{a b c}} denote the same
identifier @i{abc}.

Identifiers and numbers can consist of @emph{arbitrary} number of
characters, all of which (except internal white-space characters) are
significant.

All letters are case sensitive (except the first "b" in the keyword
@b{Boolean}). This means that @code{abc} and @code{ABC} are different
identifiers, and @code{Then} will not be recognized as the keyword
@b{then}.

Quoted character string are coded in the C style. For example:

@sp 1
@example
outstring(1, "This\tis a string\n");

outstring(1, "This\tis a st"   "ring\n");

outstring(1, "This\tis all one st"
   "ring\n");
@end example
@sp 1

Within a string (i.e. between double quotes that enclose the string
body) escape sequences may be used (as @code{\t} and @code{\n} in the
example above). Double quote and backslash within string should be
coded as @code{\"} and @code{\\} respectively. Between parts of
a string any number of white-space characters is allowed.

Except coding character strings there are no other differences between
the syntax of the reference language and the syntax of GNU MARST input
language.

Note that there are some differences between the Revised Report on
@w{Algol 60} and the Modified Report on @w{Algol 60}, because the
latter is a result of application of the following IFIP document to the
former:

@i{@w{R. M. De Morgan}, @w{I. D. Hill}, and @w{B. A. Wichmann.}}
A Supplement to the @w{ALGOL 60} Revised Report. @i{The Computer
Journal}, @w{Vol. 19}, @w{No. 3}, 1976, @w{pp. 276---88}.
(This document is an official IFIP standard. It is @emph{not} part of
GNU MARST.)

@page

@iftex
To illustrate the input language of the MARST translator, consider the
following procedure written in the @emph{reference} language:

@sp 1
@tex
{
\parskip 0 pt
\parindent 0 pt
\leftskip 12 pt
\bf{real} \bf{procedure} \it{euler}\rm{(}\it{fct}\rm{,} \it{eps}\rm{,}
\it{tim}\rm{);}

\leftskip 24 pt
\bf{value} \it{eps}\rm{,} \it{tim}\rm{;}

\leftskip 24 pt
\bf{real} \bf{procedure} \it{fct}\rm{;} \bf{real} \it{eps}\rm{;}
\bf{integer} \it{tim}\rm{;}

\bf{comment} \it{euler computes the sum of fct}\rm{(}\it{i}\rm{)}
\it{for i from zero up to infinity by means of a suitably refined euler
transformation. The summation is stopped as soon as tim times in
succession the absolute value of the terms of the transformed series
are found to be less than eps. Hence one should provide a function fct
with one integer argument}\rm{,} \it{an upper bound eps}\rm{,} \it{and
an integer tim. euler is particularly efficient in the case of a slowly
convergent or divergent alternating series}\rm{;}

\bf{begin}

\bf{integer} \it{i}\rm{,} \it{k}\rm{,} \it{n}\rm{,} \it{t}\rm{;}

\bf{array} \it{m}\rm{[0:15];}

\bf{real} \it{mn}\rm{,} \it{mp}\rm{,} \it{ds}\rm{,} \it{sum}\rm{;}

\it{n} \rm{:=} \it{t} \rm{:= 0;}

\it{m}\rm{[0] :=} \it{fct}\rm{(0);} \it{sum} \rm{:=} \it{m}\rm{[0]/2;}

\bf{for} \it{i} \rm{:= 1,} \it{i} \bf{+ 1} \bf{while} \it{t} \rm{$<$}
\it{tim} \bf{do}

\leftskip 36 pt
\bf{begin}

\it{mn} \rm{:=} \it{fct}\rm{(}\it{i}\rm{);}

\bf{for} \it{k} \rm{:= 0} \bf{step} \rm{1} \bf{until} \it{n} \bf{do}

\leftskip 48 pt
\bf{begin}

\it{mp} \rm{:= (}\it{mn} \rm{+} \it{m}\rm{[}\it{k}\rm{])/2;}

\it{m}\rm{[}\it{k}\rm{] :=} \it{mn}\rm{;} \it{mn} \rm{:=} \it{mp}

\bf{end} \it{means}\rm{;}

\leftskip 36 pt
\bf{if} \it{abs}\rm{(}\it{mn}\rm{)} \rm{$<$}
\it{abs}\rm{(}\it{m}\rm{[}\it{n}\rm{]) $\wedge$} \it{n} \rm{$<$ 15}
\bf{then}

\leftskip 48 pt
\bf{begin}

\it{ds} \rm{:=} \it{mn}\rm{/2;} \it{n} \rm{:=} \it{n} \rm{+ 1;}

\it{mn}\rm{[}\it{n}\rm{] :=} \it{mn}

\bf{end} \it{accept}\rm{;}

\leftskip 36 pt
\bf{else}

\leftskip 48 pt
\it{ds} \rm{:=} \it{mn}\rm{;}

\leftskip 36 pt
\it{sum} \rm{:=} \it{sum} \rm{+} \it{ds}\rm{;}

\it{t} \rm{:=} \bf{if} \it{abs}\rm{(}\it{ds}\rm{) $<$} \it{eps}
\bf{then} \it{t} \rm{+ 1} \bf{else} \rm{0}

\bf{end}\rm{;}

\leftskip 24 pt
\it{euler} \rm{:=} \it{sum}

\bf{end} \it{euler}\rm{;}

}
@end tex

This procedure may be coded using GNU MARST representation as follows:

@sp 1
@example
real procedure euler(fct, eps, tim);
   value eps, tim;
   real procedure fct; real eps; integer tim;
   comment euler computes the sum of fct(i) for i from zero up to
   infinity by means of a suitably refined euler transformation. The
   summation is stopped as soon as times in succession the absolute
   value of the terms of the transformed series are found to be less
   than eps. Hence one should provide a function fct with one integer
   argument, an upper bound eps, and an integer tim. euler is
   particularly efficient in the case of a slowly convergent or
   divergent alternating series;
   begin
   integer i, k, n, t;
   array m[0:15];
   real mn, mp, ds, sum;
   n := t := 0;
   m[0] := fct(0); sum := m[0] / 2;
   for i := 1, i+1 while t < tim do
      begin
      mn := fct(i);
      for k := 0 step 1 until n do
         begin
         mp := (mn + m[k]) / 2;
         m[k] := mn; mn := mp
      end means;
   if abs(mn) < abs(m[n]) & n < 15 then
      begin
      ds := mn / 2; n := n + 1;
      m[n] := mn
      end accept
   else
      ds := mn;
   sum := sum + ds;
   t := if abs(ds) < eps then t + 1 else 0
   end;
euler := sum
end euler;
@end example
@sp 1
@end iftex

@node Io
@chapter Input/Output

All input/output is performed by the standard @w{Algol 60} procedures.
GNU MARST implementation provides up to 16 input/output channels, which
have numbers 0, 1, @dots{}, 15. The channel 0 is always connected to
@code{stdin}, so only input from this channel is allowed. Similarly,
the channel 1 is always connected to @code{stdout}, so only output to
this channel is allowed. Other channels can be used for both input and
output. (The standard procedure @i{fault} uses the channel
@iftex
@tex
$\Sigma,$
@end tex
@end iftex
@ifnottex
<sigma>,
@end ifnottex
which is not available to the programmer. This latent channel is always
connected to @code{stderr}.)

Before Algol program startup all channels (except the channels 0 and 1)
are disconnected, i.e. no files are assigned to them.

If an input (output) is required by the Algol program from (to) the
channel @i{n}, the following actions occur:

@enumerate 1
@item
if the channel @i{n} is connected for output (input), the I/O routine
closes the file assigned to this channel, making it disconnected;
@item
if the channel @i{n} is disconnected, the I/O routine opens the
corresponding file in read (write) mode and assigns this file to the
channel, making it connected;
@item
finally, the I/O routine performs the input (an output) operation on
the channel @i{n}. If an end-of-file has been detected, the I/O routine
raises an error condition and terminates execution of the Algol
program.
@end enumerate

In order to determine the name of a file, which should be assigned to
the channel @i{n}, the I/O routine looks for an environment variable
named @code{FILE_n}. If such variable exists, its value is used as the
filename. Otherwise, its name (i.e. the character string
@code{"FILE_n"}) is used as the filename.

@node Extensions
@chapter Language Extensions

The MARST translator provides some extensions to the reference language
in order to make the package more convenient for the programmer.

@section Modular programming

The feature of modular programming can be illustrated by the following
example:

@ifnottex
@example
First file                    Second file
----------------------------------------------------
procedure one(a, b);          procedure one(a, b);
value a, b; real a, b;        value a, b; real a, b;
begin                         code;
      ...
end;                          procedure two(x, y);
                              value x, y; real x, y;
procedure two(x, y);          code;
value x, y; real x, y;
begin                         begin
      ...                           <main program>
end;                          end
@end example
@end ifnottex

@iftex
@tex
$$\vbox
{
\settabs 3 \columns
\+ First file & Second file & \cr
\+ \hrulefill & \hrulefill & \cr
\+ \tt{procedure one(a, b);}       & \tt{procedure one(a, b);}     &\cr
\+ \tt{value a, b; real a, b;}     & \tt{value a, b; real a, b;}   &\cr
\+ \tt{begin}                      & \tt{code;}                    &\cr
\+ \tt{. . . . . .}                &                               &\cr
\+ \tt{end;}                       & \tt{procedure two(x, y);}     &\cr
\+                                 & \tt{value x, y; array x, y;}  &\cr
\+ \tt{procedure two(x, y);}       & \tt{code;}                    &\cr
\+ \tt{value x, y; array x, y;}    &                               &\cr
\+ \tt{begin}                      & \tt{begin}                    &\cr
\+ \tt{. . . . . .}                & \tt{<main program>}           &\cr
\+ \tt{end;}                       & \tt{end;}                     &\cr
}
$$
@end tex
@end iftex

The procedures @i{one} and @i{two} in the first file are called
@dfn{precompiled procedures}. Declarations of precompiled procedures
should be outside of the main program block or compound statement. The
procedures @i{one} and @i{two} in the second file are called @dfn{code
procedures}; they have the keyword @b{code} rather than a procedure
body statement. Declarations of code procedures also should be outside
of the main program block or compound statement.

This mechanism allows translating precompiled procedures independently
on the main program. Moreover, precompiled procedures may be programmed
in any other C-compatible programming language. The programmer can
consider that directly before Algol program startup declarations of all
precompiled procedures are substituted into the file, which contains
the main program (the second file in the example above), replacing
declarations of corresponding code procedures.

Each code procedure should have the same procedure heading as the
corresponding precompiled procedure (however, formal parameter names
may differ). Note that mismatched procedure headings cannot be detected
by the MARST translator, because they are placed in different files.

@section Pseudo procedure @i{inline}

The pseudo procedure @i{inline} has the following (implicit) heading:

@sp 1
@example
procedure inline(str);
string str;
@end example
@sp 1

A procedure statement that refers to the @i{inline} pseudo procedure is
translated into the code, which is the string @i{str} without enclosing
quotes. For example:

@ifnottex
@example
Source program                  Output C code
------------------------------------------------
. . .                           . . .
a := 1;                         dsa_0->a_5 = 1;
b := 2;                         dsa_0->b_8 = 2;
inline("printf(\"OK\");");      printf("OK");
c := 3;                         dsa_0->c_4 = 3;
. . .                           . . .
@end example
@end ifnottex

@iftex
@tex
$$\vbox
{
\settabs
\+ \tt(.............................) & \tt(..............) & \cr
\+ Source program & Output C code & \cr
\+ \hrulefill & \hrulefill & \cr
\+ \tt{. . .}                       & \tt{. . .} & \cr
\+ \tt{a := 1;}                     & \tt{dsa\_0->a\_5 = 1;} & \cr
\+ \tt{b := 2;}                     & \tt{dsa\_0->b\_8 = 2;} & \cr
\+ \tt{inline("printf($\backslash$"OK$\backslash$");");}
& \tt{printf("OK");} & \cr
\+ \tt{c := 3;}                     & \tt{dsa\_0->c\_4 = 3;} & \cr
\+ \tt{. . .}                       & \tt{. . .} & \cr
}
$$
@end tex
@end iftex

The procedure statement @i{inline} may be used anywhere in the program
as an oridinary Algol statement.

@section Pseudo procedure @i{print}

The pseudo procedure @i{print} is intended mainly for test printing
(because the standard Algol input/output is out of any criticism). This
procedure has an unspecified heading and variable parameter list. For
example:

@sp 1
@example
real a, b; integer c; Boolean d;
array u, v[1:10], w[-5:5,-10:10];
. . .
print(a, b, u);
print(c);
. . .
print("test shot", (a+b)*c, !d & u[1] > v[1], u, v, w);
. . .
@end example
@sp 1

Each actual parameter passed to the pseudo procedure @i{print} is sent
to the channel number 1 (@code{stdout}) in a printable format.

@node Converter
@chapter Converter Utility

The Algol converter utility is MACVT. It is an auxiliary program, which
is intended for converting @w{Algol 60} programs from some other
representation to the MARST representation. Such conversion is usually
needed when existing Algol programs should be adjusted in order to
translate them with GNU MARST.

MACVT is not a translator itself. This program just reads an original
code of @w{Algol 60} program from the input text file, converts main
symbols to the MARST representation (see Section 5. Input Language),
and writes the resulting code on the output text file. It is assumed
that the output code produced by MACVT will be later translated by
MARST in an usual way. Note that MACVT performs no syntax checking.

The input language understood by MACVT differs from the GNU MARST input
language only in representation of basic symbols. Should note that in
this sense GNU MARST input language is a subset of the MACVT input
language.

Representation of basic symbols implemented in MACVT is based mainly on
well known (in 1960s) @w{Algol 60} compiler developed by IBM first for
IBM 7090 and later for System/360. This representation may be
considered as a non-official standard, because it was widely used at
the time, when @w{Algol 60} was an actual programming language.

To invoke the MACVT converter the following syntax should be used:

@code{macvt} [@i{options} ...] [@i{filename}]

Options:

@table @asis
@item @code{-c}, @code{--classic}
use classic representation

This option is used by default until other representation is chosen.
It assumes that the input Algol 60 program is coded using a classic
representation: all white-space characters are non-significant (except
within quoted character strings) and all keywords are enclosed within
apostrophes. For details see below.

@item @code{-f}, @code{--free-coding}
use free representation

This option allows not to enclose keywords within apostrophes.
However, in this case white-space characters should not be used within
multi-character basic symbols. See below for details.

@item @code{-h}, @code{--help}
display help information and @code{exit(0)}

@item @code{-i}, @code{--ignore-case}
convert letters to lower case

If this option is specified, all letters (except within comments and
character strings) are converted to lower case, i.e. conversion is
case-insensitive.

@item @code{-m}, @code{--more-free}
use more free representation

This option is the same as @code{--free-coding}, but additionally
keywords for arithmetic, logical, and relational operators can be coded
without apostrophes. For details see below.

@item @code{-o} @i{filename}, @code{--output} @i{filename}
name of an output text file, on which the converter writes the
converted @w{Algol 60} program

If this option is not specified, the converter uses the standard output
by default.

@item @code{-s}, @code{--old-sc}
use old (classic) semicolon representation

This option allows the converter recognizing the diphthong ., (point
and comma) as the semicolon (including its usage for terminating
comment sequences).

@item @code{-t}, @code{--old-ten}
use old (classic) ten symbol representation

This option allows the converter recognizing a single apostrophe, when
it is followed by @code{+}, @code{-}, or digit, as the ten symbol.

@item @code{-v}, @code{--version}
display the converter version and @code{exit(0)}
@end table

To convert an Algol 60 program you need to prepare it in a plain text
file and specify the name of that file in the command line. If the name
of the input text file is not specified, the converter uses the
standard input by default.

For one run the converter is able to process only one input text file.

In the table shown on the next page one or more valid representation
are given for each basic symbol. Besides, the following additional
conventions are assumed:

@enumerate 1
@item
Classic (apostrophized) form of keywords and some other basic symbols
are allowed for any (i.e. for classic as well as free) representation.
@item
In case of classic representation all white-space characters (except
their usage within comments and quoted strings) are ignored anywhere.
@item
Basic symbol enclosed by apostrophes may contain white-space characters,
which are ignored. Besides, all letters are case-insensitive.
@item
Basic symbols may be coded in the free form (without apostrophes) only
if the free representation (@code{--free-coding} or @code{--more-free})
is used.
@item
In case of free representation any multi-character basic symbol should
contain no white-space characters.
@item
Free form of keywords that denote arithmetic, logical, and relational
operators (e.g. @code{greater} instead @code{'greater'}) is allowed
only if the option @code{--more-free} is used.
@item
Single apostrophe is recognized as ten symbol only if the option
@code{--old-ten} is used. Note that in this case the sequence
@code{'10'} is not recognized as ten symbol.
@item
Diphthong ., (point and comma) is recognized as semicolon only in the
case if the option @code{--old-sc} is used.
@item
If an opening quote is coded as @code{"} (double quote), the
corresponding closing quote should be coded as @code{"} (double quote).
If an opening quote is coded as @code{`} (diacritic mark), the
corresponding closing quote should be coded as @code{'} (single
apostrophe).
@end enumerate

@ifnottex
@example
   Basic symbol            Extended hardware representation
   -----------------------------------------------------------
   a, b, ..., z            a, b, ..., z
   A, B, ..., Z            A, B, ..., Z
   0, 1, ..., 9            0, 1, ..., 9
   +                       +
   -                       -
   x                       *
   /                       /
   integer division        %                    '/'      'div'
   exponentiation          ^     **             'power'  'pow'
   <                       <                    'less'
   not greater             <=                   'notgreater'
   =                       =                    'equal'
   not less                >=                   'notless'
   >                       >                    'greater'
   not equal               !=                   'notequal'
   equivalence             ==                   'equiv'
   implication             ->                   'impl'
   or                      |                    'or'
   and                     &                    'and'
   not                     !                    'not'
   ,                       ,
   .                       .
   ten (10)                #     '              '10'
   :                       :     ..
   ;                       ;     .,
   :=                      :=    .=    ..=
   (                       (
   )                       )
   [                       [     (/
   ]                       ]     /)
   opening quote           "     `
   closing quote           "     '
   array                                        'array'
   begin                                        'begin'
   Boolean                                      'boolean'
   code                                         'code'
   comment                                      'comment'
   do                                           'do'
   else                                         'else'
   end                                          'end'
   false                                        'false'
   for                                          'for'
   go to                                        'goto'
   if                                           'if'
   integer                                      'integer'
   label                                        'label'
   own                                          'own'
   procedure                                    'procedure'
   real                                         'real'
   step                                         'step'
   string                                       'string'
   switch                                       'switch'
   then                                         'then'
   true                                         'true'
   until                                        'until'
   value                                        'value'
   while                                        'while'
@end example
@end ifnottex

@iftex
@tex
$$\vbox
{
\settabs
\+ \tt{............} & \tt{.......................}
   & \tt{.............} & \tt{............} & \cr
\+ Basic symbol & Representation & Basic symbol & Representation & \cr
\+ \hrulefill & \hrulefill & \hrulefill & \hrulefill & \cr
\+ $a, b, \dots, z$ & \tt{a}, \tt{b}, \dots, \tt{z}
   & ] & \tt{]\ \ \ \ \ \ /)} & \cr
\+ $A, B, \dots, Z$ & \tt{A}, \tt{B}, \dots, \tt{Z}
   & ` & \tt{"\ \ \ \ \ \ `} & \cr
\+ $0, 1, \dots, 9$ & \tt{0}, \tt{1}, \dots, \tt{9}
   & ' & \tt{'\ \ \ \ \ \ '} & \cr
\+ $+$       & \tt{+}           & \bf{array}     & \tt{'array'}   & \cr
\+ $-$       & \tt{-}           & \bf{begin}     & \tt{'begin'}   & \cr
\+ $\times$  & \tt{*}           & \bf{Boolean}   & \tt{'boolean'} & \cr
\+ $/$       & \tt{/}           & \bf{code}      & \tt{'code'}    & \cr
\+ $\div$    & \tt{\%\ \ \ \ \ \ '/'\ \ \ \ \ \ 'div'}
   & \bf{comment}   & \tt{'comment'} & \cr
\+ $\uparrow$ & \tt{\^{}\ \ **\ \ 'power'\ \ 'pow'}
   & \bf{do}        & \tt{'do'} & \cr
\+ $<$       & \tt{<\ \ \ \ \ \ 'less'}
   & \bf{else}      & \tt{'else'} & \cr
\+ $\leq$    & \tt{<=\ \ \ \ \ 'notgreater'}
   & \bf{end}       & \tt{'end'} & \cr
\+ $=$       & \tt{=\ \ \ \ \ \ 'equal'}
   & \bf{false}     & \tt{'false'} & \cr
\+ $\geq$    & \tt{>=\ \ \ \ \ 'notless'}
   & \bf{for}       & \tt{'for'} & \cr
\+ $\neq$    & \tt{!=\ \ \ \ \ 'notequal'}
   & \bf{go to}     & \tt{'goto'} & \cr
\+ $\equiv$  & \tt{==\ \ \ \ \ 'equiv'}
   & \bf{if}        & \tt{'if'} & \cr
\+ $\supset$ & \tt{->\ \ \ \ \ 'impl'}
   & \bf{integer}   & \tt{'integer'} & \cr
\+ $\vee$    & \tt{|\ \ \ \ \ \ 'or'}
   & \bf{label}     & \tt{'label'} & \cr
\+ $\wedge$  & \tt{\&\ \ \ \ \ \ 'and'}
   & \bf{own}       & \tt{'own'} & \cr
\+ $\neg$    & \tt{!\ \ \ \ \ \ 'not'}
   & \bf{procedure} & \tt{'procedure'} & \cr
\+ $,$       & \tt{,}           & \bf{real} & \tt{'real'} & \cr
\+ $.$       & \tt{.}           & \bf{step} & \tt{'step'} & \cr
\+ $_{10}$   & \tt{\#\ \ \ \ \ \ '\ \ \ \ \ \ \ \ '10'}
   & \bf{string}    & \tt{'string'} & \cr
\+ $:$       & \tt{:\ \ \ \ \ \ ..}
   & \bf{switch}    & \tt{'switch'} & \cr
\+ $;$       & \tt{;\ \ \ \ \ \ .,}
   & \bf{then}      & \tt{'then'} & \cr
\+ $:=$      & \tt{:=\ \ \ \ \ .=\ \ \ \ \ \ \ ..=}
   & \bf{true}      & \tt{'true'} & \cr
\+ $($       & \tt{(}           & \bf{until} & \tt{'until'} & \cr
\+ $)$       & \tt{)}           & \bf{value} & \tt{'value'} & \cr
\+ $[$       & \tt{[\ \ \ \ \ \ (/}
   & \bf{while}     & \tt{'while'} & \cr
}
$$
@end tex
@end iftex

@page

To illustrate what the MACVT converter does, consider the following
@w{Algol 60} procedure, which is coded using an old (classic)
representation:

@sp 1
@example
'PROCEDURE'EULER(FCT,SUM,EPS,TIM).,'VALUE'EPS,TIM.,
'INTEGER' TIM., 'REAL' 'PROCEDURE' FCT., 'REAL' SUM, EPS.,
'COMMENT' EULER COMPUTES THE SUM OF FCT (I) FOR I
 FROM ZERO UP TO INFINITY BY MEANS OF A SUITABLY
 REFINED EULER TRANSFORMATION. THE SUMMATION IS
 STOPPED AS SOON AS TIM TIMES IN SUCCESSION THE ABSOLUTE
 VALUE OF THE TERMS OF THE TRANSFORMED SERIES IS
 FOUND TO BE LESS THAN EPS, HENCE ONE SHOULD PROVIDE
 A FUNCTION FCT WITH ONE INTEGER ARGUMENT, AN UPPER
 BOUND EPS, AND AN INTEGER TIM. THE OUTPUT IS THE SUM SUM.
 EULER IS PARTICULARLY EFFICIENT IN THE CASE OF A SLOWLY
 CONVERGENT OR DIVERGENT ALTERNATING SERIES.,
 'BEGIN''INTEGER' I,K,N,T.,'ARRAY' M(/0..15/).,
 'REAL' MN, MP, DS.,
  I.=N.=T.=0.,M(/0/).=FCT(0).,SUM.=M(/0/)/2.,
  NEXTTERM..I.=I+1.,MN.=FCT(1).,
    'FOR' K.=0'STEP'1'UNTIL'N'DO'
         'BEGIN' MP.=(MN+M(/K/))/2.,M(/K/).=MN.,
            MN.=MP'END'MEANS.,
    'IF' (ABS(MN)'LESS' ABS (M(/N/))'AND'N'LESS'15)'THEN'
         'BEGIN'DS.=MN/2.,N.=N+1.,
            M(/N/).=MN'END' ACCEPT
         'ELSE' DS.=MN.,
          SUM.=SUM+DS.,
         'IF' ABS(DS)'LESS'EPS'THEN'T.=T+1'ELSE'T.=0.,
         'IF'T'LESS'TIM'THEN''GOTO'NEXTTERM
         'END'EULER;
@end example
@sp 1

This code can be converted to the GNU MARST input language with the
following command:

@example
macvt -i -s euler.txt -o euler.alg
@end example

The verbatim result of conversion is the following:

@sp 1
@example
procedure euler(fct,sum,eps,tim);value eps,tim;
integer tim; real procedure fct; real sum, eps;
comment EULER COMPUTES THE SUM OF FCT (I) FOR I
 FROM ZERO UP TO INFINITY BY MEANS OF A SUITABLY
 REFINED EULER TRANSFORMATION .THE SUMMATION IS
 STOPPED AS SOON AS TIM TIMES IN SUCCESSION THE ABSOLUTE
 VALUE OF THE TERMS OF THE TRANSFORMED SERIES IS
 FOUND TO BE LESS THAN EPS, HENCE ONE SHOULD PROVIDE
 A FUNCTION FCT WITH ONE INTEGER ARGUMENT, AN UPPER
 BOUND EPS, AND AN INTEGER TIM .THE OUTPUT IS THE SUM SUM
 .EULER IS PARTICULARLY EFFICIENT IN THE CASE OF A SLOWLY
 CONVERGENT OR DIVERGENT ALTERNATING SERIES;
 begin integer i,k,n,t;array m[0:15];
 real mn, mp, ds;
  i:=n:=t:=0;m[0]:=fct(0);sum:=m[0]/2;
  nextterm:i:=i+1;mn:=fct(1);
    for k:=0 step 1 until n do
         begin mp:=(mn+m[k])/2;m[k]:=mn;
            mn:=mp end means;
    if (abs(mn)< abs (m[n])&n<15)then
         begin ds:=mn/2;n:=n+1;
            m[n]:=mn end accept
         else ds:=mn;
          sum:=sum+ds;
         if abs(ds)<eps then t:=t+1 else t:=0;
         if t<tim then go to nextterm
         end euler;
@end example
@sp 1

@node Thanks
@unnumbered Acknowledgments

The author thanks Erik Sch@"onfelder <@email{schoenfr@@gaertner.de}>
for a lot of useful advices and testing MARST with real Algol 60
programs. The author also thanks Bernhard Treutwein
<@email{Bernhard.Treutwein@@Verwaltung.Uni-Muenchen.DE}> for a great
help in preparing the MARST documentation.

The author especially thanks Brian Wichmann
<@email{brian.wichmann@@totalise.co.uk}> for providing a set of
Algol 60 validation tests.

@bye
