Pristine Ack-5.5
[Ack-5.5.git] / man / pc_prlib.7
1 .\" $Id: pc_prlib.7,v 2.11 1994/06/24 14:02:12 ceriel Exp $
2 .TH PC_PRLIB 7 "$Revision: 2.11 $"
3 .ad
4 .SH NAME
5 pc_prlib \- library of Pascal runtime routines
6 .SH SYNOPSIS
7 .ta 11n 22n 33n 44n 55n
8 .nf
9 type    alpha=packed array[1..8] of char;
10         pstring= ^packed array[] of char;
11
12 function        _abi(i:integer):integer;
13 function        _abl(i:long):long;
14 function        _mdi(j,i:integer):integer;
15 function        _mdl(j,i:long):long;
16 function        _dvi(j,i:integer):integer;
17 function        _dvl(j,i:long):long;
18 function        _abr(r:real):real;
19 function        _sin(r:real):real;
20 function        _cos(r:real):real;
21 function        _atn(r:real):real;
22 function        _exp(r:real):real;
23 function        _log(r:real):real;
24 function        _sqt(r:real):real;
25 function        _rnd(r:real):real;
26
27 type    compared=-1..1;
28         gotoinfo=record
29             pcoffset:^procedure; { procedure id. without static link }
30             nlocals: integer;
31         end;
32
33 type    arrdescr=record
34             lowbnd:  integer;
35             diffbnds:integer;
36             elsize:  integer;
37         end;
38         arr1=array[] of ?;
39         arr2=packed array[] of ?;
40
41 function        _bcp(sz:integer; s2,s1:pstring):compared;
42 function        _bts(size,high,low:integer; base:^set 0..(8*size-1))
43                         :set of 0..(8*size-1);
44 procedure       _gto(lb:^integer; p:^gotoinfo);
45 procedure       _rcka(a: arrdescr; index : integer);
46 procedure       _nfa(bool:integer);
47
48 procedure       _new(size:integer; var p:^integer);
49 procedure       _dis(size:integer; var p:^integer);
50 procedure       _sav(var p:^integer);
51 procedure       _rst(var p:^integer);
52
53 procedure       _pac(var ad,zd:arrdescr; var zp:arr2; i:integer;
54                       var ap:arr1);
55 procedure       _unp(var ad,zd:arrdescr; i:integer; var ap:arr1;
56                       var zp:arr2;nosgnext:boolean);
57 function        _asz(var dp:arrdescr):integer;
58
59 procedure       _ass(line:integer; b:boolean);
60 procedure       procentry(name:pstring);
61 procedure       procexit(name:pstring);
62
63 const   lowbyte=[0..7];
64         MAGIC  =[1,3,5,7];
65         WINDOW =[11];
66         ELNBIT =[12];
67         EOFBIT =[13];
68         TXTBIT =[14];
69         WRBIT  =[15];
70         PC_BUFLEN =1024;
71 type    file=record
72             ptr:        ^char;
73             flags:      set of [0..15];
74             fname:      pstring;
75             ufd:        0..15;
76             size:       integer;
77             count:      0..buflen;
78             buflen:     max(PC_BUFLEN,size) div size * size;
79             bufadr:     packed array[1..max(PC_BUFLEN,size)]
80                              of char;
81         end;
82         filep=^file;
83 const   NFILES=15;
84         _extfl:^array[] of filep;
85
86 procedure       _ini(args:pstring; var c:integer;
87                              var p:array[] of filep; mainlb:pstring);
88 procedure       _hlt(status:0..255);
89
90 procedure       _opn(size:integer; f:filep);
91 procedure       _cre(size:integer; f:filep);
92 procedure       _cls(f:filep);
93
94 procedure       _get(f:filep);
95 procedure       _put(f:filep);
96 function        _wdw(f:filep):^char;
97 function        _efl(f:filep):boolean;
98
99 function        _eln(f:filep):boolean;
100 function        _rdc(f:filep):char;
101 function        _rdi(f:filep):integer;
102 function        _rdl(f:filep):long;
103 function        _rdr(f:filep):real;
104 procedure       _rln(f:filep);
105 procedure       _wrc(c:char; f:filep);
106 procedure       _wsc(w:integer; c:char; f:filep);
107 procedure       _wri(i:integer; f:filep);
108 procedure       _wsi(w:integer; i:integer; f:filep);
109 procedure       _wrl(l:long; f:filep);
110 procedure       _wsl(w:integer; l:long; f:filep);
111 procedure       _wrr(r:real; f:filep);
112 procedure       _wsr(w:integer; r:real; f:filep);
113 procedure       _wrf(ndigit:integer; w:integer; r:real; f:filep);
114 procedure       _wrs(l:integer; s:pstring; f:filep);
115 procedure       _wss(w:integer; l:integer; s:pstring; f:filep);
116 procedure       _wrb(b:boolean; f:filep);
117 procedure       _wsb(w:integer; b:boolean; f:filep);
118 procedure       _wrz(s:string; f:filep);
119 procedure       _wsz(w:integer; s:string; f:filep);
120 procedure       _wln(f:filep);
121 procedure       _pag(f:filep);
122 .fi
123 .SH DESCRIPTION
124 This library is used by the Pascal to EM compiler and
125 contains all the runtime routines for standard Pascal programs.
126 Most routines are written in C, a few in EM assembly language.
127 These routines can be divided into several categories.
128 A description of each category with its routines follows.
129 .PP
130 Arithmetic routines:
131 .RS
132 .IP _abi
133 Compute the absolute value of an integer.
134 .PD 0
135 .IP _abl
136 Compute the absolute value of a long.
137 .IP _mdi
138 Perform the Pascal modulo operation on integers.
139 .IP _mdl
140 Perform the Pascal modulo operation on longs.
141 .IP _dvi
142 Perform the Pascal divide operation on integers.
143 .IP _dvl
144 Perform the Pascal divide operation on longs.
145 .IP _abr
146 Compute the absolute value of a real.
147 .IP _sin
148 Compute the sine of a real.
149 .IP _cos
150 Compute the cosine of a real.
151 .IP _atn
152 Compute the arc tangent of a real.
153 .IP _exp
154 Compute the e-power of a real.
155 .IP _log
156 Compute the natural logarithm of a real.
157 .IP _sqt
158 Compute the square root of a real.
159 .IP _rnd
160 Return a real that when truncated will
161 result in the nearest integer (-3.5->-4).
162 .PD
163 .PP
164 .RE
165 Miscellaneous routines:
166 .RS
167 .IP _bcp
168 Compare two strings. Use dictionary ordering with the ASCII
169 character set. The EM instruction CMU can not be used, because it needs
170 an even number of bytes.
171 .PD 0
172 .IP _bts
173 Include a range of elements from low to high in a set of size bytes
174 at address base.(size can be divided by the wordsize)
175 .IP _gto
176 Execute a non-local goto. Lb points to the
177 local base of the target procedure.
178 A lb of zero indicates a jump to the program body, the lb of the main
179 program is found in _m_lb, which is set by _ini.
180 The new EM stack pointer is calculated by adding the number of locals
181 to the new local base
182 (jumping into statements is not allowed; there are no local generators
183 in Pascal!).
184 .IP _rcka
185 Check if an array reference isn't out of bounds. This is should be done by
186 the backends, but some don't.
187 .IP _nfa
188 Check whether a function is assigned or not. This could have
189 been done by the compiler, but that would make the interface between the
190 compiler and the run-time library messier.
191 .PD
192 .PP
193 .RE
194 Heap management:
195 .RS
196 .PP
197 There is one way to allocate new heap space (_new), but two different
198 incompatible ways to deallocate it.
199 .PP
200 The most general one is by using dispose (_dis).
201 A circular list of free blocks, ordered from low to high addresses, is maintained.
202 Merging free blocks is done when a new block enters the free list.
203 When a new block is requested (_new), the free list is searched using a
204 first fit algorithm.
205 Two global variables are needed:
206 .IP _highp 10
207 Points to the free block with the highest address.
208 .PD 0
209 .IP _lastp
210 Points to the most recently entered free block or to a block
211 in the neighborhood of the most recently allocated block.
212 .PD
213 The free list is empty, when one of these pointers (but then at the same
214 time both) is zero.
215 .PP
216 The second way to deallocate heap space is by using
217 mark (_sav) and release (_rst). Mark saves the current value of the
218 heap pointer HP in the program variable passed as a parameter.
219 By calling release with this old HP value as its argument, the old HP value
220 is restored, effectively deallocating all blocks requested between
221 the calls to mark and release.
222 The heap is used as second stack in this case.
223 .PP
224 It will be clear that these two ways of deallocating heap space
225 can not be used together.
226 To be able to maintain the free list, all blocks must be a multiple
227 of n bytes long, with a minimum of n bytes,
228 where n is the sum of the size of a word and a pointer in the
229 EM implementation used.
230 .PP
231 In summary:
232 .IP _new
233 Allocate heap space.
234 .PD 0
235 .IP _dis
236 Deallocate heap space.
237 .IP _sav
238 Save the current value of HP.
239 .IP _rst
240 Restore an old value of HP.
241 .PD
242 .PP
243 .RE
244 Array operations:
245 .RS
246 .PP
247 The only useful form of packing implemented, is packing bytes into words.
248 All other forms of packing and unpacking result in a plain copy.
249 .IP _pac
250 Pack an unpacked array \fIa\fP into a packed array \fIz\fP.
251 \fIap\fP and \fIzp\fP
252 are pointers to \fIa\fP and \fIz\fP. \fIad\fP and \fIzd\fP
253 are pointers to the descriptors of \fIa\fP and \fIz\fP. \fIi\fP is
254 the index in \fIa\fP of the first element to be packed.
255 Pack until \fIz\fP is full.
256 .PD 0
257 .IP _unp
258 Unpack \fIz\fP into \fIa\fP.
259 \fIap\fP, \fIzp\fP, \fIad\fP and \fIzd\fP are as for _pac. \fIi\fP is
260 the index in \fIa\fP where the first element of \fIz\fP is copied into.
261 Unpack all elements of \fIz\fP. The boolean flag \fInosgnext\fP indicates
262 whether the values should or should not be sign-extended.
263 .IP _asz
264 Compute array size. Used for copying conformant arrays.
265 .PD
266 .PP
267 .RE
268 Debugging facilities:
269 .RS
270 The compiler allows for the verification of assertions.
271 It generates a call to the routine _ass to check the assertion at runtime.
272 Another feature of the compiler is that it enables the user to trace the
273 procedure calling sequence. If the correct option is turned on, then
274 a call to the procedure \fIprocentry\fP is generated at the start of each
275 compiled procedure or function. Likewise, the routine \fIprocexit\fP is called
276 just before a procedure or function exits.
277 Default procedure \fIprocentry\fP
278 and \fIprocexit\fP are available in this library.
279 .IP _ass 10
280 If \fIb\fP is zero, then change eb[0] to \fIline\fP
281 (to give an error message with source line number) and call the error routine.
282 .PD 0
283 .IP procentry
284 Print the name of the called procedure on standard output. Output must
285 be declared in the program heading.
286 .IP procexit
287 Print the name of the procedure that is about to exit. Output must
288 be declared in the program heading.
289 .PD
290 .PP
291 .RE
292 Files:
293 .RS
294 .PP
295 Most of the runtime routines are needed for file handling.
296 For each file in the Pascal program a record of type file, as described
297 above, is allocated, static if this file is declared in the outermost block,
298 dynamic if it is declared in inner blocks.
299 The fields in the file record are used for:
300 .IP bufadr 10
301 IO is buffered except for standard input and output if
302 terminals are involved. The size of the buffer is the maximum of PC_BUFLEN
303 and the file element size.
304 .PD 0
305 .IP buflen
306 The effective buffer length is the maximum number of file elements
307 fitting in the buffer, multiplied by the element size.
308 .IP size
309 The file element size (1 or even).
310 .IP flags
311 Some flag bits are stored in the high byte and a magic pattern
312 in the low byte provides detection of destroyed file
313 information.
314 .IP ptr
315 Points to the file window inside the buffer.
316 .IP count
317 The number of bytes (the window inclusive) left in the buffer
318 to be read or the number of free bytes (the window inclusive) for output files.
319 .IP ufd
320 The UNIX file descriptor for the file.
321 .IP fname
322 Points to the name of the file (INPUT for standard input,
323 OUTPUT for standard output and LOCAL for local files).
324 This field is used for generating error messages.
325 .PD
326 .PP
327 The constants used by the file handling routines are:
328 .IP WINDOW 10
329 Bit in flags set if the window of an input file is initialized.
330 Used to resolve the famous interactive input problem.
331 .PD 0
332 .IP EOFBIT
333 Bit in flags set if end of file seen
334 .IP ELNBIT
335 Bit in flags set if linefeed seen
336 .IP TXTBIT
337 Bit in flags set for text files. Process linefeeds.
338 .IP WRBIT
339 Bit in flags set for output files
340 .IP MAGIC
341 Pattern for the low byte of flags
342 .IP NFILES
343 The maximum number of open files in UNIX
344 .PD
345 .PP
346 .RE
347 Prelude and postlude:
348 .RS
349 .PP
350 These routines are called once for each Pascal program:
351 .IP _ini
352 When a file mentioned in the program heading is opened by reset or
353 rewrite, its file pointer must be mapped onto one of the program
354 arguments.
355 The compiler knows how to map and therefore builds a table with
356 a pointer to the file structure for each program argument.
357 One of the first actions of the Pascal program is to call this procedure
358 with this table as an argument.
359 The global variable _extfl is used to save the address of this table.
360 Another task of _ini is to initialize the standard input and output files.
361 For standard output it must decide whether to buffer or not.
362 If standard output is a terminal, then buffering is off by setting
363 buflen to 1.
364 Two other task of _ini are the copying of two variables from
365 the argument list to global memory, mainlb to _m_lb and c to _extflc.
366 The first contains the local base of the program body, the second
367 contains the number of paremeters the program is called with.
368 A last task of _ini is to set the global variables _pargc, _pargv and
369 _penvp from args for possible reference later on.
370 Args points to the argument count placed on the stack by the EM runtime system,
371 see chapter 8 in [1].
372 .PD 0
373 .IP _hlt
374 If the program is about to finish, the buffered files must be flushed.
375 That is done by this procedure.
376 .PD
377 .PP
378 .RE
379 Opening and closing:
380 .RS
381 .PP
382 Files in Pascal are opened for reading by reset and opened for writing by
383 rewrite.
384 Files to be rewritten may or may not exist already.
385 Files not mentioned in the program heading are considered local files.
386 The next steps must be done for reset and rewrite:
387 .IP 1.
388 If size is zero, then a text file must be opened with elements of
389 size 1.
390 .PD 0
391 .IP 2.
392 Find out if this file is mentioned in the program heading
393 (scan table pointed to by _extfl).
394 If not, then it is a local file and goto 7.
395 .IP 3.
396 If the file is standard input or output then return.
397 .IP 4.
398 If there are not enough arguments supplied, generate an error.
399 .IP 5.
400 If the file was already open, flush the buffer if necessary and close it.
401 Note that reset may be used to force the buffer to be flushed.
402 This is sometimes helpful against program or system crashes.
403 .IP 6.
404 If it is a reset, open the file, otherwise create it.
405 In both cases goto 9.
406 .IP 7.
407 If the local file is to be written, then close it if it was open and
408 create a new nameless file. First try to create it in /usr/tmp, then in /tmp
409 and if both fail then try the current directory.
410 See to it that the file is open for both reading and writing.
411 .IP 8.
412 If the local file is to be read
413 and the file is opened already, then
414 flush the buffer and seek to the beginning.
415 Otherwise open a temporary file as described in 7.
416 .IP 9.
417 Initialize all the file record fields.
418 .PD
419 .PP
420 The necessary procedures are:
421 .IP _opn
422 Reset a file
423 .PD 0
424 .IP _cre
425 Rewrite a file
426 .IP _cls
427 Close a file. Closing of files is done for local files when the procedure
428 in which they are declared exits.
429 The compiler only closes local files if they are not part of a structured type.
430 Files allocated in the heap are not closed when they are deallocated.
431 There is an external routine \fIpclose\fP in libpc(7), that may be called
432 explicitly to do the closing in these cases.
433 Closing may be necessary to flush buffers or to keep the number of
434 simultaneously opened files below NFILES.
435 Files declared in the outermost block are automatically closed when the
436 program terminates.
437 .PD
438 .PP
439 .RE
440 General file IO:
441 .RS
442 .PP
443 These routines are provided for general file IO:
444 .IP _put
445 Append the file element in the window to the file and advance the
446 window.
447 .IP _get
448 Advance the file window so that it points to the next element
449 of the file.
450 For text files (TXTBIT on) the ELNBIT in flags is set if the new character
451 in the window is a line feed (ASCII 10) and the character is then changed
452 into a space.
453 Otherwise the ELNBIT is cleared.
454 .IP _wdw
455 Return the current pointer to the file window.
456 .IP _efl
457 Test if end of file is reached.
458 Is always true for output files.
459 .PD
460 .PP
461 .RE
462 Textfile routines:
463 .RS
464 .PP
465 The rest of the routines all handle text files.
466 .IP _eln
467 Return true if the next character on an input file is an end-of-line marker.
468 An error occurs if eof(f) is true.
469 .PD 0
470 .IP _rdc
471 Return the character currently in the window and advance the window.
472 .IP _rdi
473 Build an integer from the next couple of characters on the file,
474 starting with the character in the window.
475 The integer may be preceded by spaces (and line feeds), tabs and a sign.
476 There must be at least one digit.
477 The first non-digit signals the end of the integer.
478 .IP _rdl
479 Like _rdi, but for longs.
480 .IP _rdr
481 Like _rdi, but for reals. Syntax is as required for Pascal.
482 .IP _rln
483 Skips the current line and clears the WINDOW flag, so that the
484 next routine requiring an initialized window knows that it has to
485 fetch the next character first.
486 .IP _wrc
487 Write a character, not preceeded by spaces.
488 .IP _wsc
489 Write a character, left padded with spaces up to a field width
490 of \fIw\fP.
491 .IP _wri
492 Write an integer, left padded with spaces up to a field width
493 of 6 on 2-byte machines and a field width of 11 on 4-byte machines.
494 .IP _wsi
495 Write an integer, left padded with spaces up to a field width
496 of \fIw\fP.
497 .IP _wrl
498 Write a long, left padded with spaces up to a field width
499 of 11.
500 .IP _wsl
501 Write a long, left padded with spaces up to a field width
502 of \fIw\fP.
503 .IP _wrr
504 Write a real in scientific format,
505 left padded with spaces up to a field width of 13.
506 .IP _wsr
507 Write a real in scientific format,
508 left padded with spaces up to a field width of \fIw\fP.
509 .IP _wrf
510 Write a real in fixed point format, with exactly \fIndigit\fP digits
511 behind the decimal point, the last one rounded; it is left padded up to
512 a field width of \fIw\fP.
513 .IP _wrs
514 Write a string of length \fIl\fP, without additional spaces.
515 .IP _wss
516 Write a string of length \fIl\fP, left padded up to a field
517 width of \fIw\fP.
518 .IP _wrb
519 Write a boolean, represented by "true" or "false", left padded
520 up to a field width of 5.
521 .IP _wsb
522 Write a boolean, represented by "true" or "false", left padded
523 up to a field width of \fIw\fP.
524 .IP _wrz
525 Write a C-type string up to the zero-byte.
526 .IP _wsz
527 Write a C-type string, left padded up to a field width of w.
528 .IP _wln
529 Write a line feed (ASCII 10).
530 .IP _pag
531 Write a form feed (ASCII 12).
532 .PD
533 .PP
534 .RE
535 All the routines to which calls are generated by the compiler are described above.
536 They use the following global defined routines to do some of the work:
537 .IP _rf 10
538 Check input files for MAGIC and WRBIT.
539 Initialize the window if WINDOW is cleared.
540 .PD 0
541 .IP _wf
542 Check output files for MAGIC and WRBIT.
543 .IP _incpt
544 Advance the file window and read a new buffer if necessary.
545 .IP _outcpt
546 Write out the current buffer if necessary and advance the window.
547 .IP _flush
548 Flush the buffer if it is an output file.
549 Append an extra line marker if EOLBIT is off.
550 .IP _wstrin
551 All output routines make up a string in a local buffer.
552 They call _wstrin to output this buffer and to do the left padding.
553 .IP _skipsp
554 Skip spaces (and line feeds) on input files.
555 .IP _getsig
556 Read '+' or '-' if present.
557 .IP _fstdig
558 See to it that the next character is a digit. Otherwise error.
559 .IP _nxtdig
560 Check if the next character is a digit.
561 .IP _getint
562 Do the work for _rdi.
563 .IP _ecvt
564 Convert real into string of digits for printout in scientific notation.
565 .IP _fcvt
566 Convert real into string of digits for fixed point printout
567 .IP -fif
568 Split real into integer and fraction part
569 .IP _fef
570 Split real into exponent and fraction part
571 .PD
572 .PP
573 The following global variables are used:
574 .IP _lastp 10
575 For heap management (see above).
576 .PD 0
577 .IP _highp
578 For heap management (see above).
579 .IP _extfl
580 Used to save the argument p of _ini for later reference.
581 .IP _extflc
582 Used to save the argument c of _ini for later reference.
583 .IP _m_lb
584 Used to store the local base of the main program.
585 .IP _curfil
586 Save the current file pointer, so that the
587 error message can access the file name.
588 .IP "_pargc, _pargv, _penvp"
589 Used to access the arguments of the main program.
590 .PD
591 .SH FILES
592 .IP ~em/lib/*/tail_pc 20
593 The library used by ack[5] to link programs.
594 .PD
595 .SH "SEE ALSO"
596 .IP [1]
597 A.S. Tanenbaum, Ed Keizer, Hans van Staveren & J.W. Stevenson
598 "Description of a machine architecture for use of
599 block structured languages" Informatica rapport IR-81.
600 .PD 0
601 .IP [2]
602 K.Jensen & N.Wirth
603 "PASCAL, User Manual and Report" Springer-Verlag.
604 .IP [3]
605 Specification fo Computer programming language Pascal, BS6192: 1982
606 (ISO 7185)
607 .IP [4]
608 J.W. Stevenson, H. van Eck, "Amsterdam Compiler Kit-Pascal reference manual".
609 .br
610 (try \fItbl ~em/doc/pcref.doc | nroff\fP).
611 .IP [5]
612 ack(1), em_pc(6)
613 .PD
614 .SH DIAGNOSTICS
615 All errors discovered by this runtime system cause an EM TRP instruction
616 to be executed. This TRP instruction expects the error number on top
617 of the stack. See [1] for a more extensive treatment of the subject.
618 .PP
619 EM allows the user to specify a trap handling routine, called whenever
620 an EM machine trap or a language or user defined trap occurs.
621 One of the first actions in _ini is to specify that the routine _fatal,
622 available in this library, will handle traps.
623 This routine is called with an error code (0..252) as argument.
624 The following information is printed
625 on file descriptor 2:
626 .IP -
627 The name of the Pascal program
628 .PD 0
629 .IP -
630 The name of the file pointed to by _curfil, if the error number
631 is between 96 and 127 inclusive.
632 .IP -
633 The error message (or the error number if not found).
634 .IP -
635 The source line number if not equal to 0.
636 .PD
637 .PP
638 The routine _fatal stops the program as soon as the message is printed.
639 .PP
640 The following error codes are used by the Pascal runtime system:
641 .IP 64
642 more args expected
643 .PD 0
644 .IP 65
645 error in exp
646 .IP 66
647 error in ln
648 .IP 67
649 error in sqrt
650 .IP 68
651 assertion failed
652 .IP 69
653 array bound error in pack
654 .IP 70
655 array bound error in unpack
656 .IP 71
657 only positive j in \fIi mod j\fP
658 .IP 72
659 file not yet open
660 .IP 73
661 dispose error
662 .IP 74
663 function not assigned
664 .IP 75
665 illegal field width
666 .sp
667 .IP 96
668 file xxx: not writable
669 .IP 97
670 file xxx: not readable
671 .IP 98
672 file xxx: end of file
673 .IP 99
674 file xxx: truncated
675 .IP 100
676 file xxx: reset error
677 .IP 101
678 file xxx: rewrite error
679 .IP 102
680 file xxx: close error
681 .IP 103
682 file xxx: read error
683 .IP 104
684 file xxx: write error
685 .IP 105
686 file xxx: digit expected
687 .IP 106
688 file xxx: non-ASCII char read
689 .PD
690 .PP
691 .SH AUTHORS
692 Johan Stevenson and Ard Verhoog, Vrije Universiteit.