Provided by: tcl8.6-doc_8.6.5+dfsg-2_all bug

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