/
html/
<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.51
     from ProgrammersManual.texinfo on 4 March 1997 -->

<TITLE>LambdaMOO Programmer's Manual - Evaluation and Tasks</TITLE>
</HEAD>
<BODY>
Go to the <A HREF="ProgrammersManual_1.html">first</A>, <A HREF="ProgrammersManual_53.html">previous</A>, <A HREF="ProgrammersManual_55.html">next</A>, <A HREF="ProgrammersManual_77.html">last</A> section, <A HREF="ProgrammersManual_toc.html">table of contents</A>.
<P><HR><P>


<H3><A NAME="SEC54" HREF="ProgrammersManual_toc.html#TOC54">MOO-Code Evaluation and Task Manipulation</A></H3>

<P>
<DL>
<DT><U>Function:</U> none <B>raise</B> <I>(<VAR>code</VAR> [, str <VAR>message</VAR> [, <VAR>value</VAR>]])</I>
<DD><A NAME="IDX103"></A>
Raises <VAR>code</VAR> as an error in the same way as other MOO expressions,
statements, and functions do.  <VAR>Message</VAR>, which defaults to the value of
<CODE>tostr(<VAR>code</VAR>)</CODE>, and <VAR>value</VAR>, which defaults to zero, are made
available to any <CODE>try</CODE>-<CODE>except</CODE> statements that catch the error.  If
the error is not caught, then <VAR>message</VAR> will appear on the first line of
the traceback printed to the user.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> value <B>call_function</B> <I>(str <VAR>func-name</VAR>, <VAR>arg</VAR>, ...)</I>
<DD><A NAME="IDX104"></A>
Calls the built-in function named <VAR>func-name</VAR>, passing the given arguments,
and returns whatever that function returns.  Raises <CODE>E_INVARG</CODE> if
<VAR>func-name</VAR> is not recognized as the name of a known built-in function.
This allows you to compute the name of the function to call and, in particular,
allows you to write a call to a built-in function that may or may not exist in
the particular version of the server you're using.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> list <B>function_info</B> <I>([str <VAR>name</VAR>])</I>
<DD><A NAME="IDX105"></A>
Returns descriptions of the built-in functions available on the server.  If
<VAR>name</VAR> is provided, only the description of the function with that name is
returned.  If <VAR>name</VAR> is omitted, a list of descriptions is returned, one
for each function available on the server.  Raised <CODE>E_INVARG</CODE> if
<VAR>name</VAR> is provided but no function with that name is available on the
server.

</P>
<P>
Each function description is a list of the following form:

</P>

