Contact us Heritage collections Image license terms
HOME ACL Associates Technology Literature Applications Society Software revisited
Further reading □ OverviewPaper 1Paper 2Paper 3Paper 4Paper 5Paper 6Paper 7Paper 8Paper 9Paper 10Paper 11Paper 12Paper 13Paper 14Paper 15Paper 16Paper 17Paper 18Paper 19Paper 20Paper 21Paper 22Paper 23Paper 24Paper 25 revPaper 25Paper 26Paper 27Paper 28Paper 29Paper 30Paper 31Paper 32Paper 33Paper 34Paper 35Paper E
ACD C&A INF CCD CISD Archives Contact us Heritage archives Image license terms

Search

   
ACLLiteratureProgress ReportsTechnical Papers :: Literature: FR80 Technical Papers
ACLLiteratureProgress ReportsTechnical Papers :: Literature: FR80 Technical Papers
ACL ACD C&A INF CCD CISD Archives
Further reading

OverviewPaper 1Paper 2Paper 3Paper 4Paper 5Paper 6Paper 7Paper 8Paper 9Paper 10Paper 11Paper 12Paper 13Paper 14Paper 15Paper 16Paper 17Paper 18Paper 19Paper 20Paper 21Paper 22Paper 23Paper 24Paper 25 revPaper 25Paper 26Paper 27Paper 28Paper 29Paper 30Paper 31Paper 32Paper 33Paper 34Paper 35Paper E

Paper No 25: Dimensional Flowchart Generator - an FR80 Software Tool

F Louazani, R W Witty

4 September 1976

1. INTRODUCTION

The program described here is the implementation of the TREE-META dimensional flowchart definition (see Appendix 1) to generate FR80 produced dimensional flowcharts. (Ref: FR80 Technical Paper 21 - DRIVER SOFTWARE CONSTRUCTION).

1.1 DFG: What Is It?

The dimensional flowchart generator is a program to which the input is a machine readable specification of the flowchart, and the output is a dimensional flowchart drawn on FR80.

The program is written in ALGOL, and it uses the GROATS graphics package.

The top-down structured design approach was followed in developing the program.

1.2 Implementation Method

A dimensional flowchart definition consists of:

DIM FLOWCHART: = .NAME '\' NODE;

drawing the flowchart consists of:

  1. Printing the name of the flowchart.
  2. Drawing the R-dimension (ie next level).
  3. Drawing a NODE which can be several SERIALS.
  4. Each SERIAL is a flowchart in its own right, and the process of drawing is, thus, achieved recursively.

The 3-D aspect is implemented by recognizing 3 levels:

  1. The Serial dimension: drawn as a vertical line.
  2. The Parallel dimension: drawn as a horizontal line.
  3. The Refinement dimension: drawn as a diagonal line.

A statement can be either an ACTION statement or a CONDITIONAL statement. To differentiate between these 2 categories a conditional expression is denoted by drawing a half square around the beginning of its text.

The idea of scoped comments is implemented by using labels.to:

  1. Denote the beginning of a block.
  2. Describe briefly the action achieved in that block.

2. PHYSICAL AND LOGICAL CONSTRUCTION

2.1 Physical Layout

The following dimensional flowchart represents the physical layout (construction), of the program. It was generated using the data file listed in Appendix 4.

2.2 Logical Construction

The dimensional flowchart representing the logical flow of the program is listed at the end of this paper.

FLOWB-SRC PROGRAM DESCRIPTION BEGIN INITIALISE PLOTTING PROCEDURES BEGIN DECLARE VARIABLES & INITIALISE PARAMS BEGIN DEFINE LIMITS AND REGIONS DRAW 3D FLOWCHART DECLARE VARIABLES DEFINE PROCEDURES PROCEDURE MAX INTEGER PROCEDURE GET CHAR PROCEDURE DRAW THE FLOWCHART PROCEDURE GET NON BLANK CHAR PROCEDURE DRAW NEXT LEVEL PROCEDURE PRINT OUT POINTERS PROCEDURE DRAW NODE PROCEDURE DRAW SERIAL PROCEDURE DRAW VERTICAL LINE PROCEDURE DRAW HORIZONTAL LINE PROCEDURE LOOP ERROR DRAW BIG PICTURE LOOP LOOP INITIALISE PARAMS SELECT END UNITS CALL DRAW THE FLOW CHART ADVANCE FILM ADVANCE FILM END END END END END END END

3. PROGRAM PROCEDURES AND FUNCTIONS

3.1 Programmer Defined Procedures

(1) INTEGER PROCEDURE GCHAR (character)
Inputs a character in 1900 ALGOL character code and returns as its value the 1900 GROATS equivalent; this is necessary to print out using GROATS procedure 'TYPE'.
(2) INTEGER PROCEDURE MAX (a,b)
Takes two integer values a, b and returns the value of the greater.
(3) PROCEDURE DRAW THE FLOWCHART (top, left, bottom, right)
Generates the instructions to draw the flowchart defined by (top, left) → (bottom, right), where top, left, bottom, right are defined in the selected region units. To achieve the above it calls procedure:
DRAW NODE
DIMFLOWCHART:=.NAME'\' NODE
(4) PROCEDURE GET NON-BLANK CHAR(ch)
Returns the next non-blank input character as CH.
(5) PROCEDURE PRINT OUT POINTER (top, left, bottom, right)
Takes the parameters top, left, bottom, right and prints them out. The output medium is the lineprinter. This is a debugging aid.
(6) PROCEDURE DRAW NODE (top, left, bottom, right)
To understand the mechanism of this procedure, it is helpful to refer to META DIMFLOWCHART (see Appendix 1), where NODE:=FLOWC. The purpose of this procedure is to draw one or more serials (see DRAW SERIAL).
(7) PROCEDURE DRAW SERIAL (top, left, bottom, right)
SERIAL :=  STATEMENT(REFINE/EMPTY) $ (PARALLEL)
Draw a SERIAL consists of:
  1. Draw a vertical line.
  2. Draw a statement (see DRAW STATEMENT).
  3. Decide whether a refinement is needed, if so DRAW NEXT LEVEL and DRAW NODE.
  4. Draw one or more parallels which consists of:
    DRAW HORIZONTAL LINE. 
    DRAW NODE. 
    
Note how the recursive nature of dimensional flowcharts occurs in that DRAW SERIAL calls DRAW NODE which itself calls DRAW SERIAL.
(8) PROCEDURE DRAW STATEMENT (top, left, bottom, right)
STATEMENT:= ACTION/CONDITIONAL 
Draw a statement consists of:
  1. Decide whether a statement is an ACTION statement or a CONDITIONAL.
  2. If it is an ACTION then write the text and update the pointers to skip over it.
  3. If it is a CONDITIONAL then write the text and draw a half square around it.
(9) PROCEDURE DRAW VERTICAL LINE (top, left, bottom, right)
Draws a vertical line joining the points (left, top) and (left, bottom).
(10) PROCEDURE DRAW HORIZONTAL LINE (top, left, bottom, right)
Draws a horizontal line joining the points (left, top) and right, top).
(11) PROCEDURE DRAW NEXT LEVEL (top, left, bottom, right)
Draws the diagonal line for the refinement dimension.
(12) PROCEDURE LOOP ERROR (top, left, bottom, right)
Indicates that a loop error has occurred, and prints out the pointers top, left, bottom, right. After a loop error has occurred, the program terminates.

