(JaM Utilities of September 9, 1980  5:19 PM
).print

($help) .sysdict ($help) .known (.pop) .cvx (100 .dict .def) .cvx .ifelse

(/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

(=)
("="	prints the top of the stack on the default display followed by CR)
((                    ).cvis .print (
).print)/xdef

(:)
(":"	prints the top of the stack on the default display followed by SP)
((                    ).cvis .print ( ).print)/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

(/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 (                    ) .cvis .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


(/ifx)
("/ifx" is equivalent to ".cvx .if")
(.cvx .if)/xdef

(/ifelsex)
("/ifelsex" 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


(/compile)
("/compile"	transforms the string on the top of the operand stack into an
array.  This array is returned (unexecutable) on the operand stack. Note:
only one level of binding is done on the string.)
(.dup /cnttoken .array /cmpstrngarray)/xdef

(/cnttoken)
("/cnttoken" counts the number of tokens in a given string or stream and
leaves the value on the stack.
		<s>/cnttoken => <n>)
(0 .exch (.token (.pop .exch 1 .add .exch)(.exit)/ifelsex).cvx .loop)/xdef

(/cmpstrngarray)
("/cmpstrngarray" compiles a given string or stream into a given array.
		<s><a>/cmpstrngarray => <a>)
( (!a) .exch .def (!i) 0 .def (/cvtoken !a !i 3 2 .roll .aput (!i) .dup .load 1 .add .store) .cvx /tokall !a)/xdef

(/cvtoken)
("/cvtoken"	determines if a token is an identifier and loads the value from the current context. If the value is a commandtype, then the identifier is replaced with its value.
		<t> /cvtoken => <t> if not command
				<c> if t is a command)
(.dup .type (.stringtype) .eq (.dup .litchk (.executable) .eq
(.dup .load .dup .type (.commandtype) .eq (.exch .pop)(.pop) /ifelsex) /ifx) /ifx) /xdef

(/tokall)
("/tokall"  executes the object on top of the operand stack for each token in the string or stream that is next on stack.
		<s><o> /tokall)
((!x).exch .def (!s) .exch .cvlit .def (!s .token (.exch (!s) .exch .def !x )(
.exit).ifelse .cvx .exec ).cvx .loop)/xdef

(/edit)
("/edit" lists the definition in a form suitable for redefinition after editing
 e.g. (procname)/edit
)
( /lp .print .dup .print /rp .print /lp .print .load .print /rp .print (.cvx .def
).print).cvx /def

(/lp)(()) 0 1 .substring .def
(/rp)(()) 1 1 .substring .def
(/cr)(
) .def

(/writedef)
("/writedef" writes the definition on a stream in a form suitable for reading
 e.g. outstream (procname)/writedef
)
(.dup .load .dup .type (.stringtype) .eq
   (3 .copy .pop .pop
    .dup /lp .writebytes .dup 4 -1 .roll .writebytes
    .dup /rp  .writebytes .dup (
) .writebytes .dup /lp .writebytes
    2 .copy .exch .writebytes .dup /rp .writebytes
    .pop .litchk .not
      (.dup (.cvx ) .writebytes).cvx
    .if
    (.def

).writebytes).cvx
   (.pop .pop .pop).cvx
 .ifelse
).cvx /def

(/filout)
("/filout" writes all definitions in a given dictionary in a form suitable for reading
 e.g. dict (filename) /filout
)
(6 .bytestream .exch
 .dup .begin
 (.pop 2 .copy .pop .exch /writedef).cvx .dictforall
 .killstream .end
).cvx /def

(/lp)(()) 0 1 .substring .def
(/rp)(()) 1 1 .substring .def
(/cr)(
) .def

(/list)
("/list" lists a file, e.g. (file.name) /list
)
(1 .bytestream
  ( .dup .readline
      (.print (
).print).cvx
      (.pop .exit).cvx
    .ifelse
  ).cvx .loop
).cvx /def

(/type)
("/type" types the element on the top of the stack
 Arrays have their individual elements typed, the level
  of nesting being indicated by the number of '='s preceeding
  each element
)
( (indent) 0 .def
  dotype
).cvx /def

(dotype)
( (indent) indent 1 .add .def
 .dup .type (.arraytype) .eq
  (.dup .length 1 .sub 0 .exch 1 .exch
    (.exch .dup 3 -1 .roll .aget dotype).cvx
   .for
  .pop).cvx
  (indent((=).print).cvx .rept =).cvx
 .ifelse
 (indent) indent 1 .sub .def
 ).cvx .def

(/fed)(.exch .def).cvx .def

(/concat)
(concatenate two strings)
(2 .copy .length .exch .length
 .dup 4 1 .roll
 .add .string
 0 5 -1 .roll .putstring
 3 1 .roll .putstring
).cvx /def

(/ndir)
(list nested dictionary)
( (indent) 0 .def
  /dondir
).cvx /def

(/dondir)
(supports /ndir)
( (indent) indent 1 .add .def
 .dup .type (.dicttype) .eq
  ((
).print (indent((=).print).cvx .rept .exch (                    ) .cvis .print ( ).print /dondir).cvx .dictforall).cvx
  (=).cvx
 .ifelse
 (indent) indent 1 .sub .def
 ).cvx /def

(/print)
(like .print but appends cr
)
(.print (
).print).cvx /def

(/printmouse)
(print definition of mouse procedures
)
(()/print (.reddown)/edit ()/print (.redup)/edit ()/print
 (.yellowdown)/edit ()/print (.yellowup)/edit ()/print
 (.bluedown)/edit ()/print (.blueup)/edit ()/print).cvx /def

(/begin)
(.begin a dictionary and execute its begin code
)
(.begin (begin).load .exec
).cvx /def

(/end)
(execute a dictionary's end code and .end it
)
((end).load .exec .end
).cvx /def

(/args)
( <name1><name2>...<namen> n /args
 will assign the n objects on the stack before <name1> to the n names
 useful as first command in a procedure
)
(.dup 0 .eq
 (.pop).load
 ( .dup 2 .add -1 .roll
   3 -1 .roll .exch .def
   1 .sub /args
 ).cvx .ifelse
).cvx /def

(/getargs)
( (name1 name2 ... namen) /getargs
 will assign the n objects on the stack before (name1 name2 ... namen) to the names
 useful as first command in a procedure
)
(0 .exch (.exch 1 .add).cvx /tokall /args
).cvx /def

(#)(.load).load .def

(/wildsearch)
(/wildsearch takes a string and array of search strings on the stack. It returns a .true or .false depending on whether the array of search strings are all found in the target string)
[ (.true)# (.exch)# [ (.exch)# (.pop)# (.search)# [ (.pop)# (.pop)# (.true)# ] [ (.pop)# (.false)# (.exit)# ] (.ifelse)# (.cvx)# (.exec)# ] (.cvx)# (.arrayforall)# [ (.pop)# (.true)# ] [ (.false)# ] (.ifelse)# (.cvx)# (.exec)# ]  /xdef

(/wildbuild)
(/wildbuild takes a string of the form *s1*s2*...sn* and builds the array:
[s1,s2...,sn].)
[ (.mark)# (.exch)# (*) [ (.search)# [ 3 1 (.roll)# ] [ (.cnttomrk)# (.array)# (.astore)# (.exch)# (.pop)# (.exit)# ] (.ifelse)# (.cvx)# (.exec)# ] (.cvx)# (.loop)# ] /xdef

(!S) [ () ] .def

(/wildcard)
(/wildcard takes a dictionary and a string of the form *s1*s2*...sn* on the stack. It then prints all names in the dict that contain the search pattern.)
[ (/wildbuild)# !S (.exch)# 0 (.exch)# (.aput)# [ (.pop)# (            ) (.cvis)# (.dup)# !S  0 (.aget)# (/wildsearch)# [ (=)# ] [ (.pop)# ] (.ifelse)# (.cvx)# (.exec)# ] (.cvx)# (.dictforall)# ] /xdef

(.start)
((jamrun) jamrun 1 .add .def
 (JaM)/print
).cvx .def

(jamrun)1 .def

(watchmouse)((watchkeys).cvx .loop).cvx .def
(.prompt)((*).print).cvx .def

()/print