<PRE>
{<VAR>name</VAR>, <VAR>min-args</VAR>, <VAR>max-args</VAR>, <VAR>types</VAR>
</PRE>

<P>
where <VAR>name</VAR> is the name of the built-in function, <VAR>min-args</VAR> is the
minimum number of arguments that must be provided to the function,
<VAR>max-args</VAR> is the maximum number of arguments that can be provided to the
function or <CODE>-1</CODE> if there is no maximum, and <VAR>types</VAR> is a list of
<VAR>max-args</VAR> integers (or <VAR>min-args</VAR> if <VAR>max-args</VAR> is <CODE>-1</CODE>),
each of which represents the type of argument required in the corresponding
position.  Each type number is as would be returned from the <CODE>typeof()</CODE>
built-in function except that <CODE>-1</CODE> indicates that any type of value is
acceptable and <CODE>-2</CODE> indicates that either integers or floating-point
numbers may be given.  For example, here are several entries from the list:

</P>

<PRE>
{"listdelete", 2, 2, {4, 0}}
{"suspend", 0, 1, {0}}
{"server_log", 1, 2, {2, -1}}
{"max", 1, -1, {-2}}
{"tostr", 0, -1, {}}
</PRE>

<P>
<CODE>Listdelete()</CODE> takes exactly 2 arguments, of which the first must be a
list (<CODE>LIST == 4</CODE>) and the second must be an integer (<CODE>INT == 0</CODE>).
<CODE>Suspend()</CODE> has one optional argument that, if provided, must be an
integer.  <CODE>Server_log()</CODE> has one required argument that must be a string
(<CODE>STR == 2</CODE>) and one optional argument that, if provided, may be of any
type.  <CODE>Max()</CODE> requires at least one argument but can take any number
above that, and the first argument must be either an integer or a
floating-point number; the type(s) required for any other arguments can't be
determined from this description.  Finally, <CODE>tostr()</CODE> takes any number of
arguments at all, but it can't be determined from this description which
argument types would be acceptable in which positions.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> list <B>eval</B> <I>(str <VAR>string</VAR>)</I>
<DD><A NAME="IDX106"></A>
The MOO-code compiler processes <VAR>string</VAR> as if it were to be the program
associated with some verb and, if no errors are found, that fictional verb is
invoked.  If the programmer is not, in fact, a programmer, then <CODE>E_PERM</CODE>
is raised.  The normal result of calling <CODE>eval()</CODE> is a two element list.
The first element is true if there were no compilation errors and false
otherwise.  The second element is either the result returned from the fictional
verb (if there were no compilation errors) or a list of the compiler's error
messages (otherwise).

</P>
<P>
When the fictional verb is invoked, the various built-in variables have values
as shown below:

</P>

<PRE>
player    the same as in the calling verb
this      #-1
caller    the same as the initial value of <CODE>this</CODE> in the calling verb

args      {}
argstr    ""

verb      ""
dobjstr   ""
dobj      #-1
prepstr   ""
iobjstr   ""
iobj      #-1
</PRE>

<P>
The fictional verb runs with the permissions of the programmer and as if its
<SAMP>`d'</SAMP> permissions bit were on.

</P>

<PRE>
eval("return 3 + 4;")   =>   {1, 7}
</PRE>

</DL>

<P>
<DL>
<DT><U>Function:</U> none <B>set_task_perms</B> <I>(obj <VAR>who</VAR>)</I>
<DD><A NAME="IDX107"></A>
Changes the permissions with which the currently-executing verb is running to
be those of <VAR>who</VAR>.  If the programmer is neither <VAR>who</VAR> nor a wizard,
then <CODE>E_PERM</CODE> is raised.

</P>

<BLOCKQUOTE>
<P>
<STRONG>Note</STRONG>: This does not change the owner of the currently-running verb,
only the permissions of this particular invocation.  It is used in verbs owned
by wizards to make themselves run with lesser (usually non-wizard) permissions.
</BLOCKQUOTE>

</DL>

<P>
<DL>
<DT><U>Function:</U> obj <B>caller_perms</B> <I>()</I>
<DD><A NAME="IDX108"></A>
Returns the permissions in use by the verb that called the currently-executing
verb.  If the currently-executing verb was not called by another verb (i.e., it
is the first verb called in a command or server task), then
<CODE>caller_perms()</CODE> returns <CODE>#-1</CODE>.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> int <B>ticks_left</B> <I>()</I>
<DD><A NAME="IDX109"></A>
<DT><U>Function:</U> int <B>seconds_left</B> <I>()</I>
<DD><A NAME="IDX110"></A>
These two functions return the number of ticks or seconds (respectively) left
to the current task before it will be forcibly terminated.  These are useful,
for example, in deciding when to call <SAMP>`suspend()'</SAMP> to continue a long-lived
computation.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> int <B>task_id</B> <I>()</I>
<DD><A NAME="IDX111"></A>
Returns the non-zero, non-negative integer identifier for the
currently-executing task.  Such integers are randomly selected for each task and
can therefore safely be used in circumstances where unpredictability is
required.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> value <B>suspend</B> <I>([int <VAR>seconds</VAR>])</I>
<DD><A NAME="IDX112"></A>
Suspends the current task, and resumes it after at least <VAR>seconds</VAR> seconds.
(If <VAR>seconds</VAR> is not provided, the task is suspended indefinitely; such a
task can only be resumed by use of the <CODE>resume()</CODE> function.)  When the
task is resumed, it will have a full quota of ticks and seconds.  This function
is useful for programs that run for a long time or require a lot of ticks.  If
<VAR>seconds</VAR> is negative, then <CODE>E_INVARG</CODE> is raised.  <CODE>Suspend()</CODE>
returns zero unless it was resumed via <CODE>resume()</CODE>, in which case it
returns the second argument given to that function.

</P>
<P>
In some sense, this function forks the `rest' of the executing task.  However,
there is a major difference between the use of <SAMP>`suspend(<VAR>seconds</VAR>)'</SAMP>
and the use of the <SAMP>`fork (<VAR>seconds</VAR>)'</SAMP>.  The <SAMP>`fork'</SAMP> statement
creates a new task (a <STRONG>forked task</STRONG>) while the currently-running task still
goes on to completion, but a <CODE>suspend()</CODE> suspends the currently-running
task (thus making it into a <STRONG>suspended task</STRONG>).  This difference may be best
explained by the following examples, in which one verb calls another:

</P>

<PRE>
.program   #0:caller_A
#0.prop = 1;
#0:callee_A();
#0.prop = 2;
.

.program   #0:callee_A
fork(5)
  #0.prop = 3;
endfork
.

.program   #0:caller_B
#0.prop = 1;
#0:callee_B();
#0.prop = 2;
.

.program   #0:callee_B
suspend(5);
#0.prop = 3;
.
</PRE>

<P>
Consider <CODE>#0:caller_A</CODE>, which calls <CODE>#0:callee_A</CODE>.  Such a task would
assign 1 to <CODE>#0.prop</CODE>, call <CODE>#0:callee_A</CODE>, fork a new task, return to
<CODE>#0:caller_A</CODE>, and assign 2 to <CODE>#0.prop</CODE>, ending this task.  Five
seconds later, if the forked task had not been killed, then it would begin to
run; it would assign 3 to <CODE>#0.prop</CODE> and then stop.  So, the final value of
<CODE>#0.prop</CODE> (i.e., the value after more than 5 seconds) would be 3.

</P>
<P>
Now consider <CODE>#0:caller_B</CODE>, which calls <CODE>#0:callee_B</CODE> instead of
<CODE>#0:callee_A</CODE>.  This task would assign 1 to <CODE>#0.prop</CODE>, call
<CODE>#0:callee_B</CODE>, and suspend.  Five seconds later, if the suspended task had
not been killed, then it would resume; it would assign 3 to <CODE>#0.prop</CODE>,
return to <CODE>#0:caller_B</CODE>, and assign 2 to <CODE>#0.prop</CODE>, ending the task.
So, the final value of <CODE>#0.prop</CODE> (i.e., the value after more than 5
seconds) would be 2.

