Exemple #1
0
        public TCL.CompletionCode cmdProc(Interp interp, TclObject[] argv)
        {
            // Create the call frame and parameter bindings

            CallFrame frame = interp.newCallFrame(this, argv);

            // Execute the body

            interp.pushDebugStack(srcFileName, srcLineNumber);
            try
            {
                Parser.eval2(interp, body.array, body.index, body_length, 0);
            }
            catch (TclException e)
            {
                TCL.CompletionCode code = e.getCompletionCode();
                if (code == TCL.CompletionCode.RETURN)
                {
                    TCL.CompletionCode realCode = interp.updateReturnInfo();
                    if (realCode != TCL.CompletionCode.OK)
                    {
                        e.setCompletionCode(realCode);
                        throw;
                    }
                }
                else if (code == TCL.CompletionCode.ERROR)
                {
                    interp.addErrorInfo("\n    (procedure \"" + argv[0] + "\" line " + interp.errorLine + ")");
                    throw;
                }
                else if (code == TCL.CompletionCode.BREAK)
                {
                    throw new TclException(interp, "invoked \"break\" outside of a loop");
                }
                else if (code == TCL.CompletionCode.CONTINUE)
                {
                    throw new TclException(interp, "invoked \"continue\" outside of a loop");
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                interp.popDebugStack();

                // The check below is a hack.  The problem is that there
                // could be unset traces on the variables, which cause
                // scripts to be evaluated.  This will clear the
                // errInProgress flag, losing stack trace information if
                // the procedure was exiting with an error.  The code
                // below preserves the flag.  Unfortunately, that isn't
                // really enough: we really should preserve the errorInfo
                // variable too (otherwise a nested error in the trace
                // script will trash errorInfo).  What's really needed is
                // a general-purpose mechanism for saving and restoring
                // interpreter state.

                if (interp.errInProgress)
                {
                    frame.dispose();
                    interp.errInProgress = true;
                }
                else
                {
                    frame.dispose();
                }
            }
            return(TCL.CompletionCode.RETURN);
        }