NRE(3) Tcl Library Procedures NRE(3)______________________________________________________________________________NAME
Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv,
Tcl_NRCmdSwap, Tcl_NRAddCallback - Non-Recursive (stackless) evaluation
of Tcl scripts.
SYNOPSIS
#include <tcl.h>
Tcl_Command
Tcl_NRCreateCommand(interp, cmdName, proc, nreProc, clientData, deleteProc)
int
Tcl_NRCallObjProc(interp, nreProc, clientData, objc, objv)
int
Tcl_NREvalObj(interp, objPtr, flags)
int
Tcl_NREvalObjv(interp, objc, objv, flags)
int
Tcl_NRCmdSwap(interp, cmd, objc, objv, flags)
void
Tcl_NRAddCallback(interp, postProcPtr, data0, data1, data2, data3)
ARGUMENTS
Tcl_Interp *interp (in) Interpreter in which to
create or evaluate a com‐
mand.
char *cmdName (in) Name of a new command to
create.
Tcl_ObjCmdProc *proc (in) Implementation of a com‐
mand that will be called
whenever cmdName is
invoked as a command in
the unoptimized way.
Tcl_ObjCmdProc *nreProc (in) Implementation of a com‐
mand that will be called
whenever cmdName is
invoked and requested to
conserve the C stack.
ClientData clientData (in) Arbitrary one-word value
that will be passed to
proc, nreProc, deleteProc
and objProc.
Tcl_CmdDeleteProc *deleteProc (in/out) Procedure to call before
cmdName is deleted from
the interpreter. This
procedure allows for com‐
mand-specific cleanup. If
deletProc is NULL, then no
procedure is called before
the command is deleted.
int objc (in) Count of parameters pro‐
vided to the implementa‐
tion of a command.
Tcl_Obj **objv (in) Pointer to an array of Tcl
objects. Each object holds
the value of a single word
in the command to execute.
Tcl_Obj *objPtr (in) Pointer to a Tcl_Obj whose
value is a script to exe‐
cute.
int flags (in) ORed combination of flag
bits that specify addi‐
tional options.
TCL_EVAL_GLOBAL is the
only flag that is cur‐
rently supported.
Tcl_Command cmd (in)
Tcl_NRPostProc *postProcPtr (in) Pointer to a function that
will be invoked when the
command currently execut‐
ing in the interpreter
designated by interp com‐
pletes.
ClientData data0 (in)
ClientData data1 (in)
ClientData data2 (in)
ClientData data3 (in) data0 through data3 are
four one-word values that
will be passed to the
function designated by
postProcPtr when it is
invoked.
_________________________________________________________________DESCRIPTION
This series of C functions provides an interface whereby commands that
are implemented in C can be evaluated, and invoke Tcl commands scripts
and scripts, without consuming space on the C stack. The non-recursive
evaluation is done by installing a trampoline, a small piece of code
that invokes a command or script, and then executes a series of call‐
backs when the command or script returns.
The Tcl_NRCreateCommand function creates a Tcl command in the inter‐
preter designated by interp that is prepared to handle nonrecursive
evaluation with a trampoline. The cmdName argument gives the name of
the new command. If cmdName contains any namespace qualifiers, then the
new command is added to the specified namespace; otherwise, it is added
to the global namespace. proc gives the procedure that will be called
when the interpreter wishes to evaluate the command in an unoptimized
manner, and nreProc is the procedure that will be called when the
interpreter wishes to evaluate the command using a trampoline.
deleteProc is a function that will be called before the command is
deleted from the interpreter. When any of the three functions is
invoked, it is passed the clientData parameter.
Tcl_NRCreateCommand deletes any existing command name already associ‐
ated with the interpreter (however see below for an exception where the
existing command is not deleted). It returns a token that may be used
to refer to the command in subsequent calls to Tcl_GetCommandName. If
Tcl_NRCreateCommand is called for an interpreter that is in the process
of being deleted, then it does not create a new command, does not
delete any existing command of the same name, and returns NULL.
The proc and nreProc function are expected to conform to all the rules
set forth for the proc argument to Tcl_CreateObjCommand(3) (q.v.).
When a command that is written to cope with evaluation via trampoline
is invoked without a trampoline on the stack, it will usually respond
to the invocation by creating a trampoline and calling the trampoline-
enabled implementation of the same command. This call is done by means
of Tcl_NRCallObjProc. In the call to Tcl_NRCallObjProc, the interp,
clientData, objc and objv parameters should be the same ones that were
passed to proc. The nreProc parameter should designate the trampoline-
enabled implementation of the command.
Tcl_NREvalObj arranges for the script contained in objPtr to be evalu‐
ated in the interpreter designated by interp after the current command
(which must be trampoline-enabled) returns. It is the method by which a
command may invoke a script without consuming space on the C stack.
Similarly, Tcl_NREvalObjv arranges to invoke a single Tcl command whose
words have already been separated and substituted. The objc and objv
parameters give the words of the command to be evaluated when execution
reaches the trampoline.
Tcl_NRCmdSwap allows for trampoline evaluation of a command whose reso‐
lution is already known. The cmd parameter gives a Tcl_Command object
(returned from Tcl_CreateObjCmd or Tcl_GetCommandFromObj) identifying
the command to be invoked in the trampoline; this command must match
the word in objv[0]. The remaining arguments are as for Tcl_NREvalObj.
Tcl_NREvalObj, Tcl_NREvalObjv and Tcl_NRCmdSwap all accept a flags
parameter, which is an OR-ed-together set of bits to control evalua‐
tion. At the present time, the only flag available to callers is
TCL_EVAL_GLOBAL. If the TCL_EVAL_GLOBAL flag is set, the script or
command is evaluated in the global namespace. If it is not set, it is
evaluated in the current namespace.
All three of the routines return TCL_OK if command invocation has been
scheduled successfully. If for any reason command invocation cannot be
scheduled (for example, if the interpreter is unable to find the
requested command), they return TCL_ERROR with an appropriate message
left in the interpreter's result.
Tcl_NRAddCallback arranges to have a C function called when the current
trampoline-enabled command in the Tcl interpreter designated by interp
returns. The postProcPtr argument is a pointer to the callback func‐
tion, which must have arguments and return value consistent with the
Tcl_NRPostProc data type:
typedef int
Tcl_NRPostProc(
ClientData data[],
Tcl_Interp *interp,
int result);
When the trampoline invokes the callback function, the data parameter
will point to an array containing the four one-word quantities that
were passed to Tcl_NRAddCallback in the data0 through data3 parameters.
The Tcl interpreter will be designated by the interp parameter, and the
result parameter will contain the result (TCL_OK, TCL_ERROR,
TCL_RETURN, TCL_BREAK or TCL_CONTINUE) that was returned by the command
evaluation. The callback function is expected, in turn, either to
return a result to control further evaluation.
Multiple Tcl_NRAddCallback invocations may request multiple callbacks,
which may be to the same or different callback functions. If multiple
callbacks are requested, they are executed in last-in, first-out order,
that is, the most recently requested callback is executed first.
EXAMPLE
The usual pattern for Tcl commands that invoke other Tcl commands is
something like:
int TheCmdObjProc(
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
int result;
Tcl_Obj *objPtr;
... preparation ...
result = Tcl_EvalObjEx(interp, objPtr, 0);
... postprocessing ...
return result;
}
Tcl_CreateObjCommand(interp, "theCommand",
TheCmdObjProc, clientData,
TheCmdDeleteProc);
To enable a command like this one for trampoline-based evaluation, it
must be split into three pieces:
· A non-trampoline implementation, TheCmdNewObjProc, which will
simply create a trampoline and invoke the trampoline-based
implementation.
· A trampoline-enabled implementation, TheCmdNRObjProc. This
function will perform the initialization, request that the tram‐
poline call the postprocessing routine after command evaluation,
and finally, request that the trampoline call the inner command.
· A postprocessing routine, TheCmdPostProc. This function will
perform the postprocessing formerly done after the return from
the inner command in TheCmdObjProc.
The non-trampoline implementation is simple and stylized, containing a
single statement:
int
TheCmdNewObjProc
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
return Tcl_NRCallObjProc(interp, name,
TheCmdNRObjProc, clientData, objc, objv);
}
The trampoline-enabled implementation requests postprocessing, and
returns to the trampoline requesting command evaluation.
int
TheCmdNRObjProc
ClientData clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
... preparation ...
Tcl_NRAddCallback(interp, TheCmdPostProc,
data0, data1, data2, data3);
/* data0 .. data3 are up to four one-word items
* to pass to the postprocessing procedure */
return Tcl_NREvalObj(interp, objPtr, 0);
}
The postprocessing procedure does whatever the original command did
upon return from the inner evaluation.
int
TheCmdNRPostProc
ClientData data[],
Tcl_Interp *interp,
int result
{
/* data[0] .. data[4] are the four words of data
* passed to Tcl_NREvalObj */
... postprocessing ...
return result;
}
If theCommand is a command that results in multiple commands or scripts
being evaluated, its postprocessing routine may schedule additional
postprocessing and then request another command evaluation by means of
Tcl_NREvalObj or one of the other evaluation routines. Looping and
sequencing constructs may be implemented in this way.
Finally, to install a trampoline-enabled command in the interpreter,
Tcl_NRCreateCommand is used in place of Tcl_CreateObjCommand. It
accepts two command procedures instead of one. The first is for use
when no trampoline is yet on the stack, and the second is for use when
there is already a trampoline in place.
Tcl_NRCreateCommand(interp, "theCommand",
TheCmdObjProc, TheCmdNRObjProc, clientData,
TheCmdDeleteProc);
SEE ALSOTcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3),
Tcl_GetCommandFromObj(3)KEYWORDS
stackless, nonrecursive, execute, command, global, object, result,
script
COPYRIGHT
Copyright (c) 2008 by Kevin B. Kenny
Tcl 8.6 NRE(3)