Languages

Documentation

TREFOR

 

TREFOR (simple html version of the manual)

 

Trefor is a language and preprocessor for structured code design.
It works for Fortran, C, C++ and other languages.

    Features
  • Step-wise refinement of algorithms
  • Automatic documentation of the process of code design and creation of a "flow-chart" of the algorithms
  • Ease of debugging of new and especially of old codes

Trefor is designed primarily for the developmnet of sophistiacted and tricky algorithms with complicated logic.

When used for Fortran code development, Trefor is oriented to output fortran (*.f) in old fixed format, while
Trefor95 outputs files with extension *.f90 in free format.

This code is distributed under the terms of the GNU GPLv3 License.

 

Download:

Trefor95, Beta version (v6.0.0)

Trefor, Current version (v5.2.3)

Repository:

$ git clone http://dau.itep.ru/seb/trefor.git

For any questions please write to Sergei dot Blinnikov at itep dot ru

 

User's guide and references

S.I.Blinnikov 1

1 Institute for Theoretical and Experimental Physics, 117218, Moscow, Russia

 

A brief description is given of a preprocessor for structured
design of programs in Fortran or in other languages.

Introduction

More on Motivation

Input language format

The tree structure of the program design

A Nontrivial Example

Reserved words

Diagnostics

Building Trefor

 

Introduction

Trefor is a text processor for program design, the main feature
distinguishing it among other preprocessors being its ability to keep
the structure not only of the code itself but also of the process of
the construction, of the creation of a program. Using Trefor you
save the history of the stepwise refinement of the code design in the
same file which you submit to further compilation and then to run.
The graph of the process of the stepwise refinement, described in
many manuals on the structured programming, is actually a "Tree"
(in the sense of the Graph Theory). This Tree is saved in your file
by a special notation, bookkeeping the nodes of the tree and the paths
connecting them. The excessive information introduced thereby helps
you a lot not only in the process of the design, but also at the stage
of testing and then in supporting and modifying the old codes.

Trefor is extensively used in several institutes in USSR and Russia
since 1983
and it has withstood the test of time. Originally it was developed
for Fortran (Trefor = Tree Fortran), but now it is used also for C, C++,
REXX, Pascal, etc.

The origin of the Trefor goes back to the ideas developed mainly
by E.W. Dijkstra and his colleagues, see the books:

 

1.
Structured programming, O.-J. Dahl, E. W. Dijkstra & C. A. R.
Hoare. London, New York, Academic Press, 1972.
2.
Dijkstra, E. W.
A discipline of programming. Englewood Cliffs, N.J.
: Prentice-Hall, 1976.
3.
Wirth, N.
Algorithmen und Datenstrukturen. Stuttgart : Teubner, 1975.
4.
Wirth, N.
Algorithms + data structures=programs. Englewood Cliffs,
N.J. : Prentice-Hall, 1976.
5.
Gries, D.,
The science of programming. New York : Springer-Verlag,
1983.

Motivation for need of a special preprocessor comes from two sources.
The first is a need to manage a huge code with loops like
(DERIVED FROM HARWELL LIBRARY ROUTINE MA30A ):

C
C **********************************************
C **** START OF MAIN ELIMINATION LOOP ****
C **********************************************
C
DO 178 PIVOT = ISTART, ILAST
...

when the end of the loop
comes 600 lines of the code later

...
178 CONTINUE
C
C ********************************************
C **** END OF MAIN ELIMINATION LOOP ****
C ********************************************

Another source for the motivation of the Trefor development was the
necessity to transform algorithms written in pseudocodes into a machine
readable form automatically.

 

More on Motivation

Nowadays one can find on the Web many examples and tutorials on Structured programming concepts.
Here we present a very simple example taken from www.netvista.com/ssingh/vb_notes/session1/stprog.html

Topics covered-

  1. Importance of a structured program
  2. Top down approach, example

Why is structuring of a program
important?




Structuring a program
helps to break it down into understandable
chunks.
Structuring a program can
help in easier debugging and maintenance of the program,  as the
amount of details that the programmer has to understand for any one module
is less than dealing with the system as a
whole.
Modifications or
enhancements to a program become much easier due to modular approach and
better readability.


 
Top down
approach
- Structured programming results in top-down approach
with a hierarchy of levels.  The modules at each level are completely
independent, so that they can be handled separately. In this kind of approach,
the program is first designed in outline.  The outline design gives a
skeletal form of a program.  Every working program consists of three
modules in sequence -

