% util.jam
% last changed by Stone&Paxton, March 28, 1983 3:45 pm
% last changed by Doug Wyatt, 5-Oct-81 19:13:54
($help) .dup .where {.pop .pop} {100 .dict .def} .ifelse .cvx .exec
(/def)
{3 .copy .exch .pop .def .pop $help 3 1 .roll .put} .cvx .def
(/xdef)
{3 .copy .exch .pop .cvx .def .pop $help 3 1 .roll .put} .cvx .def
(/def)
("/def" accepts three entries on the stack: a key, string, and value.
the string is stored under the key in the $help dictionary, and
the value is stored as a noun under the key in the current dictionary.)
(/def).load /def
(/xdef)
("/xdef" accepts three entries on the stack: a key, string, and value.
the string is stored under the key in the $help dictionary, and
the value is stored as a verb under the key in the current dictionary.)
(/xdef).load /xdef
(?)
("?" prints the explanation of the given key from the $help dictionary)
{$help .exch .get =}/xdef
(??)
("??" prints the names of all the utility commands found in the $help
dictionary.)
{$help /kdir}/xdef
(/print)
("/print" prints the top of the stack)
{( ).cvis .print}/xdef
(/lp)
("/lp" prints a left parenthesis)
{(())0 1 .substring .print}/xdef
(/rp)
("/rp" prints a right parenthesis)
{(())1 1 .substring .print}/xdef
(/cr)
("/cr" prints a carriage return)
{(
).print}/xdef
(=)
("=" prints the top of the stack and a carriage return)
{/print /cr}/xdef
(/stk)
("/stk" prints (without destroying) the contents of the operand stack.)
{.cntstk .dup 1 .add .copy
{.dup .type /print ( ).print =}.cvx .rept .pop}/xdef
(/pstk)
("/pstk" pretty prints (without destroying) the contents of the operand stack.)
{.cntstk .dup 1 .add .copy
(:tab)(:indent).lvknown {:indent}{0}/ifelse .lv {pprint} .cvx .rept .pop}/xdef
(/clr)
("/clr" clears the operand stack (same as .clrstk))
{.clrstk} /xdef
(/dir)
("/dir" prints the contents of the dictionary on top of the operand stack.)
{{.exch /print ( ).print .dup .type .print
( ).print =}.cvx .dictforall}/xdef
(/kdir)
("/kdir" prints the keys found in the dictionary on the top of the operand
stack.)
((.exch = .pop) .cvx .dictforall)/xdef
(/if)
("/if" is equivalent to ".cvx .if")
{.cvx .if}/xdef
(/ifelse)
("/ifelse" is equivalent to ".ifelse .cvx .exec")
{.ifelse .cvx .exec}/xdef
([)
("[" is a command that marks the operand stack for use by the command "]".
This pair of commands is use to create arrays. For example:
[ 1 2 (hello) ]
will create an array containing two integers (1 and 2) and the string
"hello".)
{.mark}/xdef
(])
("]" is a command that counts the elements after the mark on the stack and
puts these elements into an array which is left on the stack.
The pair of commands ( "[" and "]" ) is use to create arrays. For example:
[ 1 2 (hello) ]
will create an array containing two integers (1 and 2) and the string
"hello".)
{.cnttomrk .array .astore .exch .pop}/xdef
(/run){(Running ).print .dup .print .run (.)=}.cvx .def
(/loadbcd){(Loading ).print .dup .print .loadbcd (.)=}.cvx .def
(==)
(== is used to print all types of objects in a manner which can easily be
read. The object to be printed is expected on the operand stack.
<x> == => -- )
{(:tab) 0 .lv pprint}/xdef
(pprint)
(pprint supports == and does all the printing)
{tabprint .dup .type .dup /print ( )/print $ptypes .exch .get .exec}/xdef
($ptypes) .dup .where {.pop .pop} {15 .dict .def} /ifelse
$ptypes .begin
(.nulltype) {.pop /cr}.cvx .def
(.integertype){=}.cvx .def
(.realtype) {=}.cvx .def
(.booleantype){=}.cvx .def
(.nametype) {=}.cvx .def
(.stringtype) {/lp .print /rp /cr}.cvx .def
(.streamtype) {.pop /cr}.cvx .def
(.commandtype){.commandname =}.cvx .def
(.dicttype) {(length )/print .dup .length /print (, maxlength )/print .maxlength =}.cvx .def
(.arraytype) {(length )/print .dup .length = tabinc {pprint}.cvx .arrayforall tabdec}.cvx .def
(.marktype) {.pop /cr}.cvx .def
(.exectype) {.pop /cr}.cvx .def
(.looptype) {.pop /cr}.cvx .def
(.scopetype) {.scopename =}.cvx .def
.end
(tabinc){(:tab) :tab 1 .add .lvstore}.cvx .def
(tabprint){:tab {( )/print}.cvx .rept}.cvx .def
(tabdec){(:tab) :tab 1 .sub .lvstore}.cvx .def