diff options
Diffstat (limited to 'doc/expr.n')
-rw-r--r-- | doc/expr.n | 433 |
1 files changed, 433 insertions, 0 deletions
diff --git a/doc/expr.n b/doc/expr.n new file mode 100644 index 0000000..d33623c --- /dev/null +++ b/doc/expr.n @@ -0,0 +1,433 @@ +'\" +'\" Copyright (c) 1993 The Regents of the University of California. +'\" Copyright (c) 1994-2000 Sun Microsystems, Inc. +'\" Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH expr n 8.5 Tcl "Tcl Built-In Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +expr \- Evaluate an expression +.SH SYNOPSIS +\fBexpr \fIarg \fR?\fIarg arg ...\fR? +.BE +.SH DESCRIPTION +.PP +Concatenates \fIarg\fRs, separated by a space, into an expression, and evaluates +that expression, returning its value. +The operators permitted in an expression include a subset of +the operators permitted in C expressions. For those operators +common to both Tcl and C, Tcl applies the same meaning and precedence +as the corresponding C operators. +The value of an expression is often a numeric result, either an integer or a +floating-point value, but may also be a non-numeric value. +For example, the expression +.PP +.CS +\fBexpr\fR 8.2 + 6 +.CE +.PP +evaluates to 14.2. +Expressions differ from C expressions in the way that +operands are specified. Expressions also support +non-numeric operands, string comparisons, and some +additional operators not found in C. +.PP +When an expression evaluates to an integer, the value is the decimal form of +the integer, and when an expression evaluates to a floating-point number, the +value is the form produced by the \fB%g\fR format specifier of Tcl's +\fBformat\fR command. +.SS OPERANDS +.PP +An expression consists of a combination of operands, operators, parentheses and +commas, possibly with whitespace between any of these elements, which is +ignored. +An integer operand may be specified in decimal (the normal case, the optional +first two characters are \fB0d\fR), binary +(the first two characters are \fB0b\fR), octal +(the first two characters are \fB0o\fR), or hexadecimal +(the first two characters are \fB0x\fR) form. For +compatibility with older Tcl releases, an operand that begins with \fB0\fR is +interpreted as an octal integer even if the second character is not \fBo\fR. +A floating-point number may be specified in any of several +common decimal formats, and may use the decimal point \fB.\fR, +\fBe\fR or \fBE\fR for scientific notation, and +the sign characters \fB+\fR and \fB\-\fR. The +following are all valid floating-point numbers: 2.1, 3., 6e4, 7.91e+16. +The strings \fBInf\fR +and \fBNaN\fR, in any combination of case, are also recognized as floating point +values. An operand that doesn't have a numeric interpretation must be quoted +with either braces or with double quotes. +.PP +An operand may be specified in any of the following ways: +.IP [1] +As a numeric value, either integer or floating-point. +.IP [2] +As a boolean value, using any form understood by \fBstring is\fR +\fBboolean\fR. +.IP [3] +As a variable, using standard \fB$\fR notation. +The value of the variable is then the value of the operand. +.IP [4] +As a string enclosed in double-quotes. +Backslash, variable, and command substitution are performed as described in +\fBTcl\fR. +.IP [5] +As a string enclosed in braces. +The operand is treated as a braced value as described in \fBTcl\fR. +.IP [6] +As a Tcl command enclosed in brackets. +Command substitution is performed as described in \fBTcl\fR. +.IP [7] +As a mathematical function such as \fBsin($x)\fR, whose arguments have any of the above +forms for operands. See \fBMATH FUNCTIONS\fR below for +a discussion of how mathematical functions are handled. +.PP +Because \fBexpr\fR parses and performs substitutions on values that have +already been parsed and substituted by \fBTcl\fR, it is usually best to enclose +expressions in braces to avoid the first round of substitutions by +\fBTcl\fR. +.PP +Below are some examples of simple expressions where the value of \fBa\fR is 3 +and the value of \fBb\fR is 6. The command on the left side of each line +produces the value on the right side. +.PP +.CS +.ta 6c +\fBexpr\fR 3.1 + $a \fI6.1\fR +\fBexpr\fR 2 + "$a.$b" \fI5.6\fR +\fBexpr\fR 4*[llength "6 2"] \fI8\fR +\fBexpr\fR {{word one} < "word $a"} \fI0\fR +.CE +.SS OPERATORS +.PP +For operators having both a numeric mode and a string mode, the numeric mode is +chosen when all operands have a numeric interpretation. The integer +interpretation of an operand is preferred over the floating-point +interpretation. To ensure string operations on arbitrary values it is generally a +good idea to use \fBeq\fR, \fBne\fR, or the \fBstring\fR command instead of +more versatile operators such as \fB==\fR. +.PP +Unless otherwise specified, operators accept non-numeric operands. The value +of a boolean operation is 1 if true, 0 otherwise. See also \fBstring is\fR +\fBboolean\fR. The valid operators, most of which are also available as +commands in the \fBtcl::mathop\fR namespace (see \fBmathop\fR(n)), are listed +below, grouped in decreasing order of precedence: +.TP 20 +\fB\-\0\0+\0\0~\0\0!\fR +. +Unary minus, unary plus, bit-wise NOT, logical NOT. These operators +may only be applied to numeric operands, and bit-wise NOT may only be +applied to integers. +.TP 20 +\fB**\fR +. +Exponentiation. Valid for numeric operands. +.TP 20 +\fB*\0\0/\0\0%\fR +. +Multiply and divide, which are valid for numeric operands, and remainder, which +is valid for integers. The remainder, an absolute value smaller than the +absolute value of the divisor, has the same sign as the divisor. +.RS +.PP +When applied to integers, division and remainder can be +considered to partition the number line into a sequence of +adjacent non-overlapping pieces, where each piece is the size of the divisor; +the quotient identifies which piece the dividend lies within, and the +remainder identifies where within that piece the dividend lies. A +consequence of this is that the result of +.QW "-57 \fB/\fR 10" +is always -6, and the result of +.QW "-57 \fB%\fR 10" +is always 3. +.RE +.TP 20 +\fB+\0\0\-\fR +. +Add and subtract. Valid for numeric operands. +.TP 20 +\fB<<\0\0>>\fR +. +Left and right shift. Valid for integers. +A right shift always propagates the sign bit. +.TP 20 +\fB<\0\0>\0\0<=\0\0>=\fR +. +Boolean less than, greater than, less than or equal, and greater than or equal. +.TP 20 +\fB==\0\0!=\fR +. +Boolean equal and not equal. +.TP 20 +\fBeq\0\0ne\fR +. +Boolean string equal and string not equal. +.TP 20 +\fBin\0\0ni\fR +. +List containment and negated list containment. The first argument is +interpreted as a string, the second as a list. \fBin\fR tests for membership +in the list, and \fBni\fR is the inverse. +.TP 20 +\fB&\fR +. +Bit-wise AND. Valid for integer operands. +.TP 20 +\fB^\fR +. +Bit-wise exclusive OR. Valid for integer operands. +.TP 20 +\fB|\fR +. +Bit-wise OR. Valid for integer operands. +.TP 20 +\fB&&\fR +. +Logical AND. If both operands are true, the result is 1, or 0 otherwise. + +.TP 20 +\fB||\fR +. +Logical OR. If both operands are false, the result is 0, or 1 otherwise. +.TP 20 +\fIx\fB?\fIy\fB:\fIz\fR +. +If-then-else, as in C. If \fIx\fR is false , the result is the value of +\fIy\fR. Otherwise the result is the value of \fIz\fR. +.PP +The exponentiation operator promotes types in the same way that the multiply +and divide operators do, and the result is is the same as the result of +\fBpow\fR. +Exponentiation groups right-to-left within a precedence level. Other binary +operators group left-to-right. For example, the value of +.PP +.CS +\fBexpr\fR {4*2 < 7} +.CE +.PP +is 0, while the value of +.PP +.CS +\fBexpr\fR {2**3**2} +.CE +.PP +is 512. +.PP +As in C, \fB&&\fR, \fB||\fR, and \fB?:\fR feature +.QW "lazy evaluation" , +which means that operands are not evaluated if they are +not needed to determine the outcome. For example, in +.PP +.CS +\fBexpr\fR {$v ? [a] : [b]} +.CE +.PP +only one of \fB[a]\fR or \fB[b]\fR is evaluated, +depending on the value of \fB$v\fR. This is not true of the normal Tcl parser, +so it is normally recommended to enclose the arguments to \fBexpr\fR in braces. +Without braces, as in +\fBexpr\fR $v ? [a] : [b] +both \fB[a]\fR and \fB[b]\fR are evaluated before \fBexpr\fR is even called. +.PP +For more details on the results +produced by each operator, see the documentation for C. +.SS "MATH FUNCTIONS" +.PP +A mathematical function such as \fBsin($x)\fR is replaced with a call to an ordinary +Tcl command in the \fBtcl::mathfunc\fR namespace. The evaluation +of an expression such as +.PP +.CS +\fBexpr\fR {sin($x+$y)} +.CE +.PP +is the same in every way as the evaluation of +.PP +.CS +\fBexpr\fR {[tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]]} +.CE +.PP +which in turn is the same as the evaluation of +.PP +.CS +tcl::mathfunc::sin [\fBexpr\fR {$x+$y}] +.CE +.PP +\fBtcl::mathfunc::sin\fR is resolved as described in +\fBNAMESPACE RESOLUTION\fR in the \fBnamespace\fR(n) documentation. Given the +default value of \fBnamespace path\fR, \fB[namespace +current]::tcl::mathfunc::sin\fR or \fB::tcl::mathfunc::sin\fR are the typical +resolutions. +.PP +As in C, a mathematical function may accept multiple arguments separated by commas. Thus, +.PP +.CS +\fBexpr\fR {hypot($x,$y)} +.CE +.PP +becomes +.PP +.CS +tcl::mathfunc::hypot $x $y +.CE +.PP +See the \fBmathfunc\fR(n) documentation for the math functions that are +available by default. +.SS "TYPES, OVERFLOW, AND PRECISION" +.PP +When needed to guarantee exact performance, internal computations involving +integers use the LibTomMath multiple precision integer library. In Tcl releases +prior to 8.5, integer calculations were performed using one of the C types +\fIlong int\fR or \fITcl_WideInt\fR, causing implicit range truncation +in those calculations where values overflowed the range of those types. +Any code that relied on these implicit truncations should instead call +\fBint()\fR or \fBwide()\fR, which do truncate. +.PP +Internal floating-point computations are +performed using the \fIdouble\fR C type. +When converting a string to floating-point value, exponent overflow is +detected and results in the \fIdouble\fR value of \fBInf\fR or +\fB\-Inf\fR as appropriate. Floating-point overflow and underflow +are detected to the degree supported by the hardware, which is generally +fairly reliable. +.PP +Conversion among internal representations for integer, floating-point, and +string operands is done automatically as needed. For arithmetic computations, +integers are used until some floating-point number is introduced, after which +floating-point values are used. For example, +.PP +.CS +\fBexpr\fR {5 / 4} +.CE +.PP +returns 1, while +.PP +.CS +\fBexpr\fR {5 / 4.0} +\fBexpr\fR {5 / ( [string length "abcd"] + 0.0 )} +.CE +.PP +both return 1.25. +A floating-point result can be distinguished from an integer result by the +presence of either +.QW \fB.\fR +or +.QW \fBe\fR +.PP +. For example, +.PP +.CS +\fBexpr\fR {20.0/5.0} +.CE +.PP +returns \fB4.0\fR, not \fB4\fR. +.SH "PERFORMANCE CONSIDERATIONS" +.PP +Where an expression contains syntax that Tcl would otherwise perform +substitutions on, enclosing an expression in braces or otherwise quoting it +so that it's a static value allows the Tcl compiler to generate bytecode for +the expression, resulting in better speed and smaller storage requirements. +This also avoids issues that can arise if Tcl is allowed to perform +substitution on the value before \fBexpr\fR is called. +.PP +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. +.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 +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. + +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. +.SH EXAMPLES +.PP +A numeric comparison whose result is 1: +.CS +\fBexpr\fR {"0x03" > "2"} +.CE +.PP +A string comparison whose result is 1: +.CS +\fBexpr\fR {"0y" > "0x12"} +.CE +.PP +Define a procedure that computes an +.QW interesting +mathematical function: +.PP +.CS +proc tcl::mathfunc::calc {x y} { + \fBexpr\fR { ($x**2 - $y**2) / exp($x**2 + $y**2) } +} +.CE +.PP +Convert polar coordinates into cartesian coordinates: +.PP +.CS +# convert from ($radius,$angle) +set x [\fBexpr\fR { $radius * cos($angle) }] +set y [\fBexpr\fR { $radius * sin($angle) }] +.CE +.PP +Convert cartesian coordinates into polar coordinates: +.PP +.CS +# convert from ($x,$y) +set radius [\fBexpr\fR { hypot($y, $x) }] +set angle [\fBexpr\fR { atan2($y, $x) }] +.CE +.PP +Print a message describing the relationship of two string values to +each other: +.PP +.CS +puts "a and b are [\fBexpr\fR {$a eq $b ? {equal} : {different}}]" +.CE +.PP +Set a variable indicating whether an environment variable is defined and has +value of true: +.PP +.CS +set isTrue [\fBexpr\fR { + [info exists ::env(SOME_ENV_VAR)] && + [string is true -strict $::env(SOME_ENV_VAR)] +}] +.CE +.PP +Generate a random integer in the range 0..99 inclusive: +.PP +.CS +set randNum [\fBexpr\fR { int(100 * rand()) }] +.CE +.SH "SEE ALSO" +array(n), for(n), if(n), mathfunc(n), mathop(n), namespace(n), proc(n), +string(n), Tcl(n), while(n) +.SH KEYWORDS +arithmetic, boolean, compare, expression, fuzzy comparison +.SH COPYRIGHT +.nf +Copyright (c) 1993 The Regents of the University of California. +Copyright (c) 1994-2000 Sun Microsystems Incorporated. +Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved. +.fi +'\" Local Variables: +'\" mode: nroff +'\" End: |