Go to the previous, next section.
Sometimes you might wish that SM's authors had decided to make
a command behave a bit differently, for instance that ERASE
or
QUIT
didn't appear on the history list, or that SAVE
deleted
all the system macros before saving your environment. Of course, you can
(usually) write macros to get around these annoyances, but you can't easily give them the same names as the original commands (for these
examples the macros are called era
, q
, and sav
).
It is possible to change the meaning of keywords (to `overload' them),
but it can be confusing, primarily because your
new commands may not behave the same way that this manual claims.
For example, if you were perverse, you could define points
to mean QUIT
. Another danger is that you could end up with a
recursive call -- for instance if you wrote your own version of box
that did all sorts of cunning things, then drew a box. If you
said box
in your macro, then overloaded the keyword, you'd have
a macro that called itself. If you tried to use it, nothing would
happen for a while, and then you'd start getting messages about "extending
i/o stack" until you hit ^C. Or if you redefined help
to mean
DELETE HISTORY HELP
(in upper case to avoid recursive calls, and
in case delete
has been overloaded), then set help vec Help string
won't work (you'd have to use set HELP vec ...
).
Despite these warnings, overloading the meaning of
SM's keywords can be very convenient. There are two sets of
system macros that do just this, the compatibility ones (see section Tips for Mongo Users),
and one called set_overload
that is described below.
In addition to the semi-trivial use of overloading to allow you to type
erase
not era
, it is possible to add extra functionality
to simple commands. For example, set_overload
defines window
to save the window parameters in variables, and box
then uses these
values to label appropriate axes in touching boxes. Another example is that
(when overloaded) lines
saves the line numbers used, so that you
can write a macro to print the top 10 lines of a file (it's called head
).
So how do you do it? The command OVERLOAD keyword #
will remove
the special meaning of lowercase keyword
if #
is
non-zero, or reinstate it otherwise. You can still use the uppercase form
-- you can't overload that. So now that e.g. box
has no
special meaning you can define it to be a macro. What the set_overload
macro does is to define new meanings for a number
of keywords, the new definitions are in the macro file `overload'.
If you intend using them (and I do all the time) you should look at
this file.
You can get them loaded by default by having a line overload 1
in your
`.sm' file.
If you don't like some, e.g. box, you can simply say OVERLOAD
box 0
in your private startup file (see `private initialisation')
which is run after the system startup.
Most of the changes are benign, but not all. For example, the
new definition of relocate
allows expressions, but it'll break
if you try to say relocate ( 100 1000 )
to move to absolute
screen coordinates. You can still say RELOCATE ( 100 1000)
of
course, and that's why most of the system macros are actually written
in uppercase. The definition of box
(actually bo
,
which box
calls) may seem very complex, but
it has to deal with box \n
as well as box 1 2
, and it
must know if you have used the WINDOW
command.
This brings up another point -- if you overload keywords,
you could slow SM down. It isn't that overloading is
inefficient, it's just that the macros that replace the old keywords
may do a good deal of work, box
is a case in point. Even when
the macro is short and to the point, it's still extra work to parse
the original word and find its value as a macro.
Go to the previous, next section.