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