1.  Initialization
routine for initializing variables, opening files etc.

2.  Main body of a program to perform actual processing.

3.  Termination routine where all tidy up procedures,
closing files and printing of totals and summaries is carried out.

Given below is a flow chart of a program, which will
explain what is structured programming and top-down approach.

This is a flow chart for a program, which accepts 10 numbers
from a   user and prints their sum and average.

image6e5 

imagedu7
               
image6mu
            image4e0
 


End of the example from www.netvista.com/ssingh/vb_notes/session1/stprog.html

Flowcharts are very useful for understanding, but in real life the
programmers, sitting in front of their terminals, do not draw them,
they just want to type their working codes
as fast as possible. Trefor allows you to preserve the advantages of
having a flow chart
when you are already typing your algorithm in the process of its
design.
We explain this rewriting in the Trefor language the example which is
given above as
a set of flowcharts.

program numbers;
    integer Tot;
    real Num, Sum, Avg;
     <*ini: Initialize *>
     <*get: Get and process numbers *>
     <*print: Print Results *>
stop;
end;
%_ini:
     Sum=0.;
     Avg=0.;
     Tot=0;
%_get:
  _repeat
    <*input: Input Num *>
    Sum=Sum+Num;
    Tot=Tot+1;
  _until Tot==10;
%_get_input:
  read(*,*) Num;
%_print:
  write(*,*)' Sum=',Sum;
  Avg=Sum/10.;
  write(*,*)' Avg=',Avg;

That's it. After feeding this script to the Trefor preprocessor we get a fully workable
Fortran code, while all two-dimensional structure contained in flowcharts is preserved.
We do not need here a design for "start" and "return" statements.

While designing a code in Trefor you just type in an appropriate
place (most convenient for you) some special combinations of symbols
which save the structure of the code. So the "flow chart" of the
code is saved in the code itself, automatically adjusting to any
changes which you might wish to introduce later.
We call such a code a "design tree".
More formal definitions are given below, but here we give just the
main idea.

At any place of the code, where one might draw a node in a flowchart
(all those squares, rhombuses, triangles etc...) we just type

       <*index: any explanatory text *>

and then continue with standard Fortran (or C, etc.) text.
At some moment,
when we are ready to refine what is going on
in the node with our "index", we type:

       %_ind1_ind2..._index:

where "ind1", "ind2", ... are the nodes in which
our node is embedded,
and so we formally introduce the stepwise refinement.

There are also other features, making Trefor convenient for writing long
and complicated codes: macros, alias names, special structure
constructions etc...

The original version of the Trefor was designed in 1983 by Sergei Weinstein
(CNIIKA, Moscow, USSR, now retired from Parametric Technology, Haifa, Israel)
and coded by Sergei Blinnikov (ITEP, Moscow, USSR)
in Fortran-IV (more primitive than Fortran-77). Some features like alias definitions
were added later by S.Blinnikov and O.Bartunov together with several versions
of wrappers for different OS. A C-version of the Trefor compiler was
coded by Vlad Popolitov (then at SAI, Moscow, Russia).
One should note that the original Trefor (actually Fortran) version of the preprocessor
is more robust and virtually free of bugs, while the C-version (which is coded
directly, not using the preprocessor) sometime may encounter problems on huge
input files (on order of 104 lines of code). Some improvemenst to MS Windows
version have been supplied by Yaroslav Urzhumov.

 

Input language format

To tell to the preprocessor, which language you wish to process just
type (in the text of the Trefor-program):

       _Fortran

or

       _REXX

       _Pascal

       _C

etc. You may use the mixture of different languages
in one file, if you wish it for some reason. If you type

       _Trefor

you return to the standard Trefor environment,
i.e., the preprocessor is
prepared to output Fortran text, and the input is to be in the
format where all operators are written from any column you like,
but they should be delimited by ";", and the labels should be
delimited by ":". The _Trefor
regime is assumed as default in the
beginning of any file submitted to the preprocessor.

Example 1.1

Pure Fortran text in input:

- - - - - - - - - - - - - - - - - - - - - - - - -


_FORTRAN
IF(A.GT.B)THEN
DO 25 I=1,N
Y(I,J)=Y(I,J)+Y(I,J+1)
25 CONTINUE
ENDIF


