/
umud/DOC/
umud/DOC/examples/
umud/DOC/internals/
umud/DOC/wizard/
umud/MISC/
umud/MISC/dbchk/
umud/RWHO/rwhod/
Macros and Stuff in General
---------------------------

	When the player types a command, the following, rather lengthy sequence
occurs:

	1) If the command starts with a " or a :, a suitable call to say or
do, with the remaineer of the line passed as the single parameter, is
generated. Thus, anything whatsoever in a " type say, or : type pose is
said or posed without further mashing. If this case occurs, no other processing
is done. Otherwise we proceed as follows:

	2) If 1) is not the case, the line of text is hacked up into
a sequence of sets of tokens. A token is either a word, or a quoted phrase.
Both " and ' are allowable quotes, and one type of quote may be used inside a
phrase quoted with the other. \ escapes also work. The sets of tokens are
delimited by semicolons. Thus:

foo "bar baz";frob "thing's; and other stuff" bop

	breaks up into sets of tokens:

(foo, bar baz)
(frob, things's; and other stuff, bop)

	In addition, the appearance of a equals sign (not in quoted text)
forces the remainder of the line to be treated as a single token. Variable
substitution also takes place at this stage, see below.

	3) Each set of tokens is examined in turn, and an attempt made to match
the first against a 'command' of some sort. When a matching command (or exit,
or what have you -- see below) is found, it is invoked with the remaining
tokens in the set as an argument list.


How Commands Are Matched
------------------------

	If the first token (referred to hereafter as the 'command') starts
with an @, the @ is stripped off, and the remainder of the token is used to
search the server-internal command tables, and then the system macro table
for a match. In event of a match, the matched command is run, and no more
processing occurs on this set of tokens. In the event of no match, an error
is displayed to the player invoking all this, and again, no further processing
is applied to this set of tokens. (Therefore, any command starting with an 
'@' *will* match either a system command or a system macro, and not any
other macro in the area.)

	Next, the command is matched against the list of exits in the room
where the player responsible for invoking all this is. If a match is found,
a suitable call to 'go' is generated. As always, this completes processing on
this set of tokens.

	If all this has failed so far, the command is matched against macros
(attributes of type cmd) on the player, room and the object the player is
holding, in that order. If a matching macro is found, then *all* of the
processing described above, starting from the breaking up into tokens,
is applied to the text of the macro. The tokenizer will, at this point, use the
arguments to command (the remaining tokens in the set) to substitute into the
tokens generated by tokenizing the text of the macro (see below, again).
The first matching macro, if any, is the only one called.

	Note that at this stage, we are running recursively. Macros can
certainly invoke other macros and so forth.

	Finally, if no matching macro has been located, the server internal
command table and then the system macro table are searched for a match.

	
Variable Expansion
------------------

	When a macro is matched, we refer to all the tokens in the set
whose first token matched as the arguments of the macro. As the macro text
itself is tokenized, tokens beginning with dollar signs are replaced according
to the following rules:

$$<text>
	Is turned into $<text>. Note *double* dollar signs.

$n
	where n is a number, is replaced with the nth argument to the macro.
	The 0th argument is the first token of the original token set, i.e.
	was the token matched against the macro name.

$*
	is replaced by a *single* token made up of all the arguments to the
	macro, including the macro name itself (the 0th argument), separated
	by spaces.

$+n
	where n is a number, is replaced by the nth and succeeding arguments
	to the macro, again as a single token separated by spaces.

$#
	is replaced by a number signifying the number of arguments given.

$actor.xxx (or, equivalently, $xxx)
	is replaced with the xxx attribute of the player whose actions
	led to this macro being run, if that attribute is a string.

$me.xxx (or, equivalently, $self.xxx)
	is replaced by the xxx attribute of the object which is actually
	running the macro, if that attribute is a string.

$here.xxx (or, equivalently, $locale.xxx)
	is replaced by the xxx attribute of the location of the player
	whose actions led to this macro being run, if that attribute
	is a string.

	The text following a dollar sign may, optionally, be enclosed in {
and }, to provide useful blocking. I.E. $me.nam and ${me.nam} are equivalent.
This allows an expansion to be concatenated with the surrounding text. 
Variable substituition is done inside strings quoted with ", but NOT inside
strings quoted with '.  This allows variable evaluation within a macro to be
defered.

Examples
--------

	A simple macro:

cmd bonk=@do "BONKs $1"

	If this is an attribute of your player object, typing 'bonk foo'
is entirely equivalent to typing '@do "BONKs foo"'. In detail, 'bonk foo'
tokenizes to

(bonk, foo)

	Since 'bonk' matches the attribute, the macro text is tokenized in to

(@do, "BONKS foo")

	which is the same token set you'd get by typing '@do "BONKs foo"'.

---

	Another simple (and popular) macro:

cmd say=@do "purrs, \"$+1\""

	Now, typing 'say hello, there' tokenizes out nicely to

(@do, "purrs, \"hello, there\"")

	which comes out as

so-and-so purrs, "hello, there"

	Notice the quotes. They had to be escaped in the macro; otherwise
they would have been stripped.  Using '"' instead of 'say' will also 
trigger the 'say' macro.

---

(thanks to Tarrant for inspiring this)

	Suppose you wish to alias 'look' to 'study' with a macro. You want to
be able to use both 'study' and 'study <thing>' to look at the room, or at a
thing. The naive approach is to attach an attribute to yourself:

cmd study=@look $1

	Then typing

study foo

	will work fine, generating a token set (study, foo) which matches the
attribute. Running the macro through the tokenizer will give you (@look, foo)
which will do the right thing. Alas:

study

	will NOT work. This will tokenize to (study), which will match the
macro. Tokenizing the macro, and substituting for the $1 will give
(@look,""). The look command will cheerfully try to match the empty 2nd token
against things here and there, and not find anything. You will NOT see the
room, in particular.

	To make it work right, you get to do this:

cmd study=@set me cmd xxxstudy "look $1";xxxstudy;@unset me xxxstudy

	Now. What happens when you type 'study foo'? First you get the token
list (study, foo). This matches the macro above, and expands into token sets:

(@set, me, cmd, xxxstudy, "look foo")
(xxxstudy)
(@unset, me, xxxstudy)

	The first is run, and generates a NEW attribute on you:

cmd xxxstudy=study foo

	Then the 2nd is run, simply running this new macro, and the 3rd set
tidies up.

	If you type 'study', this happens. The token list (study) is matched
against the study macro, which expands:

(@set, me, cmd, xxxstudy, "look ")
(xxxstudy)
(@unset, me, xxxstudy)

	Which makes a macro

cmd xxxstudy=look

	runs it, and tidies up.

---

For more macro examples for neat building tricks, see the file "ferret.unter".