From 774c2050f147750c96d391c1150c8026a9864ac3 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Jun 2019 18:24:05 +0000 Subject: Remove declarations that are never defined. --- generic/tclInt.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 57367fa..821a39f 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3287,39 +3287,21 @@ MODULE_SCOPE int TclDivOpCmd(ClientData clientData, MODULE_SCOPE int TclCompileDivOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -MODULE_SCOPE int TclLessOpCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int TclCompileLessOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -MODULE_SCOPE int TclLeqOpCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int TclCompileLeqOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -MODULE_SCOPE int TclGreaterOpCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int TclCompileGreaterOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -MODULE_SCOPE int TclGeqOpCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int TclCompileGeqOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -MODULE_SCOPE int TclEqOpCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int TclCompileEqOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -MODULE_SCOPE int TclStreqOpCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); MODULE_SCOPE int TclCompileStreqOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); -- cgit v0.12 From 5f72a5554c21a6f9ef8f355452fd19c1914da786 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Jun 2019 18:33:28 +0000 Subject: More bytecodes are non-throwing. --- generic/tclAssembly.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index b6bebb6..1a5e5f4 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -513,6 +513,7 @@ static const unsigned char NonThrowingByteCodes[] = { INST_PUSH1, INST_PUSH4, INST_POP, INST_DUP, /* 1-4 */ INST_JUMP1, INST_JUMP4, /* 34-35 */ INST_END_CATCH, INST_PUSH_RESULT, INST_PUSH_RETURN_CODE, /* 70-72 */ + INST_STR_EQ, INST_STR_NEQ, INST_STR_CMP, INST_STR_LEN, /* 73-76 */ INST_LIST, /* 79 */ INST_OVER, /* 95 */ INST_PUSH_RETURN_OPTIONS, /* 108 */ -- cgit v0.12 From 39fba10b45e247bf94cdca222334c7cd4eb40087 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Jun 2019 18:44:18 +0000 Subject: More localized documentation of lazy operators. --- doc/expr.n | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/expr.n b/doc/expr.n index 2a0af7e..58a4b7f 100644 --- a/doc/expr.n +++ b/doc/expr.n @@ -106,7 +106,7 @@ Then the command on the left side of each of the lines below will produce the value on the right side of the line: .PP .CS -.ta 6c +.ta 8c \fBexpr\fR 3.1 + $a \fI6.1\fR \fBexpr\fR 2 + "$a.$b" \fI5.6\fR \fBexpr\fR 4*[llength "6 2"] \fI8\fR @@ -201,18 +201,23 @@ Bit-wise OR. Valid for integer operands only. Logical AND. Produces a 1 result if both operands are non-zero, 0 otherwise. Valid for boolean and numeric (integers or floating-point) operands only. +This operator evaluates lazily; it only evaluates its second operand if it +must in order to determine its result. .TP 20 \fB||\fR . Logical OR. Produces a 0 result if both operands are zero, 1 otherwise. Valid for boolean and numeric (integers or floating-point) operands only. +This operator evaluates lazily; it only evaluates its second operand if it +must in order to determine its result. .TP 20 -\fIx\fB?\fIy\fB:\fIz\fR +\fIx \fB?\fI y \fB:\fI z\fR . If-then-else, as in C. If \fIx\fR evaluates to non-zero, then the result is the value of \fIy\fR. Otherwise the result is the value of \fIz\fR. The \fIx\fR operand must have a boolean or numeric value. +This operator evaluates lazily; it evaluates only one of \fIy\fR or \fIz\fR. .PP See the C manual for more details on the results produced by each operator. -- cgit v0.12 From 6a3773f6119ffaee96382a12d282e033a6a0bf95 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Jun 2019 18:58:44 +0000 Subject: Doc formatting and advice about double substitution in expressions. --- doc/expr.n | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/doc/expr.n b/doc/expr.n index 6acc4bf..996407a 100644 --- a/doc/expr.n +++ b/doc/expr.n @@ -343,25 +343,45 @@ substitution on the value before \fBexpr\fR is called. In the following example, the value of the expression is 11 because the Tcl parser first substitutes \fB$b\fR and \fBexpr\fR then substitutes \fB$a\fR. Enclosing the expression in braces would result in a syntax error. +.PP .CS set a 3 set b {$a + 2} \fBexpr\fR $b*4 .CE .PP - -When an expression is generated at runtime, like the one above is, the bytcode +When an expression is generated at runtime, like the one above is, the bytecode compiler must ensure that new code is generated each time the expression is evaluated. This is the most costly kind of expression from a performance perspective. In such cases, consider directly using the commands described in the \fBmathfunc\fR(n) or \fBmathop\fR(n) documentation instead of \fBexpr\fR. - +.PP Most expressions are not formed at runtime, but are literal strings or contain substitutions that don't introduce other substitutions. To allow the bytecode compiler to work with an expression as a string literal at compilation time, ensure that it contains no substitutions or that it is enclosed in braces or otherwise quoted to prevent Tcl from performing substitutions, allowing \fBexpr\fR to perform them instead. +.PP +If it is necessary to include a non-constant expression string within the +wider context of an otherwise-constant expression, the most efficient +technique is to put the varying part inside a recursive \fBexpr\fR, as this at +least allows for the compilation of the outer part, though it does mean that +the varying part must itself be evaluated as a separate expression. Thus, in +this example the result is 20 and the outer expression benefits from fully +cached bytecode compilation. +.PP +.CS +set a 3 +set b {$a + 2} +\fBexpr\fR {[\fBexpr\fR $b] * 4} +.CE +.PP +In general, you should enclose your expression in braces wherever possible, +and where not possible, the argument to \fBexpr\fR should be an expression +defined elsewhere as simply as possible. It is usually more efficient and +safer to use other techniques (e.g., the commands in the \fBtcl::mathop\fR +namespace) than it is to do complex expression generation. .SH EXAMPLES .PP A numeric comparison whose result is 1: -- cgit v0.12