- - - - - - - - - - - - - - - - - - - - - - - - -

Then the output is almost the same: only one
comment is added:

- - - - - - - - - - - - - - - - - - - - - - - - -



C->Fortran section begins....
IF(A.GT.B)THEN
DO 25 I=1,N
Y(I,J)=Y(I,J)+Y(I,J+1)
25 CONTINUE
ENDIF



- - - - - - - - - - - - - - - - - - - - - - - - -

Example 1.2

A bit less trivial is the next input text:

- - - - - - - - - - - - - - - - - - - - - - - - -


_FORTRAN
IF(A>B)THEN
_Do I=1,N
Y(I,J)=Y(I,J)+Y(I,J+1)
_od
ENDIF



- - - - - - - - - - - - - - - - - - - - - - - - -

Here you may use " > " instead of ".GT." and the
"_Do_od" loop
(the label is generated by the preprocessor), then the output
is:

- - - - - - - - - - - - - - - - - - - - - - - - -



C->Fortran section begins....
IF(A.GT.B)THEN
DO 32757 I=1,N
Y(I,J)=Y(I,J)+Y(I,J+1)
32757 CONTINUE
ENDIF

 

- - - - - - - - - - - - - - - - - - - - - - - - -

The preprocessor generates labels in decreasing
order starting from
the initial value which may be changed at the installation. The
standard starting value is below 32767 for compatibility with some old
translators. You should not use your explicit labels in the range
(30000-32767) but actually, using the Trefor,
you need explicit labels very rarely.

Example 1.3

If you omit the word _Fortran in the
beginning of the file, or if
you type _Trefor in any place of the text, then the same piece
may be typed from the first column, but you should then use ";" at
the ends of Fortran operators:

- - - - - - - - - - - - - - - - - - - - - - - - -



IF(A>B)THEN;
_Do I=1,N;
Y(I,J)=Y(I,J)+Y(I,J+1);
_od;
ENDIF;



- - - - - - - - - - - - - - - - - - - - - - - - -

The semicolon may be omitted before and/or after the closing
"_od",
so the next text is equivalent to the last one:

- - - - - - - - - - - - - - - - - - - - - - - - -



IF(A>B)THEN;
_Do I=1,N;
Y(I,J)=Y(I,J)+Y(I,J+1)
_od
ENDIF;

 

- - - - - - - - - - - - - - - - - - - - - - - - -

Hereafter we use the _Trefor input format in
our examples, as the
most suitable for the design of complex codes.

 

The tree structure of the program design

Here we give some definitions, but they are not quite formal,
and the best way to understand the way of writing codes in
Trefor is to read carefully our Example 2.1.

DESIGN TREE

 

:: =
the sequence of a ROOT NODE and of its CHILD NODEs

ROOT NODE

 

:: =
NODE TEXT

CHILD NODE

 

:: =
NODE HEADLINE and the NODE TEXT. A node may have no children.
If the root node has no children, then the whole code is
presented in the form usual for standard languages, without
additional information on the code structure

NODE TEXT

 

:: =
the sequence of TERMINAL TEXT segments and/or COMMENTS
and/or DESIGN REQUESTs and/or DEFINITIONS for macros and
aliases

NODE HEADLINE

 

:: =
%GLOBAL_INDEX:
where "%" is typed in the first column.
So the percent sign is reserved as an escape symbol
only here: in any other
position in the text you may use "%" if you need it

TERMINAL TEXT

 

:: =
text in the language you use,
ALIASes and some RESERVED WORDs.
In _Fortran and _Trefor
input also the symbols given below
with their Fortran equivalents
^ .NOT.
& .AND.
! .OR.
= = .EQ.
^ = .NE.
< > .NE.
> .GT.
< .LT.
> = .GE.
^ < .GE.
< = .LE.
^ > .LE.

Of course, you may use any form (old or new) you wish

for these logical and relation notations

COMMENTS

 

:: =
`two minuses' and then the comment:
-- any text to the end of the line (as in Ada).
`Slash-asterisk' comment as in PL/1 or REXX:
/* text */
  
