Operating instructions

Another
high
level
language,
COBOL (Common Business Oriented
Language), was developed for accoun-
tants and the business community
which allowed these professionals to ex-
press their computer programs in
ex-
pressions easily learned by them. The
COBOL compiler
(a
program written in
machine language) took the user's pro-
gram written
in
COBOL and compiled it
into
an
executable machine language
program. Other well known languages
which require compilation are
"C",
FORTH and PASCAL. Compilers have
been or are being developed for the
PET
for the languages
"C",
FORTH and
PASCAL, but to date there has been no
compiler for the full BASIC language.
The following discussion will point out
the usefulness of such a compiler and
tell you when and where one will
be
available.
What is the Difference Between
a Compiler and
an
Interpreter?
The code which a programmer
writes in a higher level language is call-
ed
the source code and the
output
from
the compiler, which processes that
code, is called the object code.
In
the
process of making the conversion a
compiler may have to make several
"passes",
I.e., complete scans through
the source code, so compilers are often
distinguished as being single or multiple
pass compilers. It usually takes a multi-
ple pass compiler longer
to
compile than
a single pass compiler but the multiple
pass compiler might be preferable if, for
example, the object code it generates is
more efficient.
In
any case, once the compiler has
completed
its
task the object code can
be
saved and used over and over again
without recompiling. Interpreters, such
as the BASIC Interpreter found in the
PET
and other popular micro-computers,
do not work in this manner. They take
the user's source program, written in the
higher
level
language
(the BASIC
statements), and analyze (interpret) each
statement one at a
time
to determine
its
equivalent machine code, and then ex-
ecute
this
code. Moreover,
and
this
is
the
chief
drawback
to
interpreters, they
do not save the object code. The next
time that BASIC statement is executed
the machine again has
to
interpret that
line
of
code. For example, if there is a
FOR.
...
NEXT loop in the program
that
contains six statements between the
FOR
and the NEXT and the loop is
to
be
executed 100 times, then each of those
six lines
of
code will
be
interpreted
(translated) into machine language
100
times. This results in a
total
of
600
translations made by the interpreter,
whereas the compiler would have made
only six.
In
both cases, the machine
code is performed
600 times; but in the
interpretation, the analysis represents a
20:10
significant
overhead which is absent in
the compiled version.
Purists may object that this is a
somewhat
simplified
explanation
because, in fact, the interpreter stores
token
(numbers)
for
the
BASIC
keywords, and often jumps to predefin-
ed
specific
runtime routines rather than
assembling new code. However, in prin-
cipal the interpreter works in this man-
ner and for this reason interpreted pro-
grams are
10 to 100 times slower in ex-
ecution
than
compiled
programs.
Another factor which often slows down
an
interpreter is that it must repeatedly
do much error checking that a compiler
does only one time.
The advantage
of
an
interpreter,
however, is that one need not wait for
the compile to take place before execu-
tion.
So
long as high speed in program
execution itself is not needed,
an
inter-
preted program may perform Quite fast
enough; and although there may be
other reasons (some
of
which will
be
described later) that may make compila-
tion desirable, it is apparent that an in-
terpreter will reduce the time required
for program development.
There are advantages
to
an
inter-
preter besides convenience in program-
ming. Source code requires much less
memory than object code. A single con-
cise
BASIC
statement
such
as:
If X =
(Y
•
L)
I M
THEN
R =X +
(M
-
L),
expands through compilation into many
machine language statements. Conse-
Quently a much longer program can
be
written in BASIC and stored in a small
computer that interprets each line and
"throws
away"
the object code im-
mediately after it is used, than in a
machine that has to store all the object
code before execution begins.
Incidentally, there are many high
level languages that are not general pur-
pose programming languages. RPG's
(Report Program Generators), for exam-
ple, are high level languages used to for-
mat reports. There are also many DBM
(Data Base Management) languages
(such as ADABAS, MARK
IV,
etc.) that
are used to access large files of data.
On
the surface these programs appear very
similar
to
the languages processed by
compilers as regards the syntactical
rules they require for input. That is
to
say the user writes a
"program"
for his
application that is in many ways like a
computer program that
he
would write
for a compiler. However, while these
systems
do what they are designed
to
do
very well (Le., access some particular
data base), they are not general purpose
languages and cannot
be
used efficient-
ly for many purposes that a compiled
language can.
MICRO
--
The 6502 Journal
To summarize then, a
compiler
translates
the
source
code
into object
code one time which is then used over
and over again; whereas an interpreter,
such as PET's BASIC,
"throws
away"
the object code after each execution and
then must re-translate again from the
source before an instruction can
be
us-
ed
again. The advantage
of
using an
in-
terpreter is that it takes much less
memory to store a whole program in
source format rather than in object for-
mat, and execution takes place im-
mediately rather than waiting for a com-
plete new re-compile after each program
change. However, among
its
other ad-
vantages, a compiled program can
be
executed at more than ten times the
speed
of
an interpreter and this is often
critical in certain applications.
What is the Difference Between a Direct
Compiler and a P·Code Compiler?
A compiler then, takes the source
language code
of
a particular high level
language and translates it into object
code--that is to say, into the machine
language op-codes. Because a computer
always automatically executes the next
instruction following the one it is
presently executing (unless there is a
branch),
it
is much faster not to have any
branches.
However,
code
written
without branches would usually require
more memory than is available internally
to the computer. Also, it would not take
advantage of the
"conditional"
branch-
ing or decision making power
of
the
computer which is the essence of a pro-
gram.
Consequently,
one
of
the
major
design
decisions
in designing a com-
piler is the trade-off between using
memory-consuming repeating code "in-
line" to save branches and increase
speed, or
making
time-consuming
repeated branching
to
the same sub-
routines in order to conserve memory. A
JSR (Jump-to-Sub-Routine) requires the
computer to save from the
PC
(Program
Counter) the next address
it
would have
executed in sequence, and load instead
in the program counter the address
of
the sub-routine instruction. On
RTS
(Return from Sub-routine) the instruction
address that was originally saved must
then be restored to the
PC.
If there were
only a few
instructions
in
the sub-
routine, there will
be
no saving
of
memory and time will
be
wasted in going
to the sub-routine. The computer instead
simply could have processed the next
couple
of
instructions. However, if the
sub-routine contains many instructions,
memory will
be
saved
by
going there at
the expense of a little
time
for making
the branches. It all depends on the
relative value
of
speed and memory in a
particular system.
A compiler designer soon finds that
January,
1980