1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-11 23:53:12 +00:00
PDP-10.its/doc/_info_/lisp.send
2016-11-30 17:58:42 +01:00

165 lines
8.4 KiB
Plaintext
Executable File

Documentation of the "usrhunk" apparatus for SENDing messages.
(SSTATUS USRHUNK <predicate>) specifies the "user hunk" predicate, which
determines whether to "hook into" a user-provided definition for
some system facility, or to treat the data strictly as a hunk.
(SSTATUS SENDI <function>) specifies a "SEND" interpreter -- <function>
is invoked in order to send a "message" to a "user hunk", when a
hunk which passes the "usrhunk" test is given as argument to any of
EQUAL SUBST PURCOPY EVAL SXHASH PRINT EXPLODE
FLATSIZE ALPHALESSP SAMEPNAMEP NAMESTRING
or to any of the following out-of-core facilities
GFLATSIZE SPRINT USERATOMS-HOOK DESCRIBE WHICH-OPERATIONS
(SSTATUS CALLI <function>)
The usrhunk <predicate> takes one argument, and should return
non-null for objects that LISP should send messages to. It is invoked
via (CALL 1,) so this link gets snapped, which means that if you redefine
the predicate then the new definition may not take effect unless you
un-snap by doing (SSTATUS USRHUNK (STATUS USRHNK)).
The usrhunk SEND interpreter, <function>, is invoked via (JCALL 16,)
so its link too may be snapped. This function is responsible for
delivering the message to the apropriate code for handling it; return
values are sometimes significant. See below for documentation on specific
messages which will be sent by LISP. Note that an lsubr "SEND" is assumed;
this function could be the function that is given to (SSTATUS SENDI ...).
For the dozen or so system functions which will send a message to
a usrhunk, the action is as follows. Suppose the message is, say, DOIT;
then (DOIT <weirdo> <another>) will be interpreted by doing a send like
(SEND <weirdo> 'DOIT <another>), and this will cause the send interpreter
function to select some specialized function, say, FROBULATE, which will
then be applied to the arguments in the same order as given to SEND. E.g.,
(DEFUN FROBULATE (actor msg-key other-arg)
(caseq msg-key
(DOIT <happiness>)
(DONT <ugliness>)
(T <error?>)))
Actually, the "msg-key" argument could be ignored, but this example shows
how several different messages could be dispatched to the same function.
The argument spectrum of the frobulator should match that of the original
function; thus for the SXHASH message it might be
(DEFUN HASH-IT-ALL (ob () ) ...)
where the "()" means to ignore the message key (which should be sent as
SXHASH). On the other hand, there may be some importance to the order
of arguments, as this example for the SUBST message shows:
(DEFUN SUBST-FOR-TRICKY-HUNK (hunk () old new)
(hunkify (subst old new (extract-data hunk))))
Here is a table of the actions taken by the system functions which
resort to SENDing, and of the meanings of the arguments being "sent":
EQUAL -- (send obj1 'EQUAL obj2) -- "obj1" and "obj2" are two objects
to be compared, and of course "equal" is commutative.
SUBST -- (send object 'SUBST a b) -- Substitute a for b in object.
PURCOPY -- (send object 'SUBST a b) -- Substitute a for b in object,
using static (potentially read-only) consing areas.
EVAL -- (send object 'EVAL) -- Return the value of this object.
Typically, just returns itself for "implicit quoting".
FLATSIZE -- (send object 'FLATSIZE printp level slashifyp)
"printp" -- non-null if called from inside print as part of the
autoterpri hackery; in this case it should return
characters before next legal place to break. This doesn't
matter if you're not doing autoterpri hacking.
"level" -- fixnum level of recursion of PRINT/FLATSIZE; can
be passed on to PRINT-OBJECT or FLATSIZE-OBJECT (see
below for their definitions). This is used to limit
recursion with PRINLEVEL set non-null.
"slashifyp" -- If non-null, include slashes where print would.
PRINT -- First, there will be done
(send object 'FLATSIZE 'T -1 slashifyp)
and then
(send object 'PRINT stream level slashifyp)
"stream" -- SFA, file, T, or () to print to
"level" -- recursion level of PRINT calling print or print
methods recursively. If you do printing that may wish
to be limited in depth by PRINLEVEL, you should do your
output with PRINT-OBJECT, which takes the current nesting
level as one of it's arguments. ;
"slashify-p" -- if non-null, this is PRIN1, not PRINC
EXPLODE -- As with PRINT, there will first be done
(send object 'FLATSIZE 'T -1 slashifyp)
and then
(send object 'EXPLODE slashify-p number-p)
"slashify-p" -- non-null if slashes should be output where
print would put them.
"number-p" -- non-null if characters should be returned as
fixnums; otherwise, they are single-character symbols.
ALPHALESSP -- Will send either a LESSP or GREATERP message,
with one argument, which is the 'other' object for comparison.
SAMEPNAMEP -- Sends a SAMEPNAMEP message, with one argument which is
the 'other' object for comparison.
SXHASH -- Sends a SXHASH message, which should return a FIXNUM to
be the SXHASH of the object.
NAMESTRING -- Sends a NAMESTRING message, which should return a SYMBOL
whose pname characters are a 'namestring' for the object.
Two new functions have been added to the initial MacLISP for the sake
of recursive calls to PRINT and FLATSIZE by various PRINT and FLATSIZE
methods, and they have arguments similarly.
PRINT-OBJECT (object level slashifyp stream &optional ignored)
FLATSIZE-OBJECT (object printp level slashifyp &optional ignored)
"object" -- object to be printed or to have it's FLATSIZE computed.
"level" -- recursive printing level, for PRINLEVEL detection. You should
pass in the current LEVEL, zero-origen.
"slashifyp" -- non-null indicates slashification should be done
"stream" -- file or SFA
"printp" -- non-null if FLATSIZE is being called originally from PRINT
This will be passed in to any FLATSIZE methods called
recursively and means "This is a FLATSIZE up to first place
OK to break", for print's TERPRI hacking. If you see this
and want to punt, return zero.
"ignored" -- for compatability with an irrelevant LISPM feature.
*** CALLI processing ***
CALLI interpreters must be hand coded; they cannot be coded in LISP.
This is because of the way they are invoked: They get invoked with
the stack in the format for IAPPLY. IAPPLY is LISP's Internal APPLY.
The arguments are on the stack, like for an LSUBR call, and T contains
the negative of the number of args, just like for an LSUBR call. However,
where the return address would be is found the object to be applied. What
LISP does is to take that object, figure out how to apply it, replace it's
slot on the stack with <object>,,CPOPJ . CPOPJ is the address of a POPJ P,
thus returning to it returns to the caller of the IAPPLY, who's return
address is just below that.
|arg n
|arg n-1
..
..
..
|arg 1
|arg 0
object-to-be-applied
return-address
Register T (accumulator 6) contains -n, and the slot containing
object-to-be-applied is clobbered to <object-to-be-applied>,,CPOPJ
and the function is invoked.
The user CALLI handler can act in several ways. You can figure out the
function you wish to invoke, clobber the <object-to-be-applied> slot to
contain a CPOPJ (or whatever routine you want executed later) and do
a JCALLF 16,(routine) or you can replace the <object-to-be-applied> with
another object to be used instead, and JRST off to IAPPLY. IAPPLY will
then recompute what to do (possibly invoking the user CALLI handler if
it answers true to the USRHUNK test), apply the function and return.
Since the CALLI handler is not a function, it does not live in a SUBR
or LSUBR property, but instead in a CALLI property. (SSTATUS CALLI 'FOO)
looks for a CALLI property on FOO. If it finds it, it stores a JRST to
that routine internally, and saves the symbol FOO to be returned by
(STATUS CALLI).
____________________________________________________________________________
2/19/80 -- RWK
1) **SELF-EVAL** hook
PRINC/PRIN1 now send a FLATC/FLATSIZE message first. This should be
improved some more but it really does work. PRINLEVEL info needs to be
passed back and forth between MACLISP and user printers, and FLATC/FLATSIZE
should be told whether or not it is for PRINT so they can give the FLATC
before the first break.