http:// www.metamage.com / mush / croaker / chapter8.html

Croaker's TinyMUSH Manual

Last update: December 8, 2004

Author: Croaker

Editor: Josh Juran <wanderer@metamage.com>

URL: <http://www.metamage.com/mush/croaker/>


8. Machine programming

Up until now, the attributes that have been discussed have all been directly associated with predetermined stimuli, like being picked up, killed, or cloned. This, however, limits the amount of commands a machine can perform, and leaves little room for control loops to run. Also, up to now the only way to get a continuous loop of commands has been to kludge in things like having the robot rob itself to re-trigger the ASUCC or to whisper a phrase to itself to trigger the AMHEAR. This section will solve this, and allow for real programming to be done.

8.1. General Attributes: VA-VZ

All of the attributes, such as ASUCC, AHEAR, and so on have been associated with certain occurrences or stimuli. There are also 26 attributes named VA, VB and so forth up through VZ that are not associated in any manner to an external trigger. They can be used for different things, such as storing strings, action lists, or other values without worrying about them being triggered by some outside stimulus.

General attributes are set in the normal manner:

@va = This is a test

will store a message in the VA attribute. There are functions that are available to manipulate data stored in these attributes (and in any attribute, actually.)

8.2. Action Lists and General Attributes (@trigger)

As stated above, VA-VZ are not associated with a trigger. In order for these attribute to run action lists, therefore, the @trigger command must be used. This command will cause the specified attribute on an object to run. The syntax is:

@trigger object/attribute = parameters

The parameters are what is to be given to the triggered attribute in the variables %1-%9. The parameters are necessary since any sort of triggering (the trigger command, something the object hears that matches the LISTEN attribute) will reset all of the variables. For example:

@trigger foobie/va = bing,1,23

will trigger the VA attribute of the object named foobie, with %0 set to bing, %1 set to 1, and %2 set to 23.

Example: @trigger command

@create trigger object
Created.

@va trigger object="This is a test!
Set.

drop trigger object
Dropped.

@trigger trigger object/va
Triggered.
trigger object says "This is a test!"

The @trigger command can be used to break up execution of a machine into several action lists. This allows easier programming of machines, longer and more modular programs to be created. Do not make the mistake of thinking of a @trigger as a subroutine command or a goto, however. When the @trigger command is encountered in an action list, the attribute triggered is placed in a queue to be later executed. This means that there is no way anything in the triggered attribute will be able to run before the current action list is finished (and all of the previously queued action lists, if any, have run as well.) The most common way of chaining the action lists is simply to have the @trigger command as the last command in the list to chain to the next list that should be executed. As with other action lists, if there is no @trigger command and no other action lists queued, the machine will stop running.

Example: queuing @trigger commands

@va trigger object=@trigger me/vb; @trigger me/vc; @trigger
me/vd; "This is VA
Set.

@vb trigger object="This is vb!
Set.

@vc trigger object="This is vc!
Set.

@vd trigger object="This id vd!
Set.

@trigger trigger object/va
Triggered.
trigger object says "This is VA"
trigger object says "This is vb!"
trigger object says "This is vc!"
trigger object says "This id vd!"

Note that "This is VA" is first, even though the @trigger commands came before it in the action list.

8.3. Using General Attributes for Storage

The attributes VA-VZ can also be used to store data to be manipulated by the machine. This allows such things as counters, string variables, and so forth. Storing information is simple, since the standard syntax for storing strings in attributes applies. For example:

@ahear foo=@vz = %1;@trigger me/va

will store the contents of %1 into @vz. Once set, the general attributes will retain the data until the machine's program changes it to something else. This allows for longer term storage than the %1-%9 variables which are reset after each trigger.

In order to retrieve and manipulate the data, a number of functions must be use. The simplest of these is the GET() function, which returns the contents of the specified attribute. The syntax of the GET() function call is:

get(object/attribute)