</P>
<P>
A suspended task, like a forked task, can be described by the
<CODE>queued_tasks()</CODE> function and killed by the <CODE>kill_task()</CODE> function.
Suspending a task does not change its task id.  A task can be suspended again
and again by successive calls to <CODE>suspend()</CODE>.

</P>
<P>
By default, there is no limit to the number of tasks any player may suspend,
but such a limit can be imposed from within the database.  See the chapter on
server assumptions about the database for details.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> none <B>resume</B> <I>(int <VAR>task-id</VAR> [, <VAR>value</VAR>])</I>
<DD><A NAME="IDX113"></A>
Immediately ends the suspension of the suspended task with the given
<VAR>task-id</VAR>; that task's call to <CODE>suspend()</CODE> will return <VAR>value</VAR>,
which defaults to zero.  If <VAR>value</VAR> is of type <CODE>ERR</CODE>, it will be
raised, rather than returned, in the suspended task.  <CODE>Resume()</CODE> raises
<CODE>E_INVARG</CODE> if <VAR>task-id</VAR> does not specify an existing suspended task
and <CODE>E_PERM</CODE> if the programmer is neither a wizard nor the owner of the
specified task.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> list <B>queue_info</B> <I>([obj <VAR>player</VAR>])</I>
<DD><A NAME="IDX114"></A>
If <VAR>player</VAR> is omitted, returns a list of object numbers naming all players
that currently have active task queues inside the server.  If <VAR>player</VAR> is
provided, returns the number of background tasks currently queued for that
user.  It is guaranteed that <CODE>queue_info(<VAR>X</VAR>)</CODE> will return zero for
any <VAR>X</VAR> not in the result of <CODE>queue_info()</CODE>.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> list <B>queued_tasks</B> <I>()</I>
<DD><A NAME="IDX115"></A>
Returns information on each of the background tasks (i.e., forked, suspended or
reading) owned by the programmer (or, if the programmer is a wizard, all queued
tasks).  The returned value is a list of lists, each of which encodes certain
information about a particular queued task in the following format:

</P>

<PRE>
{<VAR>task-id</VAR>, <VAR>start-time</VAR>, <VAR>x</VAR>, <VAR>y</VAR>,
 <VAR>programmer</VAR>, <VAR>verb-loc</VAR>, <VAR>verb-name</VAR>, <VAR>line</VAR>, <VAR>this</VAR>}
</PRE>

