Beruflich Dokumente
Kultur Dokumente
Andrew D Birrell
Acknowledgements
The work described in this dissertation has been supported by
the Science Research Council.
without
the
support
and
encouragement
of
Brenda,
and
of
my
Contents
Section A:
Introduction
1.
The Problem
1.1 Aims and Requirements
1.2 High Level Language Requirements
1.3 System Programming Language Requirements
1.4 The Present Approach
2.
Background
2.1 The Algol68C Project
2.2 The CAP Project
Section B:
1.
2.
3.
Compiler Portability
3.1 Other Intermediate Codes
3.2 Portability in Algol68C
3.3 Summary and Conclusions
Section C:
1.
Runtime System
1.1 The CAP Algol68C Runtime System
2.
3.
The 'Program'
3.1 Program Structure
3.2 Program Environment
Section D:
Appendix X:
Appendix Y:
Appendix Z:
Section A:
Introduction
The Problem
language
system
suitable
for
the
implementation
of
one
to
review
decisions
taken
in
the
design
of
the
languages,
(SPL's)
or
categorized
'Machine
as
Oriented
'System
Programming
Languages'
(MOL's).
generality
of
Pascal or Algol68.
ordinary
general-purpose
languages
such
as
- 1 -
the
resulting
operating system.
language
system
for
manufacturing
an
an
operating
system;
but
the
implementation,
however
of
the
design
that
the
language
system
should
not
programs
can
be
written
in
any
language
we
are
not
When
embarking
on
the
production
of
suitable
language
arise
program.
from
the
normal
requirements
of
non-numerical
but
language
the
system
techniques
are
not
and
facilities
especially
developed
CAP-oriented
- 3 -
for
they
the
have
We
are not much concerned here with faulty programs (although much
of the distinction between a 'good' and a 'bad' implementation of
a language lies in what it will do with a faulty program), but it
must
always
be
borne
in
mind
when
considering
any
topic
in
Such operations
is
involved
in
the
of
taking
single,
- 4 -
particular
bit
or
word
manipulations
allowed
by
his
it
is
sufficient
to
express
the
algorithm
in
such
algorithm.
For
example,
indexing
an
array
is
more
use
the
abstract
facility
without
knowing
how
it
is
- 5 -
in the conversion.
made a mistake in mapping his objects onto the hardware (all such
mistakes
are
centralised
in
the
compiler!);
secondly,
the
Also,
programs
which
are
not
concerned
exclusively
with
There
are
very
few
programs
concerned
with
objects
or
of such general purpose facilities in a suitable manner that section 'B' is concerned.
The language chosen as basis for the project was Algol68 [1].
The particular language chosen is not vitally important; most
general purpose high level languages such as Algol 60, PL/1, or
PASCAL
would
reasonably
be
equally
clean
suitable.
definition,
Any
powerful
language
data
having
structuring
compiler
was
suitable
starting
point.
The
Cambridge
- 7 -
are
many
features
and
facilities
which
are
often
do
not
necessarily
agree
that
these
actually
are
actually
produced
develops.
An
assessment
of
which
general,
the
system
should
provide
model
which
the
and
believe
this
to
be
fundamentally
misguided
is
free
to
decide
whether
or
not
to
use
packed
representations.
Some facility for parallel processing or synchronization is
often requested.
this
is
envisaged
not
appropriate
here.
In
the
for
the
same
style
vein,
of
some
language
mechanism
system
for
the
but
believe
the
library
facilities
for
these
an
complicated
operating
software
preferably
modular)
discussed
extensively
direction,
system
package,
is
some
compilation
below.
language
implementation tool.
- 9 -
form
will
With
system
necessarily
be
of
become
large
separate
required;
sufficient
can
support
a
very
this
in
and
(and
is
this
powerful
Algol68
particularly
suitable
for
an
as
system
architecture
as
programming
unusual
as
the
language,
CAP.
In
been
the
Detailed consideration is
of
the
operating
system,
there
are
situations
where
described, but also some changes which seem desirable but have
not been made - some of these are in the form of problems, to
which the solution is not yet apparent.
The work being described has at most stages in its development
been
required
to
provide
- 10 -
usable
system,
and
where
- 11 -
Background
Algol68C
compiling
system
grew
out
of
small
'Z70',
which
bore
some
to
the
recently
or even
a+(INT i=readint; i*i)
As
such,
its
syntax
and
semantics
were
similar
to
Algol68,
was that Z70 had only two data types ('integer' and 'function'),
whereas Algol68 has an unlimited number, through the use of modes
for describing structured values, for checking argument types in
procedure calls, and for 'united' modes (used for values whose
type varies dynamically at runtime).
Z70
prototype
was
originally
ICL
Atlas
implemented
2),
using
- 12 -
on
the
Titan
computer
syntax-directed
(a
compiler
set
of
language,
production
and
containing
rules
specifying
semantic
PSYCO is driven
the
rules
syntax
causing
of
the
output
of
itself
diagnostics
was
and
modified,
error
mainly
recovery.
By
to
produce
the
middle
intelligible
of
1972,
the
though
FORTRAN).
this
description
could
also
be
applied
to
were as follows.
in
several
ways.
Major
- 13 -
omissions
were:
some
of
the
arrays);
user-defined
operators;
the
Algol68
input-output
described
later).
'Z70'
was
now
renamed
'Algol68C',
and
any
global
optimisation).
Its
prospective
uses
were
written
in
Z70,
and
because
the
authors
had
found
available
through
the
existing
compiler.
The
system
By a minor restriction on
parse
tree
as
an
internal
data
structure,
the
called the 'parser', reads the source program, performs modeindependent parsing and links applied occurrences of identifiers
to
the
corresponding
equivalencing'
definitions.
(determining
which
Phase
textual
two
performs
'mode
representations
of
it scans the parse tree (as modified by phase two) and outputs
the intermediate code.
- 15 -
later.
For
each
machine
'translator'
was
to
be
keeping
independent
the
as
source
text
possible,
of
the
portability
compiler
would
be
as
machine-
achieved
by
work on phase two and the code for the Algol68C separate compilation mechanism.
At this
In
late
September
1973,
the
compiler
successfully
compiled itself on Titan; one week later, the Titan computer was
finally closed down.
- 16 -
intended
to
transfer
the
system
to
their
ICL4130.
The
error
recovery,
removing
dependencies,
and
the
end
of
1974,
S.R.Bourne
left
the
project,
and
the
the
IBM370
compiler.
During
1975
developed
Zcode
investigating
protection
techniques
and
their
Secondly,
execution
moves
'protected procedures'.
among
protection
domains
Within a
known
as
No operation, be it executing an
- 18 -
It is a design
'supervisor
state';
protected
procedures
which
one
would
It should be immediately
any
general
concerned
with
purpose
computer,
capabilities
and
the
the
CAP
has
protection
instructions
architecture.
There are:
MOVECAP
to move a capability
REFINE
SEGINF
INDINF
ENTER
is
specified
- 19 -
by
given
capability.
On
return
from
that
domain,
control
resumes
interpretively
using
cross-compilation
of
mini-computer.
BCPL
and
During
this
were
made
Algol68C
programs
were
written.
When
the
hardware
became
suitably
and
BCPL
updated.
were
made
In
due
course,
available
under
compilation
OS6,
of
compiling
system proper.
The
details
of
the
operating
system
which
has
been
The system
- 20 -
only
one
protected
procedure,
which
is
known
as
the
'co-
protected
protected
procedure
procedures
unique
shared
to
between
the
the
process,
and
processes,
several
providing
as
protected
procedures
entered
from
the
command
program.
At an early stage in considering the design of the operating
system, the decision was taken that the system should not be a
single program in the language sense.
In
know
nothing
about
the
- 21 -
internal
working
of
another
procedure
this
is
most
readily
fulfilled
by treating
each
independent
manner,
since
the
calling
and
called
The compiler
ordinary
user
object
programs.
Some
exercise
enormous
to
resident
real
store;
some
perform
explicit
I/O
procedures.
to
be
Interfacing
written
in
other
with
protected
languages
can
procedures
present
great
Note that
as
complicated
as
Algol68,
this
requires
the
most
is
still
under
way,
and
systems
under
different
I believe
- 23 -
Section B:
before,
or
because
they
have
not
been
viewed
in
some
It accepts
- 24 -
Linking between
separately
compiled
program-segments
is
determined
at
compile
The
as
if
it
were
an
Algol68C
program-segment.
The
source
programsegment
'X'
compiler on
'A'
Zcode of other
program-segments
Zcode
of 'X'
translator
for 'B'
executable
program
environment files to be
read by sub-segments of
'X'
any
of
the
algorithms
or
interfaces:
elsewhere [10,20].
- 25 -
these
are
described
2.1 Requirements
Separate
compilation
programming languages.
mechanisms
can
be
found
in
many
time
later,
some
source
text
'B'
is
presented
to
the
This is an argu-
if
we
wrote
faster,
cheaper
compilers
then
- 26 -
the
(This
If computers were
compilation
allows
the
source
program
to
be
programs
(and
such
programs,
unfortunately,
exist),
problems.
Further,
boundaries
having
independent
debugging
if
well-defined
may
be
source
is
interfaces,
possible
(and
segmented
some
along
amount
of
well-defining
the
library, 'A'.
the programs A+B and A+C could merely share the source text 'A' separate compilation has just allowed this sharing to occur at
some lower level (eg. assembly code). At first sight, then, this
- 27 -
consequences:
with
care
on
the
part
of
the
computer.
That
is,
it
may
be
possible (particularly
in
facilities
large
are
available,
they
can
produce
savings
in
mechanism.
We
will
see
later
how
this
aspect
of
earlier
compilation
('A'
above)
is
be
to
pass
on
the
source
used
as
input
to
A degenerate form of
text
of
'A',
but
most
It is
systems
do
so.
Perhaps
one
of
the
reasons
for
the
He
means
of
checking
this
this
requires,
information
usually,
later,
checking.
or
run
is
obscure bugs.
time
'X'
available
load
when
time
source of many
so
many
extra
statements
(such
as
FORTRAN
COMMON
in
We
the
will
source,
see
can
below
be
that
used
to
separate
improve
the
compilation,
error
even
- 29 -
Algol68
implementations
have
different
separate
defend,
but
also
criticise,
the
Algol68C
mechanism.
To
#b#
#d#
- 30 -
and:
The semantics
- 31 -
only
special
statement
is
the
'USING'
directive,
which
in
'environment
'ENVIRON's
is
files'.
compiled,
in
When
addition
associated
with
one
of
program-segment
to
the
Zcode
When subsequently a
these
'ENVIRON's
is
- 32 -
'Z'
Note that steps (2) and (3) could be in either order, or even
simultaneous.
The
Zcode
files
and
may
each
contain
In order to
allow resolution of references from subsequently compiled segments to this one, the translator outputs a 'linking file' if the
current
segment
contains
any
'ENVIRON's,
and
this
is
The
only
references
from
this
segment
to
the
subsequent ones are jumps to the entry points, which are resolved
by the translator allocating the machine segment numbers at which
the subsequent segments will be placed.
assembly
of
physically
sharable
segments,
very
powerful
facility which is used for the runtime system and for code shared
between
programs.
This
segmentation,
in
the
virtual
memory
words,
it
relies
on
the
compilation
of
construct
unit
include
the
destination
of
an
assignment
and
the
The
unit
is
identifiers
inside
inside
a
the
routine;
unit
may
here,
applied
affect
the
occurrences
'scope'
of
of
the
- 34 -
affect
the
environment
necessary
for
the
routine.
(In
an
This difficulty
is
its
simplicity.
Because
we
treat
separate
No extra
the
achieving
our
Algol68C
primary
mechanism
aim
of
is
highly
splitting
- 35 -
satisfactory
large
program
in
into
with
no
serious
constraints.
If
we
consider
our
program A
program B
Q
or
user
user
- 36 -
occurrences
in
can
identify
definitions
in
when
one
occurred.
without
being
informed
that
this
shielding
has
one
required
by
could
still
shield
the
second.
Thus
standard
the
prelude
facilities
we
definitions
desire
for
mechanism
that
follows
the
identification
rules
of
user
- 37 -
This
differs
fundamentally
from
block
structure,
but
is
an
present
implementation
of
the
Algol68C
separate
simultaneously).
This
constraint
comes
from
quite
- 38 -
BEGIN #A#
INT max = readint;
MODE V = [l : max] INT;
OP + = (INT i, j) INT:.....;
BEGIN
INT max = 7;
ENVIRON b ; ENVIRON c
END
END
------------------------------------------BEGIN #B#
print (max + 3)
END
BEGIN #C#
V w;
FOR i TO UPB w
DO w[i] := readint OD;
print (w)
END
'V'.
If
we
require
complete
freedom
in
the
order
of
requires
'interface
file'
attempting [22].
from
be
other
segments,
provided.
This,
or
some
that
separate
implementors
are
such
freedom
in
the
order
of
compilation
- 39 -
will
If we assume
only
linking
loader
as
provided
on
conventional
operating
The
general
solution
is
to
accessing definitions of A.
have
an
indirection
vector
for
Experience
have
not
changed.
What
believe
to
be
highly
achieved
than
complete
freedom.
There
are
several
techniques which can help here - only the first has so far been
used in Algol68C.
The first, and most obvious way of reducing the amount of
re-compilation needed is to arrange that if the changes made to A
are such that they do not affect the 'meaning' of B and C, then
the interface (as specified by the environment file produced when
- 40 -
compiling
A)
does
perfection here.
not
change.
It
is
difficult
to
achieve
Adding or
in Algol68C.
If the compiler reads the old environment file when compiling
'A', then with only a little additional complexity we could do
much
better.
Since
it
would
then
know
the
stack
and
label
the
original
ones,
rather
than
shuffling
them.
It
is
can
be
further
reduced
- 41 -
if
we
add
For example:
to
the
INT a,b,c;
HIDE (b,c) ENVIRON B;
Here only 'a' could be identified from inside the 'ENVIRON', so
changes to the definitions of 'b' and 'c' should not entail
re-compilation of sub-segments.
It
is
completely
thus
possible
eliminate,
to
considerably
re-compilation
without
reduce,
but
not
including in
the
Note that
- 42 -
the
most
versatile
and
successful
separate
The
this
system
is
ideal
(if
the
language
were
In
not
gathered
from
subprogram
about
some
other
vent this checking being performed at load time, but very few
implementations perform it at all, even at run time.
- 43 -
(The Titan
(It is interesting, in
Here, information is
- 44 -
acyclic
directed
prelude.
graph
having
single
origin,
the
standard
For example:
seg 1
BEGIN
PROC f = (INT i)INT:i*i:
SKIP
END
KEEP f
FINISH
|
|
|
|
|
|
|
seg 2
BEGIN
PROC g = (INT j)INT:-j;
SKIP
END
KEEP g
FINISH
seg 1
seg 2
seg 3
The restrictions imposed by this mechanism are similar to
Algol68C:
each
segment
must
be
compiled
after
any
segment
to
those
for
Algol68C.
However,
since
their
segment
(such as 'seg 1' and 'seg 2' above); this is thus a much more
powerful library system than Algol68C allows, and is the major
advantage of the Algol68R system.
set
of
segments
in
an
Algol68R
program
does
not
correspond
independently
compiled
library
segments),
Algol68R
has
to
The
we
found
lacking
in
the
present
Algol68C
system.
In
The freedom in
the order of compilation is there achieved by prefacing each segment with a list of the definitions which that segment requires
from other segments. Inevitably, a specialized linking loader is
required to perform the final parts of type-checking. Again, the
overall flow of control between segments is described separately.
Although
Algol68R
and
Berlin
provide
facility
sorely
ways.
semantic
rules.
Secondly,
there
are
facilities
This can
i
# very large number of cases #
37 # (.....),
38 # (.....),
those
units
of
the
which
we
wished
to
compile
separately into routines, then call them from inside the CASE.
Although this would achieve the desired effect, it would disturb
the desired structure of the program. An example more difficult
to resolve by any scheme other than the Algol68C one occurs as
- 47 -
follows:
BEGIN.
.
.
PROC a = (ARG g) RES:
BEGIN
PROC b = (ARG h) RES:
BEGIN.
.
...p:= g;....;
.
CASE i
IN...., b(x),.......a(y),....
ESAC
.
.
END;
.
.
END;
a(z)
END
A little explanation is required, although the structure of the
program is really quite simple.
'a' in a non-trivial manner - not only does 'b' call both 'a' and
'b' recursively, but also 'b' contains applied occurrences of
definitions
local
to
an
activation
of
'a'.
No
scheme
yet
of
text).
In
Algol68C
this
separate
compilation
is
- 48 -
definitions.
have
seen
above
how
distinct
approaches
to
separate
eliminated,
and
advantages of both.
it,
are
the
sub-committee
previous
and
single
be
produced
having
the
subject
of
scheme
IFIP
of
WG2.1;
current
ones
continuing
the
investigation
scheme
produced
depends
by
by
heavily
on
members
of
that
objection
to
the
Algol68C
scheme
is
that
there
are
These we can
objection
that
the
meaning
of
the
complete
program
Such a
[24].
Definition
modules
- 49 -
are
similar,
in
the
facilities
provided,
'clusters' [26].
to
Simula
'classes'
[25]
or
to
CLU
For example:
This
GAP,
applied
then
the
occurrences
postlude
inside
of
STACK
the
is
module
executed.
identify
Non-local
definitions
of
the
invocation,
we
know
- 50 -
the
static
offsets
In the
for
the
definitions
made
available
by
the
module.
The
environment
Thus:
static
chain
header for
current
routine
outer block
static
frame
header
for
module
static
frame for
invocation
current display
pointer
Assuming the existence of such a language feature, we can
achieve a separate compilation facility allowing libraries by
allowing
separate
compilation
of
definition
modules.
For
example:
1)
2)
3)
4)
USING '.libs.std'
INSIDE p,q BEGIN
.
.
END
This
would
correspond
to
our
desired
libraries:
- 51 -
structure
for
allowing
std
user
Segment (1)
The meaning of
This
libraries,
but
achieves
there
are
independent
still
compilation
problems.
The
of
first
the
two
of
the
Thus:
- 52 -
1)
BEGIN.
.
ENVIRON '.libs.std'
END
2)
3)
4)
USING '.libs.std'
INSIDE '.libs.p', '.libs.q' BEGIN.
.
.
END
This
would
allow
pre-compilation
of
an
arbitrary
number
of
libraries.
One question remaining about definition modules is, if, in a
program, there is more than one invocation of the same module,
then under what circumstances are the invocations shared?
That
For
stack - this we term 'unshared'; this is similar to the arrangements for SIMULA classes. The second extreme would be to always
share - this we term 'dynamic sharing', since we can determine
whether sharing occurs only at run-time; this corresponds to
FORTRAN
COMMON
storage
the
storage
for
module
can
be
block
compile-time.
(or
invocation);
this
can
be
determined
at
- 53 -
un-structured
whether
we
get
new
invocation
depends
on
- 54 -
Compiler Portability
The major purpose of any high level language is to allow the
programmer
to
express
his
algorithm
in
terms
of
objects
and
hardware
(such
as
converting
source
program
into
In
machine
on
which
the
compiler
is
running
(the
'source'
machine).
Any necessary dependence on the source machine is concerned with
how the compiler reads the source program; the most common such
dependence is the character code, but it may also be encountered
in other aspects, such as system dependent file titles.
The
compiler
may
make
the
introduction
- 55 -
of
such
dependencies
desirable).
Now
consider
programmer
wishing
to
write
an
operating
So,
initially,
the
compiler
must
run
on
'B'
(but
as
have
used
this
approach.
To
enable
the
compiler
to
produce code for more than one machine, the compiler can be
arranged in two parts.
- 56 -
is
program
(or
machine
independent;
program-segment),
it
reads
performs
the
some
source
work
on
of
the
it,
and
produces
machine
code
for
the
appropriate
machine.
To
produce machine code for some new machine, only the second part
of
the
compiler
need
be
changed.
The
Algol68C
compiler
is
look
at
how
other
bootstrapping
compilers
approach
the
problems.
distinguishing
feature
of
such
systems
is
The
their
portability
'choice'
of
and
code,
efficiency
in
of
practice,
the
compiler
means
depend.
designing
The
code
have
met
with
little
- 57 -
success.
Using
common
advantage,
apparently
common
for
two
codes
reasons.
have
Unfortunately, despite
won
Firstly,
little
however
acceptance,
general
an
That is,
(This
problem
is
similar
to
that
found
with
with
Algol68.)
ALGOL60
in
mind
is
likely
to
be
hopeless
for
the implementer will usually want extra facilities for which the
code
does
not
allow,
such
as
program
segmentation
in
some
aids
or
storage
maps.
The
second
(and,
perhaps,
- 58 -
means
requires
further
discussion).
Breaking
In
In preliminary
Zcode versions, there was no general store-to-store copy instruction, so, for example, to copy an object of mode STRUCT(INT
a,b,c,d,e) we would generate five 'load register; store register'
pairs of instructions. Since many machines (such as IBM360) allow
store-to-store copy ('MVC' instruction), we were preventing the
Zcode translator from recognising that 'MVC' was appropriate (unless the
translator
together
into
the
were
to
original
build
our
single
ten
instructions
operation).
This
back
is
particular example of the choice of how 'low-level' or 'highlevel' the code should be, that is, how close to the computer
hardware the operations should be.
machine
code.
Alternatively,
producing
high
level
this dilemma.
It takes
'static
stack'
is
allocated
within
procedure
by
the
program,
directly
which
is
addressable.
'pure'
For
(ie.
execute-only),
computers
- 60 -
having
is
assumed
restricted
appropriate
addressability.
The
Zcode
of
program
procedure-call
instruction
form
full
calling
mechanism.
Whereas Algol68C has an infinity of data types, Zcode has
only a small number (such as integer, real, character, address,
union flag), corresponding fairly closely to the types commonly
found in computer hardware; several Zcode types may map on to a
single hardware type (for example, integer and character may not
be distinguished on many computers).
only
concerned
STRUCT(REAL
objects;
re,im)
REF[]INT,
with
fairly
produces
whose
simple
Zcode
objects.
handling
representation
is
For
example,
pair
of
'real'
'descriptor'
is
of
the
compiler
has
three
tasks
to
perform:
register
- 61 -
as
possible
to
the
hardware
of
the
target
computer.
The
intention,
codes,
each
Zcode
is,
differing
in
in
fact,
the
family
number
of
of
intermediate
registers,
their
to
compile
code
for
two
computers,
'A'
and
'B'.
machine
independent
code
translator
'A'
code for
'A'
source
machine
independent
section
machine
independent
code
translator
'B'
code for
'B'
In
source
the
Algol68C
system,
the
machine
independent
part
of
the
- 62 -
source
machine
independent
section
Zcode for
machine 'A'
translator
'A'
code for
'A'
Zcode for
'B'
translator
'B'
code for
'B'
initialisation
file 'A'
source
machine
independent
initialisation
file 'B'
hardware;
hardwares
consequently,
identical
or
in
'similar'
translators
algorithms
for
will
'similar'
appear
(for
such
algorithms
into
the
machine
independent
part
by
- 63 -
in
Zcode,
make
some
assumptions
about
the
basic
as
machine
the
parameterisation
dependent
becomes
initialisation
more
data
sophisticated,
will
become
the
more
writing
the
translator;
the
initialisation
data
would
3.2.1 Storage
Storage in Zcode is either program or data.
Program storage
dependent
transformations
by
the
To ease
translator,
Zcode
values:
the
activation
record
for
each
frame,
store
A third
can
separate
it
into,
say,
separate
hardware
- 65 -
in
an
environment
file
[B2.2]),
with
an
argument
Static stack is
As mentioned above,
Zcode contains a small number of data types (in the current version, precisely: address, integer, real, character, union flag).
- 66 -
by
the
descriptor
of
the
rowof
rather
than
its
The
at
least
the
return
link,
static
chain
and
dynamic
The
only desirable facilities that it does not allow for are such
things as aligning an object at a given offset from a multiple
(eg. at one byte beyond a multiple of four bytes, which would be
the alignment required for addresses considered as 3-byte objects
on
some
computers)
or
using
spare
bits
inside
value.
In
improvement.
3.2.2 Registers
Zcode
represents
instructions
operate
a
on
register
machine,
'registers'.
in
Registers
that
some
differ
from
be
placed
in
constraints).
any
They
of
are
it,
subject
intended
to
to
map
size
and
directly
alignment
into
the
this
seems
more
convenient.
Zcode
'registers'
can
be
them
to
closely
resemble
(some
of)
the
target
machine
registers.
There are two classes of Zcode registers: system registers
and work registers.
they are:
0 - constant integer 0
1 - constant integer 1
4 - 'dynamic stack management register' (DSMR)
5 - base of current stack frame
- 68 -
Zcode
work
registers
are
where
most
operations
take
place, and where results are left (eg. on exit from a call, or
from each branch of a conditional).
The
compiler treats registers as a form of cache for the main store whenever there is a value in a register, a corresponding store
address is available, although the value may never in fact be
written to store.
an advance
is
that
to
produce
better
What I am claiming
register
allocation
The fact
does
not
affect
the
gains
which
our
approach
could
produce.
This register parameterisation is clearly not adequate.
It
of
following.
some
other
translating
Zcode.
Such
features
include
the
be
not
in
use
(eg.
even-odd
pairs
of
of
the
registers.
Another
fairly
common
particular
registers
(eg.
IBM360
multiply
(again!),
or
many
dynamically
map
Zcode
register
onto
varying
hardware
registers (the Zcode 'R' and 'K' directives make this reasonably
straightforward).
technique
is
used
in
conjunction
with
specification
of
major
problem
to
be
surmounted
in
our
register
no
registers,
that
is
'stack
machines'.
For
such
Although we could
3.2.3 Operations
One
of
the
problems
inherent
in
generating
low
level
for
single
language
operation,
we
are
removing
hardware
suitable.
is
such
that
our
low
level
operations
are
not
are upon only the basic Zcode data types, so that if the target
computer
has,
for
example,
hardware
to
manipulate
array
advantage
of
such
hardware.
This
constraint
is
as
The
In view of the
(But we must
some
intermediate
decision
code
as
operates,
to
the
we
data
should
types
on
clearly
which
the
have
one
tion, we should only break it into simpler operations to the extent that is required to express it in terms of the intermediate
code's data types.
is
unnecessary,
translator.
may
cause
unnecessary
trouble
to
the
of the form:
LOAD
SDIV
r
r
b
a
#register:=b#
#store:=store/register#
r
r
r
a
b
a
#register:=register/b#
- 73 -
preferable
(in
order
to
simplify
the
translator).
If
we
translator
can
do
the
conversion,
but
this
has
two
sequences
to
generate.
In
particular,
for
each
Zcode
'CASE'
and
instruction,
the
store-to-store
copy
instruction),
the
Zcode
generator
takes
language
operations
and
- 74 -
descriptors).
One
approach
to
this
would
be to use similar
not exploit these techniques very much: the main reason is that,
since
effort
it
does
has
sequences.
not
been
yet
support
expended
the
in
complete
allowing
language,
selection
of
little
code
the parse tree (and perhaps of some auxiliary data); low level
codes
attempt
computer.
to
resemble
the
architecture
of
the
target
- 75 -
the
ease
of
translation
of
low
level
codes.
This
stack operations (like OCODE or PCODE) instead of register operations would be more suitable, but there are so many register
machines, and good register allocation is so complicated, and to
such
large
extent
machine
independent,
that
the
gains
of
part
disadvantages.
sufficiently
to
of
the
compiler
seem
to
outweigh
the
onto
most
register
machines
with
little
Work at present in
The
[C2.2]).
None
of
the
implementers
who
have
transferred the system to the various target machines has had any
complaints about the parameterisation of storage allocation, and
none
has
wanted
lower
level
Zcode
types;
there
are
few
computers (MU5, Texas ASC) for which higher level types would be
a convenience (in that they would allow production of better
machine code), but it seems likely that the lower level types
would
still
computers,
be
the
used
for
higher
initial
level
bootstrapping
types
being
on
to
introduced
such
as
subsequent optimisation.
The
compiler
has
shown
itself
in
practice
to
be
highly
been
series,
transferred
to
IBM360
and
370
to
PDP11/45,
to
system
purposes.
thus
appears
to
be
sufficiently
portable
for
our
The work
- 78 -
Section C:
We
have
arranged,
and
seen
in
facilities
added,
sections
how
mechanisms
which
would
be
of
use
were
in
the
language.
Features
such
as
separate
compilation
and
As
expressed
in
abstract
terms,
and
using
the
concepts
and
These opera-
- 79 -
initiating
an
I/O
programs to express.
transfer)
which
our
language
must
allow
One easy
That
We will
We may
An alterna-
- 80 -
language
system
which
solved
all
three
of
the
above
Not only
I am not aware of
any existing system which has solved all these problems, but we
will see below that the solutions do not appear to be impossible.
- 81 -
1. Run-time System
An implementation of a general purpose high level language
normally includes a run-time system.
Such run-time
inevitably
programs
to
written
routines
in
in
the
machine
run-time
They are
code,
and
linking
of
system
is
achieved
by
numbers,
compiler.
All
or
code
even
entry
produced
addresses
by
such
are
built
compiler
into
the
assumes
the
on
language,
being
for
able
to
otherwise
write
we
the
have
only
run-time
system
postponed
the
in
the
problem;
writing the machine code run-time system has all the pitfalls we
are trying to avoid by use of a high level language.
even
the
excuse
that
there
is
only
- 82 -
one
run-time
Note that
system
and
run-time system is likely to be subject to considerable modification as the operating system develops.
In particular,
for
would
several
parts
of
the
operating
system
it
be
most
A second difficulty
(such
as
when
called
from
another
language,
or
Although I will
- 83 -
The units of
parallel
clause
correspond
fairly
closely
to
'asynchronous
in
concurrent
PASCAL
[28],
and
to
some
features
of
This is
because its implementation requires, in effect, a process coordinator to be available and to be called implicitly by the
compiled code.
The objection
such
high
level
facilities
As a word of warning,
have
place
in
some
in
language
for
writing
operating
systems
- 84 -
the
run-time
system
being
correspondingly
complicated.
system'
in
our
sense,
since
it
is
merely
set
of
of
our
system
programs
will
be
unlikely
(and
probably
transput is 'formats'.
Although
their
complexity
has
perturbed
many
the
compiler,
routines
are
in
and
not
ordinary
are
some
way
programmers.
- 85 -
treated
programs
specially
written
by
by
the
ordinary
Thus,
once
we
start
considering
the
run-time
system
as
such
as
formats
as
indicating
situations
where
the
ordinary
English.
These
points
are
places
where
the
the
interfaces
inadequate,
then
programmer
would
be
parts
of
the
language,
and
to
add
extra
interfacing
for
Algol68C
incompatible
Algol68C
changes
compiler
is
to
were
rather
the
less
language
considered
than
ideal:
accepted
by
undesirable,
since
the
main
method
was
file),
then
when
code
generating
the
special
only
considers
definitions
of
them
in
separately
used for 'print', it can clearly also be used for calling such
things
as
the
storage
allocation
routines
(and
thence,
for
are
parts
when
we
of
the
try
to
run-time
write
system
them
in
which
our
present
high
level
Examples of
Such
problems
are
discussed
in
later
section
[C2.2].
Apart from register initialisation and handling of entry and
exit
points
techniques
from
the
outlined
program,
above,
the
need
compiler,
have
no
by
using
knowledge
of,
the
or
this view, consists of the user's source plus the source of the
run-time system.
user's
program
[B2.2].
There
call
will
be
certain
constructs
to a routine with
a certain
- 88 -
but
the
user
(particularly
if
he
is
system
As
what
run-time
system
is
desired
if
omitted,
the
environment
file.
The
initial
environment
file
of
the
compiler's
independence
from
the
run-time
pre-compiled
- 89 -
and
shared
between
programs.
system
has
considerably
developed
and
The run-
altered
as
the
all
five.
The
default
environment,
providing
the
full
It is the
necessary,
but
at
present
the
best
can
do
is
try
to
- 90 -
[C3.2].
a
virtual
machine
on
which
compiled
code
are
three
one
defined
by
can
execute.
The
hardware,
two
by
software)
the
Register 11
Register 12
Register 14
From the main entry point (word 0 of segment P0), control is then
transferred either to the start of the compiled code, or as if
exiting from the 'return' co-routine (described later [C3.1]).
instruction
in
which
[A2.2],
case
MC
or
the
preserves
- 91 -
'return'
enough
co-routine
information
is
(ie.
of
at
heap
present
and
MC
dynamic
contains
stack
the
routines
storage.
It
for
would
be
the
environment
technique
described
files
rather
above.
This
than
using
the
undesirable
identifier
situation
could
The remainder of
operations
or
objects
not
available
in
Algol68,
'CODE'
'MCENV',
environment
which
contains
corresponds
only
the
to
program
the
segment
entry
and
MC.
This
exit
label
which
require
no
interaction
with
the
operating
tion and comparisons, and facilities such as the fast MOVE order
for bulk data transfers.
will
be
concerned.
This
is,
of
course,
the
capability.
changes
capabilities
such
as
[app.Z.1],
have
the
been
proposed
following
for
facilities
handling
have
been
provided.
A new Algol68 mode, called SLOT has been defined.
represented
in
Zcode
and
machine
code
as
the
This is
address
of
capability. Note that SLOT cannot be of the form REF CAP, since
de-referencing would have to cause a capability to be brought
into ordinary store, which the hardware does not allow.
SLOT
ordinary
storage
with
no
special
care.
However,
various
in
corresponding
workspace
SLOT
value)
capability
and
to
segment
(yielding
the
explicitly
relinquish
such
argument
to
his
protected
procedure,
or
linked
in
when
his
This, again, is a
segment.
This,
albeit
imperfect,
solution
has
possible
entry
to
the
co-ordinator.
These
entries
are
It contains
- 94 -
subroutines
the
user
does
not
need
to
know
the
is
implemented
by
various
pieces
of
relatively
elsewhere.
Other
facilities
implemented
in
of
these
are
for
handling
faults
USE
The most
(traps),
are
and
As mentioned
error'
events
or
happen.
'attention
The
MIN
routine'
and
SER
respectively)
segments
assign
when
to
these
'run-time
this
is
the
most
appropriate
default
for
users
of
those
replaced
by
new
ones
by
- 95 -
further
to
these
variables.
of
the
operating
system),
and
then
'backtrace'
Producing
this backtrace involves another example of the use of an extralingual data object, namely one which gives access to information
in
the
activation
records
of
the
recursive
stack
frames.
to
routines.
provide
package
of
floating
point
mathematical
sign-and-modulus
truncation
of
two's-complement
mantissa,
excess
7-bit
bits)
to
mantissa, 8-bit
base-16
the
base-2
exponent
CAP
(with
exponent
and
and
24-bit
unbiased
collector.
This
is
reflection
- 96 -
of
the
absence
of
However, it would
The
routine
(which
should
be
in
MIN
rather
than
MC).
To
also needs marker bits, which on the CAP would probably have to
be a bit map, and needs a subroutine which, given an address,
would indicate the corresponding bit.
The
situation
is
complicated
slightly
by
the
current
protected
procedure,
objects
obtained
from
other
assertion
must
be
satisfied,
because
external
protected
- 97 -
the
run-time
system
as
far
as
possible
in
the
run-time
system
has
provided
great
flexibility,
including provision of differing systems, and ease of modification - sometimes by those writing the operating system, with no
knowledge of the compiler.
explicit
machine
instructions,
and
provides
sufficient
very
few
parts
of
the
operating
system
(mainly
the
The
- 98 -
our
language,
system
is
typically
an
ordinary,
Algol68,
but
general
purpose
we
now
must
high
level
consider
those
In a typeless language,
This
has
been
picturesquely
problem.
- 99 -
termed
the
'white
store'
as
'integer'
and
'boolean')
operations
on
them,
and
However,
the
language
and
the
available
constructions.
For
such
techniques
than
are
presently
available
in
the
The contents of
For
It must be
into
some
'run-time
system'.
Other
examples
will
occur even in user programs - all I/O actions, for example, will
reduce to some operation not expressible in the language.
- 100 -
Care
must
be
taken
not
to
over-rate
the
importance
of
debugged
libraries.
Good
solutions
to
the
above
Indeed,
in
generators'.
two
The
ways:
former
considered
free
at
the
allocated,
and
there
'local
is
end
are
generators'
stack-like
of
the
language
block
and
the
in
storage
which
restrictions
'heap
it
is
was
preventing
Other storage
use
user-supplied
allocation
routines,
wanting
to
allow
(Invokation
of
garbage-collector,
apart
from
being
programmer.
Algol68C
[34],
The
but
has
following
not
yet
mechanism
been
was
proposed
implemented,
because
for
of
given cell
in
given
area.
new
form
- 102 -
of
generator
is
object.
The
user's
routine
determines
which
cells
to
to
the
programmer.
This
is
deliberate,
since
from being unreasonable programming practice, would also potentially confuse any garbage-collector it must be forbidden (which
is easy to implement - for example by keeping a bit-map of the
AREA).
elsewhere [35].
Arrangements for relinquishment of storage are less simple,
- 103 -
because
of
the
diversity
of
techniques:
explicit-relinquish, use-counts.
difficulties,
provided
we
garbage-collection,
Garbage-collection presents no
have
prevented
the
user
over-
can
be
seen,
then,
solution
to
the
'white
store'
scheme
all
for
the
segments
CAP,
as
since
the
REF[]INT)
present
is
facility
becoming
(which
increasingly
inadequate.
Many
languages
already
provide
type
extension
- 104 -
Since there
to
our
problem,
we
should
also
be
able
to
define
new
constructors.
Topics such as this bring to mind the various extensible
languages, but in practice these always construct new data types
from
existing
ones,
since
this
is
entirely
sufficient
for
the
recent
developments
in
languages
oriented
to
type
- 105 -
'100'
and
internal
representations
such
as
the
bit
A
To enable the
- 106 -
DEF(C,CLASS)
DEF(A,AS(C,exp))
DEF(P, PROC(C,D,lambda-expression))
APPLY(P,A)
Jorrand also describes definitions of set relations between types
(such as inclusion, cartesian product, complement), and implicit
type
conversions
(coercions,
in
Algol68
terminology)
but,
to
convert
representations.
these
into
operations
on
their
internal
this
transformation
is
straightforward,
with
simple
1-1
- 107 -
expressions
in
Jorrand's
scheme.
Similarly,
circumstances may arise where the Zcode types and operations are
inadequate, and he will have to give machine code specifications
of
them.
Thus,
the
infamous
'code
section'
appears
as
However, if
is
based
not
on
conventional
block
structure,
but
on
and
performing
manipulations
on
the
arguments
using
A cluster
An instance
A cluster
For
with
example,
operations
if
we
have
called
defined
'push'
and
cluster
'pop',
and
called
if
we
is represented as an array and a pointer, then inside the operation 'push', the array and pointer of the particular stack object
given as argument will be available. Thus the cluster might be
defined as follows.
is similar to PASCAL.)
- 109 -
our
suitable.
present
purposes,
the
explicit
REP
of
CLU
is
more
2.3 Conclusions
It is clear that there is a need for some language extensions
along the lines outlined above to enable the programmer to handle
such situations. One must bear in mind in proposing any such
- 110 -
each
requiring
its
own
language
changes.
It
of
such
above.
The
objects
'base
and
operations,
language'
could
along
the
lines
conveniently
be
Zcode),
since
Zcode
(and
the
imbedded
machine
code)
is
Zcode
inconvenient,
has
tool
proved
for
all
be
such
sufficient,
situations.
but
sometimes
more
general
- 112 -
The 'Program'
has
to
be
taken
as
to
how
the
Algol68
the
complete
operating
concept
of
system,
or
single
Having the
protection
distinction
structure.
between
It
operating
would
system
considerably
and
language,
blur
and
the
would
coordinator
to
its
junior
processes),
there
is
no
precise
Note that we
could be convenient for several languages (e.g. CLU), but not for
Algol68.
with
their
explicit interfaces.
was
designed
to
water-tight
encapsulation
and
narrow,
facilitate
enforced
checking
of
aspects
of
expense
of
protected
procedure
entry
and
exit
cannot
be
system.
A
choice
was
available
as
to
how
to
provide
the
stack
former
approach
efficiency,
grounds.
but
seemed
undesirable
desirable
on
on
grounds
protection
and
of
store
structural
exceedingly
careful
to
prevent
caller,
accidentally
or
subject
to
some
external
interlock);
conversely,
the
It thus seemed
an
Algol68
protected
procedure
is
entered,
this
- 115 -
it
was
because
soon
the
found
that
underlying
this
structure
subroutine-like
was
nature
not
of
This
program
in
most
unnatural
style,
and
one
much
less
arrive
at
the
solution,
we
consider
each
protected
The
Initially
- 116 -
control
starts
at
the
beginning
of
the
program.
If
control
The interactive
relationship
protected
between
procedure
and
the
the
'enter'
'return'
routine
routine
in
in
the
calling
the
called
Even
wish
to preserve data or
flow of
convenient
in
avoiding
initialisation code.
the
overhead
of
runtime
system
only 10 instructions.
It was subsequently noted that the form of program obtained
by use of 'return' is remarkably similar to that of programs
which
service
process.
requests
received
as
messages
from
some
other
For example:
BEGIN
.
. #initialise#
.
DO receive message;
CASE request
IN .
. #work#
.
ESAC;
return message(result)
OD
END
Work has been done to develop an architecture to take advantage
of this similarity, where the form of a call is the same to
another process as to another protected procedure in this process
[37].
- 118 -
would
be
to
alter
the
way
in
which
arguments
are
on
which
initialisation
translator,
architecture
the
file
for
specify
of
program
the
all
the
that
target
it
compiles
compiler,
needs
to
will
run.
The
together
with
the
about
the
be
computer.
known
The
environment
file
Apart
from
information
Zcode
the
assumes
properly
that
the
loaded
in
three
-
it
the
stack
is
the
environment
pointer
file
for
registers
responsibility
of
MC,
(4,5,6)
are
MC
the
and
MC,
provided
that
the
environment
with
which
we
are
- 119 -
This
USE,
library.
to
are
merely
particularly
useful
and
commonly
used
specify
different
environment
files
in
place
of
that
The compiler
At present the
Ideally,
A considerable
found.
Given an easing of the suitability constraint, and given a
convenient way of manufacturing environment files (at present an
ill-defined and error-prone task), the compiled code could run in
many
different
environments.
The
environment
file
would,
of
course, contain descriptions of where arguments are to be found these would be in the same form as, in an environment file used
by a separately compiled segment, the descriptions of non-local
identifiers are presented in the current system.
Such a programming system would greatly increase the utility
of a language system; as well as being able to compile programs
in the traditional manner, one could compile code to imbed in
existing machine code environments, or in environments provided
by other languages. There are many major operating systems and
pieces of software written in assembler or low-level languages,
and the ability to include high-level language sections could
greatly ease the problems of their repair and extension.
No work has been done on further investigation in this line.
The two aspects requiring most work would be the description of
the
environment,
and
resolving
the
problems
of
handling
quite readily from the approach adopted throughout the development of the CAP Algol68C system.
- 121 -
Section D:
However,
the system finally produced and now existing has no such language
features (other than 'CODE' sections).
peculiarly
oriented
towards
the
architecture
of
the
of
the
language
system,
working
in
its
favour.
The
to
available, BCPL.
the
alternative
high
level
language
system
that
one
can
readily
write
- 122 -
very
bad
A68
programs,
is
independence
and
system
independence
of
the
compiler
developed,
to
cross-compile
firstly
from
different
In
effect,
the
compiler
has
followed
wherever
the
made
to
the
extent
that
neither
the
nor
the
required
desired,
change
those
the
language expert.
writing
runtime
the
operating
system
without
system
can,
reference
to
if
a
on
an
coordinator.
empty
machine,
and
for
sub-processes
of
the
are
to
be
able
to
write
the
more
intimate
parts
of the
large
and
elaborate
runtime
system
available
to
those
- 124 -
extensions
to
the
separate
As described above,
compilation
mechanism
are
desirable.
The technique of considering the operating system, not as a
single
program,
but
as
set
of
co-operating
programs,
is
design
decisions
imbedded
in,
or
even
pre-empted
by,
remain,
of
course,
unresolved
problems.
Foremost
outside
or
of
the
language
the
hardware.
system,
The
in
terms
Algol68C
of
'CODE'
another
section,
- 125 -
This is
highly
in
desirable
to
promote
integrity
and
security
the
operating system, but has also had the effect that complicated
objects are never passed between programs.
Calling interfaces
effect.
sufficient
Note,
power
for
however,
writing
that
an
any
language
operating
system
system
of
such
as
discussed
above,
to
attempt
to
maximise
the
flexibility
- 126 -
Firstly, it
design
Secondly,
of
by
the
language
judicious
system
design
of
being
the
used
to
write
implementation
of
it.
the
- 127 -
Bibliography
1.
2.
3.
4.
5.
6.
7.
8.
9.
Appendix
Algol68C on CAP
Andrew D. Birrell
compilation. Note that environment files read when compiling the parent
of this segment are also read when compiling this segment. If no USING
directive is found, a default is assumed which gives access to libraries
providing the full facilities described in Chapter 8 of the Manual - see
below.
TITLE {tag}
The tag is verified on the compiler's diagnostic output stream.
ENVOUT {string}
If the segment contains any ENVIRON statements then this string is used to
open the output stream for the environment file. By default the string
'ENVOUT' is used, and a suitable keyword parameter may be supplied on the
command line when invoking the compiler.
XREF
Requests that the compiler produce cross-reference data regarding this
segment, for subsequent processing by the A68XREF program. See also the
'XREFOUT' heading item.
XREFOUT {string}
If the heading item XREF is present, then this string is used to open the
output stream for the cross-reference data. By default the string 'XREF'
is used, and a suitable keyword parameter may be supplied on the command
line when invoking the compiler.
ZCODE {string}
This string is used to open the output stream for the intermediate code
produced by the compiler. By default the string 'ZCODE' is used. If the
string 'ZCODE' is used, and the keyword ZCODE was not supplied on the
command line when invoking the compiler, then the Zcode is sent to an
anonymous stream, and after the compilation the Zcode translator ('ZCAP')
is automatically invoked. In this case, the translator uses this
anonymous stream as its only input, and has available to it the command
line used to invoke the compiler. See below for description of the action
of the translator.
NAME {string}
This string is passed to the Zcode translator - see below.
TRACE {bits-denotation}
A facility for compiler debugging
KEY {bits-denotation}
- 2 -
Ignored at present
CASESTROP
Selects as 'stropping' convention from this point onwards the convention
that tags are written in lower case letters, with digits allowed, and
indicants are written in upper case letters. This is the default stropping
convention.
QUOTESTROP
Selects as 'stropping' convention from this point onwards the convention
that tags are written in letters of either case, with digits allowed, and
indicants are written in letters of either case, and each indicant must be
preceded by the apostrophe character. Upper and lower case letters are
treated as equivalent.
UPPER
Selects as 'stropping' convention from this point onwards the convention
that tags are written in lower case letters, with digits allowed, and
indicants are written in upper case letters, with digits allowed, and each
indicant may optionally be preceded by a dot.
POINT
Selects as 'stropping' convention from this point onwards the convention
that tags are written in letters of either case, with digits allowed, and
indicants are written in letters of either case, with digits allowed, and
each indicant must be preceded by a dot. Upper and lower case letters are
treated as equivalent.
- 3 -
- 4 -
Further, all these file titles must be identical. This file title is then
used during the present run of the translator for the output of linking
information, and the same file title is opened for input when assembling
the program segments corresponding to such ENVIRON statements.
In addition to standard Zcode, the translator will accept the
directive:
M op ba bm N
0
1
13
16
14
15
2
3
4
5
6
7
10
11
accumulator
0
1
11
14
12
13
2
3
4
5
6
7
8
9
Use
constant 0
constant 1
{system}
local stack
global stack
{system}
work, result
work
work
work
work
work
work
work
- 5 -
- 6 -
- 7 -
INT
INT
INT
INT
INT
the
the
the
the
the
value
value
value
value
value
B1
B2
B3
B4
B5
had
had
had
had
had
on
on
on
on
on
entry
entry
entry
entry
entry
enter access
INT
real arg
REAL
INT
INT
INT
INT
see
see
see
see
manual;
manual;
manual;
manual;
1
1
1
1
int shorths
real shorths
bits shorths
bytes shorths
INT
INT
INT
INT
see
see
see
see
manual;
manual;
manual;
manual;
1
1
1
1
int size
real size
bits size
bool size
char size
bytes size
INT
INT
INT
INT
INT
INT
see
see
see
see
see
see
manual;
manual;
manual;
manual;
manual;
manual;
1
1
1
1
1
1
int align
real align
bits align
bool align
char align
bytes align
INT
INT
INT
INT
INT
INT
see
see
see
see
see
see
manual;
manual;
manual;
manual;
manual;
manual;
0
0
0
0
0
0
maxint
bitswidth
byteswidth
INT
INT
INT
see manual;
see manual;
see manual;
2**31 - 1
32
4
INT
CHAR
CHAR
CHAR
see
see
see
see
255
"*S"
"**"
REPR 0
manual;
manual;
manual;
manual;
- 8 -
or
or
or
or
or
re-entry.
re-entry.
re-entry.
re-entry.
re-entry.
flip
flop
CHAR
CHAR
see manual;
see manual;
"T"
"F"
int width
real width
exp width
INT
INT
INT
see manual;
see manual;
see manual;
10
8
2
ABS16rf0ff00ff
ABS16r0000ff00
ABS16r0f000000
previous error
INT
INT
INT
INT
mathlib error
INT
sysread error
INT
INT
backspace error
INT
INT
reserve error
INT
no digit error
INT
INT
INT
normal error
INT
return
return
return
return
return
INT
INT
INT
INT
INT
correct
warn
soft
hard
fatal
manual;
manual;
manual;
manual;
manual;
0
1
2
3
4
bytespack
packbytes
punstring
=(REF[]INT v)STRING:
a punning operation yielding the
string assumed to be in 'v', whose
stride must be 1
packstring
=(REF[]INT v)INT:
unpackstring
see manual
=(REF[]INT v)STRING:
allocates heap storage and copies the
packed string from 'v' into it
putbyte
char in string
=*
operator
~*
operator
mode
=(INT i)SLOT
=(INT i)SLOT
=(INT i)SLOT
=(INT i)SLOT
=(INT i)SLOT
=(INT i)SLOT
seg addr
n0
n1
n2
null capability
SLOT
SLOT
SLOT
SLOT
maparray
=(SLOT s)REF[]INT:
yields an array with LWB=0 and
in the G
in the A
in the N
in the P
in the I
in the R
N0
N1
N2
G3
- 11 -
=(SLOT s)REF[]INT:
yields an array with LWB=0 and correct
upper bound for the segment currently
described by 's'
mapstring
indinf
seginf
segsize
cseginf
=(SLOT
=(SLOT
=(SLOT
=(SLOT
movecap
movecapa
refine
makeind
s)INT
s)INT
s)INT:
s)INT
=(INT i)VOID
the
the
the
the
result
result
number
result
of
of
of
of
an INDINF order
a SEGINF order
words in 's'
a CSEGINF order
REF PROC(STRING,INT)VOID:
the routine referred to by this
variable is called whenever the library
detects an error, or when an error is
indicated to the program by the system
The STRING argument in such calls is ""
and the INT argument is the fault
number. This variable is initialised
by MIN to cause exit from the program.
allow attention
PROC VOID
enter2
=(INT i)VOID:
return
=(INT i)VOID:
return2
=(INT i,j,k,l)VOID:
as 'return', but 'i' to 'l' are placed
in B2 to B5 before executing the RETURN
order.
stop
label
movestring
moverow
INT
getslot
PROC SLOT
reserve slot
=(INT i)SLOT:
free slot
=(SLOT s)VOID:
SLOT
stack available
PROC REAL
heap available
store available
store used
PROC REAL
PROC REAL
PROC REAL
see
the
see
see
see
INT
cap type
INT
cap access
INT
cap length
INT
hardware bit
INT
enter bit
INT
exec access
read access
write access
rcap access
INT
INT
INT
INT
wcap access
INT
send capability
INT
d16=1; access
d17=1; access
d18=1; access
d20=1; access
capability
d21=1; access
capability
right
right
right
right
in store capability
in store capability
in store capability
'RC' in store
INT
INT
INT
INT
INT
INT
INT
INT
channel access
permission capability
INT
INT
INT
INT
INT
INT
INT
INT
INT
INT
INT
INT
ABS16r0000ffff
- 15 -
lhword
INT
ABS16rffff0000
byte0
byte1
byte2
byte3
INT
INT
INT
INT
ABS16r000000ff
ABS16r0000ff00
ABS16r00ff0000
ABS16rff000000
bit0
.
.
.
bit31
INT
ABS16r00000001
INT
ABS16r80000000
- 16 -
SLOT
SLOT
G1
G2
=(SLOT r)VOID:
=(SLOT s)INT:
PROC VOID
coordinator entry
what it says!
clear fault
PROC VOID
cause fault
=(INT i)VOID:
return fault
=(INT i)VOID:
=(SLOT p)VOID:
create process
=(SLOT p, s)VOID:
commence running a process whose PRL is
's'; permission 'p'
'p'
update prl capability =(SLOT p, INT i,j,k)VOID:
update the PRL capability at offset 'i'
to contain (j,k); permission 'p'
read prl capability =(SLOT p, s, REF INT w,x)INT:
assign into (w,x) the words of the PRL
capability referred to by 's';
permission 'p'
read capability =(SLOT p, s, REF INT w,x)VOID:
read the indirectory-level capability
's', permission 'p'
prlgarb
PROC VOID
claim device
release device
=(SLOT p, s)VOID:
device with pstore 's' no longer needed
by this process; permission 'p'
system crash
setup send
clock
PROC REAL
see manual
- 20 -
SLOT
SLOT
SLOT
SLOT
G4
G5
G6
G7
STRING
job number
REF INT
command line
STRING
command dir
SLOT
command parms
SLOT
current dir
REF SLOT
parms
REF SLOT
machine
PROC BOOL
command
INT
update access
INT
alter access
INT
max access
INT
create access
vmode access
xmode access
ymode access
zmode access
INT
INT
INT
INT
INT
access
access
access
access
access
- 21 -
to
to
to
to
to
directory,
directory,
directory,
directory,
directory,
at
at
at
at
at
d16
d16
d16
d16
d16
modify access
inspect access
link access
INT
INT
INT
swc access
INT
all
all
all
all
INT
INT
INT
INT
access
access
access
access
/RWE, at d16
/CVXYZ, at d16
/MIL, at d16
/s, at d16
INT
INT
INT
INT
INT
matrix
matrix
matrix
matrix
matrix
/ADURW/ARW/RW/R
/ADURE/ARE/RE/RE
/ADCV/ACX/CY/Z
/ADMIL/AMIL/IL/L
/ADUS/AS/S/
unknown
segtype
dirtype
pcbtype
swctype
INT
INT
INT
INT
INT
VMO
VMO
VMO
VMO
VMO
retrieve
remove
preserve
alter
examine
file details
file examine
INT
INT
INT
seg
dir
pcb
swc
default seg
exec seg am
default dir
default pcb
default swc
am
am
am
am
type
type
type
type
type
0
1
2
3
4
=(SLOT s)VOID:
outform
=(SLOT s)VOID:
change size
newseg
capinf
=(SLOT s)INT:
=(SLOT s)INT:
open window
move window
close window
=(SLOT s)VOID:
details
new instance
=(SLOT s)VOID:
INT
INT
stream direction
stream direction
ttr standard
INT
ttr no reflect
stdout state
overprint state
sameline state
newpage state
tr standard
tr binary
tp binary
close option
INT
INT
INT
INT
INT
INT
INT
INT
INT
wrrecord
close stream
=(SLOT s)VOID:
read state
=(SLOT s)INT:
set state
extract doc
insert doc
=(SLOT s, d)INT:
insert document 'd' into stream 's'
lookup idf
MODE
SYSFILE
MODE
=(SYSFILE sf)BOOL:
see manual. Any partially written line
is output. Any argument (even 'SKIP')
is acceptable.
sysendline
=(SYSFILE sf)BOOL:
see manual. For input, the next line
is not physically read from the stream
until the next call of 'sysfileended',
'sysendline', or any routine actually
requiring the line.
sysfileopen
=(SYSFILE sf)BOOL:
whether 'sf' is currently open (i.e.
the call of 'sysopen' yielded 0 and
'sysclose' has not been called for
'sf')
sysfileended
=(SYSFILE sf)BOOL:
see manual
syslineended
=(SYSFILE sf)BOOL:
see manual
sysreadmood
=(SYSFILE sf)BOOL:
see manual
sysmaxpos
=(SYSFILE sf)INT:
see manual
syscharpos
=(SYSFILE sf)INT:
see manual
syssetpos
- 26 -
sysmovepos
syscharsleft
=(SYSFILE sf)INT:
see manual
syslinepos
=(SYSFILE sf)INT:
see manual
syswritechar
sysreadchar
and 'force
see
see
see
see
print
read
TRANSOUT
TRANSIN
see manual
see manual
FILE
mode
see manual
chan
make term
on value error
on char error
see manual
char number
line number
file open
open
close
scratch
newline
endrec
overprint
newpage
- 28 -
space
backspace
readchar
PROC CHAR
readint
PROC INT
see manual
readbool
PROC BOOL
readbits
PROC BITS
see manual
readbytes
PROC BYTES
see manual
readstring
PROC STRING
see manual
printchar
=(CHAR c)VOID:
see manual
printint
=(INT i)VOID:
see manual
printbool
=(BOOL b)VOID:
see manual
bitsradix
REF INT
printbits
=(BITS b)VOID:
hexdigit
[]CHAR
printhex
=(BITS b)VOID:
printbytes
printstring
standout
REF FILE
standin
REF FILE
- 29 -
FILE
error message
(INT i)VOID:
a68c error
backtrace
PROC VOID
a68c attention
PROC VOID
stop
label
- 30 -
REAL
smallreal
REAL
pi
REAL
see manual
PROC REAL
readcompl
PROC COMPL
NUMBER
mode
UNION(INT,REAL)
printfixed
printfloat
printwhole
printreal
=(REAL r)VOID:
printcompl
fixed
float
whole
see manual
=(REAL x)REAL:
exp
=(REAL x)REAL:
ln
=(REAL x)REAL:
sin
=(REAL x)REAL:
see manual
cos
=(REAL x)REAL:
see manual
tan
=(REAL x)REAL:
arcsin
=(REAL x)REAL:
arccos
=(REAL x)REAL:
arctan
=(REAL x)REAL:
see manual
mode
mode
see manual
see manual
get random
=(INT i)RANDOMDATA:
see manual
save random
change random
=(RANDOMDATA r)VOID:
see manual
random
PROC REAL
normal random
=(REAL m,s)REAL:
see manual
see manual
- 32 -
Appendix
Representation of objects.
=>
char =>
real =>
=>
union(...)
=>
(marker, value)
routine
=>
Note that although the ALGOL68 report does not talk of values
of mode union(...), a value which has been united is universally
represented as the value with a small marker indicating its mode.
The 'environment pointer' in a routine is used in addressing
items in blocks outside the routine - this is considered later.
It should be pointed out here that it is possible to achieve
considerable simplification of many of our problems by an
indirection. By representing values of the more complicated
modes by a pointer to data in a global storage area, the whole
stack organization is simplified; this substitutes the problems
- 1 -
1 3
1 4
1 2 3 4
1 2 3
1 2
Additionally, the descriptor contains a stride for each
dimension, to indicate the spacing between elements. For
example, if we have
[,,]int w = (......);
[,]int p = w[,1,];
- 2 -
1 10 100 1 10 10 1 10 1
strides
0
1
w[1,1,1] w[1,1,2]
p[1,1]
p[1,2]
p =
10
11
w[1,2,1] w[1,2,2]
100
101
w[2,1,1] w[2,1,2]
p[2,1]
p[2,2]
1 10 100 1 10 1
strides
1 10 4
1 10
2 11
3 12
elements of 'v'
elements of 'w'
w =
1 10
The stack
b)
values for definitions: for 'int i' the value referred to,
for 'real x = random' the value itself.
c)
d)
array elements
e)
Of these (a), (b) and (c) are straightforward, but (d) and
(e) are difficult since the amount of storage required may be
large and may not be known at compile time.
It is common practice to store (a), (b), (c) at the start of
the frame, with (d) and (e) at the end. This has two advantages:
the offsets written in instructions are smaller (many machines
place severe limitations on such offsets), and we always know the
offsets for identifiers at compile time. We can thus consider
each frame as being divided into a static frame containing (a),
(b), (c), and a dynamic frame (possibly empty) containing (d) and
(e). Further, it is convenient to treat (c) separately as the
SWOST (static working stack) frame, calling the remainder of the
static frame the static idf frame. Similarly, we can sub-divide
the dynamic frame into the DWOST frame containing the dynamic
parts of SWOST objects, and the dynamic idf frame. For example:
begin
int p, q, r, [1:3]ref int s;
for i to 3 do s[i] := loc int od;
.
.
(p,q,r) #row display#
.
.
end
- 5 -
1 3
p q r
1 3
z := ..
w * z ....
store for
w * z
a)
b)
c)
d)
outer
dsmd
middle
block
inner
block
outer display
register
display register
for 'f'
- 8 -
current
dsma
b)
c)
b)
2)
3)
4)
5)
- 9 -
calling
store for static
called routine
static frames heading
argument frame static frames
dynamic
stack
calling
dynamic frames
argument
dynamic frame
called routine
dynamic frames
b)
On exit from any drange, restore the run time dsma to its
previous value.
c)
begin
[1:10]int a;
proc f = (int i)int:
begin
[1:10]int b;
begin
[1:10]int c;
( i <= 1 | 1 | i * f(i-1) )
end
end;
print( f(1) )
end
The stacks after declaring 'c' would be:
outer block
static
stack
middle block
inner block
dynamic
stack
elements
of 'a'
elements
of 'b'
elements
of 'c'
previous a descriptor
current
dsmd
for (1,2,3,4) dsmd
dynamic
stack
previous elements
frames
of 'a'
1 2 3 4
- 11 -
There are basically two possibilities: either copy the value onto
the outer SWOST and DWOST, or delay relinquishing the frames.
However, copying can be very expensive (and sometimes very
difficult), while delaying relinquishment can waste vast amounts
of storage. An extensive analysis of this problem has been given
by Branquart, and an algorithm which assists in copying has been
given by Meertens. It is certainly best to delay the decision as
to whether to copy or to avoid relinquishing, until as late as
possible. At present ALGOL68C does not recover the storage in
this situation - this is hardly satisfactory. With sufficient
care, it is possible to achieve satisfactory results even in
extreme examples such as:
op * = ([]int x,y)[]int: ... ,
+ = ([]int p,q)[]int: ... ;
[1:100]int a,b,c;
l: a * b + ( ... | c | goto l );
In particular, the compiler can treat some constructs as if they
were dranges (though not actually ranges) to aid the recovery of
dynamic stack.
Summary
Acknowledgements
References
- 13 -
Appendix
Program Sharing
CAPABILITIES in ALGOL68C