The get function will be replaced by the string stored in the attribute of the specified object. It is only possible to get the attributes of objects you own, even if the attribute to be fetched is publicly accessible.

Example: GET() function

@va me=This is a test
Set.
"my va = get(me/va)
You say "my va = This is a test"

There exists a shorthand method for an object to get one of its own attribute. The syntax for this method is:

%attribute

Example: Shortcut for getting attributes

"my va = %va
You say "my va = This is a test"

The next object demonstrates the ability to add a great deal more variety to the output of machines. Note the use of several attributes to store some constant strings. This allows greater ease in programming, as one does not have to retype the string over and over again. Also, it allows for easier customizing of the object: changing the name of the object is as easy as resetting a single attribute, and avoids the necessity of having to @edit several attributes.

8.4. Numerical Functions

MUSH has a set of basic math functions that can manipulate strings that consist of numbers. The treatment of strings as numbers (hereafter referred to as numeric strings) is as follows:

If the string starts with a letter, its value is 0.

If the string starts with a number, then the string is read until the end or the first letter occurs. The value of the string is equal to the numeric characters encountered.

For example, the string "A4587" will equal zero. The string "123bla" will equal one hundred twenty three. In the following descriptions of commands, we'll assume that "number" is a string that hash some numerical characters in it.

ADD(number,number)
Adds the two numbers together.
MUL(number,number)
Multiplies the first number by the second.
DIV(number,number)
Divides the first number by the second.
MOD(number,number)
Takes the modulo of the first number by the second (i.e. the remainder of dividing the first number by the second.)

Example: Math Functions

"add(34,23)
You say "57"

"add(12,-9)
You say "3"

"add(3,bearg)
You say "3"

"mul(45,34)
You say "1530"

"div(5,20)
You say "0"

"[div(20,5)]
You say "4"

"[mod(21,5)]
You say "1"

8.5. Functions to manipulate strings

There are four functions to manipulate strings in MUSH:

First(string)
returns the first word of a string, that is everything to the left of the first space in the string (or the entire string if there is no space in the string.)
Last(string)
Returns the remainder of the string after the first word. In other words, everything to the right of the first space in the string. If there is no space in the string, this function returns nothing.

Example: the FIRST() and LAST() functions

[No example]

These pair of functions allow parsing of a string word by word. This machine listens for a string with "parse:" in it. The rest of the line is stored in an attribute with an end of string indicator (###.) The machine then takes every word in the string and says it.

Example: Parsing a string word by word

look parse
parse(#7146)
You see nothing special.
Listen:*parse:*
Ahear:@vw me=0;@vz me=%1 ###;@trigger me/va
VA:@switch first(%vz)= ###,@trigger me/vb,@trigger me/vc
VB:"------ complete ------
VC:@vy me = rest(%vz);@vx me = first(%vz);@trigger me/vd
VD:@vw me=add(%vw,1);@trigger me/ve
VE:"word #%vw = %vx;@trigger me/vf
VF:@vz me=%vy;@trigger me/va

"Parse:this is a test of parsing a line
You say "Parse:this is a test of parsing a line"
parse says "word #1 = this"
parse says "word #2 = is"
parse says "word #3 = a"
parse says "word #4 = test"
parse says "word #5 = of"
parse says "word #6 = parsing"
parse says "word #7 = a"
parse says "word #8 = line""
parse says "------ complete ------"

These next two functions act almost exactly like their counterparts in the BASIC language.

Strlen(string)
Returns the length of the string in a numerical string.
Mid(string,first,length)
Returns a segment of the string, the length characters to the left of the first character. Note that the first character in the string is numbered zero, not one.

Example: STRLEN() and MID()

@va me=This is a test

"strlen(get(me/va))
You say "14"

"mid(%va,4,4)
You say " is "

"mid(%va,0,4)
You say "This"


Last updated December 10, 2004 by Josh Juran
Metamage Labs