<P>
where <VAR>task-id</VAR> is an integer identifier for this queued task,
<VAR>start-time</VAR> is the time after which this task will begin execution (in
<CODE>time()</CODE> format), <VAR>x</VAR> and <VAR>y</VAR> are obsolete values that are no
longer interesting, <VAR>programmer</VAR> is the permissions with which this task
will begin execution (and also the player who <STRONG>owns</STRONG> this task),
<VAR>verb-loc</VAR> is the object on which the verb that forked this task was
defined at the time, <VAR>verb-name</VAR> is that name of that verb, <VAR>line</VAR> is
the number of the first line of the code in that verb that this task will
execute, and <VAR>this</VAR> is the value of the variable <SAMP>`this'</SAMP> in that verb.
For reading tasks, <VAR>start-time</VAR> is <CODE>-1</CODE>.

</P>
<P>
The <VAR>x</VAR> and <VAR>y</VAR> fields are now obsolete and are retained only for
backward-compatibility reasons.  They may be reused for new purposes in some
future version of the server.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> none <B>kill_task</B> <I>(int <VAR>task-id</VAR>)</I>
<DD><A NAME="IDX116"></A>
Removes the task with the given <VAR>task-id</VAR> from the queue of waiting tasks.
If the programmer is not the owner of that task and not a wizard, then
<CODE>E_PERM</CODE> is raised.  If there is no task on the queue with the given
<VAR>task-id</VAR>, then <CODE>E_INVARG</CODE> is raised.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> list <B>callers</B> <I>([<VAR>include-line-numbers</VAR>])</I>
<DD><A NAME="IDX117"></A>
Returns information on each of the verbs and built-in functions currently
waiting to resume execution in the current task.  When one verb or function
calls another verb or function, execution of the caller is temporarily
suspended, pending the called verb or function returning a value.  At any given
time, there could be several such pending verbs and functions: the one that
called the currently executing verb, the verb or function that called that one,
and so on.  The result of <CODE>callers()</CODE> is a list, each element of which
gives information about one pending verb or function in the following format:

</P>

<PRE>
{<VAR>this</VAR>, <VAR>verb-name</VAR>, <VAR>programmer</VAR>, <VAR>verb-loc</VAR>, <VAR>player</VAR>, <VAR>line-number</VAR>}
</PRE>

<P>
For verbs, <VAR>this</VAR> is the initial value of the variable <SAMP>`this'</SAMP> in that
verb, <VAR>verb-name</VAR> is the name used to invoke that verb, <VAR>programmer</VAR> is
the player with whose permissions that verb is running, <VAR>verb-loc</VAR> is the
object on which that verb is defined, <VAR>player</VAR> is the initial value of the
variable <SAMP>`player'</SAMP> in that verb, and <VAR>line-number</VAR> indicates which line
of the verb's code is executing.  The <VAR>line-number</VAR> element is included
only if the <VAR>include-line-numbers</VAR> argument was provided and true.

</P>
<P>
For functions, <VAR>this</VAR>, <VAR>programmer</VAR>, and <VAR>verb-loc</VAR> are all
<CODE>#-1</CODE>, <VAR>verb-name</VAR> is the name of the function, and <VAR>line-number</VAR>
is an index used internally to determine the current state of the built-in
function.  The simplest correct test for a built-in function entry is

</P>

<PRE>
(VERB-LOC == #-1  &#38;&#38;  PROGRAMMER == #-1  &#38;&#38;  VERB-NAME != "")
</PRE>

<P>
The first element of the list returned by <CODE>callers()</CODE> gives information on
the verb that called the currently-executing verb, the second element describes
the verb that called that one, and so on.  The last element of the list
describes the first verb called in this task.
</DL>

</P>
<P>
<DL>
<DT><U>Function:</U> list <B>task_stack</B> <I>(int <VAR>task-id</VAR> [, <VAR>include-line-numbers</VAR>])</I>
<DD><A NAME="IDX118"></A>
Returns information like that returned by the <CODE>callers()</CODE> function, but
for the suspended task with the given <VAR>task-id</VAR>; the
<VAR>include-line-numbers</VAR> argument has the same meaning as in
<CODE>callers()</CODE>.  Raises <CODE>E_INVARG</CODE> if <VAR>task-id</VAR> does not specify an
existing suspended task and <CODE>E_PERM</CODE> if the programmer is neither a wizard
nor the owner of the specified task.
</DL>

</P>
<P><HR><P>
Go to the <A HREF="ProgrammersManual_1.html">first</A>, <A HREF="ProgrammersManual_53.html">previous</A>, <A HREF="ProgrammersManual_55.html">next</A>, <A HREF="ProgrammersManual_77.html">last</A> section, <A HREF="ProgrammersManual_toc.html">table of contents</A>.
</BODY>
</HTML>