The author thanks Erik Sch@"onfelder <schoenfr@gaertner.de> for a lot of useful advices and especially for testing MARST with real Algol 60 programs. The author also thanks Bernhard Treutwein <Bernhard.Treutwein@Verwaltung.Uni-Muenchen.DE> for great help in preparing MARST documentation.
GNU MARST is an Algol-to-C translator. It automatically translates programs written in the algorithmic language Algol 60 into the ANSI C programming language.
Processing scheme can be understood as the following:
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 +-------------+
where:
algol.h
stdio.h
, stdlib.h
, etc.), however, no other headers are
used explicitly in the generated code. This file is a part of the MARST
package;
algol.h
);
libalgol.a
;
In order to install the MARST package under GNU/Linux the standard installation
procedure should be used. For details see the file INSTALL
included into
the distribution.
As a result of installation the following four components will be installed:
marst
usr/local/bin
;
macvt
usr/local/bin
;
algol.h
usr/local/include
and/or usr/include
;
libalgol.a
usr/local/lib
.
In order to invoke the MARST translator the following syntax should be used:
marst
[options ...] [filename]
Options:
-d
, --debug
-e
nnn, --error-max
nnn
-e 0
is used and means that the translation is continued
until the end of the input file.
-h
, --help
exit(0)
-l
nnn, --linewidth
nnn
-l 72
is used.
Note that actual line width may happen to be greater than nnn, because the
translator is not able to break the output text at any place. However, this
happens relatively seldom.
-o
filename, --output
filename
-t
, --notimestamp
-v
, --version
exit(0)
-w
, --nowarn
In order to translate a program written in Algol 60, it should be prepared as a plain text file, and the name of this file should be specified 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 twice, therefore this file should be only 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.
The following example shows how the MARST translator may be used in most cases.
At first we prepare source Algol 60 program, say, in the text file named `sample.alg':
begin outstring(1, "Hello, world\n") end
Now we translate this program to the C programming language:
marst sample.alg -o sample.c
and get the text file named `sample.c', which then we compile and link in the usual way (we should remember about Algol and math libraries):
gcc sample.c -lalgol -lm
Finally, we run executable
./sample
and see what we get. That's all.
The input language of the MARST translator is hardware representation of the reference language Algol 60 as described in the following IFIP document (1):
Modified Report on the Algorithmic Language ALGOL 60. The Computer Journal, Vol. 19, No. 4, Nov. 1976, pp. 364--79. (This document is an official IFIP standard. It is not a part of the MARST package.)
Source Algol 60 program is coded as a plain text file using ASCII character set.
Basic symbols should be coded as shown in the following table:
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
Any symbol can be surrounded by any number of white-space characters (i.e. by
spaces, HT
, CR
, LF
, FF
, and 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
`go to' that may contain zero or more spaces between `go' and
`to').
For example:
... 123 then abc ...
... 123then abc ...
... 123 thenabc ...
... 123 th en abc ...
Note that identifiers and numbers can contain white-space characters. This feature may be used in that case if an identifier is the same as keyword. For example, identifier label should be coded as `la bel' or `lab el'. Note also that white-space characters are not significant (except their use within character strings), so `abc' and `a b c' denote the same identifier abc.
All letters are case sensitive (except the first "b" in the keyword Boolean). This means that `abc' and `ABC' are different identifiers, and `Then' will not be recognized as the keyword then.
Each identifier or number can contain up to 100 characters (except internal white-space characters).
Quoted character string are coded in the C style. For 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");
Within a string (i.e. between double quotes that enclose the string body) escape sequences may be used (as `\t' and `\n' in the example above). Double quote and backslash within string should be coded as `\"' and `\\' respectively. Between parts of a string any number of white-space characters is allowed.
Except coding character strings and limitation on length of identifiers and numbers, there are no other differences between the syntax of the reference language and the syntax of the MARST input language.
Note that there are some differences between the Revised Report on Algol 60 and the Modified Report on Algol 60, because the latter is a result of application of the following IFIP document to the former:
R. M. De Morgan, I. D. Hill, and B. A. Whichman. A Supplement to the ALGOL 60 Revised Report. The Computer Journal, Vol. 19, No. 3, 1976, pp. 276--88. (This document is an official IFIP standard. It is not a part of the MARST package.)
@ifnotinfo
In order to illustrate what is the input language of the MARST translator let's consider the following procedure, which is written in the reference language:
This procedure may be coded using MARST representation as the following:
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;
All input/output is performed by standard Algol 60 procedures.
The MARST implementation provides up to 16 input/output channels, which have
numbers 0, 1, ..., 15. The channel number 0 is always connected to
stdin
, so only input from this channel is allowed. Analogously, the
channel number 1 is always connected to stdout
, so only output to this
channel is allowed. Other channels allow both input and output.
(The standard procedure fault uses the channel number
which is not available to the programmer. This latent channel is always
connected to stderr
.)
Before Algol program startup all channels (except channels number 0 and 1) are disconnected, i.e. no files are assigned to them.
If input (output) is required by the Algol program from (to) the channel number n, the following actions are taken:
In order to determine the name of file, which should be assigned to the channel
number n, the I/O routine checks for environment variable named
`FILE_n'. If such variable exists, its value is used as filename.
Otherwise, its name (i.e. the character string "FILE_n"
) is used as
filename.
The MARST translator provides some extensions of the reference language in order to make the package be more convenient for the programmer.
The feature of modular programming can be illustrated by the following 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
The procedures one and two in the first file are called precompiled procedures. Declarations of precompiled procedures should be outside of main program block or compound statement. The procedures one and two in the second file are called code procedures; they have the keyword code instead a procedure body statement. Declarations of code procedures also should be outside of main program block or compound statement.
This mechanism allows translating precompiled procedures independently from 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 main program (the second file in the example above), instead declarations of corresponding code procedures.
Each code procedure should have the same procedure heading as the corresponding precompiled procedure (however, names of parameters may be altered). Note that mismatched procedure headings can't be detected by the MARST translator, because they are placed in different files.
The pseudo procedure inline has the following (implicit) heading:
procedure inline(str); string str;
A procedure statement that refers to the inline pseudo procedure is translated into the code, which is the string str without enclosing quotes. For 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; . . . . . .
Procedure statement inline may be used anywhere in the program as an oridinary Algol statement.
The pseudo procedure print is intended mainly for test printing (because standard Algol input/output is out of criticism). This procedure has unspecified heading and variable parameter list. For 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); . . .
Each actual parameter passed to the pseudo procedure print is sent to the
channel number 1 (stdout
) using printable format.
Algol converter utility is MACVT. It is an auxiliary program, which is intended for converting 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 MARST.
MACVT is not a translator itself. This program just reads original code of Algol 60 program from the input text file, converts main symbols to the MARST representation (see Section 5. Input Language), and writes resulting code to the output text file. It is assumed that the output code produced by MACVT will be later translated by MARST in usual way. Note that MACVT performs no syntax checking.
Input language understood by MACVT differs from the MARST input language only in representation of basic symbols. Should note that in this sense the 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) Algol 60 compiler developed by IBM first for IBM 7090 and later for System/360. This representation may be considered as non-official standard, because it was widely used at that time, when Algol 60 was actual programming language.
In order to invoke the MACVT converter the following syntax should be used:
macvt
[options ...] [filename]
Options:
-c
, --classic
-f
, --free-coding
-h
, --help
exit(0)
-i
, --ignore-case
-m
, --more-free
--free-coding
, but additionally keywords for
arithmetic, logical, and relational operators can be coded without apostrophes.
For details see below.
-o
filename, --output
filename
-s
, --old-sc
-t
, --old-ten
+
, -
, or digit) as ten symbol.
-v
, --version
exit(0)
In order to convert an Algol 60 program, it should be prepared as a plain text file, and the name of this file should be specified 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. Thereto the following additional rules are assumed:
--free-coding
or --more-free
) is used.
greater
instead 'greater'
) is allowed only if the option
--more-free
is used.
--old-ten
is used. Note that in this case the sequence '10'
is
not recognized as ten symbol.
--old-sc
is used.
"
(double quote), the corresponding
closing quote should be coded as "
(double quote). If an opening quote
is coded as `
(diacritic mark), the corresponding closing quote should
be coded as '
(single apostrophe).
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'
In order to illustrate what the MACVT converter does, let us consider the following Algol 60 procedure, which is coded using old (classic) representation:
'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;
We can convert this code to the MARST input language by means of the following command:
macvt -i -s euler.alg -o euler1.alg
The verbatim result of conversion is the following:
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;
The verbatim reprint of this document may be obtained from the author's page dedicated to the MARST package at <http://mai2.rcnet.ru/~mao/marst/index.htm>.
This document was generated on 1 December 2000 using texi2html 1.56k.