<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu May 17 04:33:52 GMT 2012 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='353'>
<header><title>NR-enabled Expressions for Extensions</title><author address="mailto:dgp@users.sf.net">Don Porter</author><status type='project' state='final' tclversion="8.6" vote='after'>$Revision: 1.7 $</status><history></history><created day='29' month='jul' year='2009' /></header>
<abstract>This TIP proposes the new public routine <emph style="bold">Tcl_NRExprObj</emph> to provide extension commands that evaluate Tcl expressions the ability to do so in a non-recursive manner.</abstract>
<body><section title="Background">
<para>In a few contexts, expressions that contain <emph style="bold">yield</emph> raise the error &quot;<emph style="italic">cannot yield: C stack busy</emph>&quot;; see Tcl Bugs 2823282 [<url ref="https://sourceforge.net/support/tracker.php?aid=2823282"/>] and 2823276 [<url ref="https://sourceforge.net/support/tracker.php?aid=2823276"/>]. This is because a few little-visited corners of Tcl&apos;s implementation call the routine <emph style="bold">Tcl_ExprObj</emph> and that routine is not NR-enabled.</para>
<para>For extensions wishing to evaluate Tcl expressions, <emph style="bold">Tcl_ExprObj</emph> is not little-visited. It is the public, supported, recommended tool for the job. Just as <tipref type="text" tip="322"/> provided a routine <emph style="bold">Tcl_NREvalObj</emph> as an NR-enabled replacement for <emph style="bold">Tcl_EvalObj</emph>, extensions wishing to NR-enable their commands need an analogous replacement for <emph style="bold">Tcl_ExprObj</emph>.</para>
</section>
<section title="Rationale">
<para>Tcl has a long history of providing extensions access to the same capabilities available to the built-in command set so that extension commands are on an equal footing, not in a second class status. Keeping with that, we want extensions to be able to create NR-enabled commands, so we need to provide an interface for extensions to evaluate expressions in an NR-enabled manner. This TIP can be seen as filling up a hole in <tipref type="text" tip="322"/>.</para>
</section>
<section title="Scope Limitations">
<para>The Tcl public C interface provides a whole family of variants of <emph style="bold">Tcl_ExprObj</emph>: <emph style="bold">Tcl_ExprLongObj</emph>, <emph style="bold">Tcl_ExprDoubleObj</emph>, <emph style="bold">Tcl_ExprBooleanObj</emph>, <emph style="bold">Tcl_ExprLong</emph>, <emph style="bold">Tcl_ExprDouble</emph>, <emph style="bold">Tcl_ExprBoolean</emph>, <emph style="bold">Tcl_ExprString</emph>. NR-enabled counterparts to these routines are <emph style="italic">not</emph> proposed. Extensions rewriting their command procedures to use the proposed <emph style="bold">Tcl_NRExprObj</emph> for sake of NR-enabling can at the same time be expected to convert from these convenience wrappers to more direct use of a single NR-enabled primitive.</para>
</section>
<section title="Proposal">
<para>Add the following routine to Tcl&apos;s public interface:</para>
<quote>int <emph style="bold">Tcl_NRExprObj</emph>(Tcl_Interp *<emph style="italic">interp</emph>, Tcl_Obj *<emph style="italic">objPtr</emph>, Tcl_Obj *<emph style="italic">resultPtr</emph>)</quote>
<para>This routine places on the NR stack a request that the Tcl non-recursive trampoline evaluate the <emph style="italic">objPtr</emph> value as a Tcl expression in interpreter <emph style="italic">interp</emph>. This routine returns the value <emph style="bold">TCL_OK</emph>, since there is (currently) no way this request operation can fail. The proposed interface still provides for an int return value so that future revisions to Tcl&apos;s internals have the freedom to change that without need to change the public interface.</para>
<para>The <emph style="italic">resultPtr</emph> argument must be an unshared Tcl value. When expression evaluation succeeds, the result of the expression is written to <emph style="italic">resultPtr</emph> in the same way that <emph style="bold">Tcl_SetStringObj</emph> would write a string value to an unshared Tcl value. If expression evaluation produces any return code other than <emph style="bold">TCL_OK</emph>, the value of <emph style="italic">resultPtr</emph> is left untouched.</para>
<para>Callers of <emph style="bold">Tcl_NRExprObj</emph> will also need to call <emph style="bold">Tcl_NRAddCallback</emph> to request a <emph style="bold">Tcl_NRPostProc</emph> callback routine be placed on the NR stack which can take care of managing <emph style="italic">resultPtr</emph> as appropriate depending on the <emph style="italic">result</emph> value.</para>
</section>
<section title="Implementation">
<para>The patch attached to Tcl Bug 2823282 [<url ref="https://sourceforge.net/support/tracker.php?aid=2823282"/>] implements this proposal.</para>
</section>
<section title="Compatibility">
<para>There should be no compatibility issues, since at the interface level this is just the addition of a new routine. Revisions to the internal implementations of existing routines should be harmless.</para>
</section>
<section title="Migration">
<para>As an example for extensions to follow, consider this template for a <emph style="bold">Tcl_ObjCmdProc</emph> currently calling <emph style="bold">Tcl_ExprObj</emph>.</para>
<verbatim><vline encoding='base64'>aW50IE9iakNtZChDbGllbnREYXRhIGNkLCBUY2xfSW50ZXJwICppbnRlcnAsIGludCBvYmpjLCBUY2xfT2JqICpjb25zdCBvYmp2W10p</vline><vline encoding='base64'>eyAgIGludCBjb2RlOw==</vline><vline encoding='base64'>ICAgIFRjbF9PYmogKnJlc3VsdFB0cjs=</vline><vline encoding='base64'>ICAgIC8qIGRldGVybWluZSBleHByZXNzaW9uLCBvYmpQdHIgKi8=</vline><vline encoding='base64'>ICAgIGNvZGUgPSBUY2xfRXhwck9iaihpbnRlcnAsIG9ialB0ciwgJnJlc3VsdFB0cik7</vline><vline encoding='base64'>ICAgIGlmIChjb2RlICE9IFRDTF9PSykge3JldHVybiBjb2RlfQ==</vline><vline encoding='base64'>ICAgIC8qIHJlc3VsdFB0ciBob2xkcyBleHByZXNzaW9uIHJlc3VsdDsgY29udGludWUgKi8=</vline><vline encoding='base64'>fQ==</vline><vline encoding='base64'></vline><vline encoding='base64'>VGNsX0NyZWF0ZU9iakNvbW1hbmQoaW50ZXJwLCBuYW1lLCBPYmpDbWQsIC8qIC4uLiAqLyk7</vline></verbatim>
<para>To use <emph style="bold">Tcl_NRExprObj</emph> to NR-enable this command, rewrite along these lines:</para>
<verbatim><vline encoding='base64'>aW50IE9iakNtZChDbGllbnREYXRhIGNkLCBUY2xfSW50ZXJwICppbnRlcnAsIGludCBvYmpjLCBUY2xfT2JqICpjb25zdCBvYmp2W10p</vline><vline encoding='base64'>eyAgIHJldHVybiBUY2xfTlJDYWxsT2JqUHJvYyhpbnRlcnAsIE5ST2JqQ21kLCBjZCwgb2JqYywgb2Jqdik7ICB9</vline><vline encoding='base64'></vline><vline encoding='base64'>aW50IE5ST2JqQ21kKENsaWVudERhdGEgY2QsIFRjbF9JbnRlcnAgKmludGVycCwgaW50IG9iamMsIFRjbF9PYmogKmNvbnN0IG9ianZbXSk=</vline><vline encoding='base64'>eyAgIFRjbF9PYmogKnJlc3VsdFB0ciA9IFRjbF9OZXdPYmooKTs=</vline><vline encoding='base64'>ICAgIC8qIGRldGVybWluZSBleHByZXNzaW9uLCBvYmpQdHIgKi8=</vline><vline encoding='base64'>ICAgIFRjbF9OUkFkZENhbGxiYWNrKGludGVycCwgQ2FsbGJhY2ssIHJlc3VsdFB0ciwgLyouLi4qLyk7</vline><vline encoding='base64'>ICAgIHJldHVybiBUY2xfTlJFeHByT2JqKGludGVycCwgb2JqUHRyLCByZXN1bHRQdHIpOw==</vline><vline encoding='base64'>fQ==</vline><vline encoding='base64'></vline><vline encoding='base64'>aW50IENhbGxiYWNrKENsaWVudERhdGEgZGF0YVtdLCBUY2xfSW50ZXJwICppbnRlcnAsIGludCBjb2RlKQ==</vline><vline encoding='base64'>eyAgIFRjbF9PYmogKnJlc3VsdFB0ciA9IGRhdGFbMF07</vline><vline encoding='base64'>ICAgIGlmIChjb2RlICE9IFRDTF9PSykge1RjbF9EZWNyUmVmQ291bnQocmVzdWx0UHRyKTsgcmV0dXJuIGNvZGU7fQ==</vline><vline encoding='base64'>ICAgIC8qIHJlc3VsdFB0ciBob2xkcyBleHByZXNzaW9uIHJlc3VsdDsgY29udGludWUgKi8=</vline><vline encoding='base64'>fQ==</vline><vline encoding='base64'></vline><vline encoding='base64'>VGNsX05SQ3JlYXRlQ29tbWFuZChpbnRlcnAsIG5hbWUsIE9iakNtZCwgTlJPYmpDbWQsIC8qLi4uKi8pOw==</vline></verbatim>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>

