|  | 3.1  Overview: MPI MPIis an interpretted language with aLISP-like syntax available to all players. Because it is
universally available,MPIincludes some security features
that restrict its power. In general,MPIcan only read
props on the triggering object and on objects controlled by the
controller of the object on which theMPIstring is stored,
and can only set props on the latter... on objects controlled by the
owner of theMPIobject. Other than setting props as
mentioned, it is difficult (but not impossible) to significantly modify
the database withMPI,but is ideally suited for
message-handling. And because it is interpretted, it is well-suited for
one-off programming tasks: no separate compiling and linking operations
are needed, nor is a separate program object for holding the code.
  MPI'ssyntax consists of nested functions enlcosed in
curly braces that are evaluated left-to-right and `from the inside out',
much like mathematical expressions are evaluated outward from the
innermost set of parentheses. For example... 
     {if:{eq:{ref:me},#1},Hey it's God!,Hello world!}
 The MPIparser will first evaluate the innermost
function,{ref:me}.The{ref}function returns
the dbref of its single argument  which in this case is`me' so,{ref:me}returns the user's
dbref. The returned expression `replaces', as it were, the function. So,
if the user's dbref were#123,theMPIstring
would in effect and at this moment be... 
     {if:{eq:#123,#1},Hey it's God!,Hello world!.}
 Then the next-innermost expression, effectively
{eq:#123,#1},would be evaluated. The{equals}function returns true if the two arguments supplied are the same;
otherwise it returns false. In this case, the two arguments are not the
same, so{equals}will return false. At this point, theMPIvalue for false  the string "0"  will
replace the function.  (A "" null string is also false inMPI.Any value other than "" or "0" is considered true.)
So, at this point the string would in effect be... 
      {if:"0",Hey it's God!,Hello world!}
 Finally, this, the outermost function will be evaluated. The
{if}function takes three arguments. If the first argument
is true, it returns the second argument. If the first argument is false,
it returns the third argument. In this example, the first argument is
false, so the the third argument will be returned:MPIwill
return the string"Hello world!"to player#123.If God had triggered the string, the{if}test would have been true, and the string"Hey
it's God!"would have been returned instead. The {debug}function displays the progress of the
parser. Enclosing the whole of our example in a{debug}function will show the process described above. 
====================================> @succ testmpi = {debug:{if:{eq:{ref:me},#1},Hey it's God!,Hello world!}}
 Message set.
 > testmpi
 (@Succ) {IF:"{eq:{ref:me},#1}", "Hey it's God!", "Hello world!"}
 (@Succ)   {EQ:"{ref:me}", "#1"}
 (@Succ)     {REF:"me"}
 (@Succ)       "me"
 (@Succ)     {REF:"me"} = "#123"
 (@Succ)     "#1"
 (@Succ)   {EQ:"#123", "#1"} = "0"
 (@Succ)   "Hello world!"
 (@Succ) {IF:"{eq:{ref:me},#1}", "Hey it's God!", "Hello world!"} = "Hello world!"
 Hello world!
 ====================================
 
 In the lines from the first half of the debugging output  where
indentation is moving to the right  the parser is essentially
finding the innermost, left-most function to be evaluated. The remaining
portion, with lines ending in ` = <value>' and
indentation moving back to the left, depicts the series of returned
expressions described above. 
 The keywords `me'and`here'can be used as
normal. In addition,MPIsupports the keyword `this', which
will be replaced by the dbref of the object on which theMPIis stored. 
 The variable functions {&cmd},{&arg},and{&how}may be used to retrive information about howMPIwas triggered.{&cmd}stores the command
name typed to trigger theMPI.{&arg}stores
any arguments typed along with the command.{&how}stores
the method by whichMPIwas triggered, and will have values
such as(@desc),(@succ),(@osucc),(@lock),etc. 
 Functions can be nested up to 26 levels deep. Loops may iterate a
maximum of 256 times, at which point the automatically exit. Lists may
have a maximum of 256 lines, or 4096 characters, whichever is less. 
 An MPIstring that appears in a_/prop (a@succmessage, a@desc,and so forth) will be
parsed automatically. For other triggering props, the parser must be
called by an & ambersand at the beginning of the prop string. 
====================================> @set me=_oarrive/aaa:&{null:{otell:pads in quietly.}}
 Property set.
 ====================================
 
 
 The arguments of functions are separated by commas. Commas appearing
in argument strings will confuse the parser: functions will seem 
to it  to have too many arguments. So, commas in argument strings
must be `escaped'... i.e., preceded with a \backslash
escape character, which tells the parser to treat the next character
literally, rather than as anMPIinstruction. For example,
if we wanted our first example to say"Hey, it's God!"or"Hello, world!",the commas would need to be escaped with a
backslash character. 
      {if:{eq:{ref:me},#1},Hey\, it's God!,Hello\, world!}
 
 Complex or very long MPIinstructions are often better
stored in a list, where whitespace can be used to make the code more
readable, rather than in a single prop where all will run together in an
opaque mass of characters. A simple pointing string using the{lexec}(`execute list') function can then be placed in the
triggering prop. 
====================================> lsedit harley = bikecode
 <    Welcome to the list editor. You can get help by
entering `.h'      >
 < `.end' will exit and save the list. `.abort' will abort any changes. >
 <    To save changes to the list, and continue
editing, use `.save'     >
 
 > {null:
 >    {if:
 >        {
 >        (lots of complicated really cool
 motorcycle code goes here)
 >         }
 >     }
 > }
 > .end
 < Editor exited. >
 < list saved. >
 
 > @succ ride harley;ride motorcycle;ride cycle = {lexec:bikecode}
 Message set.
 
 > ride harley
 (The Harley does something amazing.)
 ====================================
 
 The prev |
  toc |
  top |
  next{lexec}function executesMPIin a
list. The{exec}function executesMPIin a
property, and thus provides another way to break code up into managable
pieces.MUSHcoders especially might find this method more
intuitive. |  |