3.2 GROATS Procedures

(1) SELECT CAMERA(7)
Selects the camera used to produce hardcopy output - single frames.
(2) IDENTIFICATION
Initialises the GROATS system and puts identification frames onto the output.
(3) LIMITS (Xmin, Ymin, Xmax, Ymax)
Defines minimum and maximum values of x and y which coincide with corners of the currently selected region.
(4) REGION (Xmin, Ymin, Xmax, Ymax, I)
Defines sub-region I as the part of the currently selected region, which has max coordinates (Xmax, Ymax), and minimum coordinates (Xmin, Ymin).
(5) SELECT REGION (I)
Selects region I; all the GROATS procedures will have their positional parameters defined in terms of the currently selected region.
(6) CHARACTER SIZE (height, width)
Defines size of characters in units of the currently selected region.
(7) MOVE TYPE TO (x, y)
Moves typing positions to the point (x,y).
(8) CHARACTER SPACE (CH SP)
Inserts a space of CH SP units between character in the horizontal direction.
(9) TYPE (CH)
Types the GROATS character CH at the current typing position and moves the typing position one position to the right.
(10) PROCEDURE DRAW NEXT LEVEL (top, left, bottom, right)
Draws the diagonal line for the refinement dimension.
(11) PROCEDURE LOOP ERROR (top, left, bottom, right)
Indicates that a loop error has occurred, and prints out the pointers top, left, bottom, right. After a loop.error has occurred the program terminates.

3.3 Oxford Utility Library

ALGOBEY (S)

This is a semi-compiled procedure which issues GEORGE commands from within the ALGOL program. It is a Boolean procedure; it returns "true" if the command is issued successfully, and "false" otherwise (see Appendix 3).

3.4 Procedures Hierarchy

Because of the recursive nature of the procedures used in the program, it may be helpful to list the interaction between different procedures. Below are 3 different representations of the procedures hierarchy and interaction.

NAME OF PROCEDURE PROCEDURE CALLED
DRAW THE FLOWCHART GCHAR
DRAW NEXT LEVEL
PRINT OUT POINTERS
DRAW NODE
LOOP ERROR
DRAW NODE DRAW SERIAL
LOOP ERROR
DRAW HORIZONNTAL LINE
DRAW NODE
GET NON BLANK CHAR
DRAW SERIAL DRAW VERTICAL LINE
DRAW STATEMENT
GET NON BLANK CHAR
DRAW NEXT LEVEL
DRAW NODE
PRINT OUT POINTERS
DRAW HORIZONTAL LINE
LOOP ERROR
DRAW STATEMENT GET NON BLANK CHAR
LOOP ERROR
GCHAR
LOOP ERROR PRINT OUT POINTERS
REPRESENTATION 1 : A SERIAL LIST
DRAW THE FLOW CHART LOOP ERROR PRINT OUT POINTERS DRAW NODE DRAW NEXT LEVEL GCHAR LOOP ERROR GET NON BLANK CHAR DRAW SERIAL DRAW NODE DRAW HORIZONTAL LINE LOOP ERROR GET NON BLANK CHAR PRINT OUT POINTERS DRAW STATEMENT DRAW NODE DRAW VERTICAL LINE DRAW HORIZONTAL LINE DRAW NEXT LEVEL PRINT OUT POINTERS GET NON BLANK CHAR LOOP ERROR GCHAR
REPRESENTATION 2 : A TOP DOWN DIAGRAM
DRAW THE FLOW CHART GCHAR DRAW NEXT LEVEL PRINT OUT POINTERS DRAW NODE GET NON BLANK CHAR DRAW SERIAL DRAW VERTICAL LINE DRAW STATEMENT GET NON BLANK CHAR GCHAR LOOP ERROR PRINT OUT POINTERS GET NON BLANK CHAR DRAW NEXT LEVEL DRAW NODE RECURSIVE CALL DRAW HORIZONTAL LINE DRAW NODE RECURSIVE CALL LOOP ERROR DRAW HORIZONTAL LINE LOOP ERROR DRAW NODE RECURSIVE CALL PRINT OUT POINTERS LOOP ERROR
REPRESENTATION 3 : A 3-D FLOW CHART

4. LIST OF VARIABLE NAMES

VAR NAMES
(1)
SCOPE
(2)
DESCRIPTION
TR
tr 5
Block 0 Set to 'true' if the GEORGE command is issued successfully, and false otherwise.
XMAX,YMAX Block 1 Delimits size of single frame of output.
CH WIDTH, CH HEIGHT Block 1 Defines character width and height respectively in the selected region units (see Appendix 2).
CH SPACE Block 1 Sets up the horizontal spacing left between 2 consecutive characters (see Appendix 2).
WIDTH 3 CH
CH 2 HEIGHT
Block 1 Set up horizontal and vertical offset for the starting position of drawing next level (diagonal line) (see Appendix 2).
DTB Block 1 Length of vertical line between two serial statements (see Appendix 2).
DRP Block 1 Horizontal offset for next parallel node.
DELTA MLP Block 1 Horizontal offset for minimum length parallel.
RJ, RK Block 1 Used as loop parameters in drawing the big picture (ie in defining the new LIMITS).
TOP, LEFT, BOTTOM, RIGHT Block 2 These are the pointers throughout DRAW 3.D FLOWCHART to update the drawing positions, they are also used as formal parameters of the program procedures.
CH A character; defined in all procedures.
J Used as a loop counter throughout.
A, B PROC MAX Formal parameters of the procedure.
CHARACTER PROC GCHAR Formal parameter of the procedure.
NEW LEFT, NEW RIGHT, NEW TOP, NEW BOTTOM PROC DRAW THE FLOWCHART Used to reset pointers to new positions to draw next level. They are redefined in DRAW NODE to control drawing positions; they are updated after a drawing instruction has been issued.
DIAGONAL PROC DRAW NEXT LEVEL Length of X and Y components of diagonal line.
MAX NEW RIGHT, MAX NEW LEFT DRAW NODE Pointers to control drawing positions, updated after a drawing instruction has been issued.
TOP MLP, LEFT MLP, BOTTOM MLP, RIGHT MLP, MAX BOTTOM MLP, MAX RIGHT MLP DRAW NODE Pointers to denote coordinates of minimum length parallel; used in calling DRAW HORIZONTAL LINE for m.l.p.
TOP SERIAL, LEFT SERIAL, BOTTOM SERIAL, RIGHT SERIAL DRAW SERIAL Pointers to denote serial drawing positions.
NEXT TOP, NEXT LEFT, NEXT RIGHT, NEXT BOTTOM DRAW SERIAL Pointers to denote coordinates for drawing next node.
TOP PARA, LEFT PARA, BOTTOM PARA, RIGHT PARA DRAW SERIAL Denote coordinates for drawing positions of minimum width parallel.
TOP TEXT, RIGHT TEXT DRAW STATEMENT Denote X coordinates of starting and finishing of text.
ACTION DRAW STATEMENT Set to 'true' if starting character is (') (ie SERIAL) and 'false' if starting character is (?) (ie CONDITIONAL).

Notes

(1) Variable names are of integer type except the following: 
RJ, RK      : REAL 
TRS, ACTION : BOOLEAN 
(2)  BLOCK O: the most outer block 
     BLOCK 1 : the second most outer block 
     BLOCK 2: the draw 3-D flow block 

5. THE INPUT DATA

Data is presented in a form which uses the following symbols as reserve symbols to implement different features of a 3-D flowchart.

SYMBOL MEANING DRAWING ACTION
! Denotes R-dimension (ie next level) Draw diagonal line
# Denotes the end of a node Reset pointers to previous level
? text ? Denotes a conditional node Draw a half square around text
' text ' Denotes an action statement Text without half square
- Denotes a serial-parallel Draw horizontal line of length DRP followed by DRAW NODE
= Denotes a minimum length parallel Draw horizontal line of length DELTA MLP followed by DRAW NODE

The first data record is of the form:

N .NAME text; 

where:

N is the scaling factor for the whole flowchart, text describes the title of the flowchart.

The second record will be always a R dimension symbol (!).

the last data record is of the form:

. text ; 

Note: An example of the input data used to generate the physical construction of the program is included in Appendix 4.

6. ERROR CHECKING AND DEBUGGING AIDS

6.1 Error Checking

  1. Loops: all loops in the program are proved to terminate, and any iteration outside the maximum loop range will result in an appropriate error message stating the whereabouts of the error. eg:
    ERROR IN COPY TITLE. 
    
  2. The input data checks: errors in the input data format (eg, errors in statements delimiters) will result in one of the following error messages:
ERROR MESSAGE CAUSE
ERROR IN COPY TITLE Either:
(a) text exceeding 82-characters
(b) (;) missing
.ERROR (.) end of data marker not encountered
ERROR IN NON BLANK CHAR Loop to get non blank characters exhausted
ONE OR MORE SERIALS ERROR More than 5000 serials
MIN LEN PAR LOOP ERROR More than 50 consecutive min len Parallel nodes
# ERROR (#) end of node marker not encountered (often when a statement is started by an illegal character)
PARALLEL LOOP ERROR More than 82 consecutive serial - parallels encountered
? OR ' ERROR Wrong statement type (ie not an action nor a conditional statement)
WRITE OUT TEXT ERROR More than 999 chs in statement text
ACTION OR ' OR ? ERROR Delimiters of a statement not compatible (eg starting delimiter ', and terminating delimiter ?)
A LOOP ERROR HAS OCCURRED This will normally follow the error messages:
(a) one or more serials error
(b) parallel loop error
(c) write out text error
(d) .ERROR
(e) min len par loop error