Here text may include many
lines with nodes, other comments
etc. This comment may be used several times within one
line. You may use other comments in the language you use.
E.g. in _Fortran
input (but not in _Trefor) you may use
"C" or "*" in the first column of the line.
The language
_C ascribes some special meaning to "--",
so it may not be
used as a comment: the preprocessor will understand this
correctly if you type _C at the beginning of the C section

DESIGN REQUEST

 

:: =
< *LOCAL INDEX: SPECIFICATION of the child node * >
If the ":" is omitted or replaced by another symbol,
then everything inside the `brackets'
" < *" and "* > "
is understood as a comment.
If the closing "* > " is not met
until the next node headline
then the error diagnostics is issued

LOCAL INDEX

 

:: =
sequence of alphanumeric characters. The local index
is "short" if it is only one letter or digit.
The local index is "long" if it contains more than one
character

SPECIFICATION

 

:: =
text of any length, not
containing the combination "* > "

GLOBAL_INDEX

 

:: =
concatenation of local indices on the path to the node.
Two delimiters are used here:
the underscore "_" shows that the next local index in the
concatenation is the long one (but of course everything
will be OK if it is in fact the short one);
the point "." shows that the next local index is short
and all other characters appearing in the concatenation
are understood as short local indices even if they are
not separated by any delimiters until there again appears
"_". This helps to write very long node headlines
in the huge complex codes using short local indexes.
The difference in their use is explained in examples
below

 

A Nontrivial Example

 

Example 2.1

Here we want to solve a small problem: to find in SUM
the sum of all products, containing M elements of an array X(1:N).

The _Trefor input file for actually working code

*** Top of File *************************************



      --$$ ----HERE BEGINS THE ROOT NODE-----
      --$$ Throughout this text the comments with "--$$" are just for
      --$$ HELP of Trefor. In actual design tree they are omitted without
      --$$ any loss of information on the algorithm
      --$$
PROGRAM SCOMB;
       /* On entry
           X(1:N)- the array of N real elements
              M - integer >0
       On exit
              SUM is the sum of products of all combinations of M
              different elements of X
       */ --$$ this is the comment of PL1/REXX type
<*Var: variables description *>;
      --$$
      --$$ this is the request with local index "Var"
      --$$
<*Input: input N, M, and the values of X(1:N) *>;
      --$$
      --$$ this is the request with local index "Input"
      --$$
       /* abstract variable SET - the ordered set of indexes K(I):
              K(1) < K(2) < ...< K(M)
       Statement QS: SUM is the sum of products
                     X(K(I)) for all { K(I)} == SET <=SET(CURRENT) */
       <*1: make QS true for SET==SET(INITIAL) *>; --$$ local index 1
       _While <*2: SET ^ = SET(FINAL) *> _Do
              <*3: find next SET keeping QS invariant *>
       _od; -- Here SET==SET(FINAL) and QS==. TRUE., that is
                  -- sum contains all needed products of X(K(I))
       WRITE(6,*)' N=',N,'     M=',M,'     SUM=', SUM;
END;
      --$$ --- THE END OF THE ROOT NODE ----


%_Input:
      --$$ the previous line is the headline of a child node, "_" shows
      --$$ that alphanumeric sequence till the next "_" or "." or ":"
      --$$ is the one long local index
      --$$
       Write(0,*)'Enter the array length N';
       READ(5,*) N;
       Write(0,*)'Enter the number of elements in product M';
       READ(5,*) M;
       Write(0,*)'Enter the array X(1:N)';
       READ(5,*) (X(I),I=1,N);


%3:
      --$$ the previous line is the headline of another child node, the absence of
      --$$ "_" or the presence of "." tells that only one character is used
      --$$ as the local index, i.e. the local index is the short one.
      --$$ We begin the design from this node since at the moment it is
      --$$ not yet decided, what is the actual structure of the abstract
      --$$ variable SET, but we already can develop the algorithm
      --$$
       <*A: find new SET , i.e. new { K(I) } *>;
       <*B: put in PRODCT the product of X(K(I)) *>;
       SUM = SUM + PRODCT


%3A:
      --$$ the previous line is the headline of the node with local index "A"
      --$$ requested in the node %3, the global index here is "3A" which is
      --$$ equivalent to "_3_A", or to "_3.A", or to ".3.A", or to "3.A",
      --$$ or to "3_A", but not to "_3A", since there is no request with
      --$$ the local index "3A"
      --$$
       /* concrete presentation of SET:
              K(I) - array of integer M elements */
       I=M;
       _While K(I)==N+I-M _Do
              I=I-1
       _od;
       K(I)=K(I)+1;
/* The next loop is valid only for Fortran-77
       since for m==1 Fortran-66 executes Do-loop L=1,0 */
       _Do L=1, M-1;
           K(I+L)=K(I)+L
       _od


%3B:
       PRODCT=1.D0;
       _Do I=1,M;
           PRODCT = PRODCT*X(K(I))
       _od


%2:
       K(1) ^= N+1-M
      -- If K(1)==N+1-M all the K(I) reach their final value


%1:
       SUM=1.D0; -- !!!
       _Do I=1,M;
           K(I)=I;
           SUM=SUM*X(I);
       _od


%_Var:
      --$$ the design of any node may be done in any convenient place
      --$$ after the end of the requesting node, e.g. the description
      --$$ of variables may be done at the end of the design tree when
      --$$ you already know all the desired data structures
      --$$
          Implicit real*8 (a-h,o-z);
           Parameter(NDIM=10000); -- maximum dimension of arrays
           Real*8 X(NDIM), SUM, PRODCT;
           Integer K(NDIM),I,M,N,L;


*** End of File **************************************

    If this file is scomb.trf and you type

    trf -nfsl scomb.trf

then you obtain the code scomb.f which may be submitted for translation
to a Fortran compiler. Moreover you have a Trefor listing, scomb.lst,
with detailed Trefor diagnostics.

 

Reserved words

All reserved words begin with the underscore sign "_".
You may use upper, lower or
mixed case typing them. The delimiter for a reserved
word is any non-alphanumeric symbol
(usually it is just a blank). Digits are ignored
in reserved words and you may use them just for labeling,
e.g.

       _Fortran        _FORTRAN77        _FoR66Tran

produce quite the same effect: telling the
preprocessor that the input
will be in the Fortran format, and nothing more.

Now we collect the reserved words for general case.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Input/output format:

    _Trefor        (default)

    _Fortran

    _REXX

    _Pascal

    _C

The file produced after the processing (command trf -[options]
Fname) will be

     Fname.f

and you should change the extension .f to the language
you are actually using if its not Fortran.

You may use _Pascal format with many
languages with similar syntaxes
(actually _REXX and _Pascal
formats are the same from the point of
view of the Trefor).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    _Include Fname;

this is used to include other files written in the
format declared.
It is used to include the file

     Fname.inc

where the file Fname.inc will be searched for in
the alphabetical order on
the accessed disks. The included file may contain other _include
instructions.

    _IncludeN Fname

is equivalent to _Include but the
contents of included files is not printed in the Trefor listing.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    _Offprint

    _Onprint

to switch off/on the output to the listing file.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    _Trace

This word will generate messages in the output
file about leaving and entering the nodes. E.g.,

           '- > Entering Node % _Var:'

           ' < - Leaving Node % _Input:'

If you type in the example of file Scomb Trefor:

    _trace 'write(5,*)'

then you obtain in output the Fortran text:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

           PROGRAMSCOMB

           WRITE(5,*)'-> Entering Node % _Var:'

           IMPLICITREAL*8(A-H,O-Z)

           PARAMETER(NDIM=10000)

           REAL*8X(NDIM),SUM,PRODCT

           INTEGERK(NDIM),I,M,N,L

           PARAMETER(PI=3.141592653589793D0)

           WRITE(5,*)'<-Leaving Node % _Var:'

           WRITE(5,*)'->Entering Node % _Input:'

           Write(0,*)'Enter the array length N'

           READ(5,*)N

           Write(0,*)'Enter the number of elements in product M'

           READ(5,*)M

           Write(0,*)'Enter the array X(1:N)'

           READ(5,*)(X(I),I=1,N)

           WRITE(5,*)'<-Leaving Node % _Input:'

           ...

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

So you may receive messages from executing
program tracing the
nodes. Of course, the first message about the
node "% _Var:" does
not allow to obtain correct Fortran code. To avoid this you just
type "O"in the node head:

% _Var:O

where "O" is from "Offtrace". In the example
considered you should also type

%2:O

Try not to do this and look to the output Fortran
file after issuing the command "trf -nf scomb.trf" .

    You may also trace the nodes with some variables:

    _trace "write(6,'(" X(1) = ",G12.3,A)')
X(1),";

the message from trace will be always just added
to your "write...".
Note, that here you are forced to use quotation
as outside delimiter
since inside you use the apostrophe (cf. below the rules for
alias definitions).

To trace the nodes actively in other languages you have to
use other appropriate
instructions together with the _trace, e.g.
in REXX:

    _trace 'SAY'

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    _Define

    _Deflist

The description of these is given below in Sect. 5.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The following constructions have sense ONLY for standard _Trefor
or _Fortran input when preprocessor outputs Fortran .

We have already used in the examples above
_Do_od and
_While_Do_od constructions.
The best way to understand how any
Trefor construction is transformed to the standard Fortran is
to type an example, then to issue command

    trf

and then to browse the created Fortran file.
Here we do not give
the detailed syntax but only some sketch and examples.

SQUARE BRACKETS "[", "]": they are used in the
sense of BEGIN and
END of Algol-60 (or Pascal), but only in fixed constructions.

Example 4.1

The _do loop from example 1.3:

 



_Do I=1,N;


       Y(I,J)=Y(I,J)+Y(I,J+1)


_od



is equivalent to the construction

_Do I=1,N [ Y(I,J)=Y(I,J)+Y(I,J+1) ]

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Example 4.2

Embedded _do loops (Nordsieck predictor in
multi-step ODE-solvers):

 



_Do J1=1,NQ;

       _Do J2=J1,NQ;
           J=NQ-J2+J1;
               _Do I=1,N;
                   Y(I,J)=Y(I,J)+Y(I,J+1)
_Od_Od_Od;



or, equivalently:

 



_Do J1=1,NQ;
       _Do J2=J1,NQ;
           J=NQ-J2+J1;
               _Do I=1,N;
                   Y(I,J)=Y(I,J)+Y(I,J+1)
               _Od
       _Od2
_Od1;



As we have already noted the numbers in reserved
words have no effect on the output: actual
labels are produced by the preprocessor

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       A sketch of other constructions. We use the following
abbreviations:

       log.expression     :: = logical expression of Fortran/Trefor

       Op.sequence        :: = sequences of Trefor operators

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _While log.expression _do

              Op.sequence

       _Od;

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _Repeat

              Op.sequence

       _Until log.expression;

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _Repeat[

              Op.sequence

                     ];        - infinite loop

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _While log.expression1 _do

              Op.sequence

       _Until log.expression2;

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _If log.expression _then

              Op.sequence

       _Fi        - needed at Langlvl = 66 or to pass

                                        - control inside if-then-else-endif construction

                                        - at Langlvl = 77

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _If log.expression _then

              Op.sequence1

       _else

              Op.sequence2

       _Fi

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _Case Int. _Of           
- here Int. is an integer expression

           _ Op.sequence1        - and underscore delimits

           _ Op.sequence2        - the Op.sequences

           _ Op.sequence3

           .......

           _ Op.sequenceN

       _esac

this is equivalent to

       _Case Int. _Of

           _1 Op.sequence1

           _2 Op.sequence2

           _3 Op.sequence3

           .......

           _N Op.sequenceN

       _esac

and executes like GOTO(lab1,lab2,...,labN),Int.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _Select

           _1 log.expression1 [ Op.sequence1 ]

           _2 log.expression2 [ Op.sequence2 ]

           _3 log.expression3 [ Op.sequence3 ]

           ........

           _N log.expressionN [ Op.sequenceN ]

       _End

the _select operator finds the first I which
has log.expression-.TRUE. and then executes the Op.sequenceI .

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _Leave I

is used to exit _do I=m1,m2,m3; .... _od loop.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _Leave All

exits all embedded _do_od loops

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _Iterate I

is used to iterate _do I=m1,m2,m3; ....
_od loop. i.e. does
GOTO label of CONTINUE for corresponding loop.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

       _Iterate All

control passes to CONTINUE of the outermost loop.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Sometimes you do not know if a logical expression can be readily
inserted in _While, _If and _Select
construction. E.g., in the Example 2.1 :

 

        _While  < *2:  SET ??? =  SET(FINAL) * >  _Do


           < *3: find next SET keeping QS invariant * >


       _Od;



the variable SET is abstract and perhaps you need
some additional
arithmetics before you obtain the logical relation. If you need this
then you may replace

       log.expression

by

       [Op.sequence] log.expression

at the stage of designing the node and you do not
need to bother about this at the stage of requesting the node.

       _Outcom

Use this word to output comment to Fortran text.
You may then meet some
troubles if use Ada type comments in _Fortran input,
so at present for _Fortran input it is better to use
the old-fashioned
"C" or "*" in the first column, if you for some reason need the
Fortran output with comments.

After _Outcom you may type

       _trace `- - - - - - - -'

