explain the basics of using
In examples here we use the text editor
should have little trouble following these examples,
allows us to make clearer examples.\(dg
\(dg Users with \s-2CRT\s0 terminals should find the editor
we do not show its use here because its display oriented nature
makes it difficult to illustrate.
user will find it helpful to read one of the text editor documents
described in section 1.4 before continuing with this section.
we first need to have an account on
to the system on this account.
These procedures are described in the documents
.I "Communicating with UNIX"
Once we are logged in we need to choose a name for our program;
let us call it `first' as this is the first example.
We must also choose a name for the file in which the program will be stored.
system requires that programs reside in files which have names ending with
the sequence `.p' so we will call our file `first.p'.
A sample editing session to create this file would begin:
"first.p" No such file or directory
We didn't expect the file to exist, so the error diagnostic doesn't
The editor now knows the name of the file we are creating.
The `:' prompt indicates that it is ready for command input.
We can add the text for our program using the `append'
The line containing the single `\*b.\fR' character here indicated
the end of the appended text.
The `:' prompt indicates that
is ready for another command.
As the editor operates in a temporary work space we must now store the contents
of this work space in the file `first.p'
"first.p" 4 lines, 59 characters
We wrote out the file from the edit buffer here with the
indicated the number of lines and characters written.
We then quit the editor, and now have a prompt from the shell.\(dd
\(dd Our examples here assume you are using
to translate and execute our program.
The translator first printed a syntax error diagnostic.
The number 2 here indicates that the rest of the line is an image
of the second line of our program.
The translator is saying that it expected to find a `;' before the
If we look at the Pascal syntax charts in the Jensen-Wirth
or at some of the sample programs therein, we will see that
we have omitted the terminating `;' of the
One other thing to notice about the error diagnostic is the letter `e'
indicating that our input was not legal Pascal.
The fact that it is an `e' rather than an `E'
indicates that the translator managed to recover from this error well
enough that generation of code and execution could take place.
Execution is possible whenever no fatal `E' errors
occur during translation.
The other classes of diagnostics are `w' warnings,
which do not necessarily indicate errors in the program,
but point out inconsistencies which are likely to be due to program bugs,
and `s' standard-Pascal violations.\*(dg
\*(dgThe standard Pascal warnings occur only when the associated
translator option is enabled.
option is discussed in sections 5.1 and A.6 below.
Warning diagnostics are discussed at the end of section 3.2,
option is described in section 5.2.
After completing the translation of the program to interpretive code,
the Pascal system indicates that execution of the translated program began.
The output from the execution of the program then appeared.
At program termination, the Pascal runtime system indicated the
number of statements executed, and the amount of cpu time
used, with the resolution of the latter being 1/60'th of a second.
Let us now fix the error in the program and translate it to a permanent
translates Pascal programs but stores the object code instead of executing it\*(dd.
\*(ddThis script indicates some other useful approaches to debugging
we can shorten commands in
to an initial prefix of the command name as we did
We have also used the `!' shell escape command here to execute other
commands with a shell without leaving the editor.
"first.p" 4 lines, 59 characters
"first.p" 4 lines, 60 characters
The first command issued from
involved the use of the `%' character which stands in this command for
made this substitution, and then echoed back the expanded line
before executing the command.
When the command finished, the editor echoed the character `!'
so that we would know it was done.
list files command we can see what files we have:
The file `obj' here contains the Pascal interpreter code.
We can execute this by typing:
Alternatively, the command:
will have the same effect.
Some examples of different ways to execute the program follow.
will assume that `obj' is the file we wish to execute
if we don't tell it otherwise.
The last two translations use the
no-post-mortem option to eliminate
See section 5.2 for more details.
If we now look at the files in our directory we will see:
We can give our object program a name other than `obj' by using the move
Thus to name our program `hello':
Finally we can get rid of the Pascal object code by using the
(1) remove file command, e.g.:
For small programs which are being developed
tends to be more convenient to use than
Except for absence of the
command is equivalent to a
where a number of runs testing different parts of the program are
file can be executed any desired number of times.
Suppose that we have used the editor to put a larger program
We can list this program with line numbers by using the program
This program is similar to program 4.9 on page 30 of the
A number of problems have been introduced into this example for
If we attempt to translate and execute the program using
we get the following response:
Since there were fatal `E' errors in our program,
no code was generated and execution was necessarily suppressed.
One thing which would be useful at this point is a listing of the
program with the error messages.
We can get this by using the command:
There is no point in using
here, since we know there are fatal errors in the program.
This command will produce the output at our terminal.
If we are at a terminal which does not produce a hard copy
we may wish to print this
listing off-line on a line printer\*(dg.
\*(dgAt Berkeley, the line printer for the Cory Hall system is in Room 199B.
The line printers for the Computer Center
systems are in the basement of Evans Hall.
We can do this with the command:
% \*bpi -l bigger.p | lpr\fR
In the next few sections we will illustrate various aspects of the
Pascal system by correcting this program.
Correcting the first errors
Most of the errors which occurred in this program were
errors, those in the format and structure of the program rather than
Syntax errors are flagged by printing the offending line, and then a line
which flags the location at which an error was detected.
The flag line also gives an explanation
stating either a possible cause of the error,
a simple action which can be taken to recover from the error so
as to be able to continue the analysis,
a symbol which was expected at the point of error,
or an indication that the input was `malformed'.
In the last case, the recovery may skip ahead in the input
to a point where analysis of the program can continue.
the first error diagnostic indicates that the translator detected
a comment within a comment.
While this is not considered an error in `standard'
Pascal, it usually corresponds to an error in the program which
In this case, we have accidentally omitted the trailing `*)' of the comment
We can begin an editor session to correct this problem by doing:
"bigger.p" 24 lines, 512 characters
s = 32; (* 32 character width for interval [x, x+1] *)
The second diagnostic, given after line 16,
indicates that the keyword
was expected before the keyword
syntax chart on page 118 of the
is a necessary part of the
Similarly, we could have referred to section C.3 of the
statement and gotten the same information there.
It is often useful to refer to these syntax charts and to the
relevant sections of this book.
We can correct this problem by first scanning for the keyword
in the file and then substituting the keyword
to appear in front of the keyword
for i := 0 to lim do begin
The next error in the program is easy to pinpoint.
On line 18, we didn't hit the shift key and got a `9'
The translator diagnosed that `x9'
was an undefined variable and, later,
that a `)' was missing in the statement.
It should be stressed that
is not suggesting that you should insert a `)' before the `;'.
It is only indicating that making this change will help it to be able to
continue analyzing the program so as to be able to diagnose further
You must then determine the true cause of the error and make the
appropriate correction to the source text.
This error also illustrates the fact that one error in the input may lead
to multiple error diagnostics.
to give only one diagnostic for each error,
but single errors in the input sometimes appear to be more than
may not detect an error when it occurs, but may detect it later in
in this example if we had typed `x' instead of `x9'.
The translator next detected, on line 19, that the function
normally distinguishes between upper- and lower-case.
lower-case is preferred\*(dg,
\*(dgOne good reason for using lower-case is that it is easier to type.
and all keywords and built-in
names are composed of lower-case letters,
just as they are in the Jensen-Wirth
Thus we need to use the function
we can see why it is undefined if we look back to line 9
and note that its definition was lost in the non-terminated
This diagnostic need not, therefore, concern us.
The next error which occurred in the program caused the translator
to insert a `;' before the statement calling
If we examine the program around the point of error we will see
that the actual error is that the keyword
and an associated expression have been omitted here.
Note that the diagnostic from the translator does not indicate the actual
error, and is somewhat misleading.
The translator made the correction which seemed to be most plausible.
As the omission of a `;' character is a common mistake,
the translator chose to indicate this as a possible fix here.
It later detected that the keyword
was missing, but not until it saw the keyword
The combination of these diagnostics indicate to us the true problem.
The final syntactic error message indicates that the translator needed an
at line 24 is supposed to match this
we can infer that another
must have been mismatched, and have matched this
Thus we see that we need an
and to appear before the final
We can make these corrections:
y := exp(-x) * sin(i * x);
the translator summarizes references to undefined variables
and improper usages of variables.
warnings about potential errors.
In our program, the summary errors do not indicate any further problems
is unused is somewhat suspicious.
Examining the program we see that the constant was intended
to be used in the expression which is an argument to
so we can correct this expression, and translate the program.
We have now made a correction for each diagnosed error
y := exp(-x) * sin(c * x);
"bigger.p" 26 lines, 538 characters
It should be noted that the translator suppresses warning
diagnostics for a particular
when it finds severe syntax errors in that part of the source
This is to prevent possibly confusing and
incorrect warning diagnostics from being produced.
Thus these warning diagnostics may not appear in a program with
bad syntax errors until these errors are corrected.
We are now ready to execute our program for the first
We will do so in the next section after giving a listing
of the corrected program for reference purposes.
Executing the second example
We are now ready to execute the second example.
The following output was produced by our first run.
Here the interpreter is presenting us with a runtime error diagnostic.
It detected a `division by zero' at line 17.
Examining line 17, we see that we have written
the statement `x := d / i' instead of `x := d * i'.
We can correct this and rerun the program:
"bigger.p" 26 lines, 538 characters
"bigger.p" 26 lines, 538 characters
This appears to be the output we wanted.
We could now save the output in a file if we wished by using the shell
(1) to see the contents of the file graph.
We can also make a listing of the graph on the line printer without
putting it into a file, e.g.
Note here that the statistics lines came out on our terminal.
The statistics line comes out on the diagnostic output (unit 2.)
There are two ways to get rid of the statistics line.
We can redirect the statistics message to the printer using the
syntax `|\|&' to the shell rather than `|', i.e.:
or we can translate the program with the
option disabled on the command line as we did above.
This will disable all post-mortem dumping including the statistics line,
This option also disables the statement limit which normally guards
against infinite looping.
You should not use it until your program is debugged.
is specified and an error occurs, you will
not get run time diagnostic information to help you
determine what the problem is.
Formatting the program listing
It is possible to use special lines within the source text of a program
to format the program listing.
An empty line (one with no characters on it) corresponds to a
`space' macro in an assembler, leaving a completely blank line
A line containing only a control-l (form-feed) character
will cause a page eject in the listing with the corresponding line number
This corresponds to an `eject' pseudo-instruction.
See also section 5.2 for details on the
An execution profile consists of a structured listing of (all or part of)
a program with information about the number of times each statement in
the program was executed for a particular run of the program.
These profiles can be used for several purposes.
In a program which was abnormally terminated due to excessive looping
or recursion or by a program fault, the counts can facilitate location
Zero counts mark portions of the program which were not executed;
during the early debugging stages they should prompt new test data or
a re-examination of the program logic.
The profile is perhaps most valuable, however, in drawing
attention to the (typically small)
portions of the program that dominate execution time.
This information can be used for source level optimization.
A prime number is a number which is divisible only by itself and the
written by Niklaus Wirth,
determines the first few prime numbers.
In translating the program we have specified the
This option causes the translator to generate counters and count instructions
sufficient in number to determine the number of times each statement in the
program was executed.\*(dg
are completely accurate only in the absence of runtime errors and nonlocal
This is not generally a problem, however, as in structured programs
statements occur infrequently,
and counts are incorrect after abnormal termination only when the
described below to get a count passes a suspended call point.
When execution of the program completes, either normally or abnormally,
this count data is written to the file
in the current directory.\*(dd
the monitor file produced by the profiling facility of the C compiler
(1) for a discussion of the C compiler profiling facilities.
It is then possible to prepare an execution profile by giving
the name of the file associated with this data, as was done in the following
% \*bpix -l -z primes.p\fR
The header lines of the outputs of
in this example indicate the version of the translator and execution
profiler in use at the time this example was prepared.
The time given with the file name (also on the header line)
indicates the time of last modification of the program source file.
also indicates the time at which the profile data was gathered.
To determine the number of times a statement was executed,
one looks to the left of the statement and finds the corresponding
If this vertical bar is labelled with a count then that count gives the
number of times the statement was executed.
If the bar is not labelled, we look up in the listing to find the first
`|' which directly above the original one which has a count and that
was incremented 157 times on line 18,
procedure call on line 24 was executed 48 times as given by the count
can be found in its manual section
and in sections 5.4, 5.5 and 5.10.