Centrum Voor Wiskunde en Informatica: Software Engineering
Centrum Voor Wiskunde en Informatica: Software Engineering
SEN
Software Engineering
Software ENgineering
CWI's research has a theme-oriented structure and is grouped into four clusters. Listed below are the names
of the clusters and in parentheses their acronyms.
ISSN 1386-3711
The Dijkstra–Zonneveld ALGOL 60 compiler
for the Electrologica X1
Abstract
In the summer of 1960 Edsger W. Dijkstra and Jaap A. Zonneveld put into operation the
very first ALGOL 60 compiler in the world. Its code was never documented. This report
contains the full assembly text of one of the latest versions of that compiler (from 1964).
In order to make that text more accessible, an equivalent version in Pascal is added,
together with eight chapters introducing the compiler and explaining its major features.
Preface
The main purpose of this document is to preserve the code of what presumably has
been the first working ALGOL 60 compiler. It was written for the Electrologica X1 by
E.W. Dijkstra and J.A. Zonneveld at the Mathematical Centre in Amsterdam in the years
1959 and 1960. Its code has never been documented before.
Somewhere in the period 1962 to 1969, when I was working at the Mathematical Centre
and was in charge of the maintenance of that ALGOL system, I started to type the full
text of the compiler on a Friden Flexowriter, aiming to document the latest version of the
compiler in a Mathematical–Centre report. Due to more urgent work and my departure
from the institute it remained unfinished. Only after my retirement I was able to take up
the project again.
Apart from presenting the compiler code in full, including its commentary in Dutch, much
attention is paid to make that code accessible. This is done in two different ways. First,
an equivalent Pascal version of the compiler code was written and is presented as well.
Second, in a number of chapters the main components of the compiler are described and
many aspects of the compiler are dealt with.
I am grateful for the hospitality of Philips Research Laboratories, where most of the work
of preparing this document was carried out. I also gratefully used computer facilities at
the Eindhoven Technical University. Critical comments of R.R. Hoogerwoord were very
helpful to improve the readability of the text.
It would have been a pleasure to me to dedicate this work to my friends Edsger Dijkstra
and Jaap Zonneveld, from who I learned so much of computing science. Alas, Edsger died
shortly. So I can only dedicate it to Jaap and to the memory of Edsger.
1 Introduction 1
1.1 Some history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 The Electrologica X1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3 Working with the ALGOL system for the X1 . . . . . . . . . . . . . . . . . 11
1.4 Developments of the ALGOL system after 1962 . . . . . . . . . . . . . . . 17
1.5 The Pascal version of the compiler . . . . . . . . . . . . . . . . . . . . . . 18
1.6 The X1–code version of the compiler . . . . . . . . . . . . . . . . . . . . . 19
2 Overview 21
5 Main scan 39
5.1 Structure of the object program . . . . . . . . . . . . . . . . . . . . . . . . 40
5.2 The execution model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
5.2.1 The execution stack . . . . . . . . . . . . . . . . . . . . . . . . . . 43
v
vi CONTENTS
8 Program loading 87
8.1 The original loader program . . . . . . . . . . . . . . . . . . . . . . . . . . 88
8.2 The loader for the ALD7 system . . . . . . . . . . . . . . . . . . . . . . . . 89
8.3 The loading phase of the load–and–go compiler . . . . . . . . . . . . . . . 91
References 327
blanko
Chapter 1
Introduction
This report documents the first ALGOL 60 compiler, written by E.W. Dijkstra and J.A.
Zonneveld at the Mathematical Centre in Amsterdam in the period from november 1959
to august 1960. It was written for the Electrologica X1, a machine developed at the
Mathematical Centre but built by a Dutch computer factory specially founded for that
purpose.
Although Dijkstra wrote a few papers on the compiler [4, 6, 7] and although part of
the total system was documented in reports of the Mathematical Centre, the compiler
code itself never was fully described and documented. This report tries to remedy that
situation. Its value is not the possibility to use the documented code on an X1 emulator
(which can and has been done); nor will it influence the state of the art in compiler
writing. Its value, if any, is purely historical: it is a report on the result of an undertaking
that was new for that time, in spite of the existence of Fortran and Cobol.
ALGOL 60 was a tremendous step forward, a milestone in the development of computing
as a science, and writing a compiler for a language with such a new and rich structure
required the invention of many new techniques. The compiler text shows which solutions
were found for the problems encountered. It also reveals the struggle with many problems.
One of the most impressive facts is that the compiler had to work in a store of 4K 27–bit
words, in which both compiler code and working space had to be embedded.
The X1 ALGOL 60 system became operational in august 1960 and was used at the
Mathematical Centre until the late sixties.
This report presents the compiler text in full. It does so in the (rather primitive) as-
sembly language of the X1, which in its turn is documented in Dijkstra’s PhD thesis
1
2 CHAPTER 1. INTRODUCTION
[1]. Since that compiler text is not very accessible even for readers knowing Dutch and
X1 assembly language, a more or less equivalent version of it in (standard) Pascal has
been added. These compiler codes are preceded by eight chapters explaining the most
important aspects of the compiler.
In the remaining part of this introduction we deal with some general aspects in more
detail.
Prof. Van Wijngaarden and Dr. E.W. Dijkstra attended a congress on ‘ALGOL’ in
Copenhagen. A congress on ‘Information processing processes’ in Paris was attended
by Prof. Van Wijngaarden, J.A. Zonneveld, Dr. T.J. Dekker and M.L. Potters. In
Mainz Van Wijngaarden gave a presentation on ‘Divergent series’, also attending
there the so–called ‘ALGOL’ conference. F.J.M. Barning and Dr. T.J. Dekker took
a course on ‘ALGOL’ in Darmstadt, [. . . ]
A research project that has the special interest of all staff members of the Com-
puting Department is the one concerning the ‘ALGOL’. In international context a
draft is prepared of a universal language: ‘ALGOL’, i.e. ALGO–rithmic Language.
This language shall be as close as possible to the standard notations in mathematics
and be readable without further explanation. The language shall allow the descrip-
tion of any computational process, using the fixed algorithmic expressions, and it
shall be translatable mechanically into machine programs. The definition of such a
language is a big international project. The ‘ALGOL’ is now in ‘statu nascendi’;
1
The annual reports were written in Dutch these years; translation by the author.
1.1. SOME HISTORY 3
several national working groups are working towards its final shape and the inter-
national ‘ALGOL’ conferences organised regularly try to arrive at uniformity in
notation of ALGOL programs; they do so under supervision of the international
ALGOL committee. In this work the Computing Department makes an essential
contribution. From about Oktober 1959 a team of five members of the department
(A. van Wijngaarden, J.A. Zonneveld, E.W. Dijkstra, F.J.M. Barning and miss J.M.
Feringa) are hard at work on the many problems presenting themselves here. As
soon as the ALGOL language is cast in a definitive shape the construction of a
compiler program for the electronic computer X1 can be turned to. This program
shall be capable to derive, from a description in ALGOL, a program by which the
calculations concerned can be executed on the X1.
Edsger Dijkstra, Bram Loopstra and Ria Debets in front of the Mathematical Centre
building, 1954 (photograph G.A. Blaauw)
The 1960 annual report of the Mathematical Centre devotes a long passage to the ALGOL
compiler:
participated in the committee that, in January 1960, would decide on the final shape
of ALGOL, there was ample reason to discuss the various aspects of algorithmic
languages. The last two months of 1959 were also used to study the compiling
technique as we learned it from Prof.Dr. H.D. Huskey and to subject it to a critical
investigation.
Thus, when in January 1960 the final form of ALGOL – baptized ‘ALGOL 60’ in
order to avoid confusion and as an expression of modesty of the composers – was
stated, we already had a fair notion of the problems awaiting us. Moreover, we had
the final data at our disposal at first hand, i.e. very rapidly. Largely due to these
circumstances the ALGOL 60 compiler of the Mathematical Centre would be one
of the first in the world, if not the very first one, that really did work. Possibly
also the fact that precisely at that stage we got our own X1 at our disposal played
a role: we were not yet accustomed to apply this machine in a certain manner and
could therefore more easily start from scratch.
Because the implications of the language permeated to us only gradually we were
not confronted with all problems at the same time and in a number of steps a
closely fitting system was constructed. Then, in March, we had a three–day dis-
cussion in Copenhagen with a number of experts from Regnecentralen, intending
to confront our ideas with theirs before starting the detailed elaboration. Our visit
to Copenhagen resulted in a very important embellishment which we were able to
incorporate in our projects within a couple of weeks. Immediately thereafter de-
tailed elaborations started working in parallel projects. While Dr. E.W. Dijkstra
and J.A. Zonneveld were developing the compiler Miss M.J.H. Römgens and Miss
S.J. Christen started work on the organisational and arithmetic subroutines which
should be at the disposal of the object program during its execution. Where the
problems in the construction of the compiler were mainly of a logical nature, the
work on the subroutines at the service of the object program were aggravated most
by the requirement of maximal efficiency.
By July the compiler was subject to tests for the first time; a few weeks later object
programs produced were actually executed for the first time. Most of the bugs
that were revealed had the character of clerical errors or clear omissions (the latter
especially in the compiler), for which the remedy was immediately obvious. Late
September we had built up such strong confidence in our realization of ALGOL 60
that time was considered ripe for the organization of a course on ‘Programming
in ALGOL 60’. A syllabus was written and in November the first four–day course
was given. Because of the overwhelming interest this course had to be repeated in
December.
The great interest for these courses, the enthusiasm of the course–members and
especially the good experiences with ALGOL 60 that the Computing Department
1.1. SOME HISTORY 5
has acquired itself for its own work confirmed us in the confidence that the labour
invested in the completion of this project was not wasted. On the contrary!
So far our citation of the annual report 1960. Indeed it was an huge project for a computing
department of 11 people. The compiler is about 2000 instructions long, another 2000
instructions support object–program execution. The latter 2000 instructions, constituting
the collection of organisational and arithmetic subroutines supporting object–program
execution, was baptized ‘the Complex’. All these 4000 instructions were written (and
tested) in no more than 9 months, quite a feat for a machine that was only put into use
at the Mathematical Centre in March 1960.
The annual report of 1961 continues the interesting story of the ALGOL 60 project. We
cite:
Edsger Dijkstra and Jaap Zonneveld agreed not shave before the project of writing the ALGOL 60
compiler was done. Which, however, did not imply that they did shave when it was completed as
scheduled August 24, 1960, 16:00 h. Zonneveld had a proper shave in March 1961 (picture from his
personal archive); Dijkstra always kept his beard since.
A few months were spent in writing two internal reports assessing the knowledge
sofar available only by oral communication. These reports regard the construction
of MCPs and the adaptation of the compiler and the complexes to other X1 instal-
lations4 . They were written in order to be able to delegate these activities and to
protect the Computing Department from the burden of these (mainly administra-
tive) activities that are no longer of interest to it.
[. . . ]
With several foreign visitors (both from universities and industry) the problem of
implementing ALGOL 60 for their specific machines was discussed in various degree
of detail.
For the ALGOL 60 compiler for the X1, finished in 1960, the construction of a
library of standard procedures (series AP) was started. Several issues have been
published in 1962.
By these provisions the ALGOL system showed to be a highly serviceable system,
not only for testing and theoretical purposes, but also for production.
After installment of the system about 20% of machine time of the X1 was allocated
for the execution of ALGOL programs. By the middle of 1962 this percentage had
4
The first of these reports is presumably [5]; I never saw the other one.
1.2. THE ELECTROLOGICA X1 7
Some 31 machine code procedures (MCP’s) were published that year in the series AP 100
and some 24 procedures in ALGOL 60 in the series AP 200. Moreover, the complexes
ALD and ALS were printed as the series P (1)200. Also some manuals were released, in
particular for working with ALGOL programs.
A year after completing the compiler, the ALGOL 60 system for the X1 was considered
complete and no further developments to the compiler or to the complexes were planned.
The key players embarked on new endeavours. Dijkstra left the Mathematical Centre in
August 1962 for a chair at the Technical University Eindhoven. Zonneveld returned to
his specialism, numerical analysis, and was now investigating Runge–Kutta methods for
the numerical integration of differential equations, the subject of his PhD thesis[11] in
1964. When I joined the Mathematical Centre in September 1962 the original crew of the
ALGOL 60 project for the X1 was almost dissolved.
The machine on which the work was done, the Electrologica X1 computer at the second floor of the
Mathematical Centre.
It had integer arithmetic only. The number system was one–complement. It had some
double–length instructions, in which registers A and S operated as one double–length
register. This was the case in the (integer) multiplication and division instructions and
in some of the shift instructions. Integer arithmetic was minus–zero preferent.
There was neither floating–point hardware nor support for a stack: all such operations
had to be carried out completely by software. Also support for dynamic (i.e., two–level)
addressing was absent.
The 27 bits of an instruction were, in general, structured in the following way:
notation meaning
0A n A:= A + M[n]
1A n A:= A – M[n]
2A n A:= M[n]
3A n A:= – M[n]
4A n M[n]:= M[n] + A
5A n M[n]:= M[n] – A
6A n M[n]:= A
7A n M[n]:= – A
The system here should be clear. Calling the function digit f we have:
– for f < 4, the destination of the result is the register (A), otherwise the word of memory (M[n]) involved;
– for f < 2 mod 4, the result is formed by addition of register and memory word, otherwise by taking
register or memory word;
– for odd f , the inverse of the (second) operand is used rather than the operand itself.
Register S (‘function letter’ 1) and B (‘function letter’ 4) had analogous instructions.
For register T (’function letter’ 5), the instruction counter, we had:
The X1 had no operating system. It had two states, running or stopped. When running it
could be stopped by turning a switch (Stop Next Instruction) or by setting a stop address
in a number of toggles. It also stopped by executing a stop instruction. When stopped it
could be started by pressing a button. Button 1 started the assembler which was present
in read–only store (addresses from ‘0 D 0’).
At the Mathematical Centre the X1 was installed in 1960 and put into daily use March
8th, 1960. Its (read/write) store was extended from 8K to 12K words in May, 1962. It
had no backing store whatsoever (apart from paper tape). Originally it had a console
typewriter, a tape reader and a tape punch as sole peripherals; later a fast tape punch
and a plotter were connected.
3. the tape(s) containing the ALGOL 60 program a second time (during the reading
of this tape the object–program tape was punched),
If an ALGOL program did not use any of the library routines the reading of cross reference
and library could be skipped; if a program had no input the last step had to be skipped.
The reading of each tape had to be started by pushing one of the console buttons.
The greatest shortcoming of the system, however, was the almost complete absence of
syntax checks and run–time checks. At compile time most checks had to do with the
representation of the basic symbols on tape (mistrusting the proper functioning of the
Flexowriter punch and the X1 tape reader) and with store management; there was also a
check on undeclared identifiers. The run–time checks involved the arithmetic (especially
integer overflow) and again the lexical level of the input tape, but did not cover stack
overflow or array indices out–of–bound. A complete list of the error–stop numbers is given
in Appendix A.
In case of a compile–time stop the operator could give as feed back to the programmer
only the error number and the list of identifiers typed on the console typewriter7 and
could mark the position of the source tape in the tape reader at the moment of the stop.
Even the error stop for an undeclared identifier did not mention that identifier!
Also in case of a run–time stop an error number was returned to the programmer, together
with the output produced thusfar. There was no program debugger available. In case of
erroneous results the only means of debugging was to recompile and rerun the program
7
During the second reading of the source text the identifiers of labels, procedures and switches were
typed when processing their declaration started.
1.3. WORKING WITH THE ALGOL SYSTEM FOR THE X1 13
with more output statements for intermediate results added to the source text. The
stepwise execution of an ALGOL object program, using the start and stop buttons of the
console, required, apart from a lot of machine time, an enormous knowledge of details
of the ALGOL system and was used only in exceptional cases, for otherwise unsolvable
problems and in cases where the correct functioning of the ALGOL system itself or of the
X1 hardware was in doubt.
In 1963 a second ALGOL 60 system, developed by Nederkoorn and Van de Laarschot,
became available. Although it was hardly used as complete system the compiler came
in use as separate syntax checker (suppressing the punching of an object tape). In later
years no (fresh) ALGOL program was run with the Dijkstra/Zonneveld system without
a prior syntax check by the Nederkoorn/Van de Laarschot compiler.
The following ‘special properties of the MC–Algol–system’ (mostly restrictions) were men-
tioned in the user manual8 :
1. Comments starting with ‘comment’ and ending by ‘;’ are permitted also at the
beginning of the program. Apart from this a program shall have the form of an
unlabelled block or an unlabelled compound statement, in other words start with
‘begin’ and end with ‘end’.
After the last symbol ‘end’ the compiler does not accept any symbol to be skipped
but requires a symbol ‘Carriage Return’.
2. In the series of symbols that are skipped after an ‘end’ symbol (not being the last
| and
one of the program) the symbols ‘begin’, ‘comment’, and the stringquotes ‘ <’
| are not permitted.
‘>’
5. In Algol 60, function procedures can be called not only in expressions but also as a
statement by themselves. In that case the function value is of no interest and will
8
taken from the user manual dated December 12th, 1962; translation by the author.
14 CHAPTER 1. INTRODUCTION
be ignored. For the standard functions mentioned in Sections 3.2.4 and 3.2.5 of the
Report and for ‘read’ and ‘XEEN’, however, holds that they may not be called as
statement by their own in the MC–Algol–system.
6. The value of the standard function ‘abs’ has the same type as its argument. The
standard function ‘entier’ may have an argument of type integer. The standard
functions ‘sqrt’ and ‘ln’ operate on the absolute value of the argument.
10. In a goto–statement the evaluation of any possible switch designator shall result in
a well–defined value (label). If not so then the goto–statement is not equivalent to
a dummy statement but undefined.
11. Not only the value of the controled variable – called ‘V’ below –, but also the identity
of V (i.e. if it is an subscripted variable) may be changed in the statement following
the for–clause. In the expressions occurring in a for–clause (i.e. between for and
do), not only in the expressions in the list elements but also in any possible index
expression of V, the call of function procedures with side effects should be avoided.
Also it should be avoided that the identity of V depends on the value of V (e.g. a
controled variable of the form A[A[1]]).
In a for list element of the form ‘A step B until C’, where A, B, and C denote
arithmetic expressions, one should avoid the value of sign(B) to depend on the
value of V. For in the MC–Algol–system the expression B is evaluated only once per
cycle and already calculated for the first time before the assignment V:= A.
12. Upon a for–clause no conditional statement shall follow. In other words, ‘do if ’ is
prohibited.
14. Except for the explicit prohibition for certain procedures it is allowed to present an
actual parameter of type integer for a formal parameter specified as real (or vice
versa) in a procedure statement or a function designator.
16. Procedures in which declarations marked by the symbol ‘own’ occur function not in
the official manner when used recursively.
17. Only integer numbers, possibly preceded by a sign symbol, are permitted as array
bounds in array declarations of the outermost block or those preceded by ‘own’.
18. The MC–Algol–system does not discriminate between ‘real’ and ‘integer’ as the
first symbol of a function declaration: in each invocation the type of the result is
determined by the arithmetic that is carried out this time.
19. The MC–Algol–system requires a specification for each formal parameter of a pro-
cedure declaration.
21. A formal parameter specified as label or <type> procedure shall not occur in the
value list.
22. Parameters in the value list are evaluated at procedure entry in the order of spec-
ification. (This is of importance when the evaluation of an actual parameter can
influence the value of another one.)
23. An array in the value list may have at most five indices.
The restrictions contained in these ‘properties’ seldom gave any problem for the use of
ALGOL 60 as a programming language. The generality of the implementation, including
full block structure, recursive procedures, and name parameters, even Jensen’s device,
often lead to compact and nice algorithms.
16 CHAPTER 1. INTRODUCTION
The table clearly shows the trade–off between ease of programming in ALGOL 60 and
execution speed. Incrementing an integer variable by one (cf. the second example in
Figure 1) could be coded in X1 machine code in two instructions:
2A 1 A
4A n
executing in less than 100 µsec. The programmer himself has to locate the variable in
memory and to choose what register to use for the operation. In ALGOL 60, on the
other hand, he simply writes ‘i:= i + 1’ without bothering about the way of execution.
The variable i is located by the compiler and even the use of the variable in a recursive
procedure is no problem at all. The price paid for this convenience is a slowing–down of
the execution, in case of the X1 from some 100 µsec to about 3000 µsec, by the execution
of 7 instructions of the object program and 56 instructions of 4 ‘operators’ coded in
‘the Complex’ of administrative and arithmetic subroutines supporting object–program
execution. In general the ease of programming in ALGOL 60 was paid by a loss of
execution speed by a factor of 10. Given the fact that within two years more than 70%
of machine time of the X1 at the Mathematical Centre was used for the compilation and
execution of ALGOL 60 programs, the users were quite willing to pay the price.
1.4. DEVELOPMENTS OF THE ALGOL SYSTEM AFTER 1962 17
complete syntax and run–time error checks, the main stream of ALGOL 60 programs
was directed to the X8 very soon. The X1 remained in use at the Mathematical Centre,
however, until mid 1972.
make the text slightly more structured by using ‘if . . . then . . . else . . . ’, ‘while . . . do
. . . ’, and ‘repeat . . . until . . . ’ whereever simple.
Subroutines with multiple entry points also caused some problems. Some could be solved
by splitting the subroutine into several separate subroutines. In one case (in the loader)
where a subroutine conditionally added 1 or 2 to its link and where the subroutine call was
followed by two jump instructions to cater for the normal exit and one of the exceptional
cases we eliminated the whole subroutine.
But in general we believe that the Pascal version is a faithful and honest representation of
the original machine code. It reveals that the style of programming has changed largely
in the years since 1960, not the least by the activities of one of the primary authors of
the X1 system.
Those measurements would have been quite a job in the sixties, but with today’s tools
they were mere child’s play.
Chapter 2
Overview
The ALGOL 60 compiler for de El X1 uses two text scans for producing the transla-
tion. Originally, the source text, punched on papertape in Friden Flexowriter code, was
physically read twice. The two compiler scans, called prescan and main scan, used the
same routines for scanning the text. Those routines constitute the lexical scan part of
the compiler. A later version of this lexical scan stored its intermediate results during the
prescan and retrieved these from store during the main scan.
The output of the main scan was originally punched on paper tape. The output tape
consisted of three parts: the object code proper, still in a free locatable format, the
constant list, containing all numbers that occurred in the ALGOL text, and the future
list, containing the final destinations of all forward references. The object code was
punched during the main scan itself, the two other parts at the end of the main scan.
A special loading program was used to convert the object tape into executable code. In
a later load–and–go version the output of the main scan was stored in memory without
punching. The loading phase was executed immediately after completion of the main
scan.
Chapter 3 discusses the lexical scan routines. Chapter 4 presents the prescan program.
In Chapter 5 many aspects of the main–scan program are analysed. Chapter 6 gives
an overview of three versions of the compiler output. Chapter 7 introduces the library
system. Chapter 8 treats three versions of program loading. Finally, in Chapters 9 and
10 the Pascal version and the X1–code version of the compiler are printed in full.
The compiler does not use any of today’s parsing methods. In fact, there is hardly any
parsing at all, in the sense of checking whether the program text conforms the grammar
rules and constructing the parse tree. Almost any text is ‘accepted’ and the inspection
21
22 CHAPTER 2. OVERVIEW
of the symbols constituting the text is merely done for the immediate production of the
translation. There is, however, some resemblance with methods based on precedence
grammars.
A page from Dijkstra’s handwritten version of the compiler. See page 173.
Chapter 3
After its revision in 1963 the lexical scan consists of four hierarchically linked rou-
tines, called read flexowriter symbol (RFS), next ALGOL symbol (NSS), read next symbol
(RNS), and read until next delimiter (RND).
The lowest level routine in the hierarchy is read flexowriter symbol. The Flexowriter code
has two shifts, lower case and upper case, with explicit punchings marking shift changes.
Therefore, RFS keeps the most recent shift in the variable rfsb. RFS reads one or more
punchings from the input tape, skips blank and erase codes, records shift punchings, checks
parity and delivers as function value the next relevant code in internal representation.
The next level routine in the hierarchy is next ALGOL symbol. Its main task is to assemble
basic symbols that are represented by more than one Flexowriter symbol, such as word
delimiters, colonequal, unequal, or string quotes. Moreover it skips – outside strings! –
comments introduced by the basic symbol ‘comment’ and closed by a semicolon. Symbols
between a basic symbol ‘end’ and the next semicolon, ‘end’, or ‘else’1 are, however, not
skipped by NSS and only ignored by the prescan and – once again – by the main scan.
The third level routine in the hierarchy – nonexistent originally – is read next symbol.
During prescan it calls NSS for the next symbol and assigns it to the variable dl. Moreover
it stores that symbol in a symbol store, packing three symbols in one computer word.
During the main scan it takes its symbols from the symbol store and assigns them to dl.
The upper level of the hierarchy is routine read until next delimiter. It hops over numbers
and identifiers to the next delimiter, which can be found in variable dl. Whether or not
1
The ALGOL 60 report states that the sequence of symbols ‘ end <any sequence not containing end
or ; or else>’ is equivalent to ‘ end’.
23
24 CHAPTER 3. THE LEXICAL SCAN ROUTINES
a number or an identifier was met can be seen from the variable nflag: it is set to 1 if
a number or an identifier was met, and to 0 otherwise. If nflag = 1 the variable kflag
indicates whether a number (kflag = 1) or an identifier (kflag = 0) was met. In both
cases information indicating what number or identifier was met is given in variable inw
and, if more information is necessary, in variable fnw. In the latter case variable dflag
is set to 1, otherwise to 0. At most 9 letters (or digits) of an identifier are taken into
account. Consequently, identifiers that differ only after the first nine characters are not
distinguished. If an identifier consists of less than 5 characters, it can be represented by
inw alone. In that case the last three bits of inw are zero. Note that RND assembles
numbers and identifiers from their constituting characters – and does so during both
prescan and main scan –, but does no table look–up: all look–up activities are carried out
in the main loop of the main scan.
In addition to hopping over identifiers and numbers, RND also hops over the basic symbols
‘true’ and ‘false’. These are mapped onto the numbers 0 (for ‘true’) and 1 (for ‘false’),
i.e., RND delivers into dl the code for the delimiter following these symbols and sets nflag
to 1, kflag to 1, dflag to 0, and inw to 0 or 1.
Although RND, the upper level routine of the hierarchy, is the central interface between
lexical scan and the compiler scans, there are a few places in both prescan and main scan
where the underlying routine RNS is called. In the first place the contents of strings are
skipped (prescan) or read and transferred to the object code (main scan) by calls of RNS.
Secondly, in the main scan, comments after an ‘end’ symbol are skipped using calls of
RNS (during the prescan they are skipped by the main loop thereof using calls of RND).
There are two more places in the main scan using RNS: to read the type symbol following
the symbol ‘own’ in a declaration (for unknown reasons) and to read the symbol following
a ‘]’ symbol in a switch designator (for a very specific, technical reason).
Originally, RFS read its characters from an input buffer rather than directly from the
paper–tape reader. That buffer was filled by an autonomous process running in parallel
with the compiler and driven by the paper–tape reader interrupt. That was a good solu-
tion when the reader was slow (about 25 characters/second), but absolutely inadequate
for the later installed EL1000 which was capable of reading 1000 characters a second.
Recall that the EL X1 executed roughly speaking about 20 instructions in a millisecond,
whereas the interrupt handling and buffer administration took about 125 instructions or
6 millisecond per symbol read and delivered (the input buffer being full all the time, re-
trieving a symbol from the buffer implied a restart of the autonomous reading program,
the reading and buffering of a new symbol, and an inactivation of the reading program;
in the mean time the interrupt signal was set and before the symbol retrieved from the
25
buffer could be processed the interrupt handler was activated only to find no request
for reading). Therefore, we decided to replace the buffer mechanism by a direct access
from RFS to the tape reader, leading to a drastic accelleration of the prescan process.
Moreover, much attention was given to find further ways to speed up the execution of
RFS, using the code table to encode the simple cases in an easy recognizable manner. As
a result, the tape was read during the prescan phase at more than half of its maximal
speed.
We end this section by a few other remarks on the implementation.
The recognition of word delimiters in NSS is carried out in a rather primitive way. The oc-
currence of a word delimiter is noticed when an underline symbol ‘ ’ is followed by a lower
case letter, an ‘A’ or a ‘B’. If that letter happens to be in {a, c, d, g, l, o, p, r, u, v, w, B},
the identity of the word delimeter is established immediately as ‘array’, ‘comment’,
‘do’, ‘goto’, ‘label’, ‘own’, ‘procedure’, ‘real’, ‘until’, ‘value’, ‘while’, or ‘Boolean’,
respectively. Otherwise, a second underlined letter is read. If that is a ‘t’, a third (un-
derlined) letter is read in order to discriminate between ‘step’ and ‘string’. Otherwise,
if that second letter is in {a, e, f, h, r, w} the choice is, given the fact that the first letter
was ambiguous, clear: it has to be ‘false’, ‘begin’, ‘if’, ‘then’, ‘true’, or ‘switch’, re-
spectively. Otherwise, the first letter is inspected anew, and given the fact that neither
the first letter nor the second was decisive, the choice between ‘boolean’, ‘end’, ‘for’,
and ‘integer’ is made immediately. After recognition the remainder of the underlined
word is skipped. A minor detail is that repetitions of underline symbols are skipped (the
underline and the vertical bar are non–advancing symbols on a Flexowriter; therefore,
repetitions thereof do not change the print on paper). As stated before, this recognition
algorithm is rather primitive and unsafe. For example, ‘bagin’ is interpreted as ‘false’ !
It is, however, also rather fast through the use of a table.
Identifiers are represented by one or two X1 words. If the identifier consists of at most
4 characters, they are stored in inw : the last character at bit positions 26 to 21, the
second last (if any) at bit position 20 to 15, the third last (if any) at bit positions 14 to
9, and the fourth last (if available) at bit positions 8 to 3. Note that bit positions 2 to
0, the least significant three bits of inw, remain zero. If the identifier has more than 4
characters, the fifth character is stored at inw [21:26], the fourth at inw [15:20], the third
at inw [9:14], the second at inw [3:8], and the first partly at inw [0:2], partly in three bits
of fnw (depending on the number of characters). Since the first character of an identifier
is always a letter, letters are internally coded by a value from 10 upto and including 62
(value 36 is unused), and inw [0:2] is used for the most significant three bits of the code,
these bits are not all zero. In this way a single–word representation can be discriminated
26 CHAPTER 3. THE LEXICAL SCAN ROUTINES
from a two–word representation. This is used in the main scan when a name list has to
be searched through.
As said before, (unsigned) numbers are assembled by RND. If the number is an integer
not exceeding 67108863 (the integer capacity of the El X1), it is represented by one word,
inw. Otherwise, it is represented by two words, inw and fnw respectively, as a floating
point number in the so–called P9 representation of de X1. The 40 bits mantissa m is
scaled between .5 and 1 (.5 ≤ m < 1). The 26 most significant bits of m are stored in
fnw, the 14 least significant bits of m together with a sign digit 0 in the head of inw.
The remaining 12 bits of inw are used for the binary exponent e. That exponent should
fulfill the requirement −2048 ≤ e ≤ +2047 and the tail of inw contains the number
e + 2048. The conversion from decimal floating to binary floating is carried out in 52
bits precision, with 12 guarding bits. The result is rounded to 40 bits. The conversion
uses multiplications or divisions by powers of 10, preferably 108 , the largest power of 10
represented in the standard X1 system software. In the Pascal version, however, only the
first power of 10 is used for reasons of simplicity.
The transformation of the representation of an ALGOL 60 program punched on paper
tape in Flexowriter code to a sequence of delimiters possibly separated by constants
or identifiers results in an enormous reduction of information. We carried out some
measurements on a sample program taken from the PhD thesis of Zonneveld [11]. The
text used in these experiments is reproduced in Appendix B. It was typed in ASCII (using
‘ for ∨, ^ for ∧, ~ for ¬, and % for 10 ) and transferred to Flexowriter code by means of a
Pascal program. We measured:
9198 heptads, of which 1247 shift punchings, dealt with inside RFS
2730 lay–out punchings, skipped by NSS
44 punchings of comments skipped by NSS
2764 one–punching basic symbols
320 punchings for 160 two–punching symbols
2092 punchings building 276 word delimiters
1 lay–out symbol kept in stock by NSS
3200 basic symbols delivered by NSS and stored for reuse in the main scan
1254 delimiters delivered by RND, separated by 658 identifiers, 210 numbers, and
9 logical values
The comment punchings count includes the punchings used for the representation of the
symbol ‘comment’ itself and of the concluding semicolon. The punching count for word
27
delimiters is inclusive those for ‘true’ and ‘false’ but exclusive ‘comment’. The count
of one–punching basic symbols includes 22 lay–out symbols not skipped by NSS because
of their occurrence within a string.
28 CHAPTER 3. THE LEXICAL SCAN ROUTINES
Chapter 4
29
30 CHAPTER 4. THE PRESCAN PROGRAM
for statement. However, some care is taken not to introduce unnecessarily many blocks.
If the body of a procedure declaration itself is a block, it is combined with the block
containing the identifiers of the formal parameters. If, however, the controlled statement
of a for statement is a block in the sense of the ALGOL 60 report, it is treated as a block
different from the one that is introduced for the controlled statement itself.
We give a short example. Consider the following ALGOL 60 program:
begin integer i;
procedure p(x); integer x;
begin switch s:= aa, bb, cc;
aa: x:= x - 1;
goto s[sign(x) + 2];
bb:
end;
procedure q;
dd: for i:= 1, 2 do ee: p(i);
q;
cc:
for i:= 1 while i > 0 do
begin integer i;
aa: i:= 0
end
end
This program generates the following PLI:
[[cc], [q, p],[bb, aa, s], ,[dd], ,[ee], ,, ,[aa], ]
In the PLI, blocks are sorted in the same order as the occurrence of their first symbol in
the text. Within each sublist, the identifiers occur in retrograde order.
By means of the following two operations the prescan program operates upon the PLI:
fill prescan list and augment prescan list. The former operation inserts an identifier
(stored in inw and, perhaps, fnw) in some existing sublist, the latter one extends PLI
at the end with two new and empty sublists. They use two global variables, mbc (for
maximum block count) and bc (for block count). In mbc the number of blocks encoun-
tered thusfar is recorded, whilst bc gives the number of the current block. Upon block
entry mbc is incremented by one, the current value of bc is saved in a stack, and bc is set
to mbc. Upon block exit bc is restored from the stack.
4.1. THE ART OF SKIPPING PROGRAM TEXT 31
The prescan program itself can best be characterized as ‘the art of skipping text’. Its
main loop hops, by means of invocations of read until next delimiter, from delimiter to
delimiter, only paying some attention to it if it is:
- a stringquote open, in order to skip strings;
- ‘for’, in order to start a new block in PLI;
- a colon, in order to add the label identifier to PLI;
- ‘begin’, in order to see whether it is followed by a declarator (introducing a new
block in that case) and to enable a match with the corresponding ‘end’;
- ‘end’, in order to match it with the corresponding ‘begin’ and to check whether it
ends a block construction, or perhaps even the program;
- a semicolon, in order to check whether it ends a for statement or a procedure body;
- ‘procedure’, in order to add the procedure identifier to PLI and to start a new block
in PLI;
- ‘switch’, in order to add the switch identifier to the PLI and to skip the switch
declaration upto and including its concluding semicolon; or
- ‘own’, ‘Boolean’, ‘integer’, ‘real’, ‘array’, ‘string’, ‘label’, or ‘value’. For these
symbols the remainder of the corresponding declaration or specification is skipped in
an inner loop upto and including its concluding semicolon.
Note that the prescan program never meets a letter, a digit or the symbols ‘true’ or
‘false’, because these are hopped over by RND (except when occurring within a string).
The main loop as described above can, however, be in one of two states. The current
state is recorded in a variable bflag. The normal state is bflag = 0, whilst bflag = 1
indicates the possible processing of specifications. bflag is set to 1 whenever the delimiter
‘procedure’ is met in the normal state; it is, with some exceptions, reset in each iteration
of the main loop. Exceptions occur, for unknown reason, in the iteration following the
treatment of a colon, a stringquote open or a ‘begin’.
There are two inner loops. The first one is entered upon the detection of a stringquote
open. It skips, by means of invocations of read next symbol, the contents of the string
upto and including the corresponding closing stringquote. Thereafter the next cycle of
the main loop is entered without, however, resetting bflag.
The other inner loop is used to skip declarations and specifications. It is entered from the
main loop after detection or processing one of the delimiters ‘own’, ‘Boolean’, ‘integer’,
‘real’, ‘array’, ‘switch’, ‘procedure’, ‘string’, ‘label’, or ‘value’. It is exitted at the
first semicolon, after which the next cycle of the main loop is entered without resetting
bflag. In this way the parameter list of a procedure, its value list, and its specification
lists are skipped by an alternation of a cycle of the main loop and a number of cycles
32 CHAPTER 4. THE PRESCAN PROGRAM
of this inner loop. Inside this inner loop the treatment of the delimiter ‘procedure’ is
equal to that inside the main loop. In this way the occurrence of a function declaration
(starting with ‘Boolean’, ‘integer’, or ‘real’) is properly reacted upon.
The only effect of the state bflag = 1 in the main loop is that the delimiters ‘switch’ and
‘procedure’ are interpreted as specifiers and not as declarators.
Note that array declarations are skipped by an inner loop. In this way the colons that
occur in bound pair lists are never taken for a colon marking the occurrence of a label.
(In a later stage we added to the prescan program some code that checks, at each oc-
currence of a semicolon or ‘end’, whether the number of opening parentheses is equal to
the number of closing parentheses and whether the number of opening square brackets is
the same as the number of closing square brackets met in the text thusfar. In this way
a frequently occurring source of troubles could be detected early. The check was carried
out during prescan in order to enable the operator to mark the place in the paper tape
where the error was detected.)
Because we deal with a context free grammar, a push–down list is needed. It is used to
match corresponding ‘begin’ and ‘end’ symbols and to cater for the block structure of
the ALGOL 60 program. Each ‘begin’ symbol is pushed onto the stack; it is removed at
the occurrence of an ‘end’ symbol. If bflag = 1, indicating the start of a procedure body,
nothing more is added to the stack: it is by this mechanism that a procedure body which
is a block by itself does not count as a block in addition to the one that is introduced for
the procedure declaration and in which the formal parameters are accomodated. If, on
the other hand, bflag = 0, and if the ‘begin’ symbol is followed by a declarator symbol,
indicating the start of a new block, two other values are pushed onto the stack just below
the top–of–stack value (i.e. the ‘begin’ symbol): the current value of bc and the value
−1. The latter is used as block marker. The ‘begin’ symbol itself continues to be the
top–of–stack value.
Also when a ‘for’ symbol is encountered, these two values are pushed to the stack too,
this time just on top of the stack: bc and −1.
At the occurrence of a semicolon or ‘end’ symbol, pairs of a block marker and a saved
bc value on top of the stack are popped repeatedly (thereby terminating for statements,
which are treated as blocks) until a ‘begin’ symbol is found as top–of–stack value. In case
of an ‘end’ symbol the ‘begin’ is popped as well, in case of a semicolon it is preserved in
the stack. Each time that a saved bc value is popped in this process it is used to restore
variable bc.
For the push operations onto the stack the procedure fill t list is used (both by the prescan
4.1. THE ART OF SKIPPING PROGRAM TEXT 33
program and the main scan); inspections of the top–of–stack value and pop operations
are, however, explicitly coded in the text of the prescan program.
One may wonder whether such a primitive program as the prescan program can properly
accomplish its task, the construction of the prescan list, for any syntactically correct
ALGOL 60 program, and in fact it does not. We found a number of flaws but in practice
they hardly mattered: most programmers don’t write grammatically complex programs. I
remember only one user problem that we could trace back to a shortcoming of the prescan
program, and it was easily circumvented.
A first mistake, rather unimportant, is the way in which comments between an ‘end’
symbol and the subsequent semicolon, ‘else’ or ‘end’ symbol are dealt with. The comment
symbols are skipped by the main cycle of the prescan program and consequently there
is a reaction upon the occurrence of those symbols the prescan program is interested in.
In the X1 ALGOL 60 user’s manual the occurrence of the symbols ‘begin’, ‘comment’
and of stringquotes are explicitly forbidden, but also symbols like ‘for’ and ‘procedure’
better do not occur in these contexts, as is illustrated by the following example:
begin integer i;
for i:= 0 do
begin AA: end for i, BB: ;
CC:
end
producing:
[[CC], ,[AA], ,[BB], ]
as prescan list in stead of:
[[CC], ,[AA], ]
We notice already here that in the main scan program there is a separate loop of only 6
X1 instructions for skipping this kind of comments neatly, and it is incomprehensible why
the same solution is not used in the prescan program. Then no exclusion rule would have
been necessary in the user manual, and the prescan program and the main scan program
would have had the same treatment of comments. The true solution would have been
to skip such comments already in the lexical scan part of the compiler: that’s where it
belongs!
A more serious flaw is caused by the way the block structure is treated. For an ALGOL
60 block ‘begin <declarations> <statements> end’ the block marker −1 in the stack is
not removed upon reading of the ‘end’ symbol, but only at the next semicolon or ‘end’
34 CHAPTER 4. THE PRESCAN PROGRAM
(at the same level). Consequently, for the following ALGOL 60 program:
begin
if 0 < 1
then AA: begin integer i;
BB:
end
else CC: begin integer i;
DD:
end
end
the prescan program generates the following prescan list:
[[AA], ,[CC, BB], ,[DD], ]
instead of:
[[CC, AA], ,[BB], ,[DD], ]
The faulty prescan list leads to an endless loop within the main scan.
links were forward references. After the last sublist a backward reference was included as
an endmarker. PLI is initialized as:
address contents
6781 6782
6782 6783
6783 6782
representing the two (as yet) empty sublists of the outermost block.
The prescan list for the first example read:
[[cc], [q, p],[bb, aa, s], ,[dd], ,[ee], ,, ,[aa], ].
Figure 2: store representation of [[cc], [q, p],[bb, aa, s], ,[dd], ,[ee], ,, ,[aa], ]
instructions, suggesting that the tape reader would have run at 60% of its maximum
speed for this program.
A detailed analysis of the available 9198 number–of–instructions–between–successive–
reads can be given. We want to relate these figures to specific activities in the layers
of the lexical scan and in the prescan program itself. Before doing so we tried to eliminate
the effects of two different sources of a kind of noise. In the first place the second level
of the lexical routines, NSS, reads at some occasions one Flexowriter symbol in advance,
which then is stored in an internal buffer. At the next invocation of NSS this symbol is
taken from that buffer instead of reading it from the tape reader. In the second place,
within the third level of the lexical routines, RNS, the symbol obtained from NSS is stored
in the text buffer. This takes 11 instructions but at one of each three invocations an ad-
4.3. QUANTITATIVE ASPECTS 37
ditional 7 instructions are executed for starting a new text–buffer word (remember that
in the text buffer 3 symbols are stored per word).
A first observation is that the 9198 heptades read by the tape reader lead to only 3200
symbols delivered by NSS. This means that 5998 heptades are ‘absorbed’ by RFS and NSS.
In 5145 of the cases the number of instructions executed between two successive reads
is 20 or less, and in 6007 cases 27 or less. With some exceptions these will correspond
to absorbed heptades, and the average number of instructions between reads is for these
cases only 20.4, replacing again numbers less than 20 by 20.
For a second observation we mention that the PLI produced for this program counts
36 blocks (of which 32 for blocks without any identifier) and 8 short (i.e. one–word)
identifiers, resulting in a total PLI length of 81 words. The first block introduction
(for procedure f ) takes 163 instructions, including insertion of its identifier, whilst the
insertion of label identifier A requires 114 instructions, the incorporation of the first for
block 181 instructions, and that of the last for block 744! We see here clearly the effect
of the steadily increasing amount of work for adding new sublists at the end of PLI (all
numbers mentioned here are the number of instructions between successive reads). Block
introduction or name insertion costs, on the average, 413.0 instructions. As a result the
tape reader halted noticeably at the occurrence of labels, switch– or procedure identifiers
and ‘for’ symbols.
For the remaining symbols we measured an average number of instructions between suc-
cessive reads of 54.6. This caters for the activities at all the levels of the lexical scan and
at the prescan level itself. The lowest number above 27 that occurs is 34, the biggest one
not related to PLI increments is 133. Typical numbers are 36 and 43 for the letters and
digits of an identifier and 50 and 57 for the digits of a number (here we should mention
that for each digit of a number two multiplications are executed with an execution time
of 500 µsec each. Therefore the figures 50 and 57 could also be read as 68 or 75).
The prescan as a whole takes 292 810 instructions, 256 848 (88%) of which are spent in
the lexical scan. In more detail, RFS requires the execution of 95 722, NSS of 63 990,
RNS of 42 684 and RND of 54 452 instructions.
38 CHAPTER 4. THE PRESCAN PROGRAM
Chapter 5
Main scan
During the main scan the object program is generated. In the original version of the
compiler the source text was read from paper tape a second time and the object program
was punched, also on paper tape. The latter was a rather time–consuming process as the
tape punch ran at a speed of 25 punchings a second. In the latest load–and–go version
of the compiler the source text was taken from store and the object program as produced
during the main scan was stored in compressed form. After completion of the main scan
it was decompressed and stored at its final place by the loading phase of the compiler.
Inputs to the main scan are the source text (as stored by RNS during prescan) and the
prescan list PLI. Outputs are: the list of object instructions RLI (in its compressed form),
the list of future references FLI, the list of constants KLI and some numbers: the lengths
of RLI, of FLI, and of KLI and GVC, the first free address of the execution stack.
The structure of the main scan resembles that of the prescan program. There is one
central loop and some inner loops (for dealing with special constructs like strings, formal
parameter lists etc.). The central loop starts with a call of RND, whereafter there is a
case construct on the delimiter just read. In contrast to the prescan program, the main
scan has a separate case for almost every delimiter, in which a piece of object program
is generated and the appropriate administrative actions are carried out. There is also a
state, to control the activities in the central loop, and a push–down list to cater for the
context–free character of the ALGOL 60 grammar.
The state – in the prescan program just one boolean – is much more extended than during
prescan and is used to record the context. Also the stack is used for many more purposes
than in the prescan program.
39
40 CHAPTER 5. MAIN SCAN
block) or ‘dynamic’ (for variables declared in inner blocks). A dynamic address consists
of two parts, a block number n and a displacement d relative to the begin of the block
cell in the execution stack. As a parameter to an operator it is coded as 32 ∗ d + n.
As an example we present in Figure 3 the piece of object program produced as the
compilation of the statement ‘i:= 2 + i * i’, assuming the dynamic address n = 1, d =
7 for i and relative position 29 for constant 2 in the constant list.
OPC w explanation
0 2S 225 A load dynamic address of i in register S
16 TIAD, take integer address dynamic
3 2B 29 A load static address of 2 in register B
34 TIRS, take integer result static
0 2S 225 A load dynamic address of i in register S
33 TIRD, take integer result dynamic
0 2S 225 A load dynamic address of i in register S
48 MUID, multiply integer dynamic
59 ADD, add
85 ST, store
The translation is syntax directed and in polish–reversed form. The load instructions are
generated on the basis of the identifier or constant assembled by RND, the operations are
formed on the basis of the delimiters and kept in the compiler stack until they can be
inserted in the object program. The latter is regulated by the priorities of operator and
context. The assignment symbol ‘:=’ is considered an operator with lowest priority. Where
possible an operator is combined with a preceding take. MUID is such a combination
of TIRD and MUL (multiply). All of the instructions of the example given above are
generated inside procedure production of object program. We come back to these points
in a separate section.
The translation is such that the code corresponding to applied occurrences of identifiers
is generated during the analysis of the delimiter immediately following it. There is one
exception to this rule: the code for a switch identifier in a switch designator is generated
after the code for the index expression. In this case the identity of the switch designator
has to be saved in the stack (during analysis of ‘[’) and to be popped later (during analysis
of ‘]’).
As further examples we present in Figure 4 the translation of a procedure statement
42 CHAPTER 5. MAIN SCAN
OPC w explanation
511: 1 2B 18 A load begin address of SUM in register B
2 2T 3 jump over translation of parameters
513: 3 2B 0 A load static address of x in register B
15 TRAS, take real address static
0 2B 138 A load static address of i in register B
34 TIRS, take integer result static
56 IND, indexer
13 EIS, end of implicit subroutine
1 0A 513 C codeword for parameter x[i]
3 0A 5 A codeword for parameter 10
3 0A 4 A codeword for parameter 1
0 0A 138 A codeword for parameter i
523: 0 2A 4 A load number of parameters in register A
9 ETMP, extransmark procedure
OPC w explanation
0 2B 138 A load static address of i in register B
34 TIRS, take integer result static
29 SSI, store switch index (in location 48)
1 2T 65 A jump to code for declaration of s
5). This work is done in the compex routines RVA (real value array storage function
frame, OPC 92) or IVA (integer value array storage function frame, OPC 93). Thereupon
the space for the elements of all local and value arrays is reserved using LAP (local array
positioning, OPC 94) or VAP (value array positioning, OPC 95). Both LAP and VAP
increment AP and WP. VAP is also responsible for making the copy of the elements
of the actual parameter array. The amount of space required for the array elements is
not known at compile time, and does not play any role in the dynamic address system
(the displacement part of which being restricted to at most 1023). RVA, IVA, LAP, and
VAP are generated by the compiler procedure reservation of arrays which is called at the
occurrence of the first delimiter implying that no more declarations of local arrays follow.
Here it is important that all array declarations of a block precede the declarations of
switches and procedures.
The expression stack consists of 4–word cells. The last word of each cells specifies its type
( −1 for real values, −0 for integer values, some value ≥ +0 for addresses). Integer values
and addresses are given by the first word of a cell, real values use the first three cell words
(a mantissa of 52 bits + 2 sign bits, a binary exponent of 27 bits).
ETMR reserves a 4–word cell on top of the expression stack before constructing the new
block cell. Moreover, both ETMP and ETMR fill one word just below the new block cell,
ETMP giving it the value −0 and ETMR the address of the 4–word cell for the result.
This word is inspected by OPC 87 (STP, store procedure value) to see whether the calling
environment of a type procedure needs the result or not, and if so, where it should be
stored.
The translation of the procedure declaration:
real procedure SUM(i,a,b,ti);
value b; integer i,a,b; real ti;
begin real s;
s:= 0;
for i:= a step 1 until b do s:= s + ti;
SUM:= s
end;
is given in Figure 6.
In Figure 6 we assumed that location 24 of the future list contains the (relative) address
of the instruction following the return instruction, that location 8 of the constant list
contains constant 0, and that procedure SUM is declared in the outermost block.
46 CHAPTER 5. MAIN SCAN
OPC w explanation
2 2T 24 jump over procedure declaration
0 2B 1 A load block number in register B
89 SCC, short circuit
0 2S 41 A load dynamic address of b in register S
16 TIAD, take integer address dynamic
0 2S 41 A load dynamic address of b in register S
35 TFR, take formal result
85 ST, store
0 2A 2A load length local area in register A
0 4A 49 increment WP
0 4A 50 increment AP
0 2S 45 A load dynamic address of s in register S
14 TRAD, take real address dynamic
3 2B 8 A load static address of 0 in register B
34 TIRS, take integer result static
85 ST, store
... ... translation of the for statement
0 2S 45 A load dynamic address of s in register S
31 TRRD, take real result dynamic
0 2B 0 A load block nr of enclosing block in register B
87 STP, store procedure value
12 RET, return
at the start and at the end of the execution of an implicit subroutine (the translation of
a non–trivial actual parameter).
These flags are boolean variables (coded 0 for ‘false’ and 1 for ‘true’), and have the
following meaning:
eflag and oflag are set after the delimiters ‘if’, ‘do’, ‘:=’, ‘(’, ‘[’, and ‘array’. There are
several places where eflag is reacted upon, e.g. to determine whether a procedure call is a
procedure statement or a function designator. oflag is reacted upon at one place only; it
determines whether the delimiters ‘+’ and ‘-’ should be interpreted as binary (oflag = 0)
or unary (oflag = 1) operators. It is reset in each call of RND.
mflag is set after a procedure identifier followed by ‘(’, after pushing its old value to the
stack. It is reacted upon in the analysis of the delimiters ‘,’ and ‘)’, interpreting them
in case of mflag = 1 as actual parameter list separator and actual parameter list closing
parenthesis, respectively. Its old value is popped when dealing with the latter (after
generating the parameter code words and the ETMP or FTMP instruction). Moreover,
mflag is reset at the beginning of expressions between parentheses and of subscript lists
after pushing its old value, which is popped at the occurrence of the corresponding closing
48 CHAPTER 5. MAIN SCAN
bracket. (Note: mflag does not play any role in procedure declarations, since the procedure
heading is analysed in an inner loop of the case ‘procedure’ of the central loop).
iflag is set after reading the delimiter ‘[’. It is reacted upon in the analysis of the delimiter
‘,’, interpreting that delimiter as a separator in a subscript list or a bound pair list. Its
old value is temporarily saved in the stack during the scan of an actual parameter list, a
subscript list, and a bound pair list. In the first case it is also reset.
vflag is set after reading the delimiter ‘for’ and reset after reading ‘do’. It is reacted
upon in the analysis of the delimiters ‘:=’ and ‘,’, interpreting these as delimiters in a for
clause. During the scan of an actual parameter list vflag is reset, but its old value is kept
in the stack.
sflag is set after reading the delimiter ‘switch’. It is reacted upon in the analysis of the
delimiters ‘:=’ and ‘,’, interpreting these as delimiters in a switch declaration. It is reset
at the end of the switch declaration, when meeting a semicolon when sflag = 1.
In case of the opening of a new context part of the old context state is saved in the stack
and retrieved from the stack at return to the old context. This is carried out in an ad hoc
fashion: each case only that part of the state is pushed that is relevant after the return
from the new context and that (possibly) has an other value in the new context. As an
example we mention that vflag is saved in the stack in the analysis of the delimiter ‘(’
provided that it is the opening parenthesis of an actual parameter list (this changes the
interpretation of commas).
There are three more flags: pflag, jflag, and fflag. They play a role in the interpretation
of identifiers and mainly affect the generation of the object program. They are reset in
each call of RND. If RND hopped over an identifier (setting nflag = 1 and kflag = 0), the
code of the central loop following the call of RND will set, according to the data stored
in the namelist, pflag if the identifier is the name of a procedure, jflag if it is the name of
a label or switch, and fflag if it is the name of a formal parameter. Moreover, jflag is set
at the begin of a switch declaration. As said, these flags mainly affect the generation of
the object program. In some special situations they influence also the interpretation of a
delimiter. An example of the latter is the interpretation of the delimiter ‘(’: if pflag = 1
it is interpreted as the opening parenthesis of an actual parameter list. At one occasion
jflag is even pushed to the stack: at the occurrence of the delimiter ‘[’ its value is saved
in the stack and retrieved from it at the occurrence of ‘]’. Also fflag is pushed at ‘(’ and
‘[’ and popped at the corresponding closing parentheses. In these cases the information
about the identifier concerned is needed at a later stage. Since the values of these three
flags are determined anew at each delimiter of the text, we do not consider them part of
the context state.
5.4. THE NAME LIST 49
bits interpretation
d26 1 for a formal value parameter for which not yet its
evaluation code has been generated, 0 otherwise
d25, d24 OPC–value for a nonformal label, switch or procedure
identifier
d23 · · · d19 for a nonformal label, switch, or procedure identifier: its
block number, otherwise d23 · · · d20 all 0
d19 1 for an integer or Boolean type variable or array or
for a formal parameter occurring in the value list and
specified integer or Boolean (array)
d18 1 for a formal or nonformal procedure identifier
d17 1 for a formal or nonformal label or switch identifier
d16 1 for a formal name parameter identifier
d15 for a nonformal label, switch, or procedure identifier:
1 before its first occurrence in the text,
0 thereafter
for a simple variable, an array, or a formal parameter:
1 if it has a dynamic execution–stack address,
0 otherwise
d14 · · · d0 object–code address (for a label, switch, or procedure),
future–list location (idem), or
execution–stack address (for a simple variable, array, or
formal parameter)
piler routine test first occurrence is called. If d15 = 1, i.e., if it is its first texual occurrence
(which therefore precedes its defining occurrence), d15 is reset, d25 is set (giving the iden-
tifier an OPC value of 2), a place in the future list is reserved for the as yet unknown
object–code address, and the address of that place is filled in in bits d14 · · · d0 of the
descriptor.
At the defining occurrence of a label, switch, or procedure identifier the compiler routine
label declaration is invocated. If d15 = 1, d15 is reset, d24 is set (giving the identifier
an OPC value of 1), and the current length of the object code (recorded in the compiler
variable rlsc) is filled in in bits d14 · · · d0 of the descriptor. If, on the other hand, d15 = 0,
the value of rlsc is stored in the future list at the location stored in bits d14 · · · d0 of the
descriptor. Note that in that case all applied occurrences of that identifier are addressed
5.4. THE NAME LIST 51
with an OPC value of 2 and a reference to the future list, also those following its defining
occurrence. Another task of label declaration is the output to the console typewriter of
the label, switch, or procedure identifier, followed by its (relative) object–code address in
32–ary scale notation.
All other defining occurrences of identifiers (i.e. of scalar variables and of arrays) lead to
the addition of that identifier at the end of the name list. They get static addresses if
their declarations occur in the outermost block, otherwise they get dynamic addresses3 .
Therefore, they get a descriptor with d14 · · · d0 filled in, d15 = 1 in case of dynamic
addressing, and d19 = 1 in case of an integer or Boolean (array) type.
At the end of a block the old length of NLI is retrieved from the stack and stored in nlsc,
thereby effectively removing all local identifiers of the block from the name list.
Identifiers are searched for in the name list by the compiler routine look for name. If the
identifier is found then its descriptor is copied to the compiler variable id ; the (relative)
position of the descriptor within the name list is stored in another compiler variable nid.
Note that id and nid potentially change value after each call of read until next delimiter in
the main cycle. In general, the old values need not to be saved in the stack. In four cases,
however, nid is pushed to the stack: during the scan of the <switch list> of a <switch
declaration>, of the <subscript expression> of a <switch designator>, of the <bound pair
list> of an <array declaration>, and of the <subscript list> of a <subscripted variable>.
In the first two cases the old value is used afterwards indeed.
At the start of the main scan the name list is prefilled with a number of identifiers.
These are the identifiers of those procedures and functions that are available without
declaration. To these belong the standard functions abs, sign, sqrt, sin, cos, ln, exp,
entier, and arctan, some input and output procedures as read, print, TAB, SPACE,
PRINTTEXT, FLOT, FIXT, and ABSFIXT, and some frequently used functions. They fall
apart in two catagories:
- The first nlscop words of this prefill belong to procedures that are treated as operators.
A call of such a procedure is translated by code transferring its parameter values to
the stack, followed by an invocation of the corresponding routine from the complex
of runtime routines.
- The remaining nlsc0 − nlscop words belong to procedures that in the loading phase
of the system are selectively added to the code from some library source.
For the procedures of the first category the discriptor has the value d18 + 12 ∗ 256 + n + o,
3
Own scalar variables and own arrays always get static addresses, as if they were declared in the
outermost block.
52 CHAPTER 5. MAIN SCAN
OPC w explanation
182: 0 2B 138 A load static address of x in register B
32 TRRS, take real result static
0 2B 140 A load static address of y in register B
32 TRRS, take real result static
65 MOR, more
30 CAC, copy Boolean accumulator into condition
2 N 2T 18 if condition = NO, jump to else part
0 2B 138 A load static address of x in register B
32 TRRS, take real result static
2 2T 19 jump over else part
192: 0 2B 140 A load static address of y in register B
32 TRRS, take real result static
194:
Figure 8: The translation of the expression ‘(if x > y then x else y)’
OPC w explanation
2 2T f1 jump over code for <variable>
r1 : ··· ··· code generating the address of the variable on the execution stack
20 FOR1
2 2T f2 jump to translation of <statement>
FLI[f1 ]: 0 2A 0 A load 0 in register A
2 2B f3 load address of FOR0 instruction in register B
9 ETMP, extransmark procedure
··· ··· code for <for list>
2 2S f4 load address of instruction following the <for statement> into S
27 FOR8
FLI[f3 ]: 19 FOR0
1 2T r1 A jump to code for <variable>
FLI[f2 ]: ··· ··· code for <statement>
1 2T r1 A jump to code for <variable>
FLI[f4 ]:
In Figure 9, f1 , . . . , f4 are locations in the future list filled with the appropriate (relative)
object–code addresses, whereas r1 is the (relative) object–code address given to the code
for generating the address of the controlled variable on the stack (allways the second
instruction of the translation of the <for statement>).
The code for loading the address of a variable to the execution stack depends, of course,
on the nature of that variable:
- for a formal identifier ‘v’ it is:
0 2S @v A load dynamic address of v in register S
18 TFA, take formal address
- for a simple variable ‘v’ it consists of an instruction loading the address of v to register
B (static addressing) or S (dynamic addressing), followed by one of the instructions
TRAD (OPC 14), take real address dynamic, TRAS (15), take real address static,
TIAD (16), take integer address dynamic, or TIAS (17), take integer address static.
- for a subscripted variable ‘v[i1 , . . . , in ]’ the code reads:
The code for the <for list> is the concatenation of the codes of its constituent <for list
element>s, which read:
- for an arithmetic expression E: the code generating the value of E to the execution
stack, followed by FOR2 (OPC 21).
- for the ‘while element’ ’E while B’:
··· ··· code generating the value of E to the execution stack
22 FOR3
··· ··· code generating the value of B to the execution stack
23 FOR4
( 0
:= 2
≡ 3
⇒ 4
∨ 5
∧ 6
¬ 7
<, ≤, =, ≥, >, = 8
+,(binary)– 9
(unary)–,∗,/, : 10
↑ 11
58 CHAPTER 5. MAIN SCAN
Note that subtraction gets priority 9 whilst the unary operator for sign inversion gets
priority 10.
In the transformation the code for loading operands is always generated immediately,
the code for operators has possibly to be postponed until the priority of the context is
sufficiently low. In case of postponement the operator is saved in the stack. In fact,
pairs are pushed to the stack consisting of the operator itself and its priority (coded as
256 ∗ priority + representation of the operator). An invariant of the algorithm is that the
top part of the stack contains some value with priority part 0 and zero or more operators
with priority part ≥ 2.
While scanning an expression from delimiter to delimiter, for each operator roughly the
following actions are carried out:
- set the operator height oh equal to the operator’s priority.
- if nflag = 1 (indicating that the operator was immediately preceded by an identifier or
constant) then generate an instruction that loads an address into register B or S using
the information found in the compiler variable id. The appropriate load operation for
the operand is selected. If the top of stack contains one of the operators +, (binary)
–, ∗, /, or : and if its priority part is at least oh, that operator is removed from the
stack and integrated with the selected load operation. The resulting operation code
is added to the object code.
- as long as the top of the stack contains an operator/priority pair with priority part
at least oh it is removed from the stack and the corresponding operation instruction
is added to the object code.
- the current value of dl and its priority are pushed to the stack as a new opera-
tor/priority pair.
The first three of these actions are executed by a call of the compiler procedure produc-
tion of object program with the operator’s priority as a parameter.
At the occurrence of the first delimiter not belonging to the expression (i.e., one of the
symbols from the follow set of <expression> consisting of the symbols ‘)’, ‘]’, ‘;’, ‘end’,
‘then’, ‘else’, ‘do’, ‘while’, ‘step’, ‘until’, ‘,’, and ‘:’) the translation of the expression is
finalized by a call of production of object program with parameter value 1 (in some cases
indirectly via a call of the compiler procedure empty t list through thenelse).
A delimiter ‘(’ within an expression is pushed to the stack with priority value 0. The ex-
pression following it is thereby handled separately; at the occurrence of the corresponding
closing parenthesis first that expression is finalized; thereafter the opening parenthesis is
popped from the stack again.
5.10. DESIGNATIONAL EXPRESSIONS 59
The value at the bottom of the operator stack (having priority field 0) can be either
the representation of some delimiter, like ‘(’, ‘if’, ‘then’, ‘else’, ‘while’, ‘step’, ‘until’,
‘begin’, ‘[’, or the block–begin marker 161, or the switch list separation marker 160.
location contents
0 5
1 22
2 22
3 18
4 21
5 31
6 29
5.10. DESIGNATIONAL EXPRESSIONS 61
OPC w explanation
96 START
2 2T 0 jump over switch declaration to code address 5
2: 2 2T 1 jump to code address 22, i.e. AA (FLI[1] = 22)
1 2T 2 A jump to code address 2 (for index value 1)
4: 0 1T 48 jump backwards over store[48] places
5: 2 2T 2 jump over procedure declaration to code address 22
6: 0 2B 1 A load block number in register B
89 SCC, short circuit
3 2B 0 A load KLI[0], i.e. 1, in register B
34 TIRS, take integer result static
30 CAC, copy Boolean accumulator into condition
2 N 2T 3 jump over then–part to code address 18
3 2B 0 A load KLI[0], i.e. 1, in register B
34 TIRS, take integer result static
29 SSI, store switch index
0 2S 161 A load (dynamic) address of ss in register S
35 TFR, take formal result
2 2T 4 jump over else–part to code address 21
18: 0 2B 0 A load 0 (block number of BB) in register B
28 GTA, goto adjustment
2 2T 5 jump to code address 31, i.e. to BB (FLI[5] = 31)
21: 12 RET, return
22: 1 2B 6 A load code address 6, i.e. of p, in register B
2 2T 6 jump to code address 29 (FLI[6] = 29)
24: 0 2B 0 A load 0 (block number of s) in register B
28 GTA, goto adjustment
1 2T 4 A jump to code address 4, i.e. to s
13 EIS, end of implicit subroutine
1 0A 24 B parameter code word, code address 24
29: 0 2A 1 A load 1 (number of parameters) in register A
9 ETMP, extransmark procedure
31: 97 STOP
location contents
0 1
Furthermore the following (relative) code addresses are assigned to the label, switch and
procedure identifiers:
- some of the cases share a piece of code. This is implemented by jumps from one case
into another (and sometimes back again). A typical example of this is found in the
code for delimiter ‘do’, where part of the code for the delimiter ‘,’ is executed in
order to generate one of the instructions FOR2 (OPC 21), FOR4 (OPC23) or FOR7
(OPC 26), concluding the translation of the last for–list element, before continuing
the code for ‘do’ itself.
These factors make it hard to encode the main loop in a structured way.
Below we first present the cases for the four delimiters ‘∗’, ‘step’, ‘[’, and ‘:’.
‘∗’ two subroutine calls only (cf. Section 5.9):
production of object program(10);
fill t list with delimiter
‘step’ again two subroutine calls; the first one finalizes the generation of the object code
for the expression preceding the delimiter ‘step’ (which might be a conditional ex-
pression):
empty t list through thenelse;
fill result list(24{FOR5},0)
‘[’ we have the following components:
- if eflag = 0 then reservation of arrays;
in a non–expression context the occurrence of ‘[’ implies that the declaration
part of the block is over. If the block contains array declarations possibly still
some code for these has to be generated.
- oflag:= 1; oh:= 0;
since a new arithmetic expression follows, initial adding operators should be
interpreted as unary operators.
- save (part of) the current context to the stack: eflag, iflag, mflag, fflag, jflag,
and nid.
The stacking of nid is important in the case that jflag = 1, implying that the
delimiter ‘[’ is part of a switch designator.
- eflag:= 1; iflag:= 1; mflag:= 0;
redefine the context such that it is that of index expressions and not that of
actual parameters. Important for the interpretation of comma’s.
- fill t list with delimiter ;
save ‘[’ to the stack with oh–component 0.
- if jflag = 0 then generate address;
in case of an array identifier the delimiter ‘[’ is part of a subscripted variable.
The compiler has to generate code for loading the address of the storage function
64 CHAPTER 5. MAIN SCAN
- of a procedure declaration the formal parameter part, the value part, and the specifi-
cation part are completely handled after the detection of the delimiter ‘procedure’.
It leads to the addition of the formal parameter identifiers to the name list and to
the construction and alteration of their descriptors. Moreover, code is generated for
those formal parameters that occur in the value list and that are specified as ‘real’,
‘integer’, or ‘Boolean’.
the (then still empty) constant list. FLI and KLI are steadily growing during the main
scan, whilst NLI grows and shrinks in connection to block structure. If FLI is about
to overwrite KLI both KLI and NLI are shifted upwards over 16 places; if KLI would
overwrite NLI then NLI is shifted upwards over 16 places.
In this way the lists are accomodated as a kind of floating islands in a linear sea; the
fact that in case of a collision the distance is enlarged by more than one place reduces
the frequency of the necessary shifts and thereby the total costs of storage management.
Maybe this technique was rather new in that time in which ‘heaps’ still had to be invented.
Before any list is shifted it is checked that by the shift the remaining part of the prescan
list will not be overwritten. If that would be the case the compiler halts with error stop
6, 16, 18, or 25.
All assignments to RLI, FLI, KLI, and NLI in the compiler are executed by the invocation
of a procedure in which all the necessary checks are carried out and the absolute address
of the location is determined. The compiler itself only keeps track of relative positions
(with respect to the begin of the lists).
The source program (in our lay–out) takes 185 lines (blank lines inclusive), therefore
the object code has on the average 13.7 instructions per line of source text. This is a
relative high number. But we should keep in mind that a simple load operation of an
integer variable requires two instructions: one for loading the static or dynamic address
to a register and a call to one of the routines in the complex of subroutines. This is also
reflected by the fact that on the average for each delimiter found by RND 2.02 instructions
of object code are generated.
68 CHAPTER 5. MAIN SCAN
From the 2538 object code instructions 1112 were generated with OPC value ≤ 3 and
1426 with OPC value ≥ 8 (i.e., a call to the complex of run–time subroutines).
The object words with OPC values ≤ 3 can be subdivided as follows:
There are 50 parameter code words, 25 words encoding strings, 189 jump instructions, 839
instructions loading a value in register A, B or S as parameter of a complex subroutine,
and 9 instructions to increment the execution stack pointers for 3 procedure declarations.
More specifically, we found as most frequent OPC/instruction combinations:
which cater for more than two third of the subroutine calls to the complex.
Striking is the relative unimportant role of the arithmetic operations in a typical numeric
program for the calculations of planetary orbits, at least at the code level. The most
frequent arithmetic operation, ADD, occurs only at the 10/11th line in the list, and the
total count of arithmetic operations sums up to 178, i.e. 12.48 % of the invocations of a
routine in the complex.
In compacted form the object code requires only 981 words (+ 9 bits for the code word
under construction), that is about 10.5 bits per instruction. We come back to this aspect
in the next chapter. It overwrites gradually the input text which originally has a length
of 1067 words, but in our experiments it turned out that it was never necessary to shift
the yet unconsumed part of the input text upwards (together with FLI, KLI and NLI).
We also did some measurements of the number of compiler instructions executed during
the main scan. This number is exclusive the instructions for encoding and storing the
object string in the store in compact form (by giving fill result list temporarily an empty
body) but includes the repetition of (part of) the lexical scan, especially of RND. We
found in total the execution of 385 077 instructions, of which 95 058 (25 %) are spent in
the lexical scan (41 611 in RNS and 53 447 in RND). This means that for the example
program the main scan requires the execution of about 152 instructions per instruction
of object code generated, and of about 307 instructions per delimiter analyzed.
During the main scan the name list NLI had to be shifted 5 times in order to make place
for an addition to the constant list KLI, whereas KLI and NLI together had to be shifted
11 times in order to cater for the growth of the future list FLI. These 16 shifts moved
altogether 2960 words (on the average 185 words per shift), which required the execution
of 11840 instructions or 3% of the main scan execution time.
With a prefill of the name list of 51 words as used in our experiments the name list had
a maximum length of 177 words. The maximum length of the stack was 43 words.
the compiler stopped without even mentioning what identifier had not been declared.
Other grammatical errors lead to one of four possible forms of behaviour:
- during the prescan program the tape ran out of the tape reader, often caused by
some missing ‘end’ symbol. Another possible cause was the lack of some Flexowriter
symbol (preferably a newline) after the last ‘end’ symbol.
- the compiler just generated an incorrect object program, which passed on the problem
to the execution phase. An example of this behaviour is the ‘expression’
x+∗y
which produces the code given in Figure 11, leaving the stackpointer AP during
execution effectively unchanged.
The object code produced is given in Figure 12, (with FLI [0] = 20 and FLI [1] = 23).
There are two problems here.
- First of all, there is in the code only one block for procedure P, which includes both
parameter a and array A. Therefore it is impossible for the code to exit the inner
block and abandon A without abandoning a at the same time. In fact, the jump to
label AA does not leave any block, and in the repetition (the storage function of)
array A is added to the execution stack over and over again without ever removing
any of those storage functions.
- Secondly, only part of the code for declaring an array is generated: the code for
generating the storage function for array A is present but the code for reserving the
area for its elements is missing. The missing code (cf. Section 5.2.1) reads:
0 2S 163 A load dynamic address of array A in register S
94 LAP, local array positioning
5
According to the list of restrictions as reproduced in Section 1.3, ‘procedure bodies starting with a
label should be avoided’.
72 CHAPTER 5. MAIN SCAN
OPC w explanation
0: 96 START
2 2T 0 jump over procedure declaration (FLI[0] = 20)
2: 0 2B 1A load 1 into register B
89 SCC, short circuit
0 2S 161 A load dynamic address of ‘a’ in register S
16 TIAD, take integer address dynamic
0 2S 161 A load dynamic address of ‘a’ in register S
35 TFR, take formal result
85 ST, store
9: 3 2B 0A load static address of constant 1 in register B
34 TIRS, take integer result static
3 2B 1A load static address of constant 100 in register B
34 TIRS, take integer result static
0 2S 1A load number of arrays in register S
91 ISF, integer arrays storage function frame
0 2S 161 A load dynamic address of ‘a’ in register S
33 TIRD, take integer result dynamic
103 print
1 2T 9A jump to label AA
12 RET, return
20: 1 2B 2A load address of procedure in register B
2 2T 1 jump over parameter code word (FLI[1] = 23)
3 0A 2A codeword for parameter ‘100’
23: 0 2A 1A load number of parameters in register A
9 ETMP, extransmark procedure
97 STOP
zero upon the occurrence of label AA in the text (marking that the statement part
of the block is being scanned), at a moment that identifier A is not yet incorporated
in the namelist. The declaration of array A is not treated as marking the start of an
inner block to the procedure body, due to the presence of a block–begin marker just
below the top of the stack. Consequently, vlam is not set to a value = 0 again and
no further inspections of the namelist will take place when it is zero.
74 CHAPTER 5. MAIN SCAN
Chapter 6
75
76 CHAPTER 6. THE COMPILER OUTPUT
Each item, consisting of an OPC value and, in case of an OPC value ≤ 3, a 27–bit word,
was punched as 2, 5, or 7 pentads in the following way:
- for an OPC value ≥ 8: 2 pentads, consisting of a parity bit, a code bit 1, and the
OPC value in 8 bits;
- for an OPC value ≤ 3 and a w value corresponding to one of 10 different instruction
types: 5 pentads, consisting of a parity bit, two code bits 0, a value between 1 and
10 indicating the instruction type in 5 bits, the OPC value in 2 bits, and the address
part of the instruction in 15 bits;
- for an OPC value ≤ 3 and a w value not corresponding to one of the 10 instruction
types mentioned above: 7 pentades, consisting of a parity bit, a code bit 0 followed
by a code bit 1, three bits 0, the OPC value in 2 bits, and the w value in 27 bits.
The 10 instruction types leading to a 5 pentad encoding in the object tape are given by
Figure 13.
nr instruction type
1 0A 0
2 2A 0 A
3 2S 0
4 2S 0 A
5 2B 0
6 2B 0 A
7 2T 0
8 2T 0 A
9 N 2T 0
10 4A 0
gives a total of 10707 pentads requiring 428.3 seconds or about 7 minutes of punch time.
The design goal of the successor of this first output system was to reduce that punch time
by at least a factor of two.
During the design period it was suggested (came the suggestion from L.A.M. Meertens?)
that if the tape was punched in such a way that it could (and should) be read and decoded
in the backwards direction, the amount of tape handling in the program loading phase
could be reduced greatly. This requires some further explanation.
The object tape consists essentially of two sections:
- the result list and the constant list, and
- some numbers and the future list.
The problem was that they have to be produced in this order – due to the fact that those
numbers and the contents of the future list are known only at the end of the compilation
process –, but have to be loaded in the opposite order – a.o. since substitutions of
references to the future list (OPC value 2) by the value found there are carried out
immediately during reading of the result list –. Moreover, the reading of the so–called
Cross–Reference List CRF, containing information about the mutual use of MCP’s library
routines (see Chapter 7), had to be inserted in between. By inserting the contents of the
CRF in the loader (with the disadvantage that when the contents of the library were
updated also a new loader tape had to be produced) and reading the object tape in the
backwards direction the latter could be read at one stroke.
In the ALD7 version the object tape consisted of:
- a piece of 50 cm blank tape,
- a punching 124, followed by a punching 30 as end combination,
- a piece of blank tape of 6.25 cm,
- a punching 127 as section end,
- the following bitstring, cut into pieces of 27 bits, to each of which a parity bit (for
odd parity) is added and which are punched in 4 heptads:
- the result list,
- the constant list, each word of it given an OPC value of 0,
- the places in the future list which contain the identification of the MCP’s called
directly from the object program, each encoded as an address,
- the number of those MCP’s, encoded as address,
- the future list, each word of it given an OPC value 1,
- 5 numbers, i.e. the begin address of the execution stack (i.e. 138), the address
of the first unreserved word of the execution stack, the length of the future list,
the length of the constant list, and the number of object words, each encoded
as an address,
- a bit 1, as marker of the begin of the information,
- enough bits 0 to complete the current group of 27 bits,
6.3. THE LOAD–AND–GO VERSION 79
name list, and the prescan list. The compiler code was positioned at the high end of the
store. For program execution it was overwritten by the complex of run–time subroutines
(again about 2K long). The loader was positioned at the low end of the store. During
program loading the object code (the constant list included) was positioned adjacent to
the complex and the library routines (used by the program) in front of that. During
execution the loader was overwritten by the execution stack.
In the mean time the store size was extended to 12 K. The additional space was used
during program execution, but until then hardly for program compilation. The compiler
was positioned from 6K to 8K, such that the run–time routines (moved to the area from
10K to 12K) could reside in store during compilation, and substantially longer programs
could be compiled. That situation was retained in the first version of the ALD7 compiler.
The first real application at compile time of the increased store size was the storage of
the source text during the prescan phase of the compiler, thereby eliminating the need
to read the source text twice. It was implemented in the second version of the ALD7
system. After that the idea was born to store also the object code as produced by the
compiler (in its compacted form!) in the memory instead of punching it, and to integrate
the loader as a third phase of the compiling proces.
For its implementation only a suitable memory management had to be devised. The
‘system tape’ now contained the compiler, the loader, the complex, the cross–reference
list, and, in a second release, part of the library routines2 . The following store lay–out
was used:
- after system loading (addresses in the number system with base 32, therefore 01–00–
00 is just 1K):
- 00–07–00 / 00–18–26: loader program
- 00–19–15 / 00–22–02: cross–reference list
- 00–29–00 / 01–13–18: library selection
- 06–25–00 / 06–29–10: prefill of the name list
- 07–04–02 / 09–28–00: compiler program
- 09–29–21 / 11–31–00: complex ALD
- during prescan and main scan the area from 01–13–18 to 06–20–00 is used for object
string, source text, future list, constant list, name list and prescan list, in this order
as described earlier. The compiler stack is located from 00–25–00 to 00–29–00.
- in the transposition from main scan to loader the constant list is moved to its final
2
This system tape consisted of a good 6000 words, punched in 4 heptades a word. Its length was
therefore slightly more than 60 m, its reading time (by means of a special fast reading program for binary
tapes) about 25 s.
6.3. THE LOAD–AND–GO VERSION 81
3
by a piece of compiler code located from 09–13–20 to 09–13–28, apparantly never overwritten by it.
82 CHAPTER 6. THE COMPILER OUTPUT
Chapter 7
In the foregoing chapters we refered to the library system already a number of times.
Here we give some more detailed information.
In the ALGOL 60 system for the X1 a number of procedures and functions were incorpo-
rated. Part of them were the standard functions mentioned in the Revised Report: abs,
sign, sqrt, sin, cos, arctan, ln, and exp. Other ones were added for input/output (for
the console typewriter, the tape punch, and, at a later stage, a plotter). Moreover, some
frequently used algorithms were gradually added to the library, for finding zeros, solving
linear equations, computing special functions, etc. All of them could be used in ALGOL
programs without declaration or any other way of signalling their usage. All their names
were entered in a list (added to the compiler code) which was copied to the name list NLI
at the start of the main scan.
These procedures and functions were implemented in two different ways:
- abs, sign, sqrt, sin, cos, ln, exp, entier, read, print, TAB, NLCR, XEEN, and SPACE
are included in the complex of run–time subroutines. They have each an OPC num-
ber and are treated as operators changing the top of the execution stack. Conse-
quently, they cannot be used as an actual parameter in a procedure statement or
function designator, nor can the function identifiers among them be used in a pro-
cedure statement (since there is no mechanism to remove the function result from
the stack). The first nlscop words from the prefill of the name list belong to these
procedures and functions. As all routines in the run–time complex these operators
are coded in X1 code.
- All other procedures and functions are included in the library proper and called MCPs
(for Machine Code Procedures). They are written in some extension of X1 code to
83
84 CHAPTER 7. THE LIBRARY SYSTEM
be discussed below, and programmed in such a way that there were no restrictions
in usage whatsoever: they could be used as if declared in the outermost block of
the ALGOL program. Originally they were assembled and punched in object code
format on paper tape, the library tape. At the end of program loading this tape
was read and the routines that were directly or indirectly used by the program were
selectively added to the object program. The routines could refer to one another
(even recursively), and therefore the need of a program was the transitive closure
(with respect to the use relation) of the routines that were called directly from the
source program. Some MCPs were ‘anonymous’. Not having an identifier that could
be referred to in an ALGOL 60 program, they could be used only indirectly by other
MCPs. The names of the non–anonymous MCPs were collected in the second part
of the name–list prefill.
By means of an example we like to give an impression of the nature of the code of an
MCP. We present the text of ‘AP 109’: the MCP RUNOUT. Its task is to punch 81 blank
heptades on the output tape. Its code is reproduced in Figure 14.
X0X 2B 1 A blocknumber = 1
X89 SCC, short circuit
X0X 2A 80 A number of zeros
X0X 6A 0 X0 set counter
X0X 2S 128 A blank, with punch mark
X3X 6T 0 ZF 0 2 call PAS1, i.e., punch!
X1X 4T 4 X0 0E decrement counter and jump if ≥ 0
X12 RET, return
X
The first two lines of Figure 14 define the MCP numbers of MCP RUNOUT and of MCP
PAS1. The latter is an anonymous MCP (whose name is not in the prefill of the name
list). Then follows the part that constitutes the MCP itself: first two numbers, the MCP
85
length and its number (the latter encoded as an instruction of which the function part
happens to consist of 12 bits zero) and the (in this case) 8 instructions of the MCP. These
are either an X1 instruction preceded by an OPC code 0, 1, or 3, or a call to one of the
run–time routines of the complex, indicated by its OPC number (≥ 8). The last line
contains an end marker for the last instruction.
So we see that the body of an MCP is in fact a mixture of X1 code proper and ‘connectors’
to its ALGOL environment. Its starts by the standard two instructions for all procedures,
whether declared in the ALGOL program or member of the library, and ends with the
standaard return instruction for all procedures. The X1 instructions themselves have an
OPC code, indicating whether at load time the address part of the instruction should be
kept unchanged (OPC 0), whether the begin address of the MCP itself should be added to
it (OPC 1), or (OPC 3) whether it should be replaced by the begin address of some other
MCP (the number of which is given by the given address part). OPC value 2 never occurs
in MCPs. Anonymous MCPs do not need connector code to the ALGOL environment.
The library tape contained all MCPs in object code format (as described in Section 6.1)
and was concluded by an end marker (the pseudo MCP length 16383). To it corresponded
a separate cross–reference tape CRF with the following contents:
- for each MCP:
- a punching 31,
- the MCP length in 3 pentads (with odd parity),
- the MCP number, in 2 pentads (with odd parity),
- a list of the numbers of those other MCPS that call this MCP directly or indi-
rectly (each in 2 pentads with parity),
- the pseudo MCP number 511 as end marker for the list;
- a punching 31,
- the pseudo MCP length 16383 as end marker for the CRF tape.
The cross–reference table was used during program loading. Details of its use are described
in Section 8.1.
The program to translate the assembly code of MCPs to object code format had as input
the assembly code of one or more MCPs and the most recent version of the cross–reference
tape. It produced the extension to the library tape and an updated version of the cross–
reference tape. MCPs that called one another recursively should be translated together.
For the transition to the ALD7 system (discussed in Section 6.2) two programs were
written to recode both the library tape (to the new object tape format) and the CRF
tape. Since the latter was to be incorporated in the ALD7 program loader, it was punched
86 CHAPTER 7. THE LIBRARY SYSTEM
Program loading
The main task of program loading is, of course, loading into store the compiled ALGOL
60 source program and all the library routines it uses directly or indirectly, thus delivering
a program ready for execution. In order to fulfill that task, it has to do some other tasks.
First it has to determine which library routines are needed. It does so from a list of library
routines that are called directly from the source program and augments this to a list of
all library routines needed with the help of information from the cross–reference list.
Secondly, it has to determine where object program and library routines will be placed,
by computing the begin addresses of both the object code and of all the library routines
used. It does so using the length of the result list RLI, the length of the constant list
KLI, and the lengths of the library routines as given by the cross–reference list.
Thirdly, while loading the object code and the code of the library routines, it has to deal
with the OPC code of each instruction. If that OPC code is at least 8, it defines the
instruction by itself: the instruction should be taken from the OPC table. If that OPC
code is 2 (occurring in the object program only), it should replace the address part by
an address taken from the future list FLI. In case of an OPC code 3 either the begin
address of the constant list should be added (for an instruction in the object program) or
the address part should be replaced by the begin address of an MCP. An OPC value of
1 leads to the addition of the begin address of either the object program (for the object
code) or the current MCP to the address part of the instruction.
Fourthly, some minor adaptations are aplied to the object program. In case of an OPC
value of 2, if bit d17 of the instruction is 1 it is set 0, otherwise bit d19 is set 1. Probably
these indicate some ‘maintenance’ actions to the original compiler that easiest could be
87
88 CHAPTER 8. PROGRAM LOADING
done in the loader (rather than in the compiler). A number of jumps in the compiler,
certainly all jumps that refer to a location in the future list, are coded by the compiler
as indirect jumps. Maybe it was originally planned to have the future list in store during
execution and to lead those jumps via it. The setting of d19 changes the jumps into direct
jumps, and the substitution of the location in the future list by its contents then makes
the presence of the future list during program execution superfluous. The resetting of d17
has, according to a comment in the (revised) loader, to do something with a recoding of
actual parameter code words (PORDS), but its meaning is not clear.
Finally, at the end of the loading phase, the store is prepared for a reproducible program
execution by filling the whole working space by −0 (this had also the advantage of stopping
the machine if, by loosing proper control, it tries to execute an unused word of working
space as an instruction).
was wanted. In that case MCPE was decreased by the MCP length, and its new value
was copied to MLI as begin address of the MCP. Moreover, in the case of direct use from
the object code (as seen from a negative old value in MLI) that begin address was also
filled in in the corresponding location in the future list.
After the processing of the cross–reference tape all the nescessary addresses (of RLI, KLI,
and all MCPs that are needed) were known, and the actual loading could start. De X1
stopped for loading the (first part of the) object tape. After reading and loading RLI and
KLI the begin address of the object program RLIB was typed on the console typewriter
in the number system with base 32 (xx xx 00) Also MCPE was typed in the same way.
The working space (from 680 to MCPE) was filled by −0 and the X1 stopped for loading
the library tape. From this tape all MCPs were read, but only those that were used (as
indicated in MLI) were loaded from the begin address as given by MLI. At the end of the
library tape the program was ready for execution and the X1 stopped anew, now giving
opportunity to load a potential data tape.
In the implementation the main subroutine is LIL (Read List) for reading and placing
a list of instructions. LIL uses subroutine RBW (Read Binary Word), which builds the
next instruction from 2, 5, or 7 pentades, incorporating its OPC–value. RBW, in turn,
uses subroutine RNP (Read Next Pentade).
In this (second) version of the loader no use is made of the interrupt system for the tape
reader. This suggests that it was written after the arrival of the fast tape reader. It
runned reasonably fast. One inefficiency still is that during the processing of the library
tape the contents of each MCPs is decoded to instructions independent of whether that
MCP is actually needed or not. We remediated that in the load–and–go system.
tape and that the parity of each group of 4 heptades is checked to be odd.
RBS operated roughly in the following way:
It maintained, in one word of its working space, a number of ‘bits in stock’. Those bits,
at least 21 (and, of course, at most 27), were positioned at the most significant part of
the word, the first bit at position d26 (that bit was therefore easily inspected by testing
the sign of the stock word). Moreover, the number of bits in stock was registered, and
as soon as, by a call of RBS, the stock becomes shorter than 21 bits, a heptade is read
from tape and added to the low end of the stock word. The logical sum of each group
of 4 heptades is formed, and checked for parity when the first heptade of the next group
is read. In that case only (the most insignificant) six bits of the new heptade are added
to the stock, otherwise all seven bits are added. RBS is initialized by setting the number
of bits in stock equal to zero, by skipping blank tape and the first non–blank heptade
(requiring that it has the value 30), by loading 4 heptades, and by calling RBS (each time
for 1 bit) until a bit 1 is obtained.
In the main part first RLSCE and KLSCE are read (by calls of ADD), RLIB and MCPE
are computed, and FLSCE and GVC are read (again by ADD). Next the future list is
read by LIL. Then RNB, the number of directly used MCP’s is read (by ADD), and,
if different from 0, the use–list MLI is initialized, the RNB references to the future list
containing their specifiction are read (by ADD again) and incorporated in MLI, and the
cross–reference list CRF is read from store and processed. For reading CRF a subroutine
LC (Read Cross Reference), yielding an MCP length or number, is used.
Now the result list RLI and the constant list KLI are read (by a call of LIL). RLIB is
typed on the console typewriter.
Next the MCPs are loaded in the following way:
Each time an end marker (i.e., pseudo MCP length 7680) is found, it is checked whether
all MCPs have been read. If so, MCPE is typed, the working store for execution is cleared,
and the X1 stops with stop nr 3–7, ready for program execution. If not, the X1 stops
with stop nr 3–6, indicating that a (next) MCP tape should be entered in the tape reader.
This organization makes it possible both that if no MCPs are used at all the reading of
the MCP tape(s) can be skipped, and that, if the user removes the end marker from his
object tapes and glues a copy of an MCP tape to it, the loading can proceed without
intermediate stop. If an MCP length less than 7680 is found, the MCP number is read,
and if it is used, that MCP is loaded by a call of LIL. If, however, MLI indicates that it is
not used at all, the MCP is skipped (although still the instructions are decoded by calls
of RBW).
Allthough the cross–reference list is now build–in in the loader, the user had the possibility
8.3. THE LOADING PHASE OF THE LOAD–AND–GO COMPILER 91
to load his own version by means of the standard input program of the X1 using directive
DW followed by binary encoded tape (as if directive DB had been read). This did,
however, not alter the contents of the name list prefill, and, to the best of my knowledge,
this facility never was used.
In these times the typing time for the console typewriter is not taken into account; it could
have slowed down the compiler, but in view of the limited output to that typewriter for
the current program the effect is neglectible. Note that for this program the operator was
not able to rewind both the source tape and the system tape during compilation.
94 CHAPTER 8. PROGRAM LOADING
Chapter 9
The Pascal program presented in this chapter is a back–engineering of the X1 code of the
load–and–go version of the Dijkstra/Zonneveld ALGOL 60 compiler for the X1. It has
been structured in the following way.
There are three main procedures, each representing a phase of the compiling process:
‘prescan’, ‘main scan’, and ‘program loader’. All procedures that are called exclusively
from one of these main procedures are declared locally to the one that uses it. A procedure
that is shared by two or more of these main procedures is declared globally preceding the
main procedure that textually contains its first applied occurrence. We arrived at the
following program lay–out:
lines 60 – 324: the lexical scan routines. Procedure read until next delimiter is
called from both procedure prescan and from procedure main scan.
lines 325 – 327: procedure fill t list, storing its parameter on top of the compiler
stack.
lines 328 – 436: procedure prescan.
lines 437 – 570: some procedures shared by procedure main scan and the main pro-
gram, in which, before calling procedure main scan, the block ad-
ministration for the outermost block is created and the instruction
‘START’ is generated.
lines 571 – 1516: procedure main scan.
lines 1517 – 1818: procedure program loader.
lines 1819 – 1992: the main program.
The program contains some output statements not occurring in the X1 code. Some
95
96 CHAPTER 9. THE PASCAL VERSION OF THE COMPILER
of these, placed between braces, are now comment but were previously used to inspect
intermediate results.
The table given in Figure 15 can be used to find the declaration of a procedure.
In the X1–code version of the compiler as given in the next chapter each component
(subroutine, table, set of global variables, constant list) has its own address, characterized
by two ‘paragraph letters’. For example, the subroutine ‘read flexowriter symbol’, given
in the Pascal version by lines 60 through 81, has in the X1–code version addresses 0 LK 0
through 31 LK 4. In order to link the two versions of the compiler together we give
97
for each component in the Pascal text systematically the two paragraph letters of the
corresponding part in the X1–code version by means of a comment. See e.g. line 60 of
the Pascal version, mentioning paragraph LK in the comment ‘{LK}’.
98 CHAPTER 9. THE PASCAL VERSION OF THE COMPILER
1 program X1_ALGOL_60_compiler(input,output,lib_tape);
2 const d2 = 4;
3 d3 = 8;
4 d4 = 16;
5 d5 = 32;
6 d6 = 64;
7 d7 = 128;
8 d8 = 256;
9 d10 = 1024;
10 d12 = 4096;
11 d13 = 8192;
12 d15 = 32768;
13 d16 = 65536;
14 d17 = 131072;
15 d18 = 262144;
16 d19 = 524288;
17 d20 = 1048576;
18 d21 = 2097152;
19 d22 = 4194304;
20 d23 = 8388608;
21 d24 = 16777216;
22 d25 = 33554432;
23 d26 = 67108864;
24 mz = 134217727;
35 var tlsc,plib,flib,klib,nlib,
36 rht,vht,qc,scan,rfsb,rnsa,rnsb,rnsc,rnsd,
37 dl,inw,fnw,dflag,bflag,oflag,
38 nflag,kflag,
39 iflag,mflag,vflag,aflag,sflag,eflag,jflag,pflag,fflag,
40 bn,vlam,pnlv,gvc,lvc,oh,id,nid,ibd,
41 inba,fora,forc,psta,pstb,spe,
42 arra,arrb,arrc,arrd,ic,aic,rlaa,rlab,qa,qb,
99
43 rlsc,flsc,klsc,nlsc: integer;
44 bitcount,bitstock: integer;
45 store: array[0..12287] of integer;
46 rns_state: (ps,ms,virginal);
47 rfs_case,nas_stock,pos: integer;
48 word_del_table: array[10..38] of integer;
49 flex_table: array[0..127] of integer;
50 opc_table: array[0..112] of integer;
51 rlib,mcpe: integer;
52 lib_tape: text;
53 ii: integer;
301 end;
302 bexp:= bexp + 4; elsc:= elsc - 1;
303 until elsc = 0
304 else if elsc < 0
305 then repeat if fnw >= 5 * d23
306 then begin inw:= inw div 2 + (fnw mod 2) * d25;
307 fnw:= fnw div 2; bexp:= bexp + 1
308 end;
309 inw:= 8 * inw; fnw:= 8 * fnw + inw div d26;
310 inw:= inw mod d26 + fnw mod 5 * d26;
311 fnw:= fnw div 5; inw:= inw div 5;
312 bexp:= bexp - 4; elsc:= elsc + 1
313 until elsc = 0;
314 inw:= inw + 2048;
315 if inw >= d26
316 then begin inw:= 0; fnw:= fnw + 1;
317 if fnw = d26 then begin fnw:= d25; bexp:= bexp + 1 end
318 end;
319 if (bexp < 0) or (bexp > 4095) then stop(4);
320 inw:= (inw div 4096) * 4096 + bexp;
321 dflag:= 1;
322 4: oflag:= 0;
323 5:
324 end {read_until_next_delimiter};
383 end;
384 if dl <= 101 {[,]}
385 then begin if dl = 100 then vht:= vht + 1 else vht:= vht - 1;
386 goto 1
387 end;
388 if dl = 102 {|<}
389 then begin repeat if dl = 102 {|<} then qc:= qc + 1;
390 if dl = 103 {|>} then qc:= qc - 1;
391 if qc > 0 then read_next_symbol
392 until qc = 0;
393 goto 2
394 end;
395 if dl = 104 {begin}
396 then begin fill_t_list(dl);
397 if bflag <> 0 then goto 1;
398 read_until_next_delimiter;
399 if (dl <= 105) or (dl > 112) then goto 3;
400 tlsc:= tlsc - 1 {remove begin from t_list};
401 block_introduction;
402 fill_t_list(104) {add begin to t_list again};
403 goto 3;
404 end;
405 if dl = 105 {end}
406 then begin while store[tlsc-1] < 0 {block-begin marker} do
407 begin tlsc:= tlsc - 2; bc:= store[tlsc] end;
408 if rht <> 0 then stop(22); if vht <> 0 then stop(23);
409 tlsc:= tlsc - 1 {remove corresponding begin from t_list};
410 if tlsc > tlib then goto 1;
411 goto 7 {end of prescan}
412 end;
413 if dl <= 105 {dl = |>} then goto 1;
414 if dl = 111 {switch}
415 then if bflag = 0
416 then {declarator}
417 begin read_until_next_delimiter {for switch identifier};
418 fill_prescan_list(0); goto 6
419 end
420 else {specifier}
421 goto 5;
422 4: if dl = 112 {procedure}
423 then if bflag = 0
424 then {declarator}
425 begin bflag:= 1;
426 read_until_next_delimiter {for procedure identifier};
427 fill_prescan_list(1); block_introduction; goto 6
108 CHAPTER 9. THE PASCAL VERSION OF THE COMPILER
428 end
429 else {specificier}
430 goto 5;
431 if dl > 117 {false} then stop(8);
432 5: read_until_next_delimiter;
433 6: if dl <> 91 {;} then goto 4;
434 goto 2;
435 7:
436 end {prescan};
1102 end
1103 else begin fill_result_list(98{TFP},0);
1104 goto 8703
1105 end
1106 end
1107 else goto 8703
1108 else begin {completion of implicit subroutine:}
1109 store[tlsc-2]:= store[tlsc-2] + d19 + d20 + d24;
1110 fill_result_list(13{EIS},0); goto 8704
1111 end;
1112 8703: {completion of implicit subroutine:}
1113 repeat production_of_object_program(1)
1114 until not (thenelse or do_in_t_list);
1115 store[tlsc-2]:= store[tlsc-2] + d20 + d24;
1116 fill_result_list(13{EIS},0);
1117 8704: if dl = 87{,} then goto 9804 {prepare next parameter};
1118 {production of PORDs:}
1119 psta:= 0; unload_t_list_element(pstb);
1120 while pstb mod d8 = 87{,} do
1121 begin psta:= psta + 1; unload_t_list_element(pstb);
1122 if pstb div d16 mod 2 = 0
1123 then fill_result_list(pstb div d24, pstb mod d24)
1124 else fill_result_list(0,pstb);
1125 unload_t_list_element(pstb)
1126 end;
1127 tlsc:= tlsc - 1;
1128 fill_future_list(flib+store[tlsc],rlsc);
1129 fill_result_list(0,4718592+psta) {2A ’psta’ A};
1130 bn:= bn - 1;
1131 unload_t_list_element(fflag); unload_t_list_element(eflag);
1132 production_transmark;
1133 aflag:= 0;
1134 unload_t_list_element(mflag); unload_t_list_element(vflag);
1135 unload_t_list_element(iflag); goto 1;
1136 8705: empty_t_list_through_thenelse;
1137 if sflag = 0 then {array declaration} goto 1;
1138 {switch declaration:}
1139 oh:= 0; dl:= 160;
1140 fill_t_list(rlsc); fill_t_list_with_delimiter; goto 1;
1146 end
1147 else begin {label declaration}
1148 reservation_of_arrays;
1149 label_declaration
1150 end;
1151 goto 1;
1314 fill_result_list(1,88604672+store[tlsc])
1315 {2T ’stacked RLSC’ A}
1316 until store[tlsc-1] <> 160{switch comma};
1317 tlsc:= tlsc - 1; unload_t_list_element(nid);
1318 label_declaration;
1319 fill_result_list(0,85983232+48) {1T 16X1};
1320 tlsc:= tlsc - 1;
1321 fill_future_list(flib+store[tlsc],rlsc)
1322 end;
1323 eflag:= 0;
1324 if dl <> 105{end} then goto 1;
1325 tlsc:= tlsc - 1;
1326 if tlsc = tlib + 1 then goto 1052;
1327 repeat read_next_symbol
1328 until (dl = 91{;}) or (dl = 84{else}) or (dl = 105{end});
1329 jflag:= 0; pflag:= 0; fflag:= 0; nflag:= 0;
1330 goto 2;
1356 if dl = 87{,}
1357 then begin read_until_next_delimiter;
1358 goto 1082
1359 end;
1360 goto 1;
1361 1083: {dynamic addressing}
1362 id:= pnlv + d15;
1363 if ibd = 1
1364 then begin id:= id + d19;
1365 pnlv:= pnlv + 32; lvc:= lvc + 1
1366 end
1367 else begin pnlv:= pnlv + 2 * 32; lvc:= lvc + 2 end;
1368 fill_name_list;
1369 if dl = 87{,}
1370 then begin read_until_next_delimiter;
1371 goto 1083
1372 end;
1373 read_until_next_delimiter;
1374 if (dl <= 106{own}) or (dl > 109{real})
1375 then begin reservation_of_local_variables;
1376 goto 2
1377 end;
1378 if dl = 109{real} then ibd:= 0 else ibd:= 1;
1379 read_until_next_delimiter;
1380 if nflag = 1 then goto 1083 {more scalars};
1381 reservation_of_local_variables;
1382 if dl = 110{array} then goto 1101;
1383 goto 3;
1515 1052:
1516 end {main_scan};
1820 begin
1821 {initialization of word_del_table} {HT}
1822 word_del_table[10]:= 15086; word_del_table[11]:= 43;
1823 word_del_table[12]:= 1; word_del_table[13]:= 86;
1824 word_del_table[14]:= 13353; word_del_table[15]:= 10517;
1825 word_del_table[16]:= 81; word_del_table[17]:= 10624;
1826 word_del_table[18]:= 44; word_del_table[19]:= 0;
141
1885 {writeln;
1886 for bn:= plib to plie do writeln(bn:5,store[bn]:10);
1887 writeln;}
1945 intro_new_block2;
1946 bitcount:= 0; bitstock:= 0; rnsb:= bim;
1947 fill_result_list(96{START},0);
1948 pos:= 0;
1949 main_scan; {EL}
1950 fill_result_list(97{STOP},0);
1988 program_loader;
1992 end.
146 CHAPTER 9. THE PASCAL VERSION OF THE COMPILER
Chapter 10
The following text is as it occurred in manuscript. When punched for producing a tape
to be assembled by the X1 assembler, all commentary and all lay–out symbols had to be
left out. So, with some exceptions, only columns 12 to 28 are relevant as X1–code.
147
148 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
Voorponsingen VPO
DP ZF 1 Z Z 0 7-04-03 FRL
DP ZH 5 Z F 2 7-06-08 GAI
DP ZK 13 Z H 0 7-06-21 constanten
DP ZL 31 Z K 0 7-07-20 PTM
DP ZR 6 Z L 0 7-07-26 AVR/BPR
DP ZS 13 Z R 0 7-08-07 POP
DP ZT 15 Z S 3 7-11-22 FTL
DP ZW 7 Z T 0 7-11-29 FTD
DP ZU 4 Z W 0 7-12-01 LTF
DP ZY 7 Z U 0 7-12-08 RNS
DP ZN 19 Z Y 1 7-13-27 THENELSE
DP EZ 15 Z N 0 7-14-10 DDEL :=
DP EE 14 E Z 2 7-16-24 DDEL [
DP EF 27 E E 0 7-17-19 DDEL ]
DP EH 7 E F 2 7-19-26 DDEL
DP EK 15 E H 1 7-21-09 DDEL ,
DP EL 17 E K 4 7-25-26 BASIC CYCLE
DP ER 8 E L 0 7-26-02 DOT
DP ES 20 E R 0 7-26-22 DDEL + -
DP ET 14 E S 0 7-27-04 DDEL * / div
DP EW 4 E T 0 7-27-08 DDEL (
DP EU 13 E W 1 7-28-21 DDEL )
DP EY 10 E U 0 7-28-31 DDEL if
DP EN 12 E Y 0 7-29-11 DDEL then
149
VP1
DP HZ 9 F N 0 8-14-06 LFN
DP HE 11 H Z 1 8-15-17 DDEL switch
DP HF 5 H E 0 8-15-22 FPL
DP HH 3 H F 1 8-16-25 APL
DP HK 7 H H 0 8-17-00 PSP
DP HL 3 H K 4 8-21-03 EPS
DP HR 19 H L 1 8-22-22 FOB 6
DP HS 6 H R 1 8-23-28 OCT
DP HT 25 H S 0 8-24-21 NSS
DP HW 20 H T 4 8-29-09 INB
DP HU 14 H W 1 8-30-23 NBD
DP HY 8 H U 1 8-31-31 DDEL procedure
DP HN 11 H Y 3 9-03-10 FNL
150 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
VP2
VP3
DP SZ 21 R N 0 0-18-07 MT
DP SE 15 R E 0 0-19-09 (ZE) werkruimte derde doorgang
152 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep autostart 0
DA 0 Z Z 0 DI
=>> 0 2T 0 L E 0 A => start prescan
DC D0
153
aanroep 6T 0 Z F0 0 =) FRL
DA 0 Z F 0 DI
=) 0 2B 1 A RLSC:= RLSC + 1
1 4B 24 Z E 0
2 U 1A 7 A P
5 N 2T 14 Z F 0 A -> als OPCnr < 8
4 U 1A 61 A P
5 Y 2T 9 Z F 0 A -> als OPCnr > 61
6 4P AB voor 8 <= OPCnr <= 61:
7 2S 8-L R 0 B zoek codewoord in tabel en
8 2T 0 L L 0 A => BSM met OPCcode
5 => 9 U 1A 85 A Z voor 61 < OPCnr :
10 Y 2S 5127 A bouw zelf het codewoord op
11 N 4P AS
12 N 0S 10599 A
13 2T 0 L L 0 A => BSM met OPCcode
3 => 14 6A 8 L T 0 berg OPCnr (0,1,2,3)
15 2A 8 X 0 transport link
16 6A 7 L T 0
17 6T 0 L S 0 0 =) ADC voor adresgedeelte
18 3LS 32767 A isoleer functiegedeelte
19 0S 8 L T 0 en voeg OPCnr als adres toe
20 2B 19 A
23 -> 21 U 0LS 30 Z F 0 B Z
22 N 1B 1 A Z cyclus test op masker
23 N 2T 21 Z F 0 A ->
24 4P BB P masker gevonden?
25 Y 2S 17 Z F 1 B zo ja, pak maskercode uit tabel
26 N 0P 12 SS zo neen,
27 N 6T 0 L S 0 0 =) ADC voor functiegedeelte
28 N 2S 7295 A en pak speciale maskercode
29 6T 0 L L 0 0 =) BSM met maskercode
30 2T 7 L T 0 E => klaar
31 0A 0 A masker nr 1
DC D0
154 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
ZF1
DA 0 Z F 1 DI
0 0A 1 X 0 C masker nr 2
1 Y 6A 0 A 3
2 Y 2A 0 X 0 P 4
3 4A 0 X 0 5
4 Y 2A 0 A 6
5 2S 2 X 0 7
6 0A 1 X 0 B 8
7 2B 1 A 9
8 N 2T 2 X 0 10
9 0A 3 A 11
10 0A 0 X 0 12
11 2T 1 A 13
12 2B 2 X 0 14
13 2A 0 A 15
14 2B 0 A 16
15 2T 2 X 0 17
16 2B 3 A 18
17 2S 0 A DN 19
18 +7294 maskercode nr 1
19 +7293 2
20 +7292 3
21 +7291 4
22 +7290 5
23 +7289 6
24 +7288 7
25 +7287 8
26 +7286 9
27 +7285 10
28 +7284 11
29 +7283 12
30 +7282 13
31 +7281 14
DC D0
155
ZF2
DA 0 Z F 2 DN
0 +7280 maskercode nr 15
1 +4109 16
2 +4108 17
3 +3077 18
4 +3076 19
DC D0
156 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 Z H0 1 =) GAI
DA 0 Z H 0 DI
=)0 6T 0 Z R 0 0 =) AVR
1 2S 8 Z E 0 pak ID
2 U 2LS 3 Z K 0 Z non-formele?
3 N 2A 18 A OPC 18: TFA
4 N 2T 10 Z H 0 A ->
5 2A 14 A
6 U 2LS 0 Z K 0 Z statisch?
7 Y 0A 1 A
8 U 2LS 4 Z K 0 Z real?
9 N 0A 2 A OPC 14,15,16 of 17
4 -> 10 2S 0 A
11 6T 0 Z F 0 0 =) FRL
12 2T 9 X 0 E => klaar
DC D0
157
constanten ZK0
DA 0 Z K 0 DN
0 +32768 DI = d15
1 2B 0 A
2 2S 0 A DN
3 +65536 = d16
4 +524288 DI = d19
5 2B 0 X 0
6 2A 0 A
7 2T 0 A
8 2T 0 X 0 DN
9 +17825792 = d24,d20
10 +18350080 DI = d24,d20,d19
11 0D 32767 X 0 DN = d25,d24,d14/d0
12 +131072 DI = d17
13 0X 0 X 0 = d25
14 0D 0 X 0 DN = d25,d24
15 +1048576 DI = d20
16 N 2T 0 X 0
17 2S 0 X 0
18 4A 0 X 0 = d23
19 6D 0 X 0 = d25/d22
20 1T 16 X 1
21 0S 0 X 0 DN = d24
22 +65535 DI = d15/d0
23 U 0A 0 X 0 Z = d18,d15
24 U 0A 0 X 0 P = d17,d15
25 4A 17 X 1
26 4A 18 X 1
27 N 0A 0 X 0 = d16,d15
28 0B 0 X 0 = d26
29 0A 0 X 0 Z = d18
30 U 0Y 0 X 0 = d26,d25,d15
DC D0
158 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 Z L0 0 =) PTM
DA 0 Z L 0 DI
=) 0 2A 19 Z E 0 FFLA
1 0P 1 AA
2 1A 18 Z E 0 2*FFLA - EFLA
3 0A 9 A
4 2S 0 A met OPC 8,9,10 of 11
5 2T 0 Z F 0 A => door naar FRL
DC D0
159
DA 0 Z R 0 DI
=) 0 2A 8 Z E 0 pak ID
1 4P AS
2 2LS 32767 A
3 U 2LA 0 Z K 0 Z statisch?
4 N 0S 2 Z K 0 zo neen,
5 N 2A 0 A met 2S dynamisch adres A
6 N 2T 0 Z F 0 A -> door naar FRL
7 0P 3 AA
8 2LA 3 A
9 U 0LA 2 A Z verwijzing naar FLI?
10 Y 0S 5 Z K 0 met 2B FLIadres
11 N 0S 1 Z K 0 of 2B statisch adres A
12 2T 0 Z F 0 A => door naar FRL
DC D0
160 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 Z S 0 DI
=) 0 2A 1 A
=) 1 6A 5 Z E 0 OH:= 1
=) 2 2S 29 Z E 0 Z NFLA = 0?
3 N 2T 16 Z S 1 A -> zo neen, dan naam of konstante
4 2A 13 Z E 0 Z AFLA = 0 ?
5 N 2A 58 A zo neen, dan
6 N 6S 13 Z E 0 AFLA:= 0, en
18LH0 7 N 6T 0 Z F 0 0 =) FRL met OPC 58: TAR
14 -> 8 2B 25 Z E 0
26ZS1 9 2S 32767 X 0 B TLI[TLSC - 1]
10 3P 8 SS
11 2LS 15 A isoleer OH uit TLI
12 U 5S 5 Z E 0 P en check deze tegen OH-heersend
13 Y 2T 9 X 0 E -> als OH-heersend > OH-uit-TLI
14 1B 1 A
15 6B 25 Z E 0 TLSC:= TLSC - 1
16 2A 0 X 0 B
17 2LA 255 A isoleer operator uit TLI
18 U 1A 63 A P
19 U 1A 80 A E is het een adreshebbende?
27 20 Y 2T 25 Z S 0 A ->
8,11ZS1 21 1A 5 A adresloze operator: + t/m eqv
18ZS2-> 22 2S 0 A
7,14ZS3 23 6T 0 Z F 0 0 =) FRL met OPC van operator
24 2T 8 Z S 0 A => volgend element uit TLI
20 => 25 U 1A 132 A Z operator = NEG?
26 Y 2A 57 A dan OPC van NEG
27 Y 2T 22 Z S 0 A -> en verder als adresloze
28 U 1A 127 A E operator <> STORE?
29 Y 2T 9 Z S 1 A -> dan speciale functie
30 U 1A 129 A P assignment to proc.identifier?
31 6A 3 Z E 0
DC D0
161
ZS1
DA 0 Z S 1 DI
0 Y 1B 1 A
1 Y 6B 25 Z E 0 zo ja, TLSC:= TLSC - 1
2 Y 2S 0 X 0 B pak BN uit TLI
3 Y 0S 1 Z K 0
4 Y 2A 0 A
5 Y 6T 0 Z F 0 0 =) FRL met 2B ’BN’ A
6 3A 43 A
7 0A 3 Z E 0 bouw OPCnr op
8 2T 22 Z S 0 A => en verder als adresloze
29ZS0=> 9 U 1A 141 A E
10 N 1A 57 A bouw OPCnr van
11 N 2T 22 Z S 0 A ->
12 U 1A 151 A E speciale functie op
13 N 1A 40 A
14 N 2T 22 Z S 0 A -> en verder als adresloze
15 7Y 1 C 0 stop: onbekende functie (OPC>111)
3ZS0 => 16 2A 0 A
17 6A 29 Z E 0 NFLA:= 0
18 6A 13 Z E 0 AFLA:= 0
19 2S 16 Z E 0 Z PFLA = 0?
20 Y 2T 27 Z S 1 A -> dan geen procedure statement
21 6T 0 L H 0 3 =) PST voor parameterloze procedure
22 2S 6 Z K 0
23 2A 0 A
24 6T 0 Z F 0 0 =) FRL met 2A 0 A
25 6T 0 Z L 0 0 =) PTM
26 2T 8 Z S 0 A => volgend element uit TLI
20 => 27 2A 2 Z E 0 Z JFLA = 0?
28 Y 2T 19 Z S 2 A -> als geen go to statement
29 2A 19 Z E 0 Z FFLA = 0? dwz. non formele?
30 N 6T 0 Z R 0 0 =) BPR voor formele label
31 N 2A 35 A OPC 35: TFR
DC D0
162 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
ZS2
DA 0 Z S 2 DI
0 N 2T 22 Z S 0 A -> verder als adresloze operator
1 2S 8 Z E 0 ID
2 0P 8 SS
3 2LS 31 A isoleer BN uit ID
4 U 1S 7 Z E 0 Z blijven we in het block?
5 N 0S 1 Z K 0 zo neen,
6 N 6T 0 Z F 0 0 =) FRL met 2B ’BN’ A
7 N 2S 0 A
8 N 2A 28 A
9 N 6T 0 Z F 0 0 =) FRL met GTA
10 6T 0 L F 0 0 =) TFO
11 4P AS A en S bevatten nu ID
12 2LS 32767 A isoleer adres
13 0P 3 AA
14 2LA 3 A isoleer opc
15 U 0LA 2 A Z referentie naar FLI?
16 Y 0S 8 Z K 0 dan 2T ’adres’
17 N 0S 7 Z K 0 anders 2T ’adres’ A
18 2T 23 Z S 0 A => verder als adresloze operator
28ZS1=> 19 6T 0 Z R 0 0 =) AVR
20 2B 25 Z E 0
21 2S 32767 X 0 B TLI[TLSC - 1]
22 4P SA
23 3P 8 SS
24 2LS 15 A isoleer OH uit TLI
25 U 5S 5 Z E 0 P OH-heersend > OH-uit-TLI?
31 -> 26 Y 2A 315 A 5 * 63
27 Y 2T 5 Z S 3 A -> produceer dan TAKE
28 2LA 255 A isoleer operator uit TLI
29 U 1A 63 A P
30 U 1A 67 A E adresloze operator?
31 Y 2T 26 Z S 2 A -> ga dan TAKE produceren
DC D0
163
ZS3
DA 0 Z S 3 DI
0 6A 0 X 1 anders een adreshebbende
1 0P 2 AA operatie met ingebouwde TAKE
2 0A 0 X 1 produceren uit 5 * operator
3 1B 1 A
4 6B 25 Z E 0 terwijl TLSC:= TLSC - 1
27ZS2-> 5 2S 19 Z E 0 Z FFLA = 0?
6 N 1A 280 A voor formele: - 5 * 64 + 40
7 N 2T 22 Z S 0 A -> en verder als adresloze
8 2S 8 Z E 0 voor non formele:
9 U 2LS 0 Z K 0 Z d15 van ID = 0?
10 Y 0A 1 A als statisch
11 U 2LS 4 Z K 0 Z d19 van ID = 0?
12 N 0A 2 A als integer type
13 1A 284 A - 5 * 64 + 36
14 2T 22 Z S 0 A => en verder als adresloze
DC D0
164 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 Z T0 0 =) FTL
DA 0 Z T 0 DI
=) 0 2B 25 Z E 0 TLSC
1 U 1B 1 R K 0 Z = MCPB?
2 Y 7Y 2 C 0 stop: TLI vol
3 6S 0 X 0 B TLI[TLSC]:= (S)
4 0B 1 A
5 6B 25 Z E 0 TLSC:= TLSC + 1
6 2T 8 X 0 E => klaar
DC D0
165
aanroep 6T 0 Z W0 0 =) FTD
DA 0 Z W 0 DI
=) 0 2S 5 Z E 0 OH
1 0P 8 SS
2 0S 9 Z E 0 DL
3 2T 0 Z T 0 A => met 256*OH + DL door naar FTL
DC D0
166 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 Z U0 0 =) LTF
with (S) = destination of result
DA 0 Z U 0 DI
=) 0 3B 1 A
1 0B 25 Z E 0
2 6B 25 Z E 0 TLSC:= TLSC - 1
3 2A 0 X 0 B A:= TLI[TLSC]
4 4P SB
5 6A 0 X 0 B
6 2T 8 X 0 E => klaar
DC D0
167
aanroep 6T 0 Z Y0 0 =) RNS
DA 0 Z Y 0 DI
=) 0 0T 14 Z E 2 => strooisprong over toestand
0 => 1 2T 31 Z Y 0 A => RNS maagdelijk, doe voorbereiding
0 => 2 2T 0 H T 0 A => naar NSS, want prescan
NSS => 3 6S 9 Z E 0 berg symbool in DL
4 2B 12 Z E 2 oude schuifwijzer
5 1B 7 A P
6 N 2B 15 A
7 6B 12 Z E 2 nieuwe schuifwijzer
8 0P 0 SS B schuif
9 2B 19 Z E 1 vulplaats
10 Y 4S 0 X 0 B als nog plaats in
11 Y 2T 8 X 0 E -> oude woord dan klaar
12 0B 1 A
13 6B 19 Z E 1 nieuwe vulplaats
14 6S 0 X 0 B start nieuw magazijnwoord
15 0B 8 A
16 1B 21 Z E 0 P vulplaats + 8 > PLIB?
17 Y 7Y 25 C 0 stop: magazijn vol
18 2T 8 X 0 E => klaar
0 => 19 2B 20 Z E 1 ledigplaats, want vertaalscan
20 2S 0 X 0 B magazijnwoord
21 2B 13 Z E 2 schuifwijzer
22 3P 0 SS B
23 2LS 127 A isoleer symbool
24 6S 9 Z E 0 berg symbool in DL
25 1B 7 A P
26 N 2B 15 A
27 6B 13 Z E 2 nieuwe schuifwijzer
28 N 2B 1 A
29 N 4B 20 Z E 1 nieuwe ledigplaats
30 2T 8 X 0 E => klaar
1 => 31 2A 0 A voorbereiding
DC D0
168 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
ZY1
DA 0 Z Y 1 DI
0 6A 9 Z E 1 QC:= 0
1 6A 18 Z E 2 case RFS:= 0
2 6A 21 Z E 2 voorraad NSS:= 0
3 2S 15 Z E 2 P voorbereiding voor prescan?
4 Y 2A 1 A
5 N 2A 18 A zet strooisprong op
6 6A 14 Z E 2 voorbereiding geweest
7 N 2T 0 Z Y 0 A -> klaar als vertaalscan
8 2B 18 Z E 1 BIM
9 0B 8 A
10 6B 19 Z E 1 vulplaats
11 6B 20 Z E 1 ledigplaats
12 2A 0 A
13 6A 0 X 0 B clear eerste magazijnwoord
14 2A 22 A
15 6A 12 Z E 2 schuifwijzer voor vullen
16 2A 15 A
17 6A 13 Z E 2 schuifwijzer voor legen
18 2T 0 Z Y 0 A => klaar met voorbereiding
DC D0
169
THENELSE ZN0
aanroep 6T 0 Z N0 1 =) THENELSE
DA 0 Z N 0 DI
=) 0 2B 25 Z E 0
1 2S 32767 X 0 B S:= TLI[TLSC - 1]
2 2LS 255 A isoleer delimiter
3 U 0LS 83 A Z = then?
4 N 0LS 84 A Z of = else?
5 N 2T 9 X 0 Z -> zo neen, klaar met THENELSE = false
5FZ0 =) 6 1B 2 A P
7 6B 25 Z E 0 E TLSC:= TLSC - 2; cond:= YES
8 2B 0 X 0 B gedumpte FLSC
9 0B 12 Z E 0 + FLIB
10 2A 24 Z E 0 RLSC
11 6T 0 F U 0 0 =) FFL met RLSC
12 2S 18 Z E 0 A adres van EFLA
13 6T 0 Z U 0 0 =) LTF voor EFLA
14 2T 9 X 0 Z => klaar met THENELSE = true
DC D0
170 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DDEL := EZ0
DA 0 E Z 0 DI
=> 0 2T 11 E Z 2 A => doe eerst RLA
13EZ2=> 1 6A 9 Z E 0 DL:= 128 (vertaling STORE)
2 2A 1 A
3 6A 0 Z E 0 OFLA:= 1
4 U 2A 6 Z E 0 Z VFLA = 0?
5 N 2T 25 E Z 0 A -> zo neen, dan for clause
6 U 2A 17 Z E 0 Z SFLA = 0?
7 N 2T 24 E Z 1 A -> zo neen, dan switch declaratie
8 U 2A 18 Z E 0 Z EFLA = 0?
9 Y 6A 18 Z E 0 zo ja, dan EFLA:= 1
10 N 4A 9 Z E 0 zo neen, dan DL:= 129 (STORE ALSO)
11 2A 2 A
12 6A 5 Z E 0 OH:= 2
13 U 2A 16 Z E 0 Z PFLA = 0?
14 Y 2T 21 E Z 0 A -> zo ja, dan assignment aan variable
15 4A 9 Z E 0 DL:= 130 of 131 (STP of STAP)
16 2S 8 Z E 0 ID
17 0P 8 SS
18 2LS 31 A isoleer BN
19 6T 0 Z T 0 0 =) FTL met BN uit ID
20 2T 23 E Z 0 A =>
14 => 21 2A 29 Z E 0 Z NFLA = 0? dwz geindiceerd
22 N 6T 0 Z H 0 1 =) zo neen, dan GAI
20 -> 23 6T 0 Z W 0 0 =) FTD
24 2T 0 E L 0 A => terug naar basiscyclus
5 => 25 6A 18 Z E 0 FOR CLAUSE: EFLA:= 1
26 2A 29 Z E 0 Z NFLA = 0? dwz geindiceerd?
27 N 6T 0 Z H 0 1 =) zo neen, dan GAI
28 2A 20 A OPC van FOR1
29 2S 0 A
30 6T 0 Z F 0 0 =) FRL met FOR1
31 2A 2 A opc 2: referentie naar FLI
DC D0
171
EZ1
DA 0 E Z 1 DI
0 2S 26 Z E 0 FLSC
1 6S 11 Z E 0 dumpen in FORC
2 0S 8 Z K 0
3 6T 0 Z F 0 0 =) FRL met X2X 2T ’FLSC’
4 2S 1 A
5 4S 26 Z E 0 FLSC:= FLSC + 1
6 2B 10 Z E 0 pak de in FORA gedumpte FLSC
7 0B 12 Z E 0 FLIB
8 2A 24 Z E 0 RLSC
9 6T 0 F U 0 0 =) FFL, dus FLI[FORA]:= RLSC
10 2A 0 A
11 2S 6 Z K 0
12 6T 0 Z F 0 0 =) FRL met 2A 0 A
13 2S 26 Z E 0 FLSC
14 6S 10 Z E 0 dumpen in FORA
15 0S 5 Z K 0
16 2A 2 A opc 2: referentie naar FLI
17 6T 0 Z F 0 0 =) FRL met X2X 2B ’FLSC’
18 2A 1 A
19 4A 26 Z E 0 FLSC:= FLSC + 1
20 2A 9 A OPC van ETMP
21 2S 0 A
22 6T 0 Z F 0 0 =) FRL met ETMP
23 2T 0 E L 0 A => terug naar basiscyclus
7EZ0 => 24 2A 2 A SWITCH DECLARATIE
25 2S 26 Z E 0 FLSC
26 0S 8 Z K 0
27 6T 0 Z F 0 0 =) FRL met X2X 2T ’FLSC’
28 2S 26 Z E 0
29 6T 0 Z T 0 0 =) FTL met FLSC
30 2S 1 A
31 4S 26 Z E 0 FLSC:= FLSC + 1
DC D0
172 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
EZ2
DA 0 E Z 2 DI
0 2S 22 Z E 0 NID
1 6T 0 Z T 0 0 =) FTL met NID
2 2A 0 A
3 6A 5 Z E 0 OH:= 0
4 6T 0 Z W 0 0 =) FTD
4EK4 -> 5 2A 160 A
6 6A 9 Z E 0 DL:= 160 (switchkomma)
7 2S 24 Z E 0 RLSC
8 6T 0 Z T 0 0 =) FTL met RLSC
9 6T 0 Z W 0 0 =) FTD met switchkomma
10 2T 0 E L 0 A => terug naar basiscyclus
0EZ0 => 11 6T 0 K N 0 2 =) RLA
12 2A 128 A
13 2T 1 E Z 0 A =>
DC D0
173
DDEL [ EE0
DA 0 E E 0 DI
=> 0 2A 18 Z E 0 Z EFLA = 0?
1 Y 6T 0 K N 0 2 =) zo ja, dan RLA
2 2A 1 A
3 6A 0 Z E 0 OFLA:= 1
4 2A 0 A
5 6A 5 Z E 0 OH:= 0
6 2S 18 Z E 0 ga vlaggen dumpen in TLI:
7 6T 0 Z T 0 0 =) FTL met EFLA
8 2S 1 Z E 0
9 6T 0 Z T 0 0 =) FTL met IFLA
10 2S 4 Z E 0
11 6T 0 Z T 0 0 =) FTL met MFLA
12 2S 19 Z E 0
13 6T 0 Z T 0 0 =) FTL met FFLA
14 2S 2 Z E 0
15 6T 0 Z T 0 0 =) FTL met JFLA
16 2S 22 Z E 0
17 6T 0 Z T 0 0 =) FTL met NID
18 2A 1 A ga vlaggen zetten:
19 6A 18 Z E 0 EFLA:= 1
20 6A 1 Z E 0 IFLA:= 1
21 2A 0 A
22 6A 4 Z E 0 MFLA:= 0
23 6T 0 Z W 0 0 =) FTD met [
24 2S 2 Z E 0 Z JFLA = 0?
25 Y 6T 0 Z H 0 1 =) zo ja, dan GAI voor arraySTOFU
26 2T 0 E L 0 A => terug naar basiscyclus
DC D0
174 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DDEL ] EF0
DA 0 E F 0 DI
2 -> => 0 6T 0 Z S 0 1 =) OH:= 1; POP
1 6T 0 Z N 0 1 =) THENELSE?
2 Y 2T 0 E F 0 A -> zo ja, dan herhaal
3 2A 1 A
4 5A 25 Z E 0 TLSC:= TLSC - 1, dwz gooi [ weg
5 2A 1 Z E 0 Z IFLA = 0?
6 Y 2T 30 E F 0 A -> dan arraydeclaratie
7 2S 22 Z E 0 A ga gedumpte vlaggen ophalen:
8 6T 0 Z U 0 0 =) LTF voor NID
9 2S 2 Z E 0 A
10 6T 0 Z U 0 0 =) LTF voor JFLA
11 2S 19 Z E 0 A
12 6T 0 Z U 0 0 =) LTF voor FFLA
13 2S 4 Z E 0 A
14 6T 0 Z U 0 0 =) LTF voor MFLA
15 2S 1 Z E 0 A
16 6T 0 Z U 0 0 =) LTF voor IFLA
17 2S 18 Z E 0 A
18 6T 0 Z U 0 0 =) LTF voor EFLA
19 2A 2 Z E 0 Z JFLA = 0?
20 2S 0 A
21 2A 1 A
22 Y 6A 13 Z E 0 zo ja, dan AFLA:= 1
23 N 6A 29 Z E 0 zo neen, dan NFLA:= 1
24 Y 2A 56 A OPC van IND
25 N 2A 29 A OPC van SSI
26 6T 0 Z F 0 0 =) FRL met IND of SSI
27 Y 2T 0 E L 0 A -> zo ja, dan terug naar basiscyclus
28 6T 0 Z Y 0 0 =) RNS voor volgende delimiter
29 2T 0 E F 2 A => ga ID invullen en door naar DDEL
6 -> 30 2S 2 Z K 0 ARRAY DECLARATIE
31 0S 6 Z E 2
DC D0
175
EF1
DA 0 E F 1 DI
0 2A 0 A
1 6T 0 Z F 0 0 =) FRL met 2S ’AIC’ A
2 2A 24 Z E 1 IBD
3 0A 90 A OPC van RSF
4 2S 0 A
5 6T 0 Z F 0 0 =) FRL met RSF of ISF
6 2A 30 Z K 0 ga ID opbouwen: d26,d25,d15
7 U 2A 24 Z E 1 Z real?
8 N 0A 4 Z K 0 zo neen, voeg d19 toe
9 6A 5 Z E 2 frame opgebouwd
10 2B 30 Z E 0 NLSC
11 0B 31 Z E 0 NLIB
25 -> 12 2A 5 Z E 2 frame
13 0A 23 Z E 1 voeg PNLV als adres toe
14 6A 32767 X 0 B berg ID in naamlijst op
15 2S 32766 X 0 B
16 2LS 7 A Z eenwoordsnaam?
17 Y 1B 2 A
18 N 1B 3 A
19 2A 3 Z E 2 IC, de dimensie van het array
20 0A 3 A
21 2P 5 AA hoog PNLV op met IC + 3 als
22 4A 23 Z E 1 plaatsreservering voor STOFU
23 2A 1 A
24 5A 6 Z E 2 P AIC:= AIC - 1; AIC > 0?
25 Y 2T 12 E F 1 A -> zo ja, nog meer ID’s te maken
26 6T 0 F T 0 2 =) RND voor , of ;
27 2A 9 Z E 0
28 0LA 91 A Z DL = ;?
29 N 2T 20 K F 2 A -> zo neen, nog meer arrays van dit
30 6A 18 Z E 0 EFLA:= 0 type
31 2T 0 E L 0 A => terug naar basiscyclus
DC D0
176 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
EF2
DA 0 E F 2 DI
29EF0=> 0 2B 22 Z E 0 NID
1 0B 31 Z E 0 NLIB
2 2S 0 X 0 B
3 6S 8 Z E 0 ID:= NLI[NID]
4 2B 0 A
5 6B 16 Z E 0 PFLA:= 0
6 2T 0 E H 0 A => DDEL
DC D0
177
DA 0 E H 0 DI
=> 0 2B 9 Z E 0 DL
1 U 1B 65 A P
2 N 2T 0 E S 0 A -> als DL is + of -
3 U 1B 68 A P
4 N 2T 0 E T 0 A -> als * of / of div
5 U 1B 69 A P
6 N 2T 0 K T 0 A -> als **
7 U 1B 75 A P
8 N 2T 0 K K 0 A -> als < <= = >= > <>
9 U 1B 80 A P
10 N 2T 0 K L 0 A -> als not and or implies eqv
11 2T 69-E H 0 B => strooisprong
12 0A 0 K R 0 goto
13 0A 0 E Y 0 if
14 0A 0 E N 0 then
15 0A 0 F Z 0 else
16 0A 0 F E 0 for
17 0A 0 F L 0 do
18 0A 0 E K 0 ,
19 0B 0 X 0 .
20 0B 0 X 0 ten
21 0A 0 F N 0 :
22 0A 13 F S 2 ;
23 0A 0 E Z 0 :=
24 0B 0 X 0 spatie
25 0A 0 F H 0 step
26 0A 0 F K 0 until
27 0A 0 F F 0 while
28 0B 0 X 0 comment
29 0A 0 E W 0 (
30 0A 0 E U 0 )
31 0A 0 E E 0 [
DC D0
178 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
EH1
DA 0 E H 1 DI
0 0A 0 E F 0 ]
1 0A 0 K S 0 (*
2 0B 0 X 0 *)
3 0A 0 L Z 0 begin
4 0A 13 F S 2 end
5 0A 0 K H 0 own
6 0A 0 K Z 0 Boolean
7 0A 0 K Z 0 integer
8 0A 0 K E 0 real
9 0A 0 K F 0 array
10 0A 0 H E 0 switch
11 0A 0 H Y 0 procedure
12 0B 0 X 0 string
13 0B 0 X 0 label
14 0B 0 X 0 value
DC D0
179
DDEL , EK0
DA 0 E K 0 DI
11EH0=> 0 2A 1 A
1 6A 0 Z E 0 OFLA:= 1
2 2A 1 Z E 0 Z IFLA = 0?
3 Y 2T 8 E K 0 A -> dan geen subscriptscheider
6 -> 4 6T 0 Z S 0 1 =) OH:= 1; POP
5 6T 0 Z N 0 1 =) THENELSE?
6 Y 2T 4 E K 0 A -> zo ja, dan herhaal
7 2T 0 E L 0 A => terug naar basiscyclus
3 => 8 2A 6 Z E 0 Z VFLA = 0?
9 Y 2T 30 E K 0 A -> dan geen scheider in for list
12 -> 10 6T 0 Z S 0 1 =) OH:= 1; POP
11 6T 0 Z N 0 1 =) THENELSE?
12 Y 2T 10 E K 0 A -> zo ja, dan herhaal
1FL0 -> 13 2B 25 Z E 0
14 2S 32767 X 0 B TLI[TLSC - 1]
15 2LS 255 A isoleer operator
16 U 0LS 85 A Z is deze for?
17 Y 2A 21 A zo ja, dan OPC van FOR2
18 Y 2T 24 E K 0 A -> en klaar met analyse
19 1B 1 A zo neen,
20 6B 25 Z E 0 TLSC:= TLSC - 1
21 U 0LS 96 A Z was het dan misschien while?
22 Y 2A 23 A zo ja, dan OPC van FOR4
23 N 2A 26 A zo neen, dan OPC van FOR7
18 -> 24 2S 0 A
25 6T 0 Z F 0 0 =) FRL met FOR2, FOR4 of FOR7
26 2A 9 Z E 0
27 0LA 86 A Z DL = do? dwz, kwamen we uit DDEL do?
28 Y 2T 2 F L 0 A -> dan terug naar DDEL do
29 2T 0 E L 0 A => anders terug naar basiscyclus
9 => 30 2A 4 Z E 0 Z MFLA = 0?
31 Y 2T 31 E K 3 A -> dan geen parameterscheider
DC D0
180 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
EK1
DA 0 E K 1 DI
1EU0 -> 0 2B 25 Z E 0 PARAMETERSCHEIDER
1 2S 32767 X 0 B TLI[TLSC - 1]
2 2LS 255 A isoleer delimiter
3 U 0LS 87 A Z is deze een , ?
8,22 4 Y 2T 15 E K 1 A -> mogelijk geen impl.subr.
24 -> 5 6T 0 Z S 0 1 =) OH:= 1; POP
10EK4 6 6T 0 Z N 0 1 =) THENELSE?
7 N 6T 0 E R 0 1 =) zo neen, dan DOT?
8 Y 2T 5 E K 1 A -> zo ja, dan herhaal
9 2S 9 Z K 0 d24 en d20 toevoegen aan
17 -> 10 4S 32766 X 0 B TLI[TLSC - 2], de PORD in opbouw
11 2S 0 A
12 2A 13 A OPC van EIS
13 6T 0 Z F 0 0 =) FRL met EIS
14 2T 14 E K 2 A => volgende parameter voorbereiden
4 => 15 2A 13 Z E 0 Z AFLA = 0?
16 N 2S 10 Z K 0 zo neen, met d24, d20 en d19
17 N 2T 10 E K 1 A -> impl.subr. gaan afmaken
18 2S 32766 X 0 B
19 1S 24 Z E 0 Z TLI[TLSC - 2] = RLSC?
20 Y 3A 19 Z E 0 en ook
21 Y 2LA 2 Z E 0 Z not (FFLA = 0 and JFLA = 0)?
22 N 2T 5 E K 1 A -> zo neen, dan impl.subr. afmaken
23 2A 29 Z E 0 Z NFLA = 0?
24 Y 2T 5 E K 1 A -> zo ja, dan impl.subr. afmaken
25 2T 5 E K 4 A => test op standaardfunctie
16EK4=> 26 4P AS S:= A (:= ID): construeer PORD
27 U 2LA 0 Z K 0 Z statisch?
28 Y 2T 4 E K 2 A -> dan analyse voortzetten
29 2LS 32767 A isoleer adres uit ID
30 1P 5 SS schuif BN in kop
31 0S 3 Z K 0 voeg d16 toe (t oneven)
DC D0
181
EK2
DA 0 E K 2 DI
0 U 2LA 3 Z K 0 Z non-formeel?
1 N 0S 12 Z K 0 zo neen, voeg d17 toe (t:= 3)
2 N 2T 13 E K 2 A -> en klaar als actuele zelf formeel
3 2T 8 E K 2 A => zo ja, ga Q construeren
28EK1=> 4 2LS 11 Z K 0 handhaaf d25, d24 en het adres
5 0LA 13 Z K 0 inverteer d25 in ID
6 U 2LA 14 Z K 0 Z d25 = d24 = 0? dwz, is het FLI?
7 Y 0S 12 Z K 0 zo ja, voeg d17 toe (t:= 2)
3 -> 8 U 2LA 29 Z K 0 Z non-procedure?
9 N 0S 15 Z K 0 zo neen, dan d20 toevoegen (Q:= 2)
10 N 2T 13 E K 2 A -> en klaar met PORD
11 U 2LA 4 Z K 0 Z real?
12 N 0S 4 Z K 0 zo neen, dan d19 toevoegen (Q:= 1)
2,10 -> 13 6S 32766 X 0 B TLI[TLSC - 2]:= PORD
14EK1-> 14 2A 87 A
15 1A 9 Z E 0 Z DL = , ?
16 Y 2T 8 E W 1 A -> zo ja, dan volgende parameter
17 2A 0 A AFLEVERING PORD’S AAN RLI
18 6A 14 Z E 0 PSTA:= 0 (telling aantal parameters)
3EK3 -> 19 2S 15 Z E 0 A adres PSTB
20 6T 0 Z U 0 0 =) LTF voor delimiter
21 2A 15 Z E 0
22 2LA 255 A isoleer delimiter
23 0LA 87 A Z is deze een , ?
24 N 2T 4 E K 3 A -> zo neen, dan laatste PORD gehad
25 2A 1 A
26 4A 14 Z E 0 PSTA:= PSTA + 1
27 2S 15 Z E 0 A adres PSTB
28 6T 0 Z U 0 0 =) LTF voor PORD
29 2S 15 Z E 0
30 U 2LS 3 Z K 0 Z d16 = 0? dwz, t even?
31 2A 0 A
DC D0
182 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
EK3
DA 0 E K 3 DI
0 Y 0P 2 AS zo ja,
1 Y 3P 2 SS schuif d26 en d25 als opc naar A
2 6T 0 Z F 0 0 =) FRL met PORD
3 2T 19 E K 2 A => volgende PORD gaan afleveren
24EK2=> 4 3B 1 A
5 0B 25 Z E 0
6 6B 25 Z E 0 TLSC:= TLSC - 1
7 2B 0 X 0 B pak de in TLI gedumpte FLSC
8 0B 12 Z E 0 FLIB
9 2A 24 Z E 0 RLSC
10 6T 0 F U 0 0 =) FFL, dus FLI[TLI[TLSC]]:= RLSC
11 2A 0 A
12 2S 6 Z K 0
13 0S 14 Z E 0 PSTA
14 6T 0 Z F 0 0 =) FRL met 2A ’PSTA’ A
15 2A 1 A
16 5A 7 Z E 0 BN:= BN - 1
17 2S 19 Z E 0 A ga gedumpte vlaggen ophalen:
18 6T 0 Z U 0 0 =) LTF voor FFLA
19 2S 18 Z E 0 A
20 6T 0 Z U 0 0 =) LTF voor EFLA
21 6T 0 Z L 0 0 =) PTM
22 2A 0 A
23 6A 13 Z E 0 AFLA:= 0
24 2S 4 Z E 0 A
25 6T 0 Z U 0 0 =) LTF voor MFLA
26 2S 6 Z E 0 A
27 6T 0 Z U 0 0 =) LTF voor VFLA
28 2S 1 Z E 0 A
29 6T 0 Z U 0 0 =) LTF voor IFLA
30 2T 0 E L 0 A => terug naar basiscyclus
31EK0=> 31 2A 17 Z E 0 Z SFLA = 0? (dan array declaratie)
DC D0
183
EK4
DA 0 E K 4 DI
0 6T 0 F R 0 2 =) ETT
1 Y 2T 0 E L 0 A -> en zo ja, dan terug naar basiscyclus
2 2A 0 A zo neen, dan scheider in switch list
3 6A 5 Z E 0 OH:= 0
4 2T 5 E Z 2 A => verder samen met DDEL :=
25EK1=> 5 2A 22 Z E 0
6 1A 25 Z E 2 P NID > NLSCop? dwz, <> standaardftie?
7 N 2A 98 A zo neen,
8 N 2S 0 A
9 N 6T 0 Z F 0 0 =) FRL met TFP
10 N 2T 5 E K 1 A -> en klaar als standaardfunctie
11 2A 16 Z E 0 Z zo ja, is PFLA = 0?
12 N 1A 19 Z E 0 Z zo neen, is dan FFLA = 1?
13 N 6T 0 L F 0 0 =) TFO voor non-formele procedure
14 2B 25 Z E 0 neem TLSC weer op
15 2A 8 Z E 0 ID
16 2T 26 E K 1 A => ga PORD construeren
DC D0
184 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
basiscyclus EL0
DA 0 E L 0 DI
=> 0 6T 0 F T 0 2 =) RND
3HY1 -> 1 2A 29 Z E 0 Z NFLA = 0?
31KZ0 2 Y 6T 25 F W 1 0 =) zo ja, clear vlaggen
3 Y 2T 0 E H 0 A -> en weg naar DDEL
4 2A 3 Z E 1 Z KFLA = 0?
5 Y 6T 0 H Z 0 0 =) LFN indien identifier
6 N 6T 0 F W 0 0 =) LFC indien constante
7 2T 0 E H 0 A => naar DDEL
DC D0
185
aanroep 6T 0 E R0 1 =) DOT
DA 0 E R 0 DI
=) 0 2B 25 Z E 0
1 2S 32767 X 0 B S:= TLI[TLSC - 1]
2 2LS 255 A isoleer delimiter
3 0LS 86 A Z = do?
4 N 2T 9 X 0 Z zo neen, dan klaar, DOT = false
5 1B 5 A
6 6B 25 Z E 0 TLSC:= TLSC - 5
7 2A 2 X 0 B
8 6A 30 Z E 0 NLSC:= TLI[TLSC + 2]
9 2A 1 A
10 5A 7 Z E 0 BN:= BN - 1
11 2S 0 X 0 B gedumpte RLSC
12 2B 1 X 0 B gedumpte FLSC
13 0A 24 Z E 0 RLSC heersend
14 0B 12 Z E 0 FLIB
15 6T 0 F U 0 0 =) FFL, dus FLI[TLI[TLSC]:= RLSC + 1
16 0S 7 Z K 0
17 2A 1 A P opc1: relatief tov RLIB
18 6T 0 Z F 0 0 =) FRL met X1X 2T ’gedumpte RLSC’ A
19 2T 9 X 0 Z => klaar met DOT = true
DC D0
186 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DDEL + - ES0
DA 0 E S 0 DI
=>
0 2A 0 Z E 0 Z OFLA = 0?
1 N 2T 6 E S 0 A -> zo neen, dan + of - als teken
2 2A 9 A
3 6T 1 Z S 0 1 =) OH:= 9; POP
4 6T 0 Z W 0 0 =) FTD
5 2T 0 E L 0 A => terug naar basiscyclus
1 => 6 2A 64 A
7 1A 9 Z E 0 Z DL = + ?
8 N 2A 10 A zo neen, dan
9 N 6A 5 Z E 0 OH:= 10,
10 N 2A 132 A
11 N 6A 9 Z E 0 DL:= NEG,
12 N 6T 0 Z W 0 0 =) en FTD met NEG en OH
13 2T 0 E L 0 A => terug naar basiscyclus
DC D0
187
DA 0 E T 0 DI
=> 0 2A 10 A
1KT0 -> 1 6T 1 Z S 0 1 =) OH:= 10; POP
3KK0 2 6T 0 Z W 0 0 =) FTD
2KL0 3 2T 0 E L 0 A => terug naar basiscyclus
DC D0
188 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DDEL ( EW0
DA 0 E W 0 DI
=> 0 2A 1 A
1 6A 0 Z E 0 OFLA:= 1
2 2A 16 Z E 0 Z PFLA = 0?
3 N 2T 11 E W 0 A -> zo neen, dan procedurehaakje
17LH0-> 4 2S 4 Z E 0 expressiehaakje:
5 6T 0 Z T 0 0 =) FTL met MFLA
6 2A 0 A
7 6A 4 Z E 0 MFLA:= 0
12EW1-> 8 6A 5 Z E 0 OH:= 0
9 6T 0 Z W 0 0 =) FTD
10 2T 0 E L 0 A => terug naar basiscyclus
3 => 11 6T 0 L H 0 3 =) PST
12 2A 2 A opc2: referentie naar FLI
13 2S 26 Z E 0 FLSC
14 0S 8 Z K 0
15 6T 0 Z F 0 0 =) FRL met X2X 2T ’FLSC’
16 2S 1 Z E 0 ga vlaggen dumpen:
17 6T 0 Z T 0 0 =) FTL met IFLA
18 2S 6 Z E 0
19 6T 0 Z T 0 0 =) FTL met VFLA
20 2S 4 Z E 0
21 6T 0 Z T 0 0 =) FTL met MFLA
22 2S 18 Z E 0
23 6T 0 Z T 0 0 =) FTL met EFLA
24 2S 19 Z E 0
25 6T 0 Z T 0 0 =) FTL met FFLA
26 2S 26 Z E 0
27 6T 0 Z T 0 0 =) FTL met FLSC
28 2A 0 A ga vlaggen zetten:
29 6A 1 Z E 0 IFLA:= 0
30 6A 6 Z E 0 VFLA:= 0
31 2S 1 A
DC D0
189
EW1
DA 0 E W 1 DI
0 6S 4 Z E 0 MFLA:= 1
1 6S 18 Z E 0 EFLA:= 1
2 4S 26 Z E 0 FLSC:= FLSC + 1
3 6A 5 Z E 0 OH:= 0
4 4S 7 Z E 0 BN:= BN + 1
5 6T 0 Z W 0 0 =) FTD
6 2A 87 A
7 6A 9 Z E 0 DL:= ,
16EK2-> 8 2S 24 Z E 0
9 6T 0 Z T 0 0 =) FTL met RLSC
10 2A 0 A
11 6A 13 Z E 0 AFLA:= 0
12 2T 8 E W 0 A => verder als expressiehaakje
DC D0
190 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DDEL ) EU0
DA 0 E U 0 DI
=> 0 2A 4 Z E 0 Z MFLA = 0?
1 N 2T 0 E K 1 A -> zo neen, doe alsof parameterkomma
4 -> 2 6T 0 Z S 0 1 =) OH:= 1; POP
3 6T 0 Z N 0 1 =) THENELSE?
4 Y 2T 2 E U 0 A -> zo ja, dan herhaal
5 2A 1 A verwijder ( uit TLI:
6 5A 25 Z E 0 TLSC:= TLSC - 1
7 2S 4 Z E 0 A haal gedumpte vlag op:
8 6T 0 Z U 0 0 =) LTF voor MFLA
9 2T 0 E L 0 A => terug naar basiscyclus
DC D0
191
DDEL if EY0
DA 0 E Y 0 DI
=> 0 2A 18 Z E 0 Z EFLA = 0?
1 Y 6T 0 K N 0 2 =) zo ja, dan RLA
2 2S 18 Z E 0
3 6T 0 Z T 0 0 =) FTL met EFLA
4 2A 1 A
5 6A 18 Z E 0 EFLA:= 1
19EN0-> 6 2A 0 A
3KL0 -> 7 6A 5 Z E 0 OH:= 0
8 6T 0 Z W 0 0 =) FTD
9 2A 1 A
10 6A 0 Z E 0 OFLA:= 1
11 2T 0 E L 0 A => terug naar basiscyclus
DC D0
192 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 E N 0 DI
2-> => 0 6T 0 Z S 0 1 =) OH:= 1; POP
1 6T 0 Z N 0 1 =) THENELSE?
2 Y 2T 0 E N 0 A -> zo ja, dan herhaal
3 3B 1 A
4 0B 25 Z E 0 verwijder if uit TLI:
5 6B 25 Z E 0 TLSC:= TLSC - 1
6 2A 32767 X 0 B
7 6A 18 Z E 0 EFLA:= TLI[TLSC - 1]
8 2A 30 A OPC van CAC
9 2S 0 A
10 6T 0 Z F 0 0 =) FRL met CAC
11 2A 2 A opc2: referentie naar FLI
12 2S 26 Z E 0 FLSC
13 0S 16 Z K 0
14 6T 0 Z F 0 0 =) FRL met X2X N 2T ’FLSC’
3FZ1 -> 15 2S 26 Z E 0
16 6T 0 Z T 0 0 =) FTL met FLSC
17 2A 1 A
18 4A 26 Z E 0 FLSC:= FLSC + 1
19 2T 6 E Y 0 A => verder samen met DDEL if
DC D0
193
DA 0 F Z 0 DI
6-> => 0 6T 0 Z S 0 1 =) OH:= 1; POP
1 2B 25 Z E 0
2 2S 32767 X 0 B S:= TLI[TLSC - 1]
3 2LS 255 A isoleer delimiter
4 U 0LS 84 A Z is deze een else?
5 Y 6T 6 Z N 0 1 =) zo ja, dan THENELSE
6 Y 2T 0 F Z 0 A -> en herhaal
8,27 -> 7 6T 0 E R 0 1 =) DOT?
8 Y 2T 7 F Z 0 A -> zo ja, dan herhaal
9 2B 25 Z E 0
10 2S 32767 X 0 B S:= TLI[TLSC - 1]
11 U 0LS 161 A Z blokbeginmarker op top TLI?
12 N 2T 28 F Z 0 A -> zo neen, dan eenvoudig
13 1B 3 A ga eerst blok afronden:
14 6B 25 Z E 0 TLSC:= TLSC - 3
15 2S 1 X 0 B
16 6S 30 Z E 0 NLSC:= TLI[TLSC + 1]
17 2B 0 X 0 B pak gedumpte FLSC
18 0B 12 Z E 0 FLIB
19 2A 1 A
20 0A 24 Z E 0 RLSC
21 6T 0 F U 0 0 =) FFL, dus FLI[TLI[TLSC]]:= RLSC + 1
22 2S 0 A
23 2A 12 A OPC van RET
24 6T 0 Z F 0 0 =) FRL met RET
25 2A 1 A
26 5A 7 Z E 0 BN:= BN - 1
27 2T 7 F Z 0 A => en herhaal DOT-test
12 => 28 2A 2 A opc2: referentie naar FLI
29 2S 26 Z E 0 FLSC
30 0S 8 Z K 0
31 6T 0 Z F 0 0 =) FRL met X2X 2T ’FLSC’
DC D0
194 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
FZ1
DA 0 F Z 1 DI
0 6T 0 Z N 0 1 =) THENELSE (vindt then)
1 2A 1 A behoud EFLA in TLI:
2 4A 25 Z E 0 TLSC:= TLSC + 1
3 2T 15 E N 0 A => verder samen met DDEL then
DC D0
195
DA 0 F E 0 DI
=> 0 6T 0 K N 0 2 =) RLA
1 2A 2 A opc2: referentie naar FLI
2 2S 26 Z E 0 FLSC
3 0S 8 Z K 0
4 6T 0 Z F 0 0 =) FRL met X2X 2T ’FLSC’
5 2A 26 Z E 0 FLSC
6 6A 10 Z E 0 dumpen in FORA
7 0A 1 A
8 6A 26 Z E 0 FLSC:= FLSC + 1
9 2S 24 Z E 0
10 6T 0 Z T 0 0 =) FTL met RLSC
11 2A 1 A
12 6A 6 Z E 0 VFLA:= 1
3FL1 13 4A 7 Z E 0 BN:= BN + 1
4FF0 -> 14 2A 0 A
2KF3 15 6A 5 Z E 0 OH:= 0
4LZ0 16 6T 0 Z W 0 0 =) FTD
17 2T 0 E L 0 A => terug naar basiscyclus
DC D0
196 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 F F 0 DI
=> 0 6T 0 F R 0 2 =) ETT
1 2A 22 A OPC van FOR3
2KF0 -> 2 2S 0 A
3 6T 0 Z F 0 0 =) FRL met FOR3 of FOR6
4 2T 14 F E 0 A => naar einde DDEL for
DC D0
197
DA 0 F H 0 DI
=> 0 6T 0 F R 0 2 =) ETT
1 2A 24 A OPC van FOR5
2 2S 0 A
3 6T 0 Z F 0 0 =) FRL met FOR5
4 2T 0 E L 0 A => terug naar basiscyclus
DC D0
198 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 F K 0 DI
=> 0 6T 0 F R 0 2 =) ETT
1 2A 25 A OPC van FOR6
2 2T 2 F F 0 A => naar einde DDEL while
DC D0
199
DDEL do FL0
DA 0 F L 0 DI
=> 0 6T 0 F R 0 2 =) ETT
1 2T 13 E K 0 A => doe een stuk uit DDEL ,
28EK0=> 2 6A 6 Z E 0 VFLA:= 0 (einde for clause)
3 2A 1 A verwijder for uit TLI:
4 5A 25 Z E 0 TLSC:= TLSC - 1
5 2A 2 A opc2: referentie naar FLI
6 2S 26 Z E 0 FLSC
7 0S 17 Z K 0
8 6T 0 Z F 0 0 =) FRL met X2X 2S ’FLSC’
9 2S 26 Z E 0
10 6T 0 Z T 0 0 =) FTL met FLSC
11 2A 1 A
12 4A 26 Z E 0 FLSC:= FLSC + 1
13 2A 27 A OPC van FOR8
14 2S 0 A
15 6T 0 Z F 0 0 =) FRL met FOR8
16 2B 10 Z E 0 pak de in FORA gedumpte FLSC
17 0B 12 Z E 0 FLIB
18 2A 24 Z E 0 RLSC
19 6T 0 F U 0 0 =) FFL, dus FLI[FORA]:= RLSC
20 2A 19 A OPC van FOR0
21 2S 0 A
22 6T 0 Z F 0 0 =) FRL met FOR0
23 2A 1 A opc1: relatief tov RLIB
24 2B 25 Z E 0
25 2S 32766 X 0 B TLI[TLSC - 2]
26 0S 7 Z K 0
27 6T 0 Z F 0 0 =) FRL met X1X 2T ’gedumpte RLSC’ A
28 2B 11 Z E 0 pak de in FORC gedumpte FLSC
29 0B 12 Z E 0 FLIB
30 2A 24 Z E 0 RLSC
31 6T 0 F U 0 0 =) FFL, dus FLI[FORC]:= RLSC
DC D0
200 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
FL1
DA 0 F L 1 DI
0 2A 0 A
1 6A 18 Z E 0 EFLA:= 0
2 6T 2 H W 0 0 =) INB
3 2T 14 F E 0 A => naar einde DDEL for
DC D0
201
aanroep 6T 0 F R0 2 =) ETT
DA 0 F R 0 DI
=) 0 2A 10 X 0
1 6A 4 Z E 1 red link
2 2A 1 A
3 6A 0 Z E 0 OFLA:= 1
6 -> 4 6T 0 Z S 0 1 =) OH:= 1; POP
5 6T 0 Z N 0 1 =) THENELSE?
6 Y 2T 4 F R 0 A -> zo ja, dan herhaal
7 2T 4 Z E 1 E => klaar, terug via geredde link
DC D0
202 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 F S 0 DI
20FS1=> 0 6T 0 F R 0 2 =) ETT
2 1 6T 0 E R 0 1 =) DOT?
2 Y 2T 0 F S 0 A -> zo ja, dan herhaal
3 2A 17 Z E 0 Z SFLA = 0?
4 Y 2T 2 F S 1 A -> dan niet einde van switchdeclaratie
5 2A 0 A ga switchdeclaratie afmaken:
6 6A 17 Z E 0 SFLA:= 0
17 -> 7 2B 25 Z E 0
8 2S 32767 X 0 B TLI[TLSC - 1]
9 U 0LS 160 A Z = switchkomma?
10 N 2T 18 F S 0 A -> zo neen, dan laatste element gehad
11 1B 2 A
12 6B 25 Z E 0 TLSC:= TLSC - 2
13 2S 0 X 0 B TLI[TLSC]
14 0S 7 Z K 0
15 2A 1 A opc1: relatief tov RLIB
16 6T 0 Z F 0 0 =) FRL met X1X 2T ’gedumpte RLSC’ A
17 2T 7 F S 0 A => volgende sport van switchladder
10 => 18 1B 1 A verwijder := uit TLI:
19 6B 25 Z E 0 TLSC:= TLSC - 1
20 2S 22 Z E 0 A
21 6T 0 Z U 0 0 =) LTF voor NID
22 6T 0 F Y 0 2 =) LDEC
23 2S 20 Z K 0
24 2A 0 A
25 6T 0 Z F 0 0 =) FRL met 1T 16 X1
26 2B 25 Z E 0
27 1B 1 A
28 6B 25 Z E 0 TLSC:= TLSC - 1
29 2B 0 X 0 B TLI[TLSC]
30 0B 12 Z E 0 FLIB
31 2A 24 Z E 0 RLSC
DC D0
203
FS1
DA 0 F S 1 DI
0 6T 0 F U 0 0 =) FFL, dus FLI[TLI[TLSC]]:= RLSC
1 2T 10 F S 2 A => ga EFLA op 0 zetten en testen
4FS0 => 2 2B 25 Z E 0
3 2S 32767 X 0 B TLI[TLSC - 1]
4 U 0LS 161 A Z blokbeginmarker op top van TLI?
5 N 2T 10 F S 2 A -> zo neen, ga dan EFLA op 0 zetten
6 1B 3 A ga eerst blok afronden:
7 6B 25 Z E 0 TLSC:= TLSC - 3
8 2S 1 X 0 B
9 6S 30 Z E 0 NLSC:= TLI[TLSC + 1]
10 2B 0 X 0 B pak gedumpte FLSC
11 0B 12 Z E 0 FLIB
12 2A 1 A
13 0A 24 Z E 0 RLSC
14 6T 0 F U 0 0 =) FFL, dus FLI[TLI[TLSC]]:= RLSC + 1
15 2S 0 A
16 2A 12 A OPC van RET
17 6T 0 Z F 0 0 =) FRL met RET
18 2A 1 A
19 5A 7 Z E 0 BN:= BN - 1
20 2T 0 F S 0 A => en begin van voor af aan
12FS2=> 21 2S 9 Z E 0 DL
22 0LS 105 A Z = end?
23 N 2T 0 E L 0 A -> zo neen, dan terug naar basiscyclus
24 2A 25 Z E 0 verwijder begin uit TLI:
25 1A 1 A
26 6A 25 Z E 0 TLSC:= TLSC - 1
27 1A 1 A
28 1A 8 Z E 1 Z TLSC = 1? (alleen nog BB in TLI?)
29 Y 2T 0 K W 0 A -> zo ja, dan einde programma
3FS2 -> 30 6T 0 Z Y 0 0 =) RNS
31 2A 9 Z E 0 DL
DC D0
204 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
FS2
DA 0 F S 2 DI
0 U 0LA 91 A Z DL = ;?
1 N 1A 84 A Z of DL = else?
2 N 1A 21 A Z of DL = end?
3 N 2T 30 F S 1 A -> zo neen, dan commentaar skippen
4 2A 0 A ga vlaggen zetten:
5 6A 2 Z E 0 JFLA:= 0
6 6A 16 Z E 0 PFLA:= 0
7 6A 19 Z E 0 FFLA:= 0
8 6A 29 Z E 0 NFLA:= 0
9 2T 0 E H 0 A => naar DDEL
1FS1 => 10 2S 0 A
5FS1 11 6S 18 Z E 0 EFLA:= 0
12 2T 21 F S 1 A => ga testen op end
DDEL => 13 6T 0 K N 0 2 =) RLA
14 2T 0 F S 0 A => naar begin van deze DDEL
DC D0
205
aanroep 6T 0 F T0 2 =) RND
DA 0 F T 0 DI
=) 0 6T 0 Z Y 0 0 =) RNS
=) 1 2S 1 A
2 6S 29 Z E 0 NFLA:= 1
3 2A 9 Z E 0 DL
4 U 1A 63 A P
5 U 1A 9 A E verschillend van letter?
6 Y 2T 15 F T 1 A -> zo ja, dan geen identifier
7 2S 0 A
8 6S 2 Z E 1 DFLA:= 0
9 6S 3 Z E 1 KFLA:= 0
18 -> 10 1P 6 SA schuif symbool naar kop van S
11 U 2LS 7 A Z nog minder dan 5 symbolen?
12 6S 1 Z E 1 INW
13 N 2T 20 F T 0 A -> zo neen, dan dubbele naam
14 6T 0 Z Y 0 0 =) RNS
15 2S 1 Z E 1 INW
16 2A 9 Z E 0 DL
17 U 1A 63 A P geen letter of cijfer?
18 N 2T 10 F T 0 A -> zo neen, dan voortgaan
19 2T 22 F T 4 A => zo ja, dan klaar met enkele naam
13 => 20 2S 1 A
21 6S 2 Z E 1 DFLA:= 1
22 0A 18 Z K 0 d23 (als eindmarker)
23 6A 0 Z E 1 FNW
31 -> 24 6T 0 Z Y 0 0 =) RNS
25 2A 0 Z E 1 FNW
26 2S 9 Z E 0 DL
27 U 1S 63 A P verschillend van letter of cijfer?
28 Y 2T 18 F T 4 A -> dan klaar met dubbele naam
29 1P 6 SA Z aantal symbolen nog minder dan 9?
30 6A 0 Z E 1 FNW
31 Y 2T 24 F T 0 A -> zo ja, dan voortgaan
DC D0
206 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
FT1
DA 0 F T 1 DI
3 -> 0 6T 0 Z Y 0 0 =) RNS
1 2S 9 Z E 0 DL
2 1S 63 A P verschillend van letter of cijfer?
3 N 2T 0 F T 1 A -> anders overtollig symbool skippen
4 2T 22 F T 4 A => klaar met naam van 9 symbolen
=) 5 6T 0 Z Y 0 0 =) RNS SUBROUTINE TEST-OP-CIJFER
6 2A 9 Z E 0 DL
9FT5 -> 7 U 1LA 88 A Z = .?
8 Y 2S 1 A zo ja, decimale punt gevonden,
9 Y 6S 2 Z E 1 dus DFLA:= 1
10 Y 2T 4 F T 2 A -> en terug naar assemblagecyclus
11 U 1LA 89 A Z DL = ten?
12 Y 2T 10 F T 2 A -> zo ja, ga exponent lezen
13 U 1A 9 A P verschillend van cijfer?
14 2T 9 X 0 Z => terug, met behoud van conditie
6FT0 => 15 6S 3 Z E 1 KFLA:= 1
16 2B 0 A
17 6B 0 Z E 1 FNW:= 0
18 6B 1 Z E 1 INW:= 0
19 6B 2 Z E 1 DFLA:= 0
20 6B 4 Z E 1 ELSC:= 0
21 6T 7 F T 5 1 =) test op ten en doe subr. test-op-cijfer
22 Y 2B 0 A als DL <> cijfer of ten dan
23 Y 6B 29 Z E 0 NFLA:= 0 en
24 Y 2T 25 F T 4 A -> ga testen op true en false
5FT2 -> 25 2S 0 Z E 1 FNW CYCLUS GETALASSEMBLAGE
26 2LS 19 Z K 0 Z < 2**22? dan bijvermenigvuldigen:
27 Y 2S 1 Z E 1 INW
28 Y 0X 10 A AS:= 10 * INW + cijfer
29 Y 6S 1 Z E 1 nieuwe INW
30 Y 2S 0 Z E 1 FNW
31 Y 0X 10 A AS:= 10 * FNW + overloop uit INW
DC D0
207
FT2
DA 0 F T 2 DI
0 Y 6S 0 Z E 1 nieuwe FNW
1 3S 2 Z E 1 DFLA
2 N 0S 1 A aantal cijfers tellen:
3 4S 4 Z E 1 ELSC:= ELSC - DFLA + 0 of 1
10FT1-> 4 6T 5 F T 1 1 =) subr. test-op-cijfer
5 N 2T 25 F T 1 A -> als DL niet <> cijfer
6 2S 2 Z E 1 Z DFLA = 0?
7 Y 2S 0 Z E 1 Z and FNW = 0?
8 Y 2T 22 F T 4
A -> zo ja, dan klaar met integer
9 2T 27 F T 2
A => zo neen, dan gaan floaten
12FT1=> 10 6T 5 F T 1
1 =) subr. test-op-cijfer
11 N 2T 16 F T 2
A -> als DL niet <> cijfer
12 0LA 64 A Z DL = +?
13 6T 0 Z Y 0 0 =) RNS voor eerste cijfer exponent
14 Y 2A 9 Z E 0 zo ja, dan A:= + DL
15 N 3A 9 Z E 0 zo neen, dan A:= - DL
11 -> 16 6A 2 Z E 1 DFLA:= eerste cijfer exponent
17 2T 23 F T 2 A => ga volgende cijfers lezen
24 => 18 2S 2 Z E 1 P DFLA CYCLUS OPBOUW EXPONENT
19 N 5P AA
20 0X 10 A Z S:= 10 * DFLA + sign(DFLA) * cijfer
21 N 7Y 3 C 0 en stop als dit naar A overloopt
22 6S 2 Z E 1 nieuwe DFLA
17 -> 23 6T 5 F T 1 1 =) subr. test-op-cijfer
24 N 2T 18 F T 2 A -> als DL niet <> cijfer
25 2S 2 Z E 1 DFLA met
26 4S 4 Z E 1 ELSC samen de complete exponent
9 -> 27 3A 0 Z E 1 FNW CONVERSIE NAAR FLOATING
28 3S 1 Z E 1 INW
29 6P AS Z normeer; kop = 0?
17FT4-> 30 Y 7S 2 Z E 1 zo ja, dan DFLA:= 0 voor integer 0
31 Y 2T 22 F T 4 A -> en klaar
DC D0
208 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
FT3
DA 0 F T 3 DI
0 1B 2100 A 2**11 + 52 (P9-karakteristiek)
1 7B 2 Z E 1 bijdrage tot binaire karakteristiek
2 2B 8 A B:= 8
3 U 2A 4 Z E 1 P ELSC >= 0?
4 N 2T 16 F T 3 A -> zo neen, dan decimale exponent negatief
5 7A 0 Z E 1 FNW:= - kop
6 2T 30 F T 3 A =>
19 => 7 U 0A 15 D14 B P NEGATIEVE DECIMALE EXPONENT
8 N 3P 1 AS halveer zo nodig
9 0D 15 D14 B en deel door 10**B
10 7S 0 Z E 1 FNW:= - nieuwe kop
11 0D 15 D14 B deel de rest ook nog
12 3A 23 D14 B de met 10**B
13 N 0A 1 A corresponderende binaire exponent
14 4A 2 Z E 1 bijtellen bij de binaire karakteristiek
15 3A 0 Z E 1 FNW
4 -> 16 U 0B 4 Z E 1 P ELSC > - B?
17 Y 3B 4 Z E 1 Z zo ja, dan B:= - ELSC; B = 0?
18 N 4B 4 Z E 1 zo neen, dan ELSC:= ELSC + B
19 N 2T 7 F T 3 A -> en verder gaan delen
20 2T 3 F T 4 A => reductie voltooid
1FT4 => 21 2X 15 D14 B POSITIEVE DECIMALE EXPONENT
22 3S 0 Z E 1 A:= 10**B * (- staart)
23 0X 15 D14 B AS:= 10**B * (-kop) + A
24 0P 1 AS P
25 Y 1P 1 AS zo mogelijk nog verdubbelen
26 7A 0 Z E 1 FNW:= - nieuwe kop
27 2A 23 D14 B de met 10**B
28 N 1A 1 A corresponderende binaire exponent
29 4A 2 Z E 1 bijtellen bij de binaire karakteristiek
6 -> 30 U 1B 4 Z E 1 P ELSC < B?
31 Y 2B 4 Z E 1 Z zo ja, dan B:= ELSC; B = 0?
DC D0
209
FT4
DA 0 F T 4 DI
0 N 5B 4 Z E 1 zo neen, dan ELSC:= ELSC - B
1 N 2T 21 F T 3 A -> en verder gaan vermenigvuldigen
2 3A 0 Z E 1 FNW
20FT3-> 3 1S 2048 A P AFRONDING
4 Y 3S 0 A als staart overloopt dan
5 Y 1A 1 A P carry naar kop
6 Y 1P 1 AA zo nodig deze halveren
7 7A 0 Z E 1 FNW:= voltooide kop
8 5P SS
9 3LS 4095 A in staart plaats maken
10 6S 1 Z E 1 INW:= staart
11 2S 2 Z E 1 binaire karakteristiek
12 Y 0S 1 A
13 U 3LS 4095 A Z tussen - 4096 en + 4096?
14 N 7Y 4 C 0 zo neen, dan overschrijding capaciteit
15 4S 1 Z E 1 bijtellen bij staart in INW
16 3S 1 A
17 2T 30 F T 2 A => DFLA op 1 gaan zetten en klaar
28FT0=> 18 3S 0 A als naam <= 9 symbolen dan
20 19 1P 6 SA P ’loos’ bijschuiven
20 Y 2T 18 F T 4 A -> zo nodig herhalen
21 6A 0 Z E 1 FNW
19FT0-> 22 2A 0 A
6FT5 23 6A 0 Z E 0 OFLA:= 0
24 2T 10 X 0 E => klaar
24FT1=> 25 2A 9 Z E 0 DL
26 U 1A 117 A Z = false?
27 Y 2S 1 A
28 N 2S 0 A
29 U 1A 115 A E of DL = true?
30 Y 2T 10 X 0 E -> klaar als noch true noch false
31 6S 1 Z E 1 INW:= 0 of 1
DC D0
210 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
FT5
DA 0 F T 5 DI
0 2A 0 A
1 6A 2 Z E 1 DFLA:= 0
2 2A 1 A
3 6A 3 Z E
1 KFLA:= 1
4 6A 29 Z E
0 NFLA:= 1
5 6T 0 Z Y
0 0 =) RNS voor delimiter na true of false
6 2T 22 F T
4 A => klaar
21FT1=) 7 U 1LA 89 A Z DL = ten?
8 Y 6S 1 Z E 1 zo ja, maak numeriek gedeelte = 1
9 2T 7 F T 1 A => door naar test-op-cijfer
DC D0
211
aanroep 6T 0 F W0 0 =) LFC
DA 0 F W 0 DI
=) 0 2A 31 Z E 0 NLIB
1 1A 2 Z E 1 DFLA
2 1A 27 Z E 0 KLSC
3 1A 28 Z E 0 P KLIB + KLSC + DFLA < NLIB?
4 N 2T 10 F W 1 A -> zo neen, dan NLI opschuiven
24FW1-> 5 2B 27 Z E 0 KLSC
6 0B 28 Z E 0 KLIB
7 2S 1 Z E 1 INW
8 2A 2 Z E 1 Z DFLA = 0?
9 N 2T 18 F W 0 A -> zo neen, dan floating getal
10 6S 0 X 0 B KLI[KLSC]:= integer
11 2B 28 Z E 0 KLIB
14 -> 12 U 0LS 0 X 0
B Z CYCLUS ZOEK INTEGER
16 -> 13 N 0B 1 A
14 N 2T 12 F W 0 A -> als niet + 0 of - 0 dan volgende
15 U 2A 1 A E + 0?
16 N 2T 13 F W 0 A -> zo niet, dan slechts complement
17 2T 31 F W 0 A => integer gevonden
9 => 18 2A 0 Z E 1 FNW
19 6A 0 X 0 B KLI[KLSC]:= kop
20 6S 1 X 0 B KLI[KLSC + 1]:= staart
21 2B 28 Z E 0 KLIB
24 -> 22 U 0LA 0 X 0 B Z CYCLUS ZOEK FLOATING
26,28-> 23 N 0B 1 A als kop niet klopt
30 24 N 2T 22 F W 0 A -> dan volgende
25 U 2A 1 A E + 0?
26 N 2T 23 F W 0 A -> zo niet, dan slechts complement
27 U 0LS 1 X 0 B Z klopt ook de staart?
28 N 2T 23 F W 0 A -> zo neen, dan volgende
29 U 2A 1 A E + 0?
30 N 2T 23 F W 0 A -> zo niet, dan slechts complement
17 -> 31 5P BS
DC D0
212 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
FW1
DA 0 F W 1 DI
0 0S 28 Z E 0
1 U 0S 27 Z E 0 Z KLSC teruggevonden?
2 Y 2B 1 A zo ja,
3 Y 0B 2 Z E 1 dan nog niet eerder ontmoet,
4 Y 4B 27 Z E 0 dus KLSC:= KLSC + DFLA + 1
5 2A 2 Z E 1 Z CONSTRUCTIE ID
6 Y 3LS 4 Z K 0 als DFLA = 0 dan d19 toevoegen
7 3LS 14 Z K 0 d25, d24 toevoegen als opc3
8 7S 8 Z E 0 berg ID
9 2T 25 F W 1 A => ga vlaggen zetten
4FW0 => 10 2B 30 Z E 0 OPSCHUIVEN VAN NLI
11 6B 0 X 0 aantal:= NLSC
12 0B 31 Z E 0 NLIB
13 5P BS
14 1S 16 A
15 0S 21 Z E 0 P NLIB + NLSC + 16 < PLIB?
16 N 7Y 5 C 0 zo neen, stop: NLI schuift in PLI
17 2T 21 F W 1 A =>
21 => 18 1B 1 A opschuifcyclus:
19 2S 0 X 0 B 16 plaatsen
20 6S 16 X 0 B omhoog
17 -> 21 4T 18 F W 1 0 E ->
22 2S 16 A
23 4S 31 Z E 0 NLIB:= NLIB + 16
24 2T 5 F W 0 A => klaar met schuiven
9 => 25 2A 0 A zet vlaggen
26 6A 2 Z E 0 JFLA:= 0
27 6A 16 Z E 0 PFLA:= 0
28 6A 19 Z E 0 FFLA:= 0
29 2T 8 X 0 E => klaar
DC D0
213
aanroep 6T 0 F U0 0 =) FFL
functie FLI[B]:= A
DA 0 F U 0 DI
21=> =) 0 U 5B 28 Z E 0 P B < KLIB?
1 Y 6A 0 X 0 B zo ja, dan FLI[B]:= A
2 Y 2T 8 X 0 E -> en klaar
3 6B 1 X 1 OPSCHUIVEN VAN KLI EN NLI
4 6A 0 X 1 red A en B
5 2B 30 Z E 0 NLSC
6 0B 31 Z E 0 NLIB
7 5P BA
8 1A 16 A
9 U 0A 21 Z E 0 P NLIB + NLSC + 16 < PLIB?
10 N 7Y 6 C 0 zo neen, stop: schuiven in PLI
11 0A 16 A
12 0A 28 Z E 0 KLIB
13 7A 0 X 0 aantal:= NLIB + NLSC - KLIB
14 2A 16 A
15 4A 28 Z E 0 KLIB:= KLIB + 16
16 4A 31 Z E 0 NLIB:= NLIB + 16
20 -> 17 1B 1 A opschuifcyclus
18 2A 0 X 0 B 16 plaatsen
19 6A 16 X 0 B omhoog
20 4T 17 F U 0 0 P ->
21 2A 0 X 1 herstel A en B
22 2B 1 X 1
23 2T 0 F U 0 A => en opnieuw proberen
DC D0
214 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 F Y0 2 =) LDEC
DA 0 F Y 0 DI
=) 0 2B 22 Z E 0 NID
1 0B 31 Z E 0 NLIB
2 2A 0 X 0 B ID uit NLI
3 U 2LA 0 Z K 0 Z d15 = 0?
4 N 2T 10 F Y 0 A -> zo neen, dan first occurrence
5 4P AB
6 0B 12 Z E 0 FLIB
7 2A 24 Z E 0 RLSC
8 6T 0 F U 0 0 =) FFL, dus FLI[FLSC uit ID]:= RLSC
9 2T 15 F Y 0 A => ga labelnaam typen
4 => 10 3LA 0 Z K 0 d15:= 0
11 3LA 32767 A maak plaats voor adres
12 0A 24 Z E 0 RLSC als adres
13 0A 21 Z K 0 d24 als codering toevoegen
14 6A 0 X 0 B ID in NLI opbergen
9 -> 15 2S 11 X 4 A
16 6S 11 Z E 1 SHIFT:= undefined
17 6T 0 H R 0 0 =) FOB6 met TWNR
18 2B 22 Z E 0 NID
19 0B 31 Z E 0 NLIB
20 2A 32767 X 0 B INW uit NLI
21 U 2LA 7 A Z eenwoordsnaam?
22 N 2T 2 F Y 1 A -> zo neen dan dubbele naam typen
23 2B 4 A hoogstens 4 letters of cijfers
24 1P 3 AA
28 -> 25 U 2LA 63 A Z ’letter’ = loos?
26 Y 1B 1 A zo ja,
27 Y 3P 6 AA dan overslaan
28 Y 2T 25 F Y 0 A -> en herhalen
0FY1 -> 29 6T 0 H S 0 1 =) OCT
30 1B 1 A P nog meer letters?
31 Y 3P 6 AA zo ja,
DC D0
215
FY1
DA 0 F Y 1 DI
0 Y 2T 29 F Y 0 A -> dan herhalen
1 2T 10 F Y 1 A => ga 32-tallig adres typen
22FY0=> 2 2S 32766 X 0 B FNW uit NLI
3 1P 3 SS
4 0P 3 SA stel beginletter samen
5 2B 9 A hoogstens 9 letters of cijfers
9 -> 6 6T 0 H S 0 1 =) OCT
7 1B 1 A P nog meer letters?
8 Y 1P 6 SA zo ja,
9 Y 2T 6 F Y 1 A -> dan herhalen
1 -> 10 2S 10 X 4 A
11 6T 0 H R 0 0 =) FOB6 met Tabulatie
12 2B 3 A 3 groepen van 2 cijfers
13 2S 24 Z E 0 RLSC gaan herleiden
14 2T 30 F Y 1 A =>
28 => 15 2S 56 X 4 A
16 6T 0 H R 0 0 =) FOB6 met spatie
17 2S 12 Z E 1 LDECA
31 -> 18 2A 0 A isoleer 32-tallige eenheid
19 1P 10 SA
20 1P 12 AA
21 6A 12 Z E 1 LDECA:= rest
22 2A 0 A
23 0D 10 A
24 0P 27 SA
25 6T 0 H S 0 1 =) OCT met eerste cijfer
26 4P SA
27 6T 0 H S 0 1 =) OCT met tweede cijfer
28 4T 15 F Y 1 0 P ->
29 2T 10 X 0 E => klaar
14 => 30 6B 0 X 0 aantal:= 3
31 2T 18 F Y 1 A =>
DC D0
216 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DDEL : FN0
DA 0 F N 0 DI
=> 0 2A 2 Z E 0 Z JFLA = 0?
1 N 2T 6 F N 0 A -> zo neen, dan label gevonden
2 2A 1 A zo ja, dan arraydeclaratie:
3 4A 3 Z E 2 IC:= IC + 1
4 6T 0 F R 0 2 =) ETT
5 2T 0 E L 0 A => terug naar basiscyclus
1 => 6 6T 0 K N 0 2 =) RLA
7 6T 0 F Y 0 2 =) LDEC
8 2T 0 E L 0 A => terug naar basiscyclus
DC D0
217
aanroep 6T 0 H Z0 0 =) LFN
DA 0 H Z 0 DI
=) 0 2B 30 Z E 0 NLSC
1 0B 31 Z E 0 NLIB
13 -> 2 2A 32766 X 0 B INW uit NLI
3 U 1A 1 Z E 1 Z klopt INW?
4 N 2T 9 H Z 0 A -> zo neen, dan volgende proberen
5 U 2LA 7 A Z enkelwoords naam?
6 N 2S 32765 X 0 B zo neen,
7 N 1S 0 Z E 1 Z klopt dan ook FNW?
8 Y 2T 15 H Z 0 A -> zo ja, dan naam gevonden
4 -> 9 2LA 7 A Z enkelwoords naam?
10 Y 1B 2 A
11 N 1B 3 A
12 U 1B 31 Z E 0 P nog in NLI?
13 Y 2T 2 H Z 0 A -> zo ja, dan nog eens proberen
14 2B 2 Z E 1 A Z adres van DFLA
8 -> 15 Y 1B 1 A
16 Y 2A 0 X 0 B ID uit NLI
17 1B 31 Z E 0 NLIB
18 6B 22 Z E 0 NID
19 N 2T 31 H Z 0 A -> als niet naam-in-naamlijst
20 6A 8 Z E 0 berg ID
21 0P 9 SA zet vlaggen:
22 2LS 1 A
23 6S 16 Z E 0 Z PFLA:= d18 van ID
24 N 2S 0 A
25 0P 1 SA
26 6S 2 Z E 0 Z JFLA:= d17 van ID
27 N 2S 0 A
28 0P 1 SA
29 6S 19 Z E 0 FFLA:= d16 van ID
30 2T 8 X 0 E => klaar
19 => 31 2A 12 A NAAM NIET IN NAAMLIJST
DC D0
218 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
HZ1
DA 0 H Z 1 DI
0 6A 26 X 0 klasse 6 in neutrale toestand
1 7A 2 Z E 2 typ-magazijn leeg
2 7A 17 Z E 1 typen imperatief
3 2S 11 X 4 A
4 6T 0 H R 0 0 =) FOB6 met TWNR
5 2A 0 A
6 6A 24 Z E 0 RLSC:= 0
7 6T 15 F Y 0 2 =) LDEC voor typen van naam
9 -> 8 6T 5 D 1 0 =) TPA?
9 Y 1T 2 A -> wacht dan op voltooiing
10 7Y 7 C 0 stop: naam niet in NLI
DC D0
219
DA 0 H E 0 DI
=> 0 6T 0 K N 0 2 =) RLA
1 2A 1 A
2 6A 17 Z E 0 SFLA:= 1
3 6T 0 H U 0 1 =) NBD
4 2T 0 E L 0 A => terug naar basiscyclus
DC D0
220 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 H F 0 DI
=) 0 2S 0 A
1 2T 3 H F 0 A =>
=) 2 2S 1 A
1 -> 3 0S 5 Z E 1 BC
4 0S 5 Z E 1
5 6S 0 X 0 aantal:= 2 * BC + 0 of 1
6 2A 2 Z E 1 DFLA
7 0A 1 A
8 2S 21 Z E 0 A adres PLIB
12 -> 9 4P SB CYCLUS VERLAAG ADRESSEN IN
10 2S 0 X 0 B PLI-KETTING
11 5A 0 X 0 B
12 4T 9 H F 0 0 E ->
13 6S 0 X 1 S bevat nu het adres van het
14 1S 21 Z E 0 PLIB laatste nog te
15 1S 2 Z E 1 DFLA verschuiven woord
16 6S 0 X 0 aantal
17 2B 21 Z E 0 PLIB (is al afgelaagd)
18 U 2A 2 Z E 1 Z DFLA = 0?
19 Y 2T 24 H F 0 A -> zo ja, dan 1 plaats verschuiven
20 2T 31 H F 0 A => zo neen, dan 2 plaatsen verschuiven
24 => 21 2S 1 X 0 B CYCLUS VERSCHUIF OVER 1 PLAATS
22 6S 0 X 0 B
23 0B 1 A
19 -> 24 4T 21 H F 0 0 E ->
2HF1 -> 25 2S 1 Z E 1 INW
26 6S 0 X 0 B in PLI opnemen
27 2T 8 X 0 E => klaar
31 => 28 2S 2 X 0 B CYCLUS VERSCHUIF OVER 2 PLAATSEN
29 6S 0 X 0 B
30 0B 1 A
20 -> 31 4T 28 H F 0 0 E ->
DC D0
221
HF1
DA 0 H F 1 DI
0 2S 0 Z E 1 FNW
1 6S 1 X 0 B in PLI opnemen
2 2T 25 H F 0 A => ga INW in PLI opnemen
DC D0
222 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 H H0 0 =) APL
DA 0 H H 0 DI
=) 0 2A 1 A
1 6A 2 Z E 1 DFLA:= 1
2 2A 6 Z E 1 PLIE
3 6A 1 Z E 1 INW:= PLIE
4 1A 1 A
5 6A 0 Z E 1 FNW:= PLIE - 1
6 2T 0 H F 0 A => door naar FPL met [PLIE,PLIE + 1]
DC D0
223
DA 0 H K 0 DI
8LE0 => 0 2B 6 Z E 1 PLIE
1 6B 21 Z E 0 PLIB:= PLIE
2 1B 1 A
3 6B 1 X 0 B PLI[PLIE]:= PLIE - 1
4 2A 8 Z E 1 TLIB
5 6A 25 Z E 0 TLSC:= 0
6 3S 0 A
7 7S 5 Z E 1 BC:= 0
8 7S 7 Z E 1 MBC:= 0
9 7S 9 Z E 1 QC:= 0
10 7S 26 Z E 2 RHT:= 0
11 7S 27 Z E 2 VHT:= 0
12 2S 9 Z E 0 DL, hopelijk een begin
13 6T 0 Z T 0 0 =) FTL met DL
14 6T 0 H H 0 0 =) APL
-> 15 2A 0 A
16 6A 10 Z E 1 BFLA:= 0
-> 17 6T 0 F T 0 2 =) RND
6HK3 -> 18 2S 9 Z E 0 DL
0HK3 -> 19 U 1S 84 A P voor ’te kleine’ delimiter
20 N 2T 15 H K 0 A -> geen interesse
21 U 1S 85 A Z
22 Y 2T 14 H K 2 A -> als DL = for
23 U 1S 89 A P voor do of , of . of ten
24 N 2T 15 H K 0 A -> geen interesse
25 U 1S 90 A Z
26 Y 2T 12 H K 2 A -> als DL = :
27 U 1S 91 A Z
28 Y 2T 11 H K 3 A -> als DL = ;
29 U 1S 97 A P voor := of step of until of while
30 N 2T 15 H K 0 A -> of comment geen interesse
31 U 1S 99 A P
DC D0
224 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
HK1
DA 0 H K 1 DI
0 N 2T 25 H K 3 A -> als DL = ( of )
1 U 1S 101 A P
2 N 2T 30 H K 3 A -> als DL = [ of ]
3 U 1S 102 A Z
4 Y 2T 17 H K 2 A -> als DL is (*
5 U 1S 104 A Z
6 Y 2T 25 H K 2 A -> als DL = begin
7 U 1S 105 A Z
8 Y 2T 11 H K 3 A -> als DL = end
9 2A 1 A E voor *)
10 N 2T 15 H K 0 A -> geen interesse
11 U 1S 111 A Z
12 Y 2T 29 H K 1 A -> als DL = switch
20 -> 13 U 1S 112 A Z
14 Y 2T 22 H K 1 A -> als DL = procedure
15 U 1S 117 A P
16 Y 7Y 8 C 0 stop als DL ontoelaatbaar
23,30-> 17 6T 0 F T 0 2 =) RND
28 -> 18 2S 9 Z E 0 DL skip declaraties en
1HK2 19 U 1S 91 A Z specificaties
20 N 2T 13 H K 1 A -> als DL niet ; dan skippen
21 2T 17 H K 0 A => prescan vervolgen
14 => 22 U 2A 10 Z E 1 Z BFLA = 0? PROCEDURE
23 N 2T 17 H K 1 A -> zo neen, dan specificatie: skip
24 6A 10 Z E 1 BFLA:= 1
25 6T 0 F T 0 2 =) RND voor procedure identifier
26 6T 2 H F 0 0 =) FPL
27 6T 2 H K 2 1 =) blokintroductie voor body
28 2T 18 H K 1 A => ga formele parameters skippen
12 => 29 U 2A 10 Z E 1 Z BFLA = 0? SWITCH
30 N 2T 17 H K 1 A -> zo neen, dan specificatie: skip
31 6T 0 F T 0 2 =) RND voor switch identifier
DC D0
225
HK2
DA 0 H K 2 DI
0 6T 0 H F 0 0 =) FPL
1 2T 18 H K 1 A => ga switch list skippen
=) 2 2S 5 Z E 1 SUBROUTINE BLOKINTRODUCTIE
3 6T 0 Z T 0 0 =) FTL met BC
4 3S 0 A
5 6T 0 Z T 0 0 =) FTL met blokbeginmarker
6 2S 7 Z E 1 MBC
7 0S 1 A
8 6S 7 Z E 1 MBC:=
9 6S 5 Z E 1 BC:= MBC + 1
10 6T 0 H H 0 0 =) APL
11 2T 9 X 0 E => link
26HK0=> 12 6T 0 H F 0 0 =) FPL met label identifier
13 2T 17 H K 0 A => vervolg prescan
22HK0=> 14 6T 2 H K 2 1 =) blokintroductie voor for-blok
15 2T 15 H K 0 A => vervolg prescan met BFLA = 0
23 => 16 6T 0 Z Y 0 0 =) RNS voor volgend stringsymbool
4HK1 -> 17 2S 9 Z E 0 DL
18 U 1S 102 A Z (*?
19 2A 1 A
20 Y 4A 9 Z E 1 zo ja, dan QC:= QC + 1
21 U 1S 103 A Z *)?
22 Y 5A 9 Z E 1 Z zo ja, dan QC:= QC - 1
23 N 2T 16 H K 2 A -> als QC niet 0 dan herhalen
24 2T 17 H K 0 A => anders prescan voortzetten
6HK1 => 25 6T 0 Z T 0 0 =) FTL met begin BEGIN
26 U 2A 10 Z E 1 Z BFLA = 0?
27 N 2T 15 H K 0 A -> zo neen, prescan vervolgen met
28 6T 0 F T 0 2 =) RND BFLA = 0
29 2S 9 Z E 0 DL
30 U 1S 105 A P
31 U 1S 112 A E verschillend van declarator?
DC D0
226 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
HK3
DA 0 H K 3 DI
0 Y 2T 19 H K 0 A -> dan geen nieuw blok
1 3B 1 A schrap begin uit TLI:
2 4B 25 Z E 0 TLSC:= TLSC - 1
3 6T 2 H K 2 1 =) blokintroductie wegens declaratie
4 2S 104 A voeg begin weer toe:
5 6T 0 Z T 0 0 =) FTL met begin
6 2T 18 H K 0 A => zet prescan voort
13 => 7 1B 2 A uitluiden van blok:
8 6B 25 Z E 0 TLSC:= TLSC - 2
9 2A 0 X 0 B
10 6A 5 Z E 1 BC:= TLI[TLSC]
28HK0-> 11 2B 25 Z E 0 TLSC
8HK1 12 2A 32767 X 0 B P TLI[TLSC - 1] <> blokbeginmarker?
13 N 2T 7 H K 3 A -> zo neen, dan blok uitluiden
14 2A 26 Z E 2 Z RHT = 0?
15 N 7Y 22 C 0 zo neen, dan stop
16 2A 27 Z E 2 Z VHT = 0?
17 N 7Y 23 C 0 zo neen, dan stop
18 U 1S 91 A Z DL = ;?
19 Y 2T 15 H K 0 A -> zo ja, dan prescan vervolgen
20 1B 1 A verwijder begin uit TLI:
21 6B 25 Z E 0 TLSC:= TLSC - 1
22 U 1B 8 Z E 1 Z TLSC = 0?
23 N 2T 15 H K 0 A -> zo neen, dan prescan vervolgen
24 2T 0 H L 0 A => naar EPS, want prescan voltooid
0HK1 => 25 2A 1 A
26 U 1S 98 A Z DL = (?
27 Y 4A 26 Z E 2 zo ja, dan RHT:= RHT + 1
28 N 5A 26 Z E 2 zo neen, dan RHT:= RHT - 1
29 2T 15 H K 0 A => vervolg prescan
2HK1 => 30 2A 1 A
31 U 1S 100 A Z DL = [?
DC D0
227
HK4
DA 0 H K 4 DI
0 Y 4A 27 Z E 2 zo ja, dan VHT:= VHT + 1
1 N 5A 27 Z E 2 zo neen, dan VHT:= VHT - 1
2 2T 15 H K 0 A => vervolg prescan
DC D0
228 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 H L 0 DI
24HK3=> 0 2A 12 A
1 6A 26 X 0 klasse 6 in neutrale toestand
2 0Y 0 XS X1 horend
3 6T 31 H R 0 0 =) voorbereiding FOB6
4 2A 15 Z E 2 NSS-vlag op
5 7A 15 Z E 2 lezen uit magazijn zetten
6 2A 0 A
7 6A 14 Z E 2 RNS weer maagdelijk
8 6A 1 Z E 0 IFLA:= 0
9 6A 4 Z E 0 MFLA:= 0
10 6A 6 Z E 0 VFLA:= 0
11 6A 7 Z E 0 BN:= 0
12 6A 13 Z E 0 AFLA:= 0
13 6A 17 Z E 0 SFLA:= 0
14 6A 18 Z E 0 EFLA:= 0
15 6A 24 Z E 0 RLSC:= 0
16 6A 26 Z E 0 FLSC:= 0
17 6A 27 Z E 0 KLSC:= 0
18 6A 4 Z E 2 VLAM:= 0
19 2A 19 Z E 1
20 0A 1 A
21 6A 12 Z E 0 FLIB:= vulplaats + 1
22 0A 16 A
23 6A 28 Z E 0 KLIB:= FLIB + 16
24 0A 16 A
25 6A 31 Z E 0 NLIB:= KLIB + 16
26 0A 9 Z E 2 NLSC0
27 U 5A 21 Z E 0 P NLIB + NLSC0 < PLIB?
28 N 7Y 25 C 0 zo neen, stop: programma te lang
29 2A 9 Z E 2
30 6A 30 Z E 0 NLSC:= NLSC0
31 2A 8 Z E 1 TLIB
DC D0
229
HL1
DA 0 H L 1 DI
0 6A 25 Z E 0 TLSC:= 0
1 2A 3 R K 0
2 6A 26 Z E 1 GVC:= GVC0
3 2S 161 A
4 6T 0 Z T 0 0 =) FTL met blokbeginmarker
5 2A 9 Z E 2
6 6A 0 X 0 aantal:= NLSC0
13 -> 7 2B 0 X 0 CYCLUS TRANSPORT PREVULLING NLI
8 0B 17 Z E 2 PNLIB
9 2S 32767 X 0 B S:= PNLI[telling]
10 2B 0 X 0
11 0B 31 Z E 0 NLIB
12 6S 32767 X 0 B NLI[telling]:= S
13 4T 7 H L 1 0 P ->
14 6T 6 H W 0 0 =) INB
15 6T 7 L L 1 0 =) voorbereiding BSM
16 2A 96 A OPC van START
17 6T 0 Z F 0 0 =) FRL met START
18 2T 0 E L 0 A => naar basiscyclus
DC D0
230 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroepen 6T 0 H R0 0 =) FOB6
6T 31 H R0 0 =) voorbereiding FOB6
DA 0 H R 0 DI
=)0 2A 17 Z E 1 P typen onderdrukken?
1 Y 2T 8 X 0 E -> zo ja, dan al klaar
2 2B 1 Z E 2 vulplaats typmagazijn
4 -> 3 U 1B 2 Z E 2 Z magazijn vol?
4 Y 1T 2 A -> zo ja, wacht dan
5 0B 0 Z E 2 BOB6
6 6S 0 X 0 B berg symbool
7 2A 1 Z E 2 vulplaats
8 4P AS
9 0A 1 A ophogen
10 2LA 63 A en wel cyclisch modulo 64
11 6A 1 Z E 2 nieuwe vulplaats
12 2A 2 Z E 2 P typprogramma nog lopende?
13 Y 2T 8 X 0 E -> zo ja, dan klaar
14 6S 2 Z E 2 leegplaats:= oude vulplaats
15 0Y 126 XS standaardingang typprogramma
16 2A 8 X 0
17 6T 8 D 1 14 =)
29 -> 18 2B 2 Z E 2 ledigplaats
19 0B 0 Z E 2 BOB6
20 2S 0 X 0 B haal symbool
21 6T 15 D 1 14 =) TPWW
22 6Z 2 XP typ
23 2A 2 Z E 2 ledigplaats
24 0A 1 A ophogen
25 2LA 63 A en wel cyclisch modulo 64
26 U 1A 1 Z E 2 Z magazijn leeg?
27 Y 3A 1 A zo ja, dan ledigplaats < 0 zetten
28 6A 2 Z E 2 nieuwe ledigplaats
29 N 2T 18 H R 0 A -> zo neen, dan typen voortzetten
30 2T 13 D 1 A => standaarduitgang typprogramma
=) 31 2S 1 A VOORBEREIDING
DC D0
231
HR1
DA 0 H R 1 DI
0 6S 1 Z E 2 vulplaats:= 1
1 7S 2 Z E 2 ledigplaats < 0: magazijn leeg
2 2A 3 D 0 d1 van consolewoord
3 1P 2 AA in tekenbit schuiven
4 7A 17 Z E 1 zet typvergunning
5 2T 8 X 0 E => klaar
DC D0
232 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 H S0 1 =) OCT
DA 0 H S 0 DI
=)0 6A 13 Z E 1 red A
1 6S 14 Z E 1 red S
2 6B 15 Z E 1 red B
3 2LA 63 A isoleer karakter
4 U 0LA 63 A Z karakter = loos?
5 Y 2T 23 H S 0 A -> zo ja, dan klaar
6 U 1A 36 A P karakter een hoofdletter?
7 Y 2S 18 X 4 A zo ja, dan S:= UC
8 N 2S 19 X 4 A zo neen, dan S:= LC
9 U 1S 11 Z E 1 Z klopt de shift?
10 N 6S 11 Z E 1 zo neen, berg nieuwe shift en
11 N 6T 0 H R 0 0 =) FOB6 met shift
12 2S 13 Z E 1 herleiding van code:
13 2LS 63 A isoleer karakter
14 U 1S 9 A P letter?
15 N 0S 0 X 4 A zo neen, dan + typbit
16 N 2T 20 H S 0 A -> en klaar
17 U 1S 35 A P hoofdletter?
18 Y 0S 48 X 2 A
19 N 0S 75 X 2 A
16 -> 20 6T 0 H R 0 0 =) FOB6 met karakter
21 2B 15 Z E 1 herstel B
22 2S 14 Z E 1 herstel S
5 -> 23 2A 13 Z E 1 herstel A
24 2T 9 X 0 E => klaar
DC D0
233
DA 0 H T 0 DI
2ZY0 => 0 3S 21 Z E 2 P symbool in voorraad?
1 Y 6S 21 Z E 2 zo ja, dan voorrad op leeg
24HT2 2 N 6T 0 L K 0 14 =) RFS als geen voorraad
14 -> 3 U 1S 101 A P ingewikkeld?
4 Y 2T 7 H T 0 A -> zo ja, dan uitzoeken
12,24-> 5 2T 3 Z Y 0 A => terug naar RNS
6 2T 5 Z Y 0 A (overbodig)
4 => 7 U 0LS 123 A Z spatie?
8 Y 2S 93 A interne representatie voor spatie
9 U 1S 119 A P verschillend van spatie, tab, twnr?
10 Y 2T 15 H T 0 A -> dan analyse voortzetten
11 2A 9 Z E 1 Z QC = 0? dwz., buiten string?
12 N 2T 5 H T 0 A -> zo neen, dan niet skippen
13 6T 0 L K 0 14 =) RFS
14 2T 3 H T 0 A => nieuw symbool gaan onderzoeken
10 => 15 U 1S 161 A P is het | of _?
16 Y 2T 25 H T 0 A -> dan samengesteld
17 U 0LS 124 A Z is het een :?
18 N 7Y 14 C 0 zo neen, stop: ? of " of ’
19 6T 0 L K 0 14 =) RFS voor symbool na :
20 U 0LS 72 A Z is het een =?
21 N 7S 21 Z E 2 zo neen, dan in voorraad houden
22 N 2S 90 A en interne representatie voor :
23 Y 2S 92 A zo ja, interne representatie voor :=
24 2T 5 H T 0 A => en klaar
16 => 25 U 0LS 162 A Z is het |?
9HT1 -> 26 6T 0 L K 0 14 =) RFS voor volgsymbool
27 N 2T 11 H T 1 A -> zo neen, ga _ onderzoeken
28 U 0LS 77 A Z volgsymbool een ^?
29 Y 2S 69 A zo ja, dan interne representatie voor **
30 Y 2T 5 H T 0 A -> gaan afleveren
31 U 0LS 72 A Z volgsymbool een =?
DC D0
234 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
HT1
DA 0 H T 1 DI
0 Y 2S 75 A zo ja, dan interne representatie voor <>
1 Y 2T 5 H T 0 A -> gaan afleveren
2 U 0LS 74 A Z volgsymbool een <?
3 Y 2S 102 A zo ja, dan interne representatie voor (*
4 Y 2T 5 H T 0 A -> gaan afleveren
5 U 0LS 70 A Z volgsymbool een >?
6 Y 2S 103 A zo ja, dan interne representatie voor *)
7 Y 2T 5 H T 0 A -> gaan afleveren
8 U 0LS 162 A Z volgsymbool een |?
9 Y 2T 26 H T 0 A -> zo ja, dan herhaling, dus skip
10 7Y 11 C 0 en anders stop: ontoelaatbaar
27HT0=> 11 U 1S 9 A P UNDERLINING
29 12 U 1S 38 A E verschillend van letter a t/m B?
13 N 2T 30 H T 1 A -> zo neen, dan word delimiter
14 U 1S 70 A Z volgsymbool een >?
15 Y 2S 71 A zo ja, dan interne representatie voor >=
16 Y 2T 5 H T 0 A -> gaan afleveren
17 U 1S 76 A E volgsymbool niet < of not of =?
18 Y 2T 23 H T 1 A -> dan verder uitzoeken
19 U 0LS 72 A Z was het een =?
20 Y 2S 80 A zo ja, dan interne representatie voor eqv
21 N 0LS 3 A zo neen, dan die voor <= of imp
22 2T 5 H T 0 A => gaan afleveren
18 => 23 U 0LS 124 A Z volgsymbool een :?
24 Y 2S 68 A zo ja, dan interne representatie voor div
25 Y 2T 5 H T 0 A -> gaan afleveren
26 U 0LS 163 A Z volgsymbool een _?
27 N 7Y 13 C 0 zo neen, dan stop: ontoelaatbaar
28 6T 0 L K 0 14 =) RFS voor symbool na __
29 2T 11 H T 1 A => en onderzoek herhalen
13 => 30 4P SB OPBOUW WORD DELIMITER
31 2S 13 H T 3 B pak codewoord uit tabel
DC D0
235
HT2
DA 0 H T 2 DI
0 2LS 127 A isoleer waarde
1 U 3LS 63 A Z < 63? dwz., dubbelzinnig?
2 Y 2T 14 H T 2 A -> zo ja, dan nader onderzoeken
-> 3 6S 20 Z E 2 red gevonden interne representatie
10 -> 4 6T 0 L K 0 14 =) RFS CYCLUS SKIP ONDERSTREEPTE
5 U 0LS 163 A Z een _? SYMBOLEN
6 N 2T 11 H T 2 A -> zo neen, dan einde word delimiter
9 -> 7 6T 0 L K 0 14 =) RFS
8 U 0LS 163 A Z volgsymbool een herhaling van _?
9 Y 2T 7 H T 2 A -> zo ja, dan skippen
10 2T 4 H T 2 A => volgend symbool gaan lezen
6 => 11 7S 21 Z E 2 berg eerste niet-onderstreepte symbool
12 2S 20 Z E 2 haal interne representatie weer op
13 2T 5 H T 0 A => en lever delimiter af
2 => 14 4P SS Z waarde = 0?
15 Y 7Y 13 C 0 zo ja, dan ontoelaatbaar volgsymbool
16 U 0LS 1 A Z waarde = 1? dwz., een _c?
17 N 2T 26 H T 2 A -> zo neen, dan tweede letter nodig
18 2S 9 Z E 1 Z QC = 0? dwz., buiten string?
19 N 2S 97 A zo neen, dan int. repr. voor comment-sym.
20 N 2T 3 H T 2 A -> en delimiter aflezen en afleveren
21 6T 0 L K 0 14 =) RFS SKIP COMMENTAAR
25 -> 22 0LS 91 A Z gelezen symbool al een ;?
23 6T 0 L K 0 14 =) RFS voor volgsymbool
24 Y 2T 3 H T 0 A -> zo ja, dan opnieuw beginnen
25 2T 22 H T 2 A => anders skippen voortzetten
17 => 26 6S 21 Z E 2 red eerste letter
27 6T 0 L K 0 14 =) RFS voor underlining
28 U 0LS 163 A Z gelezen symbool inderdaad een _?
29 N 7Y 12 C 0 zo neen, stop: underlining ontbreekt
0HT3 -> 30 6T 0 L K 0 14 =) RFS voor tweede letter
31 U 0LS 163 A Z volgsymbool een herhaling van _?
DC D0
236 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
HT3
DA 0 H T 3 DI
0 Y 2T 30 H T 2 A -> zo ja, dan skippen
1 U 1S 9 A P
2 U 1S 32 A E verschillend van a t/m w?
3 Y 7Y 13 C 0 zo ja, dan ontoelaatbaar
4 U 0LS 29 A Z letter een t?
5 Y 2T 13 H T 3 A -> zo ja, dan derde letter nodig
6 4P SB
7 2S 13 H T 3 B pak codewoord uit tabel
8 3P 7 SS Z isoleer waarde; dubbelzinnig?
9 N 2T 3 H T 2 A -> zo neen, dan delimiter nu bekend
10 2S 21 Z E 2 pak anders de eerste letter weer op
11 0LS 64 A + 64, en nu wordt delimiter bekend
12 2T 3 H T 2 A => op grond van eerste letter
5 => 13 6T 0 L K 0 14 =) RFS voor underlining
14 U 0LS 163 A Z gelezen symbool inderdaad een _?
15 N 7Y 12 C 0 zo neen, stop: underlining ontbreekt
18 -> 16 6T 0 L K 0 14 =) RFS voor derde letter
17 U 0LS 163 A Z volgsymbool een herhaling van _?
18 Y 2T 16 H T 3 A -> zo ja, dan skippen
19 U 0LS 14 A Z derde symbool een e?
20 Y 2S 94 A zo ja, dan int. repr. voor step
21 N 2S 113 A zo neen, dan die voor string
22 Y 2T 3 H T 2 A => en delimiter aflezen en afleveren
23 DN +15086 a 117, 110 false array
24 +43 b 0, 43
25 +1 c 0, 1 comment
26 +86 d 0, 86 do
27 +13353 e 104, 41 begin
28 +10517 f 82, 21 if
29 +81 g 0, 81 goto
30 +10624 h 83, 0 then
31 +44 i 0, 44
DC D0
237
HT4
DA 0 H T 4 DN
0 +0 j 0, 0
1 +0 k 0, 0
2 +10866 l 0, 114 else label
3 +0 m 0, 0
4 +0 n 0, 0
5 +106 o 0, 106 own
6 +112 p 0, 112 procedure
7 +0 q 0, 0
8 +14957 r 116, 109 true real
9 +2 s 0, 2
10 +2 t 0, 2
11 +95 u 0, 95 until
12 +115 v 0, 115 value
13 +14304 w 111, 96 switch while
14 +0 x 0, 0
15 +0 y 0, 0
16 +0 z 0, 0
17 +0 loos 0, 0
18 +0 A 0, 0
19 +107 B 0, 107 Boolean
DC D0
238 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 H W 0 DI
=) 0 2A 1 A
1 4A 7 Z E 0 BN:= BN + 1
=) 2 2A 8 X 0 red de link in het A-register
3 2S 30 Z E 0 NLSC
4 6T 0 Z T 0 0 =) FTL met NLSC
13HW1 5 2T 10 H W 1 A => ga TLI vullen met blokbeginmarker
-> =) 6 2A 24 Z K 0
6HW1 -> 7 6A 21 Z E 1 INBA:= d17 + d15
8 2B 21 Z E 0 B:= PLIB
9 2S 0 X 0 B
10 6S 21 Z E 0 PLIB:= PLI[0]
11 0B 1 A B:= B + 1
3HW1 -> 12 U 1B 21 Z E 0 Z B = nieuwe PLIB?
13 Y 2T 4 H W 1 A -> zo ja, dan groep afgehandeld
14 2S 0 X 0 B pak INW uit PLI
15 U 2LS 7 A Z enkelwoordsnaam?
16 Y 0B 1 A zo ja, dan B:= B + 1
17 N 2A 1 X 0 B zo neen, dan ook FNW pakken
18 N 0B 2 A en B:= B + 2
19 6B 22 Z E 1 red B in INBB
20 2B 30 Z E 0 NLSC
21 0B 31 Z E 0 NLIB
22 N 6A 0 X 0 B zo neen, dan NLI[NLSC]:= FNW
23 N 0B 1 A en NLSC:= NLSC + 1
24 6S 0 X 0 B NLI[NLSC]:= INW
25 0B 2 A NLSC:= NLSC + 2
26 U 1B 22 Z E 1 P NLIB + NLSC > INBB
27 Y 7Y 15 C 0 zo ja, dan stop: NLI groeit in PLI
28 2A 7 Z E 0 BN voor constructie van ID
29 2P 19 AA * 2**19
30 0A 21 Z E 1 + INBA
31 6A 32767 X 0 B NLI[NLSC - 1]:= ID
DC D0
239
HW1
DA 0 H W 1 DI
0 1B 31 Z E 0 NLIB
1 6B 30 Z E 0 vul nieuwe NLSC in
2 2B 22 Z E 1 herstel B uit INBB
3 2T 12 H W 0 A => volgende naam overhevelen
13HW0=> 4 2A 23 Z K 0
5 U 1A 21 Z E 1 Z INBA = d18 + d15?
6 N 2T 7 H W 0 A -> zo neen, dan INBA:= d18 + d15 en
7 2A 0 A volgend stuk doen
8 6A 25 Z E 1 LVC:= 0
9 2T 8 X 0 E => klaar
5HW0 -> 10 2S 161 A
11 6T 0 Z T 0 0 =) FRL met blokbeginmarker
12 6A 8 X 0 herstel link uit A
13 2T 6 H W 0 A => ga namen uit PLI overhevelen
DC D0
240 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 H U0 1 =) NBD
DA 0 H U 0 DI
=) 0 2B 25 Z E 0 TLSC
1 2S 32766 X 0 B TLI[TLSC - 2]
2 0LS 161 A Z blokbeginmarker onder top van TLI?
3 Y 2T 9 X 0 E -> zo ja, dan klaar: geen nieuw blok
4 1B 1 A verwijder begin uit TLI:
5 6B 25 Z E 0 TLSC:= TLSC - 1
6 2S 6 Z K 0
7 2A 0 A
8 6T 0 Z F 0 0 =) FRL met 2A 0 A
9 2S 1 Z K 0
10 2A 1 A opc1: relatief tov RLIB
11 0S 24 Z E 0 RLSC
12 0S 3 A + 3 geeft beginadres anonym blok
13 6T 0 Z F 0 0 =) FRL met X1X 2B ’RLSC + 3’ A
14 2S 0 A
15 2A 9 A OPC van ETMP
16 6T 0 Z F 0 0 =) FRL met ETMP
17 2S 8 Z K 0
18 0S 26 Z E 0 FLSC
19 2A 2 A opc2: referentie naar FLI
20 6T 0 Z F 0 0 =) FRL met X2X 2T ’FLSC’
21 2S 26 Z E 0 FLSC
22 6T 0 Z T 0 0 =) FTL met FLSC
23 2S 1 A
24 4S 26 Z E 0 FLSC:= FLSC + 1
25 6T 0 H W 0 0 =) INB
26 2S 104 A
27 6T 0 Z T 0 0 =) FRL met begin
18HY0=) 28 2S 1 Z K 0
29 0S 7 Z E 0 BN
30 2A 0 A
31 6T 0 Z F 0 0 =) FRL met 2B ’BN’ A
DC D0
241
HU1
DA 0 H U 1 DI
0 2S 0 A
1 2A 89 A OPC van SCC
2 6T 0 Z F 0 0 =) FRL met SCC
3 2A 7 Z E 0 BN
4 0A 160 A + 5 * 32
5 6A 23 Z E 1 PNLV
6 6A 4 Z E 2 maak VLAM <> 0
7 2T 9 X 0 E => klaar
DC D0
242 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 H Y 0 DI
=> 0 2T 14 H Y 0 A => doe eerst RLA en NBD?
16 => 1 2S 8 Z K 0
2 0S 26 Z E 0 FLSC
3 2A 2 A opc2: referentie naar FLI
4 6T 0 Z F 0 0 =) FRL met X2X 2T ’FLSC’
5 2S 26 Z E 0 FLSC
6 6T 0 Z T 0 0 =) FTL met FLSC
7 2S 1 A
8 4S 26 Z E 0 FLSC:= FLSC + 1
9 6T 0 F T 0 2 =) RND voor procedure identifier
10 6T 0 H Z 0 0 =) LFN
11 6T 0 F Y 0 2 =) LDEC
12 6T 0 H W 0 0 =) INB
13 2T 18 H Y 0 A =>
0 => 14 6T 0 K N 0 2 =) RLA
15 6T 0 H U 0 1 =) NBD?
16 2T 1 H Y 0 A => ga sprong over body produceren
17 4S 7 Z E 0 (overbodig)
13 => 18 6T 28 H U 0 1 =) NBD-gedeeltelijk
19 2A 9 Z E 0 DL
20 0LA 91 A Z = ;?
21 Y 2T 0 E L 0 A -> zo ja, dan terug naar basiscyclus
31 -> 22 6T 0 F T 0 2 =) RND voor formele parameter
23 2A 23 Z E 1 PNLV voor constructie ID
24 0A 27 Z K 0 d16 + d15: indicatie formeel en dynamisch
25 6A 8 Z E 0 ID voorlopig voltooid
26 6T 0 H N 0 0 =) FNL
27 2A 64 A 2 * 32
28 4A 23 Z E 1 PNLV:= PNLV + 64 als PARD-reservering
29 2A 9 Z E 0 DL
30 0LA 87 A Z = ,?
31 Y 2T 22 H Y 0 A -> zo ja, dan volgende formele parameter
DC D0
243
HY1
DA 0 H Y 1 DI
0 6T 0 F T 0 2 =) RND voor ; na )
10HY3-> 1 6T 0 F T 0 2 =) RND
20 2 2A 29 Z E 0 Z NFLA = 0? dwz., kale delimiter?
3 N 2T 1 E L 0 A -> zo neen, dan terug naar basiscyclus
4 2A 9 Z E 0 DL
5 U 0LA 104 A Z = begin?
6 Y 2T 0 E H 0 A -> zo ja, dan naar DDEL
7 U 0LA 115 A Z DL = value?
8 N 2T 21 H Y 1 A -> zo neen, dan specificaties
23,26 9 2S 28 Z K 0 d26 als valuevlag
28,31-> 10 6S 5 Z E 2 zet SPE
13HY2-> 11 6T 0 F T 0 2 =) RND voor identifier uit list
19 12 6T 0 H Z 0 0 =) LFN
13 2B 22 Z E 0 NID
14 0B 31 Z E 0 NLIB
15 2S 5 Z E 2 SPE toevoegen
16 4S 0 X 0 B aan ID in NLI
17 2A 9 Z E 0 DL
18 0LA 87 A Z = ,?
19 Y 2T 11 H Y 1 A -> dan volgende identifier uit list
20 2T 1 H Y 1 A => ga testen op begin van body
8 => 21 U 0LA 113 A Z DL = string?
1HY2 -> 22 Y 2S 0 A zo ja, dan lege SPE-vlag
23 Y 2T 10 H Y 1 A -> en ga specification part lezen
24 U 0LA 114 A Z DL = label?
25 2S 12 Z K 0 zo ja, neem d17 als SPE-vlag
26 Y 2T 10 H Y 1 A -> en ga specification part lezen
27 U 0LA 111 A Z DL = switch?
28 Y 2T 10 H Y 1 A -> zo ja, ga sp. part lezen met d17 als SPE
29 U 0LA 112 A Z DL = procedure?
11HY2-> 30 Y 2S 29 Z K 0 zo ja, neem d18 als SPE-vlag
31 Y 2T 10 H Y 1 A -> en ga specification part lezen
DC D0
244 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
HY2
DA 0 H Y 2 DI
0 U 0LA 110 A Z DL = array?
1 Y 2T 22 H Y 1 A -> zo ja, ga sp. part lezen met lege
2 U 1A 109 A Z DL = real? SPE-vlag
3 Y 2S 0 A zo ja, dan d19 = 0 nemen
4 N 2S 4 Z K 0 zo neen, dan d19 = 1 als integerbit
5 U 1A 106 A E DL geen specificator?
6 Y 2T 0 E H 0 A -> zo ja, naar DDEL wegens if, for, goto
7 6S 5 Z E 2 zet SPE
8 6T 0 F T 0 2 =) RND voor delimiter na real, integer,
9 2A 9 Z E 0 DL of Boolean
10 U 0LA 112 A Z = procedure?
11 Y 2T 30 H Y 1 A -> zo ja, dan net als non-type procedure
12 U 0LA 110 A Z DL = array?
13 Y 2T 11 H Y 1 A -> zo ja, ga specification part lezen
9HY3 -> 14 6T 0 H Z 0 0 =) LFN, want blijkbaar identifier gelezen
15 2B 22 Z E 0 NID
16 0B 31 Z E 0 NLIB
17 2S 5 Z E 2 SPE toevoegen
18 4S 0 X 0 B P aan ID toevoegen; called by name?
19 Y 2T 6 H Y 3 A -> zo ja, dan eenvoudig
20 3S 3 Z K 0 d16 PRODUCTIE VALUE PROGRAMMA
21 1S 28 Z K 0 d26
22 2LS 0 X 0 B schrappen uit
23 6S 0 X 0 B ID in NLI
24 6S 8 Z E 0 wijzig ID conform
25 6T 0 Z R 0 0 =) AVR voor 2S ’pardpositie’ A
26 2A 5 Z E 2 Z SPE = 0? dwz., real?
27 Y 2A 14 A zo ja, dan OPC van TRAD
28 N 2A 16 A zo neen, dan OPC van TIAD
29 2S 0 A
30 6T 0 Z F 0 0 =) FRL met TRAD of TIAD
31 6T 0 Z R 0 0 =) AVR voor 2S ’pardpositie’ A
DC D0
245
HY3
DA 0 H Y 3 DI
0 2S 0 A
1 2A 35 A OPC van TFR
2 6T 0 Z F 0 0 =) FRL met TFR
3 2S 0 A
4 2A 85 A OPC van ST
5 6T 0 Z F 0 0 =) FRL met ST
19HY2-> 6 2A 9 Z E 0
7 0LA 87 A Z DL = ,?
8 Y 6T 0 F T 0 2 =) zo ja, dan RND voor behandeling
9 Y 2T 14 H Y 2 A -> volgende identifier uit lijst
10 2T 1 H Y 1 A => ga testen op begin van body
DC D0
246 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 H N0 0 =) FNL
DA 0 H N 0 DI
=) 0 2B 30 Z E 0 NLSC
1 0B 31 Z E 0 NLIB
2 0B 2 Z E 1 DFLA
3 0B 2 A NLSC:= NLSC + DFLA + 2
4 U 1B 21 Z E 0 P NLSC + NLIB > PLIB?
5 Y 7Y 16 C 0 zo ja, stop: NLI groeit in PLI
6 2A 8 Z E 0
7 6A 32767 X 0 B NLI[NLSC - 1]:= ID
8 2A 1 Z E 1
9 6A 32766 X 0 B NLI[NLSC - 2]:= INW
10 U 2LA 7 A Z enkelwoordsnaam?
11 N 2A 0 Z E 1 zo neen, dan
12 N 6A 32765 X 0 B NLI[NLSC - 3]:= FNW
13 1B 31 Z E 0 NLIB
14 6B 30 Z E 0 vul nieuwe NLSC in
15 2T 8 X 0 E => klaar
DC D0
247
DA 0 K Z 0 DI
=> 0 2A 1 A
1 6A 24 Z E 1 IBD:= 1
2 6T 0 H U 0 1 =) NBD?
3 6T 0 F T 0 2 =) RND
4 2A 29 Z E 0 Z NFLA = 0? dwz., geen identifier?
5 Y 2T 21 K Z 1 A -> zo ja, dan geen scalair
5KE0 -> 6 2A 7 Z E 0 Z BN = 0?
7 Y 2T 9 K Z 1 A -> dan statische adressering verzorgen
22 -> 8 2A 23 Z E 1 PNLV voor constructie ID
3KZ1 9 0A 0 Z K 0 d15 als indicatie dynamisch adres
10 2S 24 Z E 1 Z IBD = 0?
11 N 0A 4 Z K 0 anders d19 als integerbit toevoegen
12 6A 8 Z E 0 ID klaar
13 Y 2A 64 A 2 * 32 of
14 N 2A 32 A 1 * 32
15 4A 23 Z E 1 ter ophoging van PNLV
16 3P 5 AA 2 of 1
17 4A 25 Z E 1 ter ophoging van LVC
18 6T 0 H N 0 0 =) FNL
19 2A 9 Z E 0 DL
20 U 0LA 87 A Z = ,?
21 Y 6T 0 F T 0 2 =) dan RND voor volgende identifier
22 Y 2T 8 K Z 0 A -> en ID gaan construeren
23 6T 0 F T 0 2 =) RND voor delimiter na ;
24 2A 9 Z E 0 DL
25 U 1A 109 A Z = real?
26 Y 2S 0 A
27 N 2S 1 A 0 of 1
28 U 1A 106 A E DL <> real of integer of Boolean?
29 N 2T 0 K Z 1 A -> zo neen, dan voortgezette declaratie
30 6T 0 K Y 0 1 =) RLV (want klaar met scalairen)
31 2T 1 E L 0 A => terug naar basiscyclus (zonder RND)
DC D0
248 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
KZ1
DA 0 K Z 1 DI
29KZ0=> 0 6S 24 Z E 1 IBD:= 0 of 1
1 6T 0 F T 0 2 =) RND
2 2A 29 Z E 0 Z NFLA = 0? dwz., geen identifier?
3 N 2T 8 K Z 0 A -> zo neen, dan declaratie van scalair
4 6T 0 K Y 0 1 =) RLV (want geen scalairen verder)
5 2A 9 Z E 0 DL
6 0LA 110 A Z = array?
7 Y 2T 3 K F 0 A -> dan door naar DDEL array
7KZ0 8 2T 0 E H 0 A => naar DDEL
19 => 9 2A 26 Z E 1 GVC voor constructie van ID
9KH0 10 3S 24 Z E 1 Z IBD = 0?
11 N 0A 4 Z K 0 anders d19 als integerbit toevoegen
12 6A 8 Z E 0 ID klaar
13 0S 2 A 2 of 1
14 4S 26 Z E 1 ter ophoging van GVC
15 6T 0 H N 0 0 =) FNL
16 2A 9 Z E 0 DL
17 U 0LA 87 A Z = ,?
18 Y 6T 0 F T 0 2 =) zo ja, dan RND voor volgende identifier
19 Y 2T 9 K Z 1 A -> en ID gaan construeren
20 2T 0 E L 0 A => terug naar basiscyclus
5KZ0 => 21 2A 9 Z E 0 DL
22 0LA 110 A Z = array?
23 N 2T 0 H Y 0 A -> zo neen, dan naar DDEL procedure
24 2T 3 K F 0 A => door naar DDEL array
DC D0
249
DA 0 K E 0 DI
=> 0 2A 0 A
1 6A 24 Z E 1 IBD:= 0
2 6T 0 H U 0 1 =) NBD?
3 6T 0 F T 0 2 =) RND
4 2A 29 Z E 0 Z NFLA = 0? dwz., geen identifier?
5 N 2T 6 K Z 0 A -> zo neen, dan verder samen met DDEL integer
6 2T 0 E H 0 A => naar DDEL
DC D0
250 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 K F 0 DI
=> 0 2A 0 A
1 6A 24 Z E 1 IBD:= 0
7KZ1 2 6T 0 H U 0 1 =) NBD?
24KZ1-> 3 2A 7 Z E 0 Z BN = 0?
4 N 2T 20 K F 2 A -> zo neen, dan dynamische grenzen
8KF0-> 5 2A 14 Z K 0 d25, d24 als indicatie KLI
6 U 2A 24 Z E 1 Z IBD = 0? dwz., real array?
7 N 0A 4 Z K 0 anders d19 als intergerbit toevoegen
8 6A 8 Z E 0 voorlopige ID
18KF2-> 9 2A 30 Z E 0 NLSC
10 6A 23 Z E 0 dumpen in ARRA
11 2A 25 Z E 0 TLSC
12 6A 29 Z E 1 dumpen in ARRB
17 -> 13 6T 0 F T 0 2 =) RND voor array identifier
14 6T 0 H N 0 0 =) FNL
15 2A 9 Z E 0 DL
16 0LA 100 A Z = [?
17 N 2T 13 K F 0 A -> anders volgende identifier lezen
18 6A 30 Z E 1 ARRC:= 0
19 2S 2 A CONSTRUCTIE STOFU
20 1S 24 Z E 1 2 - IBD
21 6T 0 Z T 0 0 =) FTL met delta[0]
18KF1-> 22 6T 0 F T 0 2 =) RND voor lower bound
23 2A 9 Z E 0 DL
24 U 0LA 90 A Z = :?
25 Y 2T 28 K F 0 A -> dan klaar met lower bound
26 U 0LA 64 A Z DL = +?
27 6T 0 F T 0 2 =) RND voor unsigned number
25 -> 28 Y 2S 1 Z E 1 pak INW, dwz. L[i] met
29 N 3S 1 Z E 1 het juiste teken
30 6S 31 Z E 1 lower bound dumpen in ARRD
31 6T 0 F T 0 2 =) RND voor upper bound
DC D0
251
KF1
DA 0 K F 1 DI
0 2A 29 Z E 0 Z NFLA = 0? dwz., geen number?
1 N 2T 5 K F 1 A -> anders klaar met upper bound
2 2A 9 Z E 0 DL
3 0LA 65 A Z = -?
4 6T 0 F T 0 2 =) RND voor unsigned number
1 -> 5 2B 25 Z E 0 TLSC
6 2S 31 Z E 1 pak in ARRD gedumpte lower bound
7 3X 32767 X 0 B * (-TLI[TLSC - 1])
8 4S 30 Z E 1 ARRC:= ARRC - L[i] * delta[i]
9 3S 31 Z E 1 pak - L[i]
10 N 0S 1 Z E 1 tel bij INW, dwz. U[i] met
11 Y 1S 1 Z E 1 het juiste teken
12 0S 1 A
13 2A 9 Z E 0 DL
14 0LA 101 A Z = ]?
15 N 2X 32767 X 0 B delta[i+1]:= (U[i] - L[i] + 1) *
16 Y 3X 32767 X 0 B delta[i]
17 6T 0 Z T 0 0 =) FTL met delta[i+1] of - delta[n]
18 N 2T 22 K F 0 A -> zo nodig volgend bound pair lezen
19 2B 30 Z E 0 NLSC
14KF2-> 20 6B 31 Z E 1 dumpen in ARRD
21 0B 31 Z E 0 NLIB
22 2A 27 Z E 0 KLSC als adres STOFU
23 4A 32767 X 0 B voltooi ID in NLI
24 2S 26 Z E 1 GVC als beginadres arraysegment
25 6T 0 K U 0 0 =) FKL met GVC
26 2S 26 Z E 1 GVC samen met
27 0S 30 Z E 1 ARRC het geextrapoleerde nulpunt
28 6T 0 K U 0 0 =) FKL met GVC + ARRC
29 2B 29 Z E 1 pak in ARRB gedumpte TLSC
5KF2 -> 30 2S 0 X 0 B P TLI[TLSC] > 0?
31 Y 0B 1 A dan nog niet - delta[n]
DC D0
252 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
KF2
DA 0 K F 2 DI
0 N 2B 29 Z E 1 anders de in ARRB gedumpte TLSC
1 6B 25 Z E 0 TLSC resetten
2 N 5S 26 Z E 1 en GVC ophogen met delta[n]
3 6T 0 K U 0 0 =) FKL met delta[i] of - delta[n]
4 Y 2B 25 Z E 0 zo nodig TLSC pakken
5 Y 2T 30 K F 1 A -> en volgende delta
6 2B 31 Z E 1 pak de in ARRD gedumpte NLSC
7 0B 31 Z E 0 NLIB
8 2S 32766 X 0 B pak NLI[NLSC - 2], dwz., INW uit NLI
9 1B 31 Z E 0 NLIB
10 2LS 7 A Z enkelwoordsnaam?
11 Y 1B 2 A NLSC passend aflagen
12 N 1B 3 A
13 U 1B 23 Z E 0 Z de in ARRA gedumpte NLSC al bereikt?
14 N 2T 20 K F 1 A -> anders volgende STOFU gaan bouwen
15 6T 0 F T 0 2 =) RND voor delimiter na ]
16 2A 9 Z E 0 DL
17 0LA 87 A Z = ,?
18 Y 2T 9 K F 0 A -> dan voortgezette array-declaratie
19 2T 0 F S 0 A => door naar DDEL ;
4KF0 => 20 2A 0 A DYNAMISCH ARRAY ga vlaggen zetten:
29EF1 21 6A 3 Z E 2 IC:= 0
22 6A 6 Z E 2 AIC:= 0
23 6A 8 Z E 0 ID:= 0
30 -> 24 2A 1 A
25 4A 6 Z E 2 AIC:= AIC + 1
26 6T 0 F T 0 2 =) RND voor array identifier
27 6T 0 H N 0 0 =) FNL
28 2A 9 Z E 0 DL
29 0LA 87 A Z = ,?
30 Y 2T 24 K F 2 A -> dan tellen en volgende identifier
31 2A 1 A
DC D0
253
KF3
DA 0 K F 3 DI
0 6A 18 Z E 0 EFLA:= 1
1 6A 0 Z E 0 OFLA:= 1
2 2T 14 F E 0 A => OH:= 0; FTD; door naar basiscyclus
DC D0
254 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 K H 0 DI
=> 0 6T 0 H U 0 1 =) NBD?
1 6T 0 Z Y 0 0 =) RNS voor delimiter na own
2 2A 9 Z E 0 DL
3 0LA 109 A Z = real?
4 N 2A 1 A anders integer
5 6A 24 Z E 1 IBD:= 0 of 1
6 6T 0 F T 0 2 =) RND
7 2A 29 Z E 0 Z NFLA = 0? dwz., geen identifier?
8 Y 2T 5 K F 0 A -> dan als array van blok 0 behandelen
9 2T 9 K Z 1 A => anders als <type> van blok 0
DC D0
255
DA 0 K K 0 DI
=> 0 2A 8 A 8 als OH
4KL0 -> 1 2S 1 A
2 6S 0 Z E 0 OFLA:= 1
3 2T 1 E T 0 A => verder samen met DDEL * / div
DC D0
256 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 K L 0 DI
=> 0 U 1B 76 A Z DL = not?
1 2A 83 A
2 1A 9 Z E 0 construeer OH uit DL
3 Y 2T 7 E Y 0 A -> dan FTD; OFLA:= 1; naar basiscyclus
4 2T 1 K K 0 A => anders samen met DDEL < <= = >= > <>
DC D0
257
DA 0 K R 0 DI
=> 0 6T 0 K N 0 2 =) RLA
1 2T 0 E L 0 A => terug naar basiscyclus
DC D0
258 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DDEL (* KS0
DA 0 K S 0 DI
=>0 2A 1 A
1 6A 9 Z E 1 QC:= 1
22 -> 2 2B 0 A
3 6B 28 Z E 1 QB:= 0
18 -> 4 6B 27 Z E 1 QA:= (initieel) 0
5 6T 0 Z Y 0 0 =) RNS voor string-symbool
6 2A 9 Z E 0 DL
7 2S 1 A
8 U 0LA 102 A Z = (*?
9 Y 4S 9 Z E 1 zo ja, dan QC:= QC + 1
10 U 0LA 103 A Z DL = *)?
11 Y 5S 9 Z E 1 Z zo ja, dan QC:= QC - 1; QC = 0?
12 2B 27 Z E 1 QA als schuifwijzer
13 Y 2T 23 K S 0 A -> dan einde string
14 2P 0 AA B schuif symbool in goede positie
15 4A 28 Z E 1 en tel bij woord-in-opbouw
16 0B 8 A schuifwijzer ophogen
17 U 1B 24 A Z maar
18 N 2T 4 K S 0 A -> modulo 24
19 2S 28 Z E 1 pak voltooid woord
20 2A 0 A
21 6T 0 Z F 0 0 =) FRL met string-woord
22 2T 2 K S 0 A => start nieuw string-woord
13 => 23 2S 255 A eindmarker
24 2P 0 SS B in goede positie schuiven
25 0S 28 Z E 1 woord-in-opbouw erbij
26 2A 0 A
27 6A 0 Z E 0 OFLA:= 0
28 6T 0 Z F 0 0 =) FRL met laatste string-woord
29 2T 0 E L 0 A => terug naar basiscyclus
DC D0
259
DDEL ** KT0
DA 0 K T 0 DI
=> 0 2A 11 A 11 als OH
1 2T 1 E T 0 A => verder samen met DDEL * / div
DC D0
260 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
END KW0
DA 0 K W 0 DI
29FS1=> 0 2A 97 A OPC van STOP
1 6T 0 Z F 0 0 =) FRL met STOP
2 2S 24 Z E 0
3 6S 3 R E 0 RLSCE:= RLSC
4 2S 27 Z E 0
5 6S 4 R E 0 KLSCE:= KLSC
6 2S 26 Z E 1
7 6S 21 X 1 GVC naar goede plaats
8 2S 26 Z E 0
9 6S 0 X 0 zet telling met FLSC
10 2S 19 Z E 1
11 6S 13 R E 0 ledigplaats RBS:= vulplaats BSM
12 2A 2 R K 0 KLIE ter berekening van RLIB
13 1A 3 R E 0 RLSCE
14 1A 4 R E 0 KLSCE
15 3LA 31 A naar beneden afronden
16 6A 1 R E 0 RLIB klaar
17 6A 11 R E 0
18 2B 12 Z E 0
19 6B 5 R E 0 FLIB naar goede plaats
22 -> 20 4A 0 X 0 B cyclus voor
21 0B 1 A FLI[i]:= FLI[i] + RLIB
22 4T 20 K W 0 0 P ->
23 6B 6 R E 0 red FLIB + FLSCE
24 6A 15 X 1 MCPE:= RLIB (als startwaarde)
25 0A 3 R E 0
26 6A 2 R E 0 KLIB:= RLIB + RLSCE
27 2S 128 A
28 6S 0 X 0 lengte MLI:= 128
29 2S 0 A
30 2B 4 R K 0 MLIB
1KW1 -> 31 6S 0 X 0 B cyclus clear MLI:
DC D0
261
KW1
DA 0 K W 1 DI
0 0B 1 A MLI[MCPnr]:= +0
1 4T 31 K W 0 0 P ->
2 6S 14 R E 0 aantal MCP’s:= 0
3 2B 9 Z E 2 PRIMAIRE MARKERING VAN MCP’S
4 0B 31 Z E 0 NLIB + NLSC0
5 2A 25 Z E 2 NLSCop
6 0A 31 Z E 0 NLIB
7 6A 22 Z E 0
8 2T 29 K W 1 A =>
30 => 9 2S 32767 X 0 B CYCLUS TEST PRIMAIR GEBRUIK
10 2A 32766 X 0 B pak ID en INW van MCP-naam uit NLI
11 2LA 7 A Z enkelwoordsnaam?
12 Y 1B 2 A NLSC passend aflagen
13 N 1B 3 A
14 U 2LS 0 Z K 0 Z d15 van ID = 0?
15 N 2T 29 K W 1 A -> zo neen, dan MCP ongebruikt
16 6B 24 Z E 0 red NLIB + NLSC
17 2A 1 A
18 4A 14 R E 0 tel gebruikte MCP
19 2LS 32767 A isoleer FLSC uit ID
20 0S 12 Z E 0 FLIB
21 4P SB
22 2A 0 X 0 B FLI[FLSC], bevat MCPnr+RLIB+d15+d18
23 1A 1 R E 0 RLIB
24 2LA 32767 A isoleer MCPnr
25 4P AB
26 0B 4 R K 0 MLIB
27 7S 0 X 0 B MLI[MCPnr]:= - (FLIB + FLSC)
28 2B 24 Z E 0 herstel NLIB + NLSC
8,15 -> 29 U 1B 22 Z E 0 P > NLIB + NLSCop?
30 Y 2T 9 K W 1 A -> dan volgende MCP onderzoeken
31 2S 5 R K 0 CRFB
DC D0
262 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
KW2
DA 0 K W 2 DI
0 0P 1 SS SECUNDAIRE MARKERING VAN MCP’S
1 6S 0 R E 0 voorbereiding van HSC
16,30-> 2 6T 0 R S 0 0 =) HSC voor lengte MCP; eindmarker?
3 Y 2T 31 K W 2 A -> zo ja, dan klaar met CRF
4 6S 7 R E 0 red lengte MCP
5 6T 0 R S 0 0 =) HSC voor nummer MCP
6 6S 8 R E 0 red nummer MCP
7 2A 0 A
8 6A 9 R E 0 USE:= false
14 -> 9 4P SB
10 0B 4 R K 0 MLIB
11 2A 0 X 0 B Z MLI[MCPnr] = 0? dwz., geen behoefte?
12 N 6A 9 R E 0 anders USE:= true
13 6T 0 R S 0 0 =) HSC voor nummer MCP; eindmarker?
14 N 2T 9 K W 2 A -> anders verder testen
15 2A 9 R E 0 Z USE = false?
16 Y 2T 2 K W 2 A -> zo ja, dan volgende MCP onderzoeken
17 2A 15 X 1 MCPE
18 1A 7 R E 0
19 6A 15 X 1 MCPE:= MCPE - lengte MCP
20 U 1A 1 R K 0 P MCPE > MCPB?
21 N 7Y 25 C 0 anders stop: MCP zou in MLI zakken
22 2B 8 R E 0 pak gered MCPnr
23 0B 4 R K 0 MLIB
24 3S 0 X 0 B P MLI[MCPnr] < 0? dwz., primaire behoefte?
25 6A 0 X 0 B MLI[MCPnr]:= MCPE als beginadres MCP
26 Y 4P SB bij primaire behoefte ook:
27 Y 6A 0 X 0 B FLI[FLSC]:= MCPE
28 N 2S 1 A bij uitsluitend secundaire behoefte:
29 N 4S 14 R E 0 tel gebruikte MCP
30 2T 2 K W 2 A => volgende MCP gaan onderzoeken
3 => 31 2S 4 R E 0 KLSCE
DC D0
263
KW3
DA 0 K W 3 DI
0 6S 0 X 0 zet telling met KLSCE
1 2T 8 K W 3 A =>
8 => 2 2B 28 Z E 0 CYCLUS TRANSPORT KLI
3 0B 0 X 0
4 2S 0 X 0 B pak KLI[KLSC]
5 2B 2 R E 0
6 0B 0 X 0
7 6S 0 X 0 B berg KLI[KLSC]
1 -> 8 4T 2 K W 3 0 E ->
9 2T 0 R Z 0 A => naar naschouw-programma
DC D0
264 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 K U 0 DI
21-> =) 0 2B 27 Z E 0 KLSC
1 0B 28 Z E 0 KLIB
2 U 1B 31 Z E 0 Z KLIB + KLSC = NLIB?
3 N 6S 0 X 0 B zo neen, dan KLI[KLSC]:= S,
4 N 2A 1 A
5 N 4A 27 Z E 0 en KLSC:= KLSC + 1
6 N 2T 8 X 0 E => en klaar
7 2B 30 Z E 0 OPSCHUIVEN VAN NLI
8 6B 0 X 0 aantal:= NLSC
9 0B 31 Z E 0 NLIB
10 5P BA
11 1A 16 A
12 0A 21 Z E 0 P NLIB + NLSC + 16 < PLIB?
13 N 7Y 18 C 0 zo neen, stop: NLI schuift in PLI
14 2T 18 K U 0 A =>
18 => 15 1B 1 A opschuifcyclus:
16 2A 0 X 0 B 16 plaatsen
17 6A 16 X 0 B omhoog
14 -> 18 4T 15 K U 0 0 E ->
19 2A 16 A
20 4A 31 Z E 0 NLIB:= NLIB + 16
21 2T 0 K U 0 A => klaar met schuiven
DC D0
265
aanroep 6T 0 K Y0 1 =) RLV
DA 0 K Y 0 DI
=) 0 2S 25 Z E 1 Z LVC = 0?
1 Y 2T 9 X 0 E -> zo ja, dan niet nodig
2 0S 6 Z K 0
3 2A 0 A
4 6A 25 Z E 1 LVC:= 0
5 6T 0 Z F 0 0 =) FRL met 2A ’LVC’ A
6 2S 25 Z K 0
7 2A 0 A
8 6T 0 Z F 0 0 =) FRL met 4A 17 X1
9 2S 26 Z K 0
10 2A 0 A
11 6T 0 Z F 0 0 =) FRL met 4A 18 X1
12 2T 9 X 0 E => klaar
DC D0
266 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 K N0 2 =) RLV
DA 0 K N 0 DI
=) 0 2A 4 Z E 2 Z VLAM = 0? dwz., geen arrays?
1 Y 2T 10 X 0 E -> zo ja, dan klaar
2 5A 4 Z E 2 VLAM:= 0
3 2B 25 Z E 0 TLSC
4 2S 161 A
5 0LS 32767 X 0 B Z TLI[TLSC - 1] = blokbeginmarker?
6 Y 2S 32766 X 0 B pak in TLI
7 N 2S 32765 X 0 B gedumpte NLSC
8 0S 31 Z E 0 NLIB
9 6S 7 Z E 2 RLAA:= NLIB + NLSC-van-blokbegin
10 2B 30 Z E 0 NLSC
11 0B 31 Z E 0 NLIB
12 2T 3 K N 1 A =>
5KN1 => 13 6S 8 Z E 0 P CYCLUS OPBOUW STOFU VOOR VALUE ARRAYS
14 N 0P 1 SS E als d26 = 0 of d26 = 1 maar d25 = 1
15 Y 2T 31 K N 0 A -> dan geen value array
16 6B 8 Z E 2 dump NLSC in RLAB
17 0P 6 SS P d19 = 0? dwz., real?
18 6T 0 Z R 0 0 =) AVR
19 Y 2A 92 A zo ja, dan OPC van RVA
20 N 2A 93 A zo neen, dan OPC van IVA
21 2S 0 A
22 6T 0 Z F 0 0 =) FRL met RVA of IVA
23 2B 8 Z E 2 pak de in RLAB gedumpte NLSC
24 2S 32767 X 0 B pak ID uit NLI
25 3LS 32767 A schrap adresdeel
26 3LS 3 Z K 0 d16 = 0 maken: non-formeel
27 0S 23 Z E 1 PNLV als adres toevoegen
28 6S 32767 X 0 B ID klaar, naar NLI ermee
29 2A 0 X 8 A 8 * 32
30 4A 23 Z E 1 ter ophoging van PNLV: hoogstens 5
15 -> 31 2S 32766 X 0 B INW uit NLI indices
DC D0
267
KN1
DA 0 K N 1 DI
0 2LS 7 A Z enkelwoordsnaam?
1 Y 1B 2 A NLSC passend aflagen
2 N 1B 3 A
12KN0-> 3 U 1B 7 Z E 2 Z = RLAA?
4 N 2S 32767 X 0 B anders ID van volgende naam
5 N 2T 13 K N 0 A -> op value array onderzoeken
6 2B 30 Z E 0 NLSC
7 0B 31 Z E 0 NLIB
28 -> 8 U 1B 7 Z E 2 Z = RLAA?
9 Y 2T 29 K N 1 A -> zo ja, dan definitief klaar
10 2S 32767 X 0 B P RESERVERING LOCALE OF VALUE ARRAYS
11 Y 2T 24 K N 1 A als geen array dan skippen
12 U 2LS 13 Z K 0 Z d25 = 0? dwz., value array?
13 N 3LS 13 Z K 0 anders d25
14 3LS 28 Z K 0 maar in ieder geval d26
15 6S 32767 X 0 B schrappen uit ID in NLI
16 6S 8 Z E 0 zet ID
17 6B 8 Z E 2 dump NLSC in RLAB
18 6T 0 Z R 0 0 =) AVR
19 Y 2A 95 A als value dan OPC van VAP
20 N 2A 94 A als locaal dan OPC van LAP
21 2S 0 A
22 6T 0 Z F 0 0 =) FRL met VAP of LAP
23 2B 8 Z E 2 pak de in RLAB gedumpte NLSC
11 -> 24 2S 32766 X 0 B INW uit NLI
25 2LS 7 A Z enkelwoordsnaam?
26 Y 1B 2 A NLSC passend aflagen
27 N 1B 3 A
28 2T 8 K N 1 A => ga volgende naam onderzoeken
9 => 29 2A 29 Z E 0 Z NFLA = 0?
30 N 2B 22 Z E 0 zo neen, dan ID gaan
31 N 0B 31 Z E 0 herstellen
DC D0
268 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
KN2
DA 0 K N 2 DI
0 N 2A 0 X 0 B op grond van NLI[NID]
1 N 6A 8 Z E 0
2 2T 10 X 0 E => klaar
DC D0
269
DA 0 L Z 0 DI
=> 0 2B 25 Z E 0 TLSC
1 2S 32767 X 0 B TLI[TLSC - 1]
2 0LS 161 A Z = blokbeginmarker?
3 N 6T 0 K N 0 2 =) zo neen, dan RLA
4 2T 14 F E 0 A => OH:= 0; FTD; terug naar basiscyclus
DC D0
270 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 L E 0 DI
=>=> 0 2A 0 A
1 6A 14 Z E 2 zet indicatie RNS maagdelijk
2 6A 15 Z E 2 zet indicatie voor voorbereiding RNS
3 2A 12 A
4 6A 26 X 0 klasse 6 in neutrale toestand
5 2T 6 L E 0 P => zet vergunningen
6 0X 7 L E 0 klasse 6 in LV, X1 doof
5 => 7 6T 0 F T 0 2 =) RND voor eerste begin
8 2T 0 H K 0 A => door naar PSP
DC D0
271
aanroep 6T 0 L F0 0 =) TFO
DA 0 L F 0 DI
=) 0 2B 22 Z E 0 NID
1 0B 31 Z E 0 NLIB
2 2A 0 X 0 B ID uit NLI
3 U 2LA 0 Z K 0 Z d15 = 0? dwz., eerder voorgekomen?
4 Y 6A 8 Z E 0 zo ja, zet ID
5 Y 2T 8 X 0 E -> en klaar
6 4P AS VERDERE OPBOUW VOORLOPIGE ID:
7 3LA 0 Z K 0 d15:= 0
8 3LA 32767 A clear adresgedeelte
9 0A 13 Z K 0 voeg d25 toe: opc2 voor FLI-referentie
10 0A 26 Z E 0 FLSC als adresgedeelte
11 6A 0 X 0 B vul ID in NLI in
12 6A 8 Z E 0 zet ID
13 2B 22 Z E 0 NID
14 U 1B 9 Z E 2 P > NLSC0? dwz., geen MCP?
15 3B 1 A
16 5B 26 Z E 0 FLSC:= FLSC + 1
17 Y 2T 8 X 0 E -> klaar als geen MCP
18 4P SA oude ID, = d18, d15, MCPnr
19 0B 26 Z E 0 FLSC in kwestie
20 0B 12 Z E 0 FLIB
21 2T 0 F U 0 A => door naar FFL
DC D0
272 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 L H0 3 =) PST
DA 0 L H 0 DI
=)
0 2A 18 Z E 0 Z EFLA = 0?
1 Y 6T 0 K N 0 2 =) zo ja, dan RLA
2 2B 22 Z E 0 NID
3 U 1B 25 Z E 2 P > NLSCop? dwz., geen standaardfunctie?
4 N 2T 9 L H 0 A -> anders speciale behandeling
5 2A 19 Z E 0 Z FFLA = 0?
6 Y 6T 0 L F 0 0 =) zo ja, dan TFO
7 6T 0 Z R 0 0 =) BPR
8 2T 11 X 0 E => klaar
4 => 9 0B 31 Z E 0 NLIB
10 2S 0 X 0 B pak ID uit NLI
11 2LS 4095 A isoleer 256 * OH + operatornummer
12 6T 0 Z T 0 0 =) FTL
13 2A 9 Z E 0 DL
14 U 1A 98 A Z = (?
15 Y 2A 1 A
16 Y 6A 18 Z E 0 zo ja, dan EFLA:= 1
17 Y 2T 4 E W 0 A -> en verder samen met DDEL (
18 2T 8 Z S 0 A => anders verder samen met POP
DC D0
273
aanroep 6T 0 L K0 14 =) RFS
DA 0 L K 0 DI
20-> =) 0 2Z 1 XP heptade van band
1 2A 18 Z E 2 Z RFSB = 0?
2 Y 2T 10 L K 0 A -> dan shift ongedefinieerd
3 4P SB
14 -> 4 2S 0 L K 1 B P pak tabel[heptade]; > +0?
5 N 2T 22 L K 0 A zo neen, dan uitzoeken
6 0LA 124 A Z RFSB = 124?, dwz., shift = uppercase?
7 Y 3P 8 SS zo ja, dan uitschuiven
8 N 2LS 255 A zo neen, dan isoleren
9 2T 22 X 0 E => klaar
2 => 10 4P SB
11 U 0LS 62 A Z heptade = 62? dwz., TAB?
12 N 1S 16 A Z 16? SPATIE?
13 N 1S 10 A Z 26? TWNR?
14 Y 2T 4 L K 0 A -> zo ja, dan case-onafhankelijk
15 U 0LS 96 A Z heptade = 122? dwz., lower case?
16 N 1S 98 A Z 124? upper case?
17 N 0S 124 A Z 0? blank?
18 Y 6B 18 Z E 2 zo ja, zet shift (ongedefinieerd)
19 N 1S 127 A Z heptade = 127? dwz., ERASE?
20 Y 2T 0 L K 0 A -> zo ja, dan volgende heptade
21 7Y 19 C 0 stop: shift niet gedefinieerd
5 => 22 4P SS Z symbool uit tabel = -0?
23 Y 7Y 20 C 0 zo ja, dan stop: foute pariteit
24 U 1LS 1 A Z symbool uit tabel = -1?
25 Y 7Y 21 C 0 zo ja, dan stop: ontoelaatbare ponsing
26 U 1B 127 A Z heptade = 127?
27 N 6B 18 Z E 2 zo neen, dan zet shift
28 2T 0 L K 0 A => volgende heptade
DC D0
274 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
LK1
DA 0 L K 1 DN SYMBOOL TABELWAARDE
0 - 2 SHIFT ONGEDEFINIEERD
1 + 19969 OR 1 78 1
2 + 16898 * 2 66 2
3 - 0 foute pariteit
4 + 18436 = 4 72 4
5 - 0 foute pariteit
6 - 0 foute pariteit
7 + 25863 ] 7 101 7
8 + 25096 ( 8 98 8
9 - 0 foute pariteit
10 - 0 foute pariteit
11 - 1 STOPCODE
12 - 0 foute pariteit
13 - 1 ontoelaatbare ponsing
14 + 41635 | _ 162 163
15 - 0 foute pariteit
16 + 31611 SPATIE 123 123
17 - 0 foute pariteit
18 - 0 foute pariteit
19 + 17155 / 3 67 3
20 - 0 foute pariteit
21 + 23301 ; 5 91 5
22 + 25606 [ 6 100 6
23 - 0 foute pariteit
24 - 0 foute pariteit
25 + 25353 ) 9 99 9
26 + 30583 TWNR 119 119
27 - 0 foute pariteit
28 - 1 ontoelaatbare ponsing
29 - 0 foute pariteit
30 - 0 foute pariteit
31 - 1 ontoelaatbare ponsing
DC D0
275
LK2
DA 0 L K 2 DN SYMBOOL TABELWAARDE
0 + 19712 and 0 77 0
1 - 0 foute pariteit
2 - 0 foute pariteit
3 + 14365 T t 56 29
4 - 0 foute pariteit
5 + 14879 V v 58 31
6 + 15136 W w 59 32
7 - 0 foute pariteit
8 - 0 foute pariteit
9 + 15907 Z z 62 35
10 - 1 ontoelaatbare ponsing
11 - 0 foute pariteit
12 - 1 ontoelaatbare ponsing
13 - 0 foute pariteit
14 - 0 foute pariteit
15 - 1 ontoelaatbare ponsing
16 - 0 foute pariteit
17 + 17994 > < 70 74
18 + 14108 S s 55 28
19 - 0 foute pariteit
20 + 14622 U u 57 30
21 - 0 foute pariteit
22 - 0 foute pariteit
23 + 15393 X x 60 33
24 + 15650 Y y 61 34
25 - 0 foute pariteit
26 - 0 foute pariteit
27 + 30809 ’ ten 120 89
28 - 0 foute pariteit
29 - 1 ontoelaatbare ponsing
30 + 30326 TAB 118 118
31 - 0 foute pariteit
DC D0
276 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
LK3
DA 0 L K 3 DN SYMBOOL TABELWAARDE
0 + 19521 not - 76 65
1 - 0 foute pariteit
2 - 0 foute pariteit
3 + 12309 L l 48 21
4 - 0 foute pariteit
5 + 12823 N n 50 23
6 + 13080 O o 51 24
7 - 0 foute pariteit
8 - 0 foute pariteit
9 + 13851 R r 54 27
10 - 1 ontoelaatbare ponsing
11 - 0 foute pariteit
12 - 1 ontoelaatbare ponsing
13 - 0 foute pariteit
14 - 0 foute pariteit
15 - 1 ontoelaatbare ponsing
16 - 0 foute pariteit
17 + 11795 J j 46 19
18 + 12052 K k 47 20
19 - 0 foute pariteit
20 + 12566 M m 49 22
21 - 0 foute pariteit
22 - 0 foute pariteit
23 + 13337 P p 52 25
24 + 13594 Q q 53 26
25 - 0 foute pariteit
26 - 0 foute pariteit
27 + 31319 ? , 122 87
28 - 0 foute pariteit
29 - 1 ontoelaatbare ponsing
30 - 1 ontoelaatbare ponsing
31 - 0 foute pariteit
DC D0
277
LK4
DA 0 L K 4 DN SYMBOOL TABELWAARDE
0 - 0 foute pariteit
1 + 9482 A a 37 10
2 + 9739 B b 38 11
3 - 0 foute pariteit
4 + 10253 D d 40 13
5 - 0 foute pariteit
6 - 0 foute pariteit
7 + 11024 G g 43 16
8 + 11281 H h 44 17
9 - 0 foute pariteit
10 - 0 foute pariteit
11 + 31832 : . 124 88
12 - 0 foute pariteit
13 - 1 ontoelaatbare ponsing
14 - 1 ontoelaatbare ponsing
15 - 0 foute pariteit
16 + 31040 " + 121 64
17 - 0 foute pariteit
18 - 0 foute pariteit
19 + 9996 C c 39 12
20 - 0 foute pariteit
21 + 10510 E e 41 14
22 + 10767 F f 42 15
23 - 0 foute pariteit
24 - 0 foute pariteit
25 + 11538 I i 45 18
26 - 2 LOWER CASE
27 - 0 foute pariteit
28 - 2 UPPER CASE
29 - 0 foute pariteit
30 - 0 foute pariteit
31 - 2 ERASE
DC D0
278 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroepen 6T 0 L L0 0 =) BSM
6T 7 L L1 0 =) voorbereiding BSM
DA 0 L L 0 DI
=) 0 2A 0 A
1 1P 10 SA bits naar A; S:= aantal aangeboden bits
2 2B 0 L T 0 aantal bits in voorraad - 27
3 6S 0 L T 0
4 2S 0 A schuif
5 0P 10 AA aangeboden bits
6 0P 27 SA B in goede positie
7 0LA 1 L T 0 SA:= nieuwe voorraad bits
8 4B 0 L T 0 P nieuw aantal bits in voorraad > 27?
9 N 6A 1 L T 0 zo neen, dan berg voorraad
10 N 2T 8 X 0 E -> en klaar
11 6S 1 L T 0 nieuwe voorraad:= kop van SA
12 2S 27 A
13 5S 0 L T 0 aantal bits:= aantal bits - 27
14 2B 19 Z E 1 vulplaats
15 6A 0 X 0 B magazijn[vulplaats]:= staart van SA
16 0B 1 A
17 6B 19 Z E 1 vulplaats:= vulplaats + 1
18 1B 20 Z E 1 Z vulplaats = ledigplaats?
19 N 2T 8 X 0 E -> zo neen, dan klaar
20 2B 30 Z E 0 NLSC OPSCHUIVEN VAN ALGOL-TEKST,
21 0B 31 Z E 0 NLIB FLI, KLI EN NLI
22 5P BA
23 1A 8 A
24 U 0A 21 Z E 0 P PLIB > NLIB + NLSC + 8?
25 N 7Y 25 C 0 anders stop: programma te lang
26 0A 8 A
27 0A 20 Z E 1 ledigplaats
28 7A 0 X 0 aantal:= NLIB + NLSC - ledigplaats
29 2A 8 A
30 4A 20 Z E 1 ledigplaats:= ledigplaats + 8
31 4A 12 Z E 0 FLIB:= FLIB + 8
DC D0
279
LL1
DA 0 L L 1 DI
0 4A 28 Z E 0 KLIB:= KLIB + 8
1 4A 31 Z E 0 NLIB:= NLIB + 8
6 -> 2 1B 1 A opschuifcyclus
3 2A 0 X 0 B 8 plaatsen
4 6A 8 X 0 B omhoog
5 4T 2 L L 1 0 P ->
6 2T 8 X 0 E => klaar
7 =) 7 2S 27 A VOORBEREIDING
8 7S 0 L T 0 geen bits in voorraad
9 2S 0 A
10 6S 1 L T 0 clear voorraadwoord
11 2S 18 Z E 1
12 6S 19 Z E 1 vulplaats:= BIM
13 2T 8 X 0 E => klaar
DC D0
280 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 L R 0 DN OPCnr
0 + 10624 8
1 + 6160 9
2 + 10625 10
3 + 10626 11
4 + 10627 12
5 + 7208 13
6 + 6161 14
7 + 10628 15
8 + 5124 16
9 + 7209 17
10 + 6162 18
11 + 7210 19
12 + 7211 20
13 + 10629 21
14 + 10630 22
15 + 10631 23
16 + 10632 24
17 + 10633 25
18 + 10634 26
19 + 10635 27
20 + 10636 28
21 + 10637 29
22 + 6163 30
23 + 7212 31
24 + 10638 32
25 + 4096 33
26 + 4097 34
27 + 7213 35
28 + 10639 36
29 + 10640 37
30 + 10641 38
31 + 7214 39
DC D0
281
LR1
DA 0 L R 1 DN OPCnr
0 + 10642 40
1 + 10643 41
2 + 10644 42
3 + 10645 43
4 + 10646 44
5 + 10647 45
6 + 10648 46
7 + 10649 47
8 + 10650 48
9 + 10651 49
10 + 10652 50
11 + 10653 51
12 + 10654 52
13 + 10655 53
14 + 10656 54
15 + 10657 55
16 + 5125 56
17 + 10658 57
18 + 5126 58
19 + 10659 59
20 + 10660 60
21 + 7215 61
DC D0
282 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 L S0 0 =) ADC
DA 0 L S 0 DI
=) 0 2A 8 X 0
1 6A 5 L T 0 transporteer link
2 6S 6 L T 0 red te coderen adres
3 2LS 31 A isoleer d4 - d0
4 U 2LS 28 A Z <= 3?
5 N 0LS 6176 A zo neen, bouw zelf het codewoord op
6 Y 4P SB zo ja, dan
7 Y 2S 25 L S 0 B codewoord uit tabel halen
8 6T 0 L L 0 0 =) BSM met codewoord voor d4 - d0
9 2S 6 L T 0 pak te coderen adres weer
10 2LS 992 A isoleer d9 - d5
11 1P 5 SS schuif uit
12 U 1S 5 A P > 5?
13 Y 0LS 6176 A dan zelf het codewoord opbouwen
14 N 4P SB en anders
15 N 2S 29 L S 0 B codewoord uit tabel halen
16 6T 0 L L 0 0 =) BSM met codewoord voor d9 - d5
17 2S 6 L T 0 pak te coderen adres weer
18 2LS 31744 A Z isoleer d14 - d10; = 0?
19 N 1P 10 SS zo neen, dan uitschuiven
20 N 0LS 6176 A en zelf het codewoord opbouwen
21 Y 2S 1024 A zo ja, dan codewoord pakken
22 6T 0 L L 0 0 =) BSM met codewoord voor d14 - d10
23 2S 6 L T 0 herstel S
24 2T 5 L T 0 E => klaar
25 DN +6176 CODEWOORDEN d4 - d0 = 0
26 + 2048 1
27 + 3074 2
28 + 3075 3
29 + 2048 d9 - d5 = 0
30 + 4100 1
31 + 4101 2
DC D0
283
LS1
DA 0 L S 1 DN
0 + 6179 CODEWOORDEN d9 - d5 = 3
1 + 4102 4
2 + 4103 5
DC D0
284 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 R Z 0 DI
9KW3 -> 0 2S 3 R E 0
1 6S 1 X 0 telling:= RLSCE
2 6T 19 R W 1 0 =) voorbereiding RBS1
4 -> 3 6T 5 D 1 0 =) TPA?
4 Y 1T 2 A -> zo ja, dan wacht
5 6T 6 R L 0 3 =) LIL voor RLI
6 1S 89 S F 0 Z laatste opdracht = OPC 96?
7 N 7Y 5 C 3 anders stop: bitstroom ontspoord
8 2S 11 R E 0 RLIB
9 6T 0 R T 0 1 =) TYP met RLIB
10 2S 128 A
11 6S 0 X 0 telling:= lengte MLI
18 -> 12 2B 4 R K 0 CYCLUS MAAK COPIE VAN MLI
13 0B 0 X 0
14 2S 32767 X 0 B MLI[i]
15 2B 5 R K 0
16 0B 0 X 0
17 6S 32767 X 0 B CRF[i]:= MLI[i]
18 4T 12 R Z 0 0 P ->
19 2B 4 R K 0 MLIB
20 6B 2 R E 0 geef opc3 een nieuwe betekenis
21 2S 5 R E 0 FLIB
25 22 6S 6 R E 0 FLSC:= 0: vernietig FLI
1RZ1 -> 23 6T 29 R W 1 1 =) voorbereiding RBS2
24 6T 0 R U 0 4 =) MCPL
L4 => 25 2T 23 R Z 0 A => volgende MCP lezen
L4 => 26 2T 2 R Z 1 A => doe test op einde
L4 => 27 2B 13 R E 0 CYCLUS SKIP MCP: ledigplaats
31 -> 28 1B 1 A
29 2S 0 X 0 B woord uit MCP-magazijn
30 1S 4 R H 0 Z een slotcombinatie?
31 N 2T 28 R Z 0 A -> zo neen, dan verder skippen
DC D0
285
RZ1
DA 0 R Z 1 DI
0 6B 13 R E 0 nieuwe ledigplaats
1 2T 23 R Z 0 A => volgende MCP lezen
26RZ0=> 2 2S 11 R Z 1 A
3 2B 27 D16 beginadres paragraaftabel
4 6S 0 X 0 B herdefinieer autostart 0
6 -> 5 6T 5 D 1 0 =) TPA?
6 Y 1T 2 A -> zo ja, wacht dan
14 -> 7 2S 14 R E 0 Z aantal MCP’s = 0?
8 Y 2T 20 R Z 1 A -> dan is het objectprogramma klaar
9 7Y 6 C 3 anders stop: MCP-band inleggen
13 10 0Y 126 XS X1 doof
19->=>> 11 6T 5 R W 2 1 =) voorbereiding RBS3
12 6T 0 R U 0 4 =) MCPL
L4 => 13 2T 11 R Z 1 A => volgende MCP lezen
L4 => 14 2T 7 R Z 1 A => doe test op einde
16,18=> 15 2Z 1 XP Z CYCLUS SKIP MCP: heptade = 0?
l4 16 N 1T 2 A -> anders nog niet in blank
17 2Z 1 XP Z heptade van band = 0?
18 N 1T 4 A -> anders nog niet in blank
19 2T 11 R Z 1 A => volgende MCP lezen
8 => 20 2S 11 R E 0 RLIB
21 2B 27 D16 beginadres paragraaftabel
22 6S 0 X 0 B herdefinieer autostart 0
23 0Y 0 XS X1 horend
24 2S 15 X 1 MCPE
25 6T 2 R T 0 1 =) TYP met MCPE
26 2S 15 X 1 MCPE
27 1S 3 R K 0 GVC0
28 6S 0 X 0 telling:= lengte te clearen traject
29 2S 15 X 1 MCPE
30 0S 0 R K 0 clearopdracht opbouwen
31 6S 24 X 1 en wegschrijven
DC D0
286 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
RZ2
DA 0 R Z 2 DI
0 3S 0 A
1 3B 1 A
2 2T 25 X 1 A => naar cyclus clear werkruimte
24X2 => 3 2A 5 R K 0 DIRECTIEF DW
4 6A 28 X 0 transportadres:= CRFB
5 2T 30 D 8 A => verder alsof directief DB gelezen
DC D0
287
aanroep 6T 0 R F0 2 =) RBW
DA 0 R F 0 DI
=) 0 2A 0 S E 0 P begint de codering met een bit = 0?
1 Y 2T 4 R F 1 A -> dan een opdracht van het OPC-type
2 2B 1 A MASKERTYPE
3 6T 0 R W 0 0 =) RBS
4 6T 0 R N 0 1 =) ML voor functiegedeelte
5 6S 10 R E 0 red dit
6 6T 0 R Y 0 0 ADD voor adresgedeelte
7 2S 10 R E 0 functiegedeelte
8 2A 0 A scheiden van
9 0P 15 SA opc-nr
10 0S 5 S E 0 voeg adresgedeelte toe
11 U 2LA 1 A Z opc = 0 of 2?
12 Y 2T 21 R F 0 A ->
13 U 2LA 2 A Z opc = 1?
14 Y 0S 1 R E 0 dan RLIB bijtellen
15 Y 2T 10 X 0 E -> en klaar
16 2B 2 R E 0 bij opc = 3: pak KLIB of MLIB
17 U 1B 4 R K 0 Z is het MLIB? dwz., X3X bij MCP?
18 N 0S 2 R E 0 zo neen, dan X3X in RLI, dus
19 N 2T 10 X 0 E -> KLIB bijtellen en klaar
20 2T 27 R F 0 A => ga juiste adres uit MLI halen
12 => 21 U 2LA 2 A Z opc = 0?
22 Y 2T 10 X 0 E -> dan klaar
23 U 2LS 2 R F 1 Z bij opc = 2: als d17 <> 0
24 N 3LS 2 R F 1 dan d17:= 0,
25 Y 0LS 3 R F 1 anders d19:= 1
26 2B 5 R E 0 FLIB voor X2X
20 -> 27 4P SA
28 2LA 32767 A isoleer adresgedeelte
29 6A 10 R E 0
30 0B 10 R E 0
31 3LS 32767 A isoleer functiegedeelte
DC D0
288 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
RF1
DA 0 R F 1 DI
0 0S 0 X 0 B voeg FLI[adres] of MLI[adres] toe
1 2T 10 X 0 E => en klaar
2 0A 0 X 0 P | d17
3 0A 0 X 0 A | d19
1RF0 => 4 0P 1 AA P OPC-TYPE beginbits 00?
5 N 2T 14 R F 1 A -> anders > 5
6 0P 1 AA P beginbits 000?
7 Y 2B 4 A zo ja, dan 0000 of 0001 voor 0 of 1
8 N 2B 5 A zo neen, dan 00100 t/m 00111 voor 2 t/m 5
9 6T 0 R W 0 0 =) RBS
10 N 1S 2 A
22,26-> 11 4P SB haal opdracht
12 2S 0 S F 0 B uit OPC-tabel
13 2T 10 X 0 E => en klaar
5 => 14 0P 1 AA P beginbits 010?
15 N 2T 23 R F 1 A -> anders > 17
16 0P 1 AA P beginbits 0100?
17 Y 2B 6 A dan 010000 t/m 010011 voor 6 t/m 9
18 N 2B 7 A anders 0101000 t/m 0101111 voor 10 t/m 17
19 6T 0 R W 0 0 =) RBS
20 Y 1S 10 A
21 N 1S 30 A
22 2T 11 R F 1 A => haal opdracht uit OPC-tabel en klaar
15 => 23 2B 10 A bij beginbits 011
24 6T 0 R W 0 0 =) RBS 0110000000 t/m 0111111111
25 1S 366 A voor 18 t/m 145
26 2T 11 R F 1 A => haal opdracht uit OPC-tabel en klaar
DC D0
289
aanroep 6T 0 R H0 0 =) TBV
DA 0 R H 0 DI
=) 0 2S 0 S E 0 bits in voorraad
1 1S 4 R H 0 Z = slotcombinatie?
2 N 7Y 11 C 3 anders stop: decodering ontspoord
3 2T 8 X 0 E =) klaar
4 7Z 0 X 0 | 11 11110 00000 00000 00000 00000
DC D0
290 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
DA 0 R K 0 DI
0 6S 0 X 0 C clearopdracht
DC D0
aanroep 6T 6 R L0 3 =) LIL
DA 0 R L 0 DI
6 => 0 6T 0 R F 0 2 =) RBW BERGCYCLUS
25 -> 1 2B 1 R E 0 vorm het
2 0B 1 X 0 transportadres
3 U 1B 6 R E 0 P > FLIB + FLSCE?
4 N 2T 8 R L 0 A -> anders FLI naar beneden schuiven
5 6S 0 X 0 B berg
=) 6 4T 0 R L 0 1 E -> naar bergcyclus of
7 2T 11 X 0 E => klaar
4 => 8 2A 5 R E 0 FLIB OPSCHUIVEN VAN FLI
9 1A 13 R E 0 ledigplaats van RBS
10 1A 1 A P FLIB > ledigplaats + 1?
11 N 7Y 2 C3 anders stop: programma te lang
12 6A 0 R E0 schuifafastand
13 5A 5 R E0 nieuwe FLIB
14 5A 6 R E0 nieuwe (FLIB + FLSCE)
15 2A 6 R E0
16 1A 5 R E0
17 6A 0 X0 telling:= FLSCE
18 2B 13 R E0 ledigplaats
24 -> 19 0B 0 R E0 schuifafstand SCHUIFCYCLUS
20 2A 1 X0 B
21 1B 0 R E0 over schuifafstand
22 6A 1 X0 B omlaag
23 0B 1 A
24 4T 19 R L 0 0 P ->
25 2T 1 R L 0 A => terug naar bergcyclys
DC D0
292 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 R R0 2 =) LLN
DA 0 R R 0 DI
=) 0 2B 13 A
1 6T 0 R W 0 0 =) RBS
2 U 1S 7679 A P eindmarker?
3 2T 10 X 0 => klaar
DC D0
293
aanroep 6T 0 R S0 0 =) HSC
DA 0 R S 0 DI
=) 0 2A 0 R E 0 2 * haaladres
1 1P 1 AA P even?
2 2LA 32767 A entier(haaladres)
3 4P AB
4 2S 0 X 0 B CRF[entier(haaladres)]
5 Y 3P 13 SS zo nodig hiervan de kop nemen
6 2LS 8191 A isoleer symbool van 13 bits
7 2A 1 A
8 4A 0 R E 0 haaladres:= haaladres + 1/2
9 U 1S 7680 A Z symbool = eindmarker (111 10000 00000)?
10 2T 8 X 0 => klaar
DC D0
294 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
6T 2 R T0 1 =) TYP
DA 0 R T 0 DI
=) 0 2A 19 A zet schrijfmachine
1 6Y 2 XP in kleine-letterstand
=) 2 2A 11 A geef een
3 6Y 2 XP TWNR
4 4P SA A:= 32 * 32 * a + 32 * b + c
5 3P 10 SS S:= a
6 0X 2176 A S:= 32 * 68 * a + A
7 4P SA A:= 32 * 100 * a + 32 * b + c
8 3P 5 SS S:= 100 * a + b
9 0X 68 A S:= 68 * 100 * a + 68 * b + A
10 6T 0 D22 0 =) typ S (= 10000 * a + 110 * b + c)
11 DT AG6 NL2 SL2 SL2 XN
12 DI 2T 9 X 0 E => klaar
DC D0
295
aanroepen 6T 0 R W0 0 =) RBS
6T 19 R W1 0 =) voorbereiding RBS1
6T 29 R W1 1 =) voorbereiding RBS2
6T 5 R W2 1 =) voorbereiding RBS3
DA 0 R W 0 DI
=) 0 2S 0 A
1 2A 0 S E 0 pak bitvoorraad
2 0P 0 SA B schuif gevraagde bits naar S
3 6A 0 S E 0 berg nieuwe voorraad
4 4B 1 S E 0 P nieuwe ’ruimte’ > 6?
3RW1 -> 5 N 2T 8 X 0 E -> klaar als nog geen nieuwe heptade nodig
6 6S 4 S E 0 red S
7 2S 1 A
8 4S 2 S E 0 P heptadentelling:= heptadentelling + 1
9 2T 12 R E 0 => switch (naar 10RW0 of 4 RW1)
9 => 10 2Y 1 XP heptade van band
11 N 2T 26 R W 0 A -> als geen pariteitsonderzoek nodig
12 4S 1 S E 0 ’ruimte’:= ’ruimte’ + 1
13 2S 3 S E 0 test de
14 3P 4 SS pariteit van
15 0LS 3 S E 0 de vorige vier
16 2LS 15 A heptaden
17 4P SB
18 2S 13515 A 01101 00110 01011
19 1P 0 SS B P is de pariteit even?
20 Y 7Y 9 C 3 dan stop: foute pariteit
16RW2=) 21 2S 3 A
22 7S 2 S E 0 heptadentelling:= -3
23 6A 3 S E 0 pariteitswoord:= gelezen heptade
24 3P 1 AA verwijder pariteitsbit
25 2T 29 R W 0 A =>
11 => 26 4P AS
27 0LS 3 S E 0 pariteitswoord:= logische som van
18RW1-> 28 6S 3 S E 0 pariteitswoord en gelezen heptade
25 -> 29 2B 1 S E 0 schuif nieuwe heptade in goede positie
30 6Y 32767 X 0 B (2P 1- AA B)
31 4A 0 S E 0 en voeg hem aan de voorraad toe
DC D0
296 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
RW1
DA 0 R W 1 DI
0 2S 4 S E 0 herstel S
1 1B 7 A
28 -> 2 6B 1 S E 0 P ’ruimte’:= ’ruimte’ - 7, ’ruimte’ > 6?
3 2T 5 R W 0 A => klaar met aanvulling voorraad
9RW0 => 4 2A 0 A
5 N 2T 15 R W 1 A -> als magazijnwoord nog niet leeg
6 4S 1 S E 0 ’ruimte’:= ’ruimte’ + 1
7 2S 3 A
8 7S 2 S E 0 heptadentelling:= -3
9 2B 13 R E 0 ledigplaats
10 1B 1 A
11 6B 13 R E 0 ledigplaats:= ledigplaats - 1
12 2S 0 X 0 B S:= magazijn[ledigplaats]
13 2B 6 A eerste maal slechts 6 bits
14 2T 17 R W 1 A =>
5 => 15 2S 3 S E 0 pak magazijnwoord
16 2B 7 A
14 -> 17 0P 0 SA B schuif ’nieuwe heptade’ naar A
18 2T 28 R W 0 A =>
=) 19 2S 1 L T 0 VOORBEREIDING 1: voor RLI
20 3B 0 L T 0 bouw
21 0P 0 SS B bitvoorraad op
31 =) 22 6S 0 S E 0
23 1B 6 A vorm ’ruimte’
24 2S 0 A
25 7S 2 S E 0 heptadentelling:= 0
26 2S 4 R W 1 A
27 6S 12 R E 0 zet switch op 4RW1
28 2T 2 R W 1 A => ga bitvoorraad aanvullen
=) 29 2S 0 A VOORBEREIDING 2: voor MCP’s uit magazijn
30 2B 27 A ’ruimte’:= 33
31 6T 22 R W 1 0 =) doe stuk van voorbereiding 1
DC D0
297
RW2
DA 0 R W 2 DI
3 -> 0 2B 1 A CYCLUS SKIP BITS = 0
1 6T 0 R W 0 0 =) RBS voor 1 bit
2 4P SS Z = 0?
3 Y 2T 0 R W 2 A -> dan herhalen
4 2T 9 X 0 E => klaar met voorbereiding
=) 5 2S 10 R W 0 A VOORBEREIDING 3: voor MCP’s van band
6 6S 12 R E 0 zet switch op 10RW0
7 2S 0 A
8 6S 0 S E 0 bitvoorraad:= 0
9 2S 22 A
10 6S 1 S E 0 ’ruimte’:= 28
12 -> 11 2Y 1 XP Z heptade van band = 0?
12 Y 1T 2 A -> dan blank skippen
13 0LA 30 A Z eerste heptade = 30?
14 N 7Y 10 C 3 anders stop
15 2Y 1 XP heptade van band
16 6T 21 R W 0 0 =) lees nog 3 heptades
17 2T 0 R W 2 A => en skip bits = 0
DC D0
298 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
aanroep 6T 0 R U0 4 =) MCPL
DA 0 R U 0 DI
=)0 6T 0 R R 0 2 =) LLN voor lengte MCP
1 Y 2T 18 R U 0 A -> als eindmarker
2 6S 1 X 0 telling:= lengte MCP
3 6T 0 R R 0 2 =) LLN voor nummer MCP
4 4P SB
5 0B 5 R K 0 CRFB
6 2S 0 X 0 B Z CRF[nummer MCP] = 0?
7 Y 2T 19 R U 0 A -> dan MCP skippen
8 6S 1 R E 0 geef opc1 goede betekenis
9 6B 8 R E 0 dump (CRFB + nummer MCP)
10 6T 6 R L 0 3 =) LIL voor MCP
11 6T 0 R H 0 0 =) TBV
12 2A 1 A
13 5A 14 R E 0 aantal MCP’s:= aantal MCP’s - 1
14 2A 0 A
15 2B 8 R E 0 gedumpte (CRFB + nummer MCP)
16 6A 0 X 0 B CRF[nummer MCP]:= 0
17 2T 12 X 0 E => klaar met lezen
1 => 18 2A 1 A Z
7 -> 19 Y 2A 2 A
20 4A 12 X 0 hoog lambda4 met 1 of 2 op
21 2T 12 X 0 E => klaar
DC D0
299
aanroep 6T 0 R Y0 0 =) ADD
DA 0 R Y 0 DI
=) 0 2S 0 A
1 2A 0 S E 0 P begint codering met een bit = 0?
2 Y 2B 1 A zo ja, dan 0 voor pentade 0
3 N 2B 6 A anders 100001 t/m 111111 voor 1 t/m 31
4 6B 5 S E 0 onthoud aantal ’verbruikte’ bits
5 0P 0 SA B schuif juiste aantal bits naar S
6 N 2LS 31 A zo nodig d5 schoonmaken
7 4P AA P begint codering met een bit = 0?
8 N 2T 20 R Y 0 A -> anders 2-de adrespentade = 3 of > 5
9 0P 1 AA P beginbits 00?
10 Y 3B 2 A zo ja, dan 00 voor pentade 0
11 N 3B 4 A anders 0100 t/m 0111 voor 1, 2, 4, 5
12 0P 6 SS B schuif 1-ste pentade over totaal
13 5P BB 5 plaatsen op, en het juiste aantal
14 6Z 31 X 1 B (0P 1- SA B) bits uit A erbij
15 Y 2T 23 R Y 0 A -> klaar met 2-de pentade = 0
16 U 2LS 2 A Z codering 0100 0f 0101?
17 Y 1S 3 A zo ja, dan 1 of 2 ervan maken
18 N 0LS 2 A anders van 0110 of 0111 nu 4 of 5 maken
19 2T 23 R Y 0 A =>
8 => 20 0P 1 AA gooi beginbit 1 weg
21 2B 6 A
22 6Z 31 X 1 B (0P 1- SA B) schuif 2-de pentade in S
15,19-> 23 4B 5 S E 0 tel aantal ’verbruikte’ bits
24 4P AA P begint codering met bit = 0?
25 N 2T 2 R Y 1 A -> anders 3-de adrespentade = 0 of > 3
26 0P 1 AA P beginbits 00?
27 Y 3B 2 A zo ja, dan 00 voor pentade 1
28 N 3B 3 A anders 010 of 011 voor pentade 2 of 3
29 0P 6 SS B
30 5P BB
31 6Z 31 X 1 B (0P 1- SA B)
DC D0
300 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
RY1
DA 0 R Y 1 DI
0 Y 0LS 1 A bij codering 00 nog 1 optellen
1 2T 5 R Y 1 A =>
25RY0=> 2 0P 1 AA gooi beginbit 1 weg
3 2B 6 A
4 6Z 31 X 1 B (0P 1- SA B) schuif 3-de pentade in S
1 -> 5 0B 5 S E 0 aantal ’verbruikte’ bits
6 6S 5 S E 0 gelezen adres in 5 S E0 afleveren
7 2T 0 R W 0 A => door naar RBS om ’verbruikte bits’ te
DC D0 verwijderen
301
ML masker-lezer RN0
aanroep 6T 0 R N0 0 =) ML
DA 0 R N 0 DI
=) 0 2A 0 S E 0 P begint codering met een bit = 0?
1 N 2T 5 R N 0 A -> anders masker-nummer > 1
2 2B 2 A 00 of 01 voor nummer 0 of 1
3 6T 0 R W 0 0 =) RBS
4 2T 18 R N 0 A => pak opdracht
1 => 5 0P 1 AA P beginbits 10?
6 Y 2T 15 R N 0 A -> zo ja, dan 100 of 101 voor nummer 2 of 3
7 2B 6 A anders 110000 t/m 111111 voor 4 t/m 19
8 6T 0 R W 0 0 =) RBS
9 1S 63 A Z nummer = 19?
10 N 0S 19 A
11 N 2T 18 R N 0 A -> anders klaar met nummer
12 6T 0 R Y 0 0 =) ADD
13 2S 5 S E 0 bij nummer 19 functiedeel als adres gecodeerd
14 2T 9 X 0 E => klaar
6 => 15 2B 3 A
16 6T 0 R W 0 0 =) RBS
17 0LS 6 A maak er 2 of 3 van
4,11 -> 18 4P SB
19 2S 0 S Z 0 B pak functiedeel (plus opc) uit tabel
20 2T 9 X 0 E => klaar
DC D0
302 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
MT masker-tabel SZ0
DA 0 S Z 0 DN opc functie
0 + 656 0 2S 0 A
1 + 14480 3 2B 0 A
2 + 10880 2 2T 0 X0
3 + 2192 0 2B 0 A
4 + 144 0 2A 0 A
5 + 10368 2 2B 0 X0
6 + 6800 1 2T 0 A
7 + 0 0 0A 0 X0
8 + 12304 3 0A 0 A
9 + 10883 2 N 2T 0 X0
10 + 6288 1 2B 0 A
11 + 4128 1 0A 0 X0 B
12 + 8832 2 2S 0 X0
13 + 146 0 Y 2A 0 A
14 + 256 0 4A 0 X0
15 + 134 0 Y 2A 0 X0 P
16 + 402 0 Y 6A 0 A
17 + 4144 1 0A 0 X0 C
18 + 16 0 0A 0 A
DC D0
303
CC clear cycle X1
DA 24 X 1 DI
25 -> 24 0A 0 X 0 clearopdracht (zie 31 RZ1)
2RZ2 -> 25 4T 24 X 1 0 E ->
27 -> 26 6T 5 D 1 0 => TPA?
27 Y 1T 2 A -> zo ja, wacht dan
28 7Y 7 C 3 stop: klaar met vertalen
DC D0
304 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
X2
DA 24 X 2 DI
26D17=> 24 2T 3 R Z 2 A => behandeling directief DW
DC D0
305
SW0
DA 6 Z E 1 DN
+ 6783 PLIE 6-19-31
DA 8 Z E 1
+ 800 TLIB 0-25- 0
DA 18 Z E 1
+ 930 BIM 0-29- 2
DA 0 Z E 2
+ 6880 BOB 6-23- 0
DA 9 Z E 2
+ 2 NLSC0 0- 4-11
DA 17 Z E 2
+ 6944 PNLIB 6-25- 0
DA 25 Z E 2
+ 0 NLSCop 0- 1- 1
DC D0
DA 1 R K 0 DN
+ 928 MCPB 0-29- 0
+10165 KLIE 9-29-21
+ 138 GVC0 0- 4-10
+ 800 MLIB 0-25- 0
+ 623 CRFB 0-19-15
DC D0
DA 23 X 1 DN
+12256 OCB6 11-31- 0
DC D0
306 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
SW1
DA 15 X19 DN CRF
+ 245760 DI 30 0
2LS 20 X 0 DN 7680 20
+ 15872 1 7680
+ 98306 DI 12 2
2LS 63 X 0 DN 7680 63
+ 32256 3 7680
+ 122884 15 4
+ 32256 3 7680
+ 819205 DI 100 5
2LS 134 X 0 DN 7680 134
+ 49176 DI 6 24
2LS 21 X 0 DN 7680 21
+ 204288 DI 24 7680
2LS 7680 X 0 7680 7680 (eindmarker CRF)
DC D0
307
SW2
DA 18 Z E 1 DN
+ 930 BIM 0-29- 2
DA 9 Z E 2 DN
+ 48 NLSC0
DA 25 Z E 2 DN
+ 31 NLSCop
DA 6944 X 0 DN
+ 27598040 ] read
+ 265358 d18 + 12*256 + 40 + 102
- 6 ] print
+ 61580507 ]
+ 265359 d18 + 12*256 + 40 + 103
- 53284863 ] TAB
+ 265360 d18 + 12*256 + 40 + 104
- 19668591 ] NLCR
+ 265361 d18 + 12*256 + 40 + 105
- 0 ] SPACE
- 46937177 ]
+ 265363 d18 + 12*256 + 40 + 107
+ 53230304 ] stop
+ 265364 d18 + 12*256 + 40 + 108
+ 59085824 ] abs
+ 265349 d18 + 12*256 + 57 + 76
+ 48768224 ] sign
+ 265350 d18 + 12*256 + 57 + 77
+ 61715680 ] sqrt
+ 265351 d18 + 12*256 + 57 + 78
+ 48838656 ] sin
+ 265352 d18 + 12*256 + 57 + 79
+ 59512832 ] cos
+ 265353 d18 + 12*256 + 57 + 80
+ 48922624 ] ln
+ 265355 d18 + 12*256 + 57 + 82
+ 53517312 ] exp
+ 265356 d18 + 12*256 + 57 + 83
- 289 ] entier
+ 29964985 ]
+ 265357 d18 + 12*256 + 57 + 84
- 29561343 ] SUM
+ 294912 d18 + d15 + 0
308 CHAPTER 10. THE X1–CODE VERSION OF THE COMPILER
- 14789691 ] PRINTTEXT
- 15115337 ]
+ 294913 d18 + d15 + 1
- 27986615 ] EVEN
+ 294914 d18 + d15 + 2
- 325 ] arctan
+ 21928153 ]
+ 294915 d18 + d15 + 3
- 15081135 ] FLOT
+ 294917 d18 + d15 + 5
- 14787759 ] FIXT
+ 294918 d18 + d15 + 6
- 3610 ] ABSFIXT
- 38441163 ]
+ 294936 d18 + d15 + 24
DC D0
DS
Appendix A
During compilation of an ALGOL 60 program on the X1 the following stops could occur.
(In case of a stop the stop number could be retrieved from the 10 least significant bits of
the instruction register ‘OR’, which could be made visible on the operators console in a
line of 27 light bulbs.) This list is taken from a user manual dated August 1st, 1962.
0– 1 Not interpretable.
0– 4 As stop: 0– 3.
0– 5 The store capacity available is too small for the Algol program.
0– 6 As stop: 0– 5.
0– 7 An identifier that has not been declared occurs in the Algol text.
0– 9 End of PRESCAN.
0–10 As stop: 0– 1.
0–11 The symbol ‘ |’ is followed in the Algol text by a not permitted symbol.
309
310 APPENDIX A. COMPILER AND RUN–TIME STOPS
0–14 One of the symbols: ’ (accent), ” (apostrophe) or ? (question mark) occurs in the
Algol text.
0–15 As stop 0– 5.
0–16 As stop 0– 5.
0–18 As stop 0– 5.
0–19 The shift on the paper tape is undefined after ‘tape feed’.
During loading of the object tape the following stops could occur:
3– 2 As stop: 3– 1.
3– 4 Stop after reading of FLI (the second part of the object tape).
3– 5 As stop: 3– 1.
3– 7 Stop after reading of RLI (the first part of the object tape).
3– 9 As stop: 3– 8.
3–10 As stop: 3– 8.
3–11 As stop: 3– 8.
3–12 As stop: 3– 8.
311
3–13 As stop: 3– 8.
During program execution the following stops could occur (taken from the user manual
dated December 1st, 1962).
1– 2 In the declaration of a dynamic array a lower bound is larger than the corresponding
upper bound.
1– 8 At the operation ‘:’ (integer division) the two operands are not both of type integer.
1–17 On the input tape a shift definition is missing after ‘tape feed’.
1–18 Procedure ‘read’ found the symbol ‘STOP CODE’ on the input tape (only allowed
after the parts separator ‘?’).
312 APPENDIX A. COMPILER AND RUN–TIME STOPS
Appendix B
The following ALGOL 60 program is taken from the PhD thesis of Zonneveld [11] and
used for the measurements on the ALGOL 60 compiler for the X1 discussed in this report.
It is printed in an non–original layout in order to improve readability and uses ‘ for ∨, ^
for ∧, ~ for ¬, and % for 10 .
Following the program text we give the output on the X1 console as produced during the
compilation process.
313
314 APPENDIX B. A SAMPLE ALGOL 60 PROGRAM
_p_r_o_c_e_d_u_r_e RK3n(x,a,b,y,ya,z,za,fxyj,j,e,d,fi,n);
_v_a_l_u_e b,fi,n; _i_n_t_e_g_e_r j,n; _r_e_a_l x,a,b,fxyj;
_B_o_o_l_e_a_n fi; _a_r_r_a_y y,ya,z,za,e,d;
_b_e_g_i_n _i_n_t_e_g_e_r jj;
_r_e_a_l xl,h,hmin,int,hl,absh,fhm,discry,discrz,toly,tolz,mu,mu1,fhy,fhz;
_B_o_o_l_e_a_n last,first,reject;
_a_r_r_a_y yl,zl,k0,k1,k2,k3,k4,k5[1:n],ee[1:4*n];
_i_f fi
_t_h_e_n _b_e_g_i_n d[3]:= a;
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
_b_e_g_i_n d[jj+3]:= ya[jj]; d[n+jj+3]:= za[jj] _e_n_d
_e_n_d ;
d[1]:= 0; xl:= d[3];
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
_b_e_g_i_n yl[jj]:= d[jj+3]; zl[jj]:= d[n+jj+3] _e_n_d ;
_i_f fi _t_h_e_n d[2]:= b - d[3];
absh:= h:= abs(d[2]);
_i_f b - xl < 0 _t_h_e_n h:= - h;
int:= abs(b - xl); hmin:= int * e[1] + e[2];
_f_o_r jj:= 2 _s_t_e_p 1 _u_n_t_i_l 2*n _d_o
_b_e_g_i_n hl:= int * e[2*jj-1] + e[2*jj];
_i_f hl < hmin _t_h_e_n hmin:= hl
_e_n_d ;
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l 4*n _d_o ee[jj]:= e[jj]/int;
first:= reject:= _t_r_u_e ;
_i_f fi
_t_h_e_n _b_e_g_i_n last:= _t_r_u_e ; _g_o_t_o step _e_n_d ;
test: absh:= abs(h);
_i_f absh < hmin
_t_h_e_n _b_e_g_i_n h:= _i_f h > 0 _t_h_e_n hmin _e_l_s_e - hmin;
315
absh:= hmin
_e_n_d ;
_i_f h _> b - xl _= h _> 0
_t_h_e_n _b_e_g_i_n d[2]:= h; last:= _t_r_u_e ;
h:= b - xl; absh:= abs(h)
_e_n_d
_e_l_s_e last:= _f_a_l_s_e ;
step: _i_f reject
_t_h_e_n _b_e_g_i_n x:= xl;
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
y[jj]:= yl[jj];
_f_o_r j:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
k0[j]:= fxyj * h
_e_n_d
_e_l_s_e _b_e_g_i_n fhy:= h/hl;
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
k0[jj]:= k5[jj] * fhy
_e_n_d ;
x:= xl + .27639 32022 50021 * h;
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
y[jj]:= yl[jj] + (zl[jj] * .27639 32022 50021 +
k0[jj] * .03819 66011 25011) * h;
_f_o_r j:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o k1[j]:= fxyj * h;
x:= xl + .72360 67977 49979 * h;
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
y[jj]:= yl[jj] + (zl[jj] * .72360 67977 49979 +
k1[jj] * .26180 33988 74989) * h;
_f_o_r j:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o k2[j]:= fxyj * h;
x:= xl + h * .5;
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
y[jj]:= yl[jj] + (zl[jj] * .5 +
k0[jj] * .04687 5 +
k1[jj] * .07982 41558 39840 -
k2[jj] * .00169 91558 39840) * h;
_f_o_r j:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o k4[j]:= fxyj * h;
x:= _i_f last _t_h_e_n b _e_l_s_e xl + h;
_f_o_r jj:= 1 _s_t_e_p 1 _u_n_t_i_l n _d_o
y[jj]:= yl[jj] + (zl[jj] +
k0[jj] * .30901 69943 74947 +
k2[jj] * .19098 30056 25053) * h;
316 APPENDIX B. A SAMPLE ALGOL 60 PROGRAM
a:= read;
_f_o_r k:= 1 _s_t_e_p 1 _u_n_t_i_l 15 _d_o
_b_e_g_i_n ya[k]:= read; za[k]:= read _e_n_d ;
_f_o_r k:= 0 _s_t_e_p 1 _u_n_t_i_l 5 _d_o m[k]:= read;
k2:= read; e[1]:= read;
_f_o_r k:= 2 _s_t_e_p 1 _u_n_t_i_l 60 _d_o e[k]:= e[1];
NLCR; PRINTTEXT(|<JAZ164, R743, Outer Planets|>); NLCR; NLCR;
_f_o_r k:= 1 _s_t_e_p 1 _u_n_t_i_l 15 _d_o
_b_e_g_i_n FLOT(12,ya[k]); FLOT(12,za[k]); NLCR _e_n_d ;
_f_o_r k:= 0 _s_t_e_p 1 _u_n_t_i_l 5 _d_o
_b_e_g_i_n NLCR; FLOT(12,m[k]) _e_n_d ;
NLCR; NLCR; FLOT(12,k2);
318 APPENDIX B. A SAMPLE ALGOL 60 PROGRAM
Here follows the output on the console typewriter during compilation and program loading:
f 00 00 02
A 00 07 25
RK3n 00 11 04
test 00 22 28
step 00 25 13
acc 01 25 21
next 01 27 28
TYP 02 00 02
7 11 0
7 1 15
Appendix C
Below follows a list of all OPCs as documented in [5]. OPC 81, originally in use for
arctan, became obsolete after replacement of the complex routine for it by an MCP using
another algorithm.
19 FOR0
20 FOR1
21 FOR2
22 FOR3
23 FOR4
319
320 APPENDIX C. THE OPC TABLE
24 FOR5
25 FOR6
26 FOR7
27 FOR8
56 IND INDEXER
71 NON NON ¬
72 AND AND ∧
73 OR OR ∨
74 IMP IMPLIES →
75 QVL EQUIVALENT ≡
76 abs
77 sign
78 sqrt
79 sin
80 cos
82 ln
83 exp
84 entier
85 ST STORE
86 STA STORE ALSO
87 STP STORE PROCEDURE VALUE
88 STAP STORE ALSO PROCEDURE VALUE
322 APPENDIX C. THE OPC TABLE
The compact code of the object program in the ALD7 and the load–and–go versions of
the compiler (cf. Chapter 6) is given in two tables. The first one gives the encoding of
OPCs with OPC number at least 8, the second one the encoding of 19 OPC–instruction
combinations.
323
324 APPENDIX D. THE COMPACT CODE
[3] E.W. Dijkstra. A primer of ALGOL 60: report on the algorithmic language
ALGOL 60.
Academic Press, London 1962.
327
328 BIBLIOGRAPHY
[12] J.A.Th.M. van Berckel and B.J. Mailloux. Some ALGOL plotting procedures.
Mathematisch Centrum report MR 73, 1965.