then you find in the output file the comments
informing you on the current node headlines.


Here we reserve the symbol "@" as the escape one
so it may be used in other sense
only in character constants or in comments. If this symbol is already
reserved by the compiler ( as in some version of Pascal ) then it
should be changed to another one at the installation of Trefor.

       Syntax:

       _Define @name1 `defining sequence1'

              @name2 "defining sequence2"- comments are allowed here

              @name3 defining_sequence2_with_no_blank
_'_no_"_in_one_line

              ; - this closes the _define, may be omitted if the next

                 - nonblank is not "@"

Here "name" is an alphanumeric sequence

Use apostrophe if defining sequence contains quote sign.

Use quote if defining sequence contains apostrophe.

You produce a macro definition if the defining
sequence contains
other alias names, perhaps not yet defined. You may redefine them many
times when you need it before use.

NB: the _Define is visible only in the
child nodes requested after it!
So you may use alias names to protect some important variables from
unauthorized use in parallel nodes.

For _Trefor and _Fortran use also:

       _Deflist @name1,@name2,...,@nameN;

then you obtain identifiers z00001, z00002 ....

       _deflist idef00 @name1,@name2,...

using any 6-character identifier as a mask,
then in this example you obtain identifiers idef01, idef02 ....

       _Label @name1,@name2,@name3....

automatically produces labels.

To call a procedure use:

       _call @Name;

The description of a procedure has the form:

       _Proc @Name;

           /* the body of the procedure */

       _return;

The Name of a procedure must be an alias, i.e. it must begin with
the "at_sign" symbol '@'.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Example of a procedure name:

_PROC @GET_WORD;

The body of a procedure may contain any constructions of Trefor
including macros and other procedures. To call this procedure use

_call @GET_WORD;

The recursive calls are also allowed (but then one must avoid
the appearance of infinite loops).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Example of a procedure containing another procedure:

_PROC @HEAP; - HeapSort

_PROC @SIFT;

< *sift: * > ;

_RETURN;

L=N/2+1; R=N;

_WHILE L > 1 _DO

L=L-1; _CALL @SIFT;

_OD;

_WHILE R > 1 _DO

W=A(1); A(1)=A(R); A(R)=W;

R=R-1; _CALL @SIFT;

_OD;

_RETURN;

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

When calling a procedure one must obey all the rules of work
with aliases.
Using a special variable
@RET_Name_of_PROCEDURE,
which keeps the number of the procedure call, one can arrange
recursive calls, save this variable in a
STACK (an integer array). Similarly one can save
variables changing inside a procedure and restore them before the
return.

Example of a procedure with an argument:

_Proc @A; - argument i

Sarg(p)=i; Sret(p)=@Ret_A; p=p+1; - Store CALLER in STACK

< *A: body of procedure A which may contain

recursive calls of A * > ;

p=p-1; i=Sarg(p); @Ret_A=Sret(p); - Return to CALLER

_Return;

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The PROCEDUREs may be used only with
the Fortran as the object language.

In the output file a procedure looks like:

LAB0 CONTINUE

       /* body of procedure */

       GOTO(LAB1,LAB2,...,LABN), I6R00K

The _call @Name_proc is transformed into Fortran sequence

       .........

       GOTO LAB0

LAB1 CONTINUE

       .........

       GOTO LAB0

LAB2 CONTINUE

       .........

       GOTO LAB0

LABN CONTINUE

Here LAB0 - is the label of the procedure head
LAB1,LAB2,...,LABN - are the labels of return
to the instruction after _call
( N - is the number of calls),
I6R00K - an integer variable controlling the return.


Diagnostics for procedures

 

1.
'Procedure not found' -

The procedure is either not defined or is not visible from the
current node. The severity code is 8 (a fatal error).

Example:

Program QUQU;

< *var: * > ;

< *A: * > ;

< *B: * > ;

Stop;END;

%A:

_Proc @Local;

< *body: * > ;

_Return;

< *Calc: * > ;

%B:

< *Preparation: * > ;

_Call @Local;

       - the procedure @Local is not visible from the node %B

To use the procedure @Local one has to move its description
from the node %A into the root of a program:

Program QUQU;

< *var: * > ;

_Proc @Local;

< *body: * > ;

_Return;

< *A: * > ;

< *B: * > ;

Stop;END;

%A:

< *Calc: * > ;

%B:

< *Preparation: * > ;

_Call @Local;

       - now @Local is visible from the node %B

 

Diagnostics

IFAIL - diagnostics code.

IFAIL=3 - fatal error (severity 8)

IFAIL=2 - warning (severity 4)

List of messages for the
1st stage (the formation of the program tree)

1.'Error in service word        '        IFAIL=3

2.'Local index repeated        '        IFAIL=3

3.'The node is not requested        '        IFAIL=2

4.'The node requested in line        'XXXX

5.'Text ignored until the node end        '

6.'Its design begins in line        'XXXX

7.'No design for node from line        'XXXX     IFAIL=2

8.'Reference to nonexistent node        '        IFAIL=2

9.'Case or Select not opened.        '       IFAIL=3

10.'Alias not identified        '        IFAIL=3

11.'Unrecognizable symbol in Fileid.     '        IFAIL=3

12.'Unable to open include file.        '        IFAIL=2

13.'Caution: TREFOR TRACE active!        '

14.'Caution: COMMENTS will be output!     '

15.'Deflist basis is too short        '       IFAIL=3

16.'Forbidden alias definition        '        IFAIL=3

17.'Current tree completed.        '

18.'Include level exceeds max.level!     '       IFAIL=3

19.'Print full listing forced.        '

20.'Warning:Unknown service word!!!     '       IFAIL=2

21.'Print full listing started.        '

22.'Node head already in line        'XXXX     IFAIL=3

23.'Procedure not found        '        IFAIL=3

24.'Char. constant not completed'

25.'Request or comment not closed'

The 2nd stage (the formation of output text)

1.'Node head already in line' XXXX

2.'No design for the NODE requested in line:'XXXX

'Node number:'YYY' with local index:'AAAA

3.'In NODE beginning in line:'XXXX' not defined ALIAS @'AAAA

4.'In NODE beginning in line:'XXXX' recursion in ALIAS @'AAAA

The following line may be written as the comment in the output Fortran text)

'CERROR('XXXX') Syntactical or Alias Error'

Building Trefor

If you could download a file like trefor*.tar.gz from this page
then unzip and untar it, e.g.

              tar -xzvf trefor*.tar.gz

or if that does not work

              gzip -d trefor*.tar.gz

              tar -xvf trefor*.tar

Now issue commands

              make conf

              make all

              make clean

When you are prompted type "Y" if it goes OK.

Now you have 2 binary executables: trf* and trefor* - put them
to your local bin/ directory or work with Trefor in the same directory
you have them currently.

The execution of trf command is controlled by the .trfrc file. Read it
carefully and edit it to connect trf execution with the default COMPILER
(and compiler's options) and the default EDITOR that you wish to use.
The trf command looks for .trfrc file in the current directory, and
if it is not found there then in the system directories (/usr/local/lib
etc.). If .trfrc is not found at all then internal default options
are used.

The Trefor
options are explained there in .trfrc file, or you may type

              trf

and you will see the list of the options.

E.g.,

              trf -nf your_code.trf

(where -nf means No Fortran compilation)
will not submit your code to the Fortran compiler (defined in .trfrc
file).

If you wish to submit your code to Fortran compilation, then type, e.g.,

              trf - -c -O -qarch=pwr2 your_code.trf

Here you do not define any Trefor options and
" -c -O " etc. - they are your Fortran options.

If you type

              trf -e your_code.trf

then you open your_code.trf file for editing with the EDITOR - this
happens only if a severe error occurred at the stage of Trefor preprocessing.

All needed Trefor options are written in one group, e.g.,

              trf -nfl your_code.trf

- no fortran compilation and preservation of the Trefor listing
(your_code.lst) file.

Use

              a2ps -p [-Pprinter] your_code.lst

command to printout Trefor listings.


File translated from
TEX
by
TTH
,
version 2.78.
On 19 Sep 2000, 12:06.