expressions
Expressions apply operators
to numeric and string operands, and return a result.
They can be used in
$[...] expression subs,
the condition of
/if and
/while statements,
the condition of /def -E,
and as arguments to /return,
/result, and
/test commands.
Operands
Operands can be any of:
- Integer constants (e.g.,
42
).
- Real decimal point constants ("reals", for short) containing
a decimal point (e.g.,
12.3456789
) or
exponent (e.g., 1e-2
) or
both (e.g., 1.23e4
).
- Time duration ("dtime") values of the form hours:minutes,
hours:minutes:seconds, or
seconds (where seconds may contain a decimal point
followed by up to 6 digits),
will be interpreted as real seconds (e.g., 0:01:02.3 == 62.3),
and can be used anywhere a number is expected.
- Absolute time ("atime") values, in the form of a number with up to 6
decimal places. On most systems, this represents the number of seconds
since 1970-01-01 00:00:00 UTC.
- Strings of characters, surrounded with quotes (", ', or `, with the
same kind of quote on each end), like
"hello world"
.
- Variable references (see below)
like
visual
.
- Variable substitutions
(see below) like
{visual}
and {1}
.
- Macro substitutions
like
${COMPRESS_SUFFIX}
.
- Command substitutions
like
$(/listworlds
-s)
.
Named variables may be accessed by
simply using their name (with no leading '%'). This is called a
variable reference, and is the
preferred way of using a
variable in an expression.
The special substitutions
(*,
?,
#,
n,
Ln,
Pn,
R)
may not be used this way.
Variable substitutions of the
form "{selector}" and
"{selector-default}" may be
used. They follow the same rules as
variable substitution in
macros, except that there is no leading
'%', and the '{' and '}' are required.
The special substitutions
(*,
?,
#,
n,
Ln,
Pn,
R)
are allowed.
Macro-style
variable substitutions
beginning with '%' may also be used, but are not
recommended, since the multiple '%'s required in nested
macros can quickly get confusing. It
always easier to use one of the above methods.
Operators
In the following list, operators are listed in groups, from highest to
lowest precedence. Operators listed together have equal precedence. The
letters in the table below correspond to the type of objects acted on by
the operators:
n for numeric (integer or real);
s for string;
e for any expression.
All operators group left-to-right except assignment,
which groups right-to-left.
If any binary numeric operator is applied to two integers, the result
will be an integer, unless the result would overflow, in which case it
is converted to real. If either operand is a real, the other will
be converted to real if it is not already a real, and the result will be
a real.
- (e)
- Parentheses, for grouping.
- func(args)
- Perform function
func on arguments args.
(see: functions).
- !n
- Boolean NOT (1 if n==0, otherwise 0).
- +n
- Unary positive (useful for converting a string to a number).
- -n
- Unary negative.
- ++v
- Equivalent to
(v := v + 1)
.
- --v
- Equivalent to
(v := v - 1)
.
- n1 * n2
- Numeric multiplication.
- n1 / n2
- Numeric division.
Remember, if both operands are type integer, the result will be
truncated to integer.
- n1 + n2
- Numeric addition.
- n1 - n2
- Numeric subtraction.
- n1 = n2
- Numeric equality (but easily confused with assignment;
you are advised to use
==
instead).
- n1 == n2
- Numeric equality.
- n1 != n2
- Numeric inequality.
- s1 =~ s2
- String equality (case sensitive,
attribute insensitive).
- s1 !~ s2
- String inequality (case sensitive,
attribute insensitive).
- s1 =/ s2
- String s1 matches
glob pattern s2.
- s1 !/ s2
- String s1 does not match
glob pattern s2.
- n1 < n2
- Numeric less than.
- n1 <= n2
- Numeric less than or equal.
- n1 > n2
- Numeric greater than.
- n1 >= n2
- Numeric greater than or equal.
- n1 & n2
- Boolean AND. n2 will be evaluated if and only if
n1 is nonzero.
- n1 | n2
- Boolean OR. n2 will be evaluated if and only if
n1 is zero.
- n ? e1 : e2
n ? : e2
- Conditional. If n is nonzero, the result is the
value of expression
e1; otherwise it is the value of
expression e2.
If e1 is omitted, the value of n is used in
its place.
Note that digits followed by a colon is interpreted as a dtime value,
so if the e2 operand of the ?: operator is an integer,
you must separate it from the colon (with a space or parenthesis,
for example).
- v := e
- Assignment. The identifier "v" refers to the
variable in the nearest scope.
If not found, a new variable
is created at the global level, as if by
/set.
If v is a
special variable,
the value of e may need to be converted to the type of
v, or the assignment may fail altogther if the value
is not legal for v. The value of the assignment
expression is the new value of v.
- v += n
- Equivalent to
v := v + (n)
.
- v -= n
- Equivalent to
v := v - (n)
.
- v *= n
- Equivalent to
v := v * (n)
.
- v /= n
- Equivalent to
v := v / (n)
.
- e1 , e2
- Comma. Expressions
e1 and e2 are evaluated; the result is the
value of e2. Only useful if e1 has some side
effect.
The comparison operators return 0 for false, nonzero for true. The boolean
operators (& and |) stop evaluating as soon as the value of the
expression is known
("short-circuit"), and return the value of the last operand evaluated.
This does not affect the value of the
expression, but is important when
the second operand performs side effects.
Normal (non-enumerated)
Variables set with any of the
assignment operators keep the type of the
expression assigned to them.
This is different than /set and
/let, which always assign a string value
to the variables.
This distinction is important for real numeric values, which lose precision
if converted to a string and back.
All operands will be automatically converted to the type expected by the
operator.
- String to numeric: leading signs, digits, colons, and exponents are
interpreted as an integer, decimal (real), or dtime (real) value; e.g.,
"12abc" becomes 12,
"12.3junk" becomes 12.3,
"0:01:02.3" becomes 0:01:02.3,
and "xyz" becomes 0.
- Integer to real: straightforward.
- Real to integer: the fractional part is truncated.
- Enumerated variable to
string: straightforward string value.
- Enumerated variable to
numeric: one integer stands for each of the allowed values.
"Off" is always 0, "on" is always 1, etc.
This makes
(!visual)
and (visual == 0)
the same
as (visual =~ 'off')
.
- Integer to string: straightforward.
- Real to string: decimal notation if the exponent
is greater than -5 and less than
%sigfigs,
otherwise exponential notation.
- Normal (non-enumerated)
variables are treated as whatever
type their value has.
Examples
Given the variables
/set X=5
/set name=Hawkeye
/set visual=1
here are some expressions and
their values:
Expression Value Comments
---- ----- --------
3 + X * 2 13 3 + (5 * 2) = 13.
"foo" =~ "bar" 0 "foo" is not identical to "bar".
name =/ 'hawk*' 1 "Hawkeye" matches the glob "hawk*".
X =~ "+5" 0 X is interpreted as string "5".
X == "+5" 1 string "+5" is converted to integer 5.
visual & (X > 0) 1 visual is nonzero, AND %X is positive.
See: functions,
/test,
evaluation,
patterns
Back to index
Back to tf home page
Copyright © 1995, 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2005, 2006-2007 Ken Keys