6.2 Debugging Aids

Throughout the program, a number of trace statements recording the progress of the program execution are built in as 'comments' statements of the form:

'COMMENT' WRITE TEXT ('text');
'COMMENT' PRINT OUT POINTERS (top, left, bottom, right); 

Leaving out the ALGOL words 'COMMENT' will result in a full trace of the program execution; this is to be used in extreme necessity as it results in a large amount of printer paper.

APPENDIX 1: META DIMFLOWCHART

META DIMFLOWCHART
DIMFLOWCHART :=    .NAME '\' FLOWC ;
FLOWC        :=    NODE ;
NODE         :=    SERIAL $ (SERIAL) '#' ;
SERIAL       :=    STATEMENT (REFINE/.EMPTY) $ (PARALLEL) ;
REFINE       :=    '\. FLOWC ;
PARALLEL     :=    '¬' FLOWC ;
STATEMENT    :=    ACTION/CONDITIONAL ;
ACTION       :=    'TEXT' ;
CONDITIONAL  :=    '?' BOOLEAN EXPRESSION OR TEXT '?' ;

APPENDIX 2

1  CH WIDTH         = 8
2  CH HEIGHT        = 8
3  CH SP            = 2
4  CH 2 HEIGHT      = 16
5  DIAGONAL         = 40
6  WIDTH 3 CH       = 20
7  DTB              = 20
8  DRAW NEXT LEVEL
9  DRAW VERTICAL LINE
1 4 5 2 3 6 7 5 8 9

APPENDIX 3 ALGOLOBEY

  1. BOOLEAN procedure ALGOLOBEY(S); string S;
  2. This procedure issues GEORGE commands from within an ALGOL program. Most commands which do not cause deletion or suspension of the program may be issued by this procedure. The routine returns TRUE if the GEORGE command was issued successfully and FALSE otherwise.

    Since GEORGE parameter substitution involving use of % characters these cannot be used directly in an ALGOL string, the routine will convert any £ characters in the string to % characters before issuing the command. Parameter substitution is therefore accomplished using £ characters in the original string in positions where GEORGE would require % characters. % characters in the original string will of course be converted at compile time into space characters.

  3. Language: PLAN
  4. Parameters: S - a character string which consists of the command to be obeyed enclosed in string quotes.
  5. Error indicators: The routine returns FALSE if the GEORGE command was not issued successfully.
  6. Examples:

    (a) In the following example NEWFILE will he assigned to *CRO

    'IF' 'NOT' ALGOBEY ('('AS%*CRO,NEWFILE')') 'THEN' 
    'BEGIN' 'COMMENT' ERROR ROUTINE; 
        ...
        ...
        ...
    'END' 'ELSE'
    'BEGIN' 'COMMENT' COMMAND OBEYED OK;
    

    (b) If a call to the macro that runs a program includes the parameter:

    PARAM (F1 FILE1, F2 FILE2)
    

    then to issue the GEORGE commands:

    AS *CRO,%(F1) 
    AS *CPO,%(F2) 
    

    from within the ALGOL program, the calls to ALGOLOBEY should be:

    IF' 'NOT' (ALGOBEY('('AS%*CRO ,£(FI')')) 
    'AND' ALGOBEY('('AS%*CPO,£(F2)')')) 
    'THEN' 'GOTO' L99; 
    

APPENDIX 4: DATA USED TO PRODUCE FLOW CHART IN CHAPTER 2

1500  .NAME FLOWB-SRC;
|
'PROGRAM DESCRIPTION'
'BEGIN'
|
'DECLARE VARIABLES &,INITIALISE PARAMS'
'BEGIN'
|
'DEFINE LIMITS AND REGIONS'
'DRAW 3D FLOW CHART'
|
'DECLARE VARIABLES'
'DEFINE PROCEDURES'
|
'PROCEDURE MAX'
'INTEGER PROCEDURE GET CHAR'
'PROCEDURE   DRAW THE FLOW CHART'
'PROCEDURE GET NON BLANK CHAR'
'PROCEDURE DRAW NEXT LEVEL'
'PROCEDURE PRINTOUT POINTERS'
'PROCEDURE DRAW NODE'
'PROCEDURE DRAW SERIAL'
'PROCEDURE DRAW VERTICAL LINE'
'PROCEDURE DRAW HORIZONTAL LINE'
'PROCEDURE     LOOP ERROR'
#
'DRAW BIG PICTURE'
|
'LOOP'
|
'LOOP'
|
'INITIALISE PARAMS& SELECT ISO UNITS'
'CALL DRAW THE FLOW CHART'
'ADVANCE FILM'
'END'
#
'END'
#
'END'
#
'END'
#
'END'
#
'END'
#
'END'
#
.END OF FLOW;
****

APPENDIX 5: SOURCE PROGRAM LISTING OF FR80 DIMENSIONAL FLOW CHART GENERATOR

08/02/77  COMPILED BY XALH MK. 1C 

'LIST' (LP) 
'LIBRARY' (ED,A.SUBROUTINES) 
'PROGRAM' (SWA) 
'INPUT' 0,7=CR0 
'INPUT' 5 = TR5 
'OUTPUT' 0=LP0 
'OUTPUT' 2=LP0
'OUTPUT' 4=LP0 
'OUTPUT' 5 = LP5 
'OUTPUT' 12= LP1 
'OUTPUT' 13=LP2 
'SPACE' 15000 
'BEGIN' 
'BOOLEAN' 'PROCEDURE' ALGOBEY (S); 
   'STRING' S; 'EXTERNAL'; 
   'BOOLEAN' TR5; 

   SELECT CAMERA (7); 
   IDENTIFICATION; 

   'BEGIN' 
      'INTEGER' XMAX,YMAX; 
      'INTEGER' CH HEIGHT,CH WIDTH; 
      'INTEGER' HEIGHT 2 CH,WIDTH 3 CH,CH SP; 
      'INTEGER' DTB,DRP,DNS; 
      'INTEGER' DELTA MLP; 
      'REAL' RJX,RKY; 
      'REAL' TOP WINDOW,LEFT WINDOW,BOTTOM WINDOW,RIGHT WINDOW; 

      'BOOLEAN' FIRST TIME, INTERSECT; 
      'INTEGER' COUNT, NODE NUM; 
      'INTEGER' 'ARRAY' NODE TABLE [1:2,1:5000]; 

      'INTEGER' BLANK,SHRIEK,HYPHEN,BACKSLASH,HASH; 
      'INTEGER' ENDLINE,EQUALS,QUERY,SQUOTE,SEMICOLON; 
      'INTEGER' FULLSTOP; 

      BLANK := CODE('('%')'); 
      SHRIEK := CODE('('!')'); 
      HYPHEN := CODE('('-')'); 
      BACKSLASH := CODE('('$')'); 
      HASH := CODE('('#')'); 
      ENDLINE := CODE('('EL')'); 
      EQUALS := CODE('('=')'); 
      QUERY := CODE('('?')'); 
      SQUOTE := COOE('(''')'); 
      SEMICOLON := CODE('(';')'); 
      FULLSTOP := CODE('('.')'); 

      SELECT INPUT (5): 
      XMAX := YMAX := READ; 
      CH HEIGHT := CH WIDTH := 8; 
      HEIGHT 2 CH := 16; 
      WIDTH 3 CH := 20; 
      CH SP := 2; 
      DNS := 10; 'COMMENT' NODE SPACING; 
      DTB := 5; 'COMMENT' LENGTH OF VERTICAL STATEMENT LINE: 
      DRP := 40; 'COMMENT' HORIZONTAL OFFSET FOR NEXT PARALLEL NODE; 
      DELTA MLP := 100; 'COMMENT' HORIZ OFFSET FOR ML PARAS; 

      'BEGIN' 
         LIMITS ( 0,0,16383,16383 ); 
         REGION ( 1995,1995,14393,14393,0 ); 
         LIMITS ( 0,YMAX,XMAX,0 ); 
         REGION ( 0,YMAX,XMAX,0,1 ); 

         SELECT REGION (1); 
         LIMITS ( 0,YMAX,XMAX,0 ); 

         CHARACTER SIZE ( CH HEIGHT,CH WIDTH ); 

'BEGIN' 

   DRAW 30 FLOWCHART: 
   'BEGIN' 
      'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 
      'INTEGER' CH; 
      'INTEGER' J; 

   'INTEGER' 'PROCEDURE' MAX (A,B); 
   'VALUE' A,B; 
   'INTEGER' A,B; 
   
   'BEGIN' 
      MAX := 'IF' A 'GT' B 'THEN' A 'ELSE' B; 
   'END'; 

   'INTEGER' 'PROCEDURE' GCHAR (CHARACTER); 
   'VALUE' CHARACTER; 
   'INTEGER' CHARACTER; 

   'BEGIN' 
      'COMMENT' NEWLINE {1);
      'COMMENT' PRINT CH (CH); 
      'COMMENT' PRINT ( CHARACTER,12,0 );
  
      'IF' CHARACTER= ENDLINE 'THEN' 
      'BEGIN' 
         WRITE TEXT ('('EL%ERROR')');
         'GOTO' FINI; 
      'END'; 

      'IF' CHARACTER 'GE' 0 'AND' CHARACTER 'LE' 9 
           'THEN' CHARACTER := CHARACTER + 16 
      'ELSE' 'IF' CHARACTER 'GE' 3873 'AND' CHARACTER 'LE' 3898 
           'THEN' CHARACTER := CHARACTER - 3840 
      'ELSE' 'IF' CHARACTER = 29 'OR' CHARACTER = 30 
           'THEN' CHARACTER := CHARACTER + 1 
      'ELSE' 'IF' CHARACTER = 24 'OR' CHARACTER = 25 
           'THEN' CHARACTER := CHARACTER - 16 
      'ELSE' 'IF' CHARACTER = 18 'OR' CHARACTER = 31 
           'THEN' CHARACTER := CHARACTER - 16 
      'ELSE' 'IF' CHARACTER = 17 'OR' CHARACTER = 21 
           'THEN' CHARACTER := CHARACTER + 49 
      'ELSE' 'IF' CHARACTER = 16 
           'THEN' CHARACTER := 1 
      'ELSE' 'IF' CHARACTER = 28 
           'THEN' CHARACTER := 10 
      'ELSE' 'IF' CHARACTER = 26 
           'THEN' CHARACTER := 14 
      'ELSE' 'IF' CHARACTER = 27 
           'THEN' CHARACTER := 29 
      'ELSE' 'IF' CHARACTER = 10 
           'THEN' CHARACTER := 79 
      'ELSE' 'IF' CHARACTER = 11 
           'THEN' CHARACTER := 78 
      'ELSE' 'IF' CHARACTER = 12 
           'THEN' CHARACTER := 26 
      'ELSE' 'IF' CHARACTER = 13 
           'THEN' CHARACTER := 28 
      'ELSE' 'IF' CHARACTER = 14 
           'THEN' CHARACTER := 27 
      'ELSE' 'IF' CHARACTER = 15 
           'THEN' CHARACTER := 12 
      'ELSE' 'IF' CHARACTER = 19 
           'THEN' CHARACTER := 69 
      'ELSE' 'IF' CHARACTER = 22 
           'THEN' CHARACTER := 13 
      'ELSE' 'IF' CHARACTER = 23 
           'THEN' CHARACTER := 32 
      'ELSE' 'IF' CHARACTER = 20 
           'THEN' CHARACTER := 67 
      'ELSE' 'IF' CHARACTER = 3872 
           'THEN' CHARACTER := 96 
      'ELSE' 'IF' CHARACTER = 3899 
           'THEN' CHARACTER := 81 
      'ELSE' 'IF' CHARACTER = 4020 
           'THEN' CHARACTER := 75 
      'ELSE' 'IF' CHARACTER = 4021 
           'THEN' CHARACTER := 82 
      'ELSE' 'IF' CHARACTER = 4022 
           'THEN' CHARACTER := 68 
      'ELSE' 'IF' CHARACTER = 4023 
           'THEN' CHARACTER := 91 
      'ELSE' CHARACTER := -1;
      'COMMENT'   PRINT   ( CHARACTER,12,0 );   
      GCHAR   := CHARACTER;       
   'END';               

   'PROCEDURE' DRAW THE FLOWCHART (TOP,LEFT,BOTTOM,RIGHT); 
   'VALUE' TOP,LEFT; 
   'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 

   'BEGIN' 
      'INTEGER' NEW TOP,NEW LEFT,NEW BOTTOM,NEW RIGHT; 
      'INTEGER' J; 

      WRITE HEADING: 
      'BEGIN' 
          NEWLINE (1); 
  'COMMENT' 
         WRITE TEXT ('('FLOWCHART')'); 
         'COMMENT' NEWLINE (1); 
      'END'; 

      PRINT NAME OF FLOWCHART: 
      'BEGIN' 

         JUMP OVER NAME: 
         'BEGIN' 
            'FOR' J := 1 'STEP' 1 'UNTIL' 7 'DO' CH := READCH; 
         'END'; 
      
         MOVE TYPE TO ( LEFT,TOP ); 

         J := 0; 
         'FOR' J := J + 1 'WHILE' CH 'NE' SEMICOLON 
         'AND' J < 82 'DO' 

         'BEGIN' 
            PRINT CH (CH); 
            TYPE ( GCHAR(CH) ); 
            CHARACTER SPACE ( CH SP ); 
            CH := READCH; 
         'END'; 

         'IF' J = 82 'THEN' 
         'BEGIN' 
            WRITE TEXT ('('ERR0R%IN%COPY%TILL%;')'); 
            'GOTO' FINI: 
         'END'; 

         COPYTEXT ('('!')'): 

      'END'; 

      RESET POINTERS TO DRAW NEXT LEVEL: 
      'BEGIN' 
         NEW TOP := NEW BOTTOM := TOP + HEIGHT 2CH; 
         NEW LEFT := NEW RIGHT := LEFT; 
      'END'; 

      DRAW NEXT LEVEL (NEW TOP,NEW LEFT,NEW BOTTOM,NEW RIGHT); 
      
      RESET POINTERS TO TOP OF NEW RECTANGLE: 
      'BEGIN' 
         NEW TOP := NEW BOTTOM: 
         NEW LEFT := NEW RIGHT; 
      'END': 
      PRINT OUT POINTERS (NEW TOP,NEW LEFT,NEW BOTTOM,New RIGHT): 
      DRAW NODE (NEW TOP,NEW LEFT,NEW BOTTOM,NEW RIGHT); 
      PRINT OUT POINTERS (NEW TOP,NEW LEFT,NEW BOTTOM,NEW RIGHT); 
      J := 0;
      'FOR' J := J + 1 'WHILE' CH 'NE' FULLSTDP
       'AND'  ( J < 82) 'DO' CH := READCH; 

      'IF' J = 82 'THEN' 
      'BEGIN' 
         WRITE TEXT ('('.ERROR')'); 
         PRINT CH (CH); 
         LOOP ERROR (NEW TOP,NEW LEFT,NEW BOTTOM,NEW RIGHT); 
      'END' ; 
         BOTTOM := NEW BOTTOM; 
         RIGHT := NEW RIGHT; 
         COPY TEXT('(';')'); 

   'END'; 

   'PROCEDURE' GET NON BLANK CHAR (CH); 
   'INTEGER' CH; 

   'BEGIN' 
      'INTEGER' J; 
      
      SKIP CH; 
      CH := NEXTCH; 

      J := 0; 
      'FOR' J := J + 1 'WHILE' ( CH = BLANK 
       'OR' CH = ENDLINE) 'AND' ( J < 82 ) 'DO' 

      'BEGIN' 
         SKIP CH; 
         CH := NEXTCH: 
      'END'; 

      'IF' J = 82 'THEN' 
      'BEGIN' 
         WRITE TEXT ('('ERROR%IN%NON%BLANK%CHAR')'); 
         PRINT CH (CH); 
         'GOTO' FINI; 
      'END'; 

   'END'; 

   'PROCEDURE' DRAW NEXT LEVEL (TOP,LEFT,BOTTOM,RIGHT): 
   'VALUE' TOP,LEFT; 
   'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 

   'BEGIN' 
      'INTEGER' DIAGONAL; 

      DIAGONAL := 25; 
      
      WRITE NEXT LEVEL: 
      'BEGIN' 
         'COMMENT' NEWLINE(1); 
  'COMMENT' 
          WRITE TEXT ('('NEXT%LEVEL')'); 
         'COMMENT' NEWLINE (1);   
      'END'; 

      DRAW DIAGONAL LINE: 
      'BEGIN' 
         RIGHT := ( LEFT + WIDTH 3 CH ) + DIAGONAL; 
         BOTTOM := TOP + DIAGONAL; 

         VECTOR ( LEFT + WIDTH 3CH,TOP,RIGHT,BOTTOM); 
      'END'; 

   'END'; 

   'PROCEDURE' PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 
   'VALUE' T0P,LEFT,BOTTOM,RIGHT; 
   'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 
   
   'BEGIN' 
      NEWLINE (1); 
      PRINT ( TOP,6,0 ); 
      PRINT ( LEFT,6,0 ); 
      PRINT ( BOTTOM,6,0 ); 
      PRINT ( RIGHT,6,0 ); 
      NEWLINE (1); 
   'END'; 

   'PROCEDURE' DRAW NODE (TOP,LEFT,BOTTOM,RIGHT); 
   'VALUE' TOP, LEFT; 
   'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 
   
   'BEGIN' 
      'INTEGER' NWTOP,NWLEFT,NWBOTTOM,NWRIGHT; 
      'INTEGER' NODE ENTRY; 
      
      NUTOP := TOP; 
      NWLEFT := LEFT; 
      NWBOTTOM := BOTTOM; 
      NWRIGHT := RIGHT; 

      'COMMENT' NODE WINDOWING MECHANISM; 

      'IF' NODE NUM < 5000 'THEN' NODE NUM := NODE NUM + 1 
                  'ELSE' 'BEGIN' WRITE TEXT ('('NODETABLE OVERFLOW')'); 
                                 'GOTO' FINI 'END'; 
      NODE ENTRY := NODE NUM; 

      'IF' FIRST TIME 
            'THEN' 'BEGIN' 
            'COMMENT' ALLWAYS DRAW; 
            INTERSECT := 'TRUE'; 
            'END'
      'ELSE' 'BEGIN' 
            NWBOTTOM := NODE TABLE[1,NODENUM];
            NWRIGHT  := NODE TABLE[2,NODENUM];
            INTERSECT :=
             'IF' NWRIGHT  < RJX       'THEN' 'FALSE'
      'ELSE' 'IF' RJX+XMAX < NWLEFT    'THEN' 'FALSE'
      'ELSE' 'IF' NWTOP    > RKY+YMAX  'THEN' 'FALSE'
      'ELSE' 'IF' RKY      > NWLBOTTOM 'THEN' 'FALSE'
      'ELSE' 'TRUE';
            'END';
      'IF' INTERSECT 
      'THEN' 'BEGIN' 
                DRAW THE NODE (NWTOP,NWLEFT,NWBOTTOM,NWRIGHT); 
                NODE TABLE[1,NODE ENTRY] := NWBOTTOM; 
                NODE TABLE[2,NODE ENTRYJ := NWRIGHT; 
             'END' 
       'ELSE' 'BEGIN' 

       'COMMENT' SKIP TO CORRESPONDING HASH; 
       CH := READCH; 
       COUNT := 1; 
       'FOR' COUNT:=COUNT 'WHILE' COUNT 'NE' 0 
       'DO' 'BEGIN' 
       CH := READCH; 
       'IF' (CH = SHRIEK) 'OR' 
            (CH = EQUALS) 'OR' 
            (CH = HYPHEN) 
       'THEN' 'BEGIN' COUNT := COUNT + 1; NODENUM := NODENUM + 1; 'END' 
       'ELSE' 'IF' CH = HASH 'THEN' COUNT:= COUNT + 1 
       'ELSE' 'IF' CH = SQUOTE 'THEN' 'BEGIN' 
                 'FOR' CH := READCH 'WHILE' CH 'NE' SQUOTE 'DO' 'END' 
       'ELSE' 'IF' CH = QUERY 'THEN' 'BEGIN' 
                 'FOR' CH := READCH 'WHILE' CH 'NE' QUERY 'DO' 'END' 
       'ELSE' 
              'END'; 

       'COMMENT' SKIP OVER HASH; 
       'IF' CH = HASH 'THEN' GET NON BLANK CHAR (CH) 
                 'ELSE' 'BEGIN' 
                 WRITE TEXT ('('NODE%WINDOW%ERROR')'); 
                 PRINT CH (CH); 
                 'END': 
             'END'; 
       BOTTOM := NWBOTTOM; 
       RIGHT  := NWRIGHT; 

       'GOTO' MISS OUT PRINTING; 
       
       NEWLINE (4); 
       WRITE TEXT ('(' NODE%TABLE ')'); 
       PRINT (NODE ENTRY,10,0); PRINT (NODE NUM,10,0); NEWLINE (1); 

       'FOR' COUNT := 1 'STEP' 1 'UNTIL' NODE NUM 
          'DO' 'BEGIN' 
          PRINT (COUNT,10,0); 
          PRINT (NODETABLE[1,COUNT],10,0); 
          PRINT (NODETABLE[2,COUNT],10,0); 
          NEWLINE (1); 
         'END'; 

      PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 
      MISS OUT PRINTING;

      'END' NODE WINDOWING PROC; 

         'PROCEDURE' DRAW THE NODE (TOP,LEFT,BOTTOM,RIGHT); 
         'VALUE' TOP,LEFT, 
         'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 

         'BEGIN'  
            'INTEGER' NEW TOP,NEW LEFT,NEW BOTTOM,NEW RIGHT; 
            'INTEGER' MAX NEW BOTTOM,MAX NEW RIGHT; 

            'INTEGER' TOP MLP, LEFT MLP, BOTTOM MLP, RIGHT MLP; 
            'INTEGER' MAX BOTTOM MLP, MAX RIGHT MLP; 

            'INTEGER' J; 
            WRITE NODE: 
            'BEGIN' 
               'COMMENT' NEWLINE (1); 
         'COMMENT' 
               WRITE TEXT ('('NODE')'); 
            'END'; 

         'COMMENT' 
             PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 

            RESET POINTERS FOR NODE: 
            'BEGIN' 
               NEW TOP := TOP; 
               NEW LEFT := LEFT; 
               NEW BOTTOM := MAX NEW BOTTOM := TOP + DNS; 
               NEW RIGHT := MAX NEW RIGHT := LEFT: 
            'END'; 

            GET NON BLANK CHAR (CH); 
            DRAW ONE OR MORE SERIALS: 
            'BEGIN'
               J := 0; 
               'FOR' J := J + 1 'WHILE' ( CH = SQUOTE
               'OR' CH = QUERY ) 'AND' ( J < 5000 ) 'DO'
               
               'BEGIN' 
                  DRAW SERIAL (NEW TOP,NEW LEFT,NEW BOTTOM,NEW RIGHT);
                  MAX NEW BOTTOM := MAX ( NEW BOTTOM,MAX NEW BOTTOM );
                  MAX NEW RIGHT := MAX ( NEW RIGHT,MAX NEW RIGHT );
               'END';
               
               'IF' J = 5000 'THEN' 
               'BEGIN' 
                  WRITE TEXT ('('ONE%OR%MORE%SERIALS%ERROR')');
                  PRINT CH (CH); 
                  LOOP ERROR (NEW TOP,NEW LEFT,NEW BOTTOM,NEW RIGHT); 
               'END'; 

            'COMMENT' DRAW ZERO OR MORE MIN LENGTH PARALLEL NODES; 

            'IF' CH = EQUALS 'THEN' 
            'BEGIN' 

            SETUP MIN LEN PARALLELS: 
               'BEGIN' 
               TOP MLP := BOTTOM MLP := MAX BOTTOM MLP := TOP; 
               LEFT MLP := LEFT; 
               RIGHT MLP := MAX RIGHT MLP := MAX NEW RIGHT; 
               'END'; 

            DRAW MLP S: 
            'BEGIN' 
            J := 0; 
            'FOR' J:=J+1 'WHILE' ((CH = EQUALS) 'AND' (J<50)) 'DO' 
            'BEGIN' 
            'COMMENT' NEWLINE(1); 
            'COMMENT' WRITE TEXT ('('MIN%LEN%PARALLEL')'); 
            'COMMENT' PRINT OUT POINTERS (TOP MLP, LEFT MLP, 
                                      BOTTOM MLP, RIGHT MLP); 

            DRAW HORIZONTAL LINE (TOP MLP, LEFT MLP, 
                                 BOTTOM MLP, RIGHT MLP+DELTA MLP); 
            LEFT MLP := RIGHT MLP := RIGHT MLP + DELTA MLP; 
            BOTTOM MLP := TOP MLP; 

            DRAW NODE (TOP MLP, LEFT MLP, BOTTOM MLP, RIGHT MLP); 
            
            MAX BOTTOM MLP  := MAX ( BOTTOM MLP, MAX BOTTOM MLP); 
            MAX RIGHT MLP := MAX ( RIGHT MLP, MAX RIGHT MLP); 

           'END' OF WHILE LOOP; 
         'IF' J 'GE' 50 'THEN' 
           'BEGIN' 
           WRITE TEXT ('('MIN%LEN%PAR%LOOP%ERROR')'); 
           PRINT CH (CH); 
           LOOP ERROR (TOP MLP, LEFT MLP, BOTTOM MLP, RIGHT MLP); 
           'END'; 

         MAX NEW BOTTOM := MAX ( MAX BOTTOM MLP, MAX NEW BOTTOM); 
         MAX NEW RIGHT := MAX ( MAX RIGHT MLP, MAX NEW RIGHT); 

         'END' OF DRAW MLP S; 

      'END' OF MIN LEN PARALLELS; 

         'IF' CH 'NE' HASH 'THEN' 
         'BEGIN' 
            WRITE TEXT ('('#ERROR')'); 
            PRINT CH (CH); 
            'GOTO' FINI; 
         'END'; 


         GET NON BLANK CHAR (CH); 

         BOTTOM := MAX ( BOTTOM, (MAX NEW BOTTOM + DNS) ) ; 
         RIGHT := MAX ( RIGHT,MAX NEW RIGHT ); 
      'END'; 

   'COMMENT' 
      WRITE TEXT ('('END%OF%NODE')');
   'COMMENT' 
      PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 
   'END'; 

   'PROCEDURE' DRAW SFRIAL (TOP,LEFT,BOTTOM,RIGHT)'; 
   'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 

   'BEGIN' 
      'INTEGER' TOP SERIAL,LEFT SERIAL,BOTTOM SERIAL,RIGHT SERIAL;
      'INTEGER' NEXT TOP,NEXT LEFT,NEXT BOTTOM,NEXT RIGHT;
      'INTEGER' TOP  PARA,LEFT PARA,BOTTOM PARA, RIGHT PARA;
      'INTEGER' MAX BOTTOM PARA,MAX RIGHT PARA;
      'INTEGER' J; 

      WRITE SERIAL: 
      'BEGIN' 
         'COMMENT' NEWLINE ( 1 ); 
   'COMMENT' 
         WRITE TEXT ('('SERIAL')'); 
   'COMMENT' 
          PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 
       'END'; 

       DRAW VERTICAL LINE (TOP,LEFT,(BOTTOM + DTB),RIGHT); 
       RESET SERIAL POINTERS; 
       'BEGIN' 
          TOP SERIAL := BOTTOM SERIAL := BOTTOM + DTB: 
          LEFT SERIAL := RIGHT SERIAL := LEFT; 
       'END'; 

       DRAW STATEMENT (TOP SERIAL,LEFT SERIAL, BOTTOM SERIAL,
                       RIGHT SERIAL);

       SET PARALLEL POINTERS: 
       'BEGIN' 
          TOP PARA := BOTTOM PARA := MAX BOTTOM PARA := TOP; 
          LEFT PARA := LEFT; 
          RIGHT PARA := MAX RIGHT PARA := RIGHT SERIAL; 
       'END'; 

       NEXT LEVEL: 
       'BEGIN' 
          GET NON BLANK CHAR (CH); 

          NEXT TOP := NEXT BOTTOM := 0; 
          NEXT LEFT := NEXT RIGHT := 0; 

          'IF' CH = SHRIEK 'THEN' 
          'BEGIN' 

             RESET NEXT LEVEL POINTERS: 
             'BEGIN' 
                NEXT TOP := BOTTOM SERIAL; 
                NEXT LEFT := LEFT; 
             'END'; 

             'COMMENT' NEWLINE (1); 
    'COMMENT' 
             WRITE TEXT ('('SERIAL~NEXT%LEVEL')'); 

             DRAW NEXT LEVEL (NEXT TOP,NEXT LEFT,NEXT BOTTOM, 
                              NEXT RIGHT); 

             NEXT TOP := NEXT BOTTOM; 
             NEXT LEFT := NEXT RIGHT; 

             DRAW NODE (NEXT TOP,NEXT LEFT,NEXT BOTTOM,NEXT RIGHT); 
                  
             RIGHT PARA := MAX RIGHT PARA := MAX ( RIGHT PARA, 
                                                   NEXT RIGHT); 
          'END'; 
               
       'END'; 

       PARALLEL: 
       'BEGIN' 
          J := 0; 
          'FOR' J := J + 1 'WHILE' CH = HYPHEN 
          'AND' ( J < 82 ) 'DO' 

          'BEGIN' 
 
               'COMMENT' NEWLINE (1); 
     'COMMENT'
               WRITE TEXT ('('SERIAL-PARALLEL')'); 

     'COMMENT' 
               PRINT OUT POINTERS (TOP PARA,LEFT PARA,BOTTOM PARA, 
                                   RIGHT PARA); 

               DRAW HORIZONTAL LINE (TOP PARA,LEFT PARA,BOTTOM PARA, 
                                     (RIGHT PARA + DRP )); 

               LEFT PARA := RIGHT PARA := RIGHT PARA+ DRP: 
               BOTTOM PARA := TOP PARA; 

               DRAW NODE (TOP PARA,LEFT PARA,BOTTOM PARA,RIGHT PARA); 
               MAX BOTTOM PARA := MAX ( BOTTOM PARA,MAX BOTTOM PARA ); 
               MAX RIGHT PARA := MAX ( RIGHT PARA,MAX RIGHT PARA ); 

            'END'; 

            'IF' J = 82 'THEN' 
            'BEGIN' 
               WRITE TEXT ('('PARALLEL%LOOP%ERROR')'); 
               PRINT CH (CH); 
               LOOP ERROR (TOP PARA,LEFT PARA,BOTTOM PARA,RIGHT PARA); 
            'END'; 

         'END'; 

         OVERALL SIZES: 

         'BEGIN' 
            TOP := BOTTOM SERIAL; 
            BOTTOM := MAX ( BOTTOM SERIAL,MAX (NEXT BOTTOM,BOTTOM PARA) ); 
            RIGHT := MAX ( RIGHT SERIAL,MAX (NEXT RIGHT,RIGHT PARA) ); 
         'END'; 

         'COMMENT' NEWLINE (1);
      'COMMENT' 
          WRITE TEXT ('('END%OF%SERIAL')'); 

      'COMMENT' 
          PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 
       'END'; 
       
       'PROCEDURE' DRAW VERTICAL LINE (TOP,LEFT,BOTTOM,RIGHT); 
         'VALUE' TOP,LEFT,BOTTOM,RIGHT; 
         'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 

         'BEGIN' 
            'COMMENT' NEWLINE (1); 
        'COMMENT' 
            WRITE TEXT ('('VERTICAL%LINE')'); 
        'COMMENT' 
            PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 

            VECTOR ( LEFT,TOP,LEFT,BOTTOM ); 
         'END'; 

       'PROCEDURE' DRAW STATEMENT (TOP,LEFT,BOTTOM,RIGHT); 
       'VALUE' TOP,LEFT; 
       'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 

       'BEGIN' 
          'INTEGER' TOP TEXT, RIGHT TEXT; 
          'INTEGER' J; 
          'BOOLEAN' ACTION; 

          'IF' CH = SQUOTE 'THEN' ACTION := 'TRUE' 
             'ELSE' 'IF' CH = QUERY 'THEN' ACTION := 'FALSE' 
                     'ELSE' 
                     'BEGIN,' 
                        WRITE TEXT ('('?%OR%'%ERR0R')'); 
                        PRINT CH (CH); 
                        'GOTO' FINI; 
                     'END': 

          WRITE OUT TEXT: 
          'BEGIN' 

             SET TEXT POINTERS: 
                'BEGIN' 
                   TOP TEXT :=T OP+ CH HEIGHT: 
                   RIGHT TEXT := RIGHT := LEFT; 
                'END'; 
                
            'COMMENT' NEWLINE (1); 
            GET NON BLANK CHAR (CH); 
            MOVE TYPE TO ( LEFT,TOP TEXT); 

            J := O; 
            'FOR' J := J + 1 'WHILE' 
            'NOT' ((CH= ('IF' ACTION 'THEN' $QUOTE 'ELSE' QUERY)) 'OR' J 'GE' 999) 
             'DO' 
             'BEGIN' 
             'IF' CH = ENDLINE 'THEN' 
             START NEW LINE OF TEXT: 

             'BEGIN' 
                RIGHT := MAX (RIGHT, RIGHT TEXT); 
                TOP TEXT := TOP TEXT+ HEIGHT 2 CH; 
                MOVE TYPE TO (LEFT, TOP TEXT); 

                RIGHT TEXT := LEFT: 
                GET NON BLANK CHAR (CH): 
             'END' 
             'ELSE' 
                'BEGIN' 
                   'COMMENT' PRINT CH (CH); 

            'COMMENT' WINDOWING FRIG ; 
            'IF' ( LEFT WINDOW < RIGHT TEXT) 'THEN' 'BEGIN' 
            'IF' (RIGHT TEXT < RIGHT WINDOW) 'THEN' 'BEGIN' 
            'IF' (TOP WINDOW  < TOP TEXT) 'THEN' 'BEGIN' 
            'IF' (TOP TEXT < BOTTOM WINDOW) 
            'THEN' 'BEGIN' 
                        MOVE TYPE TO (RIGHT TEXT,TOP TEXT); 
                        TYPE ( GCHAR(CH) ); 
                        CHARACTER SPACE ( CH SP ); 

              'END' 'END' 'END' 
              'END' ;

                        RIGHT TEXT := RIGHT TEXT+ CH WIDTH+ CH SP; 
                        SKIP CH; 
                        CH := NEXTCH; 
              'END'; 
              'END' ; 
              'IF' J = 999 'THEN' 
              'BEGIN' 
                 NEWLINE (1); 
                 WRITE TEXT ('('WRITE%OUT%TEXT%ERR0R')'); 
                 PRINT CH (CH); 
                 LOOP ERROR (TOP,LEFT,BOTTOM,RIGHT); 
              'END'; 

              OVERALL SIZE OF TEXT
                 'BEGIN' 
                    BOTTOM : = TOP TEXT := CH HEIGHT;
                    RIGHT := MAX(RIGHT, RIGHT TEXT);
                 'END'; 

            'END'; 
            'IF' ((ACTION 'EQUIV' 'TRUE') 'AND' (CH= QUERY)) 
             'OR' ((ACTION 'EQUIV' 'FALSE') 'AND' 
                    (CH = SQUOTE)) 'THEN' 

            'BEGIN' 
              WRITE TEXT ('('ACTION%OR%'%OR%?%ERROR')'); 
              PRINT CH (CH); 
              'GOTO' FINI; 
            'END'; 

            'IF' ACTION 'EQUIV' 'TRUE' 'THEN' 
            'BEGIN' 
            
                   'COMMENT' SPACE OVER TEXT I,E, DO NOTHING; 

            'END'; 

            'IF' ACTION 'EQUIV' 'FALSE' 'THEN' 
            'BEGIN' 

               DRAW HALF SQUARE: 
               'BEGIN' 
                  'COMMENT' NEWLINE (1); 
        'COMMENT' 
                   WRITE TEXT ('('HALF-SQUARE')'); 
                   VECTOR ( LEFT,TOP,(LEFT - CH WIDTH),TOP); 
                   VECTOR ((LEFT - CH WIDTH),TOP,(LEFT ~ CH WIDTH),BOTTOM ); 
                   VECTOR ((LEFT - CH WIDTH),BOTTOM,LEFT,BOTTOM ); 
                'END'; 
                
             'END'; 
             
          'END'; 

         'PROCEDURE' DRAW HORIZONTAL LINE (TOP,LEFT,BOTTOM,RIGHT); 
         'VALUE' TOP,LEFT,BOTTOM,RIGHT; 
         'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 

         'BEGIN' 
             'COMMENT' NEWLINE (1); 
         'COMMENT' 
            WRITE TEXT ('('HORIZONTAL%LINE')'); 

         'COMMENT'
             PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 

             VECTOR ( LEFT,TOP,RIGHT,TOP ); 
         'END'; 

         'PROCEDURE' LOOP ERROR (TOP,LEFT,BOTTOM,RIGHT); 
         'VALUE' TOP,LEFT,BOTTOM,RIGHT; 
         'INTEGER' TOP,LEFT,BOTTOM,RIGHT; 

         'BEGIN' 
            WRITE TEXT ('('A%L00P%ERR0R%HAS%0CCURRED')'); 
            PRINT CH (CH); 

            PRINT OUT POINTERS (TOP,LEFT,BOTTOM,RIGHT); 
            
            'GOTO' FINI; 
         'END'; 

         DECIDE ON INPUT OUTPUT STREAMS: 
         'BEGIN' 
            SELECT INPUT (5); 
            SELECT OUTPUT (5); 
         'END'; 

         SET INITIAL VALUES OF POINTERS: 
         'BEGIN' 
            TOP := BOTTOM := 100; 
            LEFT := RIGHT := 100; 
         'END'; 

      'COMMENT' INITIALISE NODE WINDOWING: 
         FIRST TIME := 'TRUE'; 

         DRAW THE BIG PICTURE: 
         'BEGIN' 
         'FOR' RJX := 0 'STEP' XMAX 'UNTIL' RIGHT 'DO' 
         'BEGIN' 
            'FOR' RKY := 0 'STEP' YMAX 'UNTIL' BOTTOM 'DO' 
            'BEGIN' 
               FREE INPUT; 
               TR5 :; ALGOBEY ('('RL%*TR5')'); 
               TR5 := ALGOBEY ('('AS%*TR5,£E')'); 
               SELECT INPUT (5); 

               TOP := BOTTOM := 100; 
               LEFT := RIGHT := 100; 
               XMAX := YMAX := READ; 

            TOP  WINDOW := RKY - 50;
            LEFT WINDOW := RJX - 50;
            BOTTOM WINDOW := RKY + YMAX - 50; 
            RIGHT  WINDOW := RJX + XMAX - 50;
         
      NODE NUM := O; 

               LIMITS (RJX,RKY+YMAX,RJX+XMAX,RKY); 
               DRAW THE FLOWCHART (TOP,LEFT,BOTTOM,RIGHT); 
               VECTOR (RJX+XMAX,RKY,RJX+XMAX,RKY+YMAX); 
               VECTOR (RJX     ,RKY,RJX     ,RKY+YMAX); 
               ADVANCE FILM; 
               FIRST TIME := 'FALSE'; 
             'END'; 
             ADVANCE FILM; 
          'END': 

          'END': 

           FINI : 
           'BEGIN' 
              NEWLINE (3); 
           'END'; 

           'END': 

        'END'; 

           'END'; 

           'END'; 

           ENDPLOTTING; 

        'END'; 

⇑ Top of page
© Chilton Computing and UKRI Science and Technology Facilities Council webmaster@chilton-computing.org.uk
Our thanks to UKRI Science and Technology Facilities Council for hosting this site