BSD 2 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Thu, 19 Apr 1979 05:00:16 +0000 (21:00 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Thu, 19 Apr 1979 05:00:16 +0000 (21:00 -0800)
Work on file doc/px/fig1.1.n
Work on file doc/px/pxin2.n
Work on file doc/px/pxin3.n
Work on file doc/px/fig2.2.n
Work on file doc/px/pxin1.n
Work on file doc/px/makefile
Work on file doc/px/fig2.1.n
Work on file doc/px/fig2.1.raw
Work on file doc/px/pxin4.n
Work on file doc/px/pxin0.n
Work on file doc/px/fig1.3.n
Work on file doc/px/fig1.2.n
Work on file doc/pxp/pxpin3.n
Work on file doc/pxp/pxpin0.n
Work on file doc/pxp/pcrt0.s
Work on file doc/pxp/pxpin1.n
Work on file doc/pxp/makefile
Work on file doc/pxp/pxpin2.n
Work on file doc/px/tmac.p
Work on file doc/pxp/tmac.p
Work on file doc/pxp/stat.c
Work on file doc/pascal/makefile
Work on file doc/pascal/bigger.p
Work on file doc/pascal/fixcomments
Work on file doc/pascal/firstout
Work on file doc/pascal/firstobjout
Work on file doc/pascal/kat3.p
Work on file doc/pascal/bigger7.p
Work on file doc/pascal/clashout
Work on file doc/pascal/bigger5.p
Work on file doc/pascal/bigger4.p
Work on file doc/pascal/bigger2.p
Work on file doc/pascal/clash.p
Work on file doc/pascal/bigger3.p
Work on file doc/pascal/comments.p
Work on file doc/pascal/firstobjout2
Work on file doc/pascal/bigout1
Work on file doc/pascal/contents.n
Work on file doc/pascal/bigout2
Work on file doc/pascal/copydata.p
Work on file doc/pascal/bigger6.p
Work on file doc/pascal/csfix.c
Work on file doc/pascal/digits.p
Work on file doc/pascal/data
Work on file doc/pascal/bigout3
Work on file doc/pascal/bigout4
Work on file doc/pascal/primeout1
Work on file doc/pascal/primeout2
Work on file doc/pascal/digitsout
Work on file doc/pascal/synerr2out
Work on file doc/pascal/expr.p
Work on file doc/pascal/primes
Work on file doc/pascal/first.p
Work on file doc/pascal/exprout
Work on file doc/pascal/sinout1
Work on file doc/pascal/mismout
Work on file doc/pascal/typequout
Work on file doc/pascal/sinout2
Work on file doc/pascal/primeout3
Work on file doc/pascal/kat.p
Work on file doc/pascal/katout
Work on file doc/pascal/kat2.p
Work on file doc/pascal/kat2out
Work on file doc/pascal/katin
Work on file doc/pascal/copydataout
Work on file doc/pascal/katscript
Work on file doc/pascal/xxxxqqqout
Work on file doc/pascal/mism.p
Work on file doc/pascal/xxxxqqqout2
Work on file doc/pascal/primes-d
Work on file doc/pascal/motd
Work on file doc/pascal/comments1.p
Work on file doc/pascal/synerrout
Work on file doc/pascal/commentsout
Work on file doc/pascal/primes.p
Work on file doc/pascal/primes2.p
Work on file doc/pascal/puman0.n
Work on file doc/pascal/puman1.n
Work on file doc/pascal/puman2.n
Work on file doc/pascal/puman3.n
Work on file doc/pascal/pumanA.n
Work on file doc/pascal/sin1.p
Work on file doc/pascal/puman4.n
Work on file doc/pascal/puman5.n
Work on file doc/pascal/sin2.p
Work on file doc/pascal/synerr.p
Work on file doc/pascal/synerr2.p
Work on file doc/pascal/tmac.p
Work on file doc/pascal/typequ.p
Work on file doc/pascal/fixkatscript

Synthesized-from: 2bsd

90 files changed:
doc/pascal/bigger.p [new file with mode: 0644]
doc/pascal/bigger2.p [new file with mode: 0644]
doc/pascal/bigger3.p [new file with mode: 0644]
doc/pascal/bigger4.p [new file with mode: 0644]
doc/pascal/bigger5.p [new file with mode: 0644]
doc/pascal/bigger6.p [new file with mode: 0644]
doc/pascal/bigger7.p [new file with mode: 0644]
doc/pascal/bigout1 [new file with mode: 0644]
doc/pascal/bigout2 [new file with mode: 0644]
doc/pascal/bigout3 [new file with mode: 0644]
doc/pascal/bigout4 [new file with mode: 0644]
doc/pascal/clash.p [new file with mode: 0644]
doc/pascal/clashout [new file with mode: 0644]
doc/pascal/comments.p [new file with mode: 0644]
doc/pascal/comments1.p [new file with mode: 0644]
doc/pascal/commentsout [new file with mode: 0644]
doc/pascal/contents.n [new file with mode: 0644]
doc/pascal/copydata.p [new file with mode: 0644]
doc/pascal/copydataout [new file with mode: 0644]
doc/pascal/csfix.c [new file with mode: 0644]
doc/pascal/data [new file with mode: 0644]
doc/pascal/digits.p [new file with mode: 0644]
doc/pascal/digitsout [new file with mode: 0644]
doc/pascal/expr.p [new file with mode: 0644]
doc/pascal/exprout [new file with mode: 0644]
doc/pascal/first.p [new file with mode: 0644]
doc/pascal/firstobjout [new file with mode: 0644]
doc/pascal/firstobjout2 [new file with mode: 0644]
doc/pascal/firstout [new file with mode: 0644]
doc/pascal/fixcomments [new file with mode: 0644]
doc/pascal/fixkatscript [new file with mode: 0644]
doc/pascal/kat.p [new file with mode: 0644]
doc/pascal/kat2.p [new file with mode: 0644]
doc/pascal/kat2out [new file with mode: 0644]
doc/pascal/kat3.p [new file with mode: 0644]
doc/pascal/katin [new file with mode: 0644]
doc/pascal/katout [new file with mode: 0644]
doc/pascal/katscript [new file with mode: 0644]
doc/pascal/makefile [new file with mode: 0755]
doc/pascal/mism.p [new file with mode: 0644]
doc/pascal/mismout [new file with mode: 0644]
doc/pascal/motd [new file with mode: 0644]
doc/pascal/primeout1 [new file with mode: 0644]
doc/pascal/primeout2 [new file with mode: 0644]
doc/pascal/primeout3 [new file with mode: 0644]
doc/pascal/primes [new file with mode: 0644]
doc/pascal/primes-d [new file with mode: 0644]
doc/pascal/primes.p [new file with mode: 0644]
doc/pascal/primes2.p [new file with mode: 0644]
doc/pascal/puman0.n [new file with mode: 0644]
doc/pascal/puman1.n [new file with mode: 0644]
doc/pascal/puman2.n [new file with mode: 0644]
doc/pascal/puman3.n [new file with mode: 0644]
doc/pascal/puman4.n [new file with mode: 0644]
doc/pascal/puman5.n [new file with mode: 0644]
doc/pascal/pumanA.n [new file with mode: 0644]
doc/pascal/sin1.p [new file with mode: 0644]
doc/pascal/sin2.p [new file with mode: 0644]
doc/pascal/sinout1 [new file with mode: 0644]
doc/pascal/sinout2 [new file with mode: 0644]
doc/pascal/synerr.p [new file with mode: 0644]
doc/pascal/synerr2.p [new file with mode: 0644]
doc/pascal/synerr2out [new file with mode: 0644]
doc/pascal/synerrout [new file with mode: 0644]
doc/pascal/tmac.p [new file with mode: 0644]
doc/pascal/typequ.p [new file with mode: 0644]
doc/pascal/typequout [new file with mode: 0644]
doc/pascal/xxxxqqqout [new file with mode: 0644]
doc/pascal/xxxxqqqout2 [new file with mode: 0644]
doc/px/fig1.1.n [new file with mode: 0644]
doc/px/fig1.2.n [new file with mode: 0644]
doc/px/fig1.3.n [new file with mode: 0644]
doc/px/fig2.1.n [new file with mode: 0644]
doc/px/fig2.1.raw [new file with mode: 0644]
doc/px/fig2.2.n [new file with mode: 0644]
doc/px/makefile [new file with mode: 0755]
doc/px/pxin0.n [new file with mode: 0644]
doc/px/pxin1.n [new file with mode: 0644]
doc/px/pxin2.n [new file with mode: 0644]
doc/px/pxin3.n [new file with mode: 0644]
doc/px/pxin4.n [new file with mode: 0644]
doc/px/tmac.p [new file with mode: 0644]
doc/pxp/makefile [new file with mode: 0644]
doc/pxp/pcrt0.s [new file with mode: 0644]
doc/pxp/pxpin0.n [new file with mode: 0644]
doc/pxp/pxpin1.n [new file with mode: 0644]
doc/pxp/pxpin2.n [new file with mode: 0644]
doc/pxp/pxpin3.n [new file with mode: 0644]
doc/pxp/stat.c [new file with mode: 0644]
doc/pxp/tmac.p [new file with mode: 0644]

diff --git a/doc/pascal/bigger.p b/doc/pascal/bigger.p
new file mode 100644 (file)
index 0000000..d342b09
--- /dev/null
@@ -0,0 +1,24 @@
+(*
+ * Graphic representation of a function
+ *    f(x) = exp(-x) * sin(2 * pi * x)
+ *)
+program graph1(output);
+const
+       d = 0.0625;   (* 1/16, 16 lines for interval [x, x+1] *)
+       s = 32;       (* 32 character width for interval [x, x+1]
+       h = 34;       (* Character position of x-axis *)
+       c = 6.28138;  (* 2 * pi *)
+       lim = 32;
+var
+       x, y: real;
+       i, n: integer;
+begin
+       for i := 0 to lim begin
+               x := d / i;
+               y := exp(-x9 * sin(i * x);
+               n := Round(s * y) + h;
+               repeat
+                       write(' ');
+                       n := n - 1
+               writeln('*')
+end.
diff --git a/doc/pascal/bigger2.p b/doc/pascal/bigger2.p
new file mode 100644 (file)
index 0000000..e032349
--- /dev/null
@@ -0,0 +1,24 @@
+(*
+ * Graphic representation of a function
+ *    f(x) = exp(-x) * sin(2 * pi * x)
+ *)
+program graph1(output);
+const
+        d = 0.0625;   (* 1/16, 16 lines for interval [x, x+1] *)
+        s = 32;       (* 32 character width for interval [x, x+1]
+        h = 34;       (* Character position of x-axis *)
+        c = 6.28138;  (* 2 * pi *)
+        lim = 32;
+var
+        x, y: real;
+        i, n: integer;
+begin
+        for i := 0 to lim begin
+                x := d / i;
+                y := exp(-x9 * sin(i * x);
+                n := Round(s * y) + h;
+                repeat
+                        write(' ');
+                        n := n - 1
+                writeln('*')
+end.
diff --git a/doc/pascal/bigger3.p b/doc/pascal/bigger3.p
new file mode 100644 (file)
index 0000000..c63be68
--- /dev/null
@@ -0,0 +1,24 @@
+\0\0\0\0\01\0\0(*
+\0\0\0\0\02\0\0\0* Graphic representation of a function
+\0\0\0\0\03\0\0\0*    f(x) = exp(-x) * sin(2 * pi * x)
+\0\0\0\0\04\0\0\0*)
+\0\0\0\0\05\0\0program graph1(output);
+\0\0\0\0\06\0\0const
+\0\0\0\0\07\0\0\0\0\0\0\0\0\0\0d = 0.0625;   (* 1/16, 16 lines for interval [x, x+1] *)
+\0\0\0\0\08\0\0\0\0\0\0\0\0\0\0s = 32;       (* 32 character width for interval [x, x+1]
+\0\0\0\0\09\0\0\0\0\0\0\0\0\0\0h = 34;       (* Character position of x-axis *)
+\0\0\0\010\0\0\0\0\0\0\0\0\0\0c = 6.28138;  (* 2 * pi *)
+\0\0\0\011\0\0\0\0\0\0\0\0\0\0lim = 32;
+\0\0\0\012\0\0var
+\0\0\0\013\0\0\0\0\0\0\0\0\0\0x, y: real;
+\0\0\0\014\0\0\0\0\0\0\0\0\0\0i, n: integer;
+\0\0\0\015\0\0begin
+\0\0\0\016\0\0\0\0\0\0\0\0\0\0for i := 0 to lim begin
+\0\0\0\017\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0x := d / i;
+\0\0\0\018\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0y := exp(-x9 * sin(i * x);
+\0\0\0\019\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0n := Round(s * y) + h;
+\0\0\0\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0repeat
+\0\0\0\021\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0write(' ');
+\0\0\0\022\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0n := n - 1
+\0\0\0\023\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0writeln('*')
+\0\0\0\024\0\0end.
diff --git a/doc/pascal/bigger4.p b/doc/pascal/bigger4.p
new file mode 100644 (file)
index 0000000..5a16ef4
--- /dev/null
@@ -0,0 +1,26 @@
+(*
+ * Graphic representation of a function
+ *    f(x) = exp(-x) * sin(2 * pi * x)
+ *)
+program graph1(output);
+const
+       d = 0.0625;   (* 1/16, 16 lines for interval [x, x+1] *)
+       s = 32;       (* 32 character width for interval [x, x+1] *)
+       h = 34;       (* Character position of x-axis *)
+       c = 6.28138;  (* 2 * pi *)
+       lim = 32;
+var
+       x, y: real;
+       i, n: integer;
+begin
+       for i := 0 to lim do begin
+               x := d / i;
+               y := exp(-x) * sin(c * x);
+               n := round(s * y) + h;
+               repeat
+                       write(' ');
+                       n := n - 1
+               until n = 0;
+               writeln('*')
+       end
+end.
diff --git a/doc/pascal/bigger5.p b/doc/pascal/bigger5.p
new file mode 100644 (file)
index 0000000..5a16ef4
--- /dev/null
@@ -0,0 +1,26 @@
+(*
+ * Graphic representation of a function
+ *    f(x) = exp(-x) * sin(2 * pi * x)
+ *)
+program graph1(output);
+const
+       d = 0.0625;   (* 1/16, 16 lines for interval [x, x+1] *)
+       s = 32;       (* 32 character width for interval [x, x+1] *)
+       h = 34;       (* Character position of x-axis *)
+       c = 6.28138;  (* 2 * pi *)
+       lim = 32;
+var
+       x, y: real;
+       i, n: integer;
+begin
+       for i := 0 to lim do begin
+               x := d / i;
+               y := exp(-x) * sin(c * x);
+               n := round(s * y) + h;
+               repeat
+                       write(' ');
+                       n := n - 1
+               until n = 0;
+               writeln('*')
+       end
+end.
diff --git a/doc/pascal/bigger6.p b/doc/pascal/bigger6.p
new file mode 100644 (file)
index 0000000..9ba7cea
--- /dev/null
@@ -0,0 +1,26 @@
+\0\0\0\0\01\0\0(*
+\0\0\0\0\02\0\0\0* Graphic representation of a function
+\0\0\0\0\03\0\0\0*    f(x) = exp(-x) * sin(2 * pi * x)
+\0\0\0\0\04\0\0\0*)
+\0\0\0\0\05\0\0program graph1(output);
+\0\0\0\0\06\0\0const
+\0\0\0\0\07\0\0\0\0\0\0\0\0\0\0d = 0.0625;   (* 1/16, 16 lines for interval [x, x+1] *)
+\0\0\0\0\08\0\0\0\0\0\0\0\0\0\0s = 32;       (* 32 character width for interval [x, x+1] *)
+\0\0\0\0\09\0\0\0\0\0\0\0\0\0\0h = 34;       (* Character position of x-axis *)
+\0\0\0\010\0\0\0\0\0\0\0\0\0\0c = 6.28138;  (* 2 * pi *)
+\0\0\0\011\0\0\0\0\0\0\0\0\0\0lim = 32;
+\0\0\0\012\0\0var
+\0\0\0\013\0\0\0\0\0\0\0\0\0\0x, y: real;
+\0\0\0\014\0\0\0\0\0\0\0\0\0\0i, n: integer;
+\0\0\0\015\0\0begin
+\0\0\0\016\0\0\0\0\0\0\0\0\0\0for i := 0 to lim do begin
+\0\0\0\017\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0x := d / i;
+\0\0\0\018\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0y := exp(-x) * sin(c * x);
+\0\0\0\019\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0n := round(s * y) + h;
+\0\0\0\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0repeat
+\0\0\0\021\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0write(' ');
+\0\0\0\022\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0n := n - 1
+\0\0\0\023\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0until n = 0;
+\0\0\0\024\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0writeln('*')
+\0\0\0\025\0\0\0\0\0\0\0\0\0\0end
+\0\0\0\026\0\0end.
diff --git a/doc/pascal/bigger7.p b/doc/pascal/bigger7.p
new file mode 100644 (file)
index 0000000..b4cd01d
--- /dev/null
@@ -0,0 +1,26 @@
+(*
+ * Graphic representation of a function
+ *    f(x) = exp(-x) * sin(2 * pi * x)
+ *)
+program graph1(output);
+const
+       d = 0.0625;   (* 1/16, 16 lines for interval [x, x+1] *)
+       s = 32;       (* 32 character width for interval [x, x+1] *)
+       h = 34;       (* Character position of x-axis *)
+       c = 6.28138;  (* 2 * pi *)
+       lim = 32;
+var
+       x, y: real;
+       i, n: integer;
+begin
+       for i := 0 to lim do begin
+               x := d * i;
+               y := exp(-x) * sin(c * x);
+               n := round(s * y) + h;
+               repeat
+                       write(' ');
+                       n := n - 1
+               until n = 0;
+               writeln('*')
+       end
+end.
diff --git a/doc/pascal/bigout1 b/doc/pascal/bigout1
new file mode 100644 (file)
index 0000000..08deb3d
--- /dev/null
@@ -0,0 +1,21 @@
+     9          h = 34;       (* Character position of x-axis *)
+w \l'\w`     9          h = 34;       (`u-\w`w `u\&\(rh'\l'(\w`*`u-\w`^`u)/2 '\(ua\l'(\w`*`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' (* in a (* ... *) comment
+    16          for i := 0 to lim begin
+e \l'\w`w `u-\w`e `u '\l'\w`    16          for i := 0 to lim `u-\w`w `u\&\(rh'\l'(\w`b`u-\w`^`u)/2 '\(ua\l'(\w`b`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted keyword do
+    18                  y := exp(-x9 * sin(i * x);
+E \l'\w`w `u-\w`E `u '\l'\w`    18                  y := exp(-`u-\w`w `u\&\(rh'\l'(\w`x`u-\w`^`u)/2 '\(ua\l'(\w`x`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Undefined variable
+e \l'\w`w `u-\w`e `u '\l'\w`    18                  y := exp(-x9 * sin(i * x)`u-\w`w `u\&\(rh'\l'(\w`;`u-\w`^`u)/2 '\(ua\l'(\w`;`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted ')'
+    19                  n := Round(s * y) + h;
+E \l'\w`w `u-\w`E `u '\l'\w`    19                  n := `u-\w`w `u\&\(rh'\l'(\w`R`u-\w`^`u)/2 '\(ua\l'(\w`R`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Undefined function
+E \l'\w`w `u-\w`E `u '\l'\w`    19                  n := Round(s * y) + `u-\w`w `u\&\(rh'\l'(\w`h`u-\w`^`u)/2 '\(ua\l'(\w`h`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Undefined variable
+    23                  writeln('*')
+e \l'\w`w `u-\w`e `u '\l'\w`    23                  `u-\w`w `u\&\(rh'\l'(\w`w`u-\w`^`u)/2 '\(ua\l'(\w`w`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted ';'
+    24  end.
+E \l'\w`w `u-\w`E `u '\l'\w`    24  `u-\w`w `u\&\(rh'\l'(\w`e`u-\w`^`u)/2 '\(ua\l'(\w`e`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Expected keyword until
+e \l'\w`w `u-\w`e `u '\l'\w`    24  end`u-\w`w `u\&\(rh'\l'(\w`.`u-\w`^`u)/2 '\(ua\l'(\w`.`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted keyword end matching begin on line 15
+In program graph1:
+  \l'(\w`E`u-\w`w`u)/2 'w\l'(\w`E`u-\w`w`u)/2 ' - constant c is never used
+  E - x9 undefined on line 18
+  E - Round undefined on line 19
+  E - h undefined on line 19
+Execution suppressed due to compilation errors
diff --git a/doc/pascal/bigout2 b/doc/pascal/bigout2
new file mode 100644 (file)
index 0000000..cd54129
--- /dev/null
@@ -0,0 +1,7 @@
+Execution begins...
+Floating divide by zero
+
+        Error at "graph1"+2 near line 17
+
+Execution terminated abnormally
+2 statements executed in 0.04 seconds cpu time
diff --git a/doc/pascal/bigout3 b/doc/pascal/bigout3
new file mode 100644 (file)
index 0000000..b529b6a
--- /dev/null
@@ -0,0 +1,36 @@
+Execution begins...
+                                  *
+                                              *
+                                                      *
+                                                           *
+                                                           *
+                                                        *
+                                                  *
+                                          *
+                                  *
+                           *
+                      *
+                   *
+                   *
+                     *
+                         *
+                             *
+                                  *
+                                      *
+                                         *
+                                           *
+                                           *
+                                          *
+                                        *
+                                     *
+                                  *
+                               *
+                              *
+                             *
+                            *
+                             *
+                               *
+                                *
+                                  *
+Execution terminated
+2550 statements executed in 0.21 seconds cpu time
diff --git a/doc/pascal/bigout4 b/doc/pascal/bigout4
new file mode 100644 (file)
index 0000000..598d8ef
--- /dev/null
@@ -0,0 +1,3 @@
+Execution begins...
+Execution terminated
+2550 statements executed in 0.31 seconds cpu time
diff --git a/doc/pascal/clash.p b/doc/pascal/clash.p
new file mode 100644 (file)
index 0000000..4a07405
--- /dev/null
@@ -0,0 +1,9 @@
+program clash(output);
+var
+       i: integer;
+       c: char;
+begin
+       i := 1;
+       c := i;
+       write(c, i)
+end.
diff --git a/doc/pascal/clashout b/doc/pascal/clashout
new file mode 100644 (file)
index 0000000..a4d46d2
--- /dev/null
@@ -0,0 +1,2 @@
+E 7 - Type clash: integer is incompatible with char
+  ... Type of expression clashed with type of variable in assignment
diff --git a/doc/pascal/comments.p b/doc/pascal/comments.p
new file mode 100644 (file)
index 0000000..b07ddfc
--- /dev/null
@@ -0,0 +1,18 @@
+{ This is a left marginal comment. }
+program hello(output);
+var i : integer; {This is a trailing comment}
+j : integer;   {This is a right marginal comment}
+k : array [ 1..10] of array [1..10] of integer;        {Marginal, but past the margin}
+{
+  An aligned, multi-line comment
+  which explains what this program is
+  all about
+}
+begin
+i := 1; {Trailing i comment}
+{A left marginal comment}
+ {An aligned comment}
+j := 1;                {Right marginal comment}
+k[1] := 1;
+writeln(i, j, k[1])
+end.
diff --git a/doc/pascal/comments1.p b/doc/pascal/comments1.p
new file mode 100644 (file)
index 0000000..8e7de6c
--- /dev/null
@@ -0,0 +1,18 @@
+{ This is a left marginal comment. }
+program hello(output);
+var i : integer; {This is a trailing comment}
+j : integer;    {This is a right marginal comment}
+k : array [ 1..10] of array [1..10] of integer; {Marginal, but past the margin}
+{
+  An aligned, multi-line comment
+  which explains what this program is
+  all about
+}
+begin
+i := 1; {Trailing i comment}
+{A left marginal comment}
+ {An aligned comment}
+j := 1;         {Right marginal comment}
+k[1] := 1;
+writeln(i, j, k[1])
+end.
diff --git a/doc/pascal/commentsout b/doc/pascal/commentsout
new file mode 100644 (file)
index 0000000..afc089e
--- /dev/null
@@ -0,0 +1,21 @@
+.ta 3.25i
+{ This is a left marginal comment. }
+
+program hello(output);
+var
+    i: integer; {This is a trailing comment}
+    j: integer;        {This is a right marginal comment}
+    k: array [1..10] of array [1..10] of integer;       {Marginal, but past the margin}
+{
+  An aligned, multi-line comment
+  which explains what this program is
+  all about
+}
+begin
+    i := 1; {Trailing i comment}
+{A left marginal comment}
+    {An aligned comment}
+    j := 1;    {Right marginal comment}
+    k[1] := 1;
+    writeln(i, j, k[1])
+end.
diff --git a/doc/pascal/contents.n b/doc/pascal/contents.n
new file mode 100644 (file)
index 0000000..1d6e065
--- /dev/null
@@ -0,0 +1,105 @@
+.if !\n(xx .so /usr/lib/tmac.s
+.nr LL 6.5i
+.TL
+UNIX Pascal User's Manual
+.br
+Version 1.0 \- November, 1977
+.LP
+.ds CF "- \\n(PN -
+.ds CH
+.af PN i
+.ce
+.I
+.LG
+.LG
+Table of Contents
+.NL
+.R
+.sp .5i
+.KS
+.ta 5.75i
+.tc .
+.nf
+.KE
+.KS
+Introduction   \0\01
+.KE
+.sp 2
+.KS
+.B
+1.  Sources of Information     \0\02
+.R
+.sp
+ .1   Where to get documentation       \0\02
+ .2   Computer Center short courses    \0\02
+ .3   Documentation describing UNIX    \0\02
+ .4   Text editing documents   \0\03
+ .5   Pascal documents \- the language \0\04
+ .6   Pascal documents \- the UNIX implementation      \0\04
+ .7   References       \0\05
+.KE
+.sp 2
+.KS
+.B
+2.  Basic UNIX Pascal  \0\07
+.R
+.sp
+ .1   A first program  \0\07
+ .2   A larger program \010
+ .3   Correcting the first errors      \011
+ .4   Executing the second example     \014
+ .5   Formatting the program listing   \016
+ .6   Execution profiling      \016
+.KE
+.sp 2
+.KS
+.B
+3. Error diagnostics   \020
+.R
+.sp
+ .1   Translator syntax errors \020
+ .2   Translator semantic errors       \023
+ .3   Translator panics, i/o errors    \027
+ .4   Run-time errors  \027
+.KE
+.sp 2
+.KS
+.B
+4.  Input/output       \029
+.R
+.sp
+ .1   Introduction     \029
+ .2   Eof and eoln     \030
+ .3   More about eoln  \031
+ .4   Output buffering \032
+ .5   Files, reset and rewrite \032
+ .6   Argc and argv    \033
+.KE
+.sp 2
+.KS
+.B
+5.  Details on components of the system        \036
+.R
+.sp
+ .1   Options  \036
+ .2   Pi (and pix)     \037
+ .3   Px       \039
+ .4   Pxp      \039
+ .5   Formatting programs using pxp    \040
+ .6   Pcc and carriage control \042
+ .7   Pxref    \042
+ .8   Pascals  \042
+ .9   Multi-file programs      \042
+.KE
+.sp 2
+.KS
+.B
+A.  Appendix to Wirth's Pascal Report  \044
+.R
+.sp
+ .1   Extensions to the language Pascal        \045
+ .2   Resolution of the undefined specifications       \045
+ .3   Restrictions and limitations     \048
+ .4   Added types, operators, procedures and functions \048
+ .5   Remarks on standard and portable Pascal  \050
+.KE
diff --git a/doc/pascal/copydata.p b/doc/pascal/copydata.p
new file mode 100644 (file)
index 0000000..ecf237c
--- /dev/null
@@ -0,0 +1,15 @@
+program copydata(data, output);
+var
+    ch: char;
+    data: text;
+begin
+    reset(data);
+    while not eof(data) do begin
+       while not eoln(data) do begin
+           read(data, ch);
+           write(ch)
+       end;
+       readln(data);
+       writeln
+    end
+end { copydata }.
diff --git a/doc/pascal/copydataout b/doc/pascal/copydataout
new file mode 100644 (file)
index 0000000..2d060e6
--- /dev/null
@@ -0,0 +1,25 @@
+Berkeley Pascal PI -- Version 1.1 (January 4, 1979)
+
+Sat Mar 31 11:50 1979  copydata.p
+
+\0\0\0\0\01\0\0program copydata(data, output);
+\0\0\0\0\02\0\0var
+\0\0\0\0\03\0\0\0\0\0\0ch: char;
+\0\0\0\0\04\0\0\0\0\0\0data: text;
+\0\0\0\0\05\0\0begin
+\0\0\0\0\06\0\0\0\0\0\0reset(data);
+\0\0\0\0\07\0\0\0\0\0\0while not eof(data) do begin
+\0\0\0\0\08\0\0\0\0\0\0\0\0\0\0while not eoln(data) do begin
+\0\0\0\0\09\0\0\0\0\0\0\0\0\0\0\0\0\0\0read(data, ch);
+\0\0\0\010\0\0\0\0\0\0\0\0\0\0\0\0\0\0write(ch)
+\0\0\0\011\0\0\0\0\0\0\0\0\0\0end;
+\0\0\0\012\0\0\0\0\0\0\0\0\0\0readln(data);
+\0\0\0\013\0\0\0\0\0\0\0\0\0\0writeln
+\0\0\0\014\0\0\0\0\0\0end
+\0\0\0\015\0\0end { copydata }.
+Execution begins...
+line one.
+line two.
+line three is the end.
+Execution terminated
+134\0statements executed in 0.01 seconds cpu time
diff --git a/doc/pascal/csfix.c b/doc/pascal/csfix.c
new file mode 100644 (file)
index 0000000..e78e472
--- /dev/null
@@ -0,0 +1,172 @@
+#include <stdio.h>
+/*
+ * csfix - fix constant spacing for error message flags in troff
+ *
+ * Bill Joy UCB September 11, 1977
+ *
+ * This would be better written in snobol!
+ *
+ * Normally fixes error flags in a pi listing
+ * Optional - causes fixing of '---' and initial blank widthin a pxp profile.
+ */
+
+char   flag, dflag;
+
+main(argc, argv)
+       int argc;
+       char *argv[];
+{
+
+       argc--, argv++;
+       if (argc > 0 && argv[0][0] == '-' && argv[0][1] == 'd')
+               dflag++, argc--, argv++;
+       if (argc > 0 && argv[0][0] == '-')
+               flag++, argc--, argv++;
+       if (argc != 0) {
+               write(2, "Usage: csfix\n", 13);
+               exit(1);
+       }
+       while (getline()) {
+               if (errline()) {
+                       flag ? fixpxp() : reformat();
+                       continue;
+               }
+               if (flag) {
+                       fixdigits();
+                       continue;
+               }
+               if (spwarn())
+                       continue;
+               if (nontriv())
+                       save();
+               if (dflag)
+                       fixdigits();
+               else
+                       putline();
+       }
+       exit(0);
+}
+
+char   line[160], flagee[160];
+
+getline()
+{
+       register char *cp, c;
+
+       for (cp = line, c = getchar(); c != '\n' && c != EOF; c = getchar())
+               *cp++ = c;
+       if (c == EOF)
+               return (0);
+       *cp = 0;
+       return (1);
+}
+
+errline()
+{
+       register int i;
+       register char *cp;
+
+       for (cp = line; cp[0] && cp[1] && cp[2]; cp++)
+               if (cp[0] == '-' && cp[1] == '-' && cp[2] == '-')
+                       return (1);
+       return (0);
+}
+
+reformat()
+{
+       register char *cp, c, *tail;
+
+       printf("%2.2s", line);
+       if (line[0] != 'w')
+               printf("\\l'\\w`w `u-\\w`%2.2s`u '", line);
+       for (cp = line; *cp != 0 && *cp != '^'; cp++)
+               continue;
+       tail = cp + 1;
+       if (cp[-1] == '\b' && cp[-2] == '|')
+               cp =- 2;
+       c = flagee[cp - line];
+       flagee[cp - line] = 0;
+       printf("\\l'\\w`%s`u-\\w`w `u\\&\\(rh'", flagee);
+       flagee[cp - line] = c;
+       printf("\\l'(\\w`%c`u-\\w`^`u)/2 '", c);
+       printf("\\(ua");
+       printf("\\l'(\\w`%c`u-\\w`^`u)/2 '", c);
+       printf("\\l'\\w`---`u\\&\\(rh'%s\n", tail+3);
+}
+
+nontriv()
+{
+
+       switch (line[0]) {
+               case 'E':
+               case 'e':
+               case 'w':
+               case 's':
+               case 0:
+                       return (0);
+       }
+       return (1);
+}
+
+save()
+{
+
+       strcpy(flagee, line);
+}
+
+putline()
+{
+
+       printf("%s\n", flag ? digitty(0) : line);
+}
+
+spwarn()
+{
+
+       if (line[0] != ' ' || line[1] != ' ' || line[2] != 'w')
+               return (0);
+       printf("  \\l'(\\w`E`u-\\w`w`u)/2 'w\\l'(\\w`E`u-\\w`w`u)/2 '");
+       printf(&line[3]);
+       printf("\n");
+       return (1);
+}
+
+fixpxp()
+{
+       register char *cp;
+
+       for (cp = line; *cp != '-'; cp++)
+               continue;
+       *cp = 0;
+       printf("%s\\l'\\w`\\0\\0\\0\\0`u-\\w`.`u\\&\\(rh'%s\n", digitty(1), cp + 3);
+}
+
+digitty(yup)
+       char yup;
+{
+       register char *cp, *dp, *lp;
+
+       for (lp = line; *lp && *lp != '|'; lp++)
+               continue;
+       if (yup == 0 && !*lp)
+               return (line);
+       for (cp = line, dp = flagee; cp < lp; cp++)
+               if (*cp == ' ')
+                       *dp++ = '\\', *dp++ = '0';
+               else
+                       *dp++ = *cp;
+       strcpy(dp, cp);
+       return (flagee);
+}
+
+fixdigits()
+{
+       register char *cp, c;
+
+       for (cp = line; *cp == ' ' || *cp >= '0' && *cp <= '9'; cp++)
+               continue;
+       c = *cp, *cp = 0;
+       digitty(1);
+       *cp = c;
+       printf("%s%s\n", flagee, cp);
+}
diff --git a/doc/pascal/data b/doc/pascal/data
new file mode 100644 (file)
index 0000000..3f9cfb5
--- /dev/null
@@ -0,0 +1,3 @@
+line one.
+line two.
+line three is the end.
diff --git a/doc/pascal/digits.p b/doc/pascal/digits.p
new file mode 100644 (file)
index 0000000..1e59d8d
--- /dev/null
@@ -0,0 +1,9 @@
+program digits(output);
+var r: real;
+begin
+r := 0.;
+r := .0;
+r := 1.e10;
+r := .05e-10;
+writeln(r)
+end.
diff --git a/doc/pascal/digitsout b/doc/pascal/digitsout
new file mode 100644 (file)
index 0000000..e2e6ea5
--- /dev/null
@@ -0,0 +1,8 @@
+     4  r := 0.;
+e \l'\w`w `u-\w`e `u '\l'\w`     4  r := 0.`u-\w`w `u\&\(rh'\l'(\w`;`u-\w`^`u)/2 '\(ua\l'(\w`;`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Digits required after decimal point
+     5  r := .0;
+e \l'\w`w `u-\w`e `u '\l'\w`     5  r := `u-\w`w `u\&\(rh'\l'(\w`.`u-\w`^`u)/2 '\(ua\l'(\w`.`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Digits required before decimal point
+     6  r := 1.e10;
+e \l'\w`w `u-\w`e `u '\l'\w`     6  r := 1.`u-\w`w `u\&\(rh'\l'(\w`e`u-\w`^`u)/2 '\(ua\l'(\w`e`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Digits required after decimal point
+     7  r := .05e-10;
+e \l'\w`w `u-\w`e `u '\l'\w`     7  r := `u-\w`w `u\&\(rh'\l'(\w`.`u-\w`^`u)/2 '\(ua\l'(\w`.`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Digits required before decimal point
diff --git a/doc/pascal/expr.p b/doc/pascal/expr.p
new file mode 100644 (file)
index 0000000..60109af
--- /dev/null
@@ -0,0 +1,21 @@
+program x(output);
+var
+       a: set of char;
+       b: Boolean;
+       c: (red, green, blue);
+       p: ^ integer;
+       A: alfa;
+       B: packed array [1..5] of char;
+begin
+       b := true;
+       c := red;
+       new(p);
+       a := [];
+       A := 'Hello, yellow';
+       b := a and b;
+       a := a * 3;
+       if input < 2 then writeln('boo');
+       if p <= 2 then writeln('sure nuff');
+       if A = B then writeln('same');
+       if c = true then writeln('hue''s and color''s')
+end.
diff --git a/doc/pascal/exprout b/doc/pascal/exprout
new file mode 100644 (file)
index 0000000..bb1c4fd
--- /dev/null
@@ -0,0 +1,37 @@
+Berkeley Pascal PI -- Version 1.1 (January 4, 1979)
+
+Sat Mar 31 11:50 1979  expr.p
+
+     1  program x(output);
+     2  var
+     3          a: set of char;
+     4          b: Boolean;
+     5          c: (red, green, blue);
+     6          p: ^ integer;
+     7          A: alfa;
+     8          B: packed array [1..5] of char;
+     9  begin
+    10          b := true;
+    11          c := red;
+    12          new(p);
+    13          a := [];
+    14          A := 'Hello, yellow';
+    15          b := a and b;
+    16          a := a * 3;
+    17          if input < 2 then writeln('boo');
+    18          if p <= 2 then writeln('sure nuff');
+    19          if A = B then writeln('same');
+    20          if c = true then writeln('hue''s and color''s')
+    21  end.
+E 14 - Constant string too long
+E 15 - Left operand of and must be Boolean, not set
+E 16 - Cannot mix sets with integers and reals as operands of *
+E 17 - files may not participate in comparisons
+E 18 - pointers and integers cannot be compared - operator was <=
+E 19 - Strings not same length in = comparison
+E 20 - scalars and Booleans cannot be compared - operator was =
+e 20 - Input is used but not defined in the program statement
+In program x:
+  w - constant green is never used
+  w - constant blue is never used
+  w - variable B is used but never set
diff --git a/doc/pascal/first.p b/doc/pascal/first.p
new file mode 100644 (file)
index 0000000..1919694
--- /dev/null
@@ -0,0 +1,4 @@
+program first(output)
+begin
+       writeln('Hello, world!')
+end.
diff --git a/doc/pascal/firstobjout b/doc/pascal/firstobjout
new file mode 100644 (file)
index 0000000..0129da1
--- /dev/null
@@ -0,0 +1,2 @@
+Hello, world!
+1 statement executed in 0.02 seconds cpu time
diff --git a/doc/pascal/firstobjout2 b/doc/pascal/firstobjout2
new file mode 100644 (file)
index 0000000..af5626b
--- /dev/null
@@ -0,0 +1 @@
+Hello, world!
diff --git a/doc/pascal/firstout b/doc/pascal/firstout
new file mode 100644 (file)
index 0000000..1c61517
--- /dev/null
@@ -0,0 +1,6 @@
+     2  begin
+e \l'\w`w `u-\w`e `u '\l'\w`     2  `u-\w`w `u\&\(rh'\l'(\w`b`u-\w`^`u)/2 '\(ua\l'(\w`b`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted ';'
+Execution begins...
+Hello, world!
+Execution terminated
+1 statement executed in 0.04 seconds cpu time
diff --git a/doc/pascal/fixcomments b/doc/pascal/fixcomments
new file mode 100644 (file)
index 0000000..5201c8f
--- /dev/null
@@ -0,0 +1,6 @@
+1i
+.ta 3.25i
+.
+g/           *{/s//    {/
+w
+q
diff --git a/doc/pascal/fixkatscript b/doc/pascal/fixkatscript
new file mode 100644 (file)
index 0000000..7394819
--- /dev/null
@@ -0,0 +1,6 @@
+1t1
+1s/.*/\\*b&\\fR/
+3t3
+3s/.*/\\*b&\\fR/
+w
+q
diff --git a/doc/pascal/kat.p b/doc/pascal/kat.p
new file mode 100644 (file)
index 0000000..6d80453
--- /dev/null
@@ -0,0 +1,13 @@
+program kat(input, output);
+var
+    ch: char;
+begin
+    while not eof do begin
+       while not eoln do begin
+           read(ch);
+           write(ch)
+       end;
+       readln;
+       writeln
+    end
+end { kat }.
diff --git a/doc/pascal/kat2.p b/doc/pascal/kat2.p
new file mode 100644 (file)
index 0000000..0dbc01a
--- /dev/null
@@ -0,0 +1,23 @@
+program kat(input, output);
+var
+    ch: char;
+    i: integer;
+    name: packed array [1..100] of char;
+begin
+    i := 1;
+    repeat
+       if i < argc then begin
+           argv(i, name);
+           reset(input, name);
+           i := i + 1
+       end;
+       while not eof do begin
+           while not eoln do begin
+               read(ch);
+               write(ch)
+           end;
+           readln;
+           writeln
+       end
+    until i >= argc
+end { kat }.
diff --git a/doc/pascal/kat2out b/doc/pascal/kat2out
new file mode 100644 (file)
index 0000000..100f05c
--- /dev/null
@@ -0,0 +1,7 @@
+\0\0\0\0\02\0\0\0\0\03\0\0\0\0\05\0\0\0\0\07\0\0\0\011\0\0\0\013\0\0\0\017\0\0\0\019\0\0\0\023\0\0\0\029
+\0\0\0\031\0\0\0\037\0\0\0\041\0\0\0\043\0\0\0\047\0\0\0\053\0\0\0\059\0\0\0\061\0\0\0\067\0\0\0\071
+\0\0\0\073\0\0\0\079\0\0\0\083\0\0\0\089\0\0\0\097\0\0\0101\0\0\0103\0\0\0107\0\0\0109\0\0\0113
+\0\0\0127\0\0\0131\0\0\0137\0\0\0139\0\0\0149\0\0\0151\0\0\0157\0\0\0163\0\0\0167\0\0\0173
+\0\0\0179\0\0\0181\0\0\0191\0\0\0193\0\0\0197\0\0\0199\0\0\0211\0\0\0223\0\0\0227\0\0\0229
+
+930\0statements executed in 0.24 seconds cpu time
diff --git a/doc/pascal/kat3.p b/doc/pascal/kat3.p
new file mode 100644 (file)
index 0000000..411205c
--- /dev/null
@@ -0,0 +1,23 @@
+program kat(input, output);
+var
+    ch: char;
+    i: integer;
+    name: packed array [1..100] of char;
+begin
+    i := 1;
+    repeat
+        if i < argc then begin
+            argv(i, name);
+            reset(input, name);
+            i := i + 1
+        end;
+        while not eof do begin
+            while not eoln do begin
+                read(ch);
+                write(ch)
+            end;
+            readln;
+            writeln
+        end
+    until i >= argc
+end { kat }.
diff --git a/doc/pascal/katin b/doc/pascal/katin
new file mode 100644 (file)
index 0000000..220793b
--- /dev/null
@@ -0,0 +1,2 @@
+This is a line of text.
+The next line contains only an end-of-file (an invisible control-d!)
diff --git a/doc/pascal/katout b/doc/pascal/katout
new file mode 100644 (file)
index 0000000..2c5e46b
--- /dev/null
@@ -0,0 +1,26 @@
+Berkeley Pascal PI -- Version 1.1 (January 4, 1979)
+
+Sat Mar 31 11:50 1979  kat.p
+
+\0\0\0\0\01\0\0program kat(input, output);
+\0\0\0\0\02\0\0var
+\0\0\0\0\03\0\0\0\0\0\0ch: char;
+\0\0\0\0\04\0\0begin
+\0\0\0\0\05\0\0\0\0\0\0while not eof do begin
+\0\0\0\0\06\0\0\0\0\0\0\0\0\0\0while not eoln do begin
+\0\0\0\0\07\0\0\0\0\0\0\0\0\0\0\0\0\0\0read(ch);
+\0\0\0\0\08\0\0\0\0\0\0\0\0\0\0\0\0\0\0write(ch)
+\0\0\0\0\09\0\0\0\0\0\0\0\0\0\0end;
+\0\0\0\010\0\0\0\0\0\0\0\0\0\0readln;
+\0\0\0\011\0\0\0\0\0\0\0\0\0\0writeln
+\0\0\0\012\0\0\0\0\0\0end
+\0\0\0\013\0\0end { kat }.
+Execution begins...
+\0\0\0\0\02\0\0\0\0\03\0\0\0\0\05\0\0\0\0\07\0\0\0\011\0\0\0\013\0\0\0\017\0\0\0\019\0\0\0\023\0\0\0\029
+\0\0\0\031\0\0\0\037\0\0\0\041\0\0\0\043\0\0\0\047\0\0\0\053\0\0\0\059\0\0\0\061\0\0\0\067\0\0\0\071
+\0\0\0\073\0\0\0\079\0\0\0\083\0\0\0\089\0\0\0\097\0\0\0101\0\0\0103\0\0\0107\0\0\0109\0\0\0113
+\0\0\0127\0\0\0131\0\0\0137\0\0\0139\0\0\0149\0\0\0151\0\0\0157\0\0\0163\0\0\0167\0\0\0173
+\0\0\0179\0\0\0181\0\0\0191\0\0\0193\0\0\0197\0\0\0199\0\0\0211\0\0\0223\0\0\0227\0\0\0229
+
+Execution terminated
+925\0statements executed in 0.21 seconds cpu time
diff --git a/doc/pascal/katscript b/doc/pascal/katscript
new file mode 100644 (file)
index 0000000..6abbc99
--- /dev/null
@@ -0,0 +1,5 @@
+\*bThis is a line of text.\fR
+This is a line of text.
+\*bThe next line contains only an end-of-file (an invisible control-d!)\fR
+The next line contains only an end-of-file (an invisible control-d!)
+287 statements executed in 0.02 seconds cpu time
diff --git a/doc/pascal/makefile b/doc/pascal/makefile
new file mode 100755 (executable)
index 0000000..2977c4c
--- /dev/null
@@ -0,0 +1,85 @@
+# This makefile assumes that csh is running the figures
+FIGURES=\
+       firstout firstobjout firstobjout2\
+       bigger2.p bigger3.p bigout1 bigger6.p bigout2 bigout3 bigout4\
+       primeout1 primeout2\
+       digitsout synerrout synerr2out\
+       mismout clashout sinout1 sinout2\
+       exprout typequout primeout3\
+       katout copydataout kat2out katscript xxxxqqqout xxxxqqqout2\
+       primes primes-d\
+       comments1.p commentsout
+puman: ${FIGURES}
+       soelim puman0.n | tbl | /usr/new/vtroff -o-1
+csfix:
+       cc -O csfix.c -o csfix -lS
+firstout: first.p csfix
+       pix first.p |& expand | csfix >firstout
+firstobjout: first.p
+       pi first.p >& firstobjout ; px >& firstobjout
+firstobjout2: first.p
+       pi -p first.p >& firstobjout2 ; px >& firstobjout2
+bigger2.p: bigger.p
+       -expand bigger.p >bigger2.p
+bigger3.p: bigger2.p csfix
+       number bigger2.p | expand | csfix -d >bigger3.p
+bigout1: bigger.p csfix
+       pix bigger.p |& expand | csfix  >bigout1
+bigger6.p: bigger5.p csfix
+       number bigger5.p | expand | csfix -d >bigger6.p
+bigout2: bigger4.p
+       pix bigger4.p |& expand >bigout2
+bigout3: bigger7.p
+       pix bigger7.p |& expand >bigout3
+bigout4: bigger7.p
+       (pix bigger7.p >/dev/null) |& expand > bigout4
+primeout1: primes.p csfix
+       pix -l -z primes.p |& expand | csfix - >primeout1
+primeout2: primes.p csfix
+       pxp -z primes.p |& expand | csfix - >primeout2
+digitsout: digits.p csfix
+       pi digits.p |& expand | csfix >digitsout
+synerrout: synerr.p csfix
+       pi -l synerr.p |& expand | csfix >synerrout
+synerr2out: synerr2.p csfix
+       pix -l synerr2.p |& expand | csfix >synerr2out
+mismout: mism.p csfix
+       pi -l mism.p |& expand | csfix >mismout
+clashout: clash.p
+       pi clash.p |& expand >clashout
+sinout1: sin1.p
+       pi sin1.p |& expand >sinout1
+sinout2: sin2.p
+       pi sin2.p |& expand >sinout2
+exprout: expr.p
+       pi -l expr.p | expand >exprout
+typequout: typequ.p
+       -pi typequ.p >typequout
+primeout3: primes2.p csfix
+       pix primes2.p |& expand | csfix -d >primeout3
+katout: kat.p csfix primes
+       pix -l kat.p <primes |& expand | csfix -d >katout
+copydataout: copydata.p csfix
+       pix -l copydata.p |& expand | csfix -d >copydataout
+kat2out: kat2.p
+       -pi kat2.p ; px obj primes |& csfix -d >kat2out
+xxxxqqqout: kat2.p
+       -pi kat2.p
+       -px obj xxxxqqq >& xxxxqqqout
+xxxxqqqout2: kat2.p
+       pi -p kat2.p
+       -px obj xxxxqqq >& xxxxqqqout2
+primes: primes.p
+       pix -p primes.p > primes
+primes-d: primes
+       csfix -d <primes >primes-d
+katscript: katin
+       px obj katin >& katscript
+       -ed - katscript < fixkatscript
+comments1.p: comments.p
+       -expand comments.p >comments1.p
+commentsout: comments.p
+       pxp comments.p |& expand >commentsout
+       -ed - commentsout < fixcomments
+clean:
+       -rm csfix pmon.out obj ${FIGURES}
diff --git a/doc/pascal/mism.p b/doc/pascal/mism.p
new file mode 100644 (file)
index 0000000..a690b1e
--- /dev/null
@@ -0,0 +1,5 @@
+program mismatch(output)
+begin
+       writeln('***');
+       { The next line is the last line in the file }
+       writeln
diff --git a/doc/pascal/mismout b/doc/pascal/mismout
new file mode 100644 (file)
index 0000000..586b84c
--- /dev/null
@@ -0,0 +1,11 @@
+Berkeley Pascal PI -- Version 1.1 (January 4, 1979)
+
+Sat Mar 31 11:50 1979  mism.p
+
+     1  program mismatch(output)
+     2  begin
+e \l'\w`w `u-\w`e `u '\l'\w`     2  `u-\w`w `u\&\(rh'\l'(\w`b`u-\w`^`u)/2 '\(ua\l'(\w`b`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted ';'
+     3          writeln('***');
+     4          { The next line is the last line in the file }
+     5          writeln
+E \l'\w`w `u-\w`E `u '\l'\w`     5          writeln`u-\w`w `u\&\(rh'\l'(\w``u-\w`^`u)/2 '\(ua\l'(\w``u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Unexpected end-of-file - QUIT
diff --git a/doc/pascal/motd b/doc/pascal/motd
new file mode 100644 (file)
index 0000000..fbb69ce
--- /dev/null
@@ -0,0 +1,3 @@
+Cory Hall 11/70
+
+Type 'msgs' for latest system messages (Megabyte of memory installed)
diff --git a/doc/pascal/primeout1 b/doc/pascal/primeout1
new file mode 100644 (file)
index 0000000..988d01c
--- /dev/null
@@ -0,0 +1,43 @@
+Berkeley Pascal PI -- Version 1.1 (January 4, 1979)
+
+Sat Mar 31 11:50 1979  primes.p
+
+\0\0\0\0\01\0\0program primes(output);
+\0\0\0\0\02\0\0const n = 50; n1 = 7; (*n1 = sqrt(n)*)
+\0\0\0\0\03\0\0var i,k,x,inc,lim,square,l: integer;
+\0\0\0\0\04\0\0\0\0\0\0prim: boolean;
+\0\0\0\0\05\0\0\0\0\0\0p,v: array[1..n1] of integer;
+\0\0\0\0\06\0\0begin
+\0\0\0\0\07\0\0\0\0\0write(2:6, 3:6); l := 2;
+\0\0\0\0\08\0\0\0\0\0x := 1; inc := 4; lim := 1; square := 9;
+\0\0\0\0\09\0\0\0\0\0for i := 3 to n do
+\0\0\0\010\0\0\0\0\0begin (*find next prime*)
+\0\0\0\011\0\0\0\0\0\0\0\0repeat x := x + inc; inc := 6-inc;
+\0\0\0\012\0\0\0\0\0\0\0\0\0\0\0if square <= x then
+\0\0\0\013\0\0\0\0\0\0\0\0\0\0\0\0\0\0begin lim := lim+1;
+\0\0\0\014\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0v[lim] := square; square := sqr(p[lim+1])
+\0\0\0\015\0\0\0\0\0\0\0\0\0\0\0\0\0\0end ;
+\0\0\0\016\0\0\0\0\0\0\0\0\0\0\0k := 2; prim := true;
+\0\0\0\017\0\0\0\0\0\0\0\0\0\0\0while prim and (k<lim) do
+\0\0\0\018\0\0\0\0\0\0\0\0\0\0\0begin k := k+1;
+\0\0\0\019\0\0\0\0\0\0\0\0\0\0\0\0\0\0if v[k] < x then v[k] := v[k] + 2*p[k];
+\0\0\0\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0prim := x <> v[k]
+\0\0\0\021\0\0\0\0\0\0\0\0\0\0\0end
+\0\0\0\022\0\0\0\0\0\0\0\0until prim;
+\0\0\0\023\0\0\0\0\0\0\0\0if i <= n1 then p[i] := x;
+\0\0\0\024\0\0\0\0\0\0\0\0write(x:6); l := l+1;
+\0\0\0\025\0\0\0\0\0\0\0\0if l = 10 then
+\0\0\0\026\0\0\0\0\0\0\0\0\0\0\0begin writeln; l := 0
+\0\0\0\027\0\0\0\0\0\0\0\0\0\0\0end
+\0\0\0\028\0\0\0\0\0end ;
+\0\0\0\029\0\0\0\0\0writeln;
+\0\0\0\030\0\0end .
+Execution begins...
+\0\0\0\0\02\0\0\0\0\03\0\0\0\0\05\0\0\0\0\07\0\0\0\011\0\0\0\013\0\0\0\017\0\0\0\019\0\0\0\023\0\0\0\029
+\0\0\0\031\0\0\0\037\0\0\0\041\0\0\0\043\0\0\0\047\0\0\0\053\0\0\0\059\0\0\0\061\0\0\0\067\0\0\0\071
+\0\0\0\073\0\0\0\079\0\0\0\083\0\0\0\089\0\0\0\097\0\0\0101\0\0\0103\0\0\0107\0\0\0109\0\0\0113
+\0\0\0127\0\0\0131\0\0\0137\0\0\0139\0\0\0149\0\0\0151\0\0\0157\0\0\0163\0\0\0167\0\0\0173
+\0\0\0179\0\0\0181\0\0\0191\0\0\0193\0\0\0197\0\0\0199\0\0\0211\0\0\0223\0\0\0227\0\0\0229
+
+Execution terminated
+1404\0statements executed in 0.16 seconds cpu time
diff --git a/doc/pascal/primeout2 b/doc/pascal/primeout2
new file mode 100644 (file)
index 0000000..0c0ee0e
--- /dev/null
@@ -0,0 +1,50 @@
+Berkeley Pascal PXP -- Version 1.1 (November 6, 1978)
+
+Sat Mar 31 11:50 1979  primes.p
+
+Profiled Sat Mar 31 13:02 1979
+
+\0\0\0\0\01\0\0\0\0\0\0\0\01.\l'\w`\0\0\0\0`u-\w`.`u\&\(rh'|program primes(output);
+\0\0\0\0\02\0\0\0\0\0\0\0\0\0\0\0\0\0|const
+\0\0\0\0\02\0\0\0\0\0\0\0\0\0\0\0\0\0|    n = 50;
+\0\0\0\0\02\0\0\0\0\0\0\0\0\0\0\0\0\0|    n1 = 7; (*n1 = sqrt(n)*)
+\0\0\0\0\03\0\0\0\0\0\0\0\0\0\0\0\0\0|var
+\0\0\0\0\03\0\0\0\0\0\0\0\0\0\0\0\0\0|    i, k, x, inc, lim, square, l: integer;
+\0\0\0\0\04\0\0\0\0\0\0\0\0\0\0\0\0\0|    prim: boolean;
+\0\0\0\0\05\0\0\0\0\0\0\0\0\0\0\0\0\0|    p, v: array [1..n1] of integer;
+\0\0\0\0\06\0\0\0\0\0\0\0\0\0\0\0\0\0|begin
+\0\0\0\0\07\0\0\0\0\0\0\0\0\0\0\0\0\0|    write(2: 6, 3: 6);
+\0\0\0\0\07\0\0\0\0\0\0\0\0\0\0\0\0\0|    l := 2;
+\0\0\0\0\08\0\0\0\0\0\0\0\0\0\0\0\0\0|    x := 1;
+\0\0\0\0\08\0\0\0\0\0\0\0\0\0\0\0\0\0|    inc := 4;
+\0\0\0\0\08\0\0\0\0\0\0\0\0\0\0\0\0\0|    lim := 1;
+\0\0\0\0\08\0\0\0\0\0\0\0\0\0\0\0\0\0|    square := 9;
+\0\0\0\0\09\0\0\0\0\0\0\0\0\0\0\0\0\0|    for i := 3 to n do begin (*find next prime*)
+\0\0\0\0\09\0\0\0\0\0\0\0\0\0\0\048.\l'\w`\0\0\0\0`u-\w`.`u\&\(rh'|    repeat
+\0\0\0\011\0\0\0\0\0\0\0\0\0\0\0\0\0\0\076.\l'\w`\0\0\0\0`u-\w`.`u\&\(rh'|    x := x + inc;
+\0\0\0\011\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    inc := 6 - inc;
+\0\0\0\012\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    if square <= x then begin
+\0\0\0\013\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\05.\l'\w`\0\0\0\0`u-\w`.`u\&\(rh'|    lim := lim + 1;
+\0\0\0\014\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    v[lim] := square;
+\0\0\0\014\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    square := sqr(p[lim + 1])
+\0\0\0\014\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    end;
+\0\0\0\016\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    k := 2;
+\0\0\0\016\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    prim := true;
+\0\0\0\017\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    while prim and (k < lim) do begin
+\0\0\0\018\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0157.\l'\w`\0\0\0\0`u-\w`.`u\&\(rh'|    k := k + 1;
+\0\0\0\019\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    if v[k] < x then 
+\0\0\0\019\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\042.\l'\w`\0\0\0\0`u-\w`.`u\&\(rh'|    v[k] := v[k] + 2 * p[k];
+\0\0\0\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    prim := x <> v[k]
+\0\0\0\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    end
+\0\0\0\020\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|until prim;
+\0\0\0\023\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    if i <= n1 then 
+\0\0\0\023\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\05.\l'\w`\0\0\0\0`u-\w`.`u\&\(rh'|    p[i] := x;
+\0\0\0\024\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    write(x: 6);
+\0\0\0\024\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    l := l + 1;
+\0\0\0\025\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    if l = 10 then begin
+\0\0\0\026\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\05.\l'\w`\0\0\0\0`u-\w`.`u\&\(rh'|    writeln;
+\0\0\0\026\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    l := 0
+\0\0\0\026\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0|    end
+\0\0\0\026\0\0\0\0\0\0\0\0\0\0\0\0\0|    end;
+\0\0\0\029\0\0\0\0\0\0\0\0\0\0\0\0\0|    writeln
+\0\0\0\029\0\0\0\0\0\0\0\0\0\0\0\0\0|end.
diff --git a/doc/pascal/primeout3 b/doc/pascal/primeout3
new file mode 100644 (file)
index 0000000..217f2d3
--- /dev/null
@@ -0,0 +1,10 @@
+Execution begins...
+\0\0\0\0\02\0\0\0\0\03\0\0\0\0\05\0\0\0\0\07\0\0\0\011\0\0\0\013\0\0\0\017\0\0\0\019\0\0\0\023\0\0\0\029
+\0\0\0\031\0\0\0\037\0\0\0\041\0\0\0\043\0\0\0\047\0\0\0\053\0\0\0\059\0\0\0\061\0\0\0\067\0\0\0\071
+\0\0\0\073\0\0\0\079\0\0\0\083\0\0\0\089\0\0\0\097\0\0\0101\0\0\0103\0\0\0107\0\0\0109\0\0\0113
+\0\0\0127\0\0\0131\0\0\0137\0\0\0139\0\0\0149\0\0\0151\0\0\0157\0\0\0163\0\0\0167Subscript out of range
+
+\0\0\0\0\0\0\0\0Error at "primes"+8 near line 14
+
+Execution terminated abnormally
+941\0statements executed in 0.12 seconds cpu time
diff --git a/doc/pascal/primes b/doc/pascal/primes
new file mode 100644 (file)
index 0000000..aa282aa
--- /dev/null
@@ -0,0 +1,6 @@
+     2     3     5     7    11    13    17    19    23    29
+    31    37    41    43    47    53    59    61    67    71
+    73    79    83    89    97   101   103   107   109   113
+   127   131   137   139   149   151   157   163   167   173
+   179   181   191   193   197   199   211   223   227   229
+
diff --git a/doc/pascal/primes-d b/doc/pascal/primes-d
new file mode 100644 (file)
index 0000000..8d7eb8c
--- /dev/null
@@ -0,0 +1,6 @@
+\0\0\0\0\02\0\0\0\0\03\0\0\0\0\05\0\0\0\0\07\0\0\0\011\0\0\0\013\0\0\0\017\0\0\0\019\0\0\0\023\0\0\0\029
+\0\0\0\031\0\0\0\037\0\0\0\041\0\0\0\043\0\0\0\047\0\0\0\053\0\0\0\059\0\0\0\061\0\0\0\067\0\0\0\071
+\0\0\0\073\0\0\0\079\0\0\0\083\0\0\0\089\0\0\0\097\0\0\0101\0\0\0103\0\0\0107\0\0\0109\0\0\0113
+\0\0\0127\0\0\0131\0\0\0137\0\0\0139\0\0\0149\0\0\0151\0\0\0157\0\0\0163\0\0\0167\0\0\0173
+\0\0\0179\0\0\0181\0\0\0191\0\0\0193\0\0\0197\0\0\0199\0\0\0211\0\0\0223\0\0\0227\0\0\0229
+
diff --git a/doc/pascal/primes.p b/doc/pascal/primes.p
new file mode 100644 (file)
index 0000000..d840390
--- /dev/null
@@ -0,0 +1,30 @@
+program primes(output);
+const n = 50; n1 = 7; (*n1 = sqrt(n)*)
+var i,k,x,inc,lim,square,l: integer;
+    prim: boolean;
+    p,v: array[1..n1] of integer;
+begin
+   write(2:6, 3:6); l := 2;
+   x := 1; inc := 4; lim := 1; square := 9;
+   for i := 3 to n do
+   begin (*find next prime*)
+      repeat x := x + inc; inc := 6-inc;
+         if square <= x then
+            begin lim := lim+1;
+               v[lim] := square; square := sqr(p[lim+1])
+            end ;
+         k := 2; prim := true;
+         while prim and (k<lim) do
+         begin k := k+1;
+            if v[k] < x then v[k] := v[k] + 2*p[k];
+            prim := x <> v[k]
+         end
+      until prim;
+      if i <= n1 then p[i] := x;
+      write(x:6); l := l+1;
+      if l = 10 then
+         begin writeln; l := 0
+         end
+   end ;
+   writeln;
+end .
diff --git a/doc/pascal/primes2.p b/doc/pascal/primes2.p
new file mode 100644 (file)
index 0000000..7693de8
--- /dev/null
@@ -0,0 +1,30 @@
+program primes(output);
+const n = 50; n1 = 6; (*n1 = sqrt(n)*)
+var i,k,x,inc,lim,square,l: integer;
+    prim: boolean;
+    p,v: array[1..n1] of integer;
+begin
+   write(2:6, 3:6); l := 2;
+   x := 1; inc := 4; lim := 1; square := 9;
+   for i := 3 to n do
+   begin (*find next prime*)
+      repeat x := x + inc; inc := 6-inc;
+         if square <= x then
+            begin lim := lim+1;
+               v[lim] := square; square := sqr(p[lim+1])
+            end ;
+         k := 2; prim := true;
+         while prim and (k<lim) do
+         begin k := k+1;
+            if v[k] < x then v[k] := v[k] + 2*p[k];
+            prim := x <> v[k]
+         end
+      until prim;
+      if i <= n1 then p[i] := x;
+      write(x:6); l := l+1;
+      if l = 10 then
+         begin writeln; l := 0
+         end
+   end ;
+   writeln;
+end .
diff --git a/doc/pascal/puman0.n b/doc/pascal/puman0.n
new file mode 100644 (file)
index 0000000..6178dd8
--- /dev/null
@@ -0,0 +1,127 @@
+.so tmac.p
+.RP
+.TL
+Berkeley Pascal User's Manual
+.br
+Version 1.1 \- April, 1979
+.AU
+William N. Joy*
+.AU
+Susan L. Graham*
+.AU
+Charles B. Haley**
+.AI
+Computer Science Division
+.if n Department of Electrical Engineering
+.if n and Computer Science
+.if t Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+Berkeley, California  94720
+...AI
+...MH
+.AB
+.FS
+\s-2(C)\s0 1977, 1979 William N. Joy, Susan L. Graham, Charles B. Haley
+.FE
+.FS
+* Author's current address: Bell Laboratories, Murray Hill NJ  07974
+.FE
+.PP
+Berkeley
+Pascal
+is designed for interactive instructional use
+and runs on the \s-2PDP\s0 11 family of computers.
+It produces interpretive code,
+providing fast translation at the expense of slower execution speed.
+An execution profiler and
+Wirth's cross reference program are also
+available with the system.
+..An interpretive implementation for the \s-2VAX\s0 11/780 is nearly complete,
+..and a compiled version of the system, utilizing the code generator of
+..the portable C compiler, is under construction, and should be completed by
+..September, 1979.
+.PP
+The system supports full Pascal, with the exception of
+.B procedure
+and
+.B function
+names as parameters.
+The language accepted is very close to
+`standard' Pascal,
+with only a small number of extensions.
+.PP
+The
+.UM
+gives a list of sources relating to the
+.UX
+system, the Pascal language, and the
+.UP
+system.
+Basic usage examples are provided for the Pascal
+interpreter components
+.PI ,
+.X ,
+.IX ,
+and
+.XP .
+Errors commonly encountered in these programs are discussed.
+Details are given of special considerations due to the
+interactive implementation.
+A number of examples are provided including many dealing with
+input/output.  An appendix supplements Wirth's
+.I "Pascal Report"
+to form the full definition of the Berkeley implementation of the language.
+.AE
+.ND
+.SH
+'if n 'ND
+Introduction
+.PP
+.FS
+* The financial support of the first and second authors' work by
+the National Science Foundation under grants
+MCS74-07644-A03 and MCS78-07291,
+and the first author's work by an
+.SM IBM
+Graduate Fellowship
+are gratefully acknowledged.
+.FE
+.FS
+** Author's present address: Bell Laboratories, Murray Hill, NJ  07974.
+.FE
+The
+.UP
+.UM
+consists of five major sections and an appendix.
+In section 1 we give sources of information about 
+.UX ,
+about the programming
+language Pascal, and about the
+Berkeley
+implementation of the language.
+Section 2 introduces the
+Berkeley
+implementation and provides a number of basic examples.
+Section 3 discusses the error diagnostics produced by the translator
+.PI
+and the runtime interpreter
+.X .
+Section 4 describes input/output with special attention given to features
+of the interactive implementation and to features unique to
+.UX .
+Section 5 gives details on the components of the system
+and explanation of all relevant options.
+The
+.UM
+concludes with an appendix to Wirth's
+.I "Pascal Report"
+with which it forms a precise definition of the implementation.
+.SH
+History of the implementation
+.PP
+The first
+Berkeley
+system was written by Ken Thompson in early 1976.
+The main features of the present system result from the work
+of Charles Haley and William Joy during the latter half of 1976.
+Earlier versions of this system have been in use since January, 1977.
diff --git a/doc/pascal/puman1.n b/doc/pascal/puman1.n
new file mode 100644 (file)
index 0000000..0268e5e
--- /dev/null
@@ -0,0 +1,465 @@
+.if \n(xx .bp
+.if !\n(xx \{\
+.so tmac.p \}
+.if n 'ND
+'nr H1 0
+.NH
+Sources of information
+.PP
+This section lists the resources available on the UC Berkeley
+campus for information about
+general features of
+.UX ,
+text editing,
+the Pascal language,
+and the
+.UP
+implementation,
+concluding with a list of references.
+The available documents include both so-called standard documents \-
+those distributed with all
+.UX
+system \-
+and documents (such as this one) written at Berkeley.
+.NH 2
+Where to get documentation
+.PP
+On the UC Berkeley campus, documentation is available at the Computer
+Center Library, room 218B Evans Hall.
+The library is open from 8:00 A.M. to 5:00 P.M. Monday through Friday.
+Current documentation for most of the
+.UX
+system is also available ``on line'' at your terminal.
+Details on getting such documentation interactively are given
+in section 1.3.
+.NH 2
+Computer Center short courses
+.PP
+For those not enrolled in Computer Science Division courses, and
+who have no prior experience using
+.UX ,
+the short-courses offered by the staff of the Computer Center
+are highly recommended.
+These courses are offered free of charge, and are usually held
+at the beginning of each quarter.
+The two most valuable short courses for the
+Berkeley
+Pascal user are the ones dealing with basic use of
+.UX ,
+and with
+text editing.
+If you are unable to attend the short courses, documents
+for these courses are available at the Computer Center Library,
+and are recommended.
+The documents are in a tutorial format, so it is possible to use them on your
+own.
+.NH 2
+Documentation describing UNIX
+.PP
+The following documents are those recommended as tutorial and
+reference material about the
+.UX
+system.
+We give the documents with the introductory and tutorial materials
+first, the reference materials last.
+.SH
+UNIX For Beginners \- Second Edition
+.PP
+This document is the basic tutorial for 
+.UX
+available with the standard system.
+.SH
+Communicating with UNIX
+.PP
+This is also a basic tutorial on the system and assumes
+no previous familiarity
+with computers; it was written at Berkeley and is used in the short courses.
+.SH
+An introduction to the C shell
+.PP
+This document introduces
+.I csh,
+the shell in common use at Berkeley, and provides a good deal of general
+description about the way in which the system functions.
+It provides a useful glossary of terms used in discussing the system.
+.SH
+UNIX Programmer's Manual
+.PP
+This manual is the major source of details on the components of the
+.UX
+system.
+It consists of an Introduction,
+a permuted index,
+and eight command sections.
+Section 1 consists of descriptions of most of the ``commands''
+of
+.UX .
+Most of the other sections have limited relevance to the user
+of
+Berkeley
+Pascal, being of interest mainly to system programmers.
+The manual is available from the Computer Center Library.
+.PP
+U\s-2NIX\s0
+documentation often refers the reader to sections of the manual.
+Such a reference consists of a command name and a section number or name.
+An example of such a reference would be:
+.I ed
+(1).\(dg
+.FS
+\(dg Older systems may refer to the manual sections using roman numerals,
+e.g. \fIpi\fR (6).
+.FE
+Here
+.I ed
+is a command name \- the standard
+.UX
+text editor, and `(1)' indicates that its documentation is in section 1 of the
+manual.
+.PP
+The pieces of the
+Berkeley
+Pascal system are
+.I pi
+(6),
+.X
+(6),
+the combined Pascal translator and interpretive executor
+.IX
+(6),
+the Pascal execution profiler
+.XP
+(6),
+the Pascal cross-reference generator
+.I pxref
+(6),
+and the filter which interprets carriage control
+.I pcc
+(6).
+.PP
+It is possible to obtain a copy of a manual section
+by using the
+.I man
+(1) command.
+To get the Pascal documentation just described one could issue the
+command:
+.LS
+% \*bman new pi\fP
+.LE
+to the shell.
+The user input here is shown in
+.B "bold face" ;
+the `% ',
+which was printed by the shell as a prompt,
+is not.
+Similarly the command:
+.LS
+% \*bman man\fP
+.LE
+asks the
+.I man
+command to describe itself.
+.NH 2
+Text editing documents
+.PP
+The following documents introduce the various
+.UX
+text editors.
+Most Berkeley users will use a version of the text editor
+.I ex;
+either
+.I edit,
+which is a version of
+.I ex
+for new and casual users,
+.I ex
+itself,
+or
+.I vi
+(visual) which focuses on the display editing portion of
+.I ex.*
+.FS
+* Several other editors are available also.  The standard
+.UX
+editor
+.I ed,
+the \s-2RAND\s0 editor
+.I re,
+and an (undocumented) version of
+.I teco.
+.FE
+.SH
+A Tutorial Introduction to the UNIX Text Editor
+.PP
+This document, written by Brian Kernighan of Bell Laboratories,
+is a tutorial for the standard
+.UX
+text editor
+.I ed.
+It introduces you to the basics of text editing,
+and provides enough information to meet day-to-day editing needs,
+for
+.I ed
+users.
+.SH
+Edit: A tutorial
+.PP
+This introduces the use of
+.I edit,
+an editor similar to
+.I ed
+which provides a more hospitable environment for beginning users.
+The short courses on editing taught by the Computer Center use this
+document.
+.SH
+Ex/edit Command Summary
+.PP
+This summarizes the features of the editors
+.I ex
+and
+.I edit
+in a concise form.  If you have used a line oriented editor before
+this summary alone may be enough to get you started.
+.SH
+Ex Reference Manual \- Version 2.0
+.PP
+A complete reference on the features of
+.I ex
+and
+.I edit.
+.SH
+An Introduction to Display Editing with Vi
+.PP
+.I Vi
+is a display oriented text editor.  It can be used on most any \s-2CRT\s0
+terminal,
+and uses the screen as a window into the file you are editing.  Changes
+you make to the file are reflected in what you see.  This manual serves
+both as an introduction to editing with
+.I vi
+and a reference manual.
+.SH
+Vi Quick Reference
+.PP
+This reference card is a handy quick guide to
+.I vi;
+you should get one when you get the introduction to
+.I vi.
+.NH 2
+Pascal documents \- The language
+.PP
+This section describes the documents on the Pascal language
+which are likely to be most useful to the
+Berkeley
+Pascal user.
+Complete references for these documents are given in section 1.7.
+.SH
+Pascal User Manual
+.PP
+By Kathleen Jensen and Niklaus Wirth, the
+.I "User Manual"
+provides a tutorial introduction to the features
+of the language Pascal,
+and serves as an excellent quick-reference to the language.
+The reader with no familiarity with Algol-like languages 
+may prefer one of the Pascal text books listed below,
+as they provide more examples and explanation.
+Particularly important here are pages 116-118 which define the syntax
+of the language.
+Sections 13 and 14 and Appendix F pertain only to the
+6000-3.4 implementation of Pascal.
+.SH
+Pascal Report
+.PP
+By Niklaus Wirth, this document is bound with the
+.I "User Manual."
+It is the guiding reference for implementors and the fundamental
+definition of the language.
+Some programmers find this report too concise to be of practical use,
+preferring the
+.I "User Manual"
+as a reference.
+.SH
+Books on Pascal
+.PP
+Several good books which teach Pascal or use it as a medium are
+available.
+The books by Wirth
+.I "Systematic Programming"
+and
+.I "Algorithms + Data Structures = Programs"
+use Pascal as a vehicle for teaching programming and data structure
+concepts respectively.
+They are both recommended.
+Other books on Pascal are listed in the references below.
+.NH 2
+Pascal documents \- The Berkeley Implementation
+.PP
+This section describes the documentation which is available
+describing the
+Berkeley
+implementation of Pascal.
+.SH
+User's Manual
+.PP
+The document you are reading is the 
+.I "User's Manual"
+for
+.UP .
+We often refer the reader to the
+Jensen-Wirth
+.I "User Manual"
+mentioned above,
+a different document with a similar name.
+.SH
+Manual sections
+.PP
+The sections relating to Pascal in the
+.I "UNIX Programmer's Manual"
+are
+.IX
+(6),
+.PI
+(6),
+.I pcc
+(6),
+.X
+(6),
+.I pxp
+(6),
+and
+.I pxref
+(6).
+These sections give a description of each program,
+summarize the available options,
+indicate files used by the program,
+give basic information on the diagnostics produced 
+and include a list of known bugs.
+.SH
+Implementation notes
+.PP
+For those interested in the internal organization of the
+Berkeley
+Pascal system there are a series of
+.I "Implementation Notes"
+describing these details.
+The
+.I "Berkeley Pascal PXP Implementation Notes"
+describe the Pascal interpreter
+.X \|;
+and the
+.I "Berkeley Pascal PX Implementation Notes"
+describe the structure of the
+execution profiler
+.I pxp .
+.br
+.ne 8
+.NH 2
+References
+.de re
+.sp
+.IP
+'nf
+..
+.SH
+UNIX Documents
+.re
+.I "Communicating With UNIX"
+Computer Center
+University of California, Berkeley
+January, 1978.
+.re
+.I "Edit: a tutorial"
+Ricki Blau and James Joyce
+Computing Services Division, Computing Affairs
+University of California, Berkeley
+January, 1978.
+.re
+.I "Ex/edit Command Summary"
+Computer Center
+University of California, Berkeley
+August, 1978.
+.re
+.I "Ex Reference Manual \- Version 2.0"
+.I "An Introduction to Display Editing with Vi"
+.I "Vi Quick Reference"
+William Joy
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+April, 1979.
+.re
+.I "An Introduction to the C shell"
+William Joy
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+January, 1979.
+.re
+Brian W. Kernighan
+.I "UNIX for Beginners \- Second Edition"
+Bell Laboratories
+Murray Hill, New Jersey.
+.re
+Brian W. Kernighan
+.I "A Tutorial Introduction to the UNIX Text Editor"
+Bell Laboratories
+Murray Hill, New Jersey.
+.re
+Dennis M. Ritchie and Ken Thompson
+.I "The UNIX Time Sharing System"
+Communications of the ACM
+July 1974
+365-378.
+.re
+B. W. Kernighan and M. D. McIlroy
+.I "UNIX Programmer's Manual \- Seventh Edition"
+Bell Laboratories
+Murray Hill, New Jersey
+December, 1978.
+.ne 12
+.SH
+Pascal Language Documents
+.re
+Conway, Gries and Zimmerman
+.I "A Primer on PASCAL"
+Winthrop, Cambridge Mass.
+1976, 433 pp.
+.re
+Kathleen Jensen and Niklaus Wirth
+.I "Pascal \- User Manual and Report"
+Springer-Verlag, New York.
+1975, 167 pp.
+.re
+C. A. G. Webster
+.I "Introduction to Pascal"
+Heyden and Son, New York
+1976, 129pp.
+.re
+Niklaus Wirth
+.I "Algorithms + Data structures = Programs"
+Prentice-Hall, New York.
+1976, 366 pp.
+.re
+Niklaus Wirth
+.I "Systematic Programming"
+Prentice-Hall, New York.
+1973, 169 pp.
+.SH
+Berkeley Pascal documents
+.PP
+The following documents are available from the Computer Center Library
+at the University of California, Berkeley.
+.nf
+.re
+William N. Joy, Susan L. Graham, and Charles B. Haley
+.I "Berkeley Pascal User's Manual \- Version 1.1"
+April, 1979.
+.re
+William N. Joy
+.I "Berkeley Pascal PX Implementation Notes"
+Version 1.1, April 1979.
+.re
+William N. Joy
+.I "Berkeley Pascal PXP Implemetation Notex"
+Version 1.1, April 1979.
diff --git a/doc/pascal/puman2.n b/doc/pascal/puman2.n
new file mode 100644 (file)
index 0000000..6d45af5
--- /dev/null
@@ -0,0 +1,849 @@
+.if \n(xx .bp
+.if !\n(xx \{\
+.so tmac.p \}
+'if n 'ND
+.nr H1 1
+.NH
+Basic UNIX Pascal
+.PP
+The following sections
+explain the basics of using
+.UP .
+In examples here we use the text editor
+.I ex 
+(6).
+Users of the text editor
+.I ed
+should have little trouble following these examples,
+as
+.I ex
+is similar to
+.I ed .
+We use
+.I ex
+because it
+allows us to make clearer examples.\(dg
+.FS
+\(dg Users with \s-2CRT\s0 terminals should find the editor
+.I vi
+more pleasant to use;
+we do not show its use here because its display oriented nature
+makes it difficult to illustrate.
+.FE
+The new
+.UX
+user will find it helpful to read one of the text editor documents
+described in section 1.4 before continuing with this section.
+.NH 2
+A first program
+.PP
+To prepare a program for
+.UP
+we first need to have an account on
+.UX
+and to `login'
+to the system on this account.
+These procedures are described in the documents
+.I "Communicating with UNIX" 
+and
+.I "UNIX for Beginners".
+.PP
+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.
+The
+.UP
+system requires that programs reside in files which have names ending with
+the sequence `.p' so we will call our file `first.p'.
+.PP
+A sample editing session to create this file would begin:
+.LS
+% \*bex first.p\fR
+"first.p" No such file or directory
+:
+.LE
+We didn't expect the file to exist, so the error diagnostic doesn't
+bother us.
+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'
+command as follows.
+.LS
+:\*bappend\fR
+.B
+program first(output)
+begin
+       writeln('Hello, world!')
+end.
+\&.
+.R
+:
+.LE
+The line containing the single `\*b.\fR' character here indicated
+the end of the appended text.
+The `:' prompt indicates that
+.I ex
+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'
+so we can use the Pascal 
+translator and executor
+.IX
+on it.
+.LS
+:\*bwrite\fR
+"first.p" 4 lines, 59 characters
+:\*bquit\fR
+% 
+.LE
+We wrote out the file from the edit buffer here with the
+`write'
+command, and
+.I ex
+indicated the number of lines and characters written.
+We then quit the editor, and now have a prompt from the shell.\(dd
+.FS
+\(dd Our examples here assume you are using
+.I csh.
+.FE
+.KS
+.PP
+We are ready to try
+to translate and execute our program.
+.DS
+.tr '\(aa^\(ua
+% \*bpix first.p\fR
+.so firstout
+.tr ''^^
+%
+.DE
+.KE
+.PP
+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
+keyword
+.B begin
+on this line.
+If we look at the Pascal syntax charts in the Jensen-Wirth
+.I "User Manual" ,
+or at some of the sample programs therein, we will see that
+we have omitted the terminating `;' of the
+.B program 
+statement on the first
+line of our program.
+.PP
+One other thing to notice about the error diagnostic is the letter `e'
+at the beginning.
+It stands for `error',
+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
+.FS
+\*(dgThe standard Pascal warnings occur only when the associated
+.B s
+translator option is enabled.
+The
+.B s
+option is discussed in sections 5.1 and A.6 below.
+Warning diagnostics are discussed at the end of section 3.2,
+the associated
+.B w
+option is described in section 5.2.
+.FE
+.PP
+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.
+.PP
+Let us now fix the error in the program and translate it to a permanent
+object code file
+.I obj
+using
+.PI .
+The program
+.PI
+translates Pascal programs but stores the object code instead of executing it\*(dd.
+.FS
+\*(ddThis script indicates some other useful approaches to debugging
+Pascal programs.
+As in
+.I ed
+we can shorten commands in
+.I ex
+to an initial prefix of the command name as we did
+with the
+.I substitute
+command here.
+We have also used the `!' shell escape command here to execute other
+commands with a shell without leaving the editor.
+.FE
+.LS
+% \*bex first.p\fR
+"first.p" 4 lines, 59 characters
+:\*b1 print\fR
+program first(output)
+:\*bs/$/;\fR
+program first(output);
+:\*bwrite\fR
+"first.p" 4 lines, 60 characters
+:\*b!pi %\fR
+!pi first.p
+!
+:\*bquit\fR
+%
+.LE
+The first command issued from
+.I ex
+with the `!'
+involved the use of the `%' character which stands in this command for
+the file we are editing.
+.I Ex
+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.
+.PP
+If we now use the
+.UX
+.I ls
+list files command we can see what files we have:
+.LS
+% \*bls\fR
+first.p
+obj
+%
+.LE
+The file `obj' here contains the Pascal interpreter code.
+We can execute this by typing:
+.LS
+% \*bpx obj\fR
+.so firstobjout
+%
+.LE
+Alternatively, the command:
+.LS
+% \*bobj\fR
+.LE
+will have the same effect.
+Some examples of different ways to execute the program follow.
+.LS
+% \*bpx\fR
+.so firstobjout
+% \*bpi -p first.p\fR
+% \*bpx obj\fR
+.so firstobjout2
+% \*bpix -p first.p\fR
+.so firstobjout2
+%
+.LE
+.PP
+Note that
+.I px
+will assume that `obj' is the file we wish to execute
+if we don't tell it otherwise.
+The last two translations use the
+.B \-p
+no-post-mortem option to eliminate
+execution statistics and
+`Execution begins'
+and
+`Execution terminated'
+messages.
+See section 5.2 for more details.
+If we now look at the files in our directory we will see:
+.LS
+% \*bls\fR
+first.p
+obj
+%
+.LE
+We can give our object program a name other than `obj' by using the move
+command
+.I mv
+(1).
+Thus to name our program `hello':
+.LS
+% \*bmv obj hello\fR
+% \*bhello\fR
+Hello, world!
+% \*bls\fR
+first.p
+hello
+%
+.LE
+.KS
+Finally we can get rid of the Pascal object code by using the
+.I rm
+(1) remove file command, e.g.:
+.LS
+% \*brm hello\fR
+% \*bls\fR
+first.p
+%
+.LE
+.KE
+.PP
+For small programs which are being developed
+.IX
+tends to be more convenient to use than
+.PI
+and
+.X .
+Except for absence of the
+.I obj
+file after a
+.IX
+run,
+a
+.IX
+command is equivalent to a
+.PI
+command followed by a
+.X
+command.
+For larger programs,
+where a number of runs testing different parts of the program are
+to be made,
+.PI
+is useful as this
+.I obj
+file can be executed any desired number of times.
+.NH 2
+A larger program
+.PP
+Suppose that we have used the editor to put a larger program
+in the file `bigger.p'.
+We can list this program with line numbers by using the program
+.I num
+i.e.:
+.LS
+% \*bnum bigger.p\fR
+.so bigger3.p
+%
+.LE
+This program is similar to program 4.9 on page 30 of the
+Jensen-Wirth
+.I "User Manual" .
+A number of problems have been introduced into this example for
+pedagogical reasons.
+.br
+.ne 8
+.PP
+If we attempt to translate and execute the program using
+.IX
+we get the following response:
+.LS
+% \*bpix bigger.p\fR
+.so bigout1
+%
+.LE
+.PP
+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:
+.LS
+% \*bpi -l bigger.p\fR
+.LE
+There is no point in using
+.IX
+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.
+.FS
+\*(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.
+.FE
+We can do this with the command:
+.LS
+% \*bpi -l bigger.p | lpr\fR
+.LE
+.PP
+In the next few sections we will illustrate various aspects of the
+Berkeley
+Pascal system by correcting this program.
+.NH 2
+Correcting the first errors
+.PP
+Most of the errors which occurred in this program were
+.I syntactic
+errors, those in the format and structure of the program rather than
+its content.
+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.
+.PP
+In this example,
+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
+is being translated.
+In this case, we have accidentally omitted the trailing `*)' of the comment
+on line 8.
+We can begin an editor session to correct this problem by doing:
+.LS
+% \*bex bigger.p\fR
+"bigger.p" 24 lines, 512 characters
+:\*b8s/$/ *)\fR
+        s = 32;       (* 32 character width for interval [x, x+1] *)
+:
+.LE
+.PP
+The second diagnostic, given after line 16,
+indicates that the keyword
+.B do
+was expected before the keyword
+.B begin
+in the
+.B for
+statement.
+If we examine the
+.I statement
+syntax chart on page 118 of the
+Jensen-Wirth
+.I "User Manual"
+we will discover that
+.B do
+is a necessary part of the
+.B for
+statement.
+Similarly, we could have referred to section C.3 of the
+Jensen-Wirth
+.I "User Manual"
+to learn about the
+.B for
+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.
+.PP
+We can correct this problem by first scanning for the keyword
+.B for
+in the file and then substituting the keyword
+.B do
+to appear in front of the keyword
+.B begin
+there.
+Thus:
+.LS
+:\*b/for\fR
+       for i := 0 to lim begin
+:\*bs/begin/do &\fR
+       for i := 0 to lim do begin
+:
+.LE
+The next error in the program is easy to pinpoint.
+On line 18, we didn't hit the shift key and got a `9'
+instead of a `)'.
+The translator diagnosed that `x9'
+was an undefined variable and, later,
+that a `)' was missing in the statement.
+It should be stressed that
+.PI
+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
+errors.
+You must then determine the true cause of the error and make the
+appropriate correction to the source text.
+.PP
+This error also illustrates the fact that one error in the input may lead
+to multiple error diagnostics.
+.I Pi
+attempts
+to give only one diagnostic for each error,
+but single errors in the input sometimes appear to be more than
+one error.
+It is also the case that
+.PI
+may not detect an error when it occurs, but may detect it later in
+the input.
+This would have happened
+in this example if we had typed `x' instead of `x9'.
+.PP
+The translator next detected, on line 19, that the function
+.I Round
+and the variable
+.I h
+were undefined.
+It does not know about
+.I Round
+because
+.UP
+normally distinguishes between upper- and lower-case.
+On
+.UX
+lower-case is preferred\*(dg,
+.FS
+\*(dgOne good reason for using lower-case is that it is easier to type.
+.FE
+and all keywords and built-in
+.B procedure
+and
+.B function
+names are composed of lower-case letters,
+just as they are in the Jensen-Wirth
+.I "Pascal Report" .
+Thus we need to use the function
+.I round
+here.
+As far as
+.I h
+is concerned,
+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
+comment.
+This diagnostic need not, therefore, concern us.
+.PP
+The next error which occurred in the program caused the translator
+to insert a `;' before the statement calling
+.I writeln
+on line 23.
+If we examine the program around the point of error we will see
+that the actual error is that the keyword
+.B until
+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
+.B until
+was missing, but not until it saw the keyword
+.B end
+on line 24.
+The combination of these diagnostics indicate to us the true problem.
+.PP
+The final syntactic error message indicates that the translator needed an
+.B end
+keyword to match the
+.B begin 
+at line 15.
+Since the
+.B end
+at line 24 is supposed to match this
+.B begin ,
+we can infer that another
+.B begin
+must have been mismatched, and have matched this
+.B end .
+Thus we see that we need an
+.B end
+to match the
+.B begin
+at line 16,
+and to appear before the final
+.B end .
+We can make these corrections:
+.LS
+:\*b/x9/s//x)\fR
+                y := exp(-x) * sin(i * x);
+:\*b+s/Round/round\fR
+                n := round(s * y) + h;
+:\*b/write\fR
+                        write(' ');
+:\*b/\fR
+                writeln('*')
+:\*binsert\fR
+                \*buntil n = 0;\fR
+\&\*b.\fR
+:\*b$\fR
+end.
+:\*binsert\fR
+        \*bend\fR
+\&\*b.\fR
+:
+.LE
+.PP
+At the end of each
+.B procedure
+or
+.B function
+and the end of the
+.B program
+the translator summarizes references to undefined variables
+and improper usages of variables.
+It also gives
+warnings about potential errors.
+In our program, the summary errors do not indicate any further problems
+but the warning that
+.I c
+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
+.I sin ,
+so we can correct this expression, and translate the program.
+We have now made a correction for each diagnosed error
+in our program.
+.LS
+:\*b?i ?s//c /\fR
+               y := exp(-x) * sin(c * x);
+:\*bwrite\fR
+"bigger.p" 26 lines, 538 characters
+:\*b!pi %\fR
+!pi bigger.p
+!
+:\*bquit\fR
+%
+.LE
+It should be noted that the translator suppresses warning
+diagnostics for a particular
+.B procedure ,
+.B function
+or the main
+.B program
+when it finds severe syntax errors in that part of the source
+text.
+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.
+.KS
+.PP
+We are now ready to execute our program for the first
+time.
+We will do so in the next section after giving a listing
+of the corrected program for reference purposes.
+.ne 15
+.LS
+% \*bnumber bigger.p\fR
+.so bigger6.p
+%
+.LE
+.NH 2
+Executing the second example
+.PP
+We are now ready to execute the second example.
+The following output was produced by our first run.
+.LS
+% \*bpx\fR
+.so bigout2
+%
+.LE
+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:
+.ne 10
+.LS
+% \*bex bigger.p\fR
+"bigger.p" 26 lines, 538 characters
+:\*b17\fR
+        x := d / i
+:\*bs'/'*\fR
+        x := d * i
+:\*bwrite\fR
+"bigger.p" 26 lines, 538 characters
+:\*b!pix %\fR
+!pix bigger.p
+.so bigout3
+!
+:\*bq\fR
+%
+.LE
+.KS
+.PP
+This appears to be the output we wanted.
+We could now save the output in a file if we wished by using the shell
+to redirect the output:
+.LS
+% \*bpx > graph\fR
+.LE
+.KE
+We can use
+.I cat
+(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.
+.LS
+% \*bpx | lpr\fR
+.so bigout4
+%
+.LE
+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.:
+.LS
+% \*bpx |\|& lpr\fR
+%
+.LE
+or we can translate the program with the
+.B p
+option disabled on the command line as we did above.
+This will disable all post-mortem dumping including the statistics line,
+thus:
+.LS
+% \*bpi -p bigger.p\fR
+% \*bpx | lpr\fR
+%
+.LE
+This option also disables the statement limit which normally guards
+against infinite looping.
+You should not use it until your program is debugged.
+Also if
+.B p
+is specified and an error occurs, you will
+not get run time diagnostic information to help you
+determine what the problem is.
+.NH 2
+Formatting the program listing
+.PP
+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
+without a line number.
+A line containing only a control-l (form-feed) character
+will cause a page eject in the listing with the corresponding line number
+suppressed.
+This corresponds to an `eject' pseudo-instruction.
+See also section 5.2 for details on the
+.B n
+and
+.B i
+options of
+.PI .
+.NH 2
+Execution profiling
+.PP
+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
+of the error.
+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.
+.SH
+An example
+.PP
+A prime number is a number which is divisible only by itself and the
+number one.
+The program
+.I primes ,
+written by Niklaus Wirth,
+determines the first few prime numbers.
+In translating the program we have specified the
+.B z
+option to
+.IX .
+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
+.FS
+\*(dgThe counts
+are completely accurate only in the absence of runtime errors and nonlocal
+.B goto
+statements.
+This is not generally a problem, however, as in structured programs
+nonlocal
+.B goto
+statements occur infrequently,
+and counts are incorrect after abnormal termination only when the
+.I "upward look"
+described below to get a count passes a suspended call point.
+.FE
+When execution of the program completes, either normally or abnormally,
+this count data is written to the file
+.I pmon.out
+in the current directory.\*(dd
+.FS
+\*(dd\c
+.I Pmon.out
+has a name similar to
+.I mon.out
+the monitor file produced by the profiling facility of the C compiler
+.I cc
+(1).
+See
+.I prof
+(1) for a discussion of the C compiler profiling facilities.
+.FE
+It is then possible to prepare an execution profile by giving
+.XP
+the name of the file associated with this data, as was done in the following
+example.
+.LS
+% \*bpix -l -z primes.p\fR
+.so primeout1
+%
+.LE
+.SH
+Discussion
+.PP
+The header lines of the outputs of
+.IX
+and
+.XP
+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.
+This time serves to
+.I "version stamp"
+the input program.
+.I Pxp
+also indicates the time at which the profile data was gathered.
+.LS
+% \*bpxp -z primes.p\fR
+.so primeout2
+%
+.LE
+.KE
+.PP
+To determine the number of times a statement was executed,
+one looks to the left of the statement and finds the corresponding
+vertical bar `|'.
+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
+is the answer.
+Thus, in our example,
+.I k
+was incremented 157 times on line 18,
+while the
+.I write
+procedure call on line 24 was executed 48 times as given by the count
+on the
+.B repeat .
+.PP
+More information on
+.I pxp
+can be found in its manual section
+.XP
+(6)
+and in sections 5.4, 5.5 and 5.10.
diff --git a/doc/pascal/puman3.n b/doc/pascal/puman3.n
new file mode 100644 (file)
index 0000000..e371296
--- /dev/null
@@ -0,0 +1,712 @@
+.if \n(xx .bp
+.if !\n(xx \{\
+.so tmac.p \}
+.if n 'ND
+.nr H1 2
+.NH
+Error diagnostics
+.PP
+This section of the
+.UM
+discusses the error diagnostics of the programs
+.PI
+and
+.X .
+.I Pix
+is a simple but useful program which invokes
+.PI
+and
+.X
+to do all the real processing.
+See its manual section
+.IX
+(6)
+and section 5.2 below for more details.
+.NH 2
+Translator syntax errors
+.PP
+A few comments on the general nature of the syntax errors usually
+made by Pascal programmers
+and the recovery mechanisms of the current translator may help in using
+the system.
+.SH
+Illegal characters
+.PP
+Characters such as `$', `!', and `@' are not part of the language Pascal.
+If they are found in the source program,
+and are not part of a constant string, a constant character, or a comment,
+they are considered to be
+`illegal characters'.
+This can happen if you leave off an opening string quote `\(aa'.
+Note that the character `"', although used in English to quote strings,
+is not used to quote strings in Pascal.
+Most non-printing characters in your input are also illegal except
+in character constants and character strings.
+Except for the tab and form feed characters,
+which are used to ease formatting of the program,
+non-printing characters in the input file print as the character `?'
+so that they will show in your listing.
+.SH
+String errors
+.PP
+There is no character string of length 0 in Pascal.
+Consequently the input `\(aa\(aa' is not acceptable.
+Similarly, encountering an end-of-line after an opening string quote `\(aa'
+without encountering the matching closing quote yields the diagnostic
+``Unmatched \(aa for string''.
+It is permissible to use the character `#'
+instead of `\''
+to delimit character and constant strings for portability reasons.
+For this reason, a spuriously placed `#' sometimes causes the diagnostic
+about unbalanced quotes.
+Similarly, a `#' in column one is used when preparing programs which are to
+be kept in multiple files.
+See section 5.9 for details.
+.SH
+Comments in a comment, non-terminated comments
+.PP
+As we saw above, these errors are usually caused by leaving off a comment
+delimiter.
+You can convert parts of your program to comments
+without generating this diagnostic
+since there are two different kinds of comments \- those delimited by
+`{' and `}', and those delimited by `(*' and `*)'.
+Thus consider:
+.LS
+{ This is a comment enclosing a piece of program
+a := functioncall;     (* comment within comment *)
+procedurecall;
+lhs := rhs;            (* another comment *)
+}
+.LE
+.PP
+By using one kind of comment exclusively in your program you can use
+the other delimiters when you need to
+``comment out''
+parts of your program\*(dg.
+.FS
+\*(dgIf you wish to transport your program,
+especially to the 6000-3.4 implementation,
+you should use the character sequence `(*' to delimit comments.
+For transportation over the
+.I rcslink
+to Pascal 6000-3.4, the character `#' should be used to delimit characters
+and constant strings.
+.FE
+In this way you will also allow the translator to help by detecting
+statements accidentally placed within comments.
+.PP
+If a comment does not terminate before the end of the input file,
+the translator will point to the beginning of the comment,
+indicating that the comment is not terminated.
+In this case processing will terminate immediately.
+See the discussion of ``QUIT'' below.
+.SH
+Digits in numbers
+.PP
+This part of the language is a minor nuisance.
+Pascal requires digits in real numbers both before and after the decimal
+point.
+Thus the following statements, which look quite reasonable to
+.SM
+FORTRAN
+.NL
+users, generate diagnostics in Pascal:
+.LS
+.so digitsout
+.LE
+These same constructs are also illegal as input to the Pascal interpreter
+.I px .
+.SH
+Replacements, insertions, and deletions
+.PP
+When a syntax error is encountered in the input text,
+the parser invokes an error recovery procedure.
+This procedure examines the input text immediately after the point
+of error and considers a set of simple corrections to see whether they
+will allow the analysis to continue.
+These corrections involve replacing an input token with a different
+token,
+inserting a token,
+or replacing an input token with a different token.
+Most of these changes will not cause fatal syntax errors.
+The exception is the insertion of or replacement with a symbol
+such as an identifier or a number;
+in this case the recovery makes no attempt to determine
+.I which
+identifier or
+.I what 
+number should be inserted,
+hence these are considered fatal syntax errors.
+.PP
+Consider the following example.
+.LS
+% \*bpix -l synerr.p\fR
+.tr --
+.so synerrout
+%
+.LE
+The only surprise here may be that Pascal does not have an exponentiation
+operator, hence the complaint about `**'.
+This error illustrates that, if you assume that the language has a feature
+which it does not, the translator diagnostic may not indicate this,
+as the translator is unlikely to recognize the construct you supply.
+.SH
+Undefined or improper identifiers
+.PP
+If an identifier is encountered in the input but is undefined,
+the error recovery will replace it with an identifier of the
+appropriate class.
+Further references to this identifier will be summarized at the
+end of the containing
+.B procedure
+or
+.B function
+or at the end of the
+.B program
+if the reference occurred in the main program.
+Similarly,
+if an identifier is used in an inappropriate way,
+e.g. if a
+.B type
+identifier is used in an assignment statement,
+or if a simple variable
+is used where a
+.B record
+variable is required,
+a diagnostic will be produced and an identifier of the appropriate
+type inserted.
+Further incorrect references to this identifier will be flagged only
+if they involve incorrect use in a different way,
+with all incorrect uses being summarized in the same way as undefined
+variable uses are.
+.SH
+Expected symbols, malformed constructs
+.PP
+If none of the above mentioned corrections appear reasonable, the
+error recovery will examine the input 
+to the left of the point of error to see if there is only one symbol
+which can follow this input.
+If this is the case, the recovery will print a diagnostic which
+indicates that the given symbol was `Expected'.
+.PP
+In cases where none of these corrections resolve the problems
+in the input,
+the recovery may issue a diagnostic that indicates that the
+input is ``malformed''.
+If necessary, the translator may then skip forward in the input to
+a place where analysis can continue.
+This process may cause some errors in the text to be missed.
+.PP
+Consider the following example:
+.LS
+% \*bpix -l synerr2.p\fR
+.so synerr2out
+%
+.LE
+Here we misspelled
+.I input
+and gave a
+.SM FORTRAN
+style variable declaration
+which the translator diagnosed as a `Malformed declaration'.
+When, on line 6, we used `(' and `)' for subscripting
+(as in
+.SM FORTRAN )
+rather than the `[' and `]' which are used in Pascal,
+the translator noted that
+.I a
+was not defined as a
+.B procedure .
+This occurred because
+.B procedure
+and
+.B function
+argument lists are delimited by parentheses in Pascal.
+As it is not permissible to assign to procedure calls the translator
+diagnosed a malformed statement at the point of assignment.
+.SH
+Expected and unexpected end-of-file, ``QUIT''
+.PP
+If the translator finds a complete program, but there is more non-comment text
+in the input file, then it will indicate that an end-of-file was expected.
+This situation may occur after a bracketing error, or if too many
+.B end s
+are present in the input.
+The message may appear
+after the recovery says that it
+``Expected \`.\'\|''
+since `.' is the symbol that terminates a program.
+.PP
+If severe errors in the input prohibit further processing
+the translator may produce a diagnostic followed by ``QUIT''.
+One example of this was given above \-
+a non-terminated comment;
+another example is a line which is longer than 160
+characters.
+Consider also the following example.
+.LS
+% \*bpix -l mism.p\fR
+.so mismout
+%
+.LE
+.NH 2
+Translator semantic errors
+.PP
+The extremely large number of semantic diagnostic messages which the translator
+produces make it unreasonable to discuss each message or group of messages
+in detail.
+The messages are, however, very informative.
+We will here explain the typical formats and the terminology used in the error
+messages so that you will be able to make sense out of them.
+In any case in which a diagnostic is not completely comprehensible you can
+refer to the
+.I "User Manual"
+by Jensen and Wirth for examples.
+.SH
+Format of the error diagnostics
+.PP
+As we saw in the example program above, the error diagnostics from
+the Pascal translator include the number of a line in the text of the program
+as well as the text of the error message.
+While this number is most often the line where the error occurred, it
+is occasionally the number of a line containing a bracketing keyword
+like
+.B end
+or
+.B until .
+In this case, the diagnostic may refer to the previous statement.
+This occurs because of the method the translator uses for sampling line
+numbers.
+The absence of a trailing `;' in the previous statement causes the line
+number corresponding to the
+.B end
+or
+.B until .
+to become associated with the statement.
+As Pascal is a free-format language, the line number associations
+can only be approximate and may seem arbitrary to some users.
+This is the only notable exception, however, to reasonable associations.
+.SH
+Incompatible types
+.PP
+Since Pascal is a strongly typed language, many semantic errors manifest
+themselves as type errors.
+These are called `type clashes' by the translator.
+The types allowed for various operators in the language are summarized on page
+108 of the
+Jensen-Wirth
+.I "User Manual" .
+It is important to know that the Pascal translator, in its diagnostics,
+distinguishes between the following type `classes':
+.br
+.ne 8
+.TS
+center;
+lew(10) le le le le.
+array  Boolean char    file    integer
+pointer        real    record  scalar  string
+.TE
+These words are plugged into a great number of error messages.
+Thus, if you tried to assign an
+.I integer
+value to a
+.I char
+variable you would receive a diagnostic like the following:
+.LS
+.so clashout
+.LE
+In this case, one error produced a two line error message.
+If the same error occurs more than once, the same explanatory
+diagnostic will be given each time.
+.SH
+Scalar
+.PP
+The only class whose meaning is not self-explanatory is 
+`scalar'.
+Scalar has a precise meaning in the
+Jensen-Wirth
+.I "User Manual"
+where, in fact, it refers to
+.I char ,
+.I integer ,
+.I real ,
+and
+.I Boolean
+types as well as the enumerated types.
+For the purposes of the Pascal translator,
+scalar
+in an error message refers to a user-defined, enumerated
+type, such as
+.I ops
+in the example above or
+.I color
+in
+.LS
+\*btype\fP color = (red, green, blue)
+.LE
+For integers, the more explicit denotation
+.I integer
+is used.
+Although it would be correct, in the context of the
+.I "User Manual"
+to refer to an integer variable as a
+.I scalar
+variable
+.PI
+prefers the more specific identification.
+.SH
+Function and procedure type errors
+.PP
+For built-in procedures and functions, two kinds of errors occur.
+If the routines are called with the wrong number of arguments a message similar to:
+.LS
+.so sinout1
+.LE
+is given.
+If the type of the argument is wrong, a message like
+.LS
+.so sinout2
+.LE
+is produced.
+A few functions and procedures implemented in Pascal 6000-3.4 are
+diagnosed as unimplemented in
+Berkeley
+Pascal, notably those related to
+.B segmented 
+files.
+.SH
+Can't read and write scalars, etc.
+.PP
+The messages which state that scalar (user-defined) types
+cannot be written to and from files are often mysterious.
+It is in fact the case that if you define
+.LS
+\*btype\fP color = (red, green, blue)
+.LE
+the translator does not associate these constants with the strings
+`red', `green', and `blue' in any way.
+If you wish such an association to be made, you will have to write a routine
+to make it.
+Note, in particular, that you can only read characters, integers and real
+numbers from text files.
+You cannot read strings or Booleans.
+It is possible to make a
+.LS
+\*bfile of\fP color
+.LE
+but the representation is binary rather than string.
+.SH
+Expression diagnostics
+.PP
+The diagnostics for semantically ill-formed expressions are very explicit.
+Consider this sample translation:
+.LS
+% \*bpi -l expr.p\fP
+.so exprout
+%
+.LE
+This example is admittedly far-fetched, but illustrates that the error
+messages are sufficiently clear to allow easy determination of the
+problem in the expressions.
+.SH
+Type equivalence
+.PP
+Several diagnostics produced by the Pascal translator complain about
+`non-equivalent types'.
+In general,
+Berkeley
+Pascal considers variables to have the same type only if they were
+declared with the same constructed type or with the same type identifier.
+Thus, the variables
+.I x
+and
+.I y
+declared as
+.LS
+\*bvar\fP
+    x: ^ integer;
+    y: ^ integer;
+.LE
+do not have the same type.
+The assignment
+.LS
+x := y
+.LE
+thus produces the diagnostics:
+.LS
+.so typequout
+.LE
+Thus it is always necessary to declare a type such as
+.LS
+\*btype\fP intptr = ^ integer;
+.LE
+and use it to declare
+.LS
+\*bvar\fP x: intptr; y: intptr;
+.LE
+Note that if we had initially declared
+.LS
+\*bvar\fP x, y: ^ integer;
+.LE
+then the assignment statement would have worked.
+The statement
+.LS
+x^ := y^
+.LE
+is allowed in either case.
+Since the parameter to a
+.B procedure
+or
+.B function
+must be declared with a
+type identifier rather than a constructed type,
+it is always necessary, in practice,
+to declare any type which will be used in this way.
+.SH
+Unreachable statements
+.PP
+Berkeley
+Pascal flags unreachable statements.
+Such statements usually correspond to errors in the program logic.
+Note that a statement is considered to be reachable
+if there is a potential path of control,
+even if it can never be taken.
+Thus, no diagnostic is produced for the statement:
+.LS
+\*bif\fP false \*bthen\fP
+    writeln('impossible!')
+.LE
+.SH
+Goto's into structured statements
+.PP
+The translator detects and complains about
+.B goto
+statements which transfer control into structured statements (\c
+.B for ,
+.B while ,
+etc.)
+It does not allow such jumps, nor does it allow branching from the
+.B then
+part of an
+.B if
+statement into the
+.B else
+part.
+Such checks are made only within the body of a single procedure or
+function.
+.SH
+Unused variables, never set variables
+.PP
+Although
+Berkeley
+Pascal always clears variables to 0 at
+.B procedure
+and
+.B function
+entry, it is
+.B not
+good programming practice to rely on this initialization.
+To discourage this practice, and to help detect errors in program logic,
+.PI
+flags as a `w' warning error:
+.IP
+.RS
+.HP 1)
+Use of a variable which is never assigned a value.
+.IP 2)
+A variable which is declared but never used, distinguishing
+between those variables for which values are computed but which are never
+used, and those completely unused.
+.RE
+.LP
+In fact, these diagnostics are applied to all declared items.
+Thus a
+.B constant
+or a
+.B procedure
+which is declared but never used is flagged.
+The
+.B w
+option of
+.PI
+may be used to suppress these warnings;
+see sections 5.1 and 5.2.
+.NH 2
+Translator panics, i/o errors
+.SH
+Panics
+.PP
+One class of error which rarely occurs, but which causes termination
+of all processing when it does is a panic.
+A panic indicates a translator-detected internal inconsistency.
+A typical panic message is:
+.LS
+snark (rvalue) line=110 yyline=109
+Snark in pi
+.LE
+If you receive such a message, the translation will be quickly and perhaps
+ungracefully terminated.
+You should contact a teaching assistant or a member of the system staff,
+after saving a copy of your program for later inspection.
+If you were making changes to an existing program when the problem
+occurred, you may
+be able to work around the problem by ascertaining which change caused the
+.I snark
+and making a different change or correcting an error in the program.
+You should report the problem in any case.
+Pascal system bugs cannot be fixed unless they are reported.
+.SH
+Out of memory
+.PP
+The only other error which will abort translation when no errors are
+detected is running out of memory.
+All tables in the translator, with the exception of the parse stack,
+are dynamically allocated, and can grow to take up the full available
+process space of 64000 bytes.
+Generally, the size of the largest translatable program is directly related to
+.B procedure
+and
+.B function
+size.
+A number of non-trivial Pascal programs, including
+some with more than 2000 lines and 2500 statements
+have been translated and interpreted using
+Berkeley
+Pascal.
+Notable among these are the Pascal-S
+interpreter,
+a large set of programs for automated generation of
+code generators,
+and a general context-free parsing program which has been used to
+parse sentences with a grammar for a superset of English.
+.PP
+If you receive an out of space message from the translator 
+during translation of a large
+.B procedure
+or
+.B function
+or one containing a large number of string constants
+you may yet be able
+to translate your program if you break this one
+.B procedure
+or
+.B function
+into several routines.
+.SH
+I/O errors
+.PP
+Other errors which you may encounter when running
+.PI
+relate to input-output.
+If
+.PI
+cannot open the file you specify,
+or if the file is empty,
+you will be so informed.
+If your disk space quota\*(dg is exceeded while
+.PI
+is creating the file
+.I obj ,
+or if the system runs out of disk space you will be notified;
+in this case you should remove unneeded files.
+.FS
+\*(dgDisk quotas are also a modification at Berkeley
+and may not exist at your installation.
+.FE
+.NH 2
+Run-time errors
+.PP
+We saw, in our second example, a run-time error.
+We here give the general description of run-time errors.
+The more unusual interpreter error messages are explained
+briefly in the manual section for
+.I px 
+(6).
+.SH
+Start-up errors
+.PP
+These errors occur when the object file to be executed is not available
+or appropriate.
+Typical errors here are caused by the specified object file not existing,
+not being a Pascal object, or being inaccessible to the user.
+.SH
+Program execution errors
+.PP
+These errors occur when the program interacts with the Pascal runtime
+environment in an inappropriate way.
+Typical errors are values or subscripts out of range,
+bad arguments to built-in functions,
+exceeding the statement limit because of an infinite loop,
+or running out of memory\*(dd.
+.FS
+\*(ddThe checks for running out of memory are not foolproof and there
+is a chance that the interpreter will fault, producing a core image
+when it runs out of memory.
+This situation occurs very rarely.
+.FE
+The interpreter will produce a backtrace after the error occurs,
+showing all the active routine calls,
+unless the
+.B p
+option was disabled when the program was translated.
+Unfortunately, no variable values are given and no way of extracting them
+is available.
+.PP
+As an example of such an error, assume that we have accidentally
+declared the constant
+.I n1
+to be 6, instead of 7
+on line 2 of the program primes as given in section 2.6 above.
+If we run this program we get the following response.
+.LS
+% \*bpix primes.p\fP
+.so primeout3
+%
+.LE
+.PP
+Here the interpreter indicates that the program terminated
+abnormally due to a subscript out of range near line 14,
+which is eight lines into the body of the program primes.
+.SH
+Interrupts
+.PP
+If the program is interrupted while executing
+and the
+.B p
+option was not specified,
+then a backtrace will be printed.\*(dg
+.FS
+\*(dgOccasionally, the Pascal system will be in an inconsistent
+state when this occurs,
+e.g. when an interrupt terminates a
+.B procedure
+or
+.B function
+entry or exit.
+In this case, the backtrace will only contain the current line.
+A reverse call order list of procedures will not be given.
+.FE
+The file
+.I pmon.out
+of profile information will be written if the program was translated
+with the
+.B z
+option enabled to
+.PI
+or
+.IX .
+.SH
+I/O interaction errors
+.PP
+The final class of interpreter errors results from inappropriate
+interactions with files, including the user's terminal.
+Included here are bad formats for integer and real numbers (such as
+no digits after the decimal point) when reading.
+.SH
+Panics
+.PP
+A small number of panics are possible with
+.I px .
+These should be reported to a teaching assistant or to the system
+staff if they occur.
diff --git a/doc/pascal/puman4.n b/doc/pascal/puman4.n
new file mode 100644 (file)
index 0000000..0971874
--- /dev/null
@@ -0,0 +1,577 @@
+.if \n(xx .bp
+.if !\n(xx \{\
+.so tmac.p \}
+.nr H1 3
+.if n 'ND
+.NH
+Input/output
+.PP
+This section describes features of the Pascal input/output environment,
+with special consideration of the features peculiar to an
+interactive implementation.
+.NH 2
+Introduction
+.PP
+Our first sample programs, in section 2, used the file
+.I output .
+We gave examples there of redirecting the output to a file and to the line
+printer using the shell.
+Similarly, we can read the input from a file or another program.
+Consider the following Pascal program which is similar to the program
+.I cat 
+(1).
+.LS
+% \*bpix -l kat.p <primes\fR
+.so katout
+%
+.LE
+Here we have used the shell's syntax to redirect the program input from
+a file in
+.I primes
+in which we had placed the output of our prime number program of section 2.6.
+It is also possible to
+`pipe' input to this program much as we piped input
+to the line printer daemon
+.I lpr
+(1)
+before.
+Thus, the same output as above would be produced by
+.LS
+% \*bcat primes | pix -l kat.p\fR
+.LE
+.PP
+All of these examples use the shell to control the input and output
+from files.
+One very simple way to associate Pascal files with named
+.UX
+files is to place the file name in the
+.B program
+statement.
+For example, suppose we have previously created the file
+.I data.
+We then use it as input to another version of a listing program.
+.LS
+% \*bcat data\fR
+.so data
+% \*bpix -l copydata.p\fR
+.so copydataout
+%
+.LE
+By mentioning the file
+.I data
+in the
+.B program
+statement, we have indicated that we wish it
+to correspond to the
+.UX
+file
+.I data .
+Then, when we
+`reset(data)',
+the Pascal system opens our file `data' for reading.
+More sophisticated, but less portable, examples of using
+.UX
+files will be given in sections 4.5 and 4.6.
+There is a portability problem even with this simple example.
+Some Pascal systems attach meaning to the ordering of the file in the
+.B program
+statement file list.
+.UP
+does not do so.
+.NH 2
+Eof and eoln
+.PP
+An extremely common problem encountered by new users of Pascal, especially
+in the interactive environment offered by
+.UX ,
+relates to the definitions of
+.I eof
+and
+.I eoln .
+These functions are supposed to be defined at the beginning of execution of
+a Pascal program, indicating whether the input device is at the end of a
+line or the end of a file.
+Setting
+.I eof
+or
+.I eoln
+actually corresponds to an implicit read in which the input is
+inspected, but no input is ``used up''.
+In fact, there is no way the system can know whether the input is
+at the end-of-file or the end-of-line unless it attempts to read a line from it.
+If the input is from a previously created file,
+then this reading can take place without run-time action by the user.
+However, if the input is from a terminal, then the input
+is what the user types.\*(dg
+If the system were to do an initial read
+automatically at the beginning of program execution,
+and if the input were a terminal,
+the user would have to type some input before execution could begin.
+.FS
+\*(dgIt is not possible to determine whether the input is
+a terminal, as the input may appear to be a file but actually be a
+.I pipe,
+the output of a program which is reading from the terminal.
+.FE
+This would make it impossible for the program to begin by prompting
+for input or printing a herald.
+.PP
+.UP
+has been designed so that an initial read is not necessary.
+At any given time, the Pascal system may or may not know whether the
+end-of-file or end-of-line conditions are true.
+Thus, internally, these functions can have three values \-
+true, false, and ``I don't know yet; if you ask me I'll have to
+find out''.
+All files remain in this last, indeterminate state until the Pascal
+program requires a value for
+.I eof
+or
+.I eoln
+either explicitly or implicitly, e.g. in a call to
+.I read .
+The important point to note here is that if you force the Pascal
+system to determine whether the input is at the end-of-file or the end-of-line,
+it will be necessary for it to attempt to read from the input.
+.PP
+Thus consider the following example code
+.LS
+\*bwhile not\fP eof \*bdo\fP \*bbegin\fP
+    write('number, please? ');
+    read(i);
+    writeln('that was a ', i: 2)
+\*bend\fP
+.LE
+At first glance, this may be appear to be a correct program
+for requesting, reading and echoing numbers.
+Notice, however, that the
+.B while
+loop asks whether
+.I eof
+is true
+.I before
+the request is printed.
+This will force the Pascal system to decide whether the input is at the
+end-of-file.
+The Pascal system will give no messages;
+it will simply wait for the user to type a line.
+By producing the desired prompting before testing
+.I eof,
+the following code avoids this problem:
+.LS
+write('number, please ?');
+\*bwhile not\fP eof \*bdo\fP \*bbegin\fP
+    read(i);
+    writeln('that was a ', i:2);
+    write('number, please ?')
+\*bend\fP
+.LE
+The user must still type a line before the
+.B while
+test is completed, but the prompt will ask for it.
+This example, however, is still not correct.
+To understand why, it is first necessary to know, as we will discuss below,
+that there is a blank character at the end of each line in a Pascal text
+file.
+The
+.I read
+procedure, when reading integers or real numbers,
+is defined so that,
+if there are only blanks left in the file,
+it will return a zero value and set the end-of-file condition.
+If, however, there is a number remaining in the file, the end-of-file
+condition will not be set even if it is the last number, as
+.I read
+never reads the blanks after the number, and there is always at least
+one blank.
+Thus the modified code will still put out a spurious
+.LS
+that was a 0
+.LE
+at the end of a session with it when the end-of-file is reached.
+The simplest way to correct the problem in this example is to use the procedure
+.I readln
+instead of
+.I read
+here.
+In general, unless we test the end-of-file condition both before and
+after calls to
+.I read
+or
+.I readln ,
+there will be inputs for which our program will attempt
+to read past end-of-file.
+.NH 2
+More about eoln
+.PP
+To have a good understanding of when
+.I eoln
+will be true it is necessary to know that in any file
+there is a special character indicating end-of-line,
+and that, in effect, the Pascal system always reads one character ahead of the 
+Pascal
+.I read
+commands.\*(dg
+.FS
+\*(dgIn Pascal terms,
+`read(ch)'
+corresponds to
+`ch := input^; get(input)'
+.FE
+For instance,
+in response to `read(ch)',
+the system sets
+.I ch
+to the current input character and gets the next input character.
+If the current input character is the last character of the line,
+then the next input character from the file is the new-line character,
+the normal
+.UX
+line separator.
+When the read routine gets the new-line character,
+it replaces that character by a blank
+(causing every line to end with a blank)
+and sets
+.I eoln
+to true.
+.I Eoln
+will be true as soon as we read the last character of the line and
+.B before
+we read the blank character corresponding to the end of line.
+Thus it is almost always a mistake to write a program which deals with
+input in the following way:
+.LS
+read(ch);
+\*bif\fP eoln \*bthen\fP
+    \fIDone with line\fP
+\*belse\fP
+    \fINormal processing\fP
+.LE
+as this will almost surely have the effect of ignoring the last character
+in the line.
+The `read(ch)' belongs as part of the normal processing.
+.PP
+Given this framework, it is not hard to explain the function of a
+.I readln
+call, which is defined as:
+.LS
+\*bwhile not\fP eoln \*bdo\fP
+    get(input);
+get(input);
+.LE
+This advances the file until the blank corresponding to the end-of-line
+is the current input symbol and then discards this blank.
+The next character available from
+.I read
+will therefore be the first character of the next line,
+if one exists.
+.NH 2
+Output buffering
+.PP
+A final point about Pascal input-output must be noted here.
+This concerns the buffering of the file
+.I output .
+It is extremely inefficient for the Pascal system to send each character
+to the user's terminal as the program generates it for output;
+even less efficient if the output is the input of another
+program such as the line printer daemon
+.I lpr
+(1).
+To gain efficiency, the Pascal system ``buffers'' the output characters
+(i.e. it saves them in memory until the buffer is full and then emits
+the entire buffer in one system interaction.)
+However, to allow interactive prompting to work as in the example given
+above, this prompt must be printed before the Pascal system waits for a
+response.
+For this reason, Pascal normally prints all the output which has
+been generated for the file
+.I output
+whenever
+.HP
+.RS
+.IP 1)
+A
+.I writeln
+occurs, or
+.IP 2)
+The program reads from the terminal, or
+.IP 3)
+The procedure
+.I message
+or
+.I flush
+is called.
+.RE
+.LP
+Thus, in the code sequence
+.ne 5
+.LS
+\*bfor\fP i := 1 to 5 \*bdo begin\fP
+    write(i: 2);
+    \fICompute a lot with no output\fP
+\*bend;\fP
+writeln
+.LE
+the output integers will not print until the
+.I writeln
+occurs.
+The delay can be somewhat disconcerting, and you should be aware 
+that it will occur.
+By setting the
+.B b
+option to 0 before the
+.B program
+statement by inserting a comment of the form
+.LS
+(*$b0*)
+.LE
+we can cause
+.I output
+to be completely unbuffered, with a corresponding horrendous degradation
+in program efficiency.
+Option control in comments is discussed in section 5.
+.NH 2
+Files, reset, and rewrite
+.PP
+It is possible to use extended forms of the built-in functions
+.I reset
+and
+.I rewrite
+to get more general associations of
+.UX
+file names with Pascal file variables.
+When a file other than
+.I input
+or
+.I output
+is to be read or written, then the reading or writing must be preceded
+by a
+.I reset
+or
+.I rewrite
+call.
+In general, if the Pascal file variable has never been used before,
+there will be no
+.UX
+filename associated with it.
+As we saw in section 2.9,
+by mentioning the file in the
+.B program
+statement,
+we could cause a
+.UX
+file with the same name as the Pascal variable to be associated with it.
+If we do not mention a file in the
+.B program
+statement and use it for the first time with the statement
+.LS
+reset(f)
+.LE
+or
+.LS
+rewrite(f)
+.LE
+then the Pascal system will generate a temporary name of the form
+`tmp.x'
+for some character `x',
+and associate this
+.UX
+file name name with the Pascal file.
+The first such generated name will be `tmp.1'
+and the names continue by incrementing their last character through the
+.SM ASCII
+set.
+The advantage of using such temporary files is that they are automatically
+.I remove d
+by the Pascal system as soon as they become inaccessible.
+They are not removed, however, if a runtime error causes termination
+while they are in scope.
+.PP
+To cause a particular
+.UX
+pathname to be associated with a Pascal file variable
+we can give that name in the
+.I reset
+or
+.I rewrite
+call, e.g. we could have associated the Pascal file
+.I data
+with the file
+`primes'
+in our example in section 3.1 by doing:
+.LS
+reset(data, 'primes')
+.LE
+instead of a simple
+.LS
+reset(data)
+.LE
+In this case it is not essential to mention `data'
+in the program statement, but it is still a good idea
+because is serves as an aid to program documentation.
+The second parameter to
+.I reset
+and
+.I rewrite
+may be any string value, including a variable.
+Thus the names of 
+.UX
+files to be associated with Pascal file variables can be read
+in at run time.
+Full details on file name/file variable associations are given in
+section A.3.
+.NH 2
+Argc and argv
+.PP
+Each
+.UX
+process receives a variable
+length sequence of arguments each of which is a variable length
+character string.
+The built-in function
+.I argc
+and the built-in procedure
+.I argv
+can be used to access and process these arguments.
+The value of the function
+.I argc
+is the number of arguments to the process.
+By convention,
+the arguments are treated as an array,
+and indexed from 0 to
+.I argc \-1,
+with the zeroth argument being the name of the program being executed.
+The rest of the
+arguments are those passed to the command on the command line.
+Thus, the command
+.LS
+% \*bobj  /etc/motd  /usr/dict/words hello\fR
+.LE
+will invoke the program in the file
+.I obj
+with
+.I argc
+having a value of 4.
+The zeroth element accessed by
+.I argv
+will be `obj', the first `/etc/motd', etc.
+.PP
+Pascal does not provide variable size arrays, nor does it allow
+character strings of varying length.
+For this reason,
+.I argv
+is a procedure and has the syntax
+.LS
+argv(i, a)
+.LE
+where
+.I i
+is an integer and
+.I a
+is a string variable.
+This procedure call assigns the (possibly truncated or blank padded)
+.I i \|'th
+argument of the current process to the string variable
+.I a .
+The file manipulation routines
+.I reset
+and
+.I rewrite
+will strip trailing blanks from their optional second arguments
+so that this blank padding is not a problem in the usual case
+where the arguments are file names.
+.PP
+We are now ready to give a
+Berkeley
+Pascal program `kat',
+based on that given in section 3.1 above,
+which can be used with the same syntax as the
+.UX
+system program
+.I cat
+(1).
+.LS
+% \*bcat kat.p\fR
+.so kat3.p
+%
+.LE
+Note that the
+.I reset
+call to the file
+.I input
+here, which is necessary for a clear program,
+may be disallowed on other systems.
+As this program deals mostly with
+.I argc
+and
+.I argv
+and
+.UX
+system dependent considerations,
+portability is of little concern.
+.PP
+If this program is in the file `kat.p', then we can do
+.LS
+% \*bpi kat.p\fR
+% \*bmv obj kat\fR
+% \*bkat primes\fR
+.so kat2out
+% \*bkat\fR
+.so katscript
+%
+.LE
+Thus we see that, if it is given arguments, `kat' will,
+like
+.I cat,
+copy each one in turn.
+If no arguments are given, it copies from the standard input.
+Thus it will work as it did before, with
+.LS
+% \*bkat < primes\fR
+.LE
+now equivalent to
+.LS
+% \*bkat primes\fR
+.LE
+although the mechanisms are quite different in the two cases.
+Note that if `kat' is given a bad file name, for example:
+.LS
+% \*bkat xxxxqqq\fR
+.so xxxxqqqout
+%
+.LE
+it will give a diagnostic and a post-mortem control flow backtrace
+for debugging.
+If we were going to use `kat', we might want to translate it
+differently, e.g.:
+.LS
+% \*bpi -pb kat.p\fR
+% \*bmv obj kat\fR
+.LE
+Here we have disabled the post-mortem statistics printing, so
+as not to get the statistics or the traceback on error.
+The
+.B b
+option will cause the system to block buffer the input/output so that
+the program will run more efficiently on large files.
+We could have also specified the
+.B t
+option to turn off runtime tests if that was felt to be a speed hindrance
+to the program.
+Thus we can try the last examples again:
+.LS
+% \*bkat xxxxqqq\fR
+.so xxxxqqqout2
+% \*bkat primes\fR
+.so primes-d
+%
+.LE
+.PP
+The interested reader may wish to try writing a program which
+accepts command line arguments like
+.PI
+does, using
+.I argc
+and
+.I argv
+to process them.
diff --git a/doc/pascal/puman5.n b/doc/pascal/puman5.n
new file mode 100644 (file)
index 0000000..7849156
--- /dev/null
@@ -0,0 +1,828 @@
+.if \n(xx .bp
+.if !\n(xx \{\
+.so tmac.p \}
+.ND
+.nr H1 4
+.NH
+Details on the components of the system
+.NH 2
+Options
+.PP
+The programs
+.PI
+and
+.XP
+take a number of options.\*(dg
+.FS
+\*(dgAs
+.IX
+uses
+.PI
+to translate Pascal programs,
+it takes the options of
+.PI
+also.
+We refer to them here, however, as
+.PI
+options.
+.FE
+There is a standard
+.UX
+convention for passing options to programs on the command line,
+and this convention is followed by the
+.UP
+system programs.
+As we saw in the examples above,
+option related arguments consisted of the character `\-' followed
+by a single character option name.
+In fact, it is possible to place more than one option letter after
+a single `\-', thus
+.LS
+% \*bpi -lz foo.p\fR
+.LE
+and
+.LS
+% \*bpi -l -z foo.p\fR
+.LE
+are equivalent.
+.PP
+There are 26 options, one corresponding to each lower case letter.
+Except for the
+.B b
+option
+which takes a single digit value,
+each option may be set on (enabled)
+or off (disabled.)
+When an on/off valued option appears on the command line of
+.PI
+or
+.PX
+it inverts the default setting of that option.
+Thus
+.LS
+% \*bpi -l foo.p\fR
+.LE
+enables the listing option
+.B l ,
+since it defaults off, while
+.LS
+% \*bpi -t foo.p\fR
+.LE
+disables the run time tests option
+.B t ,
+since it defaults on.
+.PP
+In additon to inverting the default settings of
+.PI
+options on the command line, it is also possible to control the
+.PI
+options 
+within the body of the program by using comments of a special
+form illustrated by
+.LS
+{$l-}
+.LE
+.PP
+Here we see that the opening comment delimiter (which could also be a `(*')
+is immediately followed by the character `$'.
+After this `$', which signals the start of the option list,
+we can place a sequence of letters and option controls, separated by `,'
+characters\*(dd.
+.FS
+\*(ddThis format was chosen because it is used by Pascal 6000-3.4.
+In general the options common to both implementations are controlled
+in the same way so that comment control in options is mostly
+portable.
+It is recommended, however, that only one control be put per comment for
+maximum portability, as the Pascal 6000-3.4
+implementation will ignore controls
+after the first one which it does not recognize.
+.FE
+The most basic actions for options are to set them, thus
+.LS
+{$l+ Enable listing}
+.LE
+or to clear them
+.LS
+{$t-,p- No run-time tests, no post mortem analysis}
+.LE
+Notice that `+' always enables an option and `\-' always disables it,
+no matter what the default is.
+Thus `\-' has a different meaning in an option comment than it has on the
+command line.
+As shown in the examples,
+normal comment text may follow the option list.
+.NH 2
+Pi (and pix)
+.PP
+We now summarize the options of
+.PI .
+These options may also be specified on the command line to
+.IX
+before the name of the file to be translated.
+Arguments to
+.IX
+after the name of the file to be translated are passed to
+the executed program run by
+.X .
+With each option we give its default setting,
+the setting it would have if it appeared on the command line,
+and a sample command using the option.
+Most options are on/off valued,
+with the
+.B b
+option
+taking a single digit value.
+.SH
+Buffering of the file output \- b
+.PP
+The
+.B b
+option controls the buffering of the file
+.I output .
+The default is line buffering, with flushing at
+each reference to the file
+.I input
+and under certain other circumstances detailed in section 5
+below.
+Mentioning
+.B b
+on the command line, e.g.
+.LS
+% \*bpi -b assembler.p\fR
+.LE
+causes standard output to be block buffered,
+where a block is 512 characters.
+The
+.B b
+option may also be controlled in comments.
+It, unique among the
+.UP
+options,
+takes a single digit value rather than an on or off setting.
+A value of 0, e.g.
+.LS
+       {$b0}
+.LE
+causes the file
+.I output
+to be unbuffered.
+Any value 2 or greater causes block buffering and is equivalent
+to the flag on the command line.
+The option control comment setting
+.B b
+must precede the
+.B program
+statement.
+.SH
+Include file listing \- i
+.PP
+The
+.B i
+option takes a list of
+.B include
+files,
+.B procedure
+and
+.B function
+names and causes these portions of the
+program to be listed while translating\*(dg.
+.FS
+\*(dg\*bInclude\fR files are discussed in section 5.9.
+.FE
+All arguments after the
+.B \-i
+flag up to the name of the file being translated,
+which ends in `.p', are in this list.
+Typical uses would be
+.LS
+% \*bpix -i scanner.i compiler.p\fR
+.LE
+to make a listing of the routines in the file scanner.i, and
+.LS
+% \*bpix -i scanner compiler.p\fR
+.LE
+to make a listing of only the routine
+.I scanner .
+This option is especially useful for conservation-minded programmers making
+partial program listings.
+.SH
+Make a listing \- l
+.PP
+The
+.B l
+option enables a listing of the program.
+The
+.B l
+option defaults off.
+When specified on the command line, it causes
+a header line identifying the version of the translator in use
+and a line giving the modification time of the file being translated
+to appear before the actual program listing.
+The
+.B l
+option is pushed and popped by the
+.B i
+option at appropriate points in the program.
+.SH
+Eject new pages for include files \- n
+.PP
+The
+.B n
+option causes
+.PI
+to eject a new page in the listing and print a header line at
+.B include
+file boundaries, providing automatic pagination control.
+To have effect, either the
+.B l
+or
+.B i
+option should also be specified,
+or the input should contain listing control in comments.
+An example would be
+.LS
+% \*bpi -in scan.i c.p\fR
+.LE
+.SH
+Post-mortem dump \- p
+.PP
+The
+.B p
+option defaults on,
+and causes the runtime system to initiate a post-mortem
+backtrace when an error occurs.
+It also cause
+.X
+to count statements in the executing program,
+enforcing a statement limit to prevent infinite loops.
+Specifying
+.B p
+on the command line disables these checks and the ability
+to give this post-mortem analysis.
+It does make smaller and faster programs, however.
+It is also possible to control the
+.B p
+option in comments.
+To prevent the post-mortem backtrace on error,
+.B p
+must be off at the end of the
+.B program
+statement.
+Thus, the Pascal cross-reference program was translated with
+.LS
+% \*bpi -pbt pxref.p\fR
+.LE
+.SH
+Standard Pascal only \- s
+.PP
+The
+.B s
+option causes many of the features of the
+.SM UNIX
+implementation which are not found in standard Pascal
+to be diagnosed as `s' warning errors.
+This option defaults off and is enabled when mentioned on the command line.
+Some of the features which are diagnosed are:
+non-standard
+.B procedure s
+and
+.B function s,
+extensions to the
+.B procedure
+.I write ,
+and the padding of constant strings with blanks.
+In addition, all letters are mapped to lower case except in
+strings and characters so that the case of keywords and identifiers
+is effectively ignored.
+The
+.B s
+option is most useful when a program is to be transported, thus
+.LS
+% \*bpi -s isitstd.p\fR
+.LE
+.SH
+Runtime tests \- t
+.PP
+The
+.B t
+option controls the generation of tests that subrange variable
+values are within bounds at run time.
+By default these tests are generated.
+If the
+.B t
+option is specified on the command line,
+or in a comment which turns it off,
+then the tests are not generated.
+Thus the first line of a program to run without tests might be
+.LS
+{$t- No runtime tests}
+.LE
+Disabling runtime tests also causes
+.B assert
+statements to be treated as comments.\*(dg
+.FS
+\*(dgSee section A.1 for a description of
+.B assert
+statements.
+.FE
+.SH
+Card image, 72 column input \- u
+.PP
+Turning the
+.B u
+option on, either on the command line
+or in a comment causes the input to be treated as
+card images with sequence numbers and truncated to 72 columns.
+Thus
+.LS
+% \*bpix -u cards.p\fR
+.LE
+.SH
+Suppress warning diagnostics \- w
+.PP
+The
+.B w
+option, which defaults on,
+allows the translator to print a number of warnings about inconsistencies
+it finds in the input program.
+Turning this option off with a comment of the form
+.LS
+{$w-}
+.LE
+or on the command line
+.LS
+% \*bpi -w tryme.p\fR
+.LE
+suppresses these usually useful diagnostics.
+.SH
+Generate counters for an execution profile \- z
+.PP
+The
+.B z
+option, which defaults off,
+enables the production of execution profiles.
+By specifying
+.B z
+on the command line, i.e.
+.LS
+% \*bpi -z foo.p\fR
+.LE
+or by enabling it in a comment before the
+.B program
+statement we cause
+.PI
+to insert operations in the interpreter code to
+count the number of times each statement was executed.
+An example of using
+.XP
+was given in section 2.6;
+its options are described in section 5.5.
+.NH 2
+Px
+.PP
+The first argument to
+.X
+is the name of the file containing the program to be interpreted.
+If no arguments are given, then the file
+.I obj
+is executed.
+If more arguments are given, they are available to the Pascal
+program by using the built-ins
+.I argc
+and
+.I argv
+as described in section 4.6.
+.ne 7
+.PP
+.I Px
+may also be invoked automatically.
+In this case, whenever a Pascal object file name is given as a command,
+the command will be executed with
+.X
+prepended to it; that is
+.LS
+% \*bobj primes\fR
+.LE
+will be converted to read
+.LS
+% \*bpx obj primes\fR
+.LE
+.NH 2
+Pxp
+.PP
+.I Pxp
+takes, on its command line, a list of options followed by the program file
+name, which must end in `.p' as it must for
+.PI
+and
+.IX .
+.XP
+will produce an execution profile if any of the
+.B z
+.B t
+or
+.B c
+options are specified on the command line.
+If none of these options are specified, then
+.XP
+functions as a program reformatter.
+See section 5.5 for more details.
+.PP
+It is important to note that only the
+.B z
+option of
+.XP ,
+and the
+.B n ,
+.B u ,
+and
+.B w ,
+options, which are common to
+.PI
+and
+.XP
+can be controlled in comments.
+All other options must be specified on the command line to have any effect.
+.PP
+The following options are relevant to profiling with
+.XP :
+.SH
+Include the bodies of all routines in the profile \- a
+.PP
+.I Pxp
+normally suppresses printing the bodies of routines
+which were never executed, to make the profile more compact.
+This option forces all routine bodies to be printed.
+.SH
+Extract profile data from the file core \- c
+.PP
+This option causes
+.XP
+to extract the data from the file
+.I core
+in the current directory.
+This is used in debugging the Pascal system, and should not
+normally be needed.
+When an abnormal termination occurs in
+.X
+it writes the data to the file
+.I pmon.out .
+The
+.B z
+option enables profiling with data from this file.
+.SH
+Suppress declaration parts from a profile \- d
+.PP
+Normally a profile includes declaration parts.
+Specifying
+.B d
+on the command line suppresses declaration parts.
+.SH
+Eliminate include directives \- e
+.PP
+Normally,
+.XP
+preserves
+.B include
+directives to the output when reformatting a program,
+as though they were comments.
+Specifying
+.B \-e
+causes the contents of the specified files to be reformatted
+into the output stream instead.
+This is an easy way to eliminate
+.B include
+directives, e.g. before transporting a program.
+.SH
+Fully parenthesize expressions \- f
+.PP
+Normally
+.XP
+prints expressions with the minimal parenthesization necessary to
+preserve the structure of the input.
+This option causes
+.I pxp
+to fully parenthesize expressions.
+Thus the statement which prints as
+.LS
+d := a + b mod c / e
+.LE
+with minimal parenthesization, the default, will print as
+.LS
+d := a + ((b mod c) / e)
+.LE
+with the
+.B f
+option specified on the command line.
+.SH
+Left justify all procedures and functions \- j
+.PP
+Normally, each
+.B procedure
+and
+.B function
+body is indented to reflect its static nesting depth.
+This option prevents this nesting and can be used if the indented
+output would be too wide.
+.SH
+Print a table summarizing procedure and function calls \- t
+.PP
+The
+.B t
+option causes
+.XP
+to print a table summarizing the number of calls to each
+.B procedure
+and
+.B function
+in the program.
+It may be specified in combination with the
+.B z
+option, or separately.
+.SH
+Enable and control the profile \- z
+.PP
+The
+.B z
+profile option is very similar to the
+.B i
+listing control option of
+.PI .
+If
+.B z
+is specified on the command line, then all arguments up to the
+source file argument which ends in `.p' are taken to be the names of
+.B procedure s
+and
+.B function s
+or
+.B include
+files which are to be profiled.
+If this list is null, then the whole file is to be profiled.
+A typical command for extracting a profile of part of a large program
+would be
+.LS
+% \*bpxp -z test parser.i compiler.p\fR
+.LE
+This specifies that profiles of the routines in the file
+.I parser.i
+and the routine
+.I test
+are to be made.
+.NH 2
+Formatting programs using pxp
+.PP
+The program
+.XP
+can be used to reformat programs, by using a command of the form
+.LS
+% \*bpxp dirty.p > clean.p\fR
+.LE
+Note that since the shell creates the output file `clean.p' before
+.XP
+executes, so `clean.p' and `dirty.p' must not be the same file.
+.PP
+.I Pxp
+automatically paragraphs the program, performing housekeeping
+chores such as comment alignment, and
+treating blank lines, lines containing exactly one blank
+and lines containing only a form-feed character as though they
+were comments, preserving their vertical spacing effect in the output.
+.I Pxp
+distinguishes between four kinds of comments:
+.HP
+.RS
+.IP 1)
+Left marginal comments, which begin in the first column of the
+input line and are placed in the first column of an output line.
+.IP 2)
+Aligned comments, which are preceded by no input tokens on the
+input line.
+These are aligned in the output with the running program text.
+.IP 3)
+Trailing comments, which are preceded in the input line by a token with
+no more than two spaces separating the token from the comment.
+.IP 4)
+Right marginal comments, which are preceded in the input line
+by a token from which they are separated by at least three spaces or a tab.
+These are aligned down the right margin of the output,
+currently to the first tab stop after the 40th column from the current
+``left margin''.
+.RE
+.LP
+Consider the following program.
+.LS
+% \*bcat comments.p\fR
+.so comments1.p
+.LE
+When formatted by
+.XP
+the following output is produced.
+.LS
+% \*bpxp comments.p\fR
+.so commentsout
+%
+.LE
+The following formatting related options are currently available in
+.XP .
+The options
+.B f
+and
+.B j
+described in the previous section may also be of interest.
+.SH
+Strip comments \-s
+.PP
+The
+.B s
+option causes
+.XP
+to remove all comments from the input text.
+.SH
+Underline keywords \- \_
+.PP
+A command line argument of the form
+.B \-\_
+as in
+.LS
+% \*bpxp -_ dirty.p\fR
+.LE
+can be used to cause
+.XP
+to underline all keywords in the output for enhanced readability.
+.SH
+Specify indenting unit \- [23456789]
+.PP
+The normal unit which
+.XP
+uses to indent a structure statement level is 4 spaces.
+By giving an argument of the form
+\fB\-\fId\fR
+with
+.I d
+a digit,
+2 \(<=
+.I d
+\(<= 9
+you can specify that
+.I d
+spaces are to be used per level instead.
+.NH 2
+Pcc and carriage control
+.PP
+The
+.UX
+system printer driver does not implement
+.SM FORTRAN
+style carriage control.
+Thus the function
+.I page
+on
+.UX
+does not output a character `1'
+in column 1 of a line, but rather puts out a form-feed
+character.
+For those who wish to use carriage control, the filter
+.I pcc
+is available which interprets this control.
+A sample usage is:
+.LS
+% \*bpx | pcc\fR
+.LE
+or
+.LS
+% \*bpix prog.p | pcc | lpr\fR
+.LE
+for printer copy.
+.I Pcc
+is fully described by its manual documentation
+.I pcc
+(6).
+.NH 2
+Pxref
+.PP
+The cross-reference program
+.I pxref
+may be used to make cross-referenced listings of Pascal
+programs.
+To produce a cross-reference of the program in the file
+`foo.p'
+one can execute the command:
+.LS
+% \*bpxref foo.p\fR
+.LE
+The cross-reference is, unfortunately, not block structured.
+Full details on
+.I pxref
+are given in its manual section
+.I pxref
+(6).
+.NH 2
+Pascals
+.PP
+A version of Wirth's subset Pascal translator
+.I pascals
+is available on
+.UX .
+It was translated to interpreter code by
+.PI
+and is invoked by a command of the form:
+.LS
+% \*bpascals prog.p\fR
+.LE
+The program in the file given is translated to interpretive code
+which is then immediately executed.
+.I Pascals
+is thus similar to
+.I pix .
+Only small programs can be handled.
+.I Pascals
+is most interesting to those wishing to study its error recovery techniques,
+which are described in Wirth's book
+.I "Algorithms + Data Structures = Programs" .
+.NH 2
+Multi-file programs
+.PP
+A text inclusion facility is available with
+.UP .
+This facility allows the interpolation of source text from other
+files into the source stream of the translator.
+It can be used to divide large programs into more manageable pieces
+for ease in editing, listing, and maintenance.
+.PP
+The
+.B include
+facility is based on that of the
+.SM
+UNIX
+.NL
+C compiler.
+To trigger it you can place the character `#' in the first portion of
+a line and then, after an arbitrary number of blanks or tabs,
+the word
+`include'
+followed by a filename enclosed in single `\(aa' or double `"' quotation
+marks.
+The file name may be followed by a semicolon `;' if you wish to treat
+this as a pseudo-Pascal statement.
+The filenames of included files must end in `.i'.
+An example of the use of included files in a main program would be:
+.LS
+\*bprogram\fR compiler(input, output, obj);
+
+#\*binclude\fR "globals.i"
+#\*binclude\fR "scanner.i"
+#\*binclude\fR "parser.i"
+#\*binclude\fR "semantics.i"
+
+\*bbegin\fR
+    { main program }
+\*bend\fR.
+.LE
+.PP
+At the point the
+.B include
+pseudo-statement is encountered in the input, the lines from
+the included file are interpolated into the input stream.
+For the purposes of translate- and run-time diagnostics and
+statement numbers in the listings and post-mortem backtraces,
+the lines in the included file are numbered from 1.
+Nested includes are possible up to 10 deep.
+.PP
+See the descriptions of the
+.B i
+and
+.B n
+options of
+.PI
+in section 5.2
+above;
+these can be used to control listing when
+.B include
+files are present.
+.PP
+.I Include
+control lines are never printed in a listing.
+If the
+.B n
+option is not set, they are replaced by a line containing
+the file name and a `:' character.
+This is the default setting.
+If the
+.B n
+new page option is enabled then the 
+.B include 
+line is replaced with a banner line similar to the first line
+of a listing.
+This line is placed on a new page in the listing.
+.PP
+When a non-trivial line is encountered in the source text after an
+.B include
+finishes, the
+`popped' filename is printed, in the same manner as above.
+.PP
+For the purposes of error diagnostics when not making a listing, the filename
+will be printed before each diagnostic if the current
+filename has changed since the last
+filename was printed.
diff --git a/doc/pascal/pumanA.n b/doc/pascal/pumanA.n
new file mode 100644 (file)
index 0000000..ff2453c
--- /dev/null
@@ -0,0 +1,893 @@
+.if \n(xx .bp
+.if !\n(xx \{\
+.so tmac.p \}
+.ND
+.nr H1 0
+.af H1 A
+.NH 
+Appendix to Wirth's Pascal Report
+.PP
+This section is an appendix to
+the definition of the Pascal language in Niklaus Wirth's
+.I "Pascal Report"
+and, with that Report, precisely defines the
+Berkeley
+implementation.
+This appendix includes a summary of extensions to the language,
+gives the ways in which the undefined specifications were resolved,
+gives limitations and restrictions of the current implementation,
+and lists the added functions and procedures available.
+It concludes with a list of differences with the commonly available
+Pascal 6000\-3.4 implementation,
+and some comments on standard and portable Pascal.
+.NH 2
+Extensions to the language Pascal
+.PP
+This section defines non-standard language constructs available in
+.UP .
+The
+.B s
+standard Pascal option of the translator
+.PI
+can be used to detect these extensions in programs which are to be transported.
+.SH
+String padding
+.PP
+.UP
+will pad constant strings with blanks in expressions and as
+value parameters to make them as long as is required.
+The following is a legal
+.UP
+program:
+.LS
+\*bprogram\fP x(output);
+\*bvar\fP z : \*bpacked\fP \*barray\fP [ 1 .. 13 ] \*bof\fP char;
+\*bbegin\fP
+    z := 'red';
+    writeln(z)
+\*bend\fP;
+.LE
+The padded blanks are added on the right.
+Thus the assignment above is equivalent to:
+.LS
+z := 'red          '
+.LE
+which is standard Pascal.
+.SH
+Octal constants, octal and hexadecimal write
+.PP
+Octal constants may be given as a sequence of octal digits followed
+by the character `b' or `B'.
+The forms
+.LS
+write(a:n \*boct\fP)
+.LE
+and
+.LS
+write(a:n \*bhex\fP)
+.LE
+cause the internal representation of
+expression
+.I a,
+which must be Boolean, character, integer, pointer, or a user-defined enumerated
+type,
+to be written in octal or hexadecimal respectively.
+.SH
+Assert statement
+.PP
+An
+.B assert
+statement causes a
+.I Boolean
+expression to be evaluated
+each time the statement is executed.
+A runtime error results if any of the expressions evaluates to be 
+.I false .
+The
+.B assert
+statement is treated as a comment if run-time tests are disabled.
+The syntax for
+.B assert
+is:
+.LS
+\*bassert\fP <expr>
+.LE
+.br
+.ne 8
+.NH 2
+Resolution of the undefined specifications
+.SH
+File name \- file variable associations
+.PP
+Each Pascal file variable is associated with a named
+.UX
+file.
+Except for
+.I input
+and
+.I output,
+which are
+exceptions to some of the rules, a name can become associated
+with a file in any of three ways:
+.IP "\ \ \ \ \ 1)" 10
+If a global Pascal file variable appears in the
+.B program
+statement
+then it is associated with
+.UX
+file of the same name.
+.IP "\ \ \ \ \ 2)"
+If a file was reset or rewritten using the
+extended two-argument form of
+.I reset
+or
+.I rewrite
+then the given name
+is associated.
+.IP "\ \ \ \ \ 3)"
+If a file which has never had
+.UX
+name associated
+is reset or rewritten without specifying a name
+via the second argument, then a temporary name
+of the form `tmp.x'
+is associated with the file.
+Temporary names start with
+`tmp.1' and continue by incrementing the last character in the
+.SM
+USASCII
+.NL
+ordering.
+Temporary files are removed automatically
+when their scope is exited.
+.SH
+The program statement
+.PP
+The syntax of the
+.B program
+statement is:
+.LS
+\*bprogram\fP <id> ( <file id> { , <file id > } ) ;
+.LE
+The file identifiers (other than
+.I input
+and
+.I output )
+must be declared as variables of
+.B file
+type in the global declaration part.
+.SH
+The files input and output
+.PP
+The formal parameters
+.I input
+and
+.I output
+are associated with the
+.UX
+standard input and output and have a
+somewhat special status.
+The following rules must be noted:
+.IP "\ \ \ \ \ 1)" 10
+The program heading
+.B must
+contains the formal parameter
+.I output.
+If
+.I input
+is used, explicitly or implicitly, then it must
+also be declared here.
+.IP "\ \ \ \ \ 2)"
+Unlike all other files, the
+Pascal files
+.I input
+and
+.I output
+must not be defined in a declaration,
+as their declaration is automatically:
+.LS
+\*bvar\fP input, output: text
+.LE
+.IP "\ \ \ \ \ 3)"
+The procedure
+.I reset
+may be used on
+.I input.
+If no
+.UX
+file name has ever been associated with
+.I input,
+and no file name is given, then an attempt will be made
+to `rewind'
+.I input.
+If this fails, a run time
+error will occur.
+.I Rewrite
+calls to output act as for any other file, except that
+.I output
+initially has no associated file.
+This means that a simple
+.LS
+rewrite(output)
+.LE
+associates a temporary name with
+.I output.
+.SH
+Details for files
+.PP
+If a file other than
+.I input
+is to be read,
+then reading must be initiated by a call to the
+procedure
+.I reset
+which causes the Pascal system to attempt to open the
+associated
+.UX
+file for reading.
+If this fails, then a runtime error occurs.
+Writing of a file other than
+.I output
+must be initiated by a
+.I rewrite
+call,
+which causes the Pascal system to create the associated
+.UX
+file and
+to then open the file for writing only.
+.SH
+Buffering
+.PP
+The buffering for
+.I output
+is determined by the value of the
+.B b
+option
+at the end of the
+.B program
+statement.
+If it has its default value 1,
+then
+.I output
+is
+buffered in blocks of up to 512 characters,
+flushed whenever a writeln occurs
+and at each reference to the file
+.I input.
+If it has the value 0,
+.I output
+is unbuffered.
+Any value of
+2 or more gives block buffering without line or
+.I input
+reference flushing.
+All other output files are always buffered in blocks of 512 characters.
+All output buffers are flushed when the files are closed at scope exit,
+whenever the procedure
+.I message
+is called, and can be flushed using the
+built-in procedure
+.I flush.
+.PP
+An important point for an interactive implementation is the definition
+of `input\(ua'.
+If
+.I input
+is a teletype, and the Pascal system reads a character at the beginning
+of execution to define `input\(ua', then no prompt could be printed
+by the program before the user is required to type some input.
+For this reason, `input\(ua' is not defined by the system until its definition
+is needed, reading from a file occurring only when necessary.
+.SH
+The character set
+.PP
+Seven bit
+.SM USASCII
+is the character set used on
+.UX .
+The standard Pascal
+symbols `and', 'or', 'not', '<=', '>=', '<>',
+and the uparrow `\(ua' (for pointer qualification)
+are recognized.\*(dg
+.FS
+\*(dgOn many terminals and printers, the up arrow is represented
+as a circumflex `^'.
+These are not distinct characters, but rather different graphic
+representations of the same internal codes.
+.FE
+Less portable are the 
+synonyms tilde `~'
+for
+.B not ,
+`&' for
+.B and ,
+and `|' for
+.B or .
+.PP
+Upper and lower case are considered distinct.
+Keywords and built-in
+.B procedure
+and
+.B function
+names are
+composed of all lower case letters.
+Thus the identifiers GOTO and GOto are distinct both from each other and
+from the keyword
+\*bgoto\fP.
+The standard type `boolean' is also available as `Boolean'.
+.PP
+Character strings and constants may be delimited by the character
+`\''
+or by the character `#';
+the latter is sometimes convenient when programs are to be transported.
+Note that the `#' character has special meaning 
+.up
+when it is the first character on a line \- see
+.I "Multi-file programs"
+below.
+.SH
+The standard types
+.PP
+The standard type
+.I integer
+is conceptually defined as
+.LS
+\*btype\fP integer = minint .. maxint;
+.LE
+.I Integer
+is implemented with 32 bit twos complement arithmetic.
+Predefined constants of type
+.I integer
+are:
+.LS
+\*bconst\fP maxint = 2147483647; minint = -2147483648;
+.LE
+.PP
+The standard type
+.I char
+is conceptually defined as
+.LS
+\*btype\fP char = minchar .. maxchar;
+.LE
+Built-in character constants are `minchar' and `maxchar', `bell' and `tab';
+ord(minchar) = 0, ord(maxchar) = 127.
+.PP
+The type
+.I real
+is implemented using 64 bit floating point arithmetic.
+The floating point arithmetic is done in `rounded' mode, and
+provides approximately 17 digits of precision
+with numbers as small as 10 to the negative 38th power and as large as
+10 to the 38th power.
+.SH
+Comments
+.PP
+Comments can be delimited by either `{' and `}' or by `(*' and `*)'.
+If the character `{' appears in a comment delimited by `{' and `}',
+a warning diagnostic is printed.
+A similar warning will be printed if the sequence `(*' appears in
+a comment delimited by `(*' and `*)'.
+The restriction implied by this warning is not part of standard Pascal,
+but detects many otherwise subtle errors.
+.SH
+Option control
+.PP
+Options of the translator may be controlled
+in two distinct ways.
+A number of options may appear on the command line invoking the translator.
+These options are given as one or more strings of letters preceded by the
+character `\-' and cause the default setting of
+each given option to be changed.
+This method of communication of options is expected to predominate
+for
+.UX .
+Thus the command
+.LS
+% \*bpi \-ls foo.p\fR
+.LE
+translates the file foo.p with the listing option enabled (as it normally
+is off), and with only standard Pascal features available.
+.PP
+If more control over the portions of the program where options are enabled is
+required, then option control in comments can and should be used.
+The
+format for option control in comments is identical to that used in Pascal
+6000\-3.4.
+One places the character `$' as the first character of the comment
+and follows it by a comma separated list of directives.
+Thus an equivalent to the command line example given above would be:
+.LS
+{$l+,s+ listing on, standard Pascal}
+.LE
+as the first line of the program.
+The `l'
+option is more appropriately specified on the command line,
+since it is extremely unlikely in an interactive environment
+that one wants a listing of the program each time it is translated.
+.PP
+Directives consist of a letter designating the option,
+followed either by a `+' to turn the option on, or by a `\-' to turn the
+option off.
+The
+.B b
+option takes a single digit instead of
+a `+' or `\-'.
+.SH
+Notes on the listings
+.PP
+The first page of a listing
+includes a banner line indicating the version and date of generation of
+.PI .
+It also
+includes the
+.UX
+path name supplied for the source file and the date of
+last modification of that file.
+.PP
+Within the body of the listing, lines are numbered consecutively and
+correspond to the line numbers for the editor.
+Currently, two special
+kinds of lines may be used to format the listing:
+a line consisting of a form-feed
+character, control-l, which causes a page
+eject in the listing, and a line with
+no characters which causes the line number to be suppressed in the listing,
+creating a truly blank line.
+These lines thus correspond to `eject' and `space' macros found in many
+assemblers.
+Non-printing characters are printed as the character `?' in the listing.\*(dg
+.FS
+\*(dgThe character generated by a control-i indents
+to the next `tab stop'.
+Tab stops are set every 8 columns in
+.UX .
+Tabs thus provide a quick way of indenting in the program.
+.FE
+.SH
+Multi-file programs
+.PP
+It is also possible to prepare programs whose parts are placed in more
+than one file.
+The files other than the main one are called
+.B include
+files and have names ending with `.i'.
+The contents of an \*binclude\fR file are referenced through a pseudo-statement
+of the form:
+.LS
+#\*binclude\fR "file.i"
+.LE
+The `#' character must be the first character on the line.
+The file name may be delimited with `"' or `\'' characters.
+Nested
+.B include s
+are possible up to 10 deep.
+More details are given in sections 5.9 and 5.10.
+.SH
+The standard procedure write
+.PP
+If no minimum field length parameter is specified
+for a
+.I write,
+the following default
+values are assumed:
+.KS
+.TS
+center;
+l n.
+integer        10
+real   22
+Boolean        10
+char   1
+string length of the string
+oct    11
+hex    8
+.TE
+.KE
+The end of each line in a text file should be explicitly
+indicated by `writeln(f)', where `writeln(output)' may be written
+simply as `writeln'.
+For
+.UX ,
+the built-in function `page(f)' puts a single
+.SM ASCII
+form-feed character on the output file.
+For programs which are to be transported the filter
+.I pcc
+can be used to interpret carriage control, as
+.UX
+does not normally do so.
+.NH 2
+Restrictions and limitations
+.SH
+Files
+.PP
+Files cannot be members of files or members of dynamically
+allocated structures.
+.SH
+Arrays, sets and strings
+.PP
+The calculations involving array subscripts and set elements
+are done with 16 bit arithmetic.
+This
+restricts the types over which arrays and sets may be defined.
+The lower bound of such a range must be greater than or equal to
+\-32768, and the upper bound less than 32768.
+In particular, strings may have any length from 1 to 32767 characters,
+and sets may contain no more than 32767 elements.
+.SH
+Line and symbol length
+.PP
+There is no intrinsic limit on the length of identifiers.
+Identifiers
+are considered to be distinct if they differ
+in any single position over their entire length.
+There is a limit, however, on the maximum input
+line length.
+This is quite generous however, currently exceeding 160
+characters.
+.SH
+Procedure and function nesting and program size
+.PP
+At most 20 levels of 
+.B procedure 
+and 
+.B function 
+nesting are allowed.
+There is no fundamental, translator defined limit on the size of the
+program which can be translated.
+The ultimate limit is supplied by the
+hardware and the fact that the \s-2PDP\s0-11 has a 16 bit address space.
+If
+one runs up against the `ran out of memory' diagnostic the program may yet
+translate if smaller procedures are used, as a lot of space is freed
+by the translator at the completion of each 
+.B procedure
+or
+.B function
+in the current
+implementation.
+.SH
+Overflow
+.PP
+There is currently no checking for overflow on arithmetic operations at
+run-time.
+.br
+.ne 15
+.NH 2
+Added types, operators, procedures and functions
+.SH
+Additional predefined types
+.PP
+The type
+.I alfa
+is predefined as:
+.LS
+\*btype\fP alfa = \*bpacked\fP \*barray\fP [ 1..10 ] \*bof\fP \*bchar\fP
+.LE
+.PP
+The type
+.I intset
+is predefined as:
+.LS
+\*btype\fP intset = \*bset of\fP 0..127
+.LE
+In most cases the context of an expression involving a constant
+set allows the translator to determine the type of the set, even though the
+constant set itself may not uniquely determine this type.
+In the
+cases where it is not possible to determine the type of the set from
+local context, the expression type defaults to a set over the entire base
+type unless the base type is integer\*(dg.
+.FS
+\*(dgThe current translator makes a special case of the construct
+`if ... in [ ... ]' and enforces only the more lax restriction
+on 16 bit arithmetic given above in this case.
+.FE
+In the latter case the type defaults to the current
+binding of
+.I intset,
+which must be ``type set of (a subrange of) integer'' at that point.
+.PP
+Note that if 
+.I intset 
+is redefined via:
+.LS
+\*btype\fP intset = \*bset of\fP 0..58;
+.LE
+then the default integer set is the implicit
+.I intset 
+of
+Pascal 6000\-3.4
+.SH
+Additional predefined operators
+.PP
+The relationals `<' and `>' of proper set
+inclusion are available.
+With
+.I a
+and
+.I b
+sets, note that
+.LS
+(\*bnot\fR (\fIa\fR < \fIb\fR)) <> (\fIa\fR >= \fIb\fR)
+.LE
+As an example consider the sets
+.I a
+= [0,2]
+and
+.I b
+= [1].
+The only relation true between these sets is `<>'.
+.SH
+Non-standard procedures
+.IP argv(i,a) 25
+where
+.I i 
+is an integer and
+.I a
+is a string variable
+assigns the (possibly truncated or blank padded)
+.I i \|'th
+argument
+of the invocation of the current
+.UX
+process to the variable
+.I a .
+The range of valid
+.I i
+is
+.I 0
+to
+.I argc\-1 .
+.IP date(a) 
+assigns the current date to the alfa variable 
+.I a
+in the format `dd mmm yy ', where `mmm' is the first
+three characters of the month, i.e. `Apr'.
+.IP flush(f) 
+writes the output buffered for Pascal file
+.I f
+into the associated
+.UX
+file.
+.IP halt 
+terminates the execution of the program with
+a control flow backtrace.
+.IP linelimit(f,x)\*(dd
+.FS
+\*(ddCurrently ignored by
+.X .
+.FE
+with
+.I f 
+a textfile and
+.I x 
+an integer expression
+causes
+the program to be abnormally terminated if more than
+.I x 
+lines are
+written on file
+.I f .
+If
+.I x 
+is less than 0 then no limit is imposed.
+.IP message(x,...) 
+causes the parameters, which have the format of those
+to the
+built-in
+.B procedure
+.I write,
+to be written unbuffered on the diagnostic unit 2,
+almost always the user's terminal.
+.IP null
+a procedure of no arguments which does absolutely nothing.
+It is useful as a place holder,
+and is generated by
+.XP
+in place of the invisible empty statement.
+.IP remove(a) 
+where
+.I a 
+is a string causes the
+.UX
+file whose
+name is
+.I a, 
+with trailing blanks eliminated, to be removed.
+.IP reset(f,a) 
+where
+.I a 
+is a string causes the file whose name
+is
+.I a 
+(with blanks trimmed) to be associated with
+.I f 
+in addition
+to the normal function of
+.I reset.
+.IP rewrite(f,a) 
+is analogous to `reset' above.
+.IP stlimit(i)
+where
+.I i 
+is an integer sets the statement limit to be
+.I i 
+statements.
+Specifying the
+.B p
+option to
+.I pc
+disables statement limit counting.
+.IP time(a) 
+causes the current time in the form `\ hh:mm:ss\ ' to be
+assigned to the alfa variable
+.I a.
+.SH
+Non-standard functions
+.IP argc 25
+returns the count of arguments when the Pascal program
+was invoked.
+.I Argc
+is always at least 1.
+.IP card(x) 
+returns the cardinality of the set
+.I x, 
+i.e. the
+number of elements contained in the set.
+.IP clock 
+returns an integer which is the number of central processor
+milliseconds of user time used by this process.
+.IP expo(x) 
+yields the integer valued exponent of the floating-point
+representation of
+.I x ;
+expo(\fIx\fP) = entier(log2(abs(\fIx\fP))).
+.IP random(x) 
+where
+.I x 
+is a real parameter, evaluated but otherwise
+ignored, invokes a linear congruential random number generator.
+Successive seeds are generated as (seed*a + c) mod m and
+the new random number is a normalization of the seed to the range 0.0 to 1.0;
+a is 62605, c is 113218009, and m is
+536870912.
+The initial seed
+is 7774755.
+.IP seed(i) 
+where
+.I i 
+is an integer sets the random number generator seed
+to
+.I i 
+and returns the previous seed.
+Thus seed(seed(i))
+has no effect except to yield value
+.I i.
+.IP sysclock
+an integer function of no arguments returns the number of central processor
+milliseconds of system time used by this process.
+.IP undefined(x) 
+a Boolean function.
+Its argument is a real number and
+it always returns false.
+.IP wallclock 
+an integer function of no arguments returns the time
+in seconds since 00:00:00 GMT January 1, 1970.
+.NH 2
+Remarks on standard and portable Pascal
+.PP
+It is occasionally desirable to prepare Pascal programs which will be
+acceptable at other Pascal installations.
+While certain system dependencies are bound to creep in,
+judicious design and programming practice can usually eliminate
+most of the non-portable usages.
+Wirth's
+.I "Pascal Report"
+concludes with a standard for implementation and program exchange.
+.PP
+In particular, the following differences may cause trouble when attempting
+to transport programs between this implementation and Pascal 6000\-3.4.
+Using the
+.B s
+translator option may serve to indicate many problem areas.\*(dg
+.FS
+\*(dgThe
+.B s
+option does not, however, check that identifiers differ
+in the first 8 characters.
+.I Pi
+also does not check the semantics of
+.B packed .
+.FE
+.SH
+Features not available in Berkeley Pascal
+.IP
+Formal parameters which are
+.B procedure
+or
+.B function .
+.IP
+Segmented files and associated functions and procedures.
+.IP
+The function
+.I trunc 
+with two arguments.
+.IP
+Arrays whose indices exceed the capacity of 16 bit arithmetic.
+.SH
+Features available in Berkeley Pascal but not in Pascal 6000-3.4
+.IP
+The procedures
+.I  reset 
+and
+.I  rewrite 
+with file names.
+.IP
+The functions
+.I argc,
+.I seed,
+.I sysclock,
+and
+.I wallclock.
+.IP
+The procedures
+.I argv,
+.I flush,
+and
+.I remove.
+.IP
+.I Message
+with arguments other than character strings.
+.IP
+.I Write
+with keyword
+.B hex .
+.IP
+The
+.B assert
+statement.
+.SH
+Other problem areas
+.PP
+Sets and strings are more general in \*
+.UP ;
+see the restrictions given in
+the 
+Jensen-Wirth
+.I "User Manual"
+for details on the 6000\-3.4 restrictions.
+.PP
+The character set differences may cause problems,
+especially the use of the function
+.I chr,
+characters as arguments to
+.I ord,
+and comparisons of characters,
+since the character set ordering
+differs between the two machines.
+.PP
+The Pascal 6000\-3.4 compiler uses a less strict notion of type equivalence.
+In
+.UP ,
+types are considered identical only if they are represented
+by the same type identifier.
+Thus, in particular, unnamed types are unique
+to the variables/fields declared with them.
+.PP
+Pascal 6000\-3.4 doesn't recognize our option
+flags, so it is wise to
+put the control of
+.UP
+options to the end of option lists or, better
+yet, restrict the option list length to one.
+.PP
+For Pascal 6000\-3.4 the ordering of files in the program statement has
+significance.
+It is desirable to place
+.I input 
+and
+.I output 
+as the first two files in the
+.B program
+statement.
diff --git a/doc/pascal/sin1.p b/doc/pascal/sin1.p
new file mode 100644 (file)
index 0000000..2124883
--- /dev/null
@@ -0,0 +1,13 @@
+program sinout(output);
+begin
+
+
+
+
+
+
+
+
+
+write(sin(1,2));
+end.
diff --git a/doc/pascal/sin2.p b/doc/pascal/sin2.p
new file mode 100644 (file)
index 0000000..4a2cc31
--- /dev/null
@@ -0,0 +1,13 @@
+program sinout(output);
+begin
+
+
+
+
+
+
+
+
+
+write(sin('*'));
+end.
diff --git a/doc/pascal/sinout1 b/doc/pascal/sinout1
new file mode 100644 (file)
index 0000000..6620f40
--- /dev/null
@@ -0,0 +1 @@
+E 12 - sin takes exactly one argument
diff --git a/doc/pascal/sinout2 b/doc/pascal/sinout2
new file mode 100644 (file)
index 0000000..e0b6cd2
--- /dev/null
@@ -0,0 +1 @@
+E 12 - sin's argument must be integer or real, not char
diff --git a/doc/pascal/synerr.p b/doc/pascal/synerr.p
new file mode 100644 (file)
index 0000000..33c13e7
--- /dev/null
@@ -0,0 +1,9 @@
+progran syn(output);
+var i, j are integer;
+begin
+       for j :* 1 to 20 begin
+               write(j);
+               i = 2 ** j;
+               writeln(i))
+       end
+end.
diff --git a/doc/pascal/synerr2.p b/doc/pascal/synerr2.p
new file mode 100644 (file)
index 0000000..4b7be59
--- /dev/null
@@ -0,0 +1,7 @@
+program synerr2(input,outpu);
+integer a(10)
+begin
+       read(b);
+       for c := 1 to 10 do
+               a(c) := b * c;
+end.
diff --git a/doc/pascal/synerr2out b/doc/pascal/synerr2out
new file mode 100644 (file)
index 0000000..43bf620
--- /dev/null
@@ -0,0 +1,23 @@
+Berkeley Pascal PI -- Version 1.1 (January 4, 1979)
+
+Sat Mar 31 11:50 1979  synerr2.p
+
+     1  program synerr2(input,outpu);
+     2  integer a(10)
+E \l'\w`w `u-\w`E `u '\l'\w`     2  `u-\w`w `u\&\(rh'\l'(\w`i`u-\w`^`u)/2 '\(ua\l'(\w`i`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Malformed declaration
+     3  begin
+     4          read(b);
+E \l'\w`w `u-\w`E `u '\l'\w`     4          read(`u-\w`w `u\&\(rh'\l'(\w`b`u-\w`^`u)/2 '\(ua\l'(\w`b`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Undefined variable
+     5          for c := 1 to 10 do
+E \l'\w`w `u-\w`E `u '\l'\w`     5          for `u-\w`w `u\&\(rh'\l'(\w`c`u-\w`^`u)/2 '\(ua\l'(\w`c`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Undefined variable
+     6                  a(c) := b * c;
+E \l'\w`w `u-\w`E `u '\l'\w`     6                  `u-\w`w `u\&\(rh'\l'(\w`a`u-\w`^`u)/2 '\(ua\l'(\w`a`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Undefined procedure
+E \l'\w`w `u-\w`E `u '\l'\w`     6                  a(c) `u-\w`w `u\&\(rh'\l'(\w`:`u-\w`^`u)/2 '\(ua\l'(\w`:`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Malformed statement
+     7  end.
+E 1 - File outpu listed in program statement but not declared
+e 1 - The file output must appear in the program statement file list
+In program synerr2:
+  E - a undefined on line 6
+  E - b undefined on line 4
+  E - c undefined on lines 5 6
+Execution suppressed due to compilation errors
diff --git a/doc/pascal/synerrout b/doc/pascal/synerrout
new file mode 100644 (file)
index 0000000..66e963e
--- /dev/null
@@ -0,0 +1,20 @@
+Berkeley Pascal PI -- Version 1.1 (January 4, 1979)
+
+Sat Mar 31 11:50 1979  synerr.p
+
+     1  progran syn(output);
+e \l'\w`w `u-\w`e `u '\l'\w`     1  `u-\w`w `u\&\(rh'\l'(\w`p`u-\w`^`u)/2 '\(ua\l'(\w`p`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Replaced identifier with a keyword program
+     2  var i, j are integer;
+e \l'\w`w `u-\w`e `u '\l'\w`     2  var i, j `u-\w`w `u\&\(rh'\l'(\w`a`u-\w`^`u)/2 '\(ua\l'(\w`a`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Replaced identifier with a ':'
+     3  begin
+     4          for j :* 1 to 20 begin
+e \l'\w`w `u-\w`e `u '\l'\w`     4          for j :`u-\w`w `u\&\(rh'\l'(\w`*`u-\w`^`u)/2 '\(ua\l'(\w`*`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Replaced '*' with a '='
+e \l'\w`w `u-\w`e `u '\l'\w`     4          for j :* 1 to 20 `u-\w`w `u\&\(rh'\l'(\w`b`u-\w`^`u)/2 '\(ua\l'(\w`b`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted keyword do
+     5                  write(j);
+     6                  i = 2 ** j;
+e \l'\w`w `u-\w`e `u '\l'\w`     6                  i `u-\w`w `u\&\(rh'\l'(\w`=`u-\w`^`u)/2 '\(ua\l'(\w`=`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted ':'
+E \l'\w`w `u-\w`E `u '\l'\w`     6                  i = 2 *`u-\w`w `u\&\(rh'\l'(\w`*`u-\w`^`u)/2 '\(ua\l'(\w`*`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Inserted identifier
+     7                  writeln(i))
+E \l'\w`w `u-\w`E `u '\l'\w`     7                  writeln(i)`u-\w`w `u\&\(rh'\l'(\w`)`u-\w`^`u)/2 '\(ua\l'(\w`)`u-\w`^`u)/2 '\l'\w`---`u\&\(rh' Deleted ')'
+     8          end
+     9  end.
diff --git a/doc/pascal/tmac.p b/doc/pascal/tmac.p
new file mode 100644 (file)
index 0000000..08901f1
--- /dev/null
@@ -0,0 +1,76 @@
+'so /usr/lib/tmac/tmac.s
+.if t .tr \(rh-
+.if t .tr *\(**=\(eq/\(sl+\(pl
+.bd S B 3
+.de SM
+.if "\\$1"" .ps -2
+.if !"\\$1"" \s-2\\$1\s0\\$2
+..
+.de LG
+.if "\\$1"" .ps +2
+.if !"\\$1"" \s+2\\$a\s0\\$2
+..
+.de HP
+.nr pd \\n(PD
+.nr PD 0
+.if \\n(.$=0 .IP
+.if \\n(.$=1 .IP "\\$1"
+.if \\n(.$>=2 .IP "\\$1" "\\$2"
+.nr PD \\n(pd
+.rm pd
+..
+.de LS         \"LS - Literal display, ASCII, constant spaced DS
+.XD
+.ID
+.nf
+.if t .tr '\'`\`^\(ua-\(mi
+.if t .tr _\(ul
+..
+.de LE         \"LE - End literal display
+.DE
+.tr ''``__--^^
+..
+.de UP
+Berkeley Pascal\\$1
+..
+.de PD
+\s-2PDP\s0
+.if \\n(.$=0 11/70
+.if \\n(.$>0 11/\\$1
+..
+.de DK
+Digital Equipment Corporation\\$1
+..
+.de IN
+.I
+.if \\n(.$<2 \\$1 1.0 Implementation Notes
+.if \\n(.$>=2 \\$1 1.0 Implementation Notes\\c
+.R
+.if \\n(.$>=2 \\$2
+..
+.de UM
+.I
+User's Manual
+.R
+..
+.de PI
+.I pi \\$1
+..
+.de XP
+.I pxp \\$1
+..
+.de IX
+.I pix \\$1
+..
+.de X
+.I px \\$1
+..
+.if n .ds dg +
+.if t .ds dg \(dg
+.if n .ds dd *
+.if t .ds dd \(dd
+.if n .nr FM 1.12i
+.if t .ds b \\fB
+.if n .ds b \\fI
+.ds i \\fI
+.nr xx 1
diff --git a/doc/pascal/typequ.p b/doc/pascal/typequ.p
new file mode 100644 (file)
index 0000000..7d080dc
--- /dev/null
@@ -0,0 +1,10 @@
+program x(output);
+var
+       x: ^ integer;
+       y: ^ integer;
+begin
+       new(y);
+       x := y;
+       x^ := 1;
+       x := x;
+end.
diff --git a/doc/pascal/typequout b/doc/pascal/typequout
new file mode 100644 (file)
index 0000000..46615f2
--- /dev/null
@@ -0,0 +1,2 @@
+E 7 - Type clash: non-identical pointer types
+  ... Type of expression clashed with type of variable in assignment
diff --git a/doc/pascal/xxxxqqqout b/doc/pascal/xxxxqqqout
new file mode 100644 (file)
index 0000000..a2c8ee2
--- /dev/null
@@ -0,0 +1,5 @@
+xxxxqqq: No such file or directory
+
+       Error at "kat"+5 near line 11
+
+4 statements executed in 0.01 seconds cpu time
diff --git a/doc/pascal/xxxxqqqout2 b/doc/pascal/xxxxqqqout2
new file mode 100644 (file)
index 0000000..79145e8
--- /dev/null
@@ -0,0 +1 @@
+xxxxqqq: No such file or directory
diff --git a/doc/px/fig1.1.n b/doc/px/fig1.1.n
new file mode 100644 (file)
index 0000000..3acfbbf
--- /dev/null
@@ -0,0 +1,45 @@
+.KF
+.TS
+center;
+c l
+l l
+_ l
+| l |
+| cw(18) | aw(28)
+| _ | l
+| c |
+| _ | a
+| c |
+| l |
+| _ | l
+c l.
+Base of stack frame
+
+
+
+Block mark     Positive offsets
+.sp
+       \(<- Display entry points here
+T{
+.sp
+Local variables
+T}
+       Negative offsets
+T{
+.sp
+Temporary
+.br
+expression
+.br
+space
+T}
+
+
+.sp
+Top of stack frame
+.sp
+.TE
+.ce
+Figure 1.1 \- Structure of stack frame
+.sp
+.KE
diff --git a/doc/px/fig1.2.n b/doc/px/fig1.2.n
new file mode 100644 (file)
index 0000000..3dd4caa
--- /dev/null
@@ -0,0 +1,47 @@
+.KF
+.TS
+center;
+l l
+| lw(22n) | aw(20n).
+_      
+T{
+.ce 1000
+.sp
+Saved lino
+.sp
+Saved lc
+.sp
+Saved dp
+.sp
+.ce 0
+T}     T{
+.if n .sp 2
+Created by \s-2CALL\s0
+T}
+_      
+T{
+.ce 1000
+.sp
+Saved dp contents
+.sp
+Pointer to current
+section name and
+entry line
+.sp
+Current file name
+and buffer
+.sp
+Top of stack reference
+.sp
+.ce 0
+T}     T{
+.if n .sp 2
+Created by \s-2BEG\s0
+T}
+_      
+.TE
+.sp
+.ce
+Figure 1.2 \- Block mark structure
+.sp
+.KE
diff --git a/doc/px/fig1.3.n b/doc/px/fig1.3.n
new file mode 100644 (file)
index 0000000..958d745
--- /dev/null
@@ -0,0 +1,27 @@
+.TS
+center, allbox;
+lw(20).
+T{
+.nf
+.ce 1000
+Space for
+value returned
+from f
+.ce 0
+.fi
+T}
+T{
+.ce
+Value of a
+T}
+T{
+.sp
+.ce
+Block Mark
+.sp
+T}
+.TE
+.sp .1i
+.ce
+Figure 1.3 \- Stack structure on function call `f(a)'
+.sp .1i
diff --git a/doc/px/fig2.1.n b/doc/px/fig2.1.n
new file mode 100644 (file)
index 0000000..e74836e
--- /dev/null
@@ -0,0 +1,92 @@
+ABORT  2.2     Halt execution immediately for debugging
+ABS*   2.7     Absolute value
+ADD*   2.7     Addition
+AND    2.4     Boolean and
+ARGC   2.13    Built-in function
+ARGV   2.13    Built-in procedure
+AS*    2.5     Assignment operators
+ASRT   2.12    Assert true to continue
+ATAN   2.13    Built-in function
+BEG w,w,"      2.2,1.8 Write second part of block mark, enter block
+BUFF   3.6     Specify buffering for file output
+CALL l,a       2.2,1.8 Procedure or function call
+CARD s 2.11    Cardinality of set
+CASEOP*        2.9     Case statements
+CHR*   2.13    Built-in function
+CLCK   2.13    Built-in function clock
+CON* v 2.5     Load constant operators
+COUNT s        2.10    Count a statement count point
+CTTOT s,w,w    2.11    Construct set
+DATE   2.13    Built-in procedure
+DEFNAME s      3.6     Attach file name for prgram statement files
+DISPOSE        2.13    Built-in procedure
+DIV*   2.7     Division
+DVD*   2.7     Floating division
+END    2.2,1.8 End block execution
+EOF    3.6     Boolean built-in function
+EOLN   3.6     Boolean built-in function
+EXP    2.13    Built-in function
+EXPO   2.13    Built-in function yielding exponent of real
+FNIL   3.6     Check file initialized, not eof, synced
+FOR* a 2.12    For statements
+GET    3.6     File procedure get
+GOTO l,a       2.2,1.8 Non-local goto statement
+HALT   2.2     Produce control flow backtrace
+IF a   2.3     Conditional transfer
+IN s,w,w       2.11    Set membership
+INCT   2.11    Membership in a constructed set
+IND*   2.6     Indirection operators
+INX* s,w,w     2.6     Subscripting (indexing) operator
+ITOD   2.12    Convert integer to real
+ITOS   2.12    Convert integer to short integer
+LINO s 2.2     Set line number, count statements
+LLIMIT 2.13    Built-in procedure
+LN     2.13    Built-in function
+LV l,w 2.6     Address of operator
+MESSAGE l      3.6     Write to terminal, built-in procedure
+MOD*   2.7     Modulus
+MUL*   2.7     Multiplication
+NEG*   2.7     Negation
+NEW s  2.13    Built-in procedure
+NIL    2.6     Assert non-nil pointer
+NODUMP w       2.2     \s-2BEG\s0 main program, suppress pm dump
+NOT    2.4     Boolean not
+ODD*   2.13    Built-in function
+OFF s  2.5     Offset address (i.e. for field reference)
+OR     2.4     Boolean or
+PAGE   3.6     Built-in procedure
+POP s  2.2,1.9 Pop (arguments) off stack
+PRED*  2.13    Built-in function
+PUSH s 2.2,1.9 Clear space (for function result)
+PUT    3.6     File procedure put
+PXPBUF w       2.10    Initialize \fIpxp\fP count buffer
+RANDOM 2.13    Built-in function
+RANG* v        2.8     Subrange checking
+READ*  3.6     Built-in procedure
+REL* r 2.3     Relational test yielding Boolean result
+REMOVE s       3.6     Remove a file
+RESET s,w      3.6     Built-in procedure
+REWRITE s,w    3.6     Built-in procedure
+ROUND  2.13    Built-in function
+RV* l,a        2.5     Rvalue (load) operators
+SCLCK  2.13    Built-in function sysclock
+SDUP   2.2     Duplicate top stack word
+SEED   2.13    Built-in function
+SIN    2.13    Built-in function
+SQR*   2.7     Squaring
+SQRT   2.13    Built-in function
+STLIM  2.13    Built-in procedure for changing statement limit
+STOD   2.12    Convert short integer to real
+STOI   2.12    Convert short to long integer
+SUB*   2.7     Subtraction
+SUCC*  2.13    Built-in function
+TIME   2.13    Built-in procedure
+TRA a  2.2     Transfer of control (local goto)
+TRACNT w,a     2.10    Count a procedure entry
+TRUNC  2.13    Built-in function
+UNDEF  2.13    Built-in function
+UNIT*  3.6     Set active file
+WRHEX* l       3.6     Hexadecimal write
+WRITE* l       3.5     Built-in procedure
+WRITELN        3.6     Write a new line character
+WROCT* l       3.6     Octal write
diff --git a/doc/px/fig2.1.raw b/doc/px/fig2.1.raw
new file mode 100644 (file)
index 0000000..9bed8f3
--- /dev/null
@@ -0,0 +1,92 @@
+ABORT  2.2     Halt execution immediately for debugging
+HALT   2.2     Produce control flow backtrace
+BEG w,w,"      2.2,1.8 Write second part of block mark, enter block
+END    2.2,1.8 End block execution
+CALL l,a       2.2,1.8 Procedure or function call
+NODUMP w       2.2     \s-2BEG\s0 main program, suppress pm dump
+PUSH s 2.2,1.9 Clear space (for function result)
+POP s  2.2,1.9 Pop (arguments) off stack
+TRA a  2.2     Transfer of control (local goto)
+LINO s 2.2     Set line number, count statements
+GOTO l,a       2.2,1.8 Non-local goto statement
+IF a   2.3     Conditional transfer
+REL* r 2.3     Relational test yielding Boolean result
+AND    2.4     Boolean and
+OR     2.4     Boolean or
+NOT    2.4     Boolean not
+RV* l,a        2.5     Rvalue (load) operators
+CON* v 2.5     Load constant operators
+AS*    2.5     Assignment operators
+OFF s  2.5     Offset address (i.e. for field reference)
+INX* s,w,w     2.6     Subscripting (indexing) operator
+NIL    2.6     Assert non-nil pointer
+LV l,w 2.6     Address of operator
+IND*   2.6     Indirection operators
+ADD*   2.7     Addition
+SUB*   2.7     Subtraction
+MUL*   2.7     Multiplication
+SQR*   2.7     Squaring
+DIV*   2.7     Division
+MOD*   2.7     Modulus
+ABS*   2.7     Absolute value
+NEG*   2.7     Negation
+DVD*   2.7     Floating division
+RANG* v        2.8     Subrange checking
+CASEOP*        2.9     Case statements
+FOR* a 2.12    For statements
+PXPBUF w       2.10    Initialize \fIpxp\fP count buffer
+TRACNT w,a     2.10    Count a procedure entry
+COUNT s        2.10    Count a statement count point
+CTTOT s,w,w    2.11    Construct set
+CARD s 2.11    Cardinality of set
+STOI   2.12    Convert short to long integer
+STOD   2.12    Convert short integer to real
+ITOD   2.12    Convert integer to real
+ITOS   2.12    Convert integer to short integer
+GET    3.6     File procedure get
+PUT    3.6     File procedure put
+MESSAGE l      3.6     Write to terminal, built-in procedure
+FNIL   3.6     Check file initialized, not eof, synced
+BUFF   3.6     Specify buffering for file output
+EOF    3.6     Boolean built-in function
+EOLN   3.6     Boolean built-in function
+RESET s,w      3.6     Built-in procedure
+REWRITE s,w    3.6     Built-in procedure
+REMOVE s       3.6     Remove a file
+UNIT*  3.6     Set active file
+READ*  3.6     Built-in procedure
+WRITE* l       3.5     Built-in procedure
+PAGE   3.6     Built-in procedure
+WROCT* l       3.6     Octal write
+WRHEX* l       3.6     Hexadecimal write
+DEFNAME s      3.6     Attach file name for prgram statement files
+LLIMIT 2.13    Built-in procedure
+ARGC   2.13    Built-in function
+ARGV   2.13    Built-in procedure
+SCLCK  2.13    Built-in function sysclock
+CLCK   2.13    Built-in function clock
+DATE   2.13    Built-in procedure
+TIME   2.13    Built-in procedure
+SEED   2.13    Built-in function
+RANDOM 2.13    Built-in function
+DISPOSE        2.13    Built-in procedure
+NEW s  2.13    Built-in procedure
+EXPO   2.13    Built-in function yielding exponent of real
+ATAN   2.13    Built-in function
+EXP    2.13    Built-in function
+LN     2.13    Built-in function
+SIN    2.13    Built-in function
+SQRT   2.13    Built-in function
+CHR*   2.13    Built-in function
+ODD*   2.13    Built-in function
+PRED*  2.13    Built-in function
+STLIM  2.13    Built-in procedure for changing statement limit
+SUCC*  2.13    Built-in function
+ROUND  2.13    Built-in function
+TRUNC  2.13    Built-in function
+UNDEF  2.13    Built-in function
+SDUP   2.2     Duplicate top stack word
+WRITELN        3.6     Write a new line character
+ASRT   2.12    Assert true to continue
+IN s,w,w       2.11    Set membership
+INCT   2.11    Membership in a constructed set
diff --git a/doc/px/fig2.2.n b/doc/px/fig2.2.n
new file mode 100644 (file)
index 0000000..c0b79e4
--- /dev/null
@@ -0,0 +1,27 @@
+.TS
+center, allbox;
+cw(15)
+c
+l
+l.
+\s-2CASEOP\s0
+No. of cases
+T{
+.sp
+.nf
+.ce 3
+Case
+transfer
+table
+.fi
+T}
+T{
+.sp
+.nf
+.ce 2
+Array of case
+label values
+.fi
+.sp
+T}
+.TE
diff --git a/doc/px/makefile b/doc/px/makefile
new file mode 100755 (executable)
index 0000000..47f4c20
--- /dev/null
@@ -0,0 +1,4 @@
+pxin: fig2.1.n
+       soelim pxin?.n | tbl | /usr/new/vtroff -o-1,22-
+fig2.1.n: fig2.1.raw
+       sort fig2.1.raw >fig2.1.n
diff --git a/doc/px/pxin0.n b/doc/px/pxin0.n
new file mode 100644 (file)
index 0000000..cc8b44a
--- /dev/null
@@ -0,0 +1,98 @@
+.if !\n(xx .so tmac.p
+.RP
+.TL
+Berkeley Pascal
+PX Implementation Notes
+.br
+Version 1.1 \- April, 1979
+.AU
+William N. Joy\*(dg
+.AI
+Computer Science Division
+Department of Electrical Engineering and Computer Science
+University of California, Berkeley
+Berkeley, California  94720
+.AB
+.PP
+Berkeley Pascal
+is designed for interactive instructional use and runs on the
+\s-2PDP\s0 11 computer family.
+..A version of \fIpx\fR for the \s-2VAX\s0 11/780 is nearly complete.
+The interpreter
+.I px
+executes the Pascal binaries generated by the Pascal translator
+.I pi .
+.PP
+The
+.I
+PX Implementation Notes
+.R
+describe the overall organization of
+.I px ,
+detail the various operations of the interpreter,
+with a special section describing the file input/output structure.
+Conclusions are given as to the viability of an interpreter
+based approach to language implementation for an instructional environment.
+.AE
+.if n 'ND
+.SH
+Introduction
+.PP
+This
+.I
+PX Implementation Notes
+.R
+consists of four major parts.
+The first part outlines the overall organization of
+.I px .
+Section 2 describes the operations (instructions) of the interpreter
+while section 3 focuses on input/output related activity.
+A final section gives conclusions about the viability of an interpreter
+based approach to language implementation for instruction.
+.SH
+Related Berkeley Pascal documents
+.PP
+The
+.I "PXP Implementation Notes"
+give details of the internals of the execution profiler
+.I pxp;
+parts of the interpreter related to
+.I pxp
+are discussed in section 2.10.
+A paper describing the syntactic error recovery mechanism used in
+.I pi
+will be presented at the ACM Conference on Compiler Construction
+in Boulder Colorado in August, 1979.
+.SH
+Acknowledgements
+.PP
+This version of
+.I px
+is heavily based on an earlier
+.I px
+which was designed and implemented by Ken Thompson,
+the author of the first
+.UP
+system.
+Without his work, this
+.UP
+system would never have existed.
+Charles Haley, who collaborated with the author on this project, wrote
+some of the more difficult input/output routines in this version of
+.I px,
+and helped to debug it all.
+His assistance in teaching this author about
+.UX
+and Pascal is gratefully acknowledged and appreciated.
+The author would also like to thank his faculty advisor Susan L. Graham
+for her encouragement,
+her helpful comments and suggestions
+relating to
+.UP
+and her excellent editorial assistance.
+.FS
+\*(dg The financial support of the National Science Foundation under grants
+MCS74-07644-A03 and MCS78-07291
+and of an \s-2IBM\s0 Graduate Fellowship are gratefully acknowledged.
+.FE
+.bp
diff --git a/doc/px/pxin1.n b/doc/px/pxin1.n
new file mode 100644 (file)
index 0000000..efb2e34
--- /dev/null
@@ -0,0 +1,559 @@
+.if !\n(xx .so tmac.p
+.nr H1 0
+.NH 
+Organization
+.PP
+Most of
+.I px
+is written in the
+\s-2PDP\s0-11
+assembly language, using the
+.UX
+assembler
+.I as.
+Portions of
+.I px
+are also written in the
+.UX
+systems programming language C.
+.I Px
+consists of a main procedure which reads in the interpreter code,
+a main interpreter loop which transfers successively to various
+code segments implementing the abstract machine operations
+and built-in procedures and functions,
+the code segments themselves, and
+a number of routines which support the implementation of the
+Pascal input-output environment.
+.PP
+The interpreter runs at a fraction of the speed of equivalent
+compiled C code, with this fraction varying from 1/5 to 1/15.
+The fact that the interpreter implements 32 bit integer arithmetic
+on a 16 bit machine notably degrades its speed.
+In a code generated Pascal for a
+\s-2PDP\s0-11, 32 bit integers would be undesirable.
+.PP
+The interpreter occupies 14.6K bytes of instruction space, which is shared
+between all instances of the interpreter, and 5K bytes of data space
+of which there is a copy for each interpreter execution.
+.PP
+The interpreter occupies 14.6K bytes of instruction space, shared among
+all processes executing Pascal, and has 4.6K bytes of data space (constants,
+error messages, etc.) a copy of which is allocated to each executing process.
+.NH 2
+Format of the object file
+.PP
+.I Px
+normally interprets the code left in an object file by a run of the
+Pascal translator
+.I pi.
+The file where the translator puts the object originally, and the most
+commonly interpreted file, is called
+.I obj.
+We will first describe the way the object file was prepared in version 1.0
+of the interpreter.
+.PP
+In version 1.0 of the interpreter, the
+.I obj
+file has an extremely simple format.
+The first word of the file has the octal value 404,
+a ``magic'' number.
+This number,
+like the numbers 407, 410, and 411 which signify executable files to the
+system,
+can be recognized by a modified shell (command interpreter)
+which can then fork instances of
+.I px
+to interpret the file.
+In this way, Pascal objects can be referred to at the shell level by typing
+their names.
+The modified shell can open each file which is executable
+but does not have a magic number recognized by the operating system.
+If the first word of such a file is 404, then the shell recognizes
+the file as a Pascal object, and creates an instance of the Pascal
+interpreter with the specified file as its first argument.
+This, importantly, allows all processes executing Pascal objects to share
+the same interpreter, and allows the Pascal object files to be small
+as they do not contain a copy of the interpreter.
+.PP
+With version 1.1 of the Pascal system an option exists to have the translator
+prepare true executable files.  In order that all persons using
+.I px
+share a common text image, this executable file is not an interpreter,
+but rather a small process which coordinates with the iinterpreter to start
+execution.
+The way in which this happens is somewhat complicated.
+When one of these object files is created, the interpreter code is placed
+at the end of a special ``header'' file and the size of the initialized
+data area of this header file is expanded to include this code.
+When the process executes, the interpreter code is thus available at a
+easily determined address in its data space.
+When executed, the object process creates an
+.I pipe ,
+creates another process by doing a
+.I fork ,
+and arranges that the resulting parent process becomes an instance of
+.I px .
+The child process then writes, through the pipe whicch it has to the parent,
+interpreter process, the interpreter code.
+When this process is complete, the child exits.
+.PP
+The real advantage of this approach is that it does not require modifications
+to the shell, and that the resultant objects are ``true objects'' not
+requiring special treatment.
+A simpler mechanism would be to determine the name of the file which was
+executed and pass this to the interpreter.
+However it is not possible to determine this name in all cases.\u\*(dg\d
+.FS
+\*(dgFor instance, if the
+.I pxref
+program is placed in the directory
+`/usr/bin'
+then when the user types
+``pxref prog1.p''
+the first argument to the program, nominally the programs name, is
+``pxref.''
+While it would be possible to search in the standard place,
+i.e. the current directory, and the system directories
+`/bin'
+and
+`/usr/bin'
+for a corresponding object file,
+this would be expensive and not guaranteed to succeed.
+Several shells exist which allow other directories to be searched
+for commands, and there is,
+in general,
+no way to determine what these directories are.
+.FE
+.PP
+After the first word containing the value 404,
+the remainder of the
+.I obj
+file contains the object code.
+.NH 2
+General features of object code
+.PP
+Pascal object code is relocatable as all addressing references for
+control transfers within the code are relative.
+The code consists of instructions interspersed with inline data.
+All instructions have a length which is an even number of bytes,
+that is, an integral number of words.
+No variables are kept in the object code area.
+.PP
+The first byte of a Pascal interpreter instruction contains an operation
+code.
+This allows a total of 256 major operation codes, and 219 of these are
+in use in the current
+.I px.
+The second byte of each interpreter instruction is called the
+``sub-operation code'',
+or more commonly the
+.I subop.
+It contains a small integer which may, for example, be used as a
+block-structure level for the associated operation.
+If the instruction can take a fullword constant,
+this constant is often packed into the subop
+if it fits into 8 bits and is not zero.
+A subop value of 0 indicates that the constant wouldn't
+fit and therefore follows in the next word.
+This is a space optimization, the value of 0 for flagging
+the longer case being convenient because it is easy to test.
+.PP
+Other instruction formats are used.
+The branching
+instructions take an offset in the following word,
+operators which load constants onto the stack 
+take arbitrarily long inline constant values,
+and a large number of operations deal exclusively with data on the
+interpreter stack, requiring no inline data.
+.NH 2
+Stack structure of the interpreter
+.PP
+The interpreter emulates a stack-structured Pascal machine.
+The ``load'' instructions put values onto the stack, where all
+arithmetic operations take place.
+The ``store'' instructions take values off the stack
+and place them in an address which is also contained on the stack.
+The only way to move data or to compute in the machine is with the stack.
+.PP
+To make the interpreter operations more powerful
+and to thereby increase the interpreter speed,
+the arithmetic operations in the interpreter are ``typed''.
+That is, length conversion of arithmetic values occurs when they are
+used in an operation.
+This eliminates the need for interpreter cycles for length conversion
+and the associated overhead.
+For example, when adding an integer which fits in one byte to one which
+requires four bytes to store, no ``conversion'' operators are required.
+The one byte integer is loaded onto the stack, followed by the four
+byte integer, and then an adding operator is used which has, implicit
+in its definition, the sizes of the arguments.
+.NH 2
+Data types in the interpreter
+.PP
+The interpreter deals with several different fundamental data types.
+In the memory of the machine, 1, 2, and 4 byte integers are supported,
+with only 2 and 4 byte integers being present on the stack.
+The interpreter always converts to 4 byte integers when there is a possibility
+of overflowing the shorter formats.
+This corresponds to the Pascal language definition of overflow in
+arithmetic operations which requires that the result be correct
+if all partial values lie within the bounds of the base integer type:
+4 byte integer values.
+.PP
+Character constants are treated similarly to 1 byte integers for
+most purposes, as are Boolean values.
+All enumerated types are, in fact, treated as integer values of
+an appropriate length, usually 1 byte.
+The interpreter also has real numbers, occupying 8 bytes of storage,
+and sets and strings of varying length.
+The appropriate operations are included for each data type, such as
+set union and intersection and an operation to write a string
+which is on top of the stack to a file.
+.PP
+No special
+.B packed
+data formats are supported by the interpreter.
+The smallest unit of storage occupied by any variable is one byte.
+The built-ins
+.I pack
+and
+.I unpack
+thus degenerate to simple memory to memory transfers with
+no special processing.
+.NH 2
+Runtime environment
+.PP
+The interpreter runtime environment uses a stack data area and a heap
+data area, which are kept at opposite ends of memory
+and grow towards each other.
+All global variables and variables local to procedures and functions
+are kept in the stack area.
+Dynamically allocated variables and buffers for input/output are
+allocated in the heap.
+.PP
+The addressing of block structured variables is accomplished through
+a fixed display which contains, for each 
+statically active block, the address of its stack frame.\*(dg
+.FS
+\*(dg Here ``block'' is being used to mean any
+.I procedure ,
+.I function
+or the main program.
+.FE
+This display is referenced by instructions which load and store
+variables and maintained by the operations for
+block entry and exit, and for non-local
+.B goto
+statements.
+.NH 2
+Dp, lc, lp
+.PP
+Three ``global'' variables in the interpreter, in addition to the
+``display'', are the
+.I dp,
+.I lc,
+and the
+.I lp.
+The
+.I dp
+is a pointer to the display entry for the current block;
+the
+.I lc
+is the abstract machine location counter;
+and the
+.I lp
+is a register which holds the address of the main interpreter
+loop so that returning to the loop to fetch the next instruction is
+a fast operation.
+.NH 2
+The stack frame structure
+.PP
+Each active block
+has a stack frame consisting of three parts:
+a block mark, local variables, and temporary storage for partially
+evaluated expressions.
+The stack in the interpreter grows from the high addresses in memory
+to the low addresses,
+so that those parts of the stack frame which are ``on the top''
+of the stack have the most negative offsets from the display
+entry for the block.
+The major parts of the stack frame are represented in Figure 1.1.
+.so fig1.1.n
+Note that the local variables of each block
+have negative offsets from the corresponding display entry,
+the ``first'' local variable having offset `\-2'.
+.NH 2
+The block mark
+.PP
+The block mark contains the saved information necessary
+to restore the environment when the current block exits.
+It consists of two parts.
+The first and top-most part is saved by the
+.SM CALL
+instruction in the interpreter.
+This information is not present for the main program
+as it is never ``called''.
+The second part of the block mark is created by the
+.SM BEG
+begin block operator which also allocates and clears the
+local variable storage.
+The format of these blocks is represented in Figure 1.2.
+.sp
+.so fig1.2.n
+.PP
+The data saved by the
+.SM CALL
+operator includes the line number
+.I lino
+of the point of call,
+which is printed if the program execution terminates abnormally;
+the location counter
+.I lc
+giving the return address;
+and the current display entry address
+.I dp
+at the time of call.
+.PP
+The
+.SM BEG
+begin operator saves the previous display contents at the level
+of this block, so that the display can be restored on block exit.
+A pointer to 10 bytes of information giving the first eight characters of the
+name of this block and its beginning line number is also saved.
+This information is stored in the intepretor object code in-line after the
+.SM BEG
+operator.
+It is used in printing a post-mortem backtrace.
+The saved file name and buffer reference are necessary because of
+the input/output structure
+(this is discussed in detail in 
+sections 3.3 and 3.4).
+The top of stack reference gives the value the stack pointer should
+have when there are no expression temporaries on the stack.
+It is used for a consistency check in the
+.SM LINO
+line number operators in the interpreter, which occurs before
+each statement executed.
+This helps to catch bugs in the interpreter, which often manifest
+themselves by leaving the stack non-empty between statements.
+.PP
+Note that there is no explicit static link here.
+Thus to set up the display correctly after a non-local
+.B goto
+statement one must ``unwind''
+through all the block marks on the stack to rebuild the display.
+.NH 2
+Arguments and return values
+.PP
+A function returns its value into a space reserved by the calling
+block.
+Arguments to a
+.B function
+are placed on top of this return area.
+For both
+.B procedure
+and
+.B function
+calls, arguments are placed at the end of the expression evaluation area
+of the caller.
+When a
+.B function
+completes, expression evaluation can continue
+after popping the arguments to the
+.B function
+off the stack,
+exactly as if the function value had been ``loaded''.
+The arguments to a
+.B procedure
+are also popped off the stack by the caller
+after its execution terminates.
+.KS
+.PP
+As a simple example consider the following stack structure
+for a call to a function
+.I f,
+of the form ``f(a)''.
+.so fig1.3.n
+.KE
+.PP
+If we suppose that
+.I f
+returns a
+.I real
+and that
+.I a
+is an integer,
+the calling sequence for this function would be:
+.DS
+.TS
+lp-2w(8) l.
+PUSH   -8
+RV4    \fIa\fR
+CALL   \fIf\fR
+POP    4
+.TE
+.DE
+.ZP
+Here we use the operator
+.SM PUSH
+to clear space for the return value,
+load
+.I a
+on the stack with an ``rvalue'' operator,
+call the function,
+pop off the argument
+.I a ,
+and can then complete evaluation of the containing expression.
+The operations used here will be explained in section 2.
+.PP
+If the function
+.I f
+were given by
+.LS
+ 10 \*bfunction\fR f(i: integer): real;
+ 11 \*bbegin\fR
+ 12     f := i
+ 13 \*bend\fR;
+.LE
+then
+.I f
+would have code sequence:
+.DS
+.TS
+lp-2w(8) l.
+BEG    0
+       "f"
+       11
+LV     \fIl\fR,20
+RV4    \fIl\fR,16
+AS48
+END
+.TE
+.DE
+.ZP
+Here the
+.SM BEG
+operator takes 12 bytes of inline data.
+The first word indicates the amount of local variable storage, here none.
+The succeeding two lines give the name of the block and the line number
+of the
+.B begin
+for error traceback.
+The
+.SM BEG
+operator places a pointer to the name and line number in the block mark.
+.PP
+The body of the
+.B function
+here involved taking an address of the
+.B function
+result variable
+.I f
+using the address of operator
+.SM LV .
+.I a .
+The next operation in the interpretation of this function is the loading
+of the value of
+.I i .
+.I I
+is at the level of the
+.B function
+.I f ,
+here symbolically
+.I l,
+and the first variable in the local variable area.
+.PP
+The
+.B function
+completes by assigning the 4 byte integer on the stack to the 8 byte
+return location, hence the
+.SM AS48
+assignment operator, and then uses the
+.SM END
+operator to exit the current block.
+.NH 2
+The main interpreter loop
+.PP
+We can now describe the main interpreter loop.
+It is actually quite short:
+.DS
+loop:
+       \fBmovb\fR      (lc)+,r0
+       \fBadd\fR       r0,r0
+       \fBmovb\fR      (lc)+,r3
+       \fBjmp\fR       *optab(r0)
+.DE
+.ZP
+First the main operation code is extracted from the first byte of
+the instruction.
+The code will be a small integer in the range -128 to 127.
+It is then doubled to make a word index into the operation table.
+Note that the sub-operation code is placed in register 3, and is thus available
+for use by the individual operation sequences.
+The hardware also leaves the condition codes set based on the value of this 
+subop.
+The code will be discussed in section 2.1.
+.PP
+The label
+.I optab
+is in the middle of a branch table which has one operation address
+per word.
+The table is generated automatically from an abstract machine
+instruction list.
+The address of the instruction at
+.I loop
+is always contained in the register variable
+.I lp
+so that a return to the main interpreter loop both is quick and occupies
+little space.
+The return is thus a ``jmp\ (lp)'' instruction,
+defined for mnemonic value as the operator ``return'' in the intepreter, i.e.
+.DS
+return = 115
+.DE
+so that one can write the mnemonic ``return'' at the end of an interpreter
+code sequence.
+.NH 2
+Errors
+.PP
+Errors during interpretation cause a subroutine call to an error routine
+in a conventional fashion.  An earlier version of the interpreter
+more compactly represented the raising of these conditions by using emulator
+traps (\s-2EMT\s0s), a form of system call otherwise unused by \s-2UNIX\s0.
+Errors were assigned small integer numbers and then referred to
+symbolically in the interpreter.
+The \s-2UNIX\s0 assember,
+.I as ,
+provides a mechanism for defining the opcode ``error'' to be an ``emt,'' i.e.:
+.DS
+error = 104000 ^ sys
+.DE
+Thus there were many lines like
+.DS
+.TS
+lw(8) lp-2.
+\fBerror\fR    ESTKOVFLO
+.TE
+.DE
+in the interpreter.
+These cause a process fault,
+which is trapped by the system and passed to the label
+.I onemt
+in the interpreter which fetches the error code byte from the
+.SM EMT
+instruction and calls the procedure
+.I error
+with this argument.
+.I Error
+processes the error condition,
+printing an appropriate error message and, usually, a backtrace.
+.PP
+In order that the interpreter run on a standard \s-2UNIX\s0 without
+using non-standard system calls to fetch the \s-2EMT\s0 code
+when running in separated instruction and data spaces,
+the current version of the interpreter places the error code in a global
+variable, before doing an
+.SM EMT .
+Thus the
+.SM EMT
+is used to compactly transfer control, but not for argument transmission.
diff --git a/doc/px/pxin2.n b/doc/px/pxin2.n
new file mode 100644 (file)
index 0000000..eb90912
--- /dev/null
@@ -0,0 +1,905 @@
+.de mD
+.ta 8n 16n 24n
+..
+.if !\n(xx .so tmac.p
+.nr H1 1
+.if n .ND
+.NH
+Operations
+.NH 2
+Naming conventions and operation summary
+.PP
+As discussed in section 1.10,
+the main interpreter loop decodes the first word of the interpreter
+instruction,
+using the first byte as an operation code,
+and places the second byte,
+the ``subop'',
+in register 3.
+The subop may be used to index the display,
+as a small constant,
+or to indicate one of several relational operators.
+In the cases where a constant is needed, but it
+is not small enough to fit in the byte sub-operator,
+a zero is placed there and the constant follows in the next word.
+Zero is easily tested for,
+as the instruction which places the
+subop in r3 sets the condition code flags,
+and this condition code is still available after the transfer
+to an operation code sequence.
+A construction like
+.DS
+.mD
+_OPER:
+       \fBbne\fR       1f
+       \fBmov\fR       (lc)+,r3
+1:
+       ...
+.DE
+.IP
+is all that is needed to effect this packing of data.
+This technique saves a great deal of space in the Pascal
+.I obj
+object code.
+.PP
+Table 2.1 gives the codes used in the instruction descriptions
+to indicate the kind of inline data expected by each instruction.
+.KF
+.TS
+box center;
+c s
+l | l
+ci | aw(3.25i).
+Table 2.1 \- Inline data type codes
+_
+Code   Description
+=
+a      T{
+.fi
+An address offset is given in the word
+following the instruction.
+T}
+_
+l      T{
+An index into the display, ready as an offset or a guaranteeably small integer,
+is given in the sub-operation code.
+T}
+_
+r      T{
+A relational operator encoded as described
+in section 2.3 is given in the subop.
+T}
+_
+s      T{
+A small integer is
+placed in the subop, or in the next word
+if it is zero or too large.
+T}
+_
+v      T{
+Variable length inline data.
+T}
+_
+w      T{
+A word value in the following word.
+T}
+_
+"      T{
+An inline constant string.
+T}
+.TE
+.KE
+.PP
+Before giving a list of the machine opcodes,
+it is useful to note the naming conventions in the interpreter for typed
+operations.
+Machine instructions which have numeric operands use a simple and uniform
+naming convention in which a suffix on the root operation name indicates
+the type of operands expected.
+These are given in Table 2.2.
+Here the expression ``a above b'' means that `a' is on top of the
+stack with `b' below it.
+Short integers are 2 byte integers,
+and long integers are 4 byte integers.
+.TS
+box center;
+c s s
+c s s
+l l l
+c ap-2 a.
+Table 2.2 \- Operator Suffices
+.sp
+Unary operator suffices
+.sp .1i
+Suffix Example Argument type
+2      NEG2    Short integer
+4      SQR4    Long integer
+8      ABS8    Real
+.sp
+.T&
+c s s
+l l l
+c ap-2 a.
+Binary operator suffices
+.sp .1i
+Suffix Example Argument type
+2      ADD2    Two short integers
+24     MUL24   Short above long integer
+42     REL42   Long above short integer
+4      DIV4    Two long integers
+28     DVD28   Short integer above real
+48     REL48   Long integer above real
+82     SUB82   Real above short integer
+84     MUL84   Real above long integer
+.sp
+.T&
+c s s
+l l l
+c ap-2 a.
+Other Suffices
+.sp .1i
+Suffix Example Argument types
+T      ADDT    Sets
+G      RELG    Strings
+.TE
+.PP
+We now give the list of machine operations with a reference
+to the appropriate sections and a short description of each.
+The character `*' at the end of a name indicates that all
+operations with the root prefix before the `*' are summarized by
+the one entry.
+.br
+.ne 15
+.TS H
+box center;
+c s s
+lw(14) | lw(12) | lw(40)
+lp-2 | a | l.
+Table 2.3 \- Machine operations
+_
+Mnemonic       Reference       Description
+=
+.TH
+.so fig2.1.n
+.TE
+.bp
+.NH 2
+Basic control operations
+.LP
+.SH
+ABORT
+.IP
+This operator is used to halt execution immediately with an IOT process
+fault.
+It is used only for debugging
+.I px
+and is never generated by the translator
+.I pi.
+.SH
+HALT
+.IP
+Corresponds to the Pascal procedure
+.I halt ;
+causes execution to terminate with a post-mortem backtrace as if a run-time
+error had occurred.
+.SH
+BEG w1,w2,"
+.IP
+Causes the second part of the block mark to be created, and
+.I w1
+bytes of local variable space to be allocated and cleared to zero.
+Stack overflow is detected here.
+.I W2
+is the first line of the body of this section for error traceback,
+and he inline string (length 8) the character representation of its name.
+.SH
+NODUMP w
+.IP
+Equivalent to
+.SM BEG ,
+and used to begin the main program when the ``p''
+option is disabled so that the post-mortem backtrace will be inhibited.
+.SH
+END
+.IP
+Complementary to the operators
+.SM CALL
+and
+.SM BEG ,
+exits the current block, calling the procedure
+.I blkexit
+to flush buffers for and release any local files.
+Restores the environment of the caller from the block mark.
+If this is the end for the main program, all files are
+.I flushed,
+the profile data file is written if necessary, and
+the routine
+.I psexit
+which prints the statistics if desired (and does not return) is called.
+.SH
+CALL l,a
+.IP
+Saves the current line number, return address, and active display entry pointer
+.I dp
+in the first part of the block mark, then transfers to the entry point
+given by the relative address
+.I a ,
+which is the beginning of a
+.B procedure
+or
+.B function
+at level
+.I l.
+.SH
+PUSH s
+.IP
+Clears
+.I s
+bytes on the stack for, e.g., the return value of a
+.B function
+just before calling the function.
+.SH
+POP s
+.IP
+Pop
+.I s
+bytes off the stack.
+Used, e.g., after a
+.B function
+or
+.B procedure
+returns to remove the arguments from the stack.
+.SH
+TRA a
+.IP
+Transfer control to relative address
+.I a
+as a local
+.B goto
+or part of a structured statement.
+.SH
+LINO s
+.IP
+Set current line number to
+.I s.
+For consistency, check that the expression stack is empty
+as it should be (as this is the start of a statement.)
+This consistency check will fail only if there is a bug in the
+interpreter or the interpreter code has somehow been damaged.
+Increment the statement count and if it exceeds the statement limit,
+generate a fault.
+.SH
+GOTO l,a
+.IP
+Transfer conrol to address
+.I a
+which is in the block at level
+.I l
+of the display.
+This is a non-local
+.B goto.
+Causes each block to be exited as if with
+.SM END ,
+flushing and freeing files with
+.I blkexit,
+until the current display entry is at level
+.I l.
+.SH
+SDUP
+.IP
+Duplicate the one word integer on the top of
+the stack.
+This is used mostly for constructing sets.
+See section 2.11.
+.NH 2
+If and relational operators
+.SH
+IF a
+.IP
+The interpreter conditional transfers all take place using this operator
+which examines the Boolean value on the top of the stack.
+If the value is
+.I true ,
+the subsequent code is executed,
+otherwise control transfers to the specified address.
+.SH
+REL* r
+.IP
+These take two arguments on the stack,
+and the sub-operation code indicates which relational operation is to
+be performed, coded as follows with `a' above `b' on the stack:
+.DS
+.mD
+.TS
+lb lb
+c a.
+Code   Operation
+_
+0      a = b
+2      a <> b
+4      a < b
+6      a > b
+8      a <= b
+10     a >= b
+.TE
+.DE
+.IP
+Each operation does a number of tests to set the condition code
+appropriately and then does an indexed branch based on the
+sub-operation code to a test of the condition here specified,
+pushing a Boolean value on the stack.
+.IP
+Consider the statement fragment:
+.DS
+.mD
+\*bif\fR a = b \*bthen\fR
+.DE
+.IP
+If
+.I a
+and
+.I b
+are integers this generates the following code:
+.DS
+.TS
+lp-2w(8) l.
+RV4    \fIa\fR
+RV4    \fIb\fR
+REL4   \&=
+IF     \fIElse part offset\fR
+.sp
+.T&
+c s.
+\fI\&... Then part code ...\fR
+.TE
+.DE
+.NH 2
+Boolean operators
+.IP
+The Boolean operators
+.SM AND ,
+.SM OR ,
+and
+.SM NOT
+manipulate values on the top of the stack.
+All Boolean values are kept in single bytes in memory,
+or in single words on the stack.
+Zero represents a Boolean \fIfalse\fP, and one a Boolean \fItrue\fP.
+.NH 2
+Rvalue, constant, and assignment operators
+.SH
+RV* l,a
+.IP
+The rvalue operators load values on the stack.
+They take a block number as a subop and load the appropriate
+number of bytes from that block at the offset specified
+in the following word onto the stack. As an example, consider
+.SM RV4 :
+.DS
+.mD
+_RV4:
+       \fBmov\fR       _display(r3),r0
+       \fBadd\fR       (lc)+,r0
+       \fBsub\fR       $4,sp
+       \fBmov\fR       sp,r2
+       \fBmov\fR       (r0)+,(r2)+
+       \fBmov\fR       (r0)+,(r2)+
+       \fBreturn\fR
+.DE
+.IP
+Here the interpreter first generates the source address in r0 by adding the
+display entry to the offset in the next instruction word.
+It then reserves a long integer space on the stack (4 bytes)
+and moves the data from the source onto the stack.
+The pseudo-operation ``return''
+takes the interpreter back to the main interpreter loop.
+Note that the sub-operation code is already in
+r3 and multiplied by 2 to be immediately usable as a word index
+into the display.
+.SH
+CON* r
+.IP
+The constant operators load a value onto the stack from inline code.
+Small integer values are condensed and loaded by the
+.SM CON1
+operator, which is given by
+.DS
+.mD
+_CON1:
+       \fBmov\fR     r3,-(sp)
+       \fBreturn\fR
+.DE
+.IP
+Here note that little work was required as the required constant
+had already been placed in register 3.
+For longer constants, more work is required;
+the operator
+.SM CON
+takes a length specification in the subop and can be used to load
+strings and other variable length data onto the stack.
+.SH
+AS*
+.IP
+The assignment operators are similar to arithmetic and relational operators
+in that they take two operands, both in the stack,
+but the lengths given for them indicate
+first the length of the value on the stack and then the length
+of the target in memory.
+The target address in memory is under the value to be stored.
+Thus the statement
+.DS
+i := 1
+.DE
+.IP
+where
+.I i
+is a full-length, 4 byte, integer,
+will generate the code sequence
+.DS
+.TS
+lp-2w(8) l.
+LV     \fIi\fP
+CON1   1
+AS24
+.TE
+.DE
+.IP
+Here
+.SM LV
+will load the address of
+.I i,
+which is actually given as a block number in the subop and an
+offest in the following word,
+onto the stack, occupying a single word.
+.SM CON1 ,
+which is a single word instruction,
+then loads the constant 1,
+which is in its subop,
+onto the stack.
+Since there are not one byte constants on the stack,
+this becomes a 2 byte, single word integer.
+The interpreter then assigns a length 2 integer to a length 4 integer using
+.SM AS24 \&.
+The code sequence for
+.SM AS24
+is given by:
+.DS
+.mD
+_AS24:
+       \fBmov\fR       (sp)+,r1
+       \fBsxt\fR       r0
+       \fBmov\fR       (sp)+,r2
+       \fBmov\fR       r0,(r2)+
+       \fBmov\fR       r1,(r2)
+       \fBreturn\fR
+.DE
+.IP
+Thus the interpreter gets the single word off the stack,
+extends it to be a 4 byte integer in two registers,
+gets the target address off the stack,
+and finally stores the parts of the value in the target.
+This is a typical use of the constant and assignment operators.
+.NH 2
+Addressing operations
+.SH
+LV l,w
+.IP
+The most common operation performed by the interpreter
+is the ``lvalue'' or ``address of'' operation.
+It is given by:
+.DS
+.mD
+_LV:
+       \fBmov\fR       _display(r3),r0
+       \fBadd\fR       (lc)+,r0
+       \fBmov\fR       r0,-(sp)
+       \fBreturn
+.DE
+.IP
+It calculates an address in the block specified in the subop
+by adding the associated display entry to the
+offset which appears in the following word.
+.SH
+OFF s
+.IP
+The offset operator is used in field names.
+Thus to get the address of
+.LS
+p^.f1
+.LE
+.IP
+.I pi
+would generate the sequence
+.DS
+.mD
+.TS
+lp-2w(8) l.
+RV     \fIp\fP
+OFF    \fIf1\fP
+.TE
+.DE
+.IP
+where the
+.SM RV
+loads the value of
+.I p,
+given its block in the subop and offset in the following word,
+and the interpreter then adds the offset of the field
+.I f1
+in its record to get the correct address.
+.SM OFF
+takes its argument in the subop if it is small enough.
+.SH
+NIL
+.IP
+The example above is incomplete, lacking a check for a
+.B nil
+pointer.
+The code generated would, in fact, be
+.DS
+.TS
+lp-2w(8) l.
+RV     \fIp\fP
+NIL
+OFF    \fIf1\fP
+.TE
+.DE
+.IP
+where the
+.SM NIL
+operation checks for a
+.I nil
+pointer and generates the appropriate runtime error if it is.
+.SH
+INX* s,w,w
+.IP
+The operators
+.SM INX2
+and
+.SM INX4
+perform subscripting.
+For example, the statement
+.DS
+a[i] := 2.0
+.DE
+.IP
+with
+.I i
+a short integer, such as a subrange ``1..1000'',
+and
+.I a
+an
+``array [1..1000] of real''
+would generate
+.DS
+.TS
+lp-2w(8) l.
+LV     \fIa\fP
+RV2    \fIi\fP
+INX2   8,1,999
+CON8   2.0
+AS8
+.TE
+.DE
+.IP
+Here the
+.SM LV
+operation takes the address of
+.I a
+and places it on the stack.
+The value of
+.I i
+is then placed on top of this on the stack.
+We then perform an indexing of the array address by the
+length 2 index (a length 4 index would use
+.SM INX4 )
+where the individual elements have a size of 8 bytes.
+The code for 
+.SM INX2
+is:
+.DS
+.mD
+_INX2:
+       \fBtst\fR       r3
+       \fBbne\fR       1f
+       \fBmov\fR       (lc)+,r3
+1:
+       \fBmov\fR       (sp)+,r1
+       \fBsub\fR       (lc)+,r1
+       \fBbmi\fR       1f
+       \fBcmp\fR       r1,(lc)+
+       \fBbgt\fR       1f
+       \fBmul\fR       r3,r1
+       \fBadd\fR       r1,(sp)
+       \fBreturn
+1:
+       \fBerror\fR     ESUBSCR
+.DE
+.IP
+Here the index operation subtracts the constant value 1 from the
+supplied subscript,
+this being the low bound of the range of permissible subscripts.
+If the result is negative,
+or if the normalized subscript then exceeds 999, which
+is the maximum permissible subscript if the first is numbered 0,
+the interpreter generates a subscript error.
+Otherwise, the interpreter multiplies the offset by 8 and adds it to the address
+which is already on the stack for
+.I a ,
+to address ``a[i]''.
+Multi-dimension subscripts are translated as a sequence of single subscriptings.
+.SH
+IND*
+.IP
+For indirect references through
+.B var
+parameters and pointers,
+the interpreter has a set of indirection operators which convert a pointer
+on the stack into a value on the stack from that address.
+different
+.SM IND
+operators are necessary because of the possibility of different
+length operands.
+.NH 2
+Arithmetic operators
+.IP
+The interpreter has a large number of arithmetic operators.
+All operators produce results long enough to prevent overflow
+unless the bounds of the base type are exceeded.
+No overflow checking is done on arithmetic, but divide by zero
+and mod by zero are detected.
+.NH 2
+Range checking
+.IP
+The interpreter has a number of range checking operators.
+The important distinction among these operators is between values whose
+legal range begins at 0 and those which do not begin at 0, i.e. with
+a subrange variable whose values range from 45 to 70.
+For those which begin at 0, a simpler ``logical'' comparison against
+the upper bound suffices.
+For others, both the low and upper bounds must be checked independently,
+requiring two comparisons.
+.NH 2
+Case operators
+.IP
+The interpreter includes three operators for
+.B case
+statements which are used depending on the width of the 
+.B case
+label type.
+For each width, the structure of the case data is the same, and
+is represented in the following figure.
+.sp 1
+.KF
+.so fig2.2.n
+.KE
+.sp 1
+.IP
+The
+.SM CASEOP
+case statement operators do a sequential search through the
+case label values.
+If they find the label value, they take the corresponding entry
+from the transfer table and cause the interpreter to branch to the
+indicated statement.
+If the specified label is not found, an error results.
+.IP
+The
+.SM CASE
+operators take the number of cases as a subop
+if possible.
+Three different operators are needed to handle single byte,
+word, and double word case transfer table values.
+For example, the
+.SM CASEOP1
+operator has the following code sequence:
+.DS
+.mD
+_CASEOP1:
+       \fBbne\fR       1f
+       \fBmov\fR       (lc)+,r3
+1:
+       \fBmov\fR       lc,r0
+       \fBadd\fR       r3,r0
+       \fBadd\fR       r3,r0
+       \fBmov\fR       r3,r2
+       \fBtst\fR       (sp)+
+1:
+       \fBcmpb\fR      (r0)+,-2(sp)
+       \fBbeq\fR       5f
+       \fBsob\fR       r3,1b
+       \fBerror\fR     ECASE
+5:
+       \fBsub\fR       r3,r2
+       \fBadd\fR       r2,r2
+       \fBadd\fR       lc,r2
+       \fBadd\fR       (r2),lc
+       \fBreturn
+.DE
+.IP
+Here the interpreter first computes the address of the beginning
+of the case label value area by adding twice the number of case label
+values to the address of the transfer table, since the transfer
+table entries are full word, 2 byte, address offsets.
+It then searches through the label values, and generates an ECASE
+error if the label is not found.
+If the label is found, we calculate the index of the entry in
+the transfer table which is desired and then add that offset
+to the interpreter location counter.
+.NH 2
+Operations supporting pxp
+.IP
+For the purpose of execution profiling the following operations
+are defined.
+.SH
+PXPBUF w
+.IP
+Causes the interpreter to allocate a count buffer
+with
+.I w
+counters, each of which is a 4 byte integer,
+and to clear the counters to 0.
+The count buffer is placed within an image of the
+.I pmon.out
+file as described in the
+.I "PXP Implementation Notes."
+The contents of this buffer will be written to the file
+.I pmon.out
+when the program terminates.
+.SH
+COUNT s
+.IP
+Increments the counter specified by
+.I s.
+.SH
+TRACNT w,a
+.IP
+Used at the entry point to procedures and functions,
+combining a transfer to the entry point of the block with
+an incrementing of its entry count.
+.NH 2
+Set operations
+.IP
+The set operations 
+set union
+.SM ADDT,
+intersection
+.SM MULT,
+and the set relationals
+.SM RELT
+are straightforward.
+The following operations are more interesting.
+.SH
+CARD s
+.IP
+Takes the cardinality of a set of size
+.I s
+bytes on top of the stack, leaving a 2 byte integer count.
+.SM CARD
+uses a table of 4-bit population counts to count set bits
+in each 4-bit nibble of each byte in the set.
+.SH
+CTTOT s,w,w
+.IP
+Constructs a set.
+This operation requires a non-trivial amount of work,
+checking bounds and setting individual bits or ranges of bits.
+This operation sequence is very slow,
+and motivates the presence of the operator
+.SM INCT
+below.
+The arguments to
+.SM CTTOT
+include the number of elements
+.I s
+in the constructed set,
+the lower and upper bounds of the set,
+the two
+.I w
+values,
+and a pair of values on the stack for each range in the set, single
+elements in constructed sets being duplicated with
+.SM SDUP
+to form degenerate ranges.
+.SH
+IN s,w,w
+.IP
+The operator
+.B in
+for sets.
+The value
+.I s
+specifies the size of the set,
+the two
+.I w
+values the lower and upper bounds of the set.
+The value on the stack is checked to be in the set on the stack,
+and a Boolean value of
+.I true
+or
+.I false
+replaces the operands.
+.SH
+INCT
+.IP
+The operator
+.B in
+on a constructed set without constructing it.
+The left operand of
+.B in
+is on top of the stack followed by the number of pairs in the
+constructed set,
+and then the pairs themselves, all as single word integers.
+Pairs designate runs of values and single values are represented by
+a degenerate pair with both value equal.
+A typical situation for this operator to be generated is
+.LS
+\fBif\fR ch \fBin\fR ['+', '-', '*', '/']
+.LE
+.IP
+or
+.LS
+\fBif\fR ch \fBin\fR ['a'..'z', '$', '_']
+.LE
+.IP
+These situations are very common in Pascal, and
+.SM INCT
+makes them run much faster in the interpreter,
+as if they were written as an efficient series of
+.B if
+statements.
+.NH 2
+Miscellaneous
+.IP
+Other miscellaneous operators which are present in the interpreter
+are
+.SM ASRT
+which causes termination if the Boolean value on the stack is not
+.I true,
+and
+.SM STOI ,
+.SM STOD ,
+.SM ITOD ,
+and
+.SM ITOS
+which convert between different length arithmetic operands for
+use in aligning the arguments in
+.B procedure
+and
+.B function
+calls, and with some untyped built-ins, such as
+.SM SIN
+and
+.SM COS \&.
+.IP
+Finally, if the program is run with the run-time testing disabled, there
+are special operators for
+.B for
+statements
+and special indexing operators for arrays
+which have individual element size which is a power of 2.
+The code can run significantly faster using these operators.
+.NH 2
+Functions and procedures
+.IP
+.I Px
+has a large number of built-in procedures and functions.
+The mathematical functions are taken from the standard
+system library.
+The linear congruential random number generator is described in
+the
+.I "Berkeley Pascal User Manual"
+.IP
+The procedures
+.I linelimit
+and
+.I dispose
+are included here but currently ignored.
+One surprise is that the built-ins
+.I pack
+and
+.I unpack
+are here and quite complex, functioning as a memory to memory
+move with a number of semantic checks.
+They do no ``unpacking'' or ``packing'' in the true sense, however,
+as the interpreter supports no packed data types.
diff --git a/doc/px/pxin3.n b/doc/px/pxin3.n
new file mode 100644 (file)
index 0000000..87ada68
--- /dev/null
@@ -0,0 +1,303 @@
+.if !\n(xx .so tmac.p
+.nr H1 2
+.if n .ND
+.NH
+Input/output
+.NH 2
+The files structure
+.PP
+Each file in the Pascal environment is represented by a pointer
+to a
+.I files
+structure in the heap.
+At the location addressed by the pointer is the element
+in the file's window variable.
+Behind this window variable is information about the file,
+at the following offsets:
+.TS
+center;
+n l l.
+\-14   FBUF    Pointer to i/o buffer
+\-12   FCHAIN  Chain to next file
+\-10   FLEV    Pointer to associated block mark
+\-8    PFNAME  Name of file for error messages
+\-6    FNAME   Name of associated file
+\-4    FUNIT   Unit number packed with flags
+\-2    FSIZE   Size of elements in the file
+0              File window element
+.TE
+.PP
+Here
+.SM FBUF
+is a pointer to the input or output buffer for the file.
+The standard system routines
+.I getc
+and
+.I putc
+are used and provide block buffered input/output,
+with 512 characters normally transferred at each read or write.
+.PP
+The files in the
+Pascal environment,
+with the exception of
+.I input
+and
+.I output
+are all linked together on a single file chain through the
+.SM FCHAIN
+links.
+For each file the
+.SM FLEV
+pointer gives its associated block mark.
+These are used to free files at block exit as described in section 3.3
+below.
+.PP
+The
+NAME
+and
+PFNAME
+give the associated
+file name for the file and the name to be used when printing
+error diagnostics respectively.
+Although these names are usually the same,
+.I input
+and
+.I output
+usually have no associated
+file name so the distinction is necessary.
+.PP
+The
+FUNIT
+word contains the
+unit number on which the file is open as well as a set of flags.
+These flags and their representations are:
+.TS
+center;
+l l l.
+EOF    00400   At end-of-file
+EOLN   01000   At end-of-line
+SYNC   02000   File window is out of sync
+TEMP   04000   File is temporary
+FREAD  02000   File is open for reading
+FWRITE 04000   File is open for writing
+FTEXT  08000   File is a text file; process EOLN
+.TE
+.PP
+The
+EOF
+and
+EOLN
+bits here reflect the associated built-in function values.
+TEMP
+indicates that the file has a generated temporary name and that
+it should therefore be removed when its block exits.
+FREAD
+and
+FWRITE
+indicate that
+.I reset
+and
+.I rewrite
+respectively have been performed on the file so that
+input or output operations should be attempted.
+FTEXT
+indicates the file is a text file so that
+EOLN
+processing should be done,
+with newline characters turned into blanks, etc.
+.PP
+The
+SYNC
+bit,
+when true,
+indicates that there is no usable image in the file buffer window.
+As discussed in the
+.I "Berkeley Pascal User's Manual,"
+it is necessary,
+because of the interactive environment,
+to have ``input^'' essentially undefined at the beginning
+of execution so that a program may print a prompt
+before the user is required to type input.
+The
+SYNC
+bit implements this.
+When it is set,
+it indicates that before the element in the window
+can be used the Pascal system must actually put something there.
+This is never done until necessary.
+.NH 2
+Initialization of files
+.PP
+All the variables in the Pascal runtime environment are cleared to zero on
+block entry.
+This is necessary for simple processing of files.
+If a file is unused, its pointer will be
+.B nil.
+All references to an inactive file are thus references through a
+.B nil
+pointer.
+If the Pascal system did not clear storage to zero before execution
+it would not be possible to detect inactive files in this simple way;
+it would probably be necessary to generate (possibly complicated)
+code to initialize
+each file on block entry.
+.PP
+When a file is first mentioned in a
+.I reset
+or
+.I rewrite
+call,
+a buffer of the form described above is associated with it,
+and the necessary information about the file is placed in this
+buffer.
+The file is also linked into the active file chain.
+This chain is kept sorted by block mark address, the
+FLEV
+entries.
+.NH 2
+Block exit
+.PP
+When block exit occurs the interpreter must free the files which are in
+use in the block
+and their associated buffers.
+This is simple and efficient because the files in the active file chain are 
+sorted by increasing block mark address.
+This means that the files for the current block will be at the front
+of the chain.
+For each file which is no longer accessible
+the interpreter first flushes the files buffer
+if it is an output file.
+The interpreter then returns the file buffer and the files structure and window
+to the free space in the heap and removes the file from the active file chain.
+.NH 2
+Flushing
+.PP
+Flushing all the file buffers at abnormal termination,
+or on a call to the procedure
+.I flush
+or
+.I message
+is quite easy.
+The Pascal system simply flushes the file
+.I output
+and each file on the file chain which has the
+FWRITE
+bit set in its flags word.
+.NH 2
+The active file
+.PP
+For the purposes of input-output,
+.I px
+maintains a notion of an active file.
+Each operation which references a file makes the file
+it will be using the active file and then performs its operation.
+A subtle point here is that one may do a procedure call to
+.I write
+which involves a call to a function which references another file,
+thereby destroying the active file set up before the
+.I write.
+For this reason,
+the active file is saved at block entry
+in the block mark and restored at block exit.\*(Dg
+.FS
+\*(dgIt would probably be better to dispense with the notion of
+active file and use another mechanism which did not involve extra
+overhead on each procedure and function call.
+.FE
+.NH 2
+File operations
+.PP
+Files in Pascal can be used in two distinct ways:
+as the object of
+.I read,
+.I write,
+.I get,
+and
+.I put
+calls, or indirectly as though they were pointers.
+It should be noted that the second use as pointers must be careful
+not to destroy the active file in a reference such as
+.LS
+write(output, input\(ua)
+.LE
+or the system would end up writing on the input device.
+.PP
+The fundamental operator related to the use of a file is
+FNIL.
+This takes the file variable, as a pointer,
+insures that the pointer is not
+.B nil,
+and also that a usable image is in the file window,
+by forcing the
+SYNC
+bit to be cleared.
+.PP
+The rest of the uses of files and the file operations may be summarized
+by a simple example:
+.LS
+write('*')
+.LE
+which generates the code
+.LS
+\s-2UNITOUT\s0
+\s-2CONC\s0    '*'
+\s-2WRITC\s0
+.LE
+Here the operator
+.SM UNITOUT
+is an abbreviated form of the operator
+.SM UNIT
+which sets the active file,
+when the file to be made active is
+.I output.
+Thus to write a character to the file
+.I output
+it is only necessary to make
+.I output
+the active file,
+to place the character to be output
+on the stack,
+and to do a
+.SM WRITC
+write character operation.
+.PP
+Files other than
+.I output
+differ from this example only in that the operator
+.op UNIT
+is used preceded by an evaluation of the file variable expression.
+Thus
+.LS
+writeln(f)
+.LE
+produces
+.LS
+\s-2RV\s0      \fIf\fP
+\s-2UNIT\s0
+\s-2WRITELN\s0
+.LE
+.PP
+Write widths are easily handled here by packing information
+about the presence or absence of width specifications and their
+types into the sub-operation code and pushing the values
+of the write widths onto the top of the stack.
+.PP
+One other operation worth mentioning is
+.SM DEFNAME
+which is used to implement the program statement association of
+file names.
+.SM DEFNAME
+simply allocates the
+.I files
+(section 3.1) area for the given file as though
+it had been the object of a
+.I reset
+or
+.I rewrite
+call, initializing the
+FNAME
+field, but omitting the system interactions associated with
+and actual
+.I reset
+or
+.I rewrite.
diff --git a/doc/px/pxin4.n b/doc/px/pxin4.n
new file mode 100644 (file)
index 0000000..1724d87
--- /dev/null
@@ -0,0 +1,72 @@
+.if !\n(xx .so tmac.p
+.nr H1 3
+.if n .ND
+.NH
+Conclusions
+.PP
+It is appropriate to consider,
+given the amount of time invested in rewriting the interpreter,
+whether the time was well spent, or whether a code-generator
+could have been written with an equivalent amount of effort.
+It is the author's belief that the existing code generator for the
+.SM
+PDP-11
+.NL
+series in the
+.SM
+UNIX
+.NL
+C compiler could have been easily modified to produce good quality
+code for Pascal with not much more work than was involved in
+rewriting
+.I px.
+...FS
+..\*(dg With the release of Version 7
+...UX
+..and the portable C compiler, an effort has begun to have
+...I pi
+..use this code generator.
+..We hope to have such a system working by September, 1979.
+..This would allow Pascal, \s-2FORTRAN\s0\-77 and C programs
+..to run together on all systems which support the portable C compiler.
+...FE
+.PP
+The author feels, however, that such an endeavor
+would not have been a good choice for an instructional environment.
+The speed of binary preparation would have been degraded, and the
+necessary loading and assembly processes would have slowed the overall
+compilation process to a noticeable degree.
+This effect would be further exaggerated by the fact that
+student users spend more time in compilation than in execution.
+Measurements over the course of a quarter at Berkeley with a mixture
+of students from beginning programming to a upper division compiler
+construction show that the amount of time in compilation exceeds the amount
+of time spent in the interpreter, the ratio being approximately 60/40.
+.PP
+A more promising approach might have been a throw-away code generator
+such as was done for the
+.SM
+WATFIV
+.NL
+system.
+Here the generated code runs at full machine speed, and compilation
+speed is still very fast.
+Any code generation scheme would be hindered, however,
+if it tried to implement 32 bit integers as implemented by the
+current
+Berkeley Pascal interpreter.
+Given the small number of registers available and the difficulty
+of some of the long integer operations it is not clear that
+reasonable code generation is possible using long integers.
+A 16 bit code generated Pascal would be much simpler, and several
+other such implementations exist.
+.PP
+All things considered, interpretation seems
+to be a reasonable choice for a student environment.
+While a code generator for
+Berkeley Pascal
+would be a useful addition to the system,
+the author believes that, for instructional use,
+a high-quality post-mortem and interactive debugging facility
+would be a more valuable addition to the system than a code generator.
+The interpreter would be easy to modify to accomodate such facilities.
diff --git a/doc/px/tmac.p b/doc/px/tmac.p
new file mode 100644 (file)
index 0000000..65c44e9
--- /dev/null
@@ -0,0 +1,77 @@
+'if \n(FM=0 'so /usr/lib/tmac/tmac.s
+.if n .nr FM 1.2i
+.if t .tr *\(**=\(eq/\(sl+\(pl
+.bd S B 3
+.de SM
+.if "\\$1"" .ps -2
+.if !"\\$1"" \s-2\\$1\s0\\$2
+..
+.de LG
+.if "\\$1"" .ps +2
+.if !"\\$1"" \s+2\\$a\s0\\$2
+..
+.de HP
+.nr pd \\n(PD
+.nr PD 0
+.if \\n(.$=0 .IP
+.if \\n(.$=1 .IP "\\$1"
+.if \\n(.$>=2 .IP "\\$1" "\\$2"
+.nr PD \\n(pd
+..
+.de ZP
+.nr pd \\n(PD
+.nr PD 0
+.PP
+.nr PD \\n(pd
+..
+.de LS         \"LS - Literal display; ASCII DS
+.if \\n(.$=0 .DS
+.if \\n(.$=1 \\$1
+.if \\n(.$>1 \\$1 "\\$2"
+.if t .tr '\'`\`^\(ua-\(mi
+.if t .tr _\(ul
+..
+.de LE         \"LE - End literal display
+.DE
+.tr ''``__--^^
+..
+.de UP
+Berkeley Pascal\\$1
+..
+.de PD
+\s-2PDP\s0
+.if \\n(.$=0 11/70
+.if \\n(.$>0 11/\\$1
+..
+.de DK
+Digital Equipment Corporation\\$1
+..
+.de PI
+.I pi \\$1
+..
+.de Xp
+.I Pxp \\$1
+..
+.de XP
+.I pxp \\$1
+..
+.de IX
+.I pix \\$1
+..
+.de X
+.I px \\$1
+..
+.de PX
+.I px \\$1
+..
+.if n .ds dg +
+.if t .ds dg \(dg
+.if n .ds Dg \*(dg
+.if t .ds Dg \u\s-2\*(dg\s0\d
+.if n .ds dd *
+.if n .ds Dd \*(dd
+.if t .ds Dd \u\s-2\*(dd\s0\d
+.if t .ds dd \(dd
+.if t .ds b \\fB
+.if n .ds b \\fI
+.nr xx 1
diff --git a/doc/pxp/makefile b/doc/pxp/makefile
new file mode 100644 (file)
index 0000000..bdebbc2
--- /dev/null
@@ -0,0 +1,2 @@
+pxpin:
+       /usr/new/vtroff -o-2 pxpin?.n
diff --git a/doc/pxp/pcrt0.s b/doc/pxp/pcrt0.s
new file mode 100644 (file)
index 0000000..903d31a
--- /dev/null
@@ -0,0 +1,55 @@
+.LS .ID
+.ta 8n 16n 24n
+.nf
+/
+/ Modified C runtime startoff for pcx
+/ with floating point interpreter
+/
+\&.globl       savr5
+\&.globl       fptrap
+\&.globl       _exit, _pxpbuf, _main
+
+start:
+/
+/ If non shared text the following
+/ three words will be the beginning of the core image
+/
+       br      1f
+       0                       / 0 = Non-shared text
+       _pxpbuf
+1:
+       sys     signal; 4; fptrap
+       setd
+       mov     sp,r0
+       mov     (r0),-(sp)
+       tst     (r0)+
+       mov     r0,2(sp)
+       jsr     pc,_main
+       cmp     (sp)+,(sp)+
+       mov     r0,(sp)
+       jsr     pc,*$_exit
+       sys     exit
+
+\&.bss
+savr5: .=.+2
+\&.data
+/
+/ If pcx is loaded with shared text -n
+/ or separate i and d -i, then the
+/ following three words will be the first
+/ in the core image.  Note that in this
+/ case the pointer to the buffer will
+/ be deceivingly large.  The first word
+/ of offset can be subtracted to correct
+/ it without having to do the involved
+/ calculations to really calculate the
+/ address of the buffer correctly.  We
+/ can get away with this because we know the
+/ buffer is not in stack space.
+/
+_info:
+       _info
+       1               / 1 = pure text
+       _pxpbuf
+.fi
+.LE
diff --git a/doc/pxp/pxpin0.n b/doc/pxp/pxpin0.n
new file mode 100644 (file)
index 0000000..e2ae721
--- /dev/null
@@ -0,0 +1,114 @@
+\a
+.so tmac.p
+'nr H1 -1
+.RP
+.TL
+Berkeley
+Pascal
+PXP Implementation Notes
+.br
+Version 1.1 \- April, 1979
+.AU
+William N. Joy*
+.AI
+Computer Science Division
+.br
+Department of Electrical Engineering and Computer Science
+.br
+University of California, Berkeley
+.br
+Berkeley, California 94720
+.AB
+.PP
+Berkeley
+Pascal is designed for interactive instructional use and runs
+on the
+\s-2PDP\s0 11 family of computers.
+..A version of
+...I pxp
+..for the \s-2VAX\s0 11/780 is nearly complete.
+The Pascal execution profiler
+.XP
+can be used to generate restructured source program listings
+which are annotated with counts of the number of times each statement
+in the profiled parts of the program was executed for a
+particular run of the program.
+A number of options of
+.XP
+provide easy control over the parts of the program to be profiled.
+.Xp
+can also be used to produce restructured program listings,
+i.e. as a pretty-printer.
+.PP
+The
+.I "PXP Implementation Notes"
+describe the design decisions which lead to the present form of
+.XP
+and give details of the internal organization.
+The notes conclude with thoughts on similar facilities for future systems.
+.AE
+.if n 'ND
+.SH
+Introduction
+.PP
+This
+.I "PXP Implementation Notes"
+consists of four major sections.
+In the first section we outline the design considerations which led to the
+present
+.XP .
+Section 2 describes the implementation, with
+the comment reformatting process described separately in section 3.
+Comments on the viability of the current approach and the
+possible shape of future systems are given in section 4.
+.SH 2
+Related
+.SM
+UNIX
+.NL
+Pascal documents
+.PP
+The Pascal translator
+.I pi
+shares with
+.I pxp
+a common parser and error recovery routines, which is described in
+[1].
+.PP
+Pascal programs are currently interpreted by a program
+.X
+as described in the
+.I "PX Implementation Notes"
+[2].
+An understanding of the particular details of the interpreter is not, however,
+necessary to understand the workings of
+.XP .
+.PP
+The
+.I "Berkeley Pascal User's Manual"
+[3]
+gives examples of using
+.XP
+and is the general reference guide for the system.
+.SH
+Acknowledgements
+.PP
+Ken Thompson wrote the first version of
+Berkeley
+Pascal without which none of this would have been.
+Chuck Haley collaborated with the author on the Pascal system
+development and his help in teaching the author the ins and outs
+of
+.UX
+was indispensable.
+The author's faculty advisor,
+Susan L. Graham,
+has been a source of much encouragement, support,
+and many helpful comments and suggestions.
+.FS
+* The financial support of an \s-2IBM\s0 Graduate Fellowship
+and the National Science Foundation under grants
+MCS74-07644-A03 and MCS78-07291
+are gratefully acknowledged.
+.FE
+.bp
diff --git a/doc/pxp/pxpin1.n b/doc/pxp/pxpin1.n
new file mode 100644 (file)
index 0000000..a0248dd
--- /dev/null
@@ -0,0 +1,677 @@
+.if !\n(xx .so tmac.p
+.ND
+.nr H1 0
+.NH
+Design Considerations
+.NH 2
+Goals
+.PP
+As more fully described in [1], the goals of this
+Berkeley
+Pascal system are:
+.IP
+.RS
+.HP 1) 
+To provide an easily usable teaching tool.
+.IP 2)
+To provide high-quality diagnostics to the user.
+.IP 3)
+To provide fast compilation at the expense, if necessary,
+of execution speed.
+.IP 4)
+To faithfully implement Pascal 6000\-3.4 as described in [5], and
+to be as compatible as possible with the
+.SM CDC
+implementation of the language.
+.RE
+.PP
+The Pascal execution profiler, hereafter referred to simply as
+.XP ,
+results from the second design goal.
+The system, however, would benefit
+greatly from a more complete debugging facility.
+A design for an
+interactive and post-mortem debugger
+.I pdb
+for the system exists [6], but
+has not been implemented as of this writing.
+.NH 2
+Placement of statement counters
+.NH 3
+Basic considerations
+.PP
+Execution profiling is quite simple in concept.
+One merely places
+counters at a sufficient number of points in the program to allow
+the determination of the number of times each statement has been executed.
+Knuth, in [7], gives an algorithm for determining the minimum number
+of counters necessary to gather complete information.
+.PP
+Berkeley
+Pascal code is interpreted.
+Thus the addition of statement counters
+does not tend to have a significant degrading effect on the speed of execution.
+Even in heavily travelled loops, a statement counter is of low enough
+execution cost that techniques for, e.g., moving counters out of
+.B for
+loops were determined to be unnecessary.
+More complicated techniques
+such as determining the number of calls on a 
+.B procedure
+or
+.B function
+by adding together the call counts for all calling sites would
+not materially decrease the time in execution and would add significantly
+to the complexity of the post-processing.
+It was thus decided not to do
+any counting optimization of this type.
+.NH 3
+Goto statements
+.PP
+A more subtle consideration involved non-local 
+.B goto
+statements.
+Without global
+analysis, which was not available in the one-pass compiler scheme being
+used, there is always the possibility that an arbitrary 
+.B procedure
+or
+.B function
+call will not return to the calling site.
+To maintain
+accurate counts and a simple scheme when non-local
+.B goto
+statements are allowed
+would likely involve the placement of a counter after each such
+.B procedure
+or
+.B function
+call.
+The presence of these extra counters could easily multiply the number
+of counters
+required for typical programs by a factor of 5 or more.
+.PP
+As 
+.B goto
+statements which cut across levels of control tend to be used
+only in infrequently occurring error situations, it was decided not to place
+counters to allow for non-local 
+.B goto
+statements.
+Counters are not placed after each
+.B procedure
+and
+.B function
+call so,
+if a call fails to return, the counts will be inaccurate to
+the next sampling point.
+.PP
+An option to allow for correct counts in the presence of non-local 
+.B goto
+statements
+was considered, but rejected.
+It was felt that 
+such an option would rarely, or never, be used.
+It is the author's belief that
+summary data flow information indicating possible non-local
+control transfers would be necessary if the placement of counters were
+to be done appropriately.
+.NH 3
+Counter placement rules
+.PP
+Thus, it was decided to place counters at the following program points:
+.IP
+.RS
+.HP 1)
+At the entry point to each
+.B function
+and
+.B procedure .
+.IP 2)
+In the
+.B then
+part of each
+.B if
+statement.
+The
+.B else
+part
+of each
+.B if
+statement is counted by subtracting the count for the
+.B then
+part from the pre-statement count.
+.IP 3)
+In the body of each
+.B repeat ,
+.B while ,
+and
+.B for
+loop.
+.IP 4) 
+On each case of a
+.B case
+statement, with one counter
+for each group of case labels.
+.IP 5)
+After each
+.B goto
+statement.
+.IP 6) 
+Before any statement which has a
+.B label
+preceding it.
+.RE
+.PP
+The counts are made completely accurate in the presence of local 
+.B goto
+statements
+by placing an extra counter after each
+.B if ,
+.B repeat ,
+.B while
+and
+.B for
+statement which contains a
+.B goto .
+If there is no
+.B goto
+statement in such a statement,
+the count after the statement is taken to be the count before the statement.
+.PP
+It was later suggested to the author that one could count the frequency
+of each individual label in a
+.B case
+statement, rather than keeping one count for each group.
+This might provide useful information for some programs,
+but has not been implemented
+as an option.
+.NH 3
+Partial program counting
+.PP
+A final consideration related to the placement of counters over parts
+of the program only.
+This would surely be desirable if gathering profile data were expensive.
+In this case a
+user might be able to restrict his cost by specifying which
+parts of his code were to be counted.
+After it was decided
+that the profile listing would be constructed by reparsing
+the source text of the program and combining it with the profile data,
+it seemed clear that the savings from such partial counting would not
+materially affect the overall cost of producing a profile.
+It was therefore decided to allow selectivity of profile output
+in
+.XP
+rather than selectivity of count gathering at compile or
+execute time.
+.NH 2
+Producing the profile
+.PP
+Given the collected data in the form of an array of statement counts,
+one then wishes to produce a listing of all or part of the program
+with the count information appended in an easily understandable form.
+It seems clear that a system which presents the count information
+to the user with associated source text from his program will be
+superior to one which merely produces a table of counts for identified
+points in the program.
+.PP
+Satterthwaite's
+.SM "ALGOL W"
+debugging system [8] produced such a listing by
+.I unparsing
+a saved internal form of the source program.
+In his system
+this internal form was also used to provide symbolic flow-trace
+information at run time.
+As we did not propose to do symbolic statement tracing in our
+debugger design [6], there was no need for an internal form of the
+source program to be available at run time.
+Given the fact that our operating system is primarily disk-space
+limited, it was decided that reparsing the source text of the program
+to produce the execution profile was a reasonable approach.
+This allows the profiler to use the existing source text of the
+program without requiring a potentially large intermediate form.
+This also allowed the profiler to use the existing parser and to
+receive as its input a well defined parse tree as described in [1].
+.PP
+Thus the execution of a program normally produces a file named
+.I pmon.out
+which contains an array of counters.
+The code generated need contain
+only the instructions required to prepare these counts.
+This solution
+is very conservative of disk storage resources.
+.NH 2
+Abnormal termination
+.PP
+In cases where the execution of a Pascal program terminates abnormally,
+or has to be terminated due to apparent infinite looping, it is often
+desirable to obtain a profile to help discern the cause of the error.
+The Pascal runtime system will create the
+.I pmon.out
+file in these cases, and profiling is still possible.\u\s-2\*(dg\s0\d
+.FS
+\*(dg If the Pascal runtime system terminates due to a fault,
+either because of a bug in the runtime system,
+a severe misuse of pointers,
+or an untested out-of-range subscript,
+a core-image file will be produced.
+It is possible,
+using a
+.XP
+option,
+to extract the profile information from this core image,
+allowing profiling in this case also.
+.FE
+It should be noted that, 
+in general,
+the information so gathered is not as usable as that which could be
+garnered easily by using a debugger such as
+.I pdb
+[6],
+since variable values are not available.
+.PP
+A final point to be noted is that the counts are inaccurate
+near the suspended control points whenever the program terminates abnormally.
+This is explained more fully in [3].
+The complete
+debugging system design included the marking in the profile of the
+point of abnormal termination in a fashion similar to that used by
+Satterthwaite [9], but this has not yet been implemented.
+.NH 2
+Formatting of the program
+.PP
+As already noted, easy comprehension by the user of the the profile
+produced by
+.I pxp
+requires that the profile be in a readable form.
+One possibility would be an annotated source listing, using the
+form of the original source text.
+This has the advantage that
+the listing is in a form familiar to the user.
+A major disadvantage
+in this approach is the fact that the format of the source may not
+leave room for easy placement of all of the profile information.
+.NH 3
+Pretty printers
+.PP
+There have been a number of systems designed or constructed which
+provide automatically restructured listings of programs
+[10] [11] [12] [13].
+Such programs have often been called ``pretty printers.''
+It is not hard to see that the production of a readable profile
+from a well-structured listing would not be difficult given
+the framework of a pretty printer.
+It was therefore decided to produce such a restructured listing
+and to annotate it with the profile information.
+An option to use the execution profiler as a pretty printer was
+also provided.
+.NH 3
+Comments and output compression
+.PP
+One problem with the evolving approach was the treatment of comments.
+The interface from the parser to the semantic routines in the compiler,
+which was the available and highly suitable framework, had no
+provision for the placement of comment text anywhere in the parse tree.
+For the purposes of profiling this could be easily tolerated.
+An effort can be made when profiling to suppress output which is not absolutely
+necessary in the profile.
+In particular, comments, declarations, and the bodies of
+unexecuted procedures and functions could be normally suppressed.
+In fact, early versions of
+.XP
+suppressed all of these.
+In the current implementation, however,
+the default is that only the bodies of unexecuted
+functions and procedures are suppressed.
+All such suppression is controllable through options as described in
+[3].
+.PP
+The design of the comment formatting facility for
+.XP
+is presented in section 3.
+The author feels that significantly better approaches to program
+maintenance and formatting are possible
+in future systems.
+Some possibilities are discussed in section 4.
+.NH 3
+Bushy if\-then\-elses
+.PP
+Many different formats for presenting Pascal structure are possible.
+The author's personal programming style largely determined
+the structure of programs produced by
+\fIpxp\fR.
+In particular, the author was bothered by one feature of other ``pretty
+printers.''
+Many other pretty printers
+present a ``bushy''
+.I "if\-then\-else"
+construct in a fashion similar
+to the following:
+.LS
+\*bif\fR condition1
+        \*bthen\fR statement1
+        \*belse\fR \*bif\fR condition2
+                \*bthen\fR statement2
+                \*belse\fR ...
+.LE
+This could be termed ``wandering across the page.''
+.PP
+In structured programs, especially in a language which contains
+no
+.B return
+or other escape statement, it is easy to get ``buried''
+in many levels of conditions.
+While the merits of escape-less programming are debatable, it seems
+important to present the structure of the above construct as
+clearly as possible.
+The author feels that a more appropriate way to present
+this statement is often the following:
+.LS
+\*bif\fR condition1 \*bthen\fR
+        statement1
+\*belse\fR \*bif\fR condition2 \*bthen\fR
+        statement2
+\*belse\fR
+        ...
+.LE
+.NH 3
+Begin\-end pairs and well\-bracketing
+.PP
+Another aspect of modern programming languages which are not
+.I "well-bracketed"
+is the presence of
+.I "begin\-end"
+pairs, which, if mismatched, can cause problems,
+especially
+if they escape detection at compile time.
+With an automatically reformatted listing, the user
+no longer needs to worry that his listing may textually represent
+the structure of the program in a way different from the true structure.
+Given this situation, the author feels that the words
+.B begin
+and
+.B end
+convey no information to the user that is not already reflected in
+a more convenient form by the textual indentation.
+.PP
+Thus in considering
+how to represent the ``bushy''
+.I "if\-then\-else"
+when
+.I statement1
+and
+.I statement2
+are
+.I "begin\-end"
+blocks and choosing between:
+.LS
+\*bif\fR condition1 \*bthen\fR
+\*bbegin\fR
+        statement list 1
+\*bend\fR
+\*belse\fR \*bif\fR condition2 \*bthen\fR
+\*bbegin\fR
+        statement list 2
+\*bend\fR
+.LE
+and
+.LS
+\*bif\fR condition1 \*bthen\fR \*bbegin\fR
+        statement list 1
+\*bend\fR \*belse\fR \*bif\fR condition2 \*bthen\fR \*bbegin\fR
+        statement list 2
+\*bend\fR
+.LE
+the author chose the latter, which he prefers.
+.PP
+It should be noted that this is essentially the syntax of
+the language
+.SM
+ALGOL 68
+.NL
+[14],
+and is similar to Wirth's
+.SM
+MODULA
+.NL
+[15], e.g.:
+.LS
+\*bif\fR condition \*bthen\fR
+        statement list 1
+\*belsif\fR condition2 \*bthen\fR
+        statement list 2
+\*bfi\fR
+.LE
+.NH 3
+Indenting of structured levels
+.PP
+Another issue of style arises in choosing how many spaces to indent
+each structured statement of the source text.
+While 8 spaces per level is very
+convenient since
+one level then corresponds to one
+.SM
+ASCII
+.NL
+tab character,
+4 spaces seemed to work best with the execution profile when using
+an adaptation of the format of Satterthwaite [8].
+Thus, options were provided to allow a level to be defined as
+any small number of column positions, with 4 columns the default.
+.NH 3
+Expressions
+.PP
+The printing of expressions presented yet another problem.
+It was felt that a format which reflected the true structure of an expression
+was best.
+For this reason, a fully parenthesized expression format was first tried.
+This turned out to be a very poor choice as it made complicated
+expressions very hard to read.
+The author then implemented a minimal-parenthesis format as the default
+with full parenthesization as an option.
+.PP
+It is probably true that many users would prefer to have their
+parenthesization preserved even when the parentheses deleted are, in fact,
+unnecessary.
+This would be even more true in a language which had a large number
+of precedence levels with a large number of operators.
+It is not as necessary in Pascal since there are only a small number
+of levels here, but such an option would have been useful in any case.
+This option is not, however, included in the current
+\fIpxp\fR.
+.NH 3
+Procedures and functions
+.PP
+It was decided that
+.B procedure
+and
+.B function
+definitions which are nested
+within one another would be indented one structured statement
+level by default to improve readability.
+An option was included to omit this indenting if desired.
+.PP
+The
+.B end
+keyword of each
+.B procedure
+and
+.B function
+is labelled with the name of the
+.B procedure
+or
+\*bfunction\fR.
+This is done also for the opening
+.B begin
+if any nested
+.B procedure
+or
+.B function 
+definitions occur within the
+.B procedure
+or
+\*bfunction\fR.
+.NH 3
+Case statements
+.PP
+When first designing the statement formats, the author felt that
+the statements in a
+.B case
+statement should be formatted so that cases with one and cases with
+more than one statement would line up for easy readability.
+At the time, 8 spaces per level was the default format and the choice
+was between:
+.LS
+\*bcase\fR ch \*bof\fR
+    \(aa \(aa:
+        col := col + 1;
+    tab:
+        col := (col + 8) \*bmod\fR 8;
+    \(aa*\(aa:
+        \*bbegin\fR
+                tok := star;
+                tokval := line
+        \*bend\fR
+\*bend\fR
+.LE
+and
+.LS
+\*bcase\fR ch \*bof\fR
+  \(aa \(aa:
+        col := col + 1;
+  tab:
+        col := (col + 8) \*bmod\fR 8;
+  \(aa*\(aa:
+      \*bbegin\fR
+        tok := star;
+        tokval := line
+      \*bend\fR
+\*bend\fR
+.LE
+.PP
+With the eventual choice of 4 spaces per structured level as the
+default indentation, the difference between the corresponding formats
+is slight.
+In retrospect, this was not
+necessarily sufficiently valuable to justify the amount of time spent on the
+.B case
+statement format,
+as different strategies were needed
+for each indenting option, and the format was optimized
+to be ``pretty'' in each case subject to the alignment constraint.
+Thus the current
+.XP
+uses only the simpler first strategy.
+.NH 3
+Labels and miscellania
+.PP
+Labels are place on a separate line, aligned with the header
+line of the
+containing
+.I program,
+.I procedure
+or 
+.I function.
+Placed this way, they are easy to locate.
+.PP
+In general,
+the text editing facilities on the
+.SM
+UNIX
+.NL
+system are geared toward
+line oriented editing.
+Thus it is extremely convenient to have statements on single
+lines.
+For this reason the format of the programs produced by
+the pretty printer gives section keywords like
+.B var
+and
+.B type
+alone on a line.
+In this way deleting the first declaration
+of such a section is made easier \- there is no need to split
+the keyword away from the first declaration.
+.PP
+Other options, such as an option to underline all of the keywords
+in the program, are provided by
+.XP .
+These are detailed more fully in [3].
+.NH 3
+Summary
+.PP
+In summary, the profiler format reflects the taste of
+the author in Pascal formatting at the time this program was
+written.
+It largely succeeds in producing readable Pascal texts.
+.PP
+Treatment of long statements and placement of multiple statements per line
+are desirable additions
+and a design for some of these is described in section 2.
+They were omitted from the original
+design only because the author was not initially sure of a reasonable way
+to proceed in these areas, and felt that these were more important
+in the context of a pretty printer.
+.Xp
+was intended primarily as an execution profiler.
+Even without the features of section 3, earlier versions of
+.XP
+were useful in showing students who had trouble formatting their programs
+one acceptable way of writing Pascal.
+.NH 2
+Profile Data Presentation
+.PP
+The basic format for the profile is essentially that of Satterthwaite [8] [9].
+Examples are given in [3].
+The following pieces of information are included with the profile
+in addition to the basic count information.
+.IP
+.RS
+.HP 1) 
+The version number and date of the instance of
+.XP
+which produced the profile.
+.RE
+.IP
+.RS
+.HP 2) 
+The version of the program being profiled (taken to be the time at which
+the file it is contained in was last modified.)
+.IP 3) 
+The time at which the profile data was gathered.
+.RE
+.LP
+This information serves to identify uniquely the program involved.
+.NH 3
+Count interpretation
+.PP
+The algorithm for count interpretation is given in [3] and is essentially
+the same as that given by Satterthwaite in [9].
+.NH 3
+Data compression
+.PP
+Two options for compressing profile data are available.
+One gives a table of the procedures and functions with their activation
+counts.
+This requires only a very small amount of data even for large programs.
+.PP
+More easily readable than a simple table are profiles of parts of a
+program.
+These can be obtained without modifying the source text.
+One can give a list of
+.B procedure 
+or
+.B function 
+names on the command
+line, and profiles will be enabled for these and their contained
+procedures and functions only.
+.PP
+This ability to extract selective information and to be able to do it
+without modifying the source code is critical.
+Editing the source code (at least twice!) for each profiling pass
+would not only be tedious, but could easily be done incorrectly.
+The command line syntax is simple and relatively foolproof.
+This feature is fully described in [3].
+.bp
diff --git a/doc/pxp/pxpin2.n b/doc/pxp/pxpin2.n
new file mode 100644 (file)
index 0000000..8603bfb
--- /dev/null
@@ -0,0 +1,1415 @@
+.if !\n(xx .so tmac.p
+.ND
+.nr H1 1
+.NH
+Implementation
+.PP
+.Xp
+is written in the
+.UX
+systems programming language C.
+The structure of
+.XP
+is very similar to that of the Pascal translator
+.PI .
+In fact
+.XP
+was, until recently, a conditional compilation of
+.PI .
+.Xp
+uses the same parser and scanner as
+.PI ;
+these are described in [1].
+.PP
+The major changes to the compiler in writing
+.XP
+were the rewriting of the
+semantic routines of the compiler and the addition of three
+``clusters''
+of routines;
+one for profiling,
+one for the production of the restructured program listing,
+and one for the processing of comments.
+These ``clusters''
+are written with local data bases, are largely
+independent of the other parts of the program, and consist
+of a large number of small, related routines.
+By structuring the program in this way, functional
+independence is obtained.
+Clusters are organized separately
+from the rest of the program, and accessed through a high-level and abstract
+interface.
+The concrete implementation of a cluster is not fixed by these
+external specifications, and could be changed without the need to
+rewrite any other
+part of the program provided that the routines then implemented
+a suitable interpretation of the same abstraction.
+This organization provides a powerful and convenient decomposition
+of the profiling process.
+.PP
+The print cluster routines are kept in the file
+.I pp.c.
+Their basic function is to provide
+an interface to a high-level
+printing automaton, with primitives such as 
+``print keyword''
+and
+``print number.''
+Information about the macro- and micro-structure of the output is passed to
+the routines implicitly by calling the appropriate entry points.
+Thus, after a statement is processed, the routines are informed that an
+``item'' is finished so that an intelligent decision can be made about
+where to place the statement.
+Similarly, when processing a list of items such as a constant type
+declaration, the print cluster is given information as to where
+the ``left bracket,'' i.e. `(' occurs, where each ``separator,'' i.e. `,'
+occurs, and, when the final `)' occurs, this is noted as a ``right bracket.''
+With this information, an implementation of the printing cluster can be
+provided which sensibly divides long structured constructs even though it has
+no knowledge of the high-level language structure of its input.
+.PP
+The profile cluster, which is kept in the file
+.I pmon.c,
+has a number of related functions.
+Initially, it deals with the problem of extracting the count information
+from the profile data file.
+If the execution of the interpreter terminated abnormally, then the data must
+be extracted from the
+.I core
+process image file.
+There is an image of the profile data file in the
+.I core
+image.
+To extract the data from
+.I core,
+.I pxp
+need only determine the offset of this image in the file.
+.PP
+After extracting the data from the file, the profile cluster provides
+operations to return successive counters from the count buffer.
+In addition it
+builds the data structure for storing the information used to print
+the optional table summarizing
+.B procedure
+and
+.B function
+invocation counts.
+Other functions provided include
+saving and restoring counts before
+and after structured statements,
+determining when embedded
+.B goto
+statements will have caused extra counts to be generated,
+generating pseudo-counters for the
+.B else
+parts of
+.B if
+statements,
+and controlling when the counts are to be printed in the listing
+by keeping track of whether each count has been printed.
+All manipulation of counts and counters is handled by these routines,
+and focuses on a single counter structure called
+.PX
+which contains the current count.
+.PP
+In section 2.1 the profile data format and
+the process of getting the data from the profile
+data file or the
+.PX
+process
+.I core
+image are discussed.
+Section 2.2 gives the data and control structures of the profiling
+and printing clusters, and section 2.3 describes the tree walk
+at the function level, and at illustrative parts of the statement
+and expression levels.
+The implementation description concludes in section 2.4 with
+a note on the handling of multi-file programs.
+.NH 2
+External data structures
+.PP
+The following sections deal with the recovery of the profile data.
+The simplest case, that of normal termination, is dealt with in section 2.1.1.
+The remaining sections deal with the handling of
+.I core
+process image files.
+These are likely to be of interest to
+system programmers only.
+.NH 3
+Format of the profile data file
+.PP
+The
+.I pmon.out
+data file,
+is normally written by the Pascal system at the end of profiling
+execution.
+The record structure of the header at the beginning of the file is as
+follows:
+.LS
+.ta 8n 16n 40n
+\*bstruct\fP {
+       \*bint\fP       magic;  /* 0426 */
+       \*bint\fP       magic2; /* 0 */
+       \*blong\fP      proftime;       /* Time profiled */
+       \*bint\fP       cnt;    /* # statement cntrs */
+       \*bint\fP       pfcnt;  /* # procedures+functions + 1 */
+} header;
+.LE
+Each counter is a long integer so the rest of the file is essentially
+an array:
+.LS
+\*blong\fP counts[header\*b.\fPcnt];
+.LE
+.PP
+As an error check,
+.XP
+first insures that the first word is 0426
+and the second is a 0.
+If this is true, and the size of the remainder of the file is the size of
+the
+.I counts
+array as implied by the number
+.I cnt
+in the header, then
+profiling can proceed.
+If not, then the specified profile data file has a bad format, and
+.XP
+reports this fact.
+.NH 3
+Core data files
+.PP
+.Xp
+has the capability to
+extract the profile information from the
+.I core
+data file dumped by an
+abnormal
+.PX
+termination.
+This is greatly simplified by the fact that there is, in the core image,
+an exact replica of the
+.I pmon.out
+file which would have been written at normal termination.
+In order to extract the profile data, it is only necessary
+to locate this buffer.
+.PP
+The first 1024 bytes of the core image file is a copy of
+the system's per-user data for the process, including the registers
+as they were at the time of the fault.
+The remainder of the file represents the actual contents of the user's
+core area when the core image was written.
+If the text segment of the process was write-protected and shared,
+it will not be present; otherwise the entire address space will have
+been dumped.
+.NH 3
+Shared text programs
+.PP
+It is possible in
+.UX
+for the text image of a program to be shared by all of the persons
+who invoke it.
+The instructions will be write protected, and each process which
+executes this
+.I pure
+text will have only a data area, sharing one
+common text.
+Thus, when such a process is swapped out, only its data area need
+be swapped.
+The text space can always be abandoned and read in from external
+storage when needed, as it cannot have changed.
+.PP
+When a core image is dumped,
+the text space is not dumped if the process was running as shared text.
+This is the situation with the installed version of
+.PX .
+The disadvantage of shared text is that breakpoint debugging
+is impossible in this case.
+For this reason
+.X
+is most often debugged
+as non-shared text.
+It is desirable, therefore, to have
+.XP
+be able
+to extract data correctly in either case.
+.PP
+The important fact here, which allows a number of simplifications
+to the extraction method, is that
+the non-stack data space of the process
+is dumped immediately after the system area.
+If the text space was not ``shared,'' then the first word dumped will
+have been location 0 in the process address space, otherwise it will
+have been the first data word, as the text of the process appears
+first in the process space.
+.NH 3
+Extraction methods
+.PP
+The structure needed to navigate in the
+.I core
+image is the
+.I pcx
+information structure\u\s-2\*(dg\s0\d, which has the following format:
+.FS
+\*(dg
+.I Px
+was previously
+.I pcx
+hence the name of this structure
+.FE
+.LS
+\*bstruct\fR {
+       \*bchar\fR      *buf;
+       \*bint\fR       cnt;
+} pcx;
+.LE
+The
+.I buf
+pointer here points to the image of
+.I pmon.out
+in core, and is a memory address.
+The
+.I cnt
+gives the size of this image,
+and is not currently used by
+.XP
+as the size is determined from information in the image itself.
+If the
+.I buf
+pointer is 0, i.e. a 
+.I NIL
+pointer, then
+.PX
+was not
+gathering profile data in the execution which abnormally terminated.
+.PP
+To locate this structure, the runtime start up routine for the interpreter
+was modified from the standard C start up to be as given in the following
+figure.
+.so pcrt0.s
+This runtime start up is structured so that it is possible to determine,
+from the first three words after the system area, whether
+the process was executed as shared text, and the offset of the
+.PX
+structure in the file.
+If the second word here is a 0, then this can only be a non-pure
+core image; if it is a 1 then this can only be a pure core image.
+If it is neither then this is not a
+.PX
+core image.
+.PP
+If the core image is pure, the first word dumped of the process
+was not at location 0 in the process data space.
+In this case, however, the runtime start up is set up so the
+first word contains its address in memory.
+Thus it is possible to can convert the third core image word, which is the index
+into memory, into an index into the core image by subtracting
+this offset from it.
+In this way,
+.XP
+can find the
+.I pcx
+structure in the 
+.I core
+image.
+.PP
+As noted above, if the
+.I buf
+pointer is
+NIL,
+then
+.PX
+was not gathering profile data and an appropriate diagnostic will
+be printed.
+Otherwise, the
+.I buf
+pointer is offset by subtracting the first word
+after the system area in the
+.I core
+image if the process was pure,
+.XP
+seeks to the
+implied location and a routine common to the
+.I core
+and
+.I pmon.out
+profile data gathering routines 
+.I pmread
+is called.
+The only notable difference is that after calling
+.I pmread
+when processing a
+.I pmon.out
+file,
+.XP
+checks that all the data on the file is
+exhausted.
+This is not done when reading a
+.I core
+data file.
+.PP
+If any of this seeking or reading terminates abnormally
+a
+.I "bad format"
+diagnostic is given.
+.NH 2
+Internal data structures
+.NH 3
+External data copies
+.PP
+The following data items are kept internally after being read from
+the
+.I pmon.out
+or 
+.I core
+data file.
+They are available only by using the routines in the cluster in the file
+.I pmon.c .
+.PP
+The integer 
+.I zcnt
+gives the total number of counters, the integer 
+.I zpfcnt
+the total number of procedures and functions.
+The pointer
+.I zbuf
+is (effectively) a dynamic array of long integers
+representing the profile counts.
+In addition, the external variable
+.I ptvec
+contains the internal
+representation of the time the profile was made.
+.NH 3
+Profile cluster data structures
+.PP
+There are two major profile cluster structures.
+The first structure is the primitive unit for storing a piece
+of count information and is given by:
+.LS
+\*bstruct\fP pxcnt {
+       \*blong\fP      ntimes;
+       \*bint\fP       counter;
+       \*bint\fP       gos;
+       \*bint\fP       printed;
+};
+.LE
+Here
+.I ntimes
+is the actual count data.
+The variable
+.I counter
+gives a unique identifying tag to this structure,
+.I gos
+is the number of gotos which had been encountered when this counter
+was created, and
+.I printed
+is actually a Boolean value indicating
+whether the counter is considered to have been printed for
+the purposes of the profile.
+.I Counter
+may actually be an index into the array of
+values read in from
+.I pmon.out ,
+or it may be a negative number indicating
+that it is a counter which was generated by calculations, e.g. for
+an
+.B else
+part of an
+.B if
+statement.
+Other uses of this structure will be described below.
+.PP
+The other major structure which records information
+for each
+.B procedure
+or 
+.B function
+for the summary table. Its format is:
+.LS
+\*bstruct\fP pftab {
+       \*blong\fP      pfcnt;
+       \*bint\fP       pfline;
+       \*bchar\fP      *pfname;
+       \*bint\fP       pflev;
+} *zpf;
+.LE
+The field
+.I pfcnt
+gives the invocation count for each routine,
+.I pfline
+is the approximate source program line number for the routine,
+.I pfname
+points to the character string name of the routine, and
+.I pflev
+gives the nesting level of the routine so it is possible to print
+the table with nesting indicating structure.
+The variable
+.I zpf
+is actually a dynamic array holding these counters.
+.NH 3
+The profile cluster primitives
+.PP
+The following are the primitive operations of the profile cluster
+kept in the source file
+\fIpmon.c\fP.
+They deal in particular with one special counter structure
+.I px
+which holds the current count information as processing progresses.
+.IP
+.RS
+.HP "\*blong\fP nowcnt()"
+.br
+Returns a \*blong\fP integer which is the current count.
+.RE
+.IP
+.RS
+.HP nowcntr()
+.br
+Returns an integer uniquely identifying the current counter.
+.IP "\*blong\fP cntof(pxc)"
+.HP "\*bstruct\fP pxcnt *pxc;"
+.br
+Returns the \*blong\fP integer
+.I count
+associated with the structure addressed by
+\fIpxc\fP.
+.IP "setcnt(l)"
+.HP "\*blong\fP l;"
+.br
+Makes the current counter have count
+\fIl\fP.
+A new, unique counter is generated for this purpose.
+This is used, e.g., to assign counts to
+.B else
+parts of
+.B if
+statements.
+.IP "savecnt(pxc)"
+.HP "\*bstruct\fP pxcnt *pxc;"
+.br
+Saves the information associated with the current count
+.I px
+in the given structure.
+.IP "rescnt(pxc)"
+.HP "\*bstruct\fP pxcnt *pxc;"
+.br
+The inverse of
+.I savecnt
+setting the fields of
+.I px
+from the given structure.
+.I Rescnt
+also returns non-zero exactly when there were embedded gotos.
+.IP "getcnt()"
+.br
+Takes the next counter from the
+.I pmon.out
+or
+.I core
+data and places it and associated information into
+\fIpx\fP.
+The fact that there are less counters in the file than
+required by the supplied program is diagnosed as a
+``Counter mismatch'' here.
+.IP "cnttab(s, no)"
+.HP "\*bchar\fP *s;"
+.HP "\*bint\fP no;"
+.br
+Records the current count as being that of a
+.B procedure
+or
+.B function
+with number
+\fIno\fP.
+The number of
+procedures and functions are also counted
+here so they can be checked for consistency at the end of processing.
+.RE
+.NH 3
+Profile-printing cluster interface
+.PP
+The following routines, which are part of the
+.I pmon.c
+cluster, interface to the printing cluster, and are used
+to control the annotation of the program listing with
+profile data.
+.IP
+.RS
+.HP "unprint()"
+.br
+Causes the current counter to become logically ``unprinted''
+so that it will be printed again.
+Used, e.g., after restoring a count saved before a loop
+to force it to be printed again.
+.RE
+.IP
+.RS
+.HP "baroff()"
+.br
+Turns the printing of the bar `|' in the profile off.
+.IP "baron()"
+.br
+The inverse of
+\fIbaroff\fP.
+.IP "shudpcnt()"
+.br
+Returns an integer indicating the type of annotation of the
+current line which is desired.
+A return value of 0 indicates that only the bar `|' is to
+be printed, a value of 1 that the current count and the
+bar `|' are to be printed, and a value of -1 indicates that
+only white space is to be printed.
+A flag set by the routines
+.I baroff
+and 
+.I baron
+is inspected here.
+If the bar `|' to be printed is printed, it is noted that the
+current counter was printed so the count will not be printed again.
+.RE
+.NH 3
+The printing cluster
+.PP
+The file
+.I pp.c
+contains the cluster which performs the nitty-gritty business
+of preparing the output to be printed.
+It was the author's intention, when he wrote the program, to
+pass sufficient information to this cluster to allow it to do
+the job of breaking up long statements and of placing multiple
+statements on each line.
+This has not been implemented yet.
+The description of how the routines of this cluster
+work together to produce the profile is deferred to a later, higher level
+view.
+.PP
+This cluster currently has a very minimal set of data structures.
+These structures would expand greatly if the statement folding and 
+multiple statement placement were implemented.
+As it stands
+the input is interpreted only in a very simpleminded way.
+For this purpose it is only noted whether anything is being printed
+at all, indicated by the flag
+\fInopflg\fP,
+which if non-zero indicates that no printing is to occur, and some information
+about the way in which the listing is to be indented.
+This is contained in an array giving the indenting in spaces for
+each of three levels, i.e.:
+.LS
+\*b#define\fP DECL    0
+\*b#define\fP STAT    1
+\*b#define\fP PRFN    2
+
+\*bint\fP pplev[3];
+.LE
+.PP
+These levels have rough interpretations as follows.
+The white space generated at the very left by the indenting
+of nested
+.B procedure
+and
+.B function
+declarations is assigned to
+\fIpplev[PRFN]\fP,
+the white space generated in declaration parts by structured declarations
+such as records to DECL, and the white space generated by indenting
+of structured statements to STAT.
+.PP
+The white space is dispersed on the line, separating the left margin,
+labels, the profile information, and the program text graphically
+given below.
+.DS C
+line#  PRFN  label:  STAT  999.---|  DECL  text
+.DE
+Thus by indenting in the DECL part deeper text nesting can be shown
+without the bar wandering to the right, and when indenting in the
+STAT part the bar is moved over.
+Similarly, the option to indent nested procedures and functions
+is trivially handled by indenting in PRFN.
+.NH 3
+Printing cluster primitives
+.PP
+There are two kinds of routines in the printing cluster.
+One kind deals with printing the various kinds of tokens in
+Pascal programs, e.g. keywords, strings, etc.
+The other set of routines deals with the specifics of printing
+the profile, i.e. turning printing on and off, indenting, and
+the nasty details like the placement of labels.
+.IP
+.RS
+.HP "ppkw(s)"
+.HP "\*bchar\fP *s;"
+.br
+Prints the character string representing the keyword.
+Underlining and overstriking of keywords is also handled.
+This routine facilitate the suppression of blank lines at the beginning
+of partial profiles,
+setting a flag the first time it prints a keyword.
+Since any solid output always begins with a keyword,
+.I ppnl
+refuses to print a newline until a keyword is printed.
+.IP "ppid(s)"
+.HP "\*bchar\fP *s;"
+.br
+Prints the identifier
+.I s
+or `{identifier}' if
+.I s
+is null because of a syntax error.
+.IP "ppop(s)"
+.HP "\*bchar\fP *s;"
+.br
+Prints operators.
+.IP "ppnumb(s)"
+.HP "\*bchar\fP *s;"
+.br
+Prints numbers.
+.IP "ppstr(s)"
+.HP "\*bchar\fP *s;"
+.br
+Prints strings, dealing with doubling of the string metacharacter.
+.IP "pplab(s)"
+.HP "\*bchar\fP *s;"
+.br
+Prints a label.
+.IP "ppbra(s)"
+.HP "ppket(s)"
+.HP "ppsep(s)"
+.HP "\*bchar\fP *s;"
+.br
+These routines
+are used to indicate the recursive structure of the input
+at the microscopic level.
+Thus, when printing out the argument list to a
+.B procedure
+or
+.B function,
+the opening `(' would be printed with
+\fIppbra\fP,
+each separating `,' with
+\fIppsep\fP,
+and the closing `)' with
+\fIppket\fP.
+This would, conceivably, allow this cluster to break the output sensibly
+to conform with the nature of the output medium without having
+to deal with the passed-through data at a more difficult macroscopic
+level.
+.IP "ppspac()"
+.HP "pptab()"
+.HP "ppitem()"
+.HP "ppnl()"
+.br 
+These routines are all used to put separation into the output stream.
+In the initial design, the difference between the routines
+.I ppitem
+and
+.I ppnl
+was that
+.I ppnl
+would always force a new-line, while
+.I ppitem
+separated major units such as statements, but didn't require the
+following statement to start on a new line, leaving the possibility
+that it be placed on the same line.
+In the current implementation, however, both
+.I ppitem
+and
+.I ppnl
+force the output to be on a new line.
+Note that forcing the output to a new line does not force the
+leading white space to be printed!
+.RE
+.PP
+The utility routines which don't deal directly with
+the printing of the actual program text follow.
+.IP
+.RS
+.HP "setprint()"
+.br
+Is called at the beginning of each
+.B procedure
+or
+.B function
+body and examines the global environment and option flags
+to decide whether that routine should be printed in the profile.
+.RE
+.IP
+.RS
+.HP "printon()"
+.br
+Turns the printing on.
+If profiling is notoccuring, a summary table is desired
+then this actually turns the printing off!
+If neither profiling or a summary table is being producd,
+then this call has no effect.
+.IP "printoff()"
+.br
+Turns the printing of the profile off.
+.IP "indent()"
+.br
+If printing, ask
+.I linopr
+to print the line number.
+If producing a profile (rather than just a pretty-print)
+indent over
+.I
+pplev[PRFN] + pplev[STAT]
+.R
+spaces, and then, depending on the result of a call to
+.I shudpcnt
+print either a count, some dashes and a bar, just a bar,
+or spaces.
+Finally, indent
+.I pplev[DECL]
+more spaces and return.
+.IP "dashes(c)"
+.HP "\*bchar\fP c;"
+.br
+Spaces over an amount determined by the indenting level using
+the character given.
+.IP "indent1(in)"
+.HP "\*bint\fP in;"
+.br
+Actually advance the indent by
+.I in
+spaces.
+If pretty-printing
+it is safe to optimize the output by producing tabs,
+otherwise spaces must be used.
+.IP "linopr()"
+.br
+Prints the line number if required.
+.IP "indentlab()"
+.br
+Indents for a label print,
+.I pplev[PRFN]
+spaces using
+\fIindent1\fP.
+.IP "ppgoin(lv)"
+.HP "ppgoout(lv)"
+.br
+These routines each take one of PRFN, STAT or DECL and increase
+or decrease the indentation at that level respectively.
+.RE
+.NH 2
+Producing the profile
+.PP
+It should be obvious from the discussion above, that little
+difference can be discerned at the top level between producing
+a profile and prettyprinting.
+When prettyprinting, a large
+number of routine calls return without doing any real work.
+.PP
+The production of the profile is discussed at each of four levels.
+The first level is the main routine and option processing.
+This is discussed only to give an outline of the work done here.
+.PP
+The second level is the level of procedures and functions and
+involves such considerations as the 
+.B z
+command line option with list of
+.B procedure
+and
+.B function
+names, forward declarations, and the recording, saving and
+restoring of count information.
+.PP
+The third level is that of individual statements, and the final
+level is that of expressions.  These levels are illustrated
+with actual code to make the discussion more concrete.
+.NH 3
+Main routine and option processing
+.PP
+The main routine sets up the default options such as setting
+the indenting to 4 spaces and turning on nested
+.B procedure
+and
+.B function
+indents.
+It then examines the arguments and,
+importantly, sets the variable
+.I profile
+if profiling and
+.I table
+if producing a table of procedure and function counts.
+.PP
+If a list of
+.B procedure
+and
+.B function
+names is given it is saved as referenced by the variables
+.I pflist
+and
+.I pflstc
+for examination by the routine
+.I inpflist
+which is called by routines at
+.B procedure
+and
+.B function
+entry and exit.
+.PP
+After processing all the options, the main routine makes a call
+to the
+.I pmon.c
+cluster to get the profile data if appropriate.
+It sets up the input and does some special processing for processing
+of
+.I include
+files as described further in section 2.4 below.
+It finally calls the parser which completes the processing of the profile.
+.NH 3
+Procedure and function level processing
+.PP
+The
+.B procedure
+and 
+.B function
+level processing routines are contained in the file
+\fIfdec.c\fP.
+The routines here and their functions are:
+.IP
+.RS
+.HP "funchdr(r)"
+.HP "\*bint\fP *r;"
+.br
+Called with a tree node representing the initial declaration
+of a function or procedure, e.g.:
+.LS
+\*bfunction\fP sine(a: angle): \*breal\fP;
+.LE
+this routine first determines if the routine is in the list
+of procedures and functions given on the command line.
+If it is, then the
+.B z
+option value is saved on a stack,
+and then turned on.
+It then gets the counter associated with the procedure header
+and calls a routine in the print cluster to determine whether this
+routine should be printed or not.
+.IP
+It then saves the count information for this routine at its level
+in a global array of
+.I pxcnt
+structures called
+\fIpfcnts\fP.
+This counter will be restored later when the body of the routine
+is encountered.
+The printing of the header is also processed here, but this is
+similar to other processing to be described later.
+This printed header is indented if nested definitions are being indented,
+to be unindented after completing the printing of the header.
+.RE
+.IP
+.RS
+.HP "funcfwd(fp)"
+.HP "\*bchar\fP *fp;"
+.br
+This routine prints the keyword
+.B forward
+indented an appropriate amount.
+It returns its argument.
+.IP "funcbody(fp)"
+.HP "\*bchar\fP *fp;"
+.br
+This routine, called when the actual, resolving declaration of
+a
+.B procedure
+or
+.B function
+is encountered, indents if the indent nested procedures option
+is set, and increments the structured statement level, returning
+its argument.
+.IP "funcend(fp, blk)"
+.HP "\*bchar\fP *fp;"
+.HP "\*bint\fP *blk;"
+.br
+This routine sets up for all of the actual work in printing the body
+of procedures and functions.
+It restores the count saved by
+.I funchdr
+from the
+.I pfcnts
+array,
+.I unprints
+the count to force it to come out again if there
+were any nested procedures or functions, (if the last block number in the
+variable
+.I lastbn
+is not the current block number)
+and then prints the body of the procedure or function.
+.IP
+To print the body, it
+\fIindents\fP,
+prints the keyword
+.B begin,
+and if there were nested sections prints
+the name of this routine in a comment.
+It then goes in a level in DECL (without shifting the bar over!)
+and prints the statement list given by the parameter
+\fIblk\fP.
+.RE
+.PP
+This is an appropriate place to note the following important fact:
+When a routine is called to put out an item at the statement level,
+the
+.I "output cursor"
+is usually at the end of the previous line, and if the routine
+wants to print on a clean line, then it calls
+.I ppnl
+before it begins.
+If it is willing to print on the same line then it can call
+\fIppitem\fP.
+It also turns out that this structure is critical for the processing
+of comments which is described in section 3.
+A delay in printing
+the new line character allows the comment processing to function
+correctly.
+.PP
+Thus, after the routine
+.I statlist
+processes the parameter
+.I blk
+the rotuines
+\fIppnl\fP,
+an
+\fIindent\fP,
+are called and the keyword
+.B end
+is printed followed by the routine name in a comment and a final
+.I ;
+or
+.I \&.
+character.
+Finally unwind from any indenting that may have been done due
+to the indent nested sections option occurs, and the
+.B z
+option stack is popped if this routine was in the command line
+.B procedure
+and
+.B function
+list.
+.NH 3
+Statement processing
+.PP
+The statement level processing is done by the routines in the file
+.I stat.c
+and for case statements by the code in the file
+\fIcase.c\fP.
+As noted above, the cursor for each statement is generally left
+on the previous line so that a statement will ask for the cursor
+to be advanced to the next line if so desired.
+This is also necessary to make the placement of
+.B begin
+and
+.B end
+pairs work as desired.
+The basic loop for processing a group of statements is as follows:
+.LS
+statlist(sl)
+        \*bregister\fP \*bint\fP *sl;
+{
+        \*bif\fP (sl != NIL)
+                \*bfor\fP (;;) {
+                        statement(sl[1]);
+                        sl = sl[2];
+                        \*bif\fP (sl == NIL)
+                                \*bbreak\fP;
+                        ppsep(";");
+                }
+        \*belse\fP
+                statement(NIL);
+}
+.LE
+This is quite simple.
+A pointer to a tree structure is received, treated as an array
+of integers.
+The first word of each such node is a magic number giving the
+kind of node, the second word points to a statement and the third
+word links to the next such node, or NIL if this is the last node
+in the statement list.  This is more fully described in [1],
+the nodes here being of type T_LISTPP.
+.PP
+To illustrate the processing for statements in general,
+a subset of the code from the
+.I stat.c
+file comprising that for
+.B if
+statements, assignment statements and
+.B "begin-end"
+blocks within
+.B if
+statements follows.
+This is illustrative of the work here in general.
+.so stat.c
+.PP
+.I Statement
+receives as argument a pointer to a tree node.
+For the purposes of this discussion, assume that this node is either of type
+T_IF, T_IFEL, or T_ASGN.
+The node type T_IFEL was added to the parser because
+of the problematic case of empty
+.B else
+clauses.
+When these empty clauses are present, it is impossible
+to present the data for both
+.B if
+statements without
+.B else
+and with
+.B else
+parts in the one T_IF structure.
+An
+.B if
+statement without an
+.B else
+part looks the same as an
+.B if
+statement with an empty
+.B else
+part in this case.
+This is a problem because
+.I pxp
+does not realize that the discarding of such empty
+.B else
+parts can affect the matching of outer
+.B else
+clauses with
+.B if
+parts and alter the meaning of the program!
+.PP
+Now, if the argument to
+.I statement
+is a NIL pointer, \fInull\fR is printed,
+a call on a built-in procedure that does nothing.
+The fact that a
+.I ppitem
+rather than a
+.I ppnl
+is done here indicates that it does not matter if this is on the same line
+with something else.
+If the argument pointer is not NIL a switch is done based
+on which type of statement is involved.
+.PP
+For assignments, as for the \fInull\fR above,
+the statement can appear on the same line with something else.
+Thus
+.I ppitem
+is called.
+To print an assignment first an
+.I lvalue
+(essentially a variable)
+and then an
+.I rvalue
+(an expression)
+must be printed, separated by a `:='.
+This is as simple as knowing which fields to pass to
+procedures
+.I lvalue
+and
+.I rvalue .
+.PP
+Note that
+.I rvalue
+here takes two arguments.
+The second argument is a flag indicating whether the
+expression is to be surrounded by parentheses if
+it is not-atomic.
+Since no ambiguity can possibly result, no parenthesis are required here.
+.NH 3
+If\-then\-else's
+.PP
+It is required that an
+.I if
+statement appear on a separate line by calling
+.I ppnl .
+The routine
+.I ifop
+begins by printing:
+.LS
+\*bif\fP <expression> \*bthen\fP_
+.LE
+where the `_' will be used to represent the invisible output cursor.
+The expression here also need not be parenthesized.
+.I Ifop
+then saves the count before the statement by calling
+\fIsavecnt\fP,
+and gets the count for the
+.I then
+part of the statement by calling
+\fIgetcnt\fP.
+The
+.B then
+part can now be handled.
+.PP
+If the
+.B then
+part is a
+.B begin\-end
+block, it can be started on this line.
+Thus, in this case, the routine
+.I ppstbl1
+can be called with the
+.I then
+part as argument.
+It is also passed STAT, indicating that the indent it will do
+is to be reflected in the position of the bars on the left.
+(For
+.B with
+statements among others, the bars do not move over
+the text is indented.)
+Now
+.I ppstbl1
+prints out the keyword 
+.I begin
+and does the indent discussed above, but does not put out a newline.
+That is up to the routine
+.I statement
+which will be called by
+\fIstatlist\fP.
+The
+.B end
+is not put out yet because the counter for the
+.B else
+part belongs on the line with
+it if there is an
+.B else
+part and that count has not been set up yet.
+.PP
+If the statement in the
+.B then
+part is not a
+block then the processing here is much simpler;
+it is only necessary to indent a level in the STAT part as a block,
+call 
+.I statement
+and then unindent the level.  Thus a typical
+position after this part is completed for a
+.B then
+part which is a block would be:
+.LS
+\*bif\fP <expression> \*bthen\fP \*bbegin\fP
+        stat1;
+        stat2_
+.LE
+with the cursor convention as before.
+.PP
+If this
+.B if
+statement does not have an
+.B else
+part the rest of the processing is simple.
+The count saved before the statement is restored, doing a
+.I getcnt
+if there were one or more
+.B goto
+statements in the body of the
+statement to get the count after the statement.
+If the
+.B then
+part was a block,
+.I ppstbl2
+is called to put the keyword
+.B end
+indented on a new line with the restored count.
+This finishes the processing in this case.
+.PP
+If the statement has an
+.B else
+part then the count for this part must first be calculated.
+This is done by taking the
+.I cntof
+the saved structure from before the
+.B if
+statement and subtracting the current count which is that of the
+.B then
+part.
+This becomes the new counter generated for the
+.B else
+part.
+Processing of the
+.B then
+part is then finished either by printing a
+.B end
+with
+.I ppstbl2
+as above, followed by a space,
+or by forcing a new line in the output and calling
+.I indent.
+The keyword
+.B else
+is printed in the output and followed with a space.
+.I Unprint
+is called so that the count for an
+.B else
+part prints not only with the
+.B else
+but also on the statement in the
+.B else
+part.
+This significantly improves the readability of bushy if-then-elses.
+.PP
+The special case of an empty statement in the
+.B else
+part is caught and a null statement is put out in this case.
+Otherwise a check is made to see if the
+.B else
+part is a block, and if so, handled in a manner identical to the processing
+for the 
+.B then
+part.
+Nested
+.B if
+statements are then caught, and are recursive call is made without
+doing any indentation.
+This accomplishes the goal of not ``wandering across the page''
+in if-then-else statements.
+.PP
+Noting that normal statements are treated as before,
+the
+.B else
+part has been successfully completed except for some cleanup.
+This cleanup involves restoration of the count and printing of the
+keyword
+.B end.
+Note that the pre
+.B if
+statement count must be unprinted whenever an
+.B else
+occurs.
+This is because of the way
+.B else
+parts are printed, lined up with the
+.B if
+parts and obstructing their counts.
+.NH 3
+Expression processing
+.PP
+The final part of the profiling process to be discussed
+is the printing of expressions.  This is quite simple,
+actually, with the only interesting code being that which
+determines what parenthesization to do.  This happens as follows.
+.PP
+Whenever a binary operator is encountered each of its operands
+is processed in turn.
+The following cases are from the
+.B switch
+in the routine
+.I rvalue
+and indicates the code for processing binary operators.
+.LS
+\*bcase\fP T_AND:
+\*bcase\fP T_OR:
+\*bcase\fP T_MULT:
+\*bcase\fP T_ADD:
+\*bcase\fP T_SUB:
+\*bcase\fP T_DIVD:
+\*bcase\fP T_MOD:
+\*bcase\fP T_DIV:
+\*bcase\fP T_EQ:
+\*bcase\fP T_NE:
+\*bcase\fP T_GE:
+\*bcase\fP T_LE:
+\*bcase\fP T_GT:
+\*bcase\fP T_LT:
+\*bcase\fP T_IN:
+        al = r[2];
+        rvalue(al, prec(al) < prec(r) || opt('f'));
+        ppspac();
+        \*bif\fP (alph(opname[0]))
+                ppkw(opname);
+        \*belse\fP
+                ppop(opname);
+        ppspac();
+        al = r[3];
+        rvalue(al, prec(al) <= prec(r) || opt('f'));
+        \*bbreak\fP;
+.LE
+.PP
+The routine
+.I prec
+returns an integer representing the precedence of the
+operator given.
+It is defined by:
+.LS
+prec(r)
+        \*bregister\fP \*bint\fP *r;
+{
+        \*bif\fP (r == NIL)
+                \*breturn\fP;
+        \*bswitch\fP (r[0]) {
+                \*bcase\fP T_NOT:
+                        \*breturn\fP (3);
+                \*bcase\fP T_MULT:
+                \*bcase\fP T_DIVD:
+                \*bcase\fP T_DIV:
+                \*bcase\fP T_MOD:
+                \*bcase\fP T_AND:
+                        \*breturn\fP (2);
+                \*bcase\fP T_ADD:
+                \*bcase\fP T_SUB:
+                \*bcase\fP T_OR:
+                        \*breturn\fP (1);
+                \*bdefault\fP:
+                        \*breturn\fP (0);
+        }
+}
+.LE
+Thus, with a binary operator,
+parentheses are needed around the left operand if it is non-atomic
+and its operator has lower
+.I prec
+than the current operator.
+Parentheses are needed around the right operand if it is non-atomic
+and its operator has fewer or the same
+.I prec
+as the current operator.
+This equality condition reflects Pascal associativity.
+.NH 2
+Multiple file processing
+.PP
+.I Pxp
+has the capability of handling
+.I include
+files.
+Just as programs to
+.PI
+may be split into many pieces, they may be so split and then
+processed by
+\fIpxp\fP.
+In addition a capability for pretty printing of one piece of
+a program has been included in
+\fIpxp\fP.
+If
+.I pxp
+is pretty printing and the file being pretty printed
+has a name ending in 
+.I \&.i
+then
+.I pxp
+will place the line
+.LS
+\*bprogram\fP x(output);
+.LE
+into the source stream before the first line of the file
+and the line
+.LS
+\*bbegin\fP \*bend\fP.
+.LE
+after the last line.
+In this way, if the contents of the
+.I include
+corresponds to a global declaration part and/or
+a group of procedures and functions, the pretty print
+can proceed without modifications to the source text.
+This is the only case in which the pretty printer will
+take anything other than a complete Pascal program.
+.I Pxp
+suppresses printing back out the inserted and appended lines
+in this case.
+.PP
+.Xp
+does not normally process
+.I include
+directives but rather prints them back out as includes.
+An option to eliminate the includes is also available.
+.bp
diff --git a/doc/pxp/pxpin3.n b/doc/pxp/pxpin3.n
new file mode 100644 (file)
index 0000000..c0e98b6
--- /dev/null
@@ -0,0 +1,441 @@
+.if !\n(xx .so tmac.p
+.ND
+'nr H1 2
+.NH
+Automatic program formatting
+.NH 2
+Motivation
+.PP
+Just as software packages to automatically format documents 
+aid the construction of readable and accurate documents,
+packages which aid the construction of programs by helping prepare
+and maintain the text in a standard and easily readable format
+can aid the entire programming process.
+With an automatically structured listing, the reader can trust the
+textual display of the program to be accurate and can concentrate
+on understanding the program, rather than deciphering the style in
+which it is written.
+Even when
+.I "programming secretaries"
+are available, an automated preparation system can improve the
+programming process by defining a standard format for programs,
+making them easier to read.
+After programs are completed, and modifications to provide new features
+or to correct bugs are required, an automatic formatting system
+can work with an intelligently designed source code control
+system to help maintain clean programs with their histories.
+.PP
+The first version of
+.I pxp
+took a step toward the goal of machine aided program formatting
+by formatting the code of the program.
+It did not, however, in any way help with the annotation of
+the program with comments.
+The following sections describe a comment processing
+facility design which was added to
+.I pxp.
+.NH 2
+Implementation
+.PP
+When parsing the program information is saved in the parse tree which
+tells the source text coordinates (sequence numbers and columns)
+for the input tokens at the boundaries of chosen productions.
+The comments from the source program are saved in a separate data
+structure together with information about their source text locations and a
+classification of their ``type.''
+The comment reformatting process proceeds by printing out the parsed program
+and periodically flushing out comments.
+.NH 3
+The kinds of comments
+.PP
+.I Pxp
+distinguishes several types of comments in the input thereby varying
+their placement in the output.
+The four basic kinds of comments are:
+.IP
+.B
+Left marginal.
+.R
+At the left margin on input these comments are retained at the
+left margin in the output.
+.IP
+.B
+Aligned.
+.R
+Comments which are not at the left margin on input but which have no tokens
+preceding them on the input line are aligned with the program text on output.
+.IP
+.B
+Trailing.
+.R
+Comments appearing after tokens in the input line but separated from the
+last token on the line by only a small amount of white space are placed
+similarly in the output.
+.IP
+.B
+Right marginal.
+.R
+Comments which are more than a small amount of white space past the last
+token on a line are aligned about 35 spaces to the right of the running
+program text.
+.PP
+In addition to these comments, other formatting features of the input
+are preserved to the output.
+These include blank lines, form ejects, and
+.B include
+directives.
+.NH 2
+Examples of comment types
+.PP
+Consider the following example:
+.LS
+{ Factorial program - Assigment 1
+  John Jones, CS 153, Fall 1977 }
+
+\fBprogram\fP fact(output);
+\fBconst\fP maxfact = 20; {last factorial to be computed}
+
+        \fBfunction\fP rfact(i: integer): integer;
+        \fBbegin\fP
+               \fBif\fP i <= 1 \fBthen\fP         {terminate}
+                      fact := 1
+               \fBelse\fP                   {recurse}
+                      fact := i * fact(i - 1)
+        \fBend\fP;
+
+\fBbegin\fP
+        i := 1;
+        j := 1;
+        {iterative factorial}
+        \fBrepeat\fP
+               writeln(i, j);
+               j := j * i;
+               i := i + 1;
+        \fBuntil\fP i > maxfact;
+
+        {recursive factorial}
+        \fBfor\fP i := 1 \fBto\fP maxfact \fBdo\fP
+               writeln(i, rfact(i))
+\fBend\fP.
+.LE
+.PP
+This program has all four basic comment types.
+The first comment is
+.I marginal
+(and is followed by a blank line which is also preserved in a
+reformatted listing.)
+The comments in the text ``iterative factorial''
+and ``recursive factorial'' are 
+.I aligned
+comments.
+The comment on the declaration of
+.I maxfact
+is a
+.I trailing
+comment while the comments in
+.I rfact
+are
+.I "right marginal."
+.PP
+Since the objective of the program reformatting is to not require the
+saving of the raw programs which produced the restructured programs,
+it is necessary for the reformatting to produce programs which are
+.I "fixed points"
+with respect to the comment processing;
+that is the form of restructured programs must be preserved under
+repeated reformatting.
+The above types of comments have been carefully chosen so that
+this occurs.
+.NH 3
+Data structures (overview)
+.PP
+The following sections provide a brief descriptions of the data structures
+used by the comment formatting cluster and the method used by the cluster
+itself.
+The actual reformatting process involves a number of complications not
+detailed here, necessary to discern as much as possible from the source
+text in order to reasonably classify comments into one of the four available
+types, and in order to live with the existing structure of the parser of
+.I pi .
+.PP
+As each comment is encountered in the source text it is chained 
+onto a singly linked list recording the kind of comment involved;
+the comment delimiter, either `{' or `(*';
+the source text coordinates of the comment;
+and a linked list of lines of comment text.
+.PP
+The other data structure used to gather information is a stack parallel to the
+parse stack.
+For each element of the parse stack this stack contains the source text
+coordinates of the leftmost token shifted over in creating the associated
+state.
+Thus, when a reduction occurs, it is possible to identify the portion of the
+input text which was reduced.
+At numerous points in the parse tree where comment text is to be processed
+we save the source coordinates of the first and last token in the reduced
+production as well as the coordinates of the following (lookahead) token.
+.NH 3
+Comment processing (overview)
+.PP
+Formatting of the comments back into the program uses the source text
+coordinates embedded in the parse tree and attached to comments to construct
+a formatted listing.
+The ideas involved are quite simple.
+When we begin to print out a statement level subtree we first print out
+comments which precede this statement.
+We then print out the statement itself,
+possible invoking this process recursively.
+In recursive declarations provisions are made for embedded comments also.
+.PP
+The most important complication is that comments which appear after the last
+token of a
+.B procedure
+or
+.B function
+must be associated with this routine rather than being printed before the
+next.
+This requires a special ``to end of line'' kind of comment flushing.
+Other complications arise because of the pre-existing data structures in
+.I pxp .
+The code for
+.I pxp
+contains a number of comments detailing the resolution of these and other
+problems.
+.bp
+.NH
+Conclusions
+.NH 2
+Design
+.PP
+In retrospect, most of the design decisions were well-made.
+The counter placement rules resulted in a small number of counters.
+The reparsing of the program runs at a reasonable rate,
+approximately twice the speed of compilation.
+The inaccurate counts which may be generated with non-local
+.B goto
+statements have as yet caused no problems.
+The biggest deficiency in the design is, in fact, the lack of a debugger
+implementation to complement the profiling facilities.
+.NH 2
+Implementation
+.PP
+The implementation proved to be quite simple.
+The design choices allowing
+.I pxp
+to use the framework of
+.I pi
+were well taken.
+The largest weakness of the implementation may be the fact that
+the print cluster structure may not necessarily be the best one for
+doing long statement folding across line boundaries, and for
+processing the placement of multiple statements per line.
+Whether or not this is true would be seen if such a implementation
+modification were attempted.
+.NH 2
+Profiling
+.PP
+The format of the profile worked out quite well.
+Basing the format on [9] was an excellent choice.
+For initialization procedures and some others, multiple
+statement per line placements is noticeably needed.
+It is felt that languages which offer initialization facilities
+for structured statements will likewise need more complex format
+processing in such declarations.
+With comment reformatting a profile can substitute
+for a program listing.
+In this case the philosophy of suppressing unexecuted
+.B procedure
+and
+.B function
+bodies as well as declaration parts
+might be re-examined.
+.NH 2
+Reformatting
+.PP
+For program formatting, a comment formatting facility is a must.
+The author feels that the basic format of programs is well chosen,
+but most persons would prefer an (at least slightly) different format.
+Again, long statement folding and the placement of multiple statements
+per line would be a plus here.
+Even in its present state, the formatting facilities are judged to be
+useful, especially for showing students with no perceivable style
+one plausible way of formatting Pascal programs.
+.NH 2
+Future systems
+.PP
+Execution profiling is an important tool because it provides feedback at the
+source program level.
+A number of systems including such facilities exist or are proposed
+[10] [11] [12] [13].
+The author expects the following to be components of future systems:
+.HP
+.RS
+.IP 1)
+Source language editors [16] [17]
+.IP 2)
+Symbolic source language debuggers [8] [16]
+.IP 3)
+Source code control systems [18]
+.RE
+.PP
+A well-designed programming language system with these components could provide
+systems programmers with a powerful set of system construction tools,
+similar to those available in excellent \s-2LISP\s0 systems such as [16].
+.bp
+.SH
+References
+.PP
+.IP [1]
+Charles B. Haley
+.br
+Master's Project Report
+.br
+U.C. Berkeley, June, 1977.
+.IP [2]
+William N. Joy
+.br
+.I "PX 1.1 Implementation Notes"
+.br
+October, 1978.
+.IP [3]
+William N. Joy, Susan L. Graham, and Charles B. Haley
+.br
+.I "Berkeley Pascal User's Manual"
+.br
+Version 1.0 \- November, 1977.
+.IP [4]
+K. Thompson and D. M. Ritchie
+.br
+.I
+UNIX
+Programmers Manual
+.R
+.br
+Version 6.7
+(revised at University of California)
+.br
+June 1977.
+.IP [5]
+Kathleen Jensen and Niklaus Wirth
+.br
+.I
+Pascal \- User Manual and Report
+.R
+.br
+Springer-Verlag, New York
+.br
+1975.
+.IP [6]
+William N. Joy
+.br
+.I "PDB Design notes and draft manual"
+.br
+January, 1977.
+.IP [7]
+D. E. Knuth and F. R. Stevenson
+.br
+.I "Optimal measurement points for program frequency counts"
+.br
+BIT 13 (1973) 313-322.
+.IP [8]
+Edwin H. Satterthwaite
+.br
+.I "Source Language Debugging Tools"
+.br
+STAN-CS-75-494, May, 1975.
+.IP [9]
+Edwin H. Satterthwaite
+.br
+.I "Debugging Tools for High Level Languages"
+.br
+Software, Practice and Experience
+.br
+Vol. 2, 197-217, 1972.
+.IP [10]
+J. D. Ichbiah, J, C. H\*'eliard, J. P. Rissen, P. Cousot
+.br
+.I "The Systems Implementation Language LIS - Reference Manual"
+.br
+Technical Report 4549 E1/EN.
+.br
+Compagnie Internationale pour l\(aaInformatique
+.br
+68, route de Versailles \- 78430 LOUVECIENNES
+.br
+December 1974. Revised January 1976.
+.IP [11]
+B. W. Lampson, J. J. Horning, R. L. London, J. G. Mitchell, G. L. Popek
+.br
+.I "Report on the Programming Language Euclid"
+.br
+Sigplan Notices, Volume 12, Number 2.
+.br
+February 1977.
+.br
+Pp. 64-65.
+.IP [12]
+D. T. Barnard
+.br
+.I "Automatic generation of syntax-repairing and paragraphing parsers"
+.br
+Technical Report CSRG-52.
+.br
+Computer Systems Research Group
+.br
+University of Toronto, Toronto, Ontario.
+.br
+April 1975.
+.IP [13]
+R. C. Holt and D. T. Barnard
+.br
+.I "Syntax directed error repair and paragraphing"
+.br
+Computer Systems Research Group.
+.br
+University of Toronto, Toronto, Ontario.
+.br
+June, 1976.
+.IP [14]
+A. van Wijngaarden, et. al.
+.br
+.I "Revised Report on the algorithmic language ALGOL 68"
+.br
+Sigplan Notices, Volume 12, Number 5.
+.br
+May 1977.
+.IP [15]
+Niklaus Wirth
+.br
+.I "Modula: A language for modular multiprogramming"
+.br
+Institut f\*:ur Informatik
+.br
+ETH, CH 8092 Z\*:urich
+.br
+March, 1976.
+.IP [16]
+Warren Teitleman
+.br
+.I "Interlisp Reference Manual"
+.br
+Xerox Palo Alto Research Center
+.br
+Palo Alto, California
+.br
+December 1974.
+.IP [17]
+Steve German
+.br
+.I
+ECL in-core editor
+.R
+.br
+Documentation dated 10/20/1973.
+.IP [18]
+Rochkind, Marc J.
+.br
+The Source Code Control System
+.br
+IEEE TOSE Vol SE-1 #4
+.br
+Dec. 1975, 364-370
diff --git a/doc/pxp/stat.c b/doc/pxp/stat.c
new file mode 100644 (file)
index 0000000..109985e
--- /dev/null
@@ -0,0 +1,109 @@
+.LS .ID
+.nf
+statement(s)
+        \*bregister\fP \*bint\fR *s;
+{
+
+        \*bif\fP (s == NIL) {
+                ppitem();
+                ppid("null");
+                \*breturn\fP;
+        }
+        line = s[1];
+        \*bswitch\fP (s[0]) {
+                \*bdefault\fP:
+                        panic("stat");
+                \*bcase\fP T_IF:
+                \*bcase\fP T_IFEL:
+                        ppnl();
+                        indent();
+                        ifop(s);
+                        \*breturn\fP;
+                \*bcase\fP T_ASGN:
+                        ppitem();
+                        asgnop(s);
+                        \*breturn\fP;
+        }
+}
+
+asgnop(r)
+        \*bregister\fP \*bint\fR *r;
+{
+        lvalue(r[2]);
+        ppsep(" := ");
+        rvalue(r[3], NIL);
+}
+
+ifop(r)
+        \*bregister\fP \*bint\fR *r;
+{
+        \*bregister\fP \*bint\fR *s;
+        \*bstruct\fP pxcnt scnt;
+
+        ppkw("if");
+        ppspac();
+        rvalue(r[2], NIL);
+        ppspac();
+        ppkw("then");
+        ppspac();
+        s = r[3];
+        savecnt(&scnt);
+        getcnt();
+        \*bif\fP (s != NIL && s[0] == T_BLOCK)
+                ppstbl1(s, STAT);
+        \*b\*belse\fP\fR {
+                ppgoin(STAT);
+                statement(s);
+                ppgoout(STAT);
+        }
+        \*bif\fP (r[0] == T_IFEL) {
+                setcnt(cntof(&scnt)-nowcnt());
+                \*bif\fP (s == NIL || s[0] != T_BLOCK) {
+                        ppnl();
+                        indent();
+                } \*belse\fP {
+                        ppstbl2();
+                        ppspac();
+                }
+                s = r[4];
+                ppkw("else");
+                unprint();
+                ppspac();
+                \*bif\fP (s == NIL)
+                        \*bgoto\fP burp;
+                \*bif\fP (s[0] == T_BLOCK)
+                        ppstbl1(s, STAT);
+                \*belse\fP \*bif\fR (s[0] == T_IF || s[0] == T_IFEL)
+                        ifop(s);
+                \*belse\fP {
+burp:
+                        ppgoin(STAT);
+                        statement(s);
+                        ppgoout(STAT);
+                }
+        }
+        \*bif\fP (rescnt(&scnt))
+                getcnt();
+        \*bif\fP (r[4] != NIL)
+                unprint();
+        \*bif\fP (s != NIL && s[0] == T_BLOCK)
+                ppstbl2();
+}
+
+ppstbl1(r, m)
+       \*bint\fP *r, m;
+{
+        ppkw("begin");
+        ppgoin(m);
+        statlist(r[2]);
+        ppgoout(m);
+}
+
+ppstbl2()
+{
+        ppnl();
+        indent();
+        ppkw("end");
+}
+.fi
+.LE
diff --git a/doc/pxp/tmac.p b/doc/pxp/tmac.p
new file mode 100644 (file)
index 0000000..b1ea274
--- /dev/null
@@ -0,0 +1,77 @@
+'if \n(FM=0 'so /usr/lib/tmac/tmac.s
+.if n .nr FM 1.2i
+.if t .tr *\(**=\(eq/\(sl+\(pl
+.bd S B 3
+.de SM
+.if "\\$1"" .ps -2
+.if !"\\$1"" \s-2\\$1\s0\\$2
+..
+.de LG
+.if "\\$1"" .ps +2
+.if !"\\$1"" \s+2\\$a\s0\\$2
+..
+.de HP
+.nr pd \\n(PD
+.nr PD 0
+.if \\n(.$=0 .IP
+.if \\n(.$=1 .IP "\\$1"
+.if \\n(.$>=2 .IP "\\$1" "\\$2"
+.nr PD \\n(pd
+..
+.de ZP
+.nr pd \\n(PD
+.nr PD 0
+.PP
+.nr PD \\n(pd
+..
+.de LS         \"LS - Literal display, ASCII, constant spaced DS
+.if \\n(.$=0 .DS
+.if \\n(.$=1 \\$1
+.if \\n(.$>1 \\$1 "\\$2"
+.if t .tr '\'`\`^\(ua-\(mi
+.if t .tr _\(ul
+..
+.de LE         \"LE - End literal display
+.DE
+.tr ''``__--^^
+..
+.de UP
+Berkeley Pascal\\$1
+..
+.de PD
+\s-2PDP\s0
+.if \\n(.$=0 11/70
+.if \\n(.$>0 11/\\$1
+..
+.de DK
+Digital Equipment Corporation\\$1
+..
+.de PI
+.I pi \\$1
+..
+.de Xp
+.I Pxp \\$1
+..
+.de XP
+.I pxp \\$1
+..
+.de IX
+.I pix \\$1
+..
+.de X
+.I px \\$1
+..
+.de PX
+.I px \\$1
+..
+.if n .ds dg +
+.if t .ds dg \(dg
+.if n .ds Dg \*(dg
+.if t .ds Dg \*(dg
+.if n .ds dd *
+.if n .ds Dd \*(dd
+.if t .ds Dd \*(dd
+.if t .ds dd \(dd
+.if t .ds b \\fB
+.if n .ds b \\fI
+.nr xx 1