Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / share / doc / papers / px / pxin2.n
1 .\" Copyright (c) 1979 The Regents of the University of California.
2 .\" All rights reserved.
3 .\"
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
6 .\" are met:
7 .\" 1. Redistributions of source code must retain the above copyright
8 .\"    notice, this list of conditions and the following disclaimer.
9 .\" 2. Redistributions in binary form must reproduce the above copyright
10 .\"    notice, this list of conditions and the following disclaimer in the
11 .\"    documentation and/or other materials provided with the distribution.
12 .\" 3. All advertising materials mentioning features or use of this software
13 .\"    must display the following acknowledgement:
14 .\"     This product includes software developed by the University of
15 .\"     California, Berkeley and its contributors.
16 .\" 4. Neither the name of the University nor the names of its contributors
17 .\"    may be used to endorse or promote products derived from this software
18 .\"    without specific prior written permission.
19 .\"
20 .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 .\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 .\" SUCH DAMAGE.
31 .\"
32 .\"     @(#)pxin2.n     5.2 (Berkeley) 4/17/91
33 .\" $FreeBSD: src/share/doc/papers/px/pxin2.n,v 1.1.1.1.14.1 2000/11/30 17:13:59 ru Exp $
34 .\" $DragonFly: src/share/doc/papers/px/pxin2.n,v 1.2 2003/06/17 04:36:56 dillon Exp $
35 .\"
36 .nr H1 1
37 .if n .ND
38 .NH
39 Operations
40 .NH 2
41 Naming conventions and operation summary
42 .PP
43 Table 2.1 outlines the opcode typing convention.
44 The expression ``a above b'' means that `a' is on top
45 of the stack with `b' below it.
46 Table 2.3 describes each of the opcodes.
47 The character `*' at the end of a name specifies that
48 all operations with the root prefix 
49 before the `*'
50 are summarized by one entry.
51 Table 2.2 gives the codes used 
52 to describe the type inline data expected by each instruction.
53 .sp 2
54 .so table2.1.n
55 .sp 2
56 .so table2.2.n
57 .bp
58 .so table2.3.n
59 .bp
60 .NH 2
61 Basic control operations
62 .LP
63 .SH
64 HALT
65 .IP
66 Corresponds to the Pascal procedure
67 .I halt ;
68 causes execution to end with a post-mortem backtrace as if a run-time
69 error had occurred.
70 .SH
71 BEG s,W,w,"
72 .IP
73 Causes the second part of the block mark to be created, and
74 .I W
75 bytes of local variable space to be allocated and cleared to zero.
76 Stack overflow is detected here.
77 .I w
78 is the first line of the body of this section for error traceback,
79 and the inline string (length s) the character representation of its name.
80 .SH
81 NODUMP s,W,w,"
82 .IP
83 Equivalent to
84 .SM BEG ,
85 and used to begin the main program when the ``p''
86 option is disabled so that the post-mortem backtrace will be inhibited.
87 .SH
88 END
89 .IP
90 Complementary to the operators
91 .SM CALL
92 and
93 .SM BEG ,
94 exits the current block, calling the procedure
95 .I pclose
96 to flush buffers for and release any local files.
97 Restores the environment of the caller from the block mark.
98 If this is the end for the main program, all files are
99 .I flushed,
100 and the interpreter is exited.
101 .SH
102 CALL l,A
103 .IP
104 Saves the current line number, return address, and active display entry pointer
105 .I dp
106 in the first part of the block mark, then transfers to the entry point
107 given by the relative address
108 .I A ,
109 that is the beginning of a
110 .B procedure
111 or
112 .B function
113 at level
114 .I l.
115 .SH
116 PUSH s
117 .IP
118 Clears
119 .I s
120 bytes on the stack.
121 Used to make space for the return value of a
122 .B function
123 just before calling it.
124 .SH
125 POP s
126 .IP
127 Pop
128 .I s
129 bytes off the stack.
130 Used after a
131 .B function
132 or
133 .B procedure
134 returns to remove the arguments from the stack.
135 .SH
136 TRA a
137 .IP
138 Transfer control to relative address
139 .I a
140 as a local
141 .B goto
142 or part of a structured statement.
143 .SH
144 TRA4 A
145 .IP
146 Transfer control to an absolute address as part of a non-local
147 .B goto
148 or to branch over procedure bodies.
149 .SH
150 LINO s
151 .IP
152 Set current line number to
153 .I s.
154 For consistency, check that the expression stack is empty
155 as it should be (as this is the start of a statement.)
156 This consistency check will fail only if there is a bug in the
157 interpreter or the interpreter code has somehow been damaged.
158 Increment the statement count and if it exceeds the statement limit,
159 generate a fault.
160 .SH
161 GOTO l,A
162 .IP
163 Transfer control to address
164 .I A
165 that is in the block at level
166 .I l
167 of the display.
168 This is a non-local
169 .B goto.
170 Causes each block to be exited as if with
171 .SM END ,
172 flushing and freeing files with
173 .I pclose,
174 until the current display entry is at level
175 .I l.
176 .SH
177 SDUP*
178 .IP
179 Duplicate the word or long on the top of
180 the stack.
181 This is used mostly for constructing sets.
182 See section 2.11.
183 .NH 2
184 If and relational operators
185 .SH
186 IF a
187 .IP
188 The interpreter conditional transfers all take place using this operator
189 that examines the Boolean value on the top of the stack.
190 If the value is
191 .I true ,
192 the next code is executed,
193 otherwise control transfers to the specified address.
194 .SH
195 REL* r
196 .IP
197 These take two arguments on the stack,
198 and the sub-operation code specifies the relational operation to
199 be done, coded as follows with `a' above `b' on the stack:
200 .DS
201 .mD
202 .TS
203 lb lb
204 c a.
205 Code    Operation
206 _
207 0       a = b
208 2       a <> b
209 4       a < b
210 6       a > b
211 8       a <= b
212 10      a >= b
213 .TE
214 .DE
215 .IP
216 Each operation does a test to set the condition code
217 appropriately and then does an indexed branch based on the
218 sub-operation code to a test of the condition here specified,
219 pushing a Boolean value on the stack.
220 .IP
221 Consider the statement fragment:
222 .DS
223 .mD
224 \*bif\fR a = b \*bthen\fR
225 .DE
226 .IP
227 If
228 .I a
229 and
230 .I b
231 are integers this generates the following code:
232 .DS
233 .TS
234 lp-2w(8) l.
235 RV4:\fIl        a\fR
236 RV4:\fIl        b\fR
237 REL4    \&=
238 IF      \fIElse part offset\fR
239 .sp
240 .T&
241 c s.
242 \fI\&... Then part code ...\fR
243 .TE
244 .DE
245 .NH 2
246 Boolean operators
247 .PP
248 The Boolean operators
249 .SM AND ,
250 .SM OR ,
251 and
252 .SM NOT
253 manipulate values on the top of the stack.
254 All Boolean values are kept in single bytes in memory,
255 or in single words on the stack.
256 Zero represents a Boolean \fIfalse\fP, and one a Boolean \fItrue\fP.
257 .NH 2
258 Right value, constant, and assignment operators
259 .SH
260 LRV* l,A
261 .br
262 RV* l,a
263 .IP
264 The right value operators load values on the stack.
265 They take a block number as a sub-opcode and load the appropriate
266 number of bytes from that block at the offset specified
267 in the following word onto the stack. As an example, consider
268 .SM LRV4 :
269 .DS
270 .mD
271 _LRV4:
272         \fBcvtbl\fR     (lc)+,r0        #r0 has display index
273         \fBaddl3\fR     _display(r0),(lc)+,r1   #r1 has variable address
274         \fBpushl\fR     (r1)    #put value on the stack
275         \fBjmp\fR       (loop)
276 .DE
277 .IP
278 Here the interpreter places the display level in r0.
279 It then adds the appropriate display value to the inline offset and
280 pushes the value at this location onto the stack.
281 Control then returns to the main
282 interpreter loop.
283 The
284 .SM RV* 
285 operators have short inline data that
286 reduces the space required to address the first 32K of
287 stack space in each stack frame.
288 The operators
289 .SM RV14
290 and
291 .SM RV24
292 provide explicit conversion to long as the data
293 is pushed.
294 This saves the generation of
295 .SM STOI
296 to align arguments to 
297 .SM C
298 subroutines.
299 .SH
300 CON* r
301 .IP
302 The constant operators load a value onto the stack from inline code.
303 Small integer values are condensed and loaded by the
304 .SM CON1
305 operator, that is given by
306 .DS
307 .mD
308 _CON1:
309         \fBcvtbw\fR     (lc)+,\-(sp)
310         \fBjmp\fR       (loop)
311 .DE
312 .IP
313 Here note that little work was required as the required constant
314 was available at (lc)+.
315 For longer constants,
316 .I lc
317 must be incremented before moving the constant.
318 The operator
319 .SM CON
320 takes a length specification in the sub-opcode and can be used to load
321 strings and other variable length data onto the stack.
322 The operators 
323 .SM CON14
324 and
325 .SM CON24
326 provide explicit conversion to long as the constant is pushed.
327 .SH
328 AS*
329 .IP
330 The assignment operators are similar to arithmetic and relational operators
331 in that they take two operands, both in the stack,
332 but the lengths given for them specify
333 first the length of the value on the stack and then the length
334 of the target in memory.
335 The target address in memory is under the value to be stored.
336 Thus the statement
337 .DS
338 i := 1
339 .DE
340 .IP
341 where
342 .I i
343 is a full-length, 4 byte, integer,
344 will generate the code sequence
345 .DS
346 .TS
347 lp-2w(8) l.
348 LV:\fIl i\fP
349 CON1:1
350 AS24
351 .TE
352 .DE
353 .IP
354 Here
355 .SM LV
356 will load the address of
357 .I i,
358 that is really given as a block number in the sub-opcode and an
359 offset in the following word,
360 onto the stack, occupying a single word.
361 .SM CON1 ,
362 that is a single word instruction,
363 then loads the constant 1,
364 that is in its sub-opcode,
365 onto the stack.
366 Since there are not one byte constants on the stack,
367 this becomes a 2 byte, single word integer.
368 The interpreter then assigns a length 2 integer to a length 4 integer using
369 .SM AS24 \&.
370 The code sequence for
371 .SM AS24
372 is given by:
373 .DS
374 .mD
375 _AS24:
376         \fBincl\fR      lc
377         \fBcvtwl\fR     (sp)+,*(sp)+
378         \fBjmp\fR       (loop)
379 .DE
380 .IP
381 Thus the interpreter gets the single word off the stack,
382 extends it to be a 4 byte integer
383 gets the target address off the stack,
384 and finally stores the value in the target.
385 This is a typical use of the constant and assignment operators.
386 .NH 2
387 Addressing operations
388 .SH
389 LLV l,W
390 .br
391 LV l,w
392 .IP
393 The most common operation done by the interpreter
394 is the ``left value'' or ``address of'' operation.
395 It is given by:
396 .DS
397 .mD
398 _LLV:
399         \fBcvtbl\fR     (lc)+,r0        #r0 has display index
400         \fBaddl3\fR     _display(r0),(lc)+,\-(sp)       #push address onto the stack
401         \fBjmp\fR       (loop)
402 .DE
403 .IP
404 It calculates an address in the block specified in the sub-opcode
405 by adding the associated display entry to the
406 offset that appears in the following word.
407 The
408 .SM LV
409 operator has a short inline data that reduces the space
410 required to address the first 32K of stack space in each call frame.
411 .SH
412 OFF s
413 .IP
414 The offset operator is used in field names.
415 Thus to get the address of
416 .LS
417 p^.f1
418 .LE
419 .IP
420 .I pi
421 would generate the sequence
422 .DS
423 .mD
424 .TS
425 lp-2w(8) l.
426 RV:\fIl p\fP
427 OFF     \fIf1\fP
428 .TE
429 .DE
430 .IP
431 where the
432 .SM RV
433 loads the value of
434 .I p,
435 given its block in the sub-opcode and offset in the following word,
436 and the interpreter then adds the offset of the field
437 .I f1
438 in its record to get the correct address.
439 .SM OFF
440 takes its argument in the sub-opcode if it is small enough.
441 .SH
442 NIL
443 .IP
444 The example above is incomplete, lacking a check for a
445 .B nil
446 pointer.
447 The code generated would be
448 .DS
449 .TS
450 lp-2w(8) l.
451 RV:\fIl p\fP
452 NIL
453 OFF     \fIf1\fP
454 .TE
455 .DE
456 .IP
457 where the
458 .SM NIL
459 operation checks for a
460 .I nil
461 pointer and generates the appropriate runtime error if it is.
462 .SH
463 LVCON s,"
464 .IP
465 A pointer to the specified length inline data is pushed
466 onto the stack.
467 This is primarily used for
468 .I printf
469 type strings used by 
470 .SM WRITEF .
471 (see sections 3.6 and 3.8)
472 .SH
473 INX* s,w,w
474 .IP
475 The operators
476 .SM INX2
477 and
478 .SM INX4
479 are used for subscripting.
480 For example, the statement
481 .DS
482 a[i] := 2.0
483 .DE
484 .IP
485 with
486 .I i
487 an integer and
488 .I a
489 an
490 ``array [1..1000] of real''
491 would generate
492 .DS
493 .TS
494 lp-2w(8) l.
495 LV:\fIl a\fP
496 RV4:\fIl        i\fP
497 INX4:8  1,999
498 CON8    2.0
499 AS8
500 .TE
501 .DE
502 .IP
503 Here the
504 .SM LV
505 operation takes the address of
506 .I a
507 and places it on the stack.
508 The value of
509 .I i
510 is then placed on top of this on the stack.
511 The array address is indexed by the
512 length 4 index (a length 2 index would use
513 .SM INX2 )
514 where the individual elements have a size of 8 bytes.
515 The code for 
516 .SM INX4
517 is:
518 .DS
519 .mD
520 _INX4:
521         \fBcvtbl\fR     (lc)+,r0
522         \fBbneq\fR      L1
523         \fBcvtwl\fR     (lc)+,r0        #r0 has size of records
524 L1:
525         \fBcvtwl\fR     (lc)+,r1        #r1 has lower bound
526         \fBmovzwl\fR    (lc)+,r2        #r2 has upper-lower bound
527         \fBsubl3\fR     r1,(sp)+,r3     #r3 has base subscript
528         \fBcmpl\fR      r3,r2   #check for out of bounds
529         \fBbgtru\fR     esubscr
530         \fBmull2\fR     r0,r3   #calculate byte offset
531         \fBaddl2\fR     r3,(sp)         #calculate actual address
532         \fBjmp\fR       (loop)
533 esubscr:
534         \fBmovw\fR      $ESUBSCR,_perrno
535         \fBjbr\fR       error
536 .DE
537 .IP
538 Here the lower bound is subtracted, and range checked against the
539 upper minus lower bound.
540 The offset is then scaled to a byte offset into the array
541 and added to the base address on the stack.
542 Multi-dimension subscripts are translated as a sequence of single subscriptings.
543 .SH
544 IND*
545 .IP
546 For indirect references through
547 .B var
548 parameters and pointers,
549 the interpreter has a set of indirection operators that convert a pointer
550 on the stack into a value on the stack from that address.
551 different
552 .SM IND
553 operators are necessary because of the possibility of different
554 length operands.
555 The
556 .SM IND14
557 and
558 .SM IND24
559 operators do conversions to long
560 as they push their data.
561 .NH 2
562 Arithmetic operators
563 .PP
564 The interpreter has many arithmetic operators.
565 All operators produce results long enough to prevent overflow
566 unless the bounds of the base type are exceeded.
567 The basic operators available are
568 .DS
569 Addition:       ADD*, SUCC*
570 Subtraction:    SUB*, PRED*
571 Multiplication: MUL*, SQR*
572 Division:       DIV*, DVD*, MOD*
573 Unary:          NEG*, ABS*
574 .DE
575 .NH 2
576 Range checking
577 .PP
578 The interpreter has several range checking operators.
579 The important distinction among these operators is between values whose
580 legal range begins at zero and those that do not begin at zero, 
581 for example
582 a subrange variable whose values range from 45 to 70.
583 For those that begin at zero, a simpler ``logical'' comparison against
584 the upper bound suffices.
585 For others, both the low and upper bounds must be checked independently,
586 requiring two comparisons.
587 On the 
588 .SM "VAX 11/780"
589 both checks are done using a single index instruction
590 so the only gain is in reducing the inline data.
591 .NH 2
592 Case operators
593 .PP
594 The interpreter includes three operators for
595 .B case
596 statements that are used depending on the width of the 
597 .B case
598 label type.
599 For each width, the structure of the case data is the same, and
600 is represented in figure 2.4.
601 .sp 1
602 .so fig2.4.n
603 .PP
604 The
605 .SM CASEOP
606 case statement operators do a sequential search through the
607 case label values.
608 If they find the label value, they take the corresponding entry
609 from the transfer table and cause the interpreter to branch to the
610 specified statement.
611 If the specified label is not found, an error results.
612 .PP
613 The
614 .SM CASE
615 operators take the number of cases as a sub-opcode
616 if possible.
617 Three different operators are needed to handle single byte,
618 word, and long case transfer table values.
619 For example, the
620 .SM CASEOP1
621 operator has the following code sequence:
622 .DS
623 .mD
624 _CASEOP1:
625         \fBcvtbl\fR     (lc)+,r0
626         \fBbneq\fR      L1
627         \fBcvtwl\fR     (lc)+,r0        #r0 has length of case table
628 L1:
629         \fBmovaw\fR     (lc)[r0],r2     #r2 has pointer to case labels
630         \fBmovzwl\fR    (sp)+,r3        #r3 has the element to find
631         \fBlocc\fR      r3,r0,(r2)      #r0 has index of located element
632         \fBbeql\fR      caserr  #element not found
633         \fBmnegl\fR     r0,r0   #calculate new lc
634         \fBcvtwl\fR     (r2)[r0],r1     #r1 has lc offset
635         \fBaddl2\fR     r1,lc
636         \fBjmp\fR       (loop)
637 caserr:
638         \fBmovw\fR      $ECASE,_perrno
639         \fBjbr\fR       error
640 .DE
641 .PP
642 Here the interpreter first computes the address of the beginning
643 of the case label value area by adding twice the number of case label
644 values to the address of the transfer table, since the transfer
645 table entries are 2 byte address offsets.
646 It then searches through the label values, and generates an ECASE
647 error if the label is not found.
648 If the label is found, the index of the corresponding entry
649 in the transfer table is extracted and that offset is added
650 to the interpreter location counter.
651 .NH 2
652 Operations supporting pxp
653 .PP
654 The following operations are defined to do execution profiling.
655 .SH
656 PXPBUF w
657 .IP
658 Causes the interpreter to allocate a count buffer
659 with
660 .I w
661 four byte counters
662 and to clear them to zero.
663 The count buffer is placed within an image of the
664 .I pmon.out
665 file as described in the
666 .I "PXP Implementation Notes."
667 The contents of this buffer are written to the file
668 .I pmon.out
669 when the program ends.
670 .SH
671 COUNT w
672 .IP
673 Increments the counter specified by
674 .I w .
675 .SH
676 TRACNT w,A
677 .IP
678 Used at the entry point to procedures and functions,
679 combining a transfer to the entry point of the block with
680 an incrementing of its entry count.
681 .NH 2
682 Set operations
683 .PP
684 The set operations:
685 union
686 .SM ADDT,
687 intersection
688 .SM MULT,
689 element removal
690 .SM SUBT,
691 and the set relationals
692 .SM RELT
693 are straightforward.
694 The following operations are more interesting.
695 .SH
696 CARD s
697 .IP
698 Takes the cardinality of a set of size
699 .I s
700 bytes on top of the stack, leaving a 2 byte integer count.
701 .SM CARD
702 uses the 
703 .B ffs
704 opcode to successively count the number of set bits in the set.
705 .SH
706 CTTOT s,w,w
707 .IP
708 Constructs a set.
709 This operation requires a non-trivial amount of work,
710 checking bounds and setting individual bits or ranges of bits.
711 This operation sequence is slow,
712 and motivates the presence of the operator
713 .SM INCT
714 below.
715 The arguments to
716 .SM CTTOT
717 include the number of elements
718 .I s
719 in the constructed set,
720 the lower and upper bounds of the set,
721 the two
722 .I w
723 values,
724 and a pair of values on the stack for each range in the set, single
725 elements in constructed sets being duplicated with
726 .SM SDUP
727 to form degenerate ranges.
728 .SH
729 IN s,w,w
730 .IP
731 The operator
732 .B in
733 for sets.
734 The value
735 .I s
736 specifies the size of the set,
737 the two
738 .I w
739 values the lower and upper bounds of the set.
740 The value on the stack is checked to be in the set on the stack,
741 and a Boolean value of
742 .I true
743 or
744 .I false
745 replaces the operands.
746 .SH
747 INCT
748 .IP
749 The operator
750 .B in
751 on a constructed set without constructing it.
752 The left operand of
753 .B in
754 is on top of the stack followed by the number of pairs in the
755 constructed set,
756 and then the pairs themselves, all as single word integers.
757 Pairs designate runs of values and single values are represented by
758 a degenerate pair with both value equal.
759 This operator is generated in grammatical constructs such as
760 .LS
761 \fBif\fR character \fBin\fR [`+', '\-', `*', `/']
762 .LE
763 .IP
764 or
765 .LS
766 \fBif\fR character \fBin\fR [`a'..`z', `$', `_']
767 .LE
768 .IP
769 These constructs are common in Pascal, and
770 .SM INCT
771 makes them run much faster in the interpreter,
772 as if they were written as an efficient series of
773 .B if
774 statements.
775 .NH 2
776 Miscellaneous
777 .PP
778 Other miscellaneous operators that are present in the interpreter
779 are
780 .SM ASRT
781 that causes the program to end if the Boolean value on the stack is not
782 .I true,
783 and
784 .SM STOI ,
785 .SM STOD ,
786 .SM ITOD ,
787 and
788 .SM ITOS
789 that convert between different length arithmetic operands for
790 use in aligning the arguments in
791 .B procedure
792 and
793 .B function
794 calls, and with some untyped built-ins, such as
795 .SM SIN
796 and
797 .SM COS \&.
798 .PP
799 Finally, if the program is run with the run-time testing disabled, there
800 are special operators for
801 .B for
802 statements
803 and special indexing operators for arrays
804 that have individual element size that is a power of 2.
805 The code can run significantly faster using these operators.
806 .NH 2
807 Mathematical Functions
808 .PP
809 The transcendental functions 
810 .SM SIN ,
811 .SM COS ,
812 .SM ATAN ,
813 .SM EXP ,
814 .SM LN ,
815 .SM SQRT ,
816 .SM SEED ,
817 and
818 .SM RANDOM
819 are taken from the standard UNIX
820 mathematical package.
821 These functions take double precision floating point
822 values and return the same.
823 .PP
824 The functions
825 .SM EXPO ,
826 .SM TRUNC ,
827 and
828 .SM ROUND
829 take a double precision floating point number.
830 .SM EXPO
831 returns an integer representing the machine 
832 representation of its argument's exponent,
833 .SM TRUNC
834 returns the integer part of its argument, and
835 .SM ROUND
836 returns the rounded integer part of its argument.
837 .NH 2
838 System functions and procedures
839 .SH
840 LLIMIT
841 .IP
842 A line limit and a file pointer are passed on the stack.
843 If the limit is non-negative the line limit is set to the
844 specified value, otherwise it is set to unlimited.
845 The default is unlimited.
846 .SH
847 STLIM
848 .IP
849 A statement limit is passed on the stack. The statement limit 
850 is set as specified.
851 The default is 500,000.
852 No limit is enforced when the ``p'' option is disabled.
853 .SH
854 CLCK
855 .br
856 SCLCK
857 .IP
858 .SM CLCK
859 returns the number of milliseconds of user time used by the program;
860 .SM SCLCK
861 returns the number of milliseconds of system time used by the program.
862 .SH
863 WCLCK
864 .IP
865 The number of seconds since some predefined time is
866 returned. Its primary usefulness is in determining
867 elapsed time and in providing a unique time stamp.
868 .sp
869 .LP
870 The other system time procedures are
871 .SM DATE
872 and
873 .SM TIME
874 that copy an appropriate text string into a pascal string array.
875 The function
876 .SM ARGC
877 returns the number of command line arguments passed to the program.
878 The procedure
879 .SM ARGV
880 takes an index on the stack and copies the specified
881 command line argument into a pascal string array.
882 .NH 2
883 Pascal procedures and functions
884 .SH
885 PACK s,w,w,w
886 .br
887 UNPACK s,w,w,w
888 .IP
889 They function as a memory to memory move with several
890 semantic checks. 
891 They do no ``unpacking'' or ``packing'' in the true sense as the
892 interpreter supports no packed data types.
893 .SH
894 NEW s
895 .br
896 DISPOSE s
897 .IP
898 An 
899 .SM LV
900 of a pointer is passed. 
901 .SM NEW
902 allocates a record of a specified size and puts a pointer
903 to it into the pointer variable.
904 .SM DISPOSE
905 deallocates the record pointed to by the pointer
906 and sets the pointer to 
907 .SM NIL .
908 .sp
909 .LP
910 The function
911 .SM CHR*
912 converts a suitably small integer into an ascii character.
913 Its primary purpose is to do a range check.
914 The function
915 .SM ODD*
916 returns 
917 .I true
918 if its argument is odd and returns
919 .I false
920 if its argument is even.
921 The function 
922 .SM UNDEF
923 always returns the value
924 .I false .