Provided by: tcl8.6-doc_8.6.1-4ubuntu1_all 

NAME
Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv, Tcl_NRCmdSwap, Tcl_NRExprObj,
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)
int
Tcl_NRExprObj(interp, objPtr, resultPtr)
void
Tcl_NRAddCallback(interp, postProcPtr, data0, data1, data2, data3)
ARGUMENTS
Tcl_Interp *interp (in) Interpreter in which to create or evaluate a command.
char *cmdName (in) Name of a new command to create.
Tcl_ObjCmdProc *proc (in) Implementation of a command that will be called whenever cmdName
is invoked as a command in the unoptimized way.
Tcl_ObjCmdProc *nreProc (in) Implementation of a command 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 command-specific cleanup. If deleteProc
is NULL, then no procedure is called before the command is
deleted.
int objc (in) Count of parameters provided to the implementation of a command.
Tcl_Obj **objv (in) Pointer to an array of Tcl values. Each value 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 or expression to
execute.
int flags (in) ORed combination of flag bits that specify additional options.
TCL_EVAL_GLOBAL is the only flag that is currently supported.
Tcl_Command cmd (in) Token for a command that is to be used instead of the currently
executing command.
Tcl_Obj *resultPtr (out) Pointer to an unshared Tcl_Obj where the result of expression
evaluation is written.
Tcl_NRPostProc *postProcPtr (in) Pointer to a function that will be invoked when the command
currently executing in the interpreter designated by interp
completes.
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 callbacks when the command or script returns.
The Tcl_NRCreateCommand function creates a Tcl command in the interpreter 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 associated 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(3tcl) (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 evaluated 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 resolution is already known. The cmd
parameter gives a Tcl_Command token (returned from Tcl_CreateObjCommand 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_NREvalObjv.
Tcl_NREvalObj, Tcl_NREvalObjv and Tcl_NRCmdSwap all accept a flags parameter, which is an OR-ed-together
set of bits to control evaluation. At the present time, the only supported 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.
Tcl_NRExprObj arranges for the expression contained in objPtr to be evaluated 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 evaluate a Tcl expression without consuming space on the C stack. The
argument resultPtr is a pointer to an unshared Tcl_Obj where the result of expression evaluation is to be
written. If expression evaluation returns any code other than TCL_OK, the resultPtr value is left
untouched.
All of the routines return TCL_OK if command or expression invocation has been scheduled successfully. If
for any reason the scheduling cannot be completed (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
function, 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
TheCmdOldObjProc(
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",
TheCmdOldObjProc, 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 trampoline 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, 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[])
{
Tcl_Obj *objPtr;
... 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[3] are the four words of data
* passed to Tcl_NRAddCallback */
... 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",
TheCmdNewObjProc, TheCmdNRObjProc, clientData,
TheCmdDeleteProc);
SEE ALSO
Tcl_CreateCommand(3tcl), Tcl_CreateObjCommand(3tcl), Tcl_EvalObjEx(3tcl), Tcl_GetCommandFromObj(3tcl),
Tcl_ExprObj(3tcl)
KEYWORDS
stackless, nonrecursive, execute, command, global, value, result, script
COPYRIGHT
Copyright (c) 2008 by Kevin B. Kenny
Tcl 8.6 NRE(3tcl)