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