123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681 |
- .\" $Header$
- .TH PC_PRLIB 7ACK
- .ad
- .SH NAME
- pc_prlib \- library of Pascal runtime routines
- .SH SYNOPSIS
- .ta 11n 22n 33n 44n 55n
- .nf
- type alpha=packed array[1..8] of char;
- pstring= ^packed array[] of char;
- function _abi(i:integer):integer;
- function _abl(i:long):long;
- function _mdi(j,i:integer):integer;
- function _mdl(j,i:long):long;
- function _abr(r:real):real;
- function _sin(r:real):real;
- function _cos(r:real):real;
- function _atn(r:real):real;
- function _exp(r:real):real;
- function _log(r:real):real;
- function _sqt(r:real):real;
- function _rnd(r:real):real;
- type compared=-1..1;
- gotoinfo=record
- pcoffset:^procedure; { procedure id. without static link }
- nlocals: integer;
- end;
- function _bcp(sz:integer; s2,s1:pstring):compared;
- function _bts(size,high,low:integer; base:^set 0..(8*size-1))
- :set of 0..(8*size-1);
- procedure _gto(lb:^integer; p:^gotoinfo);
- procedure _new(size:integer; var p:^integer);
- procedure _dis(size:integer; var p:^integer);
- procedure _sav(var p:^integer);
- procedure _rst(var p:^integer);
- type arrdescr=record
- lowbnd: integer;
- diffbnds:integer;
- elsize: integer;
- end;
- arr1=array[] of ?;
- arr2=packed array[] of ?;
- procedure _pac(var ad,zd:arrdescr; var zp:arr2; i:integer;
- var ap:arr1);
- procedure _unp(var ad,zd:arrdescr; i:integer; var ap:arr1;
- var zp:arr2;);
- function _asz(var dp:arrdescr):integer;
- procedure _ass(line:integer; b:boolean);
- procedure procentry(var name:alpha);
- procedure procexit(var name:alpha);
- const lowbyte=[0..7];
- MAGIC =[1,3,5,7];
- WINDOW =[11];
- ELNBIT =[12];
- EOFBIT =[13];
- TXTBIT =[14];
- WRBIT =[15];
- type file=record
- ptr: ^char;
- flags: set of [0..15];
- fname: string;
- ufd: 0..15;
- size: integer;
- count: 0..buflen;
- buflen: max(512,size) div size * size;
- bufadr: packed array[1..max(512,size)]
- of char;
- end;
- filep=^file;
- const NFILES=15;
- _extfl:^array[] of filep;
- procedure _ini(var args:integer; var hb:integer;
- var p:array[] of filep; var mainlb:integer);
- procedure _hlt(status:0..255);
- procedure _opn(size:integer; f:filep);
- procedure _cre(size:integer; f:filep);
- procedure _cls(f:filep);
- procedure _get(f:filep);
- procedure _put(f:filep);
- function _wdw(f:filep):^char;
- function _efl(f:filep):boolean;
- function _eln(f:filep):boolean;
- function _rdc(f:filep):char;
- function _rdi(f:filep):integer;
- function _rdl(f:filep):long;
- function _rdr(f:filep):real;
- procedure _rln(f:filep);
- procedure _wrc(c:char; f:filep);
- procedure _wsc(w:integer; c:char; f:filep);
- procedure _wri(i:integer; f:filep);
- procedure _wsi(w:integer; i:integer; f:filep);
- procedure _wrl(l:long; f:filep);
- procedure _wsl(w:integer; l:long; f:filep);
- procedure _wrr(r:real; f:filep);
- procedure _wsr(w:integer; r:real; f:filep);
- procedure _wrf(ndigit:integer; w:integer; r:real; f:filep);
- procedure _wrs(l:integer; s:pstring; f:filep);
- procedure _wss(w:integer; l:integer; s:pstring; f:filep);
- procedure _wrb(b:boolean; f:filep);
- procedure _wsb(w:integer; b:boolean; f:filep);
- procedure _wrz(s:string; f:filep);
- procedure _wsz(w:integer; s:string; f:filep);
- procedure _wln(f:filep);
- procedure _pag(f:filep);
- .fi
- .SH DESCRIPTION
- This library is used by the Pascal to EM compiler and
- contains all the runtime routines for standard Pascal programs.
- Most routines are written in C, a few in EM assembly language.
- These routines can be divided into several categories.
- A description of each category with its routines follows.
- .PP
- Arithmetic routines:
- .RS
- .IP _abi
- Compute the absolute value of an integer.
- .PD 0
- .IP _abl
- Compute the absolute value of a long.
- .IP _mdi
- Perform the Pascal modulo operation on integers.
- .IP _mdl
- Perform the Pascal modulo operation on longs.
- .IP _abr
- Compute the absolute value of a real.
- .IP _sin
- Compute the sine of a real.
- .IP _cos
- Compute the cosine of a real.
- .IP _atn
- Compute the arc tangent of a real.
- .IP _exp
- Compute the e-power of a real.
- .IP _log
- Compute the natural logarithm of a real.
- .IP _sqt
- Compute the square root of a real.
- .IP _rnd
- Return a real that when truncated will
- result in the nearest integer (-3.5->-4).
- .PD
- .PP
- .RE
- Miscellaneous routines:
- .RS
- .IP _bcp
- Compare two strings. Use dictionary ordering with the ASCII
- character set. The EM instruction CMU can not be used, because it needs
- an even number of bytes.
- .PD 0
- .IP _bts
- Include a range of elements from low to high in a set of size bytes
- at address base.(size can be divided by the wordsize)
- .IP _gto
- Execute a non-local goto. Lb points to the
- local base of the target procedure.
- A lb of zero indicates a jump to the program body, the lb of the main
- program is found in _m_lb, which is set by _ini.
- The new EM stack pointer is calculated by adding the number of locals
- to the new local base
- (jumping into statements is not allowed; there are no local generators
- in Pascal!).
- .PD
- .PP
- .RE
- Heap management:
- .RS
- .PP
- There is one way to allocate new heap space (_new), but two different
- incompatible ways to deallocate it.
- .PP
- The most general one is by using dispose (_dis).
- A circular list of free blocks, ordered from low to high addresses, is maintained.
- Merging free blocks is done when a new block enters the free list.
- When a new block is requested (_new), the free list is searched using a
- first fit algorithm.
- Two global variables are needed:
- .IP _highp 10
- Points to the free block with the highest address.
- .PD 0
- .IP _lastp
- Points to the most recently entered free block or to a block
- in the neighborhood of the most recently allocated block.
- .PD
- The free list is empty, when one of these pointers (but then at the same
- time both) is zero.
- .PP
- The second way to deallocate heap space is by using
- mark (_sav) and release (_rst). Mark saves the current value of the
- heap pointer HP in the program variable passed as a parameter.
- By calling release with this old HP value as its argument, the old HP value
- is restored, effectively deallocating all blocks requested between
- the calls to mark and release.
- The heap is used as second stack in this case.
- .PP
- It will be clear that these two ways of deallocating heap space
- can not be used together.
- To be able to maintain the free list, all blocks must be a multiple
- of n bytes long, with a minimum of n bytes,
- where n is the sum of the size of a word and a pointer in the
- EM implementation used.
- .PP
- In summary:
- .IP _new
- Allocate heap space.
- .PD 0
- .IP _dis
- Deallocate heap space.
- .IP _sav
- Save the current value of HP.
- .IP _rst
- Restore an old value of HP.
- .PD
- .PP
- .RE
- Array operations:
- .RS
- .PP
- The only useful form of packing implemented, is packing bytes into words.
- All other forms of packing and unpacking result in a plain copy.
- .IP _pac
- Pack an unpacked array \fIa\fP into a packed array \fIz\fP.
- \fIap\fP and \fIzp\fP
- are pointers to \fIa\fP and \fIz\fP. \fIad\fP and \fIzd\fP
- are pointers to the descriptors of \fIa\fP and \fIz\fP. \fIi\fP is
- the index in \fIa\fP of the first element to be packed.
- Pack until \fIz\fP is full.
- .PD 0
- .IP _unp
- Unpack \fIz\fP into \fIa\fP.
- \fIap\fP, \fIzp\fP, \fIad\fP and \fIzd\fP are as for _pac. \fIi\fP is
- the index in \fIa\fP where the first element of \fIz\fP is copied into.
- Unpack all elements of \fIz\fP.
- .IP _asz
- Compute array size. Used for copying conformant arrays.
- .PD
- .PP
- .RE
- Debugging facilities:
- .RS
- The compiler allows you to verify assertions.
- It generates a call to the routine _ass to check the assertion at runtime.
- Another feature of the compiler is that it enables you to trace the
- procedure calling sequence. If the correct option is turned on, then
- a call to the procedure \fIprocentry\fP is generated at the start of each
- compiled procedure or function. Likewise, the routine \fIprocexit\fP is called
- just before a procedure or function exits.
- Default procedure \fIprocentry\fP
- and \fIprocexit\fP are available in this library.
- .IP _ass 10
- If \fIb\fP is zero, then change eb[0] to \fIline\fP
- (to give an error message with source line number) and call the error routine.
- .PD 0
- .IP procentry
- Print the name of the called procedure with up to seven argument words
- in decimal on standard output. Output must be declared in the program heading.
- .IP procexit
- Print the name of the procedure that is about to exit.
- Same remarks as for procentry.
- .PD
- .PP
- .RE
- Files:
- .RS
- .PP
- Most of the runtime routines are needed for file handling.
- For each file in your Pascal program a record of type file, as described
- above, is allocated, static if your file is declared in the outermost block,
- dynamic if it is declared in inner blocks.
- The fields in the file record are used for:
- .IP bufadr 10
- IO is buffered except for standard input and output if
- terminals are involved. The size of the buffer is the maximum of 512
- and the file element size.
- .PD 0
- .IP buflen
- The effective buffer length is the maximum number of file elements
- fitting in the buffer, multiplied by the element size.
- .IP size
- The file element size (1 or even).
- .IP flags
- Some flag bits are stored in the high byte and a magic pattern
- in the low byte provides detection of destroyed file
- information.
- .IP ptr
- Points to the file window inside the buffer.
- .IP count
- The number of bytes (the window inclusive) left in the buffer
- to be read or the number of free bytes (the window inclusive) for output files.
- .IP ufd
- The UNIX file descriptor for the file.
- .IP fname
- Points to the name of the file (INPUT for standard input,
- OUTPUT for standard output and LOCAL for local files).
- This field is used for generating error messages.
- .PD
- .PP
- The constants used by the file handling routines are:
- .IP WINDOW 10
- Bit in flags set if the window of an input file is initialized.
- Used to resolve the famous interactive input problem.
- .PD 0
- .IP EOFBIT
- Bit in flags set if end of file seen
- .IP ELNBIT
- Bit in flags set if linefeed seen
- .IP TXTBIT
- Bit in flags set for text files. Process linefeeds.
- .IP WRBIT
- Bit in flags set for output files
- .IP MAGIC
- Pattern for the low byte of flags
- .IP NFILES
- The maximum number of open files in UNIX
- .PD
- .PP
- .RE
- Prelude and postlude:
- .RS
- .PP
- These routines are called once for each Pascal program:
- .IP _ini
- When a file mentioned in the program heading is opened by reset or
- rewrite, its file pointer must be mapped onto one of the program
- arguments.
- The compiler knows how to map and therefore builds a table with
- a pointer to the file structure for each program argument.
- One of the first actions of the Pascal program is to call this procedure
- with this table as an argument.
- The global variable _extfl is used to save the address of this table.
- Another task of _ini is to initialize the standard input and output files.
- For standard output it must decide whether to buffer or not.
- If standard output is a terminal, then buffering is off by setting
- buflen to 1.
- Two other task of _ini are the copying of two pointers from
- the argument list to global memory, mainlb to _m_lb and hb to _hbase.
- The first contains the local base of the program body, the second
- contains the address of the hol containing the global variables
- of the program.
- A last task of _ini is to set the global variables _argc, _argv and _environ
- from args for
- possible reference later on.
- Args points to the argument count placed on the stack by the EM runtime system,
- see chapter 8 in [1].
- .PD 0
- .IP _hlt
- If the program is about to finish, the buffered files must be flushed.
- That is done by this procedure.
- .PD
- .PP
- .RE
- Opening and closing:
- .RS
- .PP
- Files in Pascal are opened for reading by reset and opened for writing by
- rewrite.
- Files to be rewritten may or may not exist already.
- Files not mentioned in the program heading are considered local files.
- The next steps must be done for reset and rewrite:
- .IP 1.
- If size is zero, then a text file must be opened with elements of
- size 1.
- .PD 0
- .IP 2.
- Find out if this file is mentioned in the program heading
- (scan table pointed to by _extfl).
- If not, then it is a local file and goto 7.
- .IP 3.
- If the file is standard input or output then return.
- .IP 4.
- If there are not enough arguments supplied, generate an error.
- .IP 5.
- If the file was already open, flush the buffer if necessary and close it.
- Note that reset may be used to force the buffer to be flushed.
- This is sometimes helpful against program or system crashes.
- .IP 6.
- If it is a reset, open the file, otherwise create it.
- In both cases goto 9.
- .IP 7.
- If the local file is to be written, then close it if it was open and
- create a new nameless file. First try to create it in /usr/tmp, then in /tmp
- and if both fail then try the current directory.
- See to it that the file is open for both reading and writing.
- .IP 8.
- If the local file is to be read
- and the file is opened already, then
- flush the buffer and seek to the beginning.
- Otherwise open a temporary file as described in 7.
- .IP 9.
- Initialize all the file record fields.
- .PD
- .PP
- The necessary procedures are:
- .IP _opn
- Reset a file
- .PD 0
- .IP _cre
- Rewrite a file
- .IP _cls
- Close a file. Closing of files is done for local files when the procedure
- in which they are declared exits.
- The compiler only closes local files if they are not part of a structured type.
- Files allocated in the heap are not closed when they are deallocated.
- There is an external routine \fIpclose\fP in libP(VII), that may be called
- explicitly to do the closing in these cases.
- Closing may be necessary to flush buffers or to keep the number of
- simultaneously opened files below NFILES.
- Files declared in the outermost block are automatically closed when the
- program terminates.
- .PD
- .PP
- .RE
- General file IO:
- .RS
- .PP
- These routines are provided for general file IO:
- .IP _put
- Append the file element in the window to the file and advance the
- window.
- .IP _get
- Advance the file window so that it points to the next element
- of the file.
- For text files (TXTBIT on) the ELNBIT in flags is set if the new character
- in the window is a line feed (ASCII 10) and the character is then changed
- into a space.
- Otherwise the ELNBIT is cleared.
- .IP _wdw
- Return the current pointer to the file window.
- .IP _eof
- Test if you reached end of file.
- Is always true for output files.
- .PD
- .PP
- .RE
- Textfile routines:
- .RS
- .PP
- The rest of the routines all handle text files.
- .IP _eln
- Return true if the next character on an input file is an end-of-line marker.
- An error occurs if eof(f) is true.
- .PD 0
- .IP _rdc
- Return the character currently in the window and advance the window.
- .IP _rdi
- Build an integer from the next couple of characters on the file,
- starting with the character in the window.
- The integer may be preceded by spaces (and line feeds), tabs and a sign.
- There must be at least one digit.
- The first non-digit signals the end of the integer.
- .IP _rdl
- Like _rdi, but for longs.
- .IP _rdr
- Like _rdi, but for reals. Syntax is as required for Pascal.
- .IP _rln
- Skips the current line and clears the WINDOW flag, so that the
- next routine requiring an initialized window knows that it has to
- fetch the next character first.
- .IP _wrc
- Write a character, not preceeded by spaces.
- .IP _wsc
- Write a character, left padded with spaces up to a field width
- of \fIw\fP.
- .IP _wri
- Write an integer, left padded with spaces up to a field width
- of 6.
- .IP _wsi
- Write an integer, left padded with spaces up to a field width
- of \fIw\fP.
- .IP _wrl
- Write a long, left padded with spaces up to a field width
- of 11.
- .IP _wsl
- Write a long, left padded with spaces up to a field width
- of \fIw\fP.
- .IP _wrr
- Write a real in scientific format,
- left padded with spaces up to a field width of 13.
- .IP _wsr
- Write a real in scientific format,
- left padded with spaces up to a field width of \fIw\fP.
- .IP _wrf
- Write a real in fixed point format, with exactly \fIndigit\fP digits
- behind the decimal point, the last one rounded; it is left padded up to
- a field width of \fIw\fP.
- .IP _wrs
- Write a string of length \fIl\fP, without additional spaces.
- .IP _wss
- Write a string of length \fIl\fP, left padded up to a field
- width of \fIw\fP.
- .IP _wrb
- Write a boolean, represented by "true" or "false", left padded
- up to a field width of 5.
- .IP _wsb
- Write a boolean, represented by "true" or "false", left padded
- up to a field width of \fIw\fP.
- .IP _wrz
- Write a C-type string up to the zero-byte.
- .IP _wsz
- Write a C-type string, left padded up to a field width of w.
- .IP _wln
- Write a line feed (ASCII 10).
- .IP _pag
- Write a form feed (ASCII 12).
- .PD
- .PP
- .RE
- All the routines to which calls are generated by the compiler are described above.
- They use the following global defined routines to do some of the work:
- .IP _rf 10
- Check input files for MAGIC and WRBIT.
- Initialize the window if WINDOW is cleared.
- .PD 0
- .IP _wf
- Check output files for MAGIC and WRBIT.
- .IP _incpt
- Advance the file window and read a new buffer if necessary.
- .IP _outcpt
- Write out the current buffer if necessary and advance the window.
- .IP _flush
- Flush the buffer if it is an output file.
- Append an extra line marker if EOLBIT is off.
- .IP _wstrin
- All output routines make up a string in a local buffer.
- They call _wstrin to output this buffer and to do the left padding.
- .IP _skipsp
- Skip spaces (and line feeds) on input files.
- .IP _getsig
- Read '+' or '-' if present.
- .IP _fstdig
- See to it that the next character is a digit. Otherwise error.
- .IP _nxtdig
- Check if the next character is a digit.
- .IP _getint
- Do the work for _rdi.
- .IP _ecvt
- Convert real into string of digits for printout in scientific notation.
- .IP _fcvt
- Convert real into string of digits for fixed point printout
- .IP -fif
- Split real into integer and fraction part
- .IP _fef
- Split real into exponent and fraction part
- .PD
- .PP
- The following global variables are used:
- .IP _lastp 10
- For heap management (see above).
- .PD 0
- .IP _highp
- For heap management (see above).
- .IP _extfl
- Used to save the argument p of _ini for later reference.
- .IP _hbase
- Used to save the argument hb of _ini for later reference.
- .IP _m_lb
- Used to store the local base of the main program.
- .IP _curfil
- Save the current file pointer, so that the
- error message can access the file name.
- .IP "_pargc, _pargv, _penvp"
- Used to access the arguments of the main program.
- .PD
- .SH FILES
- .IP ~em/lib/*/tail_pc 20
- The library used by ack[5] to link programs.
- .IP ~em/etc/pc_rterrors
- The error messages
- .PD
- .SH "SEE ALSO"
- .IP [1]
- A.S. Tanenbaum, Ed Keizer, Hans van Staveren & J.W. Stevenson
- "Description of a machine architecture for use of
- block structured languages" Informatica rapport IR-81.
- .PD 0
- .IP [2]
- K.Jensen & N.Wirth
- "PASCAL, User Manual and Report" Springer-Verlag.
- .IP [3]
- An improved version of the ISO standard proposal for the language Pascal
- ISO/TC97/SC5-N462, received November 1979.
- .IP [4]
- Ed Keizer, "The Amsterdam Compiler Kit reference manual".
- .br
- (try \fInroff ~em/doc/pcref.doc\fP).
- .IP [5]
- ack(1), pc_pem(6)
- .PD
- .SH DIAGNOSTICS
- All errors discovered by this runtime system cause an EM TRP instruction
- to be executed. This TRP instruction expects the error number on top
- of the stack. See [1] for a more extensive treatment of the subject.
- .PP
- EM allows the user to specify a trap handling routine, called whenever
- an EM machine trap or a language or user defined trap occurs.
- One of the first actions in _ini is to specify that the routine _fatal,
- available in this library, will handle traps.
- This routine is called with an error code (0..252) as argument.
- The file "~em/etc/pc_rterrors" is opened and searched for a message
- corresponding with this number.
- If the file can not be opened, or if the error number is not recorded
- in the file, then the same trap is generated again, but without
- a user-defined trap handler, so that the low levels generate an
- error message.
- Otherwise the following information is printed
- on file descriptor 2:
- .IP -
- The name of the Pascal program
- .PD 0
- .IP -
- The name of the file pointed to by _curfil, if the error number
- is between 96 and 127 inclusive.
- .IP -
- The error message (or the error number if not found).
- .IP -
- The source line number if not equal to 0.
- .PD
- .PP
- The routine _fatal stops the program as soon as the message is printed.
- .PP
- The following error codes are used by the Pascal runtime system:
- .IP 64
- more args expected
- .PD 0
- .IP 65
- error in exp
- .IP 66
- error in ln
- .IP 67
- error in sqrt
- .IP 68
- assertion failed
- .IP 69
- array bound error in pack
- .IP 70
- array bound error in unpack
- .IP 71
- only positive j in \fIi mod j\fP
- .IP 72
- file not yet open
- .IP 73
- dispose error
- .sp
- .IP 96
- file xxx: not writable
- .IP 97
- file xxx: not readable
- .IP 98
- file xxx: end of file
- .IP 99
- file xxx: truncated
- .IP 100
- file xxx: reset error
- .IP 101
- file xxx: rewrite error
- .IP 102
- file xxx: close error
- .IP 103
- file xxx: read error
- .IP 104
- file xxx: write error
- .IP 105
- file xxx: digit expected
- .IP 106
- file xxx: non-ASCII char read
- .PD
- .PP
- .SH AUTHORS
- Johan Stevenson and Ard Verhoog, Vrije Universiteit.
|