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