BSD 2 development
[unix-history] / doc / pascal / puman2.n
CommitLineData
1662094b
BJ
1.if \n(xx .bp
2.if !\n(xx \{\
3.so tmac.p \}
4'if n 'ND
5.nr H1 1
6.NH
7Basic UNIX Pascal
8.PP
9The following sections
10explain the basics of using
11.UP .
12In examples here we use the text editor
13.I ex
14(6).
15Users of the text editor
16.I ed
17should have little trouble following these examples,
18as
19.I ex
20is similar to
21.I ed .
22We use
23.I ex
24because it
25allows us to make clearer examples.\(dg
26.FS
27\(dg Users with \s-2CRT\s0 terminals should find the editor
28.I vi
29more pleasant to use;
30we do not show its use here because its display oriented nature
31makes it difficult to illustrate.
32.FE
33The new
34.UX
35user will find it helpful to read one of the text editor documents
36described in section 1.4 before continuing with this section.
37.NH 2
38A first program
39.PP
40To prepare a program for
41.UP
42we first need to have an account on
43.UX
44and to `login'
45to the system on this account.
46These procedures are described in the documents
47.I "Communicating with UNIX"
48and
49.I "UNIX for Beginners".
50.PP
51Once we are logged in we need to choose a name for our program;
52let us call it `first' as this is the first example.
53We must also choose a name for the file in which the program will be stored.
54The
55.UP
56system requires that programs reside in files which have names ending with
57the sequence `.p' so we will call our file `first.p'.
58.PP
59A sample editing session to create this file would begin:
60.LS
61% \*bex first.p\fR
62"first.p" No such file or directory
63:
64.LE
65We didn't expect the file to exist, so the error diagnostic doesn't
66bother us.
67The editor now knows the name of the file we are creating.
68The `:' prompt indicates that it is ready for command input.
69We can add the text for our program using the `append'
70command as follows.
71.LS
72:\*bappend\fR
73.B
74program first(output)
75begin
76 writeln('Hello, world!')
77end.
78\&.
79.R
80:
81.LE
82The line containing the single `\*b.\fR' character here indicated
83the end of the appended text.
84The `:' prompt indicates that
85.I ex
86is ready for another command.
87As the editor operates in a temporary work space we must now store the contents
88of this work space in the file `first.p'
89so we can use the Pascal
90translator and executor
91.IX
92on it.
93.LS
94:\*bwrite\fR
95"first.p" 4 lines, 59 characters
96:\*bquit\fR
97%
98.LE
99We wrote out the file from the edit buffer here with the
100`write'
101command, and
102.I ex
103indicated the number of lines and characters written.
104We then quit the editor, and now have a prompt from the shell.\(dd
105.FS
106\(dd Our examples here assume you are using
107.I csh.
108.FE
109.KS
110.PP
111We are ready to try
112to translate and execute our program.
113.DS
114.tr '\(aa^\(ua
115% \*bpix first.p\fR
116.so firstout
117.tr ''^^
118%
119.DE
120.KE
121.PP
122The translator first printed a syntax error diagnostic.
123The number 2 here indicates that the rest of the line is an image
124of the second line of our program.
125The translator is saying that it expected to find a `;' before the
126keyword
127.B begin
128on this line.
129If we look at the Pascal syntax charts in the Jensen-Wirth
130.I "User Manual" ,
131or at some of the sample programs therein, we will see that
132we have omitted the terminating `;' of the
133.B program
134statement on the first
135line of our program.
136.PP
137One other thing to notice about the error diagnostic is the letter `e'
138at the beginning.
139It stands for `error',
140indicating that our input was not legal Pascal.
141The fact that it is an `e' rather than an `E'
142indicates that the translator managed to recover from this error well
143enough that generation of code and execution could take place.
144Execution is possible whenever no fatal `E' errors
145occur during translation.
146The other classes of diagnostics are `w' warnings,
147which do not necessarily indicate errors in the program,
148but point out inconsistencies which are likely to be due to program bugs,
149and `s' standard-Pascal violations.\*(dg
150.FS
151\*(dgThe standard Pascal warnings occur only when the associated
152.B s
153translator option is enabled.
154The
155.B s
156option is discussed in sections 5.1 and A.6 below.
157Warning diagnostics are discussed at the end of section 3.2,
158the associated
159.B w
160option is described in section 5.2.
161.FE
162.PP
163After completing the translation of the program to interpretive code,
164the Pascal system indicates that execution of the translated program began.
165The output from the execution of the program then appeared.
166At program termination, the Pascal runtime system indicated the
167number of statements executed, and the amount of cpu time
168used, with the resolution of the latter being 1/60'th of a second.
169.PP
170Let us now fix the error in the program and translate it to a permanent
171object code file
172.I obj
173using
174.PI .
175The program
176.PI
177translates Pascal programs but stores the object code instead of executing it\*(dd.
178.FS
179\*(ddThis script indicates some other useful approaches to debugging
180Pascal programs.
181As in
182.I ed
183we can shorten commands in
184.I ex
185to an initial prefix of the command name as we did
186with the
187.I substitute
188command here.
189We have also used the `!' shell escape command here to execute other
190commands with a shell without leaving the editor.
191.FE
192.LS
193% \*bex first.p\fR
194"first.p" 4 lines, 59 characters
195:\*b1 print\fR
196program first(output)
197:\*bs/$/;\fR
198program first(output);
199:\*bwrite\fR
200"first.p" 4 lines, 60 characters
201:\*b!pi %\fR
202!pi first.p
203!
204:\*bquit\fR
205%
206.LE
207The first command issued from
208.I ex
209with the `!'
210involved the use of the `%' character which stands in this command for
211the file we are editing.
212.I Ex
213made this substitution, and then echoed back the expanded line
214before executing the command.
215When the command finished, the editor echoed the character `!'
216so that we would know it was done.
217.PP
218If we now use the
219.UX
220.I ls
221list files command we can see what files we have:
222.LS
223% \*bls\fR
224first.p
225obj
226%
227.LE
228The file `obj' here contains the Pascal interpreter code.
229We can execute this by typing:
230.LS
231% \*bpx obj\fR
232.so firstobjout
233%
234.LE
235Alternatively, the command:
236.LS
237% \*bobj\fR
238.LE
239will have the same effect.
240Some examples of different ways to execute the program follow.
241.LS
242% \*bpx\fR
243.so firstobjout
244% \*bpi -p first.p\fR
245% \*bpx obj\fR
246.so firstobjout2
247% \*bpix -p first.p\fR
248.so firstobjout2
249%
250.LE
251.PP
252Note that
253.I px
254will assume that `obj' is the file we wish to execute
255if we don't tell it otherwise.
256The last two translations use the
257.B \-p
258no-post-mortem option to eliminate
259execution statistics and
260`Execution begins'
261and
262`Execution terminated'
263messages.
264See section 5.2 for more details.
265If we now look at the files in our directory we will see:
266.LS
267% \*bls\fR
268first.p
269obj
270%
271.LE
272We can give our object program a name other than `obj' by using the move
273command
274.I mv
275(1).
276Thus to name our program `hello':
277.LS
278% \*bmv obj hello\fR
279% \*bhello\fR
280Hello, world!
281% \*bls\fR
282first.p
283hello
284%
285.LE
286.KS
287Finally we can get rid of the Pascal object code by using the
288.I rm
289(1) remove file command, e.g.:
290.LS
291% \*brm hello\fR
292% \*bls\fR
293first.p
294%
295.LE
296.KE
297.PP
298For small programs which are being developed
299.IX
300tends to be more convenient to use than
301.PI
302and
303.X .
304Except for absence of the
305.I obj
306file after a
307.IX
308run,
309a
310.IX
311command is equivalent to a
312.PI
313command followed by a
314.X
315command.
316For larger programs,
317where a number of runs testing different parts of the program are
318to be made,
319.PI
320is useful as this
321.I obj
322file can be executed any desired number of times.
323.NH 2
324A larger program
325.PP
326Suppose that we have used the editor to put a larger program
327in the file `bigger.p'.
328We can list this program with line numbers by using the program
329.I num
330i.e.:
331.LS
332% \*bnum bigger.p\fR
333.so bigger3.p
334%
335.LE
336This program is similar to program 4.9 on page 30 of the
337Jensen-Wirth
338.I "User Manual" .
339A number of problems have been introduced into this example for
340pedagogical reasons.
341.br
342.ne 8
343.PP
344If we attempt to translate and execute the program using
345.IX
346we get the following response:
347.LS
348% \*bpix bigger.p\fR
349.so bigout1
350%
351.LE
352.PP
353Since there were fatal `E' errors in our program,
354no code was generated and execution was necessarily suppressed.
355One thing which would be useful at this point is a listing of the
356program with the error messages.
357We can get this by using the command:
358.LS
359% \*bpi -l bigger.p\fR
360.LE
361There is no point in using
362.IX
363here, since we know there are fatal errors in the program.
364This command will produce the output at our terminal.
365If we are at a terminal which does not produce a hard copy
366we may wish to print this
367listing off-line on a line printer\*(dg.
368.FS
369\*(dgAt Berkeley, the line printer for the Cory Hall system is in Room 199B.
370The line printers for the Computer Center
371systems are in the basement of Evans Hall.
372.FE
373We can do this with the command:
374.LS
375% \*bpi -l bigger.p | lpr\fR
376.LE
377.PP
378In the next few sections we will illustrate various aspects of the
379Berkeley
380Pascal system by correcting this program.
381.NH 2
382Correcting the first errors
383.PP
384Most of the errors which occurred in this program were
385.I syntactic
386errors, those in the format and structure of the program rather than
387its content.
388Syntax errors are flagged by printing the offending line, and then a line
389which flags the location at which an error was detected.
390The flag line also gives an explanation
391stating either a possible cause of the error,
392a simple action which can be taken to recover from the error so
393as to be able to continue the analysis,
394a symbol which was expected at the point of error,
395or an indication that the input was `malformed'.
396In the last case, the recovery may skip ahead in the input
397to a point where analysis of the program can continue.
398.PP
399In this example,
400the first error diagnostic indicates that the translator detected
401a comment within a comment.
402While this is not considered an error in `standard'
403Pascal, it usually corresponds to an error in the program which
404is being translated.
405In this case, we have accidentally omitted the trailing `*)' of the comment
406on line 8.
407We can begin an editor session to correct this problem by doing:
408.LS
409% \*bex bigger.p\fR
410"bigger.p" 24 lines, 512 characters
411:\*b8s/$/ *)\fR
412 s = 32; (* 32 character width for interval [x, x+1] *)
413:
414.LE
415.PP
416The second diagnostic, given after line 16,
417indicates that the keyword
418.B do
419was expected before the keyword
420.B begin
421in the
422.B for
423statement.
424If we examine the
425.I statement
426syntax chart on page 118 of the
427Jensen-Wirth
428.I "User Manual"
429we will discover that
430.B do
431is a necessary part of the
432.B for
433statement.
434Similarly, we could have referred to section C.3 of the
435Jensen-Wirth
436.I "User Manual"
437to learn about the
438.B for
439statement and gotten the same information there.
440It is often useful to refer to these syntax charts and to the
441relevant sections of this book.
442.PP
443We can correct this problem by first scanning for the keyword
444.B for
445in the file and then substituting the keyword
446.B do
447to appear in front of the keyword
448.B begin
449there.
450Thus:
451.LS
452:\*b/for\fR
453 for i := 0 to lim begin
454:\*bs/begin/do &\fR
455 for i := 0 to lim do begin
456:
457.LE
458The next error in the program is easy to pinpoint.
459On line 18, we didn't hit the shift key and got a `9'
460instead of a `)'.
461The translator diagnosed that `x9'
462was an undefined variable and, later,
463that a `)' was missing in the statement.
464It should be stressed that
465.PI
466is not suggesting that you should insert a `)' before the `;'.
467It is only indicating that making this change will help it to be able to
468continue analyzing the program so as to be able to diagnose further
469errors.
470You must then determine the true cause of the error and make the
471appropriate correction to the source text.
472.PP
473This error also illustrates the fact that one error in the input may lead
474to multiple error diagnostics.
475.I Pi
476attempts
477to give only one diagnostic for each error,
478but single errors in the input sometimes appear to be more than
479one error.
480It is also the case that
481.PI
482may not detect an error when it occurs, but may detect it later in
483the input.
484This would have happened
485in this example if we had typed `x' instead of `x9'.
486.PP
487The translator next detected, on line 19, that the function
488.I Round
489and the variable
490.I h
491were undefined.
492It does not know about
493.I Round
494because
495.UP
496normally distinguishes between upper- and lower-case.
497On
498.UX
499lower-case is preferred\*(dg,
500.FS
501\*(dgOne good reason for using lower-case is that it is easier to type.
502.FE
503and all keywords and built-in
504.B procedure
505and
506.B function
507names are composed of lower-case letters,
508just as they are in the Jensen-Wirth
509.I "Pascal Report" .
510Thus we need to use the function
511.I round
512here.
513As far as
514.I h
515is concerned,
516we can see why it is undefined if we look back to line 9
517and note that its definition was lost in the non-terminated
518comment.
519This diagnostic need not, therefore, concern us.
520.PP
521The next error which occurred in the program caused the translator
522to insert a `;' before the statement calling
523.I writeln
524on line 23.
525If we examine the program around the point of error we will see
526that the actual error is that the keyword
527.B until
528and an associated expression have been omitted here.
529Note that the diagnostic from the translator does not indicate the actual
530error, and is somewhat misleading.
531The translator made the correction which seemed to be most plausible.
532As the omission of a `;' character is a common mistake,
533the translator chose to indicate this as a possible fix here.
534It later detected that the keyword
535.B until
536was missing, but not until it saw the keyword
537.B end
538on line 24.
539The combination of these diagnostics indicate to us the true problem.
540.PP
541The final syntactic error message indicates that the translator needed an
542.B end
543keyword to match the
544.B begin
545at line 15.
546Since the
547.B end
548at line 24 is supposed to match this
549.B begin ,
550we can infer that another
551.B begin
552must have been mismatched, and have matched this
553.B end .
554Thus we see that we need an
555.B end
556to match the
557.B begin
558at line 16,
559and to appear before the final
560.B end .
561We can make these corrections:
562.LS
563:\*b/x9/s//x)\fR
564 y := exp(-x) * sin(i * x);
565:\*b+s/Round/round\fR
566 n := round(s * y) + h;
567:\*b/write\fR
568 write(' ');
569:\*b/\fR
570 writeln('*')
571:\*binsert\fR
572 \*buntil n = 0;\fR
573\&\*b.\fR
574:\*b$\fR
575end.
576:\*binsert\fR
577 \*bend\fR
578\&\*b.\fR
579:
580.LE
581.PP
582At the end of each
583.B procedure
584or
585.B function
586and the end of the
587.B program
588the translator summarizes references to undefined variables
589and improper usages of variables.
590It also gives
591warnings about potential errors.
592In our program, the summary errors do not indicate any further problems
593but the warning that
594.I c
595is unused is somewhat suspicious.
596Examining the program we see that the constant was intended
597to be used in the expression which is an argument to
598.I sin ,
599so we can correct this expression, and translate the program.
600We have now made a correction for each diagnosed error
601in our program.
602.LS
603:\*b?i ?s//c /\fR
604 y := exp(-x) * sin(c * x);
605:\*bwrite\fR
606"bigger.p" 26 lines, 538 characters
607:\*b!pi %\fR
608!pi bigger.p
609!
610:\*bquit\fR
611%
612.LE
613It should be noted that the translator suppresses warning
614diagnostics for a particular
615.B procedure ,
616.B function
617or the main
618.B program
619when it finds severe syntax errors in that part of the source
620text.
621This is to prevent possibly confusing and
622incorrect warning diagnostics from being produced.
623Thus these warning diagnostics may not appear in a program with
624bad syntax errors until these errors are corrected.
625.KS
626.PP
627We are now ready to execute our program for the first
628time.
629We will do so in the next section after giving a listing
630of the corrected program for reference purposes.
631.ne 15
632.LS
633% \*bnumber bigger.p\fR
634.so bigger6.p
635%
636.LE
637.NH 2
638Executing the second example
639.PP
640We are now ready to execute the second example.
641The following output was produced by our first run.
642.LS
643% \*bpx\fR
644.so bigout2
645%
646.LE
647Here the interpreter is presenting us with a runtime error diagnostic.
648It detected a `division by zero' at line 17.
649Examining line 17, we see that we have written
650the statement `x := d / i' instead of `x := d * i'.
651We can correct this and rerun the program:
652.ne 10
653.LS
654% \*bex bigger.p\fR
655"bigger.p" 26 lines, 538 characters
656:\*b17\fR
657 x := d / i
658:\*bs'/'*\fR
659 x := d * i
660:\*bwrite\fR
661"bigger.p" 26 lines, 538 characters
662:\*b!pix %\fR
663!pix bigger.p
664.so bigout3
665!
666:\*bq\fR
667%
668.LE
669.KS
670.PP
671This appears to be the output we wanted.
672We could now save the output in a file if we wished by using the shell
673to redirect the output:
674.LS
675% \*bpx > graph\fR
676.LE
677.KE
678We can use
679.I cat
680(1) to see the contents of the file graph.
681We can also make a listing of the graph on the line printer without
682putting it into a file, e.g.
683.LS
684% \*bpx | lpr\fR
685.so bigout4
686%
687.LE
688Note here that the statistics lines came out on our terminal.
689The statistics line comes out on the diagnostic output (unit 2.)
690There are two ways to get rid of the statistics line.
691We can redirect the statistics message to the printer using the
692syntax `|\|&' to the shell rather than `|', i.e.:
693.LS
694% \*bpx |\|& lpr\fR
695%
696.LE
697or we can translate the program with the
698.B p
699option disabled on the command line as we did above.
700This will disable all post-mortem dumping including the statistics line,
701thus:
702.LS
703% \*bpi -p bigger.p\fR
704% \*bpx | lpr\fR
705%
706.LE
707This option also disables the statement limit which normally guards
708against infinite looping.
709You should not use it until your program is debugged.
710Also if
711.B p
712is specified and an error occurs, you will
713not get run time diagnostic information to help you
714determine what the problem is.
715.NH 2
716Formatting the program listing
717.PP
718It is possible to use special lines within the source text of a program
719to format the program listing.
720An empty line (one with no characters on it) corresponds to a
721`space' macro in an assembler, leaving a completely blank line
722without a line number.
723A line containing only a control-l (form-feed) character
724will cause a page eject in the listing with the corresponding line number
725suppressed.
726This corresponds to an `eject' pseudo-instruction.
727See also section 5.2 for details on the
728.B n
729and
730.B i
731options of
732.PI .
733.NH 2
734Execution profiling
735.PP
736An execution profile consists of a structured listing of (all or part of)
737a program with information about the number of times each statement in
738the program was executed for a particular run of the program.
739These profiles can be used for several purposes.
740In a program which was abnormally terminated due to excessive looping
741or recursion or by a program fault, the counts can facilitate location
742of the error.
743Zero counts mark portions of the program which were not executed;
744during the early debugging stages they should prompt new test data or
745a re-examination of the program logic.
746The profile is perhaps most valuable, however, in drawing
747attention to the (typically small)
748portions of the program that dominate execution time.
749This information can be used for source level optimization.
750.SH
751An example
752.PP
753A prime number is a number which is divisible only by itself and the
754number one.
755The program
756.I primes ,
757written by Niklaus Wirth,
758determines the first few prime numbers.
759In translating the program we have specified the
760.B z
761option to
762.IX .
763This option causes the translator to generate counters and count instructions
764sufficient in number to determine the number of times each statement in the
765program was executed.\*(dg
766.FS
767\*(dgThe counts
768are completely accurate only in the absence of runtime errors and nonlocal
769.B goto
770statements.
771This is not generally a problem, however, as in structured programs
772nonlocal
773.B goto
774statements occur infrequently,
775and counts are incorrect after abnormal termination only when the
776.I "upward look"
777described below to get a count passes a suspended call point.
778.FE
779When execution of the program completes, either normally or abnormally,
780this count data is written to the file
781.I pmon.out
782in the current directory.\*(dd
783.FS
784\*(dd\c
785.I Pmon.out
786has a name similar to
787.I mon.out
788the monitor file produced by the profiling facility of the C compiler
789.I cc
790(1).
791See
792.I prof
793(1) for a discussion of the C compiler profiling facilities.
794.FE
795It is then possible to prepare an execution profile by giving
796.XP
797the name of the file associated with this data, as was done in the following
798example.
799.LS
800% \*bpix -l -z primes.p\fR
801.so primeout1
802%
803.LE
804.SH
805Discussion
806.PP
807The header lines of the outputs of
808.IX
809and
810.XP
811in this example indicate the version of the translator and execution
812profiler in use at the time this example was prepared.
813The time given with the file name (also on the header line)
814indicates the time of last modification of the program source file.
815This time serves to
816.I "version stamp"
817the input program.
818.I Pxp
819also indicates the time at which the profile data was gathered.
820.LS
821% \*bpxp -z primes.p\fR
822.so primeout2
823%
824.LE
825.KE
826.PP
827To determine the number of times a statement was executed,
828one looks to the left of the statement and finds the corresponding
829vertical bar `|'.
830If this vertical bar is labelled with a count then that count gives the
831number of times the statement was executed.
832If the bar is not labelled, we look up in the listing to find the first
833`|' which directly above the original one which has a count and that
834is the answer.
835Thus, in our example,
836.I k
837was incremented 157 times on line 18,
838while the
839.I write
840procedure call on line 24 was executed 48 times as given by the count
841on the
842.B repeat .
843.PP
844More information on
845.I pxp
846can be found in its manual section
847.XP
848(6)
849and in sections 5.4, 5.5 and 5.10.