-
Notifications
You must be signed in to change notification settings - Fork 0
/
mpi.html
224 lines (190 loc) · 8.88 KB
/
mpi.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
<html>
<head>
<title>The MUCK Manual: Overview: MPI</title>
</head>
<body bgcolor="#FFFFFF">
<center>
<a href="programming.html">prev</a>|
<a href="toc.html">toc</a>|
<a href="mpimacs.html">next</a>
</center>
<table>
<tr>
<td width="20%"> </tc>
<td>
<!-- BODY CONTENT HERE -->
<p><b>3.1 Overview: MPI</b></p>
<p><code>MPI</code> is an interpretted language with a
<code>LISP</code>-like syntax available to all players. Because it is
universally available, <code>MPI</code> includes some security features
that restrict its power. In general, <code>MPI</code> can only read
props on the triggering object and on objects controlled by the
controller of the object on which the <code>MPI</code> string is stored,
and can only set props on the latter... on objects controlled by the
owner of the <code>MPI</code> object. Other than setting props as
mentioned, it is difficult (but not impossible) to significantly modify
the database with <code>MPI,</code> 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.</p>
<p> <code>MPI's</code> syntax 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...</p>
<p><code>
{if:{eq:{ref:me},#1},Hey it's God!,Hello world!}
</code></p>
<p>The <code>MPI</code> parser will first evaluate the innermost
function, <code>{ref:me}.</code> The <code>{ref}</code> function returns
the dbref of its single argument — which in this case is
<code>`me'</code> — so, <code>{ref:me}</code> returns the user's
dbref. The returned expression `replaces', as it were, the function. So,
if the user's dbref were <code>#123,</code> the <code>MPI</code> string
would in effect and at this moment be...</p>
<p><code>
{if:{eq:#123,#1},Hey it's God!,Hello world!.}
</code></p>
<p>Then the next-innermost expression, effectively
<code>{eq:#123,#1},</code> would be evaluated. The <code>{equals}</code>
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 <code>{equals}</code> will return false. At this point, the
<code>MPI</code> value for false — the string "0" — will
replace the function. (A "" null string is also false in
<code>MPI.</code> Any value other than "" or "0" is considered true.)
So, at this point the string would in effect be...</p>
<p><code>
{if:"0",Hey it's God!,Hello world!}
</code></p>
<p>Finally, this, the outermost function will be evaluated. The
<code>{if}</code> 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: <code>MPI</code> will
return the string <code>"Hello world!"</code> to player
<code>#123.</code> If God had triggered the string, the
<code>{if}</code> test would have been true, and the string <code>"Hey
it's God!"</code> would have been returned instead.</p>
<p>The <code>{debug}</code> function displays the progress of the
parser. Enclosing the whole of our example in a <code>{debug}</code>
function will show the process described above.</p>
<p><code>
====================================<br>
<nobr>> @succ testmpi = {debug:{if:{eq:{ref:me},#1},Hey it's God!,Hello world!}}</nobr><br>
Message set.<br>
> testmpi<br>
(@Succ) {IF:"{eq:{ref:me},#1}", "Hey it's God!", "Hello world!"}<br>
(@Succ) {EQ:"{ref:me}", "#1"}<br>
(@Succ) {REF:"me"}<br>
(@Succ) "me"<br>
(@Succ) {REF:"me"} = "#123"<br>
(@Succ) "#1"<br>
(@Succ) {EQ:"#123", "#1"} = "0"<br>
(@Succ) "Hello world!"<br>
<nobr> (@Succ) {IF:"{eq:{ref:me},#1}", "Hey it's God!", "Hello world!"} = "Hello world!"</nobr><br>
Hello world!<br>
====================================<br>
</code></p>
<p>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 ` <code>= <value></code> ' and
indentation moving back to the left, depicts the series of returned
expressions described above.</p>
<hr>
<p>The keywords <code>`me'</code> and <code>`here'</code> can be used as
normal. In addition, <code>MPI</code> supports the keyword `this', which
will be replaced by the dbref of the object on which the
<code>MPI</code> is stored.</p>
<hr>
<p>The variable functions <code>{&cmd},</code> <code>{&arg},</code> and
<code>{&how}</code> may be used to retrive information about how
<code>MPI</code> was triggered. <code>{&cmd}</code> stores the command
name typed to trigger the <code>MPI.</code> <code>{&arg}</code> stores
any arguments typed along with the command. <code>{&how}</code> stores
the method by which <code>MPI</code> was triggered, and will have values
such as <code>(@desc),</code> <code>(@succ),</code>
<code>(@osucc),</code> <code>(@lock),</code> etc.</p>
<hr>
<p>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.</p>
<hr>
<p>An <code>MPI</code> string that appears in a <code>_/</code> prop (a
<code>@succ</code> message, a <code>@desc,</code> 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.</p>
<p><code>
====================================<br>
> @set me=_oarrive/aaa:&{null:{otell:pads in quietly.}}<br>
Property set.<br>
====================================<br>
</code></p>
<hr>
<p>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 <code>\</code> backslash
escape character, which tells the parser to treat the next character
literally, rather than as an <code>MPI</code> instruction. For example,
if we wanted our first example to say <code>"Hey, it's God!"</code> or
<code>"Hello, world!",</code> the commas would need to be escaped with a
backslash character.</p>
<p><code>
{if:{eq:{ref:me},#1},Hey\, it's God!,Hello\, world!}
</code></p>
<hr>
<p>Complex or very long <code>MPI</code> instructions 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
<code>{lexec}</code> (`execute list') function can then be placed in the
triggering prop.</p>
<p><code>
====================================<br>
> lsedit harley = bikecode<br>
<nobr>
< Welcome to the list editor. You can get help by
entering `.h' ><br>
</nobr><nobr>
< `.end' will exit and save the list. `.abort' will abort any changes. ><br>
</nobr><nobr>
< To save changes to the list, and continue
editing, use `.save' ><br>
</nobr>
<br>
> {null:<br>
> {if:<br>
> {<br>
> (lots of complicated really cool <br>
motorcycle code goes here)<br>
> }<br>
> }<br>
> }<br>
> .end<br>
< Editor exited. ><br>
< list saved. ><br>
<br>
> @succ ride harley;ride motorcycle;ride cycle = {lexec:bikecode}<br>
Message set.<br>
<br>
> ride harley<br>
(The Harley does something amazing.)<br>
====================================<br>
</code></p>
<p>The <code>{lexec}</code> function executes <code>MPI</code> in a
list. The <code>{exec}</code> function executes <code>MPI</code> in a
property, and thus provides another way to break code up into managable
pieces. <code>MUSH</code> coders especially might find this method more
intuitive.</p>
<center>
<a href="programming.html">prev</a>|
<a href="toc.html">toc</a>|
<a href="#top">top</a>|
<a href="mpimacs.html">next</a>
</center>
</td>
<td width="20%"> </tc>
</table>